diff --git a/server/drivers/bayrad.c b/server/drivers/bayrad.c index 63566eb..c3cb809 100644 --- a/server/drivers/bayrad.c +++ b/server/drivers/bayrad.c @@ -47,13 +47,18 @@ ////////////////////// Base "class" to derive from /////////////////////// ////////////////////////////////////////////////////////////////////////// -static int fd = -1; -static int width = 0; -static int height = 0; -static int cellwidth = 5; -static int cellheight = 8; -static char *framebuf = NULL; -static char ccmode = CCMODE_STANDARD; +typedef struct driver_private_data { + char device[256]; + int speed; + int fd; + int width; + int height; + int cellwidth; + int cellheight; + char *framebuf; + char ccmode; +} PrivateData; + ///////////////////////////////////////////////////////////// /* Declare a bunch of global, static custom character data */ @@ -340,57 +345,58 @@ MODULE_EXPORT char *symbol_prefix = "bayrad_"; MODULE_EXPORT int bayrad_init(Driver *drvthis) { + PrivateData *p; + struct termios portset; - char device[256] = BAYRAD_DEFAULT_DEVICE; - int speed = B9600; - struct termios portset; - - width = 20; - height = 2; - - framebuf = malloc(width * height); - if (framebuf == NULL) { - bayrad_close(drvthis); - report(RPT_ERR, "bayrad_init: Error: unable to create BayRAD framebuffer."); + /* Allocate and store private data */ + p = (PrivateData *) calloc(1, sizeof(PrivateData)); + if (p == NULL) + return -1; + if (drvthis->store_private_ptr(drvthis, p)) return -1; - } - memset(framebuf, ' ', width * height); + /* initialize private data */ + p->fd = -1; + p->speed = B9600; + p->width = 20; + p->height = 2; + p->cellwidth = 5; + p->cellheight = 8; + p->framebuf = NULL; + p->ccmode = CCMODE_STANDARD; - //cellheight = 5; - //cellwidth = 8; /* Read config file */ /* What device should be used */ - strncpy(device, drvthis->config_get_string(drvthis->name, "Device", 0, - BAYRAD_DEFAULT_DEVICE), sizeof(device)); - device[sizeof(device)-1] = '\0'; - report(RPT_INFO, "%s: using Device %s", drvthis->name, device); + strncpy(p->device, drvthis->config_get_string(drvthis->name, "Device", 0, + BAYRAD_DEFAULT_DEVICE), sizeof(p->device)); + p->device[sizeof(p->device)-1] = '\0'; + report(RPT_INFO, "%s: using Device %s", drvthis->name, p->device); /* What speed to use */ - speed = drvthis->config_get_int(drvthis->name, "Speed", 0, 9600); + p->speed = drvthis->config_get_int(drvthis->name, "Speed", 0, 9600); - if (speed == 1200) speed = B1200; - else if (speed == 2400) speed = B2400; - else if (speed == 9600) speed = B9600; - else if (speed == 19200) speed = B19200; + if (p->speed == 1200) p->speed = B1200; + else if (p->speed == 2400) p->speed = B2400; + else if (p->speed == 9600) p->speed = B9600; + else if (p->speed == 19200) p->speed = B19200; else { report(RPT_WARNING, "%s: illegal Speed %d; must be one of 1200, 2400, 9600 or 19200; using default %d", - drvthis->name, speed, 9600); - speed = B9600; + drvthis->name, p->speed, 9600); + p->speed = B9600; } // Set up io port correctly, and open it... - fd = open(device, O_RDWR | O_NOCTTY | O_NDELAY); - if (fd == -1) { - report(RPT_ERR, "%s: open(%s) failed (%s)", drvthis->name, device, strerror(errno)); + p->fd = open(p->device, O_RDWR | O_NOCTTY | O_NDELAY); + if (p->fd == -1) { + report(RPT_ERR, "%s: open(%s) failed (%s)", drvthis->name, p->device, strerror(errno)); return -1; } //else debug(RPT_DEBUG, "bayrad_init: opened device %s", device); - tcflush(fd, TCIOFLUSH); + tcflush(p->fd, TCIOFLUSH); // We use RAW mode #ifdef HAVE_CFMAKERAW @@ -414,19 +420,27 @@ bayrad_init(Driver *drvthis) cfsetispeed(&portset, B0); // Do it... - tcsetattr(fd, TCSANOW, &portset); - tcflush(fd, TCIOFLUSH); + tcsetattr(p->fd, TCSANOW, &portset); + tcflush(p->fd, TCIOFLUSH); /*------------------------------------*/ + p->framebuf = malloc(p->width * p->height); + if (p->framebuf == NULL) { + bayrad_close(drvthis); + report(RPT_ERR, "%s: Error: unable to create framebuffer", drvthis->name); + return -1; + } + memset(p->framebuf, ' ', p->width * p->height); + /*** Open the port write-only, then fork off a process that reads chars ?!!? ***/ /* Reset and clear the BayRAD */ - write(fd, "\x80\x86\x00\x1a\x1e", 5); // sync,reset to type 0, clear screen, home + write(p->fd, "\x80\x86\x00\x1a\x1e", 5); // sync,reset to type 0, clear screen, home report(RPT_DEBUG, "%s: init() done", drvthis->name); - return 0; + return 1; } @@ -437,15 +451,21 @@ bayrad_init(Driver *drvthis) MODULE_EXPORT void bayrad_close(Driver * drvthis) { - //debug(RPT_DEBUG, "Closing BayRAD"); - if (fd >= 0) { - write(fd, "\x8e\x00", 2); // Backlight OFF - close(fd); - } + PrivateData *p = drvthis->private_data; - if (framebuf != NULL) - free(framebuf); - framebuf = NULL; + //debug(RPT_DEBUG, "Closing BayRAD"); + if (p != NULL) { + if (p->fd >= 0) { + write(p->fd, "\x8e\x00", 2); // Backlight OFF + close(p->fd); + } + + if (p->framebuf != NULL) + free(p->framebuf); + + free(p); + } + drvthis->store_private_ptr(drvthis, NULL); } @@ -455,7 +475,9 @@ bayrad_close(Driver * drvthis) MODULE_EXPORT int bayrad_width(Driver * drvthis) { - return width; + PrivateData *p = drvthis->private_data; + + return p->width; } @@ -465,7 +487,33 @@ bayrad_width(Driver * drvthis) MODULE_EXPORT int bayrad_height(Driver * drvthis) { - return height; + PrivateData *p = drvthis->private_data; + + return p->cellheight; +} + + +///////////////////////////////////////////////////////////////// +// Returns the display's cell width +// +MODULE_EXPORT int +bayrad_cellwidth(Driver * drvthis) +{ + PrivateData *p = drvthis->private_data; + + return p->width; +} + + +///////////////////////////////////////////////////////////////// +// Returns the display's cell height +// +MODULE_EXPORT int +bayrad_cellheight(Driver * drvthis) +{ + PrivateData *p = drvthis->private_data; + + return p->cellheight; } @@ -475,8 +523,10 @@ bayrad_height(Driver * drvthis) MODULE_EXPORT void bayrad_clear(Driver * drvthis) { - memset(framebuf, ' ', width * height); - ccmode = CCMODE_STANDARD; + PrivateData *p = drvthis->private_data; + + memset(p->framebuf, ' ', p->width * p->height); + p->ccmode = CCMODE_STANDARD; } @@ -486,11 +536,13 @@ bayrad_clear(Driver * drvthis) MODULE_EXPORT void bayrad_flush(Driver * drvthis) { + PrivateData *p = drvthis->private_data; + //debug(RPT_DEBUG, "BayRAD flush"); - write(fd, "\x80\x1e", 2); //sync, home - write(fd, framebuf, 20); - write(fd, "\x1e\x0a", 2); //home, LF - write(fd, framebuf+20, 20); + write(p->fd, "\x80\x1e", 2); //sync, home + write(p->fd, p->framebuf, 20); + write(p->fd, "\x1e\x0a", 2); //home, LF + write(p->fd, p->framebuf+20, 20); } ///////////////////////////////////////////////////////////////// @@ -500,6 +552,7 @@ bayrad_flush(Driver * drvthis) MODULE_EXPORT void bayrad_string(Driver * drvthis, int x, int y, char string[]) { + PrivateData *p = drvthis->private_data; int i; //debug(RPT_DEBUG, "Putting string %s at %i, %i", string, x, y); @@ -511,7 +564,7 @@ bayrad_string(Driver * drvthis, int x, int y, char string[]) unsigned char c = (unsigned char) string[i]; // Check for buffer overflows... - if ((y * width) + x + i > (width * height)) + if ((y * p->width) + x + i > (p->width * p->height)) break; if ((c > 0x7F) && (c < 0x98)) { @@ -524,7 +577,7 @@ bayrad_string(Driver * drvthis, int x, int y, char string[]) if (c < 8) /* The custom characters are mapped at 0x98 - 0x9F, */ c += 0x98; /* as 0x07 makes a beep instead of printing a character */ - framebuf[(y * width) + x + i] = c; + p->framebuf[(y * p->width) + x + i] = c; } } @@ -535,6 +588,7 @@ bayrad_string(Driver * drvthis, int x, int y, char string[]) MODULE_EXPORT void bayrad_chr(Driver * drvthis, int x, int y, char c) { + PrivateData *p = drvthis->private_data; unsigned char ch = (unsigned char) c; //debug(RPT_DEBUG, "Putting char %c (%#x) at %i, %i", c, c, x, y); @@ -549,8 +603,7 @@ bayrad_chr(Driver * drvthis, int x, int y, char c) } /* No shifting the custom chars here, so bayrad_chr() can beep */ - - framebuf[(y * width) + x] = ch; + p->framebuf[(y * p->width) + x] = ch; } ////////////////////////////////////////////////////////////////////// @@ -559,6 +612,8 @@ bayrad_chr(Driver * drvthis, int x, int y, char c) MODULE_EXPORT void bayrad_backlight(Driver * drvthis, int on) { + //PrivateData *p = drvthis->private_data; + /* This violates the LCDd driver model, but it does leave the * backlight control entirely in the hands of the user via * BayRAd buttons, which is nice, since the backlights have @@ -566,12 +621,12 @@ bayrad_backlight(Driver * drvthis, int on) if (on) { ; - //write(fd, "\x8e\x0f", 2); + //write(p->fd, "\x8e\x0f", 2); //debug(RPT_DEBUG, "Backlight ON"); } else { ; - //write(fd, "\x8e\x00", 2); + //write(p->fd, "\x8e\x00", 2); //debug(RPT_DEBUG, "Backlight OFF"); } } @@ -582,20 +637,22 @@ bayrad_backlight(Driver * drvthis, int on) void bayrad_init_vbar(Driver * drvthis) { + PrivateData *p = drvthis->private_data; + //debug(RPT_DEBUG,"Init Vertical bars."); - if (ccmode == CCMODE_VBAR) { + if (p->ccmode == CCMODE_VBAR) { /* Work already done */ return; } - if (ccmode != CCMODE_STANDARD) { + if (p->ccmode != CCMODE_STANDARD) { /* Not supported (yet) */ report(RPT_WARNING, "%s: cannot combine two modes using user defined characters", drvthis->name); return; } - ccmode = CCMODE_VBAR; + p->ccmode = CCMODE_VBAR; bayrad_set_char(drvthis, 1, bar_up[0]); bayrad_set_char(drvthis, 2, bar_up[1]); @@ -612,20 +669,22 @@ bayrad_init_vbar(Driver * drvthis) void bayrad_init_hbar(Driver * drvthis) { + PrivateData *p = drvthis->private_data; + //debug(RPT_DEBUG,"Init Horizontal bars."); - if (ccmode == CCMODE_HBAR) { + if (p->ccmode == CCMODE_HBAR) { /* Work already done */ return; } - if (ccmode != CCMODE_STANDARD) { + if (p->ccmode != CCMODE_STANDARD) { /* Not supported (yet) */ report(RPT_WARNING, "%s: cannot combine two modes using user defined characters", drvthis->name); return; } - ccmode = CCMODE_HBAR; + p->ccmode = CCMODE_HBAR; bayrad_set_char(drvthis, 1, bar_right[0]); bayrad_set_char(drvthis, 2, bar_right[1]); @@ -640,6 +699,8 @@ bayrad_init_hbar(Driver * drvthis) void bayrad_init_num(Driver * drvthis) { + //PrivateData *p = drvthis->private_data; + // debug(RPT_DEBUG,"Big Numbers."); } @@ -649,6 +710,8 @@ bayrad_init_num(Driver * drvthis) MODULE_EXPORT void bayrad_num(Driver * drvthis, int x, int num) { + //PrivateData *p = drvthis->private_data; + // debug(RPT_DEBUG,"BigNum(%i, %i)", x, num); } @@ -658,6 +721,7 @@ bayrad_num(Driver * drvthis, int x, int num) MODULE_EXPORT void bayrad_set_char(Driver * drvthis, int n, char *dat) { + PrivateData *p = drvthis->private_data; char out[4]; int row, col; @@ -671,20 +735,20 @@ bayrad_set_char(Driver * drvthis, int n, char *dat) /* Set the LCD to accept data for rewrite-able char n */ snprintf(out, sizeof(out), "\x88%c", 0x40 + (n * 8)); - write(fd, out, 2); + write(p->fd, out, 2); - for (row = 0; row < cellheight; row++) { + for (row = 0; row < p->cellheight; row++) { char letter = 0; - for (col = 0; col < cellwidth; col++) { + for (col = 0; col < p->cellwidth; col++) { letter <<= 1; - letter |= (dat[(row*cellwidth) + col] > 0); + letter |= (dat[(row * p->cellwidth) + col] > 0); } - write(fd, &letter, 1); + write(p->fd, &letter, 1); } /* return the LCD to normal operation */ - write(fd, "\x80", 1); + write(p->fd, "\x80", 1); } ///////////////////////////////////////////////////////////////// @@ -693,6 +757,8 @@ bayrad_set_char(Driver * drvthis, int n, char *dat) MODULE_EXPORT void bayrad_vbar(Driver * drvthis, int x, int y, int len, int promille, int options) { + PrivateData *p = drvthis->private_data; + //debug(RPT_DEBUG, "Vbar at %i, length %i", x, len); /* x and y are the start position of the bar. @@ -704,7 +770,7 @@ bayrad_vbar(Driver * drvthis, int x, int y, int len, int promille, int options) bayrad_init_vbar(drvthis); - lib_vbar_static(drvthis, x, y, len, promille, options, cellheight, 0x98); + lib_vbar_static(drvthis, x, y, len, promille, options, p->cellheight, 0x98); } ///////////////////////////////////////////////////////////////// @@ -713,6 +779,8 @@ bayrad_vbar(Driver * drvthis, int x, int y, int len, int promille, int options) MODULE_EXPORT void bayrad_hbar(Driver * drvthis, int x, int y, int len, int promille, int options) { + PrivateData *p = drvthis->private_data; + //debug(RPT_DEBUG, "Hbar at %i,%i; length %i", x, y, len); /* x and y are the start position of the bar. @@ -724,7 +792,7 @@ bayrad_hbar(Driver * drvthis, int x, int y, int len, int promille, int options) bayrad_init_hbar(drvthis); - lib_hbar_static(drvthis, x, y, len, promille, options, cellwidth, 0x98); + lib_hbar_static(drvthis, x, y, len, promille, options, p->cellwidth, 0x98); } @@ -734,6 +802,8 @@ bayrad_hbar(Driver * drvthis, int x, int y, int len, int promille, int options) MODULE_EXPORT int bayrad_icon(Driver * drvthis, int x, int y, int icon) { + //PrivateData *p = drvthis->private_data; + switch (icon) { case ICON_BLOCK_FILLED: bayrad_chr( drvthis, x, y, 0xFF ); @@ -753,6 +823,8 @@ bayrad_icon(Driver * drvthis, int x, int y, int icon) MODULE_EXPORT const char * bayrad_get_key(Driver * drvthis) { + PrivateData *p = drvthis->private_data; + fd_set brfdset; struct timeval twait; char readchar; @@ -766,21 +838,21 @@ bayrad_get_key(Driver * drvthis) /* TODO: NEEDS TO BE ADAPTED TO RETURN REAL KEY DESCRIPTION STRINGS ! */ FD_ZERO(&brfdset); - FD_SET(fd, &brfdset); + FD_SET(p->fd, &brfdset); twait.tv_sec = 0; twait.tv_usec = 0; - if (select(fd+1, &brfdset, NULL, NULL, &twait)) { - retval = read(fd, &readchar, 1); + if (select(p->fd + 1, &brfdset, NULL, NULL, &twait)) { + retval = read(p->fd, &readchar, 1); if (retval > 0) { debug(RPT_INFO, "bayrad_get_key: Got key: %c", readchar); if (readchar == 'Y') { - write(fd, "\x8e\x0f", 2); + write(p->fd, "\x8e\x0f", 2); } else if (readchar == 'N') { - write(fd, "\x8e\x00", 2); + write(p->fd, "\x8e\x00", 2); } } /* if read returned data */ else { diff --git a/server/drivers/bayrad.h b/server/drivers/bayrad.h index 5ce05b9..48b1bab 100644 --- a/server/drivers/bayrad.h +++ b/server/drivers/bayrad.h @@ -14,6 +14,8 @@ MODULE_EXPORT int bayrad_init(Driver * drvthis); MODULE_EXPORT void bayrad_close(Driver * drvthis); MODULE_EXPORT int bayrad_width(Driver * drvthis); MODULE_EXPORT int bayrad_height(Driver * drvthis); +MODULE_EXPORT int bayrad_cellwidth(Driver * drvthis); +MODULE_EXPORT int bayrad_cellheight(Driver * drvthis); MODULE_EXPORT void bayrad_clear(Driver * drvthis); MODULE_EXPORT void bayrad_flush(Driver * drvthis); MODULE_EXPORT void bayrad_string(Driver * drvthis, int x, int y, char string[]);