diff --git a/server/drivers/CFontz.c b/server/drivers/CFontz.c index bb7b1b5..f57e2f8 100644 --- a/server/drivers/CFontz.c +++ b/server/drivers/CFontz.c @@ -39,6 +39,8 @@ #include "CFontz.h" #include "report.h" #include "lcd_lib.h" +#include "CFontz-charmap.h" +#include "adv_bignum.h" /* Constants for userdefchar_mode */ @@ -93,12 +95,12 @@ MODULE_EXPORT char *symbol_prefix = "CFontz_"; // Internal functions -static void CFontz_linewrap (Driver *drvthis, int on); -static void CFontz_autoscroll (Driver *drvthis, int on); -static void CFontz_hidecursor (Driver *drvthis); -static void CFontz_reboot (Driver *drvthis); -static void CFontz_init_vbar (Driver *drvthis); -static void CFontz_init_hbar (Driver *drvthis); +static void CFontz_linewrap(Driver *drvthis, int on); +static void CFontz_autoscroll(Driver *drvthis, int on); +static void CFontz_hidecursor(Driver *drvthis); +static void CFontz_reboot(Driver *drvthis); +static void CFontz_cursor_goto(Driver *drvthis, int x, int y); +static void CFontz_raw_chr(Driver *drvthis, int x, int y, unsigned char c); // TODO: Get the frame buffers working right @@ -107,7 +109,7 @@ static void CFontz_init_hbar (Driver *drvthis); // Opens com port and sets baud correctly... // MODULE_EXPORT int -CFontz_init (Driver *drvthis) +CFontz_init(Driver *drvthis) { struct termios portset; int tmp, w, h; @@ -275,7 +277,7 @@ CFontz_init (Driver *drvthis) // Clean-up // MODULE_EXPORT void -CFontz_close (Driver *drvthis) +CFontz_close(Driver *drvthis) { PrivateData *p = drvthis->private_data; @@ -293,10 +295,10 @@ CFontz_close (Driver *drvthis) } ///////////////////////////////////////////////////////////////// -// Returns the display p->width +// Returns the display's character width // MODULE_EXPORT int -CFontz_width (Driver *drvthis) +CFontz_width(Driver *drvthis) { PrivateData *p = drvthis->private_data; @@ -304,42 +306,91 @@ CFontz_width (Driver *drvthis) } ///////////////////////////////////////////////////////////////// -// Returns the display p->height +// Returns the display's character height // MODULE_EXPORT int -CFontz_height (Driver *drvthis) +CFontz_height(Driver *drvthis) { PrivateData *p = drvthis->private_data; return p->height; } +///////////////////////////////////////////////////////////////// +// Returns the display's cell width +// +MODULE_EXPORT int +CFontz_cellwidth(Driver *drvthis) +{ + PrivateData *p = drvthis->private_data; + + return p->cellwidth; +} + +///////////////////////////////////////////////////////////////// +// Returns the display's cell height +// +MODULE_EXPORT int +CFontz_cellheight(Driver *drvthis) +{ + PrivateData *p = drvthis->private_data; + + return p->cellheight; +} + ////////////////////////////////////////////////////////////////// // Flushes all output to the lcd... // MODULE_EXPORT void -CFontz_flush (Driver *drvthis) +CFontz_flush(Driver *drvthis) { PrivateData *p = drvthis->private_data; - char out[LCD_MAX_WIDTH * LCD_MAX_HEIGHT]; + unsigned char out[3 * LCD_MAX_WIDTH]; int i; - // Custom characters start at 128, not at 0. - for (i = 0; i < p->width * p->height; i++) { - if (p->framebuf[i] < 32) - p->framebuf[i] += 128; - } + if (p->newfirmware) { + unsigned char *ptr = out; - for (i = 0; i < p->height; i++) { - snprintf(out, sizeof(out), "%c%c%c", 17, 0, i); - write(p->fd, out, 3); - write(p->fd, p->framebuf + (p->width * i), p->width); + for (i = 0; i < p->height; i++) { + int j; + + /* move cursor to start of (i+1)'th line */ + CFontz_cursor_goto(drvthis, 1, i+1); + + for (j = 0; j < p->width; j++) { + unsigned char c = p->framebuf[(i * p->width) + j]; + + /* characters that need to be treated special */ + if ((c < 0x20) || ((c >= 0xF0) && (c < 0xF8))) { + if (c < 0x08) { + // custom chars are at position 0xF0 - 0xF7 + c += 0xF0; + } + else { + // send data directly to LCD + *ptr++ = CFONTZ_Send_Data_Directly_To_LCD; + *ptr++ = 0x01; + } + } + *ptr++ = c; + } + write(p->fd, out, (ptr - out)); + } } - /* - snprintf(out, sizeof(out), "%c", 1); - write(p->fd, out, 1); - write(p->fd, p->framebuf, p->width*p->height); - */ + else { + // Custom characters start at 0xF0, not at 0. + for (i = 0; i < p->width * p->height; i++) { + if (p->framebuf[i] < 32) + p->framebuf[i] += 128; + } + + for (i = 0; i < p->height; i++) { + /* move cursor to start of (i+1)'th line */ + CFontz_cursor_goto(drvthis, 1, i+1); + + write(p->fd, p->framebuf + (p->width * i), p->width); + } + } } ///////////////////////////////////////////////////////////////// @@ -347,34 +398,44 @@ CFontz_flush (Driver *drvthis) // upper-left is (1,1), and the lower right should be (20,4). // MODULE_EXPORT void -CFontz_chr (Driver *drvthis, int x, int y, unsigned char c) +CFontz_chr(Driver *drvthis, int x, int y, unsigned char c) { PrivateData *p = drvthis->private_data; y--; x--; - if ((x < 0) || (y < 0) || (x >= p->width) || (y >= p->height)) - return; - - if (c < 32) - c += 128; - - // For V2 of the firmware to get the block to display right - if (p->newfirmware && (c == 255)) - c = 214; - - p->framebuf[(y * p->width) + x] = c; + if ((x >= 0) && (y >= 0) && (x < p->width) && (y < p->height)) + p->framebuf[(y * p->width) + x] = (p->newfirmware) + ? CFontz_charmap[(unsigned) c] + : c; } +/* + * Prints a character on the lcd display, at position (x,y). + * The upper-left is (1,1), and the lower right should be (20,4). + */ +static void +CFontz_raw_chr(Driver *drvthis, int x, int y, unsigned char c) +{ + PrivateData *p = drvthis->private_data; + + y--; + x--; + + if ((x >= 0) && (y >= 0) && (x < p->width) && (y < p->height)) + p->framebuf[(y * p->width) + x] = c; +} + + ///////////////////////////////////////////////////////////////// // Returns current p->contrast -// This is only the locally stored p->contrast, the p->contrast value +// This is only the locally stored p->contrast, the contrast value // cannot be retrieved from the LCD. // Value 0 to 1000. // MODULE_EXPORT int -CFontz_get_contrast (Driver *drvthis) +CFontz_get_contrast(Driver *drvthis) { PrivateData *p = drvthis->private_data; @@ -386,10 +447,10 @@ CFontz_get_contrast (Driver *drvthis) // Value 0 to 100. // MODULE_EXPORT void -CFontz_set_contrast (Driver *drvthis, int promille) +CFontz_set_contrast(Driver *drvthis, int promille) { PrivateData *p = drvthis->private_data; - char out[4]; + char out[4] = { CFONTZ_Contrast_Control, 0 }; // Check it if ((promille < 0) || (promille > 1000)) @@ -398,9 +459,9 @@ CFontz_set_contrast (Driver *drvthis, int promille) // Store it p->contrast = promille; - // And do it - snprintf(out, sizeof(out), "%c%c", 15, (unsigned char) (promille / 10)); // converted to be 0 to 100 - write(p->fd, out, 3); + // And do it (converted from [0,1000] - > [0,100]) + out[1] = (unsigned char) (promille / 10); + write(p->fd, out, 2); } ///////////////////////////////////////////////////////////////// @@ -408,25 +469,25 @@ CFontz_set_contrast (Driver *drvthis, int promille) // an intermediate p->brightness... // MODULE_EXPORT void -CFontz_backlight (Driver *drvthis, int on) +CFontz_backlight(Driver *drvthis, int on) { PrivateData *p = drvthis->private_data; - char out[4]; + char out[4] = { CFONTZ_Backlight_Control, 0 }; - snprintf(out, sizeof(out), "%c%c", 14, (on) ? p->brightness : p->offbrightness); - write(p->fd, out, 3); + out[1] = (on) ? p->brightness : p->offbrightness; + write(p->fd, out, 2); } ///////////////////////////////////////////////////////////////// // Toggle the built-in linewrapping feature // static void -CFontz_linewrap (Driver *drvthis, int on) +CFontz_linewrap(Driver *drvthis, int on) { PrivateData *p = drvthis->private_data; char out[4]; - snprintf(out, sizeof(out), "%c", (on) ? 23 : 24); + out[0] = (on) ? CFONTZ_Wrap_On : CFONTZ_Wrap_Off; write(p->fd, out, 1); } @@ -434,12 +495,12 @@ CFontz_linewrap (Driver *drvthis, int on) // Toggle the built-in automatic scrolling feature // static void -CFontz_autoscroll (Driver *drvthis, int on) +CFontz_autoscroll(Driver *drvthis, int on) { PrivateData *p = drvthis->private_data; char out[4]; - snprintf(out, sizeof(out), "%c", (on) ? 19 : 20); + out[0] = (on) ? CFONTZ_Scroll_On : CFONTZ_Scroll_Off; write(p->fd, out, 1); } @@ -447,12 +508,11 @@ CFontz_autoscroll (Driver *drvthis, int on) // Get rid of the blinking cursor // static void -CFontz_hidecursor (Driver *drvthis) +CFontz_hidecursor(Driver *drvthis) { PrivateData *p = drvthis->private_data; - char out[4]; + char out[4] = { CFONTZ_Hide_Cursor }; - snprintf(out, sizeof(out), "%c", 4); write(p->fd, out, 1); } @@ -460,191 +520,37 @@ CFontz_hidecursor (Driver *drvthis) // Reset the display bios // static void -CFontz_reboot (Driver *drvthis) +CFontz_reboot(Driver *drvthis) { PrivateData *p = drvthis->private_data; - char out[4]; + char out[4] = { CFONTZ_Reboot, CFONTZ_Reboot }; - snprintf(out, sizeof(out), "%c", 26); - write(p->fd, out, 1); + write(p->fd, out, 2); sleep(4); } ///////////////////////////////////////////////////////////////// -// Sets up for vertical bars. +// Toggle the built-in automatic scrolling feature // static void -CFontz_init_vbar (Driver *drvthis) +CFontz_cursor_goto(Driver *drvthis, int x, int y) { PrivateData *p = 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, 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, - 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, - 0, 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, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, - 0, 1, 1, 1, 1, 1, - 0, 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, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, - 0, 1, 1, 1, 1, 1, - 0, 1, 1, 1, 1, 1, - 0, 1, 1, 1, 1, 1, - }; - char e[] = { - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, - 0, 1, 1, 1, 1, 1, - 0, 1, 1, 1, 1, 1, - 0, 1, 1, 1, 1, 1, - 0, 1, 1, 1, 1, 1, - }; - char f[] = { - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, - 0, 1, 1, 1, 1, 1, - 0, 1, 1, 1, 1, 1, - 0, 1, 1, 1, 1, 1, - 0, 1, 1, 1, 1, 1, - 0, 1, 1, 1, 1, 1, - }; - char g[] = { - 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, - 0, 1, 1, 1, 1, 1, - 0, 1, 1, 1, 1, 1, - 0, 1, 1, 1, 1, 1, - 0, 1, 1, 1, 1, 1, - 0, 1, 1, 1, 1, 1, - 0, 1, 1, 1, 1, 1, - }; + unsigned char out[4] = { CFONTZ_Set_Cursor_Position, 0, 0 }; - if (p->ccmode != vbar) { - CFontz_set_char(drvthis, 1, a); - CFontz_set_char(drvthis, 2, b); - CFontz_set_char(drvthis, 3, c); - CFontz_set_char(drvthis, 4, d); - CFontz_set_char(drvthis, 5, e); - CFontz_set_char(drvthis, 6, f); - CFontz_set_char(drvthis, 7, g); - p->ccmode = vbar; - } -} - -///////////////////////////////////////////////////////////////// -// Inits horizontal bars... -// -static void -CFontz_init_hbar (Driver *drvthis) -{ - PrivateData *p = drvthis->private_data; - - char a[] = { - 1, 0, 0, 0, 0, 0, - 1, 0, 0, 0, 0, 0, - 1, 0, 0, 0, 0, 0, - 1, 0, 0, 0, 0, 0, - 1, 0, 0, 0, 0, 0, - 1, 0, 0, 0, 0, 0, - 1, 0, 0, 0, 0, 0, - 1, 0, 0, 0, 0, 0, - }; - char b[] = { - 1, 1, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 0, - }; - char c[] = { - 1, 1, 1, 0, 0, 0, - 1, 1, 1, 0, 0, 0, - 1, 1, 1, 0, 0, 0, - 1, 1, 1, 0, 0, 0, - 1, 1, 1, 0, 0, 0, - 1, 1, 1, 0, 0, 0, - 1, 1, 1, 0, 0, 0, - 1, 1, 1, 0, 0, 0, - }; - char d[] = { - 1, 1, 1, 1, 0, 0, - 1, 1, 1, 1, 0, 0, - 1, 1, 1, 1, 0, 0, - 1, 1, 1, 1, 0, 0, - 1, 1, 1, 1, 0, 0, - 1, 1, 1, 1, 0, 0, - 1, 1, 1, 1, 0, 0, - 1, 1, 1, 1, 0, 0, - }; - char e[] = { - 1, 1, 1, 1, 1, 0, - 1, 1, 1, 1, 1, 0, - 1, 1, 1, 1, 1, 0, - 1, 1, 1, 1, 1, 0, - 1, 1, 1, 1, 1, 0, - 1, 1, 1, 1, 1, 0, - 1, 1, 1, 1, 1, 0, - 1, 1, 1, 1, 1, 0, - }; - char f[] = { - 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, 1, 1, - 1, 1, 1, 1, 1, 1, - }; - - if (p->ccmode != hbar) { - CFontz_set_char(drvthis, 1, a); - CFontz_set_char(drvthis, 2, b); - CFontz_set_char(drvthis, 3, c); - CFontz_set_char(drvthis, 4, d); - CFontz_set_char(drvthis, 5, e); - CFontz_set_char(drvthis, 6, f); - p->ccmode = hbar; - } + /* set cursor position */ + if ((x > 0) && (x <= p->width)) + out[1] = x - 1; + if ((y > 0) && (y <= p->height)) + out[2] = y - 1; + write(p->fd, out, 3); } ///////////////////////////////////////////////////////////////// // Draws a vertical bar... // MODULE_EXPORT void -CFontz_vbar (Driver *drvthis, int x, int y, int len, int promille, int options) +CFontz_vbar(Driver *drvthis, int x, int y, int len, int promille, int options) { /* x and y are the start position of the bar. * The bar by default grows in the 'up' direction @@ -654,7 +560,28 @@ CFontz_vbar (Driver *drvthis, int x, int y, int len, int promille, int options) */ PrivateData *p = drvthis->private_data; - CFontz_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 ... + // NOTE: cellwidth != bar width: 0x1F = 0xFF & ((1 << (p->cellwidth - 1)) - 1) + vBar[p->cellheight - i] = 0x1F; + CFontz_set_char(drvthis, i, vBar); + } + } + lib_vbar_static(drvthis, x, y, len, promille, options, p->cellheight, 0); } @@ -662,7 +589,7 @@ CFontz_vbar (Driver *drvthis, int x, int y, int len, int promille, int options) // Draws a horizontal bar to the right. // MODULE_EXPORT void -CFontz_hbar (Driver *drvthis, int x, int y, int len, int promille, int options) +CFontz_hbar(Driver *drvthis, int x, int y, int len, int promille, int options) { /* x and y are the start position of the bar. * The bar by default grows in the 'right' direction @@ -672,11 +599,73 @@ CFontz_hbar (Driver *drvthis, int x, int y, int len, int promille, int options) */ PrivateData *p = drvthis->private_data; - CFontz_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; + + memset(hBar, 0x00, sizeof(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)-1); + CFontz_set_char(drvthis, i, hBar); + } + } + lib_hbar_static(drvthis, x, y, len, promille, options, p->cellwidth, 0); } +/* + * Writes a big number. + */ +MODULE_EXPORT void +CFontz_num(Driver *drvthis, int x, int num) +{ +PrivateData *p = drvthis->private_data; +int do_init = 0; + + if ((num < 0) || (num > 10)) + return; + + 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; + } + + // Lib_adv_bignum does everything needed to show the bignumbers. + lib_adv_bignum(drvthis, x, num, do_init, NUM_CCs); +} + + +/* + * Gets number of custom chars (always NUM_CCs) + */ +MODULE_EXPORT int +CFontz_get_free_chars(Driver *drvthis) +{ +//PrivateData *p = drvthis->private_data; + + return NUM_CCs; +} + + ///////////////////////////////////////////////////////////////// // Sets a custom character from 0 - (NUM_CCs-1)... // @@ -685,11 +674,12 @@ CFontz_hbar (Driver *drvthis, int x, int y, int len, int promille, int options) // The input is just an array of characters... // MODULE_EXPORT void -CFontz_set_char (Driver *drvthis, int n, char *dat) +CFontz_set_char(Driver *drvthis, int n, unsigned char *dat) { PrivateData *p = drvthis->private_data; unsigned char out[4 + p->cellheight]; - int row, col; + unsigned char mask = (1 << p->cellwidth) - 1; + int row; if ((n < 0) || (n >= NUM_CCs)) return; @@ -697,17 +687,11 @@ CFontz_set_char (Driver *drvthis, int n, char *dat) return; /* define the n'th custom character */ - out[0] = 0x19; + out[0] = CFONTZ_Set_Custom_Char; out[1] = n; for (row = 0; row < p->cellheight; row++) { - int letter = 0; - - for (col = 0; col < p->cellwidth; col++) { - letter <<= 1; - letter |= (dat[(row * p->cellheight) + col] > 0); - } - out[2+row] = (unsigned char) letter; + out[2+row] = dat[row] & mask; } write(p->fd, out, 2 + p->cellheight); } @@ -716,72 +700,213 @@ CFontz_set_char (Driver *drvthis, int n, char *dat) // Places an icon on screen // MODULE_EXPORT int -CFontz_icon (Driver *drvthis, int x, int y, int icon) +CFontz_icon(Driver *drvthis, int x, int y, int icon) { PrivateData *p = drvthis->private_data; - char icons[3][6 * 8] = { - // Empty Heart - { - 1, 1, 1, 1, 1, 1, - 1, 1, 0, 1, 0, 1, - 1, 0, 0, 0, 0, 0, - 1, 0, 0, 0, 0, 0, - 1, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 0, 1, - 1, 1, 1, 0, 1, 1, - 1, 1, 1, 1, 1, 1, - }, - // Filled Heart - { - 1, 1, 1, 1, 1, 1, - 1, 1, 0, 1, 0, 1, - 1, 0, 1, 0, 1, 0, - 1, 0, 1, 1, 1, 0, - 1, 0, 1, 1, 1, 0, - 1, 1, 0, 1, 0, 1, - 1, 1, 1, 0, 1, 1, - 1, 1, 1, 1, 1, 1, - }, - // Ellipsis - { - 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, 0, 1, 0, 1, 0, - }, - }; - - if (p->ccmode == bignum) - p->ccmode = standard; + 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 we know, this is a VERY BAD implementation :-) */ switch (icon) { case ICON_BLOCK_FILLED: - CFontz_chr(drvthis, x, y, 255); + CFontz_raw_chr(drvthis, x, y, (p->newfirmware) ? 214 : 255); break; case ICON_HEART_FILLED: - CFontz_set_char(drvthis, 0, icons[1]); - CFontz_chr(drvthis, x, y, 0); + CFontz_set_char(drvthis, 0, heart_filled); + CFontz_raw_chr(drvthis, x, y, 0); break; case ICON_HEART_OPEN: - CFontz_set_char(drvthis, 0, icons[0]); - CFontz_chr(drvthis, x, y, 0); + CFontz_set_char(drvthis, 0, heart_open); + CFontz_raw_chr(drvthis, x, y, 0); + break; + case ICON_ARROW_UP: + CFontz_raw_chr(drvthis, x, y, 0xDE); + break; + case ICON_ARROW_DOWN: + CFontz_raw_chr(drvthis, x, y, 0xE0); + break; + case ICON_ARROW_LEFT: + CFontz_raw_chr(drvthis, x, y, 0xE1); + break; + case ICON_ARROW_RIGHT: + CFontz_raw_chr(drvthis, x, y, 0xDF); + break; + case ICON_CHECKBOX_OFF: + CFontz_set_char(drvthis, 3, checkbox_off); + CFontz_raw_chr(drvthis, x, y, 3); + break; + case ICON_CHECKBOX_ON: + CFontz_set_char(drvthis, 4, checkbox_on); + CFontz_raw_chr(drvthis, x, y, 4); + break; + case ICON_CHECKBOX_GRAY: + CFontz_set_char(drvthis, 5, checkbox_gray); + CFontz_raw_chr(drvthis, x, y, 5); break; default: - return -1; + return -1; /* Let the core do other icons */ } return 0; } + +/* + * Sets cursor position and state + */ +MODULE_EXPORT void +CFontz_cursor(Driver *drvthis, int x, int y, int state) +{ + PrivateData *p = (PrivateData *) drvthis->private_data; + unsigned char stylecmd[1]; + + /* set cursor state */ + switch (state) { + case CURSOR_OFF: // no cursor + stylecmd[0] = CFONTZ_Hide_Cursor; + break; + case CURSOR_UNDER: // underline cursor + stylecmd[0] = CFONTZ_Show_Underline_Cursor; + break; + case CURSOR_BLOCK: // inverting blinking block + stylecmd[0] = CFONTZ_Show_Inverting_Block_Cursor; + break; + case CURSOR_DEFAULT_ON: // blinking block + default: + stylecmd[0] = CFONTZ_Show_Block_Cursor; + break; + } + write(p->fd, stylecmd, 1); + + /* set cursor position */ + CFontz_cursor_goto(drvthis, x, y); +} + + ///////////////////////////////////////////////////////////////// // Clears the LCD screen // MODULE_EXPORT void -CFontz_clear (Driver *drvthis) +CFontz_clear(Driver *drvthis) { PrivateData *p = drvthis->private_data; @@ -793,12 +918,12 @@ CFontz_clear (Driver *drvthis) // upper-left is (1,1), and the lower right should be (20,4). // MODULE_EXPORT void -CFontz_string (Driver *drvthis, int x, int y, unsigned char string[]) +CFontz_string(Driver *drvthis, int x, int y, unsigned char string[]) { PrivateData *p = drvthis->private_data; int i; - // Convert 1-based coords to 0-based... + /* Convert 1-based coords to 0-based... */ x--; y--; @@ -806,15 +931,11 @@ CFontz_string (Driver *drvthis, int x, int y, unsigned char string[]) return; for (i = 0; (string[i] != '\0') && (x < p->width); i++, x++) { - unsigned char c = string[i]; - - // For V2 of the firmware to get the block to display right - if (p->newfirmware && (c == 255)) - c = 214; - - // Check for buffer overflows... + /* Check for buffer overflows... */ if (x >= 0) - p->framebuf[(y * p->width) + x] = c; + p->framebuf[(y * p->width) + x] = (p->newfirmware) + ? CFontz_charmap[(unsigned) string[i]] + : string[i]; } } diff --git a/server/drivers/CFontz.h b/server/drivers/CFontz.h index a6f8c89..8d801fd 100644 --- a/server/drivers/CFontz.h +++ b/server/drivers/CFontz.h @@ -3,33 +3,68 @@ #include "lcd.h" -#define DEFAULT_CELL_WIDTH 6 -#define DEFAULT_CELL_HEIGHT 8 -#define DEFAULT_CONTRAST 560 -#define DEFAULT_DEVICE "/dev/lcd" -#define DEFAULT_SPEED B9600 -#define DEFAULT_BRIGHTNESS 60 -#define DEFAULT_OFFBRIGHTNESS 0 -#define DEFAULT_SIZE "20x4" +#define DEFAULT_CELL_WIDTH 6 +#define DEFAULT_CELL_HEIGHT 8 +#define DEFAULT_CONTRAST 560 +#define DEFAULT_DEVICE "/dev/lcd" +#define DEFAULT_SPEED B9600 +#define DEFAULT_BRIGHTNESS 60 +#define DEFAULT_OFFBRIGHTNESS 0 +#define DEFAULT_SIZE "20x4" + +#define CFONTZ_Cursor_Home 0x01 +#define CFONTZ_Hide_Display 0x02 +#define CFONTZ_Restore_Display 0x03 +#define CFONTZ_Hide_Cursor 0x04 +#define CFONTZ_Show_Underline_Cursor 0x05 +#define CFONTZ_Show_Block_Cursor 0x06 +#define CFONTZ_Show_Inverting_Block_Cursor 0x07 +#define CFONTZ_Backspace 0x08 +#define CFONTZ_Control_Boot_Screen 0x09 +#define CFONTZ_LineFeed 0x0A +#define CFONTZ_Delete_InPlace 0x0B +#define CFONTZ_FormFeed 0x0C +#define CFONTZ_CarriageReturn 0x0D +#define CFONTZ_Backlight_Control 0x0E +#define CFONTZ_Contrast_Control 0x0F +#define CFONTZ_Set_Cursor_Position 0x11 +#define CFONTZ_Horizontal_Bar_Graph 0x12 +#define CFONTZ_Scroll_On 0x13 +#define CFONTZ_Scroll_Off 0x14 +#define CFONTZ_Set_Scrolling_Marquee 0x15 +#define CFONTZ_Enable_Scrolling_Marquee 0x16 +#define CFONTZ_Wrap_On 0x17 +#define CFONTZ_Wrap_Off 0x18 +#define CFONTZ_Set_Custom_Char 0x19 +#define CFONTZ_Reboot 0x1A +#define CFONTZ_Escape_Sequence_Prefix 0x1B +#define CFONTZ_Large_Block_Number 0x1C +#define CFONTZ_Send_Data_Directly_To_LCD 0x1E +#define CFONTZ_Show_Information_Screen 0x1F -MODULE_EXPORT int CFontz_init (Driver *drvthis); -MODULE_EXPORT void CFontz_close (Driver *drvthis); -MODULE_EXPORT int CFontz_width (Driver *drvthis); -MODULE_EXPORT int CFontz_height (Driver *drvthis); -MODULE_EXPORT void CFontz_clear (Driver *drvthis); -MODULE_EXPORT void CFontz_flush (Driver *drvthis); -MODULE_EXPORT void CFontz_string (Driver *drvthis, int x, int y, unsigned char string[]); -MODULE_EXPORT void CFontz_chr (Driver *drvthis, int x, int y, unsigned char c); +MODULE_EXPORT int CFontz_init(Driver *drvthis); +MODULE_EXPORT void CFontz_close(Driver *drvthis); +MODULE_EXPORT int CFontz_width(Driver *drvthis); +MODULE_EXPORT int CFontz_height(Driver *drvthis); +MODULE_EXPORT int CFontz_cellwidth(Driver *drvthis); +MODULE_EXPORT int CFontz_cellheight(Driver *drvthis); +MODULE_EXPORT void CFontz_clear(Driver *drvthis); +MODULE_EXPORT void CFontz_flush(Driver *drvthis); +MODULE_EXPORT void CFontz_string(Driver *drvthis, int x, int y, unsigned char string[]); +MODULE_EXPORT void CFontz_chr(Driver *drvthis, int x, int y, unsigned char c); -MODULE_EXPORT void CFontz_vbar (Driver *drvthis, int x, int y, int len, int promille, int options); -MODULE_EXPORT void CFontz_hbar (Driver *drvthis, int x, int y, int len, int promille, int options); +MODULE_EXPORT void CFontz_vbar(Driver *drvthis, int x, int y, int len, int promille, int options); +MODULE_EXPORT void CFontz_hbar(Driver *drvthis, int x, int y, int len, int promille, int options); +MODULE_EXPORT void CFontz_num(Driver *drvthis, int x, int num); MODULE_EXPORT int CFontz_icon(Driver *drvthis, int x, int y, int icon); +MODULE_EXPORT void CFontz_cursor(Driver *drvthis, int x, int y, int state); -MODULE_EXPORT void CFontz_set_char (Driver *drvthis, int n, char *dat); +MODULE_EXPORT int CFontz_get_free_chars(Driver *drvthis); +MODULE_EXPORT void CFontz_set_char(Driver *drvthis, int n, unsigned char *dat); -MODULE_EXPORT int CFontz_get_contrast (Driver *drvthis); -MODULE_EXPORT void CFontz_set_contrast (Driver *drvthis, int contrast); -MODULE_EXPORT void CFontz_backlight (Driver *drvthis, int on); +MODULE_EXPORT int CFontz_get_contrast(Driver *drvthis); +MODULE_EXPORT void CFontz_set_contrast(Driver *drvthis, int contrast); +MODULE_EXPORT void CFontz_backlight(Driver *drvthis, int on); #endif diff --git a/server/drivers/Makefile.am b/server/drivers/Makefile.am index 12c8094..e98940d 100644 --- a/server/drivers/Makefile.am +++ b/server/drivers/Makefile.am @@ -25,7 +25,7 @@ noinst_LIBRARIES = libLCD.a libbignum.a IOWarrior_CFLAGS = @libusb_cflags@ $(AM_CFLAGS) hd44780_CFLAGS = @libusb_cflags@ $(AM_CFLAGS) -CFontz_LDADD = libLCD.a +CFontz_LDADD = libLCD.a libbignum.a CFontz633_LDADD = libLCD.a libbignum.a CFontzPacket_LDADD = libLCD.a libbignum.a curses_LDADD = @LIBCURSES@ @@ -46,7 +46,7 @@ pyramid_LDADD = libLCD.a serialVFD_LDADD = libLCD.a libbignum.a svga_LDADD = @LIBSVGA@ t6963_LDADD = libLCD.a -tyan_LDADD = libLCD.a +tyan_LDADD = libLCD.a libbignum.a ula200_LDADD = libLCD.a @LIBFTDI@ sli_LDADD = libLCD.a xosd_LDADD = @LIBXOSD@ @@ -55,7 +55,7 @@ libLCD_a_SOURCES = lcd_lib.h lcd_lib.c libbignum_a_SOURCES = adv_bignum.h adv_bignum.c bayrad_SOURCES = lcd.h lcd_lib.h bayrad.h bayrad.c report.h -CFontz_SOURCES = lcd.h lcd_lib.h CFontz.c CFontz.h CFontz-charmap.h report.h +CFontz_SOURCES = lcd.h lcd_lib.h CFontz.c CFontz.h CFontz-charmap.h report.h adv_bignum.h CFontz633_SOURCES = lcd.h lcd_lib.h CFontz633.c CFontz633.h CFontz-charmap.h CFontz633io.c CFontz633io.h report.h adv_bignum.h CFontzPacket_SOURCES = lcd.h lcd_lib.h CFontzPacket.c CFontzPacket.h CFontz-charmap.h CFontz633io.c CFontz633io.h report.h adv_bignum.h curses_SOURCES = lcd.h curses_drv.h curses_drv.c report.h @@ -87,7 +87,7 @@ stv5730_SOURCES = lcd.h stv5730.c stv5730.h report.h svga_SOURCES = lcd.h svgalib_drv.c svgalib_drv.h report.h t6963_SOURCES = lcd.h lcd_lib.h t6963.c t6963.h t6963_font.h report.h text_SOURCES = lcd.h text.h text.c report.h -tyan_SOURCES = lcd.h lcd_lib.h tyan_lcdm.h tyan_lcdm.c report.h +tyan_SOURCES = lcd.h lcd_lib.h tyan_lcdm.h tyan_lcdm.c report.h adv_bignum.h ula200_SOURCES = lcd.h lcd_lib.h ula200.h ula200.c report.h sli_SOURCES = lcd.h lcd_lib.h wirz-sli.h wirz-sli.c report.h xosd_SOURCES = lcd.h xosdlib_drv.c xosdlib_drv.h report.h diff --git a/server/drivers/tyan_lcdm.c b/server/drivers/tyan_lcdm.c index 4bea6ab..fede1ae 100644 --- a/server/drivers/tyan_lcdm.c +++ b/server/drivers/tyan_lcdm.c @@ -44,49 +44,10 @@ #include "tyan_lcdm.h" #include "report.h" #include "lcd_lib.h" +#include "adv_bignum.h" -#define TYAN_LCDM_KEY_ENTER 0xF2 -#define TYAN_LCDM_KEY_ESCAPE 0xF3 -#define TYAN_LCDM_KEY_RIGHT 0xF5 -#define TYAN_LCDM_KEY_LEFT 0xF6 -#define TYAN_LCDM_KEY_UP 0xF7 -#define TYAN_LCDM_KEY_DOWN 0xF8 - -#define TYAN_LCDM_CMD_BEGIN 0xF1 -#define TYAN_LCDM_CMD_END 0xF2 - - - -typedef enum { - normal = 0, - hbar = 1, - vbar = 2, - cust = 3, -} custom_type; - -typedef struct driver_private_data { - char device[200]; - int speed; - int fd; - unsigned char *framebuf; - unsigned char *backingstore; - int width; - int height; - int cellwidth; - int cellheight; - custom_type custom; -} PrivateData; - -/* Vars for the server core */ -MODULE_EXPORT char *api_version = API_VERSION; -MODULE_EXPORT int stay_in_foreground = 0; -MODULE_EXPORT int supports_multiple = 0; -MODULE_EXPORT char *symbol_prefix = "tyan_lcdm_"; /* Internal functions */ -static void tyan_lcdm_init_vbar(Driver *drvthis); -static void tyan_lcdm_init_hbar(Driver *drvthis); - static void tyan_lcdm_switch_mode(int fdfd); static void tyan_lcdm_hardware_clear(int fd); @@ -97,6 +58,7 @@ static void tyan_lcdm_set_cursor(int fd, unsigned char start_addr, int pos); #endif static unsigned char tyan_lcdm_read_key(int fd); + /* * Opens com port and sets baud correctly... */ @@ -117,7 +79,7 @@ tyan_lcdm_init (Driver * drvthis, char *args) /* initialize private data */ p->speed = DEFAULT_SPEED; - p->custom = normal; + p->ccmode = standard; p->fd = -1; p->framebuf = NULL; p->backingstore = NULL; @@ -212,6 +174,7 @@ tyan_lcdm_init (Driver * drvthis, char *args) return 1; } + /* * Clean-up */ @@ -235,6 +198,7 @@ tyan_lcdm_close (Driver * drvthis) drvthis->store_private_ptr(drvthis, NULL); } + /* * Returns the display width */ @@ -246,6 +210,7 @@ tyan_lcdm_width (Driver *drvthis) return p->width; } + /* * Returns the display height */ @@ -257,6 +222,31 @@ tyan_lcdm_height (Driver *drvthis) return p->height; } + +/* + * Returns the display's character cell width + */ +MODULE_EXPORT int +tyan_lcmd_cellwidth(Driver *drvthis) +{ +PrivateData *p = drvthis->private_data; + + return p->cellwidth; +} + + +/* + * Returns the display's character cell height + */ +MODULE_EXPORT int +tyan_lcmd_cellheight(Driver *drvthis) +{ +PrivateData *p = drvthis->private_data; + + return p->cellheight; +} + + /* * Flushes all output to the lcd... */ @@ -294,6 +284,7 @@ tyan_lcdm_flush (Driver * drvthis) } } + /* * Return one char from the KeyRing */ @@ -349,6 +340,7 @@ tyan_lcdm_chr (Driver * drvthis, int x, int y, char c) p->framebuf[(y * p->width) + x] = c; } + /* * Sets the backlight on or off. * The hardware support any value between 0 and 100. @@ -360,176 +352,6 @@ tyan_lcdm_backlight (Driver * drvthis, int on) } -/* - * Sets up for vertical bars. - */ -static void -tyan_lcdm_init_vbar (Driver * drvthis) -{ - PrivateData *p = 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->custom != vbar) { - tyan_lcdm_set_char(drvthis, 1, a); - tyan_lcdm_set_char(drvthis, 2, b); - tyan_lcdm_set_char(drvthis, 3, c); - tyan_lcdm_set_char(drvthis, 4, d); - tyan_lcdm_set_char(drvthis, 5, e); - tyan_lcdm_set_char(drvthis, 6, f); - tyan_lcdm_set_char(drvthis, 7, g); - p->custom = vbar; - } -} - -/* - * Inits horizontal bars... - */ -static void -tyan_lcdm_init_hbar (Driver * drvthis) -{ - PrivateData *p = 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, - 0, 0, 0, 0, 0, - }; - char b[] = { - 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 c[] = { - 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 d[] = { - 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 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, - }; - char f[] = { - 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, - }; - - if (p->custom != hbar) { - tyan_lcdm_set_char(drvthis, 1, a); - tyan_lcdm_set_char(drvthis, 2, b); - tyan_lcdm_set_char(drvthis, 3, c); - tyan_lcdm_set_char(drvthis, 4, d); - tyan_lcdm_set_char(drvthis, 5, e); - tyan_lcdm_set_char(drvthis, 6, f); - p->custom = hbar; - } -} - - /* * Draws a vertical bar... */ @@ -544,7 +366,26 @@ tyan_lcdm_vbar (Driver * drvthis, int x, int y, int len, int promille, int optio */ PrivateData *p = drvthis->private_data; - tyan_lcdm_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; + tyan_lcdm_set_char(drvthis, i, vBar); + } + } lib_vbar_static(drvthis, x, y, len, promille, options, p->cellheight, 0); } @@ -564,7 +405,24 @@ tyan_lcdm_hbar (Driver * drvthis, int x, int y, int len, int promille, int optio */ PrivateData *p = drvthis->private_data; - tyan_lcdm_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)); + tyan_lcdm_set_char(drvthis, i, hBar); + } + } lib_hbar_static(drvthis, x, y, len, promille, options, p->cellwidth, 0); } @@ -572,55 +430,75 @@ tyan_lcdm_hbar (Driver * drvthis, int x, int y, int len, int promille, int optio /* * Writes a big number. - * This is not supported on 633 because we only have 2 lines... */ MODULE_EXPORT void tyan_lcdm_num (Driver * drvthis, int x, int num) { - //PrivateData *p = drvthis->private_data; -/* - char out[5]; + PrivateData *p = drvthis->private_data; + int do_init = 0; - snprintf(out, sizeof(out), "%c%c%c", 28, x, num); - write(fd, out, 3); -*/ + if ((num < 0) || (num > 10)) + return; + + 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; + } + + // Lib_adv_bignum does everything needed to show the bignumbers. + lib_adv_bignum(drvthis, x, num, do_init, NUM_CCs); } + /* - * Sets a custom character from 0-7... + * Gets number of custom chars (always NUM_CCs) + */ +MODULE_EXPORT int +tyan_lcdm_get_free_chars(Driver *drvthis) +{ +//PrivateData *p = drvthis->private_data; + + return NUM_CCs; +} + + +/* + * Sets a custom character from 0 - (NUM_CCs-1)... * - * For input, values > 0 mean "on" and values <= 0 are "off". - * - * The input is just an array of characters... + * The input is an array of bytes, each representing a pixel row + * starting from the top to bottom. + * The bits in each byte represent the pixels where the LSB + * (least significant bit) is the rightmost pixel in each pixel row */ MODULE_EXPORT void -tyan_lcdm_set_char (Driver * drvthis, int n, char *dat) +tyan_lcdm_set_char (Driver * drvthis, int n, unsigned char *dat) { PrivateData *p = drvthis->private_data; - unsigned char out[8]; - int row, col; + unsigned char mask = (1 << p->cellwidth) - 1; + unsigned char out[p->cellheight + 1]; + int row; - if ((n < 0) || (n > 7)) + if ((n < 0) || (n >= NUM_CCs)) return; - if (!dat) + if (dat == NULL) return; for (row = 0; row < p->cellheight; row++) { - int letter = 0; + int 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; - for (col = 0; col < p->cellwidth; col++) { - letter <<= 1; - letter |= (dat[(row * p->cellwidth) + col] > 0); - /* I should remove that debug code. */ - //if (dat[(row * cellheight) + col] == 0) printf("."); - //if (dat[(row * cellheight) + col] == 1) printf("+"); - //if (dat[(row * cellheight) + col] == 2) printf("x"); - //if (dat[(row * cellheight) + col] == 3) printf("*"); - //printf("'%1d'", dat[(row * cellwidth) + col]); - //printf("%3d ", letter); - } out[row+1] = letter; - //printf(": %d\n", letter); } tyan_lcdm_write_str(p->fd, out, (unsigned char) (0x40 + n * 8), 8); } @@ -632,120 +510,151 @@ MODULE_EXPORT int tyan_lcdm_icon (Driver * drvthis, int x, int y, int icon) { PrivateData *p = drvthis->private_data; - char icons[8][5 * 8] = { - /* Empty Heart */ - { - 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, - }, - /* Filled Heart */ - { - 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, - }, - /* 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, - }, - /* 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, - }, - /* 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, - }, - /* 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, - }, - /* 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, - }, - /* Ellipsis */ - { - 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, 0, 1, 0, - }, - }; + 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 we know, this is a VERY BAD implementation :-) */ switch (icon) { case ICON_BLOCK_FILLED: tyan_lcdm_chr(drvthis, x, y, 255); - break; - case ICON_HEART_FILLED: - p->custom = cust; - tyan_lcdm_set_char(drvthis, 0, icons[1]); - tyan_lcdm_chr(drvthis, x, y, 0); + //tyan_lcdm_set_char(drvthis, 6, block_filled); + //tyan_lcdm_chr(drvthis, x, y, 0); break; case ICON_HEART_OPEN: - p->custom = cust; - tyan_lcdm_set_char(drvthis, 0, icons[0]); + tyan_lcdm_set_char(drvthis, 0, heart_open); + tyan_lcdm_chr(drvthis, x, y, 0); + break; + case ICON_HEART_FILLED: + tyan_lcdm_set_char(drvthis, 0, heart_filled); tyan_lcdm_chr(drvthis, x, y, 0); break; case ICON_ARROW_UP: - p->custom = cust; - tyan_lcdm_set_char(drvthis, 1, icons[2]); + p->ccmode = custom; + tyan_lcdm_set_char(drvthis, 1, arrow_up); tyan_lcdm_chr(drvthis, x, y, 1); break; case ICON_ARROW_DOWN: - p->custom = cust; - tyan_lcdm_set_char(drvthis, 2, icons[3]); + p->ccmode = custom; + tyan_lcdm_set_char(drvthis, 2, arrow_down); tyan_lcdm_chr(drvthis, x, y, 2); break; case ICON_ARROW_LEFT: @@ -755,18 +664,18 @@ tyan_lcdm_icon (Driver * drvthis, int x, int y, int icon) tyan_lcdm_chr(drvthis, x, y, 0x7E); break; case ICON_CHECKBOX_OFF: - p->custom = cust; - tyan_lcdm_set_char(drvthis, 3, icons[4]); + p->ccmode = custom; + tyan_lcdm_set_char(drvthis, 3, checkbox_off); tyan_lcdm_chr(drvthis, x, y, 3); break; case ICON_CHECKBOX_ON: - p->custom = cust; - tyan_lcdm_set_char(drvthis, 4, icons[5]); + p->ccmode = custom; + tyan_lcdm_set_char(drvthis, 4, checkbox_on); tyan_lcdm_chr(drvthis, x, y, 4); break; case ICON_CHECKBOX_GRAY: - p->custom = cust; - tyan_lcdm_set_char(drvthis, 5, icons[6]); + p->ccmode = custom; + tyan_lcdm_set_char(drvthis, 5, checkbox_gray); tyan_lcdm_chr(drvthis, x, y, 5); break; default: @@ -775,6 +684,7 @@ tyan_lcdm_icon (Driver * drvthis, int x, int y, int icon) return 0; } + /* * Clears the LCD screen */ @@ -786,6 +696,7 @@ tyan_lcdm_clear (Driver * drvthis) memset(p->framebuf, ' ', p->width * p->height); } + /* * Prints a string on the lcd display, at position (x,y). The * upper-left is (1,1), and the lower right should be (16,2). @@ -872,6 +783,7 @@ void tyan_lcdm_write_str(int fd, unsigned char *str,unsigned char start_addr, in write(fd, cmd_str, 20); } + #if 0 static void tyan_lcdm_set_cursor(int fd, unsigned char start_addr, int pos) @@ -883,6 +795,7 @@ void tyan_lcdm_set_cursor(int fd, unsigned char start_addr, int pos) } #endif + static unsigned char tyan_lcdm_read_key(int fd) { @@ -899,3 +812,4 @@ unsigned char tyan_lcdm_read_key(int fd) } return 0xF4; //error } + diff --git a/server/drivers/tyan_lcdm.h b/server/drivers/tyan_lcdm.h index e4f9a97..84acf12 100644 --- a/server/drivers/tyan_lcdm.h +++ b/server/drivers/tyan_lcdm.h @@ -22,16 +22,74 @@ #include "lcd.h" -#define DEFAULT_CELL_WIDTH 5 -#define DEFAULT_CELL_HEIGHT 8 -#define DEFAULT_DEVICE "/dev/lcd" -#define DEFAULT_SPEED 9600 -#define DEFAULT_SIZE "16x2" +#define DEFAULT_CELL_WIDTH 5 +#define DEFAULT_CELL_HEIGHT 8 +#define DEFAULT_DEVICE "/dev/lcd" +#define DEFAULT_SPEED 9600 +#define DEFAULT_SIZE "16x2" +#define TYAN_LCDM_KEY_ENTER 0xF2 +#define TYAN_LCDM_KEY_ESCAPE 0xF3 +#define TYAN_LCDM_KEY_RIGHT 0xF5 +#define TYAN_LCDM_KEY_LEFT 0xF6 +#define TYAN_LCDM_KEY_UP 0xF7 +#define TYAN_LCDM_KEY_DOWN 0xF8 + +#define TYAN_LCDM_CMD_BEGIN 0xF1 +#define TYAN_LCDM_CMD_END 0xF2 + + +/* Constants for userdefchar_mode */ +#define NUM_CCs 8 /* max. number of custom characters */ + +typedef enum { + standard, /* only char 0 is used for heartbeat */ + vbar, /* vertical bars */ + hbar, /* horizontaln bars */ + bignum, /* big numbers */ + bigchar, /* big characters */ + custom /* custom icons */ +} CGmode; + + +typedef struct cgram_cache { + unsigned char cache[LCD_DEFAULT_CELLHEIGHT]; + int clean; +} CGram; + + +typedef struct driver_private_data { + char device[200]; + int speed; + int fd; + + unsigned char *framebuf; + unsigned char *backingstore; + + int width; + int height; + int cellwidth; + int cellheight; + + /* defineable characters */ + CGram cc[NUM_CCs]; + CGmode ccmode; +} PrivateData; + + +/* API: variables for the server core */ +MODULE_EXPORT char *api_version = API_VERSION; +MODULE_EXPORT int stay_in_foreground = 0; +MODULE_EXPORT int supports_multiple = 0; +MODULE_EXPORT char *symbol_prefix = "tyan_lcdm_"; + +/* API: functions for the server core */ MODULE_EXPORT int tyan_lcdm_init (Driver * drvthis, char *device); MODULE_EXPORT void tyan_lcdm_close (Driver * drvthis); MODULE_EXPORT int tyan_lcdm_width (Driver * drvthis); MODULE_EXPORT int tyan_lcdm_height (Driver * drvthis); +MODULE_EXPORT int tyan_lcdm_cellwidth (Driver * drvthis); +MODULE_EXPORT int tyan_lcdm_cellheight (Driver * drvthis); MODULE_EXPORT void tyan_lcdm_clear (Driver * drvthis); MODULE_EXPORT void tyan_lcdm_flush (Driver * drvthis); MODULE_EXPORT void tyan_lcdm_string (Driver * drvthis, int x, int y, char string[]); @@ -42,7 +100,8 @@ MODULE_EXPORT void tyan_lcdm_hbar (Driver * drvthis, int x, int y, int len, int MODULE_EXPORT void tyan_lcdm_num (Driver * drvthis, int x, int num); MODULE_EXPORT int tyan_lcdm_icon(Driver * drvthis, int x, int y, int icon); -MODULE_EXPORT void tyan_lcdm_set_char (Driver * drvthis, int n, char *dat); +MODULE_EXPORT int tyan_lcdm_get_free_chars (Driver *drvthis); +MODULE_EXPORT void tyan_lcdm_set_char (Driver * drvthis, int n, unsigned char *dat); MODULE_EXPORT void tyan_lcdm_backlight (Driver * drvthis, int on);