diff --git a/server/drivers/Makefile.am b/server/drivers/Makefile.am index 499aca4..30b0fef 100644 --- a/server/drivers/Makefile.am +++ b/server/drivers/Makefile.am @@ -81,7 +81,7 @@ lirc_SOURCES = lcd.h lircin.c lircin.h report.h MD8800_SOURCES = lcd.h lcd_lib.h MD8800.c MD8800.h report.h ms6931_SOURCES = lcd.h lcd_lib.h ms6931.h ms6931.c report.h mtc_s16209x_SOURCES = lcd.h lcd_lib.h mtc_s16209x.c mtc_s16209x.h report.h -MtxOrb_SOURCES = lcd.h lcd_lib.h MtxOrb.c MtxOrb.h report.h bigfont.h +MtxOrb_SOURCES = lcd.h lcd_lib.h MtxOrb.c MtxOrb.h report.h NoritakeVFD_SOURCES = lcd.h lcd_lib.h NoritakeVFD.c NoritakeVFD.h report.h pyramid_SOURCES = lcd.h pylcd.c pylcd.h sed1330_SOURCES = lcd.h sed1330.h sed1330.c port.h lpt-port.h timing.h report.h diff --git a/server/drivers/MtxOrb.c b/server/drivers/MtxOrb.c index a60e948..66f86ef 100644 --- a/server/drivers/MtxOrb.c +++ b/server/drivers/MtxOrb.c @@ -6,12 +6,14 @@ NOTE: GLK displays have a different driver. Copyright (C) 1999, William Ferrell and Scott Scriven - 2001, André Breiler + 2001, Andre Breiler 2001, Philip Pokorny 2001, David Douthitt 2001, David Glaude 2001, Joris Robijn 2001, Rene Wagner + 2006, Peter Marschall + 2006, Ethan Dicks 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 @@ -48,6 +50,7 @@ #include "lcd.h" #include "lcd_lib.h" #include "MtxOrb.h" +#include "adv_bignum.h" #include "report.h" /* #include "shared/str.h" @@ -76,102 +79,30 @@ #define IS_VKD_DISPLAY (p->MtxOrb_type == MTXORB_VKD) /* - * The MtxOrb driver do not use a lot of hardware feature. - * We try to replace them by more flexible software version. - * That's why vbar/hbar/bignum are using Matrix Orbital build-in function. - * It permit simultanious use of those features and custom char. + * The MtxOrb driver does not use a lot of hardware features. + * We try to replace them with more flexible software alternatives. + * That's why vbar/hbar/bignum are using locally-defined functions; + * it permits simultaneous use of those features and custom chars. * - * The same way we don't use the hardware clear but empty the frame buffer. - * The frame buffer hold all the change that are requested, - * until the server ask us to flush that to display. - * This also permit to do incremental update and reduce the number of - * character to be send to the display accross the serial link. + * For the same reason, we don't use the hardware clear but rather + * empty the internal frame buffer. The frame buffer holds all + * the requested changes until the server asks us to flush the + * changes to the display. This also permits us to do an + * incremental update and reduce the number of characters to be + * sent to the display across the serial link. * - * In order to display graphic widget we use and define our own custom char. - * To avoid multiple definition of the same custom character, - * we use a caching mechanisme that remember what is currently define. - * In order to avoid always redefining the same custom character - * wich are at the begining of the table, we rotate the begining of the table. - * This is suppose to reduce the number of caracter redefinition - * and make the caching more effective. All in all we reduce the number - * of caracter we need to send to the display. - * - * David GLAUDE + * In order to display graphic widgets, we define and use our own + * custom characters. To avoid multiple definitions of the same + * custom characters, we use a caching mechanism that remembers + * what is currently defined. In order to avoid always redefining + * the same custom character at the beginning of the table, we + * rotate the beginning of the table. This is supposed to reduce + * the number of character redefinitions and make the caching more + * effective. The overall goal is to reduce the number of + * characters sent to the display. */ -/* TODO: Find a better way to deal with the bitmap/name of custom char - * Here the value link to the enum and the definition at the end. - */ -#define START_FONT 30 -#define WHITE 254 -#define BLACK 255 - -/* Starting from now bigfont.h does not define S=White and F=Black anymore */ -/* Due to the way _num is implemented we need to delta by START_FONT */ -#define S WHITE - START_FONT -#define F BLACK - START_FONT -#include "bigfont.h" -#undef F -#undef S - -typedef enum { -/* This is for standard icon: IT MUST START AT POSITION ZERO */ - empty_heart = 0, - filled_heart = 1, - ellipsis = 2, -/* This was for standard icon */ -/* This is for non standard icon */ - play = 3, - fforward = 4, - frewind = 5, - uparrow = 6, - downarrow = 7, -/* This was for non standard icon */ -/* This is for bar up */ - baru1 = 8, - baru2 = 9, - baru3 = 10, - baru4 = 11, - baru5 = 12, - baru6 = 13, - baru7 = 14, -/* This was for bar up */ -/* This is for bar down */ - bard1 = 15, - bard2 = 16, - bard3 = 17, - bard4 = 18, - bard5 = 19, - bard6 = 20, - bard7 = 21, -/* This was for bar down */ -/* This is for bar right */ - barr1 = 22, - barr2 = 23, - barr3 = 24, - barr4 = 25, -/* This was for bar right */ -/* This is for bar left */ - barl1 = 26, - barl2 = 27, - barl3 = 28, - barl4 = 29, -/* This was for bar left */ -/* This is for sofware bigfont */ - bigfonta = 30, - bigfontb = 31, - bigfontc = 32, - bigfontd = 33, - bigfonte = 34, - bigfontf = 35, - bigfontg = 36, - bigfonth = 37, -/* This was for software bigfont */ - barw = WHITE, - barb = BLACK -} bar_type; - typedef enum { MTXORB_LCD, MTXORB_LKD, @@ -180,22 +111,40 @@ typedef enum { } MtxOrb_type_type; -typedef struct p { - int def[9]; - int use[9]; - int circular; /* static data from MtxOrb_ask_bar */ - int output_state; /* static data from MtxOrb_output */ - int backlight_state; /* static data from MtxOrb_backlight */ - int width; - int height; - char *framebuf; /* Frame buffer */ - char *old; /* Current on screen frame buffer */ - int widthBYheight; /* Avoid computing width * height frequently */ - int clear; /* Control when the LCD is cleared */ +/* 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, /* horizontal bars */ + custom, /* custom settings */ + bignum, /* big numbers */ + bigchar /* big characters */ +} CGmode; + + +typedef struct { int fd; /* The LCD file descriptor */ + + /* dimensions */ + int width, height; + int cellwidth, cellheight; + + /* framebuffer and buffer for old LCD contents */ + unsigned char *framebuf; + unsigned char *backingstore; + + /* defineable characters */ + CGmode ccmode; + + int output_state; /* static data from MtxOrb_output */ int contrast; /* static data from set/get_contrast */ + int backlight_state; /* static data from MtxOrb_backlight */ int backlightenabled; + MtxOrb_type_type MtxOrb_type; + char left_key; char right_key; char up_key; @@ -203,12 +152,8 @@ typedef struct p { char enter_key; char escape_key; int keypad_test_mode; - int cellwidth; - int cellheight; char info[255]; /* static data from MtxOrb_get_info */ -/* LibData *libdata; */ -/* Private Data of the new library: Work in progress */ - } PrivateData; +} PrivateData; /* Vars for the server core */ MODULE_EXPORT char *api_version = API_VERSION; @@ -216,17 +161,15 @@ MODULE_EXPORT int stay_in_foreground = 0; MODULE_EXPORT int supports_multiple = 1; MODULE_EXPORT char *symbol_prefix = "MtxOrb_"; -static int MtxOrb_ask_bar (Driver *drvthis, int type); -static void MtxOrb_set_known_char (Driver * drvthis, int car, int type); static void MtxOrb_linewrap (Driver *drvthis, int on); static void MtxOrb_autoscroll (Driver *drvthis, int on); static void MtxOrb_cursorblink (Driver *drvthis, int on); -static void MtxOrb_mold_vbar (Driver *drvthis, int x, int y, int len); -static void MtxOrb_old_hbar (Driver *drvthis, int x, int y, int len); +static void MtxOrb_cursor_goto(Driver *drvthis, int x, int y); /* Parse one key from the configfile */ -static char MtxOrb_parse_keypad_setting (Driver *drvthis, char * keyname, char default_value) +static char +MtxOrb_parse_keypad_setting (Driver *drvthis, char *keyname, char default_value) { char return_val = 0; const char *s; @@ -243,11 +186,11 @@ static char MtxOrb_parse_keypad_setting (Driver *drvthis, char * keyname, char d return return_val; } -/* TODO: Get the frame buffers working right */ -/* Opens com port and sets baud correctly... - * - * Called to initialize driver settings +/** + * Initialize the driver. + * \param drvthis Pointer to driver structure. + * \return Information of success (0) or failure (non-0). */ MODULE_EXPORT int MtxOrb_init (Driver *drvthis) @@ -271,21 +214,22 @@ MtxOrb_init (Driver *drvthis) return -1; /* Initialise the PrivateData structure */ - memset(p->def, -1, sizeof(p->def)); - memset(p->use, 0, sizeof(p->use)); p->fd = -1; - p->circular = -1; /* static data from MtxOrb_ask_bar */ - p->output_state = -1; /* static data from MtxOrb_output */ - p->backlight_state = 1; /* static data from MtxOrb_backlight */ + p->MtxOrb_type = MTXORB_LKD; /* Assume it's an LCD w/keypad */ + p->width = LCD_DEFAULT_WIDTH; p->height = LCD_DEFAULT_HEIGHT; - p->widthBYheight = LCD_DEFAULT_WIDTH * LCD_DEFAULT_HEIGHT; - p->clear = 1; /* assume LCD is cleared at startup */ - p->contrast = DEFAULT_CONTRAST; + p->cellwidth = LCD_DEFAULT_CELLWIDTH; + p->cellheight = LCD_DEFAULT_CELLHEIGHT; + p->framebuf = NULL; + p->backingstore = NULL; + + p->contrast = DEFAULT_CONTRAST; + p->output_state = -1; /* static data from MtxOrb_output */ + p->backlight_state = 1; /* static data from MtxOrb_backlight */ p->backlightenabled = DEFAULT_BACKLIGHT; - p->old = NULL; - p->MtxOrb_type = MTXORB_LKD; /* Assume it's an LCD w/keypad */ + p->left_key = MTXORB_DEFAULT_Left; p->right_key = MTXORB_DEFAULT_Right; p->up_key = MTXORB_DEFAULT_Up; @@ -293,8 +237,6 @@ MtxOrb_init (Driver *drvthis) p->enter_key = MTXORB_DEFAULT_Enter; p->escape_key = MTXORB_DEFAULT_Escape; p->keypad_test_mode = 0; - p->cellwidth = LCD_DEFAULT_CELLWIDTH; - p->cellheight = LCD_DEFAULT_CELLHEIGHT; debug(RPT_INFO, "MtxOrb: init(%p)", drvthis); @@ -317,7 +259,6 @@ MtxOrb_init (Driver *drvthis) } p->width = w; p->height = h; - p->widthBYheight = w * h; /* Get contrast */ tmp = drvthis->config_get_int(drvthis->name, "Contrast", 0, DEFAULT_CONTRAST); @@ -349,7 +290,7 @@ MtxOrb_init (Driver *drvthis) drvthis->name, tmp); } - /* Get backlight setting*/ + /* Get backlight setting */ p->backlightenabled = drvthis->config_get_bool(drvthis->name, "Backlight", 0, DEFAULT_BACKLIGHT); /* Get display type */ @@ -364,12 +305,12 @@ MtxOrb_init (Driver *drvthis) } else if (strncasecmp(buf, "vkd", 3) == 0) { p->MtxOrb_type = MTXORB_VKD; } else { - report(RPT_ERR, "%s: unknwon display Type %s; must be one of lcd, lkd, vfd, or vkd", + report(RPT_ERR, "%s: unknown display Type %s; must be one of lcd, lkd, vfd, or vkd", drvthis->name, buf); return -1; } - /* Get keypad settings*/ + /* Get keypad settings */ /* keypad test mode? */ if (drvthis->config_get_bool(drvthis->name, "keypad_test_mode", 0, 0)) { @@ -409,7 +350,7 @@ MtxOrb_init (Driver *drvthis) report(RPT_DEBUG, "%s: Using \"%c\" as EscapeKey.", drvthis->name, p->escape_key); } - /* End of config file parsing*/ + /* End of config file parsing */ /* Set up io port correctly, and open it... */ p->fd = open(device, O_RDWR | O_NOCTTY); @@ -448,12 +389,20 @@ MtxOrb_init (Driver *drvthis) tcsetattr(p->fd, TCSANOW, &portset); /* Make sure the frame buffer is there... */ - p->framebuf = (char *) calloc(p->widthBYheight, 1); + p->framebuf = (unsigned char *) calloc(p->width * p->height, 1); if (p->framebuf == NULL) { report(RPT_ERR, "%s: unable to create framebuffer", drvthis->name); return -1; } - memset(p->framebuf, ' ', p->widthBYheight); + memset(p->framebuf, ' ', p->width * p->height); + + /* make sure the framebuffer backing store is there... */ + p->backingstore = (unsigned char *) malloc(p->width * p->height); + if (p->backingstore == NULL) { + report(RPT_ERR, "%s: unable to create framebuffer backing store", drvthis->name); + return -1; + } + memset(p->backingstore, ' ', p->width * p->height); /* * Configure display @@ -469,32 +418,37 @@ MtxOrb_init (Driver *drvthis) return 1; } -#define ValidX(x) if ((x) > p->width) { (x) = p->width; } else (x) = (x) < 1 ? 1 : (x); -#define ValidY(y) if ((y) > p->height) { (y) = p->height; } else (y) = (y) < 1 ? 1 : (y); - -/****************************** - * Clear the screen (the frame buffer) +/** + * Clear the screen. + * \param drvthis Pointer to driver structure. */ MODULE_EXPORT void MtxOrb_clear (Driver *drvthis) { - PrivateData * p = drvthis->private_data; + PrivateData *p = drvthis->private_data; - if (p->framebuf != NULL) - memset(p->framebuf, ' ', (p->widthBYheight)); - p->clear = 1; /* Remember that custom char are no more visible. */ + /* set hbar/vbar/bignum mode back to normal character display */ + p->ccmode = standard; + + /* replace all chars in framebuf with spaces */ + memset(p->framebuf, ' ', (p->width * p->height)); + + /* make backing store differ from framebuf so it all gets cleared by MtxOrb_flush */ + memset(p->backingstore, 0xFE, (p->width * p->height)); debug(RPT_DEBUG, "MtxOrb: cleared screen"); } -/****************************** - * Clean-up + +/** + * Close the driver (do necessary clean-up). + * \param drvthis Pointer to driver structure. */ MODULE_EXPORT void MtxOrb_close (Driver *drvthis) { - PrivateData * p = drvthis->private_data; + PrivateData *p = drvthis->private_data; if (p != NULL) { if (p->fd >= 0) @@ -504,165 +458,201 @@ MtxOrb_close (Driver *drvthis) free(p->framebuf); p->framebuf = NULL; + if (p->backingstore) + free(p->backingstore); + p->backingstore = NULL; + free(p); } drvthis->store_private_ptr(drvthis, NULL); debug(RPT_DEBUG, "MtxOrb: closed"); } -/****************************** - * Returns the display width + +/** + * Return the display width in characters. + * \param drvthis Pointer to driver structure. + * \return Number of characters the display is wide. */ MODULE_EXPORT int MtxOrb_width (Driver *drvthis) { - PrivateData * p = drvthis->private_data; + PrivateData *p = drvthis->private_data; return p->width; } -/****************************** - * Returns the display height + +/** + * Return the display height in characters. + * \param drvthis Pointer to driver structure. + * \return Number of characters the display is high. */ MODULE_EXPORT int MtxOrb_height (Driver *drvthis) { - PrivateData * p = drvthis->private_data; + PrivateData *p = drvthis->private_data; return p->height; } -/****************************** - * Display a string at x,y + +/** + * Return the width of a character in pixels. + * \param drvthis Pointer to driver structure. + * \return Number of pixel columns a character cell is wide. + */ +MODULE_EXPORT int +MtxcOrb_cellwidth (Driver *drvthis) +{ + PrivateData *p = drvthis->private_data; + + return p->cellwidth; +} + + +/** + * Return the height of a character in pixels. + * \param drvthis Pointer to driver structure. + * \return Number of pixel lines a character cell is high. + */ +MODULE_EXPORT int +MtxcOrb_cellheight (Driver *drvthis) +{ + PrivateData *p = drvthis->private_data; + + return p->cellheight; +} + + +/** + * Print a string on the screen at position (x,y). + * The upper-left corner is (1,1), the lower-right corner is (p->width, p->height). + * \param drvthis Pointer to driver structure. + * \param x Horizontal character position (column). + * \param y Vertical character position (row). + * \param string String that gets written. */ MODULE_EXPORT void -MtxOrb_string (Driver *drvthis, int x, int y, char *string) +MtxOrb_string (Driver *drvthis, int x, int y, char string[]) { - int offset, siz; + PrivateData *p = drvthis->private_data; + int i; - PrivateData * p = drvthis->private_data; + /* Convert 1-based coords to 0-based... */ + x--; + y--; - ValidX(x); - ValidY(y); + if ((y < 0) || (y >= p->height)) + return; - x--; y--; /* Convert 1-based coords to 0-based... */ - offset = (y * p->width) + x; - siz = (p->widthBYheight) - offset; - siz = (siz > strlen(string)) ? strlen(string) : siz; - - memcpy(p->framebuf + offset, string, siz); + for (i = 0; (string[i] != '\0') && (x < p->width); i++, x++) { + /* Check for buffer overflows... */ + if (x >= 0) + p->framebuf[(y * p->width) + x] = string[i]; + } debug(RPT_DEBUG, "MtxOrb: printed string at (%d,%d)", x, y); } -/****************************** - * Send what we have to the hardware + +/** + * Flush data on screen to the LCD. + * \param drvthis Pointer to driver structure. */ MODULE_EXPORT void MtxOrb_flush (Driver *drvthis) { - char out[12]; - int i,j,mv = 1; - char *xp, *xq; - - PrivateData * p = drvthis->private_data; - - if (p->old == NULL) { - p->old = malloc(p->widthBYheight); - - write(p->fd, "\x0FEG\x01\x01", 4); - write(p->fd, p->framebuf, p->widthBYheight); - - strncpy(p->old, p->framebuf, p->widthBYheight); - - return; - } - - xp = p->framebuf; - xq = p->old; + PrivateData *p = drvthis->private_data; + unsigned char *xp = p->framebuf; + unsigned char *xq = p->backingstore; + int i; + /* Note: this implementation is not optimal as it does 1 write per char */ for (i = 1; i <= p->height; i++) { + int j; + int move = 1; /* need to move to the 1st char of each line */ + for (j = 1; j <= p->width; j++) { - if ((*xp == *xq) && (*xp > 8)) - mv = 1; + if (*xp == *xq) + move++; /* skip a char => need to move cursor */ else { - /* Draw characters that have changed, as well - * as custom characters. We know not if a custom - * character has changed. - */ - if (mv == 1) { - snprintf(out, sizeof(out), "\x0FEG%c%c", j, i); - write(p->fd, out, 4); - mv = 0; + /* Draw characters that have changed */ + + /* don't send the command character to the display */ + unsigned char c = (*xp == 0xFE) ? ' ': *xp; + + if (move != 0) { + MtxOrb_cursor_goto(drvthis, j, i); + move = 0; } - write(p->fd, xp, 1); + write(p->fd, &c, 1); } xp++; xq++; } } - - - strncpy(p->old, p->framebuf, p->widthBYheight); + memcpy(p->backingstore, p->framebuf, p->width * p->height); debug(RPT_DEBUG, "MtxOrb: frame buffer flushed"); } -/****************************** - * 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). + +/** + * Print a character on the screen at position (x,y). + * The upper-left corner is (1,1), the lower-right corner is (p->width, p->height). + * \param drvthis Pointer to driver structure. + * \param x Horizontal character position (column). + * \param y Vertical character position (row). + * \param c Character that gets written. */ MODULE_EXPORT void MtxOrb_chr (Driver *drvthis, int x, int y, char c) { - int offset; + PrivateData *p = drvthis->private_data; - /* Characters may or may NOT be alphabetic; it appears - * that characters 0..4 (or similar) are graphic fonts - */ + /* Convert 1-based coords to 0-based... */ + x--; + y--; - PrivateData * p = drvthis->private_data; - - ValidX(x); - ValidY(y); - - /* write immediately to screen... this code was taken - * from the LK202-25; should work for others, yes? - * snprintf(out, sizeof(out), "\x0FEG%c%c%c", x, y, c); - * write(fd, out, 4); - */ - - /* write to frame buffer */ - y--; x--; /* translate to 0-index */ - offset = (y * p->width) + x; - p->framebuf[offset] = c; + if ((x >= 0) && (y >= 0) && (x < p->width) && (y < p->height)) + p->framebuf[(y * p->width) + x] = c; debug(RPT_DEBUG, "writing character %02X to position (%d,%d)", c, x, y); } + +/** + * Get current LCD contrast. + * This is only the locally stored contrast, the contrast value + * cannot be retrieved from the LCD. + * \param drvthis Pointer to driver structure. + * \return Stored contrast in promille. + */ + MODULE_EXPORT int MtxOrb_get_contrast (Driver *drvthis) { - PrivateData * p = drvthis->private_data; + PrivateData *p = drvthis->private_data; return p->contrast; } -/****************************** - * Changes screen contrast in promille - * The hardware support value from 0 to 255. - * Hardware 140 seems good - * note: works only for LCD displays + +/** + * Change LCD contrast. + * Whis only works on LCD displays where the + * HW supports values from 0 to 255 with 140 looking OK. * Is it better to use the brightness for VFD/VKD displays ? + * \param drvthis Pointer to driver structure. + * \param promille New contrast value in promille. */ MODULE_EXPORT void MtxOrb_set_contrast (Driver *drvthis, int promille) { - char out[4]; - int real_contrast; - - PrivateData * p = drvthis->private_data; + PrivateData *p = drvthis->private_data; + int real_contrast = (int) ((long) promille * 255 / 1000); /* Check it */ if ((promille < 0) || (promille > 1000)) @@ -671,11 +661,11 @@ MtxOrb_set_contrast (Driver *drvthis, int promille) /* Store it */ p->contrast = promille; - real_contrast = (int) ((long) promille * 255 / 1000 ); - /* And do it */ if (IS_LCD_DISPLAY || IS_LKD_DISPLAY) { - snprintf(out, sizeof(out), "\x0FEP%c", real_contrast); + unsigned char out[4] = { '\xFE', 'P', 0 }; + + out[2] = (unsigned char) real_contrast; write(p->fd, out, 3); report(RPT_DEBUG, "%s: contrast set to %d", @@ -686,42 +676,35 @@ MtxOrb_set_contrast (Driver *drvthis, int promille) } } -/****************************** - * Sets the backlight on or off -- can be done quickly for - * an intermediate brightness... + +/** + * Turn the LCD backlight on or off. + * \param drvthis Pointer to driver structure. + * \param on New backlight status. * - * WARNING: off switches vfd/vkd displays off entirely - * so maybe it is best to start LCDd with -b on + * \warning on=0 switches vfd/vkd displays off entirely * - * WARNING: there seems to be a movement afoot to add more - * functions than just on/off to this.. + * \warning There seems to be a movement afoot to add more functions than just on/off to this.. */ - -#define BACKLIGHT_OFF 0 -#define BACKLIGHT_ON 1 - MODULE_EXPORT void MtxOrb_backlight (Driver *drvthis, int on) { - PrivateData * p = drvthis->private_data; - - if (p->backlight_state == on) - return; + PrivateData *p = drvthis->private_data; p->backlight_state = on; switch (on) { case BACKLIGHT_ON: - write(p->fd, "\x0FE" "F", 2); - debug(RPT_DEBUG, "MtxOrb: backlight turned on"); + debug(RPT_DEBUG, "MtxOrb: display timer set to leave display on indefinitely"); + write(p->fd, "\xFE" "B" "\0", 3); /* 0 minutes == never turn display off */ break; case BACKLIGHT_OFF: if (IS_VKD_DISPLAY || IS_VFD_DISPLAY) { - debug(RPT_DEBUG, "MtxOrb: backlight ignored - not LCD or LKD display"); + debug(RPT_DEBUG, "MtxOrb: backlight off ignored - not LCD or LKD display"); ; /* turns display off entirely (whoops!) */ } else { debug(RPT_DEBUG, "MtxOrb: backlight turned off"); - write(p->fd, "\x0FE" "B" "\x000", 3); + write(p->fd, "\xFE" "F", 2); } break; default: /* ignored... */ @@ -730,105 +713,127 @@ MtxOrb_backlight (Driver *drvthis, int on) } } -/****************************** - * Sets output port on or off - * displays with keypad have 6 outputs but the one without kepad - * have only one output - * NOTE: length of command are different + +/** + * Set output port(s). + * Displays with keypad have 6 outputs whereas the others only have one. + * \param drvthis Pointer to driver structure. + * \param state Integer with bits representing port states. */ MODULE_EXPORT void -MtxOrb_output (Driver *drvthis, int on) +MtxOrb_output (Driver *drvthis, int state) { - char out[5]; + PrivateData *p = drvthis->private_data; + unsigned char out[5] = { '\xFE', 0, 0 }; - PrivateData * p = drvthis->private_data; + state &= 0x3F; /* strip to six bits */ - on = on & 077; /* strip to six bits */ + p->output_state = state; - if (p->output_state == on) - return; - - p->output_state = on; - - debug(RPT_DEBUG, "MtxOrb: output pins set: %04X", on); + debug(RPT_DEBUG, "MtxOrb: output pins set: %04X", state); if (IS_LCD_DISPLAY || IS_VFD_DISPLAY) { /* LCD and VFD displays only have one output port */ - (on) ? - write(p->fd, "\x0FEW", 2) : - write(p->fd, "\x0FEV", 2); - } else { + out[1] = (state) ? 'W' : 'V'; + write(p->fd, out, 2); + } + else { int i; /* Other displays have six output ports; * the value "on" is a binary value determining which * ports are turned on (1) and off (0). */ - for (i = 0; i < 6; i++) { - (on & (1 << i)) ? - snprintf(out, sizeof(out), "\x0FEW%c", i + 1) : - snprintf(out, sizeof(out), "\x0FEV%c", i + 1); + out[1] = (state & (1 << i)) ? 'W' : 'V'; + out[2] = i+1; write(p->fd, out, 3); } } } -/****************************** - * Toggle the built-in linewrapping feature + +/** + * Turn the LCD's built-in linewrapping feature on or off. + * \param drvthis Pointer to driver structure. + * \param on New state. */ static void MtxOrb_linewrap (Driver *drvthis, int on) { - PrivateData * p = drvthis->private_data; + PrivateData *p = drvthis->private_data; + unsigned char out[3] = { '\xFE', 0 }; - if (on) { - write(p->fd, "\x0FE" "C", 2); - debug(RPT_DEBUG, "MtxOrb: linewrap turned on"); - } else { - write(p->fd, "\x0FE" "D", 2); - debug(RPT_DEBUG, "MtxOrb: linewrap turned off"); - } + out[1] = (on) ? 'C' : 'D'; + write(p->fd, out, 2); + + debug(RPT_DEBUG, "MtxOrb: linewrap turned %s", (on) ? "on" : "off"); } -/****************************** - * Toggle the built-in automatic scrolling feature + +/** + * Turn the LCD's built-in automatic scrolling feature on or off. + * \param drvthis Pointer to driver structure. + * \param on New state. */ static void MtxOrb_autoscroll (Driver *drvthis, int on) { - PrivateData * p = drvthis->private_data; + PrivateData *p = drvthis->private_data; + unsigned char out[3] = { '\xFE', 0 }; - if (on) { - write(p->fd, "\x0FEQ", 2); - debug(RPT_DEBUG, "MtxOrb: autoscroll turned on"); - } else { - write(p->fd, "\x0FER", 2); - debug(RPT_DEBUG, "MtxOrb: autoscroll turned off"); - } + out[1] = (on) ? 'Q' : 'R'; + write(p->fd, out, 2); + + debug(RPT_DEBUG, "MtxOrb: autoscroll turned %s", (on) ? "on" : "off"); } -/* TODO: make sure this doesn't mess up non-VFD displays - ****************************** - * Toggle cursor blink on/off + +/** + * Turn LCD's hardware cursor blinking on or off. + * \param drvthis Pointer to driver structure. + * \param on New state. + * + * \todo Make sure this doesn't mess up non-VFD displays. */ static void MtxOrb_cursorblink (Driver *drvthis, int on) { - PrivateData * p = drvthis->private_data; + PrivateData *p = drvthis->private_data; + unsigned char out[3] = { '\xFE', 0 }; - if (on) { - write(p->fd, "\x0FES", 2); - debug(RPT_DEBUG, "MtxOrb: cursorblink turned on"); - } else { - write(p->fd, "\x0FET", 2); - debug(RPT_DEBUG, "MtxOrb: cursorblink turned off"); - } + out[1] = (on) ? 'S' : 'T'; + write(p->fd, out, 2); + + debug(RPT_DEBUG, "MtxOrb: cursorblink turned %s", (on) ? "on" : "off"); } -/****************************** - * Returns string with general information about the display +/** + * Move cursor to position (x,y). + * \param drvthis Pointer to driver structure. + * \param x Horizontal character position (column). + * \param y Vertical character position (row). + */ +static void +MtxOrb_cursor_goto(Driver *drvthis, int x, int y) +{ + PrivateData *p = drvthis->private_data; + unsigned char out[5] = { '\xFE', 'G', 0, 0 }; + + /* set cursor position */ + if ((x > 0) && (x <= p->width)) + out[2] = (unsigned char) x; + if ((y > 0) && (y <= p->height)) + out[3] = (unsigned char) y; + write(p->fd, out, 4); +} + + +/** + * Provide general information about the LCD/VFD display. + * \param drvthis Pointer to driver structure. + * \return Constant string with information. */ MODULE_EXPORT const char * MtxOrb_get_info (Driver *drvthis) @@ -836,7 +841,7 @@ MtxOrb_get_info (Driver *drvthis) char in = 0; char tmp[255], buf[64]; /* int i = 0; */ - PrivateData * p = drvthis->private_data; + PrivateData *p = drvthis->private_data; fd_set rfds; @@ -873,7 +878,7 @@ MtxOrb_get_info (Driver *drvthis) case '\x01': strcat(p->info, "LCD0821 "); break; case '\x03': strcat(p->info, "LCD2021 "); break; case '\x04': strcat(p->info, "LCD1641 "); break; - case '\x05': strcat(p->info, "LCD2041 "); break; + case '\x05': strcat(p->info, "LCD2041 "); break; /* VK202-25 ? */ case '\x06': strcat(p->info, "LCD4021 "); break; case '\x07': strcat(p->info, "LCD4041 "); break; case '\x08': strcat(p->info, "LK202-25 "); break; @@ -886,17 +891,40 @@ MtxOrb_get_info (Driver *drvthis) case '\x0F': strcat(p->info, "VK204-25 "); break; case '\x10': strcat(p->info, "GLC12232 "); break; case '\x11': strcat(p->info, "GLC12864 "); break; - case '\x12': strcat(p->info, "GLC128128 "); break; + case '\x12': strcat(p->info, "GLC128128 "); break; /* ??? */ case '\x13': strcat(p->info, "GLC24064 "); break; - case '\x14': strcat(p->info, "GLK12864-25 "); break; + case '\x14': strcat(p->info, "GLK12864-25 "); break; /* ??? */ case '\x15': strcat(p->info, "GLK24064-25 "); break; - case '\x21': strcat(p->info, "GLK128128-25 "); break; - case '\x22': strcat(p->info, "GLK12232-25 "); break; + case '\x21': strcat(p->info, "GLK128128-25 "); break; /* ??? */ + case '\x22': strcat(p->info, "GLK12232-25-WBL "); break; + case '\x24': strcat(p->info, "GLK12232-25-SM "); break; case '\x31': strcat(p->info, "LK404-AT "); break; - case '\x32': strcat(p->info, "VFD1621 "); break; + case '\x32': strcat(p->info, "VFD1621 "); break; /* MOS-AV-162A ? */ case '\x33': strcat(p->info, "LK402-12 "); break; case '\x34': strcat(p->info, "LK162-12 "); break; case '\x35': strcat(p->info, "LK204-25PC "); break; + case '\x36': strcat(p->info, "LK202-24-USB "); break; + case '\x37': strcat(p->info, "VK202-24-USB "); break; + case '\x38': strcat(p->info, "LK204-24-USB "); break; + case '\x39': strcat(p->info, "VK204-24-USB "); break; + case '\x3A': strcat(p->info, "PK162-12 "); break; + case '\x3B': strcat(p->info, "VK162-12 "); break; + case '\x3C': strcat(p->info, "MOS-AP-162A "); break; + case '\x3D': strcat(p->info, "PK202-25 "); break; + case '\x3E': strcat(p->info, "MOS-AL-162A "); break; + case '\x40': strcat(p->info, "MOS-AV-202A "); break; + case '\x41': strcat(p->info, "MOS-AP-202A "); break; + case '\x42': strcat(p->info, "PK202-24-USB "); break; + case '\x43': strcat(p->info, "MOS-AL-082 "); break; + case '\x44': strcat(p->info, "MOS-AL-204 "); break; + case '\x45': strcat(p->info, "MOS-AV-204 "); break; + case '\x46': strcat(p->info, "MOS-AL-402 "); break; + case '\x47': strcat(p->info, "MOS-AV-402 "); break; + case '\x48': strcat(p->info, "LK082-12 "); break; + case '\x49': strcat(p->info, "VK402-12 "); break; + case '\x4A': strcat(p->info, "VK404-55 "); break; + case '\x4B': strcat(p->info, "LK402-25 "); break; + case '\x4C': strcat(p->info, "VK402-25 "); break; default: /*snprintf(tmp, sizeof(tmp), "Unknown (%X) ", in); strcat(info, tmp); */ break; } @@ -955,286 +983,390 @@ MtxOrb_get_info (Driver *drvthis) return p->info; } -/* TODO: Finish the support for bar growing reverse way. - * TODO: Migrate to the new vbar. - ****************************** - * Draws a vertical bar... - * This is the new version using dynamic icon alocation + +/** + * Draw a vertical bar bottom-up. + * \param drvthis Pointer to driver structure. + * \param x Horizontal character position (column) of the starting point. + * \param y Vertical character position (row) of the starting point. + * \param len Number of characters that the bar is high at 100% + * \param promille Current height level of the bar in promille. + * \param options Options (currently unused). */ -static void MtxOrb_mold_vbar (Driver *drvthis, int x, int y, int len) -{ - /* baru5 = bigfonte ... The cache can benefit from it. */ - unsigned char mapu[9] = - { barw, baru1, baru2, baru3, baru4, bigfonte, baru6, baru7, barb }; - /* bard5 = bigfontf ... The cache can benefit from it. */ -/* - unsigned char mapd[9] = - { barw, bard1, bard2, bard3, bard4, bigfontf, bard6, bard7, barb }; -*/ - - - PrivateData * p = drvthis->private_data; - - debug(RPT_DEBUG, "MtxOrb: vertical bar at %d set to %d", x, len); - -/* REMOVE THE NEXT LINE FOR TESTING ONLY... */ -/* len=-len; */ /* This is to test negative len. */ -/* REMOVE THE PREVIOUS LINE FOR TESTING ONLY... */ - - if (len > 0) { - for ( ; (y > 0) && (len > 0); y--) { - if (len >= p->cellheight) - MtxOrb_icon(drvthis, x, y, barb); - else - MtxOrb_icon(drvthis, x, y, mapu[len]); - - len -= p->cellheight; - } -/* - } else { - len = -len; - for (y = 2; y <= p->height && len > 0; y++) { - if (len >= p->cellheight) - MtxOrb_icon (drvthis, x, y, barb); - else - MtxOrb_icon (drvthis, x, y, mapd[len]); - - len -= p->cellheight; - } -*/ - } - -} - - -/* TODO: Finish the support for bar growing reverse way. - * TODO: Migrate to the new hbar. - ****************************** - * Draws a horizontal bar to the right. - * This is the new version ussing dynamic icon alocation - */ -static void MtxOrb_old_hbar (Driver *drvthis, int x, int y, int len) -{ - unsigned char mapr[6] = { barw, barr1, barr2, barr3, barr4, barb }; -/* - unsigned char mapl[6] = { barw, barl1, barl2, barl3, barl4, barb }; -*/ - - PrivateData * p = drvthis->private_data; - - ValidX(x); - ValidY(y); - - debug(RPT_DEBUG, "MtxOrb: horizontal bar at %d set to %d", x, len); - - if (len > 0) { - for ( ; (x <= p->width) && (len > 0); x++) { - if (len >= p->cellwidth) - MtxOrb_icon(drvthis, x, y, barb); - else - MtxOrb_icon(drvthis, x, y, mapr[len]); - - len -= p->cellwidth; - } -/* - } else { - len = -len; - for (; x > 0 && len > 0; x--) { - if (len >= p->cellwidth) - MtxOrb_icon (drvthis, x, y, barb); - else - MtxOrb_icon (drvthis, x, y, mapl[len]); - - len -= p->cellwidth; - - } -*/ - } - -} - - -///////////////////////////////////////////////////////////////// -// Draws a vertical bar... -// MODULE_EXPORT void MtxOrb_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 - * (other direction not yet implemented). - * len is the number of characters that the bar is long at 100% - * promille is the number of promilles (0..1000) - * that the bar should be filled. - */ + PrivateData *p = drvthis->private_data; - PrivateData * p = drvthis->private_data; - int total_pixels = ((long) 2 * len * p->cellwidth + 1) * promille / 2000; + if (p->ccmode != vbar) { + unsigned char vBar[p->cellheight]; + int i; - /* - * This function does not fully implement API V0.5 - * It is an adaptation layer using the API V0.4 function. - * Ideally it should use the library but then the library - * need to be enhanced with the idea privately exchange - * between David & Joris. - */ + 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; - MtxOrb_mold_vbar(drvthis, x, y, total_pixels); - // this is what's in the library for it: - // lib_vbar_static(drvthis, x, y, len, promille, options, p->cellheight, 0); + memset(vBar, 0x00, sizeof(vBar)); + + for (i = 1; i < p->cellheight; i++) { + // add pixel line per pixel line ... + vBar[p->cellheight - i] = 0xFF; + MtxOrb_set_char(drvthis, i, vBar); + } + } + + lib_vbar_static(drvthis, x, y, len, promille, options, p->cellheight, 0); } -///////////////////////////////////////////////////////////////// -// Draws a horizontal bar to the right. -// + +/** + * Draw a horizontal bar to the right. + * \param drvthis Pointer to driver structure. + * \param x Horizontal character position (column) of the starting point. + * \param y Vertical character position (row) of the starting point. + * \param len Number of characters that the bar is long at 100% + * \param promille Current length level of the bar in promille. + * \param options Options (currently unused). + */ MODULE_EXPORT void MtxOrb_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 - * (other direction not yet implemented). - * len is the number of characters that the bar is long at 100% - * promille is the number of promilles (0..1000) - * that the bar should be filled. - */ + PrivateData *p = drvthis->private_data; - PrivateData * p = drvthis->private_data; - int total_pixels = ((long) 2 * len * p->cellwidth + 1) * promille / 2000; + if (p->ccmode != hbar) { + unsigned char hBar[p->cellheight]; + int i; - /* - * This function does not fully implement API V0.5 - * It is an adaptation layer using the API V0.4 function. - * Ideally it should use the library but then the library - * need to be enhanced with the idea privately exchange - * between David & Joris. - */ + 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; - MtxOrb_old_hbar(drvthis, x, y, total_pixels); - // this is what's in the library for it: - // lib_hbar_static(drvthis, x, y, len, promille, options, p->cellwidth, 0); -} + memset(hBar, 0x00, sizeof(hBar)); - -/* TODO: MtxOrb_set_char is doing the job "real-time" as oppose - * to at flush time. Call to this function should be done in flush - * this mean in raw_frame. GLU - ****************************** - * Writes a big number. - */ -MODULE_EXPORT void -MtxOrb_num (Driver *drvthis, int pos, int val) -{ - int x, y; - int c; - - if ((val < 0) || (val > 10)) - return; - - debug(RPT_DEBUG, "MtxOrb: write big number %d at %d", val, pos); - - /* Currently we are bignum but if bigalpha is there remove this line */ - c = val + '0'; /* We transform from 0-9 to 'O' to '9' */ - - if ((pos < -2) || (pos > 20)) /* are we outisde the visible spectrum */ - return; - if ((c < 32) || (c > 127)) /* are we characteristic or not? */ - return; - - c -= 32; - - /* printf("pos: %d char: %d val: %d\n", pos, c, val); */ - for (y = 0; y < 4; y++) { - for (x = 0; x < 3; x++) { - MtxOrb_icon(drvthis, x+pos, y+1, START_FONT + normal[c][x + (y * 3)]); + 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); + MtxOrb_set_char(drvthis, i, hBar); } } + + lib_hbar_static(drvthis, x, y, len, promille, options, p->cellwidth, 0); } -/* TODO: Every time we define a custom char within the LCD, - * we have to compute the binary value we are going to use. - * It is easy to keep the bitmap in this source file, - * but we compute that once rather than every time. GLU - * - * TODO: MtxOrb_set_char is doing the job "real-time" as oppose - * to at flush time. Call to this function should be done in flush. GLU - * - * TODO: We make one 3 bytes write folowed by cellheight one byte - * write. This should be done in one single write. GLU - */ -#define MAX_CUSTOM_CHARS 7 - -/****************************** - * Sets a custom character from 0-7... - * - * The input is just an array of characters... +/** + * Write a big number to the screen. + * \param drvthis Pointer to driver structure. + * \param x Horizontal character position (column). + * \param num Character to write (0 - 10 with 10 representing ':') */ MODULE_EXPORT void -MtxOrb_set_char (Driver *drvthis, int n, char *dat) +MtxOrb_num (Driver *drvthis, int x, int num) { - char out[4]; - int row, col; - int letter; + PrivateData *p = drvthis->private_data; + int do_init = 0; - PrivateData * p = drvthis->private_data; + if ((num < 0) || (num > 10)) + return; - if ((n < 0) || (n > MAX_CUSTOM_CHARS)) + 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); +} + + +/** + * Get number of custom chars available. + * \param drvthis Pointer to driver structure. + * \returns Number of custom characters (always NUM_CCs). + */ +MODULE_EXPORT int +MtxOrb_get_free_chars (Driver *drvthis) +{ +//PrivateData *p = drvthis->private_data; + + return NUM_CCs; +} + + +/** + * 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 8(=cellheight) 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 +MtxOrb_set_char (Driver *drvthis, int n, unsigned char *dat) +{ + PrivateData *p = drvthis->private_data; + unsigned char out[12] = { '\xFE', 'N', 0, 0,0,0,0,0,0,0,0 };; + unsigned char mask = (1 << p->cellwidth) - 1; + int row; + + if ((n < 0) || (n >= NUM_CCs)) return; if (!dat) return; - snprintf(out, sizeof(out), "\x0FEN%c", n); - write(p->fd, out, 3); + out[2] = n; /* Custom char to define. xxx */ for (row = 0; row < p->cellheight; row++) { - letter = 0; - for (col = 0; col < p->cellwidth; col++) { - /* shift to make room for new scan line data */ - letter <<= 1; - /* Now read a single bit of data - * -- one entry in dat[] -- - * and add it to the binary data in "letter" - */ - letter |= (dat[(row * p->cellwidth) + col] > 0); - } - write(p->fd, &letter, 1); /* write one character for each row */ + out[row+3] = dat[row] & mask; } + write(p->fd, out, 11); } -/* TODO: This is not yet my idea of icon frame buffer but it work well. +/** + * Place an icon on the screen. + * \param drvthis Pointer to driver structure. + * \param x Horizontal character position (column). + * \param y Vertical character position (row). + * \param icon synbolic value representing the icon. + * \return Information whether the icon is handled here or needs to be handled by the server core. */ MODULE_EXPORT int MtxOrb_icon (Driver *drvthis, int x, int y, int icon) { - return -1; - /* Does not use current icon definitions */ +// PrivateData *p = drvthis->private_data; - MtxOrb_chr(drvthis, x, y, MtxOrb_ask_bar (drvthis, icon)); + 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: + MtxOrb_chr(drvthis, x, y, 255); + break; + case ICON_HEART_FILLED: + MtxOrb_set_char(drvthis, 0, heart_filled); + MtxOrb_chr(drvthis, x, y, 0); + break; + case ICON_HEART_OPEN: + MtxOrb_set_char(drvthis, 0, heart_open); + MtxOrb_chr(drvthis, x, y, 0); + break; + case ICON_ARROW_UP: + MtxOrb_set_char(drvthis, 1, arrow_up); + MtxOrb_chr(drvthis, x, y, 1); + case ICON_ARROW_DOWN: + MtxOrb_set_char(drvthis, 2, arrow_down); + MtxOrb_chr(drvthis, x, y, 2); + break; + case ICON_ARROW_LEFT: + MtxOrb_chr(drvthis, x, y, 0x7F); + break; + case ICON_ARROW_RIGHT: + MtxOrb_chr(drvthis, x, y, 0x7E); + break; + case ICON_CHECKBOX_OFF: + MtxOrb_set_char(drvthis, 3, checkbox_off); + MtxOrb_chr(drvthis, x, y, 3); + break; + case ICON_CHECKBOX_ON: + MtxOrb_set_char(drvthis, 4, checkbox_on); + MtxOrb_chr(drvthis, x, y, 4); + break; + case ICON_CHECKBOX_GRAY: + MtxOrb_set_char(drvthis, 5, checkbox_gray); + MtxOrb_chr(drvthis, x, y, 5); + break; + default: + return -1; /* Let the core do other icons */ + } + return 0; } -/* TODO: Recover the code for I2C connectivity to MtxOrb + +/** + * Set cursor position and state. + * \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 +MtxOrb_cursor (Driver *drvthis, int x, int y, int state) +{ + PrivateData *p = (PrivateData *) drvthis->private_data; + + /* set cursor state */ + switch (state) { + case CURSOR_OFF: // no cursor + write(p->fd, "\xFE" "K", 2); + break; + case CURSOR_UNDER: // underline cursor + case CURSOR_BLOCK: // inverting blinking block + case CURSOR_DEFAULT_ON: // blinking block + default: + write(p->fd, "\xFE" "J", 2); + break; + } + + /* set cursor position */ + MtxOrb_cursor_goto(drvthis, x, y); +} + + +/** + * Get key from the LCD/VFD. + * \param drvthis Pointer to driver structure. + * \return String representation of the key. + * + * \todo Recover the code for I2C connectivity to MtxOrb * and don't query the LCD if it does not support keypad. * Otherwise crash of the LCD and/or I2C bus. - * - ****************************** - * returns a string for the function characters from the keypad... - * (A-Z) on success, 0 on failure... - */ - -/* - * Return one char from the KeyRing */ MODULE_EXPORT const char * MtxOrb_get_key (Driver *drvthis) { - PrivateData * p = drvthis->private_data; - + PrivateData *p = drvthis->private_data; char in = 0; + struct pollfd fds[1]; // POLL For data or return - struct pollfd fds[1]; fds[0].fd = p->fd; fds[0].events = POLLIN; fds[0].revents = 0; @@ -1274,483 +1406,34 @@ MtxOrb_get_key (Driver *drvthis) } -/************************************************************************* - * Ask for allocation of a custom caracter to be a well known graphic. - * The function is suppose to return a value between 0 and 7. - * 0 is NOT reserver anymore for heartbeat or icon. - * This function manadge a cache of graphical caracter in use. - */ -static int -MtxOrb_ask_bar (Driver *drvthis, int type) -{ - int i; - int pos; - int last_not_in_use; - - PrivateData * p = drvthis->private_data; - -/* fprintf(stderr, "GLU: MtxOrb_ask_bar(%d).\n", type); */ - -/* This bypass the search for WHITE and BLACK */ - if (type == barw) - return 32; - if (type == barb) - return 255; - - /* If the screen was clear then no graphic caracter are in use yet. */ - if (p->clear) { - for (pos = 0; pos < 8; pos++) - p->use[pos] = 0; - p->clear = 0; - } - - /* Search for a match with caracter already defined. */ - pos = 8; /* Not found. */ - for (i = 0; i < 8; i++) { /* For all including heartbeat. */ - if (p->def[i] == type) - pos = i; /* Founded (should break now). */ - } - - if (pos == 8) { - last_not_in_use = 8; /* No empty slot to reuse. */ -/* fprintf(stderr, "GLU: MtxOrb_ask_bar| not found.\n"); */ - p->circular = (p->circular + 1) % 8; - - for (i = 0; i < 8; i++) { - if (!p->use[(i + p->circular) % 8]) - last_not_in_use = (i + p->circular) % 8; - } - pos = last_not_in_use; - } - - if (pos != 8) { - /* A character is found (Best match could solve our problem). - * REMOVE: fprintf(stderr, "GLU: MtxOrb_ask_bar| found at %d.\n", pos); - */ - if (p->def[pos] != type) { - MtxOrb_set_known_char(drvthis, pos, type); - /* fprintf(stderr, "GLU: MtxOrb_ask_bar [Set a char] pos: %d.\n", pos); */ - /* Define a new graphic caracter. */ - p->def[pos] = type; - /* Remember that now the caracter is available. */ - } - if (!p->use[pos]) { - /* If the caracter is no yet in use (but defined). */ - p->use[pos] = 1; - /* Remember it is in use (so protect it from re-use). */ - } - } - if (pos == 8) { - /* pos = 65; ("A")? */ - switch (type) { - case baru1: pos = '_'; break; - case baru2: pos = '.'; break; - case baru3: pos = ','; break; - case baru4: pos = 'o'; break; - case baru5: pos = 'o'; break; - case baru6: pos = 'O'; break; - case baru7: pos = '8'; break; - case bard1: pos = '\''; break; - case bard2: pos = '"'; break; - case bard3: pos = '^'; break; - case bard4: pos = '^'; break; - case bard5: pos = '*'; break; - case bard6: pos = 'O'; break; - case bard7: pos = '8'; break; - case barr1: pos = '-'; break; - case barr2: pos = '-'; break; - case barr3: pos = '='; break; - case barr4: pos = '='; break; - case barl1: pos = '-'; break; - case barl2: pos = '-'; break; - case barl3: pos = '='; break; - case barl4: pos = '='; break; - case barw: pos = ' '; break; - case barb: pos = 255; break; - - case bigfonta: pos = '\\'; break; - case bigfontb: pos = '/'; break; - case bigfontc: pos = '\\'; break; - case bigfontd: pos = '\\'; break; - case bigfonte: pos = '-'; break; - case bigfontf: pos = '-'; break; - case bigfontg: pos = '\\'; break; - case bigfonth: pos = '/'; break; - - case play: pos = 'P'; break; - case fforward: pos = '>'; break; - case frewind: pos = '<'; break; - case uparrow: pos = '^'; break; - case downarrow: pos = 'v'; break; - default: pos = '?'; break; - } - } - - return pos; -} - -/****************************** - * Sets up a well known character for use. - */ -static void -MtxOrb_set_known_char (Driver *drvthis, int car, int type) -{ - char all_bar[39][5 * 8] = { -/* Here start 3 standard icons used by heartbeat and other. */ - { - 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, - }, { - 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, - }, { - 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, - }, -/* This is not suppose to be standard icon, just I don't want to lose them. - * They come directly from the old patch for bignum any MP3 player love them. - */ - { - 0, 1, 0, 0, 0, /* Play */ - 0, 1, 1, 0, 0, - 0, 1, 1, 1, 0, - 0, 1, 1, 1, 1, - 0, 1, 1, 1, 0, - 0, 1, 1, 0, 0, - 0, 1, 0, 0, 0, - 0, 0, 0, 0, 0, - }, { - 0, 0, 0, 0, 0, /* FForward */ - 1, 0, 1, 0, 0, - 1, 1, 0, 1, 0, - 1, 1, 1, 0, 1, - 1, 1, 0, 1, 0, - 1, 0, 1, 0, 0, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - }, { - 0, 0, 0, 0, 0, /* FRewind */ - 0, 0, 1, 0, 1, - 0, 1, 0, 1, 1, - 1, 0, 1, 1, 1, - 0, 1, 0, 1, 1, - 0, 0, 1, 0, 1, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - }, { - 0, 0, 1, 0, 0, /* Up arrow */ - 0, 1, 1, 1, 0, - 1, 1, 1, 1, 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, - }, { - 0, 0, 1, 0, 0, /* Down arrow */ - 0, 0, 1, 0, 0, - 0, 0, 1, 0, 0, - 0, 0, 1, 0, 0, - 1, 1, 1, 1, 1, - 0, 1, 1, 1, 0, - 0, 0, 1, 0, 0, - 0, 0, 0, 0, 0, - }, -/* Here start the bar stuff */ - { - 0, 0, 0, 0, 0, /* char u1[] = */ - 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, 0, 0, 0, 0, /* char u2[] = */ - 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, - }, { - 0, 0, 0, 0, 0, /* char u3[] = */ - 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, - }, { - 0, 0, 0, 0, 0, /* char u4[] = */ - 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, - }, { - 0, 0, 0, 0, 0, /* char u5[] = */ - 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, - }, { - 0, 0, 0, 0, 0, /* char u6[] = */ - 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, - }, { - 0, 0, 0, 0, 0, /* char u7[] = */ - 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, /* char d1[] = */ - 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 d2[] = */ - 1, 1, 1, 1, 1, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - }, { - 1, 1, 1, 1, 1, /* char d3[] = */ - 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - }, { - 1, 1, 1, 1, 1, /* char d4[] = */ - 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, - 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 d5[] = */ - 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - }, { - 1, 1, 1, 1, 1, /* char d6[] = */ - 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, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - }, { - 1, 1, 1, 1, 1, /* char d7[] = */ - 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, - 0, 0, 0, 0, 0, - }, { - 1, 0, 0, 0, 0, /* char r1[] = */ - 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, 1, 0, 0, 0, /* char r2[] = */ - 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, 1, 0, 0, /* char r3[] = */ - 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, 1, 0, /* char r4[] = */ - 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, - }, { - 0, 0, 0, 0, 1, /* char l1[] = */ - 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, 1, 1, /* char l2[] = */ - 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, 1, 1, 1, /* char l3[] = */ - 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, 1, 1, 1, 1, /* char l4[] = */ - 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, - }, -/* Here start the 8 basic block used by bigfont.h */ - { /* char a[] */ - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 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, - }, { /* char b[] */ - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1, - 0, 0, 0, 1, 1, - 0, 0, 1, 1, 1, - 0, 1, 1, 1, 1, - 1, 1, 1, 1, 1, - }, { /* char c[] */ - 1, 1, 1, 1, 1, - 0, 1, 1, 1, 1, - 0, 0, 1, 1, 1, - 0, 0, 0, 1, 1, - 0, 0, 0, 0, 1, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - }, { /* char d[] */ - 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, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - }, { /* char e[] = u5 */ - 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[] = d5 */ - 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, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - }, { /* char g[] */ - 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, - 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, - }, { /* char h[] */ - 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, - 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, - } - }; - - MtxOrb_set_char(drvthis, car, &all_bar[type][0]); -} - +/* + static unsigned char play[] = + { b___X___, + b___XX__, + b___XXX_, + b___XXXX, + b___XXX_, + b___XX__, + b___X___, + b_______ }; + static unsigned char fforward[] = + { b_______, + b__X_X__, + b__XX_X_, + b__XXX_X, + b__XX_X_, + b__X_X__, + b_______, + b_______ }; + static unsigned char frewind[] = + { b_______, + b____X_X, + b___X_XX, + b__X_XXX, + b___X_XX, + b____X_X, + b_______, + b_______ }; +*/ +/* EOF */ diff --git a/server/drivers/MtxOrb.h b/server/drivers/MtxOrb.h index 0ea7b6f..767a8f0 100644 --- a/server/drivers/MtxOrb.h +++ b/server/drivers/MtxOrb.h @@ -15,26 +15,27 @@ MODULE_EXPORT int MtxOrb_init (Driver *drvthis); MODULE_EXPORT void MtxOrb_close (Driver *drvthis); MODULE_EXPORT int MtxOrb_width (Driver *drvthis); MODULE_EXPORT int MtxOrb_height (Driver *drvthis); +MODULE_EXPORT int MtxOrb_cellwidth (Driver *drvthis); +MODULE_EXPORT int MtxOrb_cellheight (Driver *drvthis); MODULE_EXPORT void MtxOrb_clear (Driver *drvthis); MODULE_EXPORT void MtxOrb_flush (Driver *drvthis); -MODULE_EXPORT void MtxOrb_string (Driver *drvthis, int x, int y, char *string); +MODULE_EXPORT void MtxOrb_string (Driver *drvthis, int x, int y, char string[]); MODULE_EXPORT void MtxOrb_chr (Driver *drvthis, int x, int y, char c); +MODULE_EXPORT const char * MtxOrb_get_key (Driver *drvthis); -MODULE_EXPORT void MtxOrb_set_char (Driver *drvthis, int n, char *dat); +MODULE_EXPORT void MtxOrb_vbar (Driver * drvthis, int x, int y, int len, int promille, int options); +MODULE_EXPORT void MtxOrb_hbar (Driver * drvthis, int x, int y, int len, int promille, int options); +MODULE_EXPORT int MtxOrb_icon (Driver *drvthis, int x, int y, int icon); +MODULE_EXPORT void MtxOrb_num (Driver *drvthis, int x, int num); +MODULE_EXPORT void MtxOrb_cursor (Driver *drvthis, int x, int y, int state); + +MODULE_EXPORT int MtxOrb_get_free_chars (Driver *drvthis); +MODULE_EXPORT void MtxOrb_set_char (Driver *drvthis, int n, unsigned char *dat); MODULE_EXPORT int MtxOrb_get_contrast (Driver *drvthis); MODULE_EXPORT void MtxOrb_set_contrast (Driver *drvthis, int promille); MODULE_EXPORT void MtxOrb_backlight (Driver *drvthis, int on); -MODULE_EXPORT void MtxOrb_output (Driver *drvthis, int on); - -MODULE_EXPORT const char * MtxOrb_get_key (Driver *drvthis); +MODULE_EXPORT void MtxOrb_output (Driver *drvthis, int state); MODULE_EXPORT const char * MtxOrb_get_info (Driver *drvthis); -MODULE_EXPORT void MtxOrb_num (Driver *drvthis, int x, int num); - -MODULE_EXPORT int MtxOrb_icon (Driver *drvthis, int x, int y, int icon); -MODULE_EXPORT void MtxOrb_vbar (Driver * drvthis, int x, int y, int len, int promille, int options); -MODULE_EXPORT void MtxOrb_hbar (Driver * drvthis, int x, int y, int len, int promille, int options); - -#endif - +#endif /* MTXORB_H */