diff --git a/server/drivers/Makefile.am b/server/drivers/Makefile.am index d6ea385..9c3af80 100644 --- a/server/drivers/Makefile.am +++ b/server/drivers/Makefile.am @@ -31,7 +31,7 @@ CFontzPacket_LDADD = libLCD.a libbignum.a curses_LDADD = @LIBCURSES@ CwLnx_LDADD = libLCD.a glcdlib_LDADD = libLCD.a @LIBGLCD@ -hd44780_LDADD = libLCD.a @HD44780_DRIVERS@ @libusb_libs@ +hd44780_LDADD = libLCD.a @HD44780_DRIVERS@ @libusb_libs@ libbignum.a hd44780_DEPENDENCIES = @HD44780_DRIVERS@ icp_a106_LDADD = libLCD.a imon_LDADD = libLCD.a @@ -61,7 +61,7 @@ curses_SOURCES = lcd.h curses_drv.h curses_drv.c report.h CwLnx_SOURCES = lcd.h lcd_lib.h CwLnx.c CwLnx.h report.h glcdlib_SOURCES = lcd.h lcd_lib.h glcdlib.h glcdlib.c report.h glk_SOURCES = lcd.h glk.c glk.h glkproto.c glkproto.h report.h -hd44780_SOURCES = lcd.h lcd_lib.h hd44780.h hd44780.c hd44780-drivers.h hd44780-low.h hd44780-charmap.h report.h +hd44780_SOURCES = lcd.h lcd_lib.h hd44780.h hd44780.c hd44780-drivers.h hd44780-low.h hd44780-charmap.h report.h adv_bignum.h EXTRA_hd44780_SOURCES = hd44780-4bit.c hd44780-4bit.h hd44780-ext8bit.c hd44780-ext8bit.h lcd_sem.c lcd_sem.h hd44780-serialLpt.c hd44780-serialLpt.h hd44780-winamp.c hd44780-winamp.h hd44780-picanlcd.c hd44780-picanlcd.h hd44780-bwct-usb.c hd44780-bwct-usb.h hd44780-lcdserializer.c hd44780-lcdserializer.h hd44780-lis2.c hd44780-lis2.h hd44780-i2c.c hd44780-i2c.h port.h lpt-port.h timing.h icp_a106_SOURCES = lcd.h lcd_lib.h icp_a106.c icp_a106.h report.h diff --git a/server/drivers/hd44780-low.h b/server/drivers/hd44780-low.h index ad738d9..646a7ce 100644 --- a/server/drivers/hd44780-low.h +++ b/server/drivers/hd44780-low.h @@ -29,11 +29,19 @@ /* Constants for userdefchar_mode */ #define NUM_CCs 8 /* number of custom characters */ -#define CCMODE_STANDARD 0 /* only char 0 is used for heartbeat */ -#define CCMODE_VBAR 1 -#define CCMODE_HBAR 2 -#define CCMODE_BIGNUM 3 -#define CCMODE_BIGCHAR 4 + +typedef enum { + standard, /* only char 0 is used for heartbeat */ + vbar, /* vertical bars */ + hbar, /* horizontaln bars */ + bignum, /* big numbers */ + bigchar /* big characters */ +} CGmode; + +typedef struct cgram_cache { + unsigned char cache[LCD_DEFAULT_CELLHEIGHT]; + int clean; +} CGram; typedef struct ConnectionMapping { char *name; @@ -57,8 +65,8 @@ typedef struct driver_private_data { char *lcd_contents; // The defineable characters - char *cc_buf; - char *cc_dirty; + CGram cc[NUM_CCs]; + CGmode ccmode; // Connection type data int connectiontype_index; @@ -106,9 +114,6 @@ typedef struct driver_private_data { int backlight_bit; int output_state; // what was most recently output to the output port - - int ccmode; - } PrivateData; // Structures holding pointers to HD44780 specific functions diff --git a/server/drivers/hd44780.c b/server/drivers/hd44780.c index f231e0c..672eff8 100644 --- a/server/drivers/hd44780.c +++ b/server/drivers/hd44780.c @@ -73,6 +73,7 @@ #include "lcd_lib.h" #include "hd44780.h" #include "report.h" +#include "adv_bignum.h" #include "timing.h" #include "hd44780-low.h" @@ -131,17 +132,16 @@ HD44780_init (Driver * drvthis) PrivateData *p; // Alocate and store private data - p = (PrivateData *) malloc(sizeof(PrivateData)); + p = (PrivateData *) calloc(1, sizeof(PrivateData)); if (p == NULL) return -1; - if (drvthis->store_private_ptr( drvthis, p)) + if (drvthis->store_private_ptr(drvthis, p)) return -1; - // Clear data struct - memset( p, 0, sizeof(*p) ); + // initialize private data p->cellheight = 8; /* Do not change this !!! This is a controller property, not a display property !!! */ p->cellwidth = 5; - p->ccmode = CCMODE_STANDARD; + p->ccmode = standard; //// READ THE CONFIG FILE @@ -189,18 +189,18 @@ HD44780_init (Driver * drvthis) // default case for when spans aren't indicated // - add a sanity check against p->height ?? if (p->numLines == 0) { - if ((p->spanList = (int *) malloc(sizeof(int) * p->height))) { + if ((p->spanList = (int *) calloc(sizeof(int), p->height)) != NULL) { int i; for (i = 0; i < p->height; ++i) { p->spanList[i] = 1; p->numLines = p->height; } } else - report(RPT_ERR, "%s: error mallocing", drvthis->name); + report(RPT_ERR, "%s: error allocing", drvthis->name); } if (p->numDisplays == 0) { - if ((p->dispVOffset = (int *) malloc(sizeof(int))) && - (p->dispSizes = (int *) malloc(sizeof(int)))) { + if (((p->dispVOffset = (int *) calloc(1, sizeof(int))) != NULL) && + ((p->dispSizes = (int *) calloc(1, sizeof(int))) != NULL)) { p->dispVOffset[0] = 0; p->dispSizes[0] = p->height; p->numDisplays = 1; @@ -228,7 +228,7 @@ HD44780_init (Driver * drvthis) #endif // Allocate framebuffer - p->framebuf = (char *) malloc(p->width * p->height); + p->framebuf = (char *) calloc(p->width * p->height, sizeof(char)); if (p->framebuf == NULL) { report(RPT_ERR, "%s: unable to allocate framebuffer", drvthis->name); //HD44780_close(); @@ -236,29 +236,18 @@ HD44780_init (Driver * drvthis) } // Allocate and clear the buffer for incremental updates - p->lcd_contents = (char *) malloc (p->width * p->height); + p->lcd_contents = (char *) calloc (p->width * p->height, sizeof(char)); if (p->lcd_contents == NULL) { report(RPT_ERR, "%s: unable to allocate framebuffer backing store", drvthis->name); return -1; } - memset(p->lcd_contents, 0, p->width * p->height); - - // Allocate and clear the buffer for defineable characters - p->cc_buf = (char *) malloc(NUM_CCs * p->cellheight); - p->cc_dirty = (char *) malloc(NUM_CCs); - if (!p->cc_buf || !p->cc_dirty) { - report(RPT_ERR, "%s: error mallocing", drvthis->name); - return -1; - } - memset(p->cc_buf, 0, NUM_CCs * p->cellheight); - memset(p->cc_dirty, 1, NUM_CCs); /* all custom chars dirty */ // Keypad ? if (p->have_keypad) { int x, y; // Read keymap - for ( x=0; xoutput_state = 999999; - if ((p->hd44780_functions = (HD44780_functions *) malloc(sizeof(HD44780_functions))) == NULL) { + if ((p->hd44780_functions = (HD44780_functions *) calloc(1, sizeof(HD44780_functions))) == NULL) { report(RPT_ERR, "%s: error mallocing", drvthis->name); return -1; } @@ -307,7 +296,7 @@ HD44780_init (Driver * drvthis) p->hd44780_functions->output = NULL; // Do connection type specific display init - if (connectionMapping[p->connectiontype_index].init_fn (drvthis) != 0) + if (connectionMapping[p->connectiontype_index].init_fn(drvthis) != 0) return -1; // Display startup parameters on the LCD @@ -477,9 +466,9 @@ HD44780_flush (Driver *drvthis) // Update LCD incrementally by comparing with last contents count = 0; - for (y=0; yheight; y++) { + for (y = 0; y < p->height; y++) { drawing = 0; - for (x=0 ; xframebuf[(y * wid) + x]; if ( ch != p->lcd_contents[(y*wid)+x] ) { if ( !drawing || x % 8 == 0 ) { // x%8 is for 16x1 displays ! @@ -489,7 +478,7 @@ HD44780_flush (Driver *drvthis) p->hd44780_functions->senddata (p, p->spanList[y], RS_DATA, HD44780_charmap[(unsigned char)ch]); p->hd44780_functions->uPause (p, 40); // Minimum exec time for all commands p->lcd_contents[(y*wid)+x] = ch; - count ++; + count++; } else { drawing = 0; @@ -500,8 +489,8 @@ HD44780_flush (Driver *drvthis) /* Check which defineable chars we need to update */ count = 0; - for ( i = 0; i < NUM_CCs; i ++ ) { - if ( p->cc_dirty[i] ) { + for (i = 0; i < NUM_CCs; i++) { + if (!p->cc[i].clean) { /* Tell the HD44780 we will redefine char number i */ p->hd44780_functions->senddata (p, 0, RS_INSTR, SETCHAR | i * 8); @@ -509,15 +498,14 @@ HD44780_flush (Driver *drvthis) /* Send the subsequent rows */ for (row = 0; row < p->cellheight; row++) { - p->hd44780_functions->senddata (p, 0, RS_DATA, p->cc_buf[i*p->cellheight+row]); + p->hd44780_functions->senddata (p, 0, RS_DATA, p->cc[i].cache[row]); p->hd44780_functions->uPause (p, 40); /* Minimum exec time for all commands */ } - /* Mark as not dirty anymore */ - p->cc_dirty[i] = 0; - count ++; + p->cc[i].clean = 1; /* mark as clean */ + count++; } } - debug(RPT_DEBUG, "HD44780: flushed %d custom chars's", count ); + debug(RPT_DEBUG, "%s: flushed %d custom chars", drvthis->name, count); } ///////////////////////////////////////////////////////////////// @@ -528,7 +516,7 @@ HD44780_clear (Driver *drvthis) { PrivateData *p = (PrivateData *) drvthis->private_data; memset(p->framebuf, ' ', p->width * p->height); - p->ccmode = CCMODE_STANDARD; + p->ccmode = standard; } ///////////////////////////////////////////////////////////////// @@ -541,26 +529,28 @@ HD44780_chr (Driver *drvthis, int x, int y, char ch) y--; x--; - p->framebuf[ (y * p->width) + x] = ch; + if ((x >= 0) && (y >= 0) && (x < p->width) && (y < p->height)) + p->framebuf[ (y * p->width) + x] = ch; } ///////////////////////////////////////////////////////////////// // Place a string in the framebuffer // MODULE_EXPORT void -HD44780_string (Driver *drvthis, int x, int y, char *s) +HD44780_string (Driver *drvthis, int x, int y, char *string) { PrivateData *p = (PrivateData *) drvthis->private_data; int i; - x --; // Convert 1-based coords to 0-based - y --; + x--; // Convert 1-based coords to 0-based + y--; - for (i = 0; s[i]; i++) { - // Check for buffer overflows... - if ((y * p->width) + x + i > (p->width * p->height)) - break; - p->framebuf[(y*p->width) + x + i] = s[i]; + if ((y < 0) || (y >= p->height)) + return; + + for (i = 0; (string[i] != '\0') && (x < p->width); i++, x++) { + if (x >= 0) // no write left of left border + p->framebuf[(y * p->width) + x] = string[i]; } } @@ -574,185 +564,6 @@ HD44780_backlight (Driver *drvthis, int on) p->hd44780_functions->backlight (p, on); } -///////////////////////////////////////////////////////////////// -// Sets up for vertical bars. Call before HD44780->vbar() -// -static void -HD44780_init_vbar (Driver *drvthis) -{ - PrivateData *p = (PrivateData *) drvthis->private_data; - - char a[] = { - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, - }; - char b[] = { - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, - }; - char c[] = { - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, - }; - char d[] = { - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, - }; - char e[] = { - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, - }; - char f[] = { - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, - }; - char g[] = { - 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, - }; - - if ( p->ccmode == CCMODE_VBAR ) { - /* Work already done */ - return; - } - - if ( p->ccmode != CCMODE_STANDARD ) { - /* Not supported (yet) */ - report(RPT_WARNING, "HD44780_init_vbar: Cannot combine two modes using user defined characters" ); - return; - } - p->ccmode = CCMODE_VBAR; - - HD44780_set_char (drvthis, 1, a); - HD44780_set_char (drvthis, 2, b); - HD44780_set_char (drvthis, 3, c); - HD44780_set_char (drvthis, 4, d); - HD44780_set_char (drvthis, 5, e); - HD44780_set_char (drvthis, 6, f); - HD44780_set_char (drvthis, 7, g); -} - -///////////////////////////////////////////////////////////////// -// Inits horizontal bars... -// -static void -HD44780_init_hbar (Driver *drvthis) -{ - PrivateData *p = (PrivateData *) drvthis->private_data; - - char a[] = { - 1, 0, 0, 0, 0, - 1, 0, 0, 0, 0, - 1, 0, 0, 0, 0, - 1, 0, 0, 0, 0, - 1, 0, 0, 0, 0, - 1, 0, 0, 0, 0, - 1, 0, 0, 0, 0, - 1, 0, 0, 0, 0, - }; - char b[] = { - 1, 1, 0, 0, 0, - 1, 1, 0, 0, 0, - 1, 1, 0, 0, 0, - 1, 1, 0, 0, 0, - 1, 1, 0, 0, 0, - 1, 1, 0, 0, 0, - 1, 1, 0, 0, 0, - 1, 1, 0, 0, 0, - }; - char c[] = { - 1, 1, 1, 0, 0, - 1, 1, 1, 0, 0, - 1, 1, 1, 0, 0, - 1, 1, 1, 0, 0, - 1, 1, 1, 0, 0, - 1, 1, 1, 0, 0, - 1, 1, 1, 0, 0, - 1, 1, 1, 0, 0, - }; - char d[] = { - 1, 1, 1, 1, 0, - 1, 1, 1, 1, 0, - 1, 1, 1, 1, 0, - 1, 1, 1, 1, 0, - 1, 1, 1, 1, 0, - 1, 1, 1, 1, 0, - 1, 1, 1, 1, 0, - 1, 1, 1, 1, 0, - }; - char e[] = { - 1, 1, 1, 1, 0, - 1, 1, 1, 1, 0, - 1, 1, 1, 1, 0, - 1, 1, 1, 1, 0, - 1, 1, 1, 1, 0, - 1, 1, 1, 1, 0, - 1, 1, 1, 1, 0, - 1, 1, 1, 1, 0, - }; - - if ( p->ccmode == CCMODE_HBAR ) { - /* Work already done */ - return; - } - - if ( p->ccmode != CCMODE_STANDARD ) { - /* Not supported (yet) */ - report(RPT_WARNING, "HD44780_init_hbar: Cannot combine two modes using user defined characters" ); - return; - } - p->ccmode = CCMODE_HBAR; - - HD44780_set_char (drvthis, 1, a); - HD44780_set_char (drvthis, 2, b); - HD44780_set_char (drvthis, 3, c); - HD44780_set_char (drvthis, 4, d); - HD44780_set_char (drvthis, 5, e); - -} - ///////////////////////////////////////////////////////////////// // Draws a vertical bar... // @@ -768,7 +579,26 @@ HD44780_vbar (Driver *drvthis, int x, int y, int len, int promille, int options) * promille is the number of promilles (0..1000) that the bar should be filled. */ - HD44780_init_vbar(drvthis); + if (p->ccmode != vbar) { + unsigned char vBar[p->cellheight]; + int i; + + if (p->ccmode != standard) { + /* Not supported(yet) */ + report(RPT_WARNING, "%s: vbar: cannot combine two modes using user defined characters", + drvthis->name); + return; + } + p->ccmode = vbar; + + memset(vBar, 0x00, sizeof(vBar)); + + for (i = 1; i < p->cellheight; i++) { + // add pixel line per pixel line ... + vBar[p->cellheight - i] = 0xFF; + HD44780_set_char(drvthis, i, vBar); + } + } lib_vbar_static(drvthis, x, y, len, promille, options, p->cellheight, 0); } @@ -788,107 +618,29 @@ HD44780_hbar (Driver *drvthis, int x, int y, int len, int promille, int options) * promille is the number of promilles (0..1000) that the bar should be filled. */ - HD44780_init_hbar(drvthis); + if (p->ccmode != hbar) { + unsigned char hBar[p->cellheight]; + int i; + + if (p->ccmode != standard) { + /* Not supported(yet) */ + report(RPT_WARNING, "%s: hbar: cannot combine two modes using user defined characters", + drvthis->name); + return; + } + + p->ccmode = hbar; + + for (i = 1; i <= p->cellwidth; i++) { + // fill pixel columns from left to right. + memset(hBar, 0xFF & ~((1 << (p->cellwidth - i)) - 1), sizeof(hBar)); + HD44780_set_char(drvthis, i, hBar); + } + } lib_hbar_static(drvthis, x, y, len, promille, options, p->cellwidth, 0); } -///////////////////////////////////////////////////////////////// -// Sets up for big numbers. -// -static void -HD44780_init_num (Driver *drvthis) -{ - PrivateData *p = (PrivateData *) drvthis->private_data; - - char bignum_ccs[8][5*8] = {{ - 1, 1, 0, 0, 0, - 1, 1, 0, 0, 0, - 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0 - }, { - 0, 0, 0, 1, 1, - 0, 0, 0, 1, 1, - 0, 0, 0, 1, 1, - 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, - 1, 1, 0, 0, 0, - 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0 - }, { - 1, 1, 0, 1, 1, - 1, 1, 0, 1, 1, - 1, 1, 0, 1, 1, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0 - }, { - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, - 1, 1, 0, 0, 0, - 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0 - }, { - 1, 1, 0, 0, 0, - 1, 1, 0, 0, 0, - 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, - 0, 0, 0, 1, 1, - 0, 0, 0, 1, 1, - 0, 0, 0, 0, 0 - }, { - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 1, 1, 0, 1, 1, - 1, 1, 0, 1, 1, - 1, 1, 0, 1, 1, - 0, 0, 0, 0, 0 - }, { - 1, 1, 0, 0, 0, - 1, 1, 0, 0, 0, - 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, - 1, 1, 0, 0, 0, - 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0 - }, { - 0, 0, 0, 1, 1, - 0, 0, 0, 1, 1, - 0, 0, 0, 1, 1, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0 - }}; - - if (p->ccmode != CCMODE_BIGNUM) { - int i; - - if ( p->ccmode != CCMODE_STANDARD ) { - /* Not supported (yet) */ - report(RPT_WARNING, "HD44780_init_num: Cannot combine two modes using user defined characters" ); - return; - } - p->ccmode = CCMODE_BIGNUM; - - for (i = 0; i < 8; i++) - HD44780_set_char (drvthis, i, bignum_ccs[i]); - } -} ///////////////////////////////////////////////////////////////// // Writes a big number. @@ -897,85 +649,26 @@ MODULE_EXPORT void HD44780_num (Driver *drvthis, int x, int num) { PrivateData *p = (PrivateData *) drvthis->private_data; + int do_init = 0; - char bignum_map[11][4][3] = { - { /* 0: */ - { 1, 2, 3 }, - { 6, 32, 6 }, - { 6, 32, 6 }, - { 7, 2, 32 } }, - { /* 1: */ - { 7, 6, 32 }, - { 32, 6, 32 }, - { 32, 6, 32 }, - { 7, 2, 32 } }, - { /* 2: */ - { 1, 2, 3 }, - { 32, 5, 0 }, - { 1, 32, 32 }, - { 2, 2, 0 } }, - { /* 3: */ - { 1, 2, 3 }, - { 32, 5, 0 }, - { 3, 32, 6 }, - { 7, 2, 32 } }, - { /* 4: */ - { 32, 3, 6 }, - { 1, 32, 6 }, - { 2, 2, 6 }, - { 32, 32, 0 } }, - { /* 5: */ - { 1, 2, 0 }, - { 2, 2, 3 }, - { 3, 32, 6 }, - { 7, 2, 32 } }, - { /* 6: */ - { 1, 2, 32 }, - { 6, 5, 32 }, - { 6, 32, 6 }, - { 7, 2, 32 } }, - { /* 7: */ - { 2, 2, 6 }, - { 32, 1, 32 }, - { 32, 6, 32 }, - { 32, 0, 32 } }, - { /* 8: */ - { 1, 2, 3 }, - { 4, 5, 0 }, - { 6, 32, 6 }, - { 7, 2, 32 } }, - { /* 9: */ - { 1, 2, 3 }, - { 4, 3, 6 }, - { 32, 1, 32 }, - { 7, 32, 32 } }, - { /* colon: (only 1st column used) */ - { 32, 32, 32 }, - { 7, 32, 32 }, - { 7, 32, 32 }, - { 32, 32, 32 } } - }; - - if ((num < 0) || (num > 10)) + if ((num < 0) || (num > 10)) return; - if (p->height >= 4) { - int y = (p->height - 2) / 2; - int x2, y2; - - HD44780_init_num(drvthis); - - for (x2 = 0; x2 < 3; x2++) { - for (y2 = 0; y2 < 4; y2++) { - HD44780_chr( drvthis, x+x2, y+y2, bignum_map[num][y2][x2] ); - } - if (num == 10) - x2 = 2; /* =break, for colon only */ + if (p->ccmode != bignum) { + if (p->ccmode != standard) { + /* Not supported (yet) */ + report(RPT_WARNING, "%s: num: cannot combine two modes using user defined characters", + drvthis->name); + return; } + + p->ccmode = bignum; + + do_init = 1; } - else - HD44780_chr(drvthis, x, 1 + (p->height - 1) / 2, - (num == 10) ? ':' : (num + '0')); + + // Lib_adv_bignum does everything needed to show the bignumbers. + lib_adv_bignum(drvthis, x, num, do_init, NUM_CCs); } ///////////////////////////////////////////////////////////////// @@ -986,29 +679,26 @@ HD44780_num (Driver *drvthis, int x, int num) // The input is just an array of characters... // MODULE_EXPORT void -HD44780_set_char (Driver *drvthis, int n, char *dat) +HD44780_set_char (Driver *drvthis, int n, unsigned char *dat) { PrivateData *p = (PrivateData *) drvthis->private_data; - int row, col; - int letter; + unsigned char mask = (1 << p->cellwidth) - 1; + int row; - if (n < 0 || n > 7) + if ((n < 0) || (n >= NUM_CCs)) return; if (!dat) return; for (row = 0; row < p->cellheight; row++) { - letter = 0; - if (p->lastline || (row < p->cellheight - 1)) { - for (col = 0; col < p->cellwidth; col++) { - letter <<= 1; - letter |= (dat[(row * p->cellwidth) + col] > 0) ? 1 : 0; - } - } - if ( p->cc_buf[n*p->cellheight+row] != letter ) { - p->cc_dirty[n] = 1; /* only mark as dirty if really different */ - } - p->cc_buf[n*p->cellheight+row] = letter; + int letter = 0; + + if (p->lastline || (row < p->cellheight - 1)) + letter = dat[row] & mask; + + if (p->cc[n].cache[row] != letter) + p->cc[n].clean = 0; /* only mark dirty if really different */ + p->cc[n].cache[row] = letter; } } @@ -1018,78 +708,127 @@ HD44780_set_char (Driver *drvthis, int n, char *dat) MODULE_EXPORT int HD44780_icon (Driver *drvthis, int x, int y, int icon) { - char heart_open[] = { - 1, 1, 1, 1, 1, - 1, 0, 1, 0, 1, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 1, 0, 0, 0, 1, - 1, 1, 0, 1, 1, - 1, 1, 1, 1, 1 }; - char heart_filled[] = { - 1, 1, 1, 1, 1, - 1, 0, 1, 0, 1, - 0, 1, 0, 1, 0, - 0, 1, 1, 1, 0, - 0, 1, 1, 1, 0, - 1, 0, 1, 0, 1, - 1, 1, 0, 1, 1, - 1, 1, 1, 1, 1 }; - char arrow_up[] = { - 0, 0, 1, 0, 0, - 0, 1, 1, 1, 0, - 1, 0, 1, 0, 1, - 0, 0, 1, 0, 0, - 0, 0, 1, 0, 0, - 0, 0, 1, 0, 0, - 0, 0, 1, 0, 0, - 0, 0, 0, 0, 0 }; - char arrow_down[] = { - 0, 0, 1, 0, 0, - 0, 0, 1, 0, 0, - 0, 0, 1, 0, 0, - 0, 0, 1, 0, 0, - 1, 0, 1, 0, 1, - 0, 1, 1, 1, 0, - 0, 0, 1, 0, 0, - 0, 0, 0, 0, 0 }; - char checkbox_off[] = { - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, - 1, 0, 0, 0, 1, - 1, 0, 0, 0, 1, - 1, 0, 0, 0, 1, - 1, 1, 1, 1, 1, - 0, 0, 0, 0, 0 }; - char checkbox_on[] = { - 0, 0, 1, 0, 0, - 0, 0, 1, 0, 0, - 1, 1, 1, 0, 1, - 1, 0, 1, 1, 0, - 1, 0, 1, 0, 1, - 1, 0, 0, 0, 1, - 1, 1, 1, 1, 1, - 0, 0, 0, 0, 0 }; - char checkbox_gray[] = { - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, - 1, 0, 1, 0, 1, - 1, 1, 0, 1, 1, - 1, 0, 1, 0, 1, - 1, 1, 1, 1, 1, - 0, 0, 0, 0, 0 }; - char block_filled[] = { - 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1 }; + static unsigned char heart_open[] = + { b__XXXXX, + b__X_X_X, + b_______, + b_______, + b_______, + b__X___X, + b__XX_XX, + b__XXXXX }; + static unsigned char heart_filled[] = + { b__XXXXX, + b__X_X_X, + b___X_X_, + b___XXX_, + b___XXX_, + b__X_X_X, + b__XX_XX, + b__XXXXX }; + static unsigned char arrow_up[] = + { b____X__, + b___XXX_, + b__X_X_X, + b____X__, + b____X__, + b____X__, + b____X__, + b_______ }; + static unsigned char arrow_down[] = + { b____X__, + b____X__, + b____X__, + b____X__, + b__X_X_X, + b___XXX_, + b____X__, + b_______ }; + /* + static unsigned char arrow_left[] = + { b_______, + b____X__, + b___X___, + b__XXXXX, + b___X___, + b____X__, + b_______, + b_______ }; + static unsigned char arrow_right[] = + { b_______, + b____X__, + b_____X_, + b__XXXXX, + b_____X_, + b____X__, + b_______, + b_______ }; + */ + static unsigned char checkbox_off[] = + { b_______, + b_______, + b__XXXXX, + b__X___X, + b__X___X, + b__X___X, + b__XXXXX, + b_______ }; + static unsigned char checkbox_on[] = + { b____X__, + b____X__, + b__XXX_X, + b__X_XX_, + b__X_X_X, + b__X___X, + b__XXXXX, + b_______ }; + static unsigned char checkbox_gray[] = + { b_______, + b_______, + b__XXXXX, + b__X_X_X, + b__XX_XX, + b__X_X_X, + b__XXXXX, + b_______ }; + /* + static unsigned char selector_left[] = + { b___X___, + b___XX__, + b___XXX_, + b___XXXX, + b___XXX_, + b___XX__, + b___X___, + b_______ }; + static unsigned char selector_right[] = + { b_____X_, + b____XX_, + b___XXX_, + b__XXXX_, + b___XXX_, + b____XX_, + b_____X_, + b_______ }; + static unsigned char ellipsis[] = + { b_______, + b_______, + b_______, + b_______, + b_______, + b_______, + b__X_X_X, + b_______ }; + */ + static unsigned char block_filled[] = + { b__XXXXX, + b__XXXXX, + b__XXXXX, + b__XXXXX, + b__XXXXX, + b__XXXXX, + b__XXXXX, + b__XXXXX }; /* Yes I know, this is a VERY BAD implementation */ switch ( icon ) { @@ -1171,7 +910,7 @@ HD44780_get_key(Driver *drvthis) return NULL; } // Otherwise a keypress will be returned - p->pressed_key_repetitions ++; + p->pressed_key_repetitions++; } else { // It's a new keypress diff --git a/server/drivers/hd44780.h b/server/drivers/hd44780.h index 0e89b6a..a5d7f68 100644 --- a/server/drivers/hd44780.h +++ b/server/drivers/hd44780.h @@ -34,7 +34,7 @@ MODULE_EXPORT void HD44780_hbar (Driver *drvthis, int x, int y, int len, int pro MODULE_EXPORT void HD44780_num (Driver *drvthis, int x, int num); MODULE_EXPORT int HD44780_icon (Driver *drvthis, int x, int y, int icon); -MODULE_EXPORT void HD44780_set_char (Driver *drvthis, int n, char *dat); +MODULE_EXPORT void HD44780_set_char (Driver *drvthis, int n, unsigned char *dat); MODULE_EXPORT void HD44780_backlight (Driver *drvthis, int on); MODULE_EXPORT void HD44780_output (Driver *drvthis, int state);