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