From 4d73e6660c8d29a096337e5a1db471d35b422f65 Mon Sep 17 00:00:00 2001 From: mmdolze Date: Sun, 13 Feb 2011 17:50:29 +0000 Subject: [PATCH] Pyramid driver: - Convert set_char to 8 byte bitmap. - Reset ccmode on clear. Add a custom character cache to avoid unnecessary updates of custom characters because of the reset. - Add support for bignum. - Remove the FB_modified flag, it did never work. Instead add a backing store buffer to compare against. Remove the 40ms block of updates, this was a no-op as well. However, pause 40ms after sending a complete screen update. The display I have requires this to recognize the following cursor updates. - Do not treat frame buffer as string. Always use memcpy, memcmp, and memset. - Remove the changelog. This should be read from SCM. - Remove contact info as T. Riewe has left Pyramid. - Pass through indent, preserving 4 space indention. --- ChangeLog | 1 + server/drivers/Makefile.am | 2 +- server/drivers/pylcd.c | 1190 ++++++++++++++++-------------------- server/drivers/pylcd.h | 102 ++-- 4 files changed, 577 insertions(+), 718 deletions(-) diff --git a/ChangeLog b/ChangeLog index 69200e3..845bf6e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -21,6 +21,7 @@ v.0.5dev (ongoing development) * Pyramid: Only send LED state changes, doxygen-ize * sed1520: Make it work with 68-family style interface, convert to 0.5 API * hd44780/imon: Add charmap for NEC uPD16314 and make it configurable + * Pyramid: Convert set_char to 8 byte bitmap, add support for bignum v0.5.4 * Update driver includes and LDFLAGS (fixed glk and bayrad binding error) diff --git a/server/drivers/Makefile.am b/server/drivers/Makefile.am index 6dc52b7..245bc3a 100644 --- a/server/drivers/Makefile.am +++ b/server/drivers/Makefile.am @@ -60,7 +60,7 @@ MtxOrb_LDADD = libLCD.a libbignum.a mx5000_LDADD = @LIBMX5000@ NoritakeVFD_LDADD = libbignum.a picolcd_LDADD = @LIBUSB_LIBS@ libLCD.a libbignum.a -pyramid_LDADD = libLCD.a +pyramid_LDADD = libLCD.a libbignum.a serialPOS_LDADD = libbignum.a serialVFD_LDADD = libLCD.a libbignum.a shuttleVFD_LDADD = @LIBUSB_LIBS@ diff --git a/server/drivers/pylcd.c b/server/drivers/pylcd.c index 5d2ce3e..116bd11 100644 --- a/server/drivers/pylcd.c +++ b/server/drivers/pylcd.c @@ -4,54 +4,25 @@ * * For more information see * https://www.pyramid.de/de/hardware/spezialkomponenten.php + */ + +/*- + * Copyright (C) 2005 Silvan Marco Fin + * 2006 coresystems GmbH * - * Contact Thomas Riewe for further - * information on the LCD. - */ - -/* - - Copyright (C) 2005 Silvan Marco Fin - Copyright (C) 2006 coresystems GmbH - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - - */ - -/* - * Changes: - * 2006-02-20 Stefan Reinauer - * - add support for onboard LEDs via "output" command - * 2006-04-12 Stefan Reinauer - * - add support for user-defined characters (set_char/get_free_chars) - * - add support for vbars/hbars, get_info, reorganize pyramid_init() - * - fixed a timing bug and implemented escaping in (real_)send_tele() - * 2006-04-18 Stefan Reinauer - * - support combined key events - * - add more custom characters - * - fix german umlauts - * - fix cursor handling - * 2011-01-29 Markus Dolze - * - fix string overflow in set_leds - * - fix several possible buffer overflows - * - correct escaping for characters 128-255 (also fixes the 'ß' issue) - * - correct icons (custom chars 8-15 cannot be set, checkboxes were wrong) - * - Add a delay after set_char. This seems to fix occasional hangs - * - Cache status of LEDs and only send on update, reduces communication - * - Add prototypes for all and Doxygen comments to internal functions - * - remove unused read_ACK() + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 */ #include @@ -76,11 +47,11 @@ #include "pylcd.h" #include "lcd_lib.h" #include "report.h" +#include "adv_bignum.h" #define True 1 #define False 0 - #define MICROTIMEOUT 50000 /* Timeout for select() */ #define NOKEY "00000" @@ -92,7 +63,6 @@ MODULE_EXPORT int supports_multiple = 0; MODULE_EXPORT char *symbol_prefix = "pyramid_"; /* Prototypes: */ - static int data_ready(PrivateData *p); static int read_tele(PrivateData *p, char *buffer); static int real_send_tele(PrivateData *p, char *buffer, int len); @@ -112,7 +82,7 @@ data_ready(PrivateData *p) { FD_ZERO(&p->rdfs); FD_SET(p->FD, &p->rdfs); - return select(p->FD+1, &p->rdfs, NULL, NULL, &p->timeout)>0; + return select(p->FD + 1, &p->rdfs, NULL, NULL, &p->timeout) > 0; } @@ -128,36 +98,35 @@ data_ready(PrivateData *p) static int read_tele(PrivateData *p, char *buffer) { - char zeichen=0; - int len=0; - char cc=0x00; + char zeichen = 0; + int len = 0; + char cc = 0x00; /* Try to find STX within first 10 chars */ while (data_ready(p) - && (read(p->FD, &zeichen, 1)>0) - && (zeichen!=0x02) - && (lenFD, &zeichen, 1) > 0) + && (zeichen != 0x02) + && (len < MAXCOUNT)) + len++; /* If no STX available, set buffer all zero and return */ - if (zeichen!=0x02) - { - memset(buffer, 0, MAXCOUNT); - return False; + if (zeichen != 0x02) { + memset(buffer, 0, MAXCOUNT); + return False; } /* Now start reading until ETX */ cc ^= zeichen; - len=0; + len = 0; while (data_ready(p) - && (read(p->FD, &zeichen, 1)>0) - && (lenFD, &zeichen, 1) > 0) + && (len < MAXCOUNT)) { + buffer[len] = zeichen; + cc ^= zeichen; + if (zeichen == 0x03) + break; /* break before len++! */ + len++; } /* @@ -167,17 +136,15 @@ read_tele(PrivateData *p, char *buffer) * read data) and return. */ if (data_ready(p) - && (read(p->FD, &zeichen, 1)>0) - && (buffer[len]==0x03) - && (zeichen==cc)) - { - buffer[len]=0x00; - return True; + && (read(p->FD, &zeichen, 1) > 0) + && (buffer[len] == 0x03) + && (zeichen == cc)) { + buffer[len] = 0x00; + return True; } - else - { - memset(buffer, 0, MAXCOUNT); - return False; + else { + memset(buffer, 0, MAXCOUNT); + return False; } } @@ -198,34 +165,36 @@ read_tele(PrivateData *p, char *buffer) static int real_send_tele(PrivateData *p, char *buffer, int len) { - char cc=0x00; + char cc = 0x00; int i, j; char buffer2[255]; - i=0; j=0; - buffer2[j++]=2; /* emit */ + i = 0; + j = 0; + buffer2[j++] = 0x02; /* emit */ /* - * copy the whole telegram package and escape characters below 0x20. - * ie. 0x8 --> 0x28. + * copy the whole telegram package and escape characters below 0x20. ie. + * 0x8 --> 0x28. */ while (len-- && j < 253) { - if (buffer[i]>=0x00 && buffer[i]<0x20) { - buffer2[j++]=0x1b; - buffer2[j++]=buffer[i++]+0x20; - } else { - buffer2[j++]=buffer[i++]; - } + if (buffer[i] >= 0x00 && buffer[i] < 0x20) { + buffer2[j++] = 0x1b; + buffer2[j++] = buffer[i++] + 0x20; + } + else { + buffer2[j++] = buffer[i++]; + } } - buffer2[j++]=3; /* emit */ - len=j; /* new package length */ + buffer2[j++] = 0x03; /* emit */ + len = j; /* new package length */ /* calculate over all bytes */ - for (i=0; iFD, buffer2, len); @@ -266,7 +235,7 @@ timestamp(PrivateData *p) struct timeval tv; gettimeofday(&tv, NULL); - return (unsigned long long)tv.tv_sec*1000000+(unsigned long long)tv.tv_usec; + return (unsigned long long)tv.tv_sec * 1000000 + (unsigned long long)tv.tv_usec; } @@ -282,32 +251,29 @@ initTTY(Driver *drvthis, int FD) struct termios tty_mode; if (tcgetattr(FD, &tty_mode) == 0) { - cfmakeraw(&tty_mode); -#ifdef CBAUDEX /* CBAUDEX not defined in FreeBSD */ - tty_mode.c_cflag |= CBAUDEX; + cfmakeraw(&tty_mode); +#ifdef CBAUDEX /* CBAUDEX not defined in FreeBSD */ + tty_mode.c_cflag |= CBAUDEX; #endif - cfsetospeed(&tty_mode, B115200); - cfsetispeed(&tty_mode, 0); - tty_mode.c_cc[VMIN] = 1; - tty_mode.c_cc[VTIME] = 1; + cfsetospeed(&tty_mode, B115200); + cfsetispeed(&tty_mode, 0); + tty_mode.c_cc[VMIN] = 1; + tty_mode.c_cc[VTIME] = 1; - if (tcsetattr(FD, TCSANOW, &tty_mode) != 0) { - report(RPT_ERR, "%s: setting TTY failed: %s", drvthis->name, strerror(errno)); - return -1; - } - } else { - report(RPT_ERR, "%s: reading TTY failed: %s", drvthis->name, strerror(errno)); - return -1; + if (tcsetattr(FD, TCSANOW, &tty_mode) != 0) { + report(RPT_ERR, "%s: setting TTY failed: %s", drvthis->name, strerror(errno)); + return -1; + } + } + else { + report(RPT_ERR, "%s: reading TTY failed: %s", drvthis->name, strerror(errno)); + return -1; } return 0; } -/* Driver functions according to current API-Version */ - -/* Basic functions */ - /** * Initialize the driver. * \param drvthis Pointer to driver structure. @@ -315,46 +281,43 @@ initTTY(Driver *drvthis, int FD) * \retval <0 Error. */ MODULE_EXPORT int -pyramid_init (Driver *drvthis) +pyramid_init(Driver *drvthis) { char buffer[MAXCOUNT]; int i; PrivateData *p; /* get memory for private data */ - p = (PrivateData *) malloc(sizeof(PrivateData)); - if ((p == NULL) || (drvthis->store_private_ptr(drvthis, p) < 0)) - { - report(RPT_ERR, "%s: error allocating memory for modules private data", drvthis->name); - return -1; + if ((p == NULL) || (drvthis->store_private_ptr(drvthis, p) < 0)) { + report(RPT_ERR, "%s: error allocating memory for modules private data", drvthis->name); + return -1; } - /* fill static elements of private data */ + /* initialize elements of private data */ p->width = WIDTH; p->height = HEIGHT; - p->customchars=CUSTOMCHARS; - p->cellwidth=CELLWIDTH; - p->cellheight=CELLHEIGHT; - p->custom = standard; + p->customchars = CUSTOMCHARS; + p->cellwidth = CELLWIDTH; + p->cellheight = CELLHEIGHT; + p->ccmode = standard; + memset(p->framebuffer, ' ', SCREEN_SIZE); + memset(p->backingstore, ' ', SCREEN_SIZE); strcpy(p->last_key_pressed, NOKEY); p->last_key_time = timestamp(p); - p->last_buf_time = timestamp(p); p->timeout.tv_sec = 0; p->timeout.tv_usec = MICROTIMEOUT; - strcpy(p->framebuffer, "D "); - p->FB_modified = 1; - - /* read config file, fill configuration - * dependent elements of private data + /* + * read config file, fill configuration dependent elements of private + * data */ /* Which serial device should be used? */ strncpy(p->device, drvthis->config_get_string(drvthis->name, "Device", 0, "/dev/lcd"), sizeof(p->device)); - p->device[sizeof(p->device)-1] = '\0'; + p->device[sizeof(p->device) - 1] = '\0'; report(RPT_INFO, "%s: using Device %s", drvthis->name, p->device); /* Initialize connection to the LCD */ @@ -363,30 +326,28 @@ pyramid_init (Driver *drvthis) p->FD = open(p->device, O_RDWR); if (p->FD == -1) { - report(RPT_ERR, "%s: open(%s) failed: %s", drvthis->name, p->device, strerror(errno)); - return -1; + report(RPT_ERR, "%s: open(%s) failed: %s", drvthis->name, p->device, strerror(errno)); + return -1; } if (initTTY(drvthis, p->FD) != 0) - return -1; + return -1; - /* Acknowledge all telegramms, the device may yet be sending. + /* + * Acknowledge all telegramms, the device may yet be sending. * (Reset doesn't clear telegramms, darn protocol ... ) */ - - tcflush(p->FD, TCIFLUSH); /* clear everything */ - + tcflush(p->FD, TCIFLUSH); /* clear port buffer */ while (1) { - i = read_tele(p, buffer); - if (i == True) - send_ACK(p); - else - break; - usleep(600000); + i = read_tele(p, buffer); + if (i == True) + send_ACK(p); + else + break; + usleep(600000); } /* Initialize the display hardware: reset, clear and set cursor shape */ - send_tele(p, "R"); send_tele(p, "C0101"); send_tele(p, "D "); @@ -397,7 +358,7 @@ pyramid_init (Driver *drvthis) for (i = 0; i < 7; i++) p->led[i] = -1; /* hardware selftest + clear all LEDs */ - pyramid_output(drvthis, 0); /* needed, otherwise L11 won't work */ + pyramid_output(drvthis, 0); /* needed, otherwise L11 won't work */ for (i = 0; i < 7; i++) { pyramid_output(drvthis, 1 << i); usleep(10000); @@ -419,7 +380,7 @@ pyramid_init (Driver *drvthis) * \param drvthis Pointer to driver structure. */ MODULE_EXPORT void -pyramid_close (Driver *drvthis) +pyramid_close(Driver *drvthis) { PrivateData *p = (PrivateData *) drvthis->private_data; @@ -437,7 +398,7 @@ pyramid_close (Driver *drvthis) * \return Number of characters the display is wide. */ MODULE_EXPORT int -pyramid_width (Driver *drvthis) +pyramid_width(Driver *drvthis) { PrivateData *p = (PrivateData *) drvthis->private_data; @@ -451,7 +412,7 @@ pyramid_width (Driver *drvthis) * \return Number of characters the display is high. */ MODULE_EXPORT int -pyramid_height (Driver *drvthis) +pyramid_height(Driver *drvthis) { PrivateData *p = (PrivateData *) drvthis->private_data; @@ -464,61 +425,75 @@ pyramid_height (Driver *drvthis) * \param drvthis Pointer to driver structure. */ MODULE_EXPORT void -pyramid_clear (Driver *drvthis) +pyramid_clear(Driver *drvthis) { PrivateData *p = (PrivateData *) drvthis->private_data; - p->FB_modified=1; - strcpy(p->framebuffer, "D "); + memset(p->framebuffer, ' ', SCREEN_SIZE); + p->ccmode = standard; } /** - * Flush data on screen to the display. - * p->FB_modified tells if the content was modified. If not, - * that means, nothing has to be done + * Flush data on screen to the display. Compares the current frame buffer + * contents with the stored backing store. Send complete screen content if + * they are different. * \param drvthis Pointer to driver structure. */ MODULE_EXPORT void -pyramid_flush (Driver *drvthis) +pyramid_flush(Driver *drvthis) { static char mesg[33]; PrivateData *p = (PrivateData *) drvthis->private_data; - unsigned long long current_time=timestamp(p); int i; - /* Updates only once every 40 ms */ - if ((p->FB_modified==True) && (current_time>(p->last_buf_time+40000))) - { - memcpy(mesg, p->framebuffer, 33); + if (memcmp(p->framebuffer, p->backingstore, SCREEN_SIZE)) { + memcpy(p->backingstore, p->framebuffer, SCREEN_SIZE); + + /* Prepare send buffer */ + mesg[0] = 'D'; + memcpy(mesg + 1, p->framebuffer, SCREEN_SIZE); /* * we got the japanese HD44780U, so convert the german umlauts and * other stuff, assuming input is iso_8859-1. */ - for (i=1; i<33; i++) { - switch ((unsigned char)mesg[i]) { - case 0xe4: mesg[i]=0xe1; break; /* ä */ - case 0xf6: mesg[i]=0xef; break; /* ö */ - case 0xfc: mesg[i]=0xf5; break; /* ü */ - case 0xdf: mesg[i]=0xe2; break; /* ß */ - case 0xb7: mesg[i]=0xa5; break; /* · */ - case 0xb0: mesg[i]=0xdf; break; /* ° */ - } + for (i = 1; i < 33; i++) { + switch ((unsigned char)mesg[i]) { + case 0xe4: /* ä */ + mesg[i] = 0xe1; + break; + case 0xf6: /* ö */ + mesg[i] = 0xef; + break; + case 0xfc: /* ü */ + mesg[i] = 0xf5; + break; + case 0xdf: /* ß */ + mesg[i] = 0xe2; + break; + case 0xb7: /* · */ + mesg[i] = 0xa5; + break; + case 0xb0: /* ° */ + mesg[i] = 0xdf; + break; + } } /* We do not wait for the ACK here, these are read by get_key() */ - send_tele(p, "C0101"); - real_send_tele(p, mesg, 33); - p->FB_modified=False; - p->last_buf_time=current_time; + send_tele(p, "C0101"); + real_send_tele(p, mesg, 33); - /* Set cursor */ - sprintf(mesg, "C%02d%02d", p->C_x, p->C_y); - real_send_tele(p, mesg,5); - sprintf(mesg, "M%d", p->C_state); - real_send_tele(p, mesg,2); + /* Minimum execution time 40ms */ + usleep(40000); } + + /* Set cursor */ + sprintf(mesg, "C%02d%02d", p->C_x, p->C_y); + real_send_tele(p, mesg, 5); + sprintf(mesg, "M%d", p->C_state); + real_send_tele(p, mesg, 2); } @@ -531,17 +506,16 @@ pyramid_flush (Driver *drvthis) * \param string String that gets written. */ MODULE_EXPORT void -pyramid_string (Driver *drvthis, int x, int y, const char string[]) +pyramid_string(Driver *drvthis, int x, int y, const char string[]) { int offset; int len; PrivateData *p = (PrivateData *) drvthis->private_data; - p->FB_modified = True; x = min(p->width, x); y = min(p->height, y); - offset = (x)+p->width*(y-1); - len = min(strlen(string), p->width*p->height-offset+1); + offset = (x - 1) + p->width * (y - 1); + len = min(strlen(string), p->width * p->height - offset + 1); memcpy(&p->framebuffer[offset], string, len); } @@ -555,58 +529,58 @@ pyramid_string (Driver *drvthis, int x, int y, const char string[]) * \param c Character that gets written. */ MODULE_EXPORT void -pyramid_chr (Driver *drvthis, int x, int y, char c) +pyramid_chr(Driver *drvthis, int x, int y, char c) { PrivateData *p = (PrivateData *) drvthis->private_data; - p->FB_modified = True; x = min(p->width, x); y = min(p->height, y); - p->framebuffer[x+p->width*(y-1)]=c; + p->framebuffer[(x - 1) + p->width * (y - 1)] = c; } -/* User defined characters */ - /** * Define a custom character and write it to the LCD. * \param drvthis Pointer to driver structure. * \param n Custom character to define [0 - (NUM_CCs-1)]. - * \param dat Array of 40(=8*5=cellheight*cellwidth) bytes, each representing a pixel - * starting from the top left to the bottom right. + * \param dat Array of 8 (= cellheight) bytes, each representing a row in + * CGRAM starting from the top. The five rightmost bits in + * each byte represent the pixels in that row. */ -MODULE_EXPORT void pyramid_set_char (Driver *drvthis, int n, char *dat) +MODULE_EXPORT void +pyramid_set_char(Driver *drvthis, int n, unsigned char *dat) { - char tele[10] = "G@ABCDEFGH"; - int row, column, pixels; + char tele[10] = "G@ABCDEFGH"; + int row, pixels; + PrivateData *p = (PrivateData *) drvthis->private_data; + unsigned char mask = (1 << p->cellwidth) - 1; - PrivateData *p = (PrivateData *) drvthis->private_data; + if (n < 0 && n > 7) { + debug(RPT_WARNING, "only characters 0-7 can be changed"); + return; + } - if (n<0 && n>7) { - debug(RPT_WARNING, "only characters 0-7 can be changed"); - return; - } + if (!dat) { + debug(RPT_WARNING, "no character data"); + return; + } - if (!dat) { - debug(RPT_WARNING, "no character data"); - return; - } + if (memcmp(dat, p->cc_cache[n], CELLHEIGHT)) { + memcpy(p->cc_cache[n], dat, CELLHEIGHT); /* which character? */ - tele[1]=n+0x40; + tele[1] = n + 0x40; for (row = 0; row < p->cellheight; row++) { - pixels=0; - for (column = 0; column < p->cellwidth; column++) { - pixels <<= 1; - pixels |= (dat[(row * p->cellwidth) + column] != 0); - } - /* pixel information is transferred with an offset of 40h */ - pixels |= 0x40; - tele[row+2]=pixels; + pixels = dat[row] & mask; + + /* pixel information is transferred with an offset of 40h */ + pixels |= 0x40; + tele[row + 2] = pixels; } - real_send_tele(p, tele, 10); - usleep(50); /* extra delay required for processing this */ + real_send_tele(p, tele, 10); + usleep(200); /* extra delay required for processing this */ + } } @@ -615,10 +589,11 @@ MODULE_EXPORT void pyramid_set_char (Driver *drvthis, int n, char *dat) * \param drvthis Pointer to driver structure. * \return Number of custom characters. */ -MODULE_EXPORT int pyramid_get_free_chars (Driver *drvthis) +MODULE_EXPORT int +pyramid_get_free_chars(Driver *drvthis) { - PrivateData *p = (PrivateData *) drvthis->private_data; - return (p->customchars); + PrivateData *p = (PrivateData *) drvthis->private_data; + return (p->customchars); } @@ -627,10 +602,11 @@ MODULE_EXPORT int pyramid_get_free_chars (Driver *drvthis) * \param drvthis Pointer to driver structure. * \return Number of pixel columns a character cell is wide. */ -MODULE_EXPORT int pyramid_cellwidth (Driver *drvthis) +MODULE_EXPORT int +pyramid_cellwidth(Driver *drvthis) { - PrivateData *p = (PrivateData *) drvthis->private_data; - return (p->cellwidth); + PrivateData *p = (PrivateData *) drvthis->private_data; + return (p->cellwidth); } @@ -639,235 +615,74 @@ MODULE_EXPORT int pyramid_cellwidth (Driver *drvthis) * \param drvthis Pointer to driver structure. * \return Number of pixel lines a character cell is high. */ -MODULE_EXPORT int pyramid_cellheight (Driver *drvthis) +MODULE_EXPORT int +pyramid_cellheight(Driver *drvthis) { - PrivateData *p = (PrivateData *) drvthis->private_data; - return (p->cellheight); + PrivateData *p = (PrivateData *) drvthis->private_data; + return (p->cellheight); } - -/** - * Set up vertical bars. - * \param drvthis Pointer to driver structure. - */ -static void -pyramid_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->custom != vbar) { - pyramid_set_char (drvthis, 1, a); - pyramid_set_char (drvthis, 2, b); - pyramid_set_char (drvthis, 3, c); - pyramid_set_char (drvthis, 4, d); - pyramid_set_char (drvthis, 5, e); - pyramid_set_char (drvthis, 6, f); - pyramid_set_char (drvthis, 7, g); - p->custom = vbar; - } -} - - -/** - * Set up horizontal bars. - * \param drvthis Pointer to driver structure. - */ -static void -pyramid_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, 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) { - pyramid_set_char (drvthis, 1, a); - pyramid_set_char (drvthis, 2, b); - pyramid_set_char (drvthis, 3, c); - pyramid_set_char (drvthis, 4, d); - pyramid_set_char (drvthis, 5, e); - p->custom = hbar; - } -} - /** * Defines some custom characters. * These characters are enabled if the value 0x100 is sent to the \c output command. * \param drvthis Pointer to driver structure. */ static void -pyramid_init_custom1 (Driver *drvthis) +pyramid_init_custom1(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, 1, 1, 1, 1, - 0, 1, 1, 1, 1, - 0, 1, 1, 1, 1, - 0, 1, 1, 1, 1, - 0, 1, 1, 1, 1, - }; + PrivateData *p = (PrivateData *) drvthis->private_data; + static unsigned char a[] = { + b_______, + b_______, + b_______, + b___XXXX, + b___XXXX, + b___XXXX, + b___XXXX, + b___XXXX + }; - char b[] = { - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, - 1, 1, 1, 1, 0, - 1, 1, 1, 0, 0, - 1, 1, 0, 0, 0, - 1, 0, 0, 0, 0, - }; + static unsigned char b[] = { + b_______, + b_______, + b_______, + b__XXXXX, + b__XXXX_, + b__XXX__, + b__XX___, + b__X____, + }; - char c[] = { - 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, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - }; + static unsigned char c[] = { + b___XXXX, + b___XXXX, + b___XXXX, + b___XXXX, + b___XXXX, + b_______, + b_______, + b_______ + }; - char d[] = { - 1, 0, 0, 0, 0, - 1, 1, 0, 0, 0, - 1, 1, 1, 0, 0, - 1, 1, 1, 1, 0, - 1, 1, 1, 1, 1, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - }; + static unsigned char d[] = { + b__X____, + b__XX___, + b__XXX__, + b__XXXX_, + b__XXXXX, + b_______, + b_______, + b_______ + }; - if (p->custom != custom) { - pyramid_set_char (drvthis, 1, a); - pyramid_set_char (drvthis, 2, b); - pyramid_set_char (drvthis, 3, c); - pyramid_set_char (drvthis, 4, d); - p->custom = custom; - } + if (p->ccmode != custom) { + pyramid_set_char(drvthis, 1, a); + pyramid_set_char(drvthis, 2, b); + pyramid_set_char(drvthis, 3, c); + pyramid_set_char(drvthis, 4, d); + p->ccmode = custom; + } } @@ -881,13 +696,34 @@ pyramid_init_custom1 (Driver *drvthis) * \param options Options (currently unused). */ MODULE_EXPORT void -pyramid_vbar (Driver *drvthis, int x, int y, int len, int promille, int options) +pyramid_vbar(Driver *drvthis, int x, int y, int len, int promille, int options) { - PrivateData *p = (PrivateData *) drvthis->private_data; + PrivateData *p = (PrivateData *) drvthis->private_data; + static unsigned char vBars[7][8] = { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x1F}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x1F, 0x1F}, + {0x00, 0x00, 0x00, 0x00, 0x1F, 0x1F, 0x1F, 0x1F}, + {0x00, 0x00, 0x00, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F}, + {0x00, 0x00, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F}, + {0x00, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F}, + }; - pyramid_init_vbar(drvthis); + if (p->ccmode != vbar) { + int i; - lib_vbar_static(drvthis, x, y, len, promille, options, p->cellheight, 0); + if (p->ccmode != standard) { + report(RPT_WARNING, "%s: vbar: cannot combine two modes using user-defined characters", + drvthis->name); + return; + } + + for (i = 0; i < 7; i++) + pyramid_set_char(drvthis, i + 1, vBars[i]); + p->ccmode = vbar; + } + + lib_vbar_static(drvthis, x, y, len, promille, options, p->cellheight, 0); } @@ -901,13 +737,31 @@ pyramid_vbar (Driver *drvthis, int x, int y, int len, int promille, int options) * \param options Options (currently unused). */ MODULE_EXPORT void -pyramid_hbar (Driver *drvthis, int x, int y, int len, int promille, int options) +pyramid_hbar(Driver *drvthis, int x, int y, int len, int promille, int options) { - PrivateData *p = (PrivateData *) drvthis->private_data; + PrivateData *p = (PrivateData *) drvthis->private_data; + static unsigned char hBars[4][8] = { + {0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10}, + {0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18}, + {0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C}, + {0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E}, + }; - pyramid_init_hbar(drvthis); + if (p->ccmode != hbar) { + int i; - lib_hbar_static(drvthis, x, y, len, promille, options, p->cellwidth, 0); + if (p->ccmode != standard) { + report(RPT_WARNING, "%s: hbar: cannot combine two modes using user-defined characters", + drvthis->name); + return; + } + + for (i = 0; i < 4; i++) + pyramid_set_char(drvthis, i + 1, hBars[i]); + p->ccmode = hbar; + } + + lib_hbar_static(drvthis, x, y, len, promille, options, p->cellwidth, 0); } @@ -921,198 +775,214 @@ pyramid_hbar (Driver *drvthis, int x, int y, int len, int promille, int options) * \retval <0 Server core shall define/write the icon. */ MODULE_EXPORT int -pyramid_icon (Driver *drvthis, int x, int y, int icon) +pyramid_icon(Driver *drvthis, int x, int y, int icon) { - char icons[8][5 * 8] = { - { - 1, 1, 1, 1, 1, // Empty Heart - 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, - }, + 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 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 ellipsis[] = { + b_______, + b_______, + b_______, + b_______, + b_______, + b_______, + b__X_X_X, + b_______ + }; - { - 1, 1, 1, 1, 1, // Filled Heart - 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, - }, + switch (icon) { + case ICON_BLOCK_FILLED: + pyramid_chr(drvthis, x, y, 255); + break; - { - 0, 0, 1, 0, 0, // Arrow up - 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, - }, + case ICON_HEART_OPEN: + pyramid_set_char(drvthis, 0, heart_open); + pyramid_chr(drvthis, x, y, 0); + break; - { - 0, 0, 1, 0, 0, // Arrow Down - 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, - }, + case ICON_HEART_FILLED: + pyramid_set_char(drvthis, 0, heart_filled); + pyramid_chr(drvthis, x, y, 0); + break; - { - 0, 0, 0, 0, 0, // Checkbox off - 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, - }, + case ICON_ARROW_UP: + pyramid_set_char(drvthis, 2, arrow_up); + pyramid_chr(drvthis, x, y, 2); + break; - { - 0, 0, 1, 0, 0, // Checkbox on - 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, - }, + case ICON_ARROW_DOWN: + pyramid_set_char(drvthis, 3, arrow_down); + pyramid_chr(drvthis, x, y, 3); + break; - { - 0, 0, 0, 0, 0, // Checkbox gray - 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, - }, + case ICON_ARROW_LEFT: + pyramid_chr(drvthis, x, y, 127); + break; - { - 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, - 1, 0, 1, 0, 1, - }, - }; + case ICON_ARROW_RIGHT: + pyramid_chr(drvthis, x, y, 126); + break; - switch( icon ) { - case ICON_BLOCK_FILLED: - pyramid_chr( drvthis, x, y, 255 ); - break; + case ICON_CHECKBOX_OFF: + pyramid_set_char(drvthis, 4, checkbox_off); + pyramid_chr(drvthis, x, y, 4); + break; - case ICON_HEART_OPEN: - pyramid_set_char( drvthis, 0, icons[0] ); - pyramid_chr( drvthis, x, y, 0 ); - break; + case ICON_CHECKBOX_ON: + pyramid_set_char(drvthis, 5, checkbox_on); + pyramid_chr(drvthis, x, y, 5); + break; - case ICON_HEART_FILLED: - pyramid_set_char( drvthis, 0, icons[1] ); - pyramid_chr( drvthis, x, y, 0 ); - break; + case ICON_CHECKBOX_GRAY: + pyramid_set_char(drvthis, 6, checkbox_gray); + pyramid_chr(drvthis, x, y, 6); + break; - case ICON_ARROW_UP: - pyramid_set_char( drvthis, 2, icons[2] ); - pyramid_chr( drvthis, x, y, 2 ); - break; + case ICON_ELLIPSIS: + pyramid_set_char(drvthis, 7, ellipsis); + pyramid_chr(drvthis, x, y, 7); + break; - case ICON_ARROW_DOWN: - pyramid_set_char( drvthis, 3, icons[3] ); - pyramid_chr( drvthis, x, y, 3 ); - break; - - case ICON_ARROW_LEFT: - pyramid_chr( drvthis, x, y, '\177' ); - break; - - case ICON_ARROW_RIGHT: - pyramid_chr( drvthis, x, y, '\176' ); - break; - - case ICON_CHECKBOX_OFF: - pyramid_set_char( drvthis, 4, icons[4] ); - pyramid_chr( drvthis, x, y, 4 ); - break; - - case ICON_CHECKBOX_ON: - pyramid_set_char( drvthis, 5, icons[5] ); - pyramid_chr( drvthis, x, y, 5 ); - break; - - case ICON_CHECKBOX_GRAY: - pyramid_set_char( drvthis, 6, icons[6] ); - pyramid_chr( drvthis, x, y, 6 ); - break; - - case ICON_ELLIPSIS: - pyramid_set_char( drvthis, 7, icons[7] ); - pyramid_chr( drvthis, x, y, 7 ); - break; - - default: - debug(RPT_DEBUG, "%s: x=%d, y=%d, icon=%x", __FUNCTION__, x, y, icon); - return -1; - } - return 0; + default: + debug(RPT_DEBUG, "%s: x=%d, y=%d, icon=%x", __FUNCTION__, x, y, icon); + return -1; + } + return 0; } -/* TODO: Implement this after converting to 8 byte CC. +/** + * API: Draw a big number (0-9 and colon) on the screen. + */ MODULE_EXPORT void -pyramid_num (Driver *drvthis, int x, int num){}; -*/ +pyramid_num(Driver *drvthis, int x, int num) +{ + PrivateData *p = (PrivateData *) drvthis->private_data; + int do_init = 0; + + if ((num < 0) || (num > 10)) + return; + + if (p->ccmode != bignum) { + if (p->ccmode != standard) { + 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(drvthis, x, num, 0, do_init); +}; + /** - * Set cursor position and state. + * Set cursor position and state. Cursor position and state is not immediately + * set, but stored in PrivateData and set on flush. + * * \param drvthis Pointer to driver structure. * \param x Horizontal cursor position (column). * \param y Vertical cursor position (row). * \param state New cursor state. */ MODULE_EXPORT void -pyramid_cursor (Driver *drvthis, int x, int y, int state) +pyramid_cursor(Driver *drvthis, int x, int y, int state) { PrivateData *p = (PrivateData *) drvthis->private_data; p->C_x = x; p->C_y = y; + switch (state) { case CURSOR_OFF: - state=0; + state = 0; break; case CURSOR_DEFAULT_ON: - state=3; + state = 3; break; case CURSOR_UNDER: - state=1; + state = 1; break; case CURSOR_BLOCK: - state=2; + state = 2; break; + default: + report(RPT_WARNING, "%s: Unknown cursor state %d", drvthis->name, state); + state = 0; } p->C_state = state; } -/* Hardware functions */ - /** * Set output port. * Setting an output port bit lights the associated LED; @@ -1121,11 +991,11 @@ pyramid_cursor (Driver *drvthis, int x, int y, int state) * \param state Integer with bits representing port states. */ MODULE_EXPORT void -pyramid_output (Driver *drvthis, int state) +pyramid_output(Driver *drvthis, int state) { PrivateData *p = (PrivateData *) drvthis->private_data; int i; - char tele[]= {"L00"}; + char tele[] = {"L00"}; for (i = 0; i < 7; i++) { if (p->led[i] != (state & (1 << i))) { @@ -1136,15 +1006,13 @@ pyramid_output (Driver *drvthis, int state) } } - if(state & (1 << 8)) { - pyramid_init_custom1(drvthis); + if (state & (1 << 8)) { + pyramid_init_custom1(drvthis); } } -/* Key functions */ - /** * Get key from the device * \param drvthis Pointer to driver structure. @@ -1152,96 +1020,96 @@ pyramid_output (Driver *drvthis, int state) * \c NULL if nothing available / unmapped key. */ MODULE_EXPORT const char * -pyramid_get_key (Driver *drvthis) +pyramid_get_key(Driver *drvthis) { /* supports only one key at a time */ - static char buffer[MAXCOUNT]; /* has to be static to be visible outside this function */ + static char buffer[MAXCOUNT]; /* has to be static to be visible + * outside this function */ unsigned long long current_time; int retval; PrivateData *p = (PrivateData *) drvthis->private_data; - /* Now we read everything from the display, - * and as long as we got ACKs, we ignore them. - * (eat up all pending ACKs) + /* + * Now we read everything from the display, and as long as we got ACKs, + * we ignore them. (eat up all pending ACKs) */ while (1) { - retval = read_tele(p, buffer); - if ((retval == False) || (buffer[0] != 'Q')) break; + retval = read_tele(p, buffer); + if ((retval == False) || (buffer[0] != 'Q')) + break; } if (retval == False) - strcpy(buffer, p->last_key_pressed); + strcpy(buffer, p->last_key_pressed); else - send_ACK(p); + send_ACK(p); /* If a key wasn't released yet it may be released now. */ - if (buffer[0] == 'K') - { - /* test if its a release event */ - if ( (strcmp(buffer, "K0003") == 0) - || (strcmp(buffer, "K0030") == 0) - || (strcmp(buffer, "K0300") == 0) - || (strcmp(buffer, "K3000") == 0)) - { - debug(RPT_DEBUG, "%s: Key released: %s", __FUNCTION__, p->last_key_pressed); - strcpy(p->last_key_pressed, NOKEY); - return NULL; - } - else /* It must be a new key event */ - { - strcpy(p->last_key_pressed, buffer); - debug(RPT_DEBUG, "%s: Key pressed: %s", __FUNCTION__, p->last_key_pressed); - } + if (buffer[0] == 'K') { + /* test if its a release event */ + if ((strcmp(buffer, "K0003") == 0) + || (strcmp(buffer, "K0030") == 0) + || (strcmp(buffer, "K0300") == 0) + || (strcmp(buffer, "K3000") == 0)) { + debug(RPT_DEBUG, "%s: Key released: %s", __FUNCTION__, p->last_key_pressed); + strcpy(p->last_key_pressed, NOKEY); + return NULL; + } + else { /* It must be a new key event */ + strcpy(p->last_key_pressed, buffer); + debug(RPT_DEBUG, "%s: Key pressed: %s", __FUNCTION__, p->last_key_pressed); + } } /* If no keys are pressed at this time, we are done. */ if (p->last_key_pressed[0] == NOKEY[0]) - return NULL; + return NULL; current_time = timestamp(p); - if (current_time > p->last_key_time + 500000) /* New keys only every 0.5 seconds */ - p->last_key_time = current_time; + if (current_time > p->last_key_time + 500000) /* New keys only every + * 0.5 seconds */ + p->last_key_time = current_time; else - return NULL; + return NULL; - if (strcmp(p->last_key_pressed, "K0001") == 0) /* first from left */ - return "Up"; - if (strcmp(p->last_key_pressed, "K0010") == 0) /* second from left */ - return "Down"; - if (strcmp(p->last_key_pressed, "K0100") == 0) /* third from left */ - return "Enter"; - if (strcmp(p->last_key_pressed, "K1000") == 0) /* last from left */ - return "Escape"; + if (strcmp(p->last_key_pressed, "K0001") == 0) /* first from left */ + return "Up"; + if (strcmp(p->last_key_pressed, "K0010") == 0) /* second from left */ + return "Down"; + if (strcmp(p->last_key_pressed, "K0100") == 0) /* third from left */ + return "Enter"; + if (strcmp(p->last_key_pressed, "K1000") == 0) /* last from left */ + return "Escape"; #ifdef PYRAMID_DECODE_COMBINED_KEYPRESSES /* Do we really want to type that much */ - if (strcmp(p->last_key_pressed, "K0012") == 0) /* A+B */ - return "Up+Down"; - if (strcmp(p->last_key_pressed, "K0021") == 0) /* B+A */ - return "Down+Up"; + if (strcmp(p->last_key_pressed, "K0012") == 0) /* A+B */ + return "Up+Down"; + if (strcmp(p->last_key_pressed, "K0021") == 0) /* B+A */ + return "Down+Up"; - if (strcmp(p->last_key_pressed, "K0102") == 0) /* A+C */ - return "Up+Enter"; - if (strcmp(p->last_key_pressed, "K0201") == 0) /* C+A */ - return "Enter+Up"; - if (strcmp(p->last_key_pressed, "K1002") == 0) /* A+D */ - return "Up+Escape"; - if (strcmp(p->last_key_pressed, "K2001") == 0) /* D+A */ - return "Escape+Up"; + if (strcmp(p->last_key_pressed, "K0102") == 0) /* A+C */ + return "Up+Enter"; + if (strcmp(p->last_key_pressed, "K0201") == 0) /* C+A */ + return "Enter+Up"; + if (strcmp(p->last_key_pressed, "K1002") == 0) /* A+D */ + return "Up+Escape"; + if (strcmp(p->last_key_pressed, "K2001") == 0) /* D+A */ + return "Escape+Up"; - if (strcmp(p->last_key_pressed, "K0120") == 0) /* B+C */ - return "Down+Enter"; - if (strcmp(p->last_key_pressed, "K0210") == 0) /* C+B */ - return "Enter+Down"; - if (strcmp(p->last_key_pressed, "K1020") == 0) /* B+D */ - return "Down+Escape"; - if (strcmp(p->last_key_pressed, "K2010") == 0) /* D+B */ - return "Escape+Down"; + if (strcmp(p->last_key_pressed, "K0120") == 0) /* B+C */ + return "Down+Enter"; + if (strcmp(p->last_key_pressed, "K0210") == 0) /* C+B */ + return "Enter+Down"; + if (strcmp(p->last_key_pressed, "K1020") == 0) /* B+D */ + return "Down+Escape"; + if (strcmp(p->last_key_pressed, "K2010") == 0) /* D+B */ + return "Escape+Down"; - if (strcmp(p->last_key_pressed, "K0012") == 0) /* C+D */ - return "Enter+Escape"; - if (strcmp(p->last_key_pressed, "K0021") == 0) /* D+C */ - return "Escape+Enter"; + if (strcmp(p->last_key_pressed, "K0012") == 0) /* C+D */ + return "Enter+Escape"; + if (strcmp(p->last_key_pressed, "K0021") == 0) /* D+C */ + return "Escape+Enter"; #endif return NULL; /* Ignore combined key events */ @@ -1254,11 +1122,9 @@ pyramid_get_key (Driver *drvthis) * \return Constant string with information. */ MODULE_EXPORT const char * -pyramid_get_info (Driver *drvthis) +pyramid_get_info(Driver *drvthis) { - static char *pyramid_info_string="Pyramid LCD driver"; + static char *pyramid_info_string = "Pyramid LCD driver"; return pyramid_info_string; } - - diff --git a/server/drivers/pylcd.h b/server/drivers/pylcd.h index 4325681..05725d6 100644 --- a/server/drivers/pylcd.h +++ b/server/drivers/pylcd.h @@ -1,47 +1,40 @@ -/* pylcd.h */ - -/* - This is the header file of the LCDproc driver for - the "pyramid" LCD device from Pyramid. - - Copyright (C) 2005 Silvan Marco Fin - Copyright (C) 2006 coresystems GmbH - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 +/** \file server/drivers/pylcd.h + * This is the header file of the LCDproc driver for the "pyramid" LCD device + * from Pyramid. + */ +/*- + * Copyright (C) 2005 Silvan Marco Fin + * 2006 coresystems GmbH + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 */ #ifndef PYLCD_H #define PYLCD_H -#include "lcd.h" +#define MAXCOUNT 10 /* Size of read buffer including NUL */ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#define MAXCOUNT 10 /* Including terminating NUL */ +/* Display properties */ #define WIDTH 16 #define HEIGHT 2 - +#define SCREEN_SIZE (WIDTH * HEIGHT) #define CUSTOMCHARS 8 - #define CELLHEIGHT 8 #define CELLWIDTH 5 - /** private data for the \c pyramid driver */ typedef struct pyramid_private_data { /* device io */ @@ -58,14 +51,14 @@ typedef struct pyramid_private_data { int cellheight; /* output handling */ - char framebuffer[WIDTH*HEIGHT+2]; - int FB_modified; - CGmode custom; + char framebuffer[SCREEN_SIZE]; + char backingstore[SCREEN_SIZE]; + CGmode ccmode; + unsigned char cc_cache[CUSTOMCHARS][CELLHEIGHT]; /* button handling */ char last_key_pressed[6]; unsigned long long last_key_time; - unsigned long long last_buf_time; /* cursor handling */ int C_x; @@ -77,25 +70,24 @@ typedef struct pyramid_private_data { } PrivateData; -MODULE_EXPORT int pyramid_init (Driver *drvthis); -MODULE_EXPORT void pyramid_close (Driver *drvthis); -MODULE_EXPORT int pyramid_width (Driver *drvthis); -MODULE_EXPORT int pyramid_height (Driver *drvthis); -MODULE_EXPORT int pyramid_cellwidth (Driver *drvthis); -MODULE_EXPORT int pyramid_cellheight (Driver *drvthis); -MODULE_EXPORT void pyramid_clear (Driver *drvthis); -MODULE_EXPORT void pyramid_flush (Driver *drvthis); -MODULE_EXPORT void pyramid_string (Driver *drvthis, int x, int y, const char string[]); -MODULE_EXPORT void pyramid_chr (Driver *drvthis, int x, int y, char c); -MODULE_EXPORT void pyramid_vbar (Driver *drvthis, int x, int y, int len, int promille, int options); -MODULE_EXPORT void pyramid_hbar (Driver *drvthis, int x, int y, int len, int promille, int options); -MODULE_EXPORT int pyramid_icon (Driver *drvthis, int x, int y, int icon); -MODULE_EXPORT void pyramid_cursor (Driver *drvthis, int x, int y, int state); -MODULE_EXPORT int pyramid_get_free_chars (Driver *drvthis); -MODULE_EXPORT void pyramid_set_char (Driver *drvthis, int n, char *dat); -MODULE_EXPORT void pyramid_output (Driver *drvthis, int state); -MODULE_EXPORT const char * pyramid_get_key (Driver *drvthis); -MODULE_EXPORT const char * pyramid_get_info (Driver *drvthis); +MODULE_EXPORT int pyramid_init(Driver *drvthis); +MODULE_EXPORT void pyramid_close(Driver *drvthis); +MODULE_EXPORT int pyramid_width(Driver *drvthis); +MODULE_EXPORT int pyramid_height(Driver *drvthis); +MODULE_EXPORT int pyramid_cellwidth(Driver *drvthis); +MODULE_EXPORT int pyramid_cellheight(Driver *drvthis); +MODULE_EXPORT void pyramid_clear(Driver *drvthis); +MODULE_EXPORT void pyramid_flush(Driver *drvthis); +MODULE_EXPORT void pyramid_string(Driver *drvthis, int x, int y, const char string[]); +MODULE_EXPORT void pyramid_chr(Driver *drvthis, int x, int y, char c); +MODULE_EXPORT void pyramid_vbar(Driver *drvthis, int x, int y, int len, int promille, int options); +MODULE_EXPORT void pyramid_hbar(Driver *drvthis, int x, int y, int len, int promille, int options); +MODULE_EXPORT int pyramid_icon(Driver *drvthis, int x, int y, int icon); +MODULE_EXPORT void pyramid_cursor(Driver *drvthis, int x, int y, int state); +MODULE_EXPORT int pyramid_get_free_chars(Driver *drvthis); +MODULE_EXPORT void pyramid_set_char(Driver *drvthis, int n, unsigned char *dat); +MODULE_EXPORT void pyramid_output(Driver *drvthis, int state); +MODULE_EXPORT const char *pyramid_get_key(Driver *drvthis); +MODULE_EXPORT const char *pyramid_get_info(Driver *drvthis); #endif -