aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile.am2
-rw-r--r--Makefile.in20
-rw-r--r--drv_MatrixOrbital.c513
-rw-r--r--drv_generic.c292
-rw-r--r--drv_generic.h74
-rw-r--r--drv_generic_bar.c471
-rw-r--r--drv_generic_bar.h43
-rw-r--r--lcd4linux.conf.sample19
-rw-r--r--widget_bar.c78
-rw-r--r--widget_bar.h15
-rw-r--r--widget_text.c7
11 files changed, 1092 insertions, 442 deletions
diff --git a/Makefile.am b/Makefile.am
index d0b5732..c11e881 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -54,6 +54,8 @@ imon.c imon.h \
\
display.c display.h \
drv.c drv.h \
+drv_generic.c drv_generic.h \
+drv_generic_bar.c \
debug.c debug.h \
cfg.c cfg.h \
lock.c lock.h \
diff --git a/Makefile.in b/Makefile.in
index 9d903e3..18a2148 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -106,7 +106,7 @@ lcd4linux_LDADD = @DRIVERS@ @DRVLIBS@
#remove next line for liblcd4linux
lcd4linux_DEPENDENCIES = @DRIVERS@
-lcd4linux_SOURCES = lcd4linux.c pid.c pid.h hash.c hash.h parser.c parser.h processor.c processor.h layout.c layout.h timer.c timer.h evaluator.c evaluator.h widget.c widget.h widget_text.c widget_text.h widget_bar.c widget_bar.h plugin.c plugin.h plugin_math.c plugin_string.c plugin_cfg.c plugin_uname.c plugin_loadavg.c plugin_proc_stat.c plugin_cpuinfo.c plugin_meminfo.c plugin_i2c_sensors.c plugin_xmms.c system.c system.h isdn.c isdn.h wifi.c wifi.h mail.c mail.h seti.c seti.h battery.c battery.h dvb.c dvb.h filter.c filter.h exec.c exec.h expr.c expr.h mail2.c socket.c socket.h imon.c imon.h display.c display.h drv.c drv.h debug.c debug.h cfg.c cfg.h lock.c lock.h pixmap.c pixmap.h bar.c bar.h icon.c icon.h fontmap.c fontmap.h udelay.c udelay.h
+lcd4linux_SOURCES = lcd4linux.c pid.c pid.h hash.c hash.h parser.c parser.h processor.c processor.h layout.c layout.h timer.c timer.h evaluator.c evaluator.h widget.c widget.h widget_text.c widget_text.h widget_bar.c widget_bar.h plugin.c plugin.h plugin_math.c plugin_string.c plugin_cfg.c plugin_uname.c plugin_loadavg.c plugin_proc_stat.c plugin_cpuinfo.c plugin_meminfo.c plugin_i2c_sensors.c plugin_xmms.c system.c system.h isdn.c isdn.h wifi.c wifi.h mail.c mail.h seti.c seti.h battery.c battery.h dvb.c dvb.h filter.c filter.h exec.c exec.h expr.c expr.h mail2.c socket.c socket.h imon.c imon.h display.c display.h drv.c drv.h drv_generic.c drv_generic.h drv_generic_bar.c debug.c debug.h cfg.c cfg.h lock.c lock.h pixmap.c pixmap.h bar.c bar.h icon.c icon.h fontmap.c fontmap.h udelay.c udelay.h
#liblcd4linux_la_DEPENDENCIES = @DRIVERS@
@@ -157,9 +157,10 @@ plugin_i2c_sensors.$(OBJEXT) plugin_xmms.$(OBJEXT) system.$(OBJEXT) \
isdn.$(OBJEXT) wifi.$(OBJEXT) mail.$(OBJEXT) seti.$(OBJEXT) \
battery.$(OBJEXT) dvb.$(OBJEXT) filter.$(OBJEXT) exec.$(OBJEXT) \
expr.$(OBJEXT) mail2.$(OBJEXT) socket.$(OBJEXT) imon.$(OBJEXT) \
-display.$(OBJEXT) drv.$(OBJEXT) debug.$(OBJEXT) cfg.$(OBJEXT) \
-lock.$(OBJEXT) pixmap.$(OBJEXT) bar.$(OBJEXT) icon.$(OBJEXT) \
-fontmap.$(OBJEXT) udelay.$(OBJEXT)
+display.$(OBJEXT) drv.$(OBJEXT) drv_generic.$(OBJEXT) \
+drv_generic_bar.$(OBJEXT) debug.$(OBJEXT) cfg.$(OBJEXT) lock.$(OBJEXT) \
+pixmap.$(OBJEXT) bar.$(OBJEXT) icon.$(OBJEXT) fontmap.$(OBJEXT) \
+udelay.$(OBJEXT)
CFLAGS = @CFLAGS@
COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
@@ -180,11 +181,12 @@ DEP_FILES = .deps/BeckmannEgle.P .deps/Crystalfontz.P .deps/Cwlinux.P \
.deps/MilfordInstruments.P .deps/PalmPilot.P .deps/Raster.P .deps/SIN.P \
.deps/T6963.P .deps/Text.P .deps/USBLCD.P .deps/XWindow.P .deps/bar.P \
.deps/battery.P .deps/cfg.P .deps/debug.P .deps/display.P .deps/drv.P \
-.deps/drv_MatrixOrbital.P .deps/dvb.P .deps/evaluator.P .deps/exec.P \
-.deps/expr.P .deps/filter.P .deps/fontmap.P .deps/hash.P .deps/icon.P \
-.deps/imon.P .deps/isdn.P .deps/layout.P .deps/lcd4linux.P .deps/lock.P \
-.deps/mail.P .deps/mail2.P .deps/parport.P .deps/parser.P .deps/pid.P \
-.deps/pixmap.P .deps/plugin.P .deps/plugin_cfg.P .deps/plugin_cpuinfo.P \
+.deps/drv_MatrixOrbital.P .deps/drv_generic.P .deps/drv_generic_bar.P \
+.deps/dvb.P .deps/evaluator.P .deps/exec.P .deps/expr.P .deps/filter.P \
+.deps/fontmap.P .deps/hash.P .deps/icon.P .deps/imon.P .deps/isdn.P \
+.deps/layout.P .deps/lcd4linux.P .deps/lock.P .deps/mail.P \
+.deps/mail2.P .deps/parport.P .deps/parser.P .deps/pid.P .deps/pixmap.P \
+.deps/plugin.P .deps/plugin_cfg.P .deps/plugin_cpuinfo.P \
.deps/plugin_i2c_sensors.P .deps/plugin_loadavg.P .deps/plugin_math.P \
.deps/plugin_meminfo.P .deps/plugin_proc_stat.P .deps/plugin_string.P \
.deps/plugin_uname.P .deps/plugin_xmms.P .deps/processor.P .deps/seti.P \
diff --git a/drv_MatrixOrbital.c b/drv_MatrixOrbital.c
index 96692ae..1fb70d6 100644
--- a/drv_MatrixOrbital.c
+++ b/drv_MatrixOrbital.c
@@ -1,4 +1,4 @@
-/* $Id: drv_MatrixOrbital.c,v 1.9 2004/01/18 21:25:16 reinelt Exp $
+/* $Id: drv_MatrixOrbital.c,v 1.10 2004/01/20 04:51:39 reinelt Exp $
*
* new style driver for Matrix Orbital serial display modules
*
@@ -23,6 +23,10 @@
*
*
* $Log: drv_MatrixOrbital.c,v $
+ * Revision 1.10 2004/01/20 04:51:39 reinelt
+ * moved generic stuff from drv_MatrixOrbital to drv_generic
+ * implemented new-stylish bars which are nearly finished
+ *
* Revision 1.9 2004/01/18 21:25:16 reinelt
* Framework for bar widget opened
*
@@ -84,31 +88,22 @@
#include "cfg.h"
#include "plugin.h"
#include "lock.h"
-#include "drv.h"
-#include "bar.h"
-#include "icon.h"
#include "widget.h"
#include "widget_text.h"
#include "widget_bar.h"
+#include "drv.h"
+#include "drv_generic.h"
+#include "drv_generic_bar.h"
-// these values are hardcoded
-#define XRES 5
-#define YRES 8
-#define CHARS 8
+static char Name[]="MatrixOrbital";
-static char *Port=NULL;
-static speed_t Speed;
-static int Device=-1;
static int Model;
-static int DROWS, DCOLS; // display size
-static int LROWS, LCOLS; // layout size
static int GPOS, ICONS, PROTOCOL;
-static char *LayoutFB=NULL;
-static char *DisplayFB=NULL;
-static int GPO[8];
+// Fixme:
+// static int GPO[8];
typedef struct {
@@ -153,105 +148,17 @@ static MODEL Models[] = {
};
-static int drv_MO_open (void)
-{
- int fd;
- pid_t pid;
- struct termios portset;
-
- if ((pid=lock_port(Port))!=0) {
- if (pid==-1)
- error ("MatrixOrbital: port %s could not be locked", Port);
- else
- error ("MatrixOrbital: port %s is locked by process %d", Port, pid);
- return -1;
- }
- fd = open(Port, O_RDWR | O_NOCTTY | O_NDELAY);
- if (fd==-1) {
- error ("MatrixOrbital: open(%s) failed: %s", Port, strerror(errno));
- unlock_port(Port);
- return -1;
- }
- if (tcgetattr(fd, &portset)==-1) {
- error ("MatrixOrbital: tcgetattr(%s) failed: %s", Port, strerror(errno));
- unlock_port(Port);
- return -1;
- }
- cfmakeraw(&portset);
- cfsetospeed(&portset, Speed);
- if (tcsetattr(fd, TCSANOW, &portset)==-1) {
- error ("MatrixOrbital: tcsetattr(%s) failed: %s", Port, strerror(errno));
- unlock_port(Port);
- return -1;
- }
- return fd;
-}
-
-
-static int drv_MO_read (char *string, int len)
-{
- int run, ret;
-
- if (Device==-1) return -1;
- for (run=0; run<10; run++) {
- ret=read (Device, string, len);
- if (ret>=0 || errno!=EAGAIN) break;
- debug ("read(): EAGAIN");
- usleep(1000);
- }
-
- if (ret<0) {
- error("MatrixOrbital: read(%s, %d) failed: %s", Port, len, strerror(errno));
- }
-
- return ret;
-}
-
-
-static void drv_MO_write (char *string, int len)
-{
- int run, ret;
-
- if (Device==-1) return;
- for (run=0; run<10; run++) {
- ret=write (Device, string, len);
- if (ret>=0 || errno!=EAGAIN) break;
- debug ("write(): EAGAIN");
- usleep(1000);
- }
-
- if (ret<0) {
- error ("MatrixOrbital: write(%s) failed: %s", Port, strerror(errno));
- }
-
- // Fixme
- if (ret!=len) {
- error ("MatrixOrbital: partial write: len=%d ret=%d", len, ret);
- }
-
- return;
-}
-
-
-static int drv_MO_contrast (int contrast)
-{
- char buffer[4];
-
- if (contrast<0 ) contrast=0;
- if (contrast>255) contrast=255;
- snprintf (buffer, 4, "\376P%c", contrast);
- drv_MO_write (buffer, 3);
- return contrast;
-}
-
+// ****************************************
+// *** hardware dependant functions ***
+// ****************************************
static void drv_MO_define_char (int ascii, char *buffer)
{
char cmd[3]="\376N";
cmd[2]=(char)ascii;
- drv_MO_write (cmd, 3);
- drv_MO_write (buffer, 8);
+ drv_generic_serial_write (cmd, 3);
+ drv_generic_serial_write (buffer, 8);
}
@@ -260,79 +167,7 @@ static void drv_MO_goto (int row, int col)
char cmd[5]="\376Gyx";
cmd[2]=(char)col+1;
cmd[3]=(char)row+1;
- drv_MO_write(cmd,4);
-}
-
-
-static int drv_MO_clear (int full)
-{
- int gpo;
-
- memset (LayoutFB, ' ', LROWS*LCOLS*sizeof(char));
-
- icon_clear();
- bar_clear();
- memset(GPO, 0, sizeof(GPO));
-
- if (full) {
- memset (DisplayFB, ' ', DROWS*DCOLS*sizeof(char));
- switch (PROTOCOL) {
- case 1:
- drv_MO_write ("\014", 1); // Clear Screen
- drv_MO_write ("\376V", 2); // GPO off
- break;
- case 2:
- drv_MO_write ("\376\130", 2); // Clear Screen
- for (gpo=1; gpo<=GPOS; gpo++) {
- char cmd1[3]="\376V";
- char cmd2[4]="\376\300x\377";
- cmd1[2]=(char)gpo;
- cmd2[2]=(char)gpo;
- drv_MO_write (cmd1, 3); // GPO off
- drv_MO_write (cmd2, 4); // PWM full power
- }
- break;
- }
- }
-
- return 0;
-}
-
-static int drv_MO_put (int row, int col, char *text)
-{
- char *p=LayoutFB+row*DCOLS+col;
- char *t=text;
-
- while (*t && col++<=DCOLS) {
- *p++=*t++;
- }
- return 0;
-}
-
-
-static int drv_MO_bar (int type, int row, int col, int max, int len1, int len2)
-{
- return bar_draw (type, row, col, max, len1, len2);
-}
-
-
-static int drv_MO_icon (int num, int seq, int row, int col)
-{
- return icon_draw (num, seq, row, col);
-}
-
-
-static int drv_MO_gpo (int num, int val)
-{
- if (num>=GPOS)
- return -1;
-
- GPO[num]=val;
-
- // Fixme
- GPO[num]=255;
-
- return 0;
+ drv_generic_serial_write(cmd,4);
}
@@ -340,98 +175,92 @@ static int drv_MO_gpo (int num, int val)
static int drv_MO_start (char *section)
{
int i;
- char *port, buffer[256];
char *model;
+ char *port, buffer[256];
+ speed_t speed;
- if (Port) {
- free (Port);
- Port=NULL;
- }
-
model=cfg_get(section, "Model", NULL);
if (model!=NULL && *model!='\0') {
for (i=0; Models[i].type!=0xff; i++) {
if (strcasecmp(Models[i].name, model)==0) break;
}
if (Models[i].type==0xff) {
- error ("MatrixOrbital: %s.Model '%s' is unknown from %s", section, model, cfg_source());
+ error ("%s: %s.Model '%s' is unknown from %s", Name, section, model, cfg_source());
return -1;
}
Model=i;
- info ("MatrixOrbital: using model '%s'", Models[Model].name);
+ info ("%s: using model '%s'", Name, Models[Model].name);
} else {
- info ("MatrixOrbital: no '%s.Model' entry from %s, auto-dedecting", section, cfg_source());
+ info ("%s: no '%s.Model' entry from %s, auto-dedecting", Name, section, cfg_source());
Model=-1;
}
port=cfg_get(section, "Port", NULL);
if (port==NULL || *port=='\0') {
- error ("MatrixOrbital: no '%s.Port' entry from %s", section, cfg_source());
+ error ("%s: no '%s.Port' entry from %s", Name, section, cfg_source());
return -1;
}
- Port=strdup(port);
-
+
if (cfg_number(section, "Speed", 19200, 1200, 19200, &i)<0) return -1;
switch (i) {
case 1200:
- Speed=B1200;
+ speed=B1200;
break;
case 2400:
- Speed=B2400;
+ speed=B2400;
break;
case 9600:
- Speed=B9600;
+ speed=B9600;
break;
case 19200:
- Speed=B19200;
+ speed=B19200;
break;
default:
- error ("MatrixOrbital: unsupported speed '%d' from %s", i, cfg_source());
+ error ("%s: unsupported speed '%d' from %s", Name, i, cfg_source());
return -1;
}
- info ("MatrixOrbital: using port '%s' at %d baud", Port, i);
+ info ("%s: using port '%s' at %d baud", Name, port, i);
- Device=drv_MO_open();
- if (Device==-1) return -1;
+ if (drv_generic_serial_open(Name, port, speed)<0) return -1;
// read module type
- drv_MO_write ("\3767", 2);
+ drv_generic_serial_write ("\3767", 2);
usleep(1000);
- if (drv_MO_read (buffer, 1)==1) {
+ if (drv_generic_serial_read (buffer, 1)==1) {
for (i=0; Models[i].type!=0xff; i++) {
if (Models[i].type == (int)*buffer) break;
}
- info ("MatrixOrbital: display reports model '%s' (type 0x%02x)",
- Models[i].name, Models[i].type);
+ info ("%s: display reports model '%s' (type 0x%02x)",
+ Name, Models[i].name, Models[i].type);
// auto-dedection
if (Model==-1) Model=i;
// auto-dedection matches specified model?
if (Models[i].type!=0xff && Model!=i) {
- error ("MatrixOrbital: %s.Model '%s' from %s does not match dedected Model '%s'",
- section, model, cfg_source(), Models[i].name);
+ error ("%s: %s.Model '%s' from %s does not match dedected Model '%s'",
+ Name, section, model, cfg_source(), Models[i].name);
return -1;
}
} else {
- info ("MatrixOrbital: display detection failed.");
+ info ("%s: display detection failed.", Name);
}
// read serial number
- drv_MO_write ("\3765", 2);
+ drv_generic_serial_write ("\3765", 2);
usleep(100000);
- if (drv_MO_read (buffer, 2)==2) {
- info ("MatrixOrbital: display reports serial number 0x%x", *(short*)buffer);
+ if (drv_generic_serial_read (buffer, 2)==2) {
+ info ("%s: display reports serial number 0x%x", Name, *(short*)buffer);
}
// read version number
- drv_MO_write ("\3766", 2);
+ drv_generic_serial_write ("\3766", 2);
usleep(100000);
- if (drv_MO_read (buffer, 1)==1) {
- info ("MatrixOrbital: display reports firmware version 0x%x", *buffer);
+ if (drv_generic_serial_read (buffer, 1)==1) {
+ info ("%s: display reports firmware version 0x%x", Name, *buffer);
}
// initialize global variables
@@ -440,95 +269,28 @@ static int drv_MO_start (char *section)
GPOS = Models[Model].gpos;
PROTOCOL = Models[Model].protocol;
- // init Icons
- if (cfg_number(NULL, "Icons", 0, 0, CHARS, &ICONS)<0) return -1;
- if (ICONS>0) {
- debug ("reserving %d of %d user-defined characters for icons", ICONS, CHARS);
- icon_init(DROWS, DCOLS, XRES, YRES, CHARS, ICONS, drv_MO_define_char);
- }
-
// init Bars
- bar_init(DROWS, DCOLS, XRES, YRES, CHARS-ICONS);
- bar_add_segment( 0, 0,255, 32); // ASCII 32 = blank
- bar_add_segment(255,255,255,255); // ASCII 255 = block
+ // Fixme
+ // bar_init(DROWS, DCOLS, XRES, YRES, CHARS-ICONS);
+ // bar_add_segment( 0, 0,255, 32); // ASCII 32 = blank
+ // bar_add_segment(255,255,255,255); // ASCII 255 = block
- // Fixme: where to init contrast?
- drv_MO_contrast(128);
-
if (PROTOCOL==2)
- drv_MO_write ("\376\130", 2); // Clear Screen
+ drv_generic_serial_write ("\376\130", 2); // Clear Screen
else
- drv_MO_write ("\014", 1); // Clear Screen
+ drv_generic_serial_write ("\014", 1); // Clear Screen
- drv_MO_write ("\376B", 3); // backlight on
- drv_MO_write ("\376K", 2); // cursor off
- drv_MO_write ("\376T", 2); // blink off
- drv_MO_write ("\376D", 2); // line wrapping off
- drv_MO_write ("\376R", 2); // auto scroll off
-
- return 0;
-}
-
+ drv_generic_serial_write ("\376B", 3); // backlight on
+ drv_generic_serial_write ("\376K", 2); // cursor off
+ drv_generic_serial_write ("\376T", 2); // blink off
+ drv_generic_serial_write ("\376D", 2); // line wrapping off
+ drv_generic_serial_write ("\376R", 2); // auto scroll off
-static int drv_MO_flush (void)
-{
- int row, col, pos1, pos2;
- int c, equal;
- int gpo;
-
- bar_process(drv_MO_define_char);
-
- for (row=0; row<DROWS; row++) {
- for (col=0; col<DCOLS; col++) {
- c=bar_peek(row, col);
- if (c==-1) c=icon_peek(row, col);
- if (c!=-1) {
- LayoutFB[row*DCOLS+col]=(char)c;
- }
- }
- for (col=0; col<DCOLS; col++) {
- if (LayoutFB[row*DCOLS+col]==DisplayFB[row*DCOLS+col]) continue;
- drv_MO_goto (row, col);
- for (pos1=col++, pos2=pos1, equal=0; col<DCOLS; col++) {
- if (LayoutFB[row*DCOLS+col]==DisplayFB[row*DCOLS+col]) {
- // If we find just one equal byte, we don't break, because this
- // would require a goto, which takes one byte, too.
- if (++equal>5) break;
- } else {
- pos2=col;
- equal=0;
- }
- }
- drv_MO_write (LayoutFB+row*DCOLS+pos1, pos2-pos1+1);
- }
- }
-
- memcpy (DisplayFB, LayoutFB, DROWS*DCOLS*sizeof(char));
-
- switch (PROTOCOL) {
- case 1:
- if (GPO[0]) {
- drv_MO_write ("\376W", 2); // GPO on
- } else {
- drv_MO_write ("\376V", 2); // GPO off
- }
- break;
- case 2:
- for (gpo=1; gpo<=GPOS; gpo++) {
- char cmd[3]="\376";
- cmd[1]=GPO[gpo]? 'W':'V';
- cmd[2]=(char)gpo;
- drv_MO_write (cmd, 3);
- }
- break;
- }
-
return 0;
}
-
// ****************************************
// *** plugins ***
// ****************************************
@@ -543,7 +305,7 @@ static void plugin_contrast (RESULT *result, RESULT *arg1)
if (contrast<0 ) contrast=0;
if (contrast>255) contrast=255;
snprintf (buffer, 4, "\376P%c", (int)contrast);
- drv_MO_write (buffer, 3);
+ drv_generic_serial_write (buffer, 3);
SetResult(&result, R_NUMBER, &contrast);
}
@@ -560,11 +322,11 @@ static void plugin_backlight (RESULT *result, RESULT *arg1)
if (backlight<0) {
// backlight off
snprintf (buffer, 3, "\376F");
- drv_MO_write (buffer, 2);
+ drv_generic_serial_write (buffer, 2);
} else {
// backlight on for n minutes
snprintf (buffer, 4, "\376B%c", (int)backlight);
- drv_MO_write (buffer, 3);
+ drv_generic_serial_write (buffer, 3);
}
SetResult(&result, R_NUMBER, &backlight);
}
@@ -592,9 +354,9 @@ static void plugin_gpo (RESULT *result, RESULT *arg1, RESULT *arg2)
case 1:
if (num==0) {
if (val>=1.0) {
- drv_MO_write ("\376W", 2); // GPO on
+ drv_generic_serial_write ("\376W", 2); // GPO on
} else {
- drv_MO_write ("\376V", 2); // GPO off
+ drv_generic_serial_write ("\376V", 2); // GPO off
}
} else {
error("Fixme");
@@ -609,7 +371,7 @@ static void plugin_gpo (RESULT *result, RESULT *arg1, RESULT *arg2)
cmd[1]='V'; // GPO off
}
cmd[2]=(char)num;
- drv_MO_write (cmd, 3);
+ drv_generic_serial_write (cmd, 3);
break;
}
@@ -633,7 +395,7 @@ static void plugin_pwm (RESULT *result, RESULT *arg1, RESULT *arg2)
if (val>255.0) val=255.0;
cmd[3]=(char)val;
- drv_MO_write (cmd, 4);
+ drv_generic_serial_write (cmd, 4);
SetResult(&result, R_NUMBER, &val);
}
@@ -651,9 +413,9 @@ static void plugin_rpm (RESULT *result, RESULT *arg1)
if (num>6) num=6;
cmd[2]=(char)num;
- drv_MO_write (cmd, 3);
+ drv_generic_serial_write (cmd, 3);
usleep(100000);
- drv_MO_read (buffer, 7);
+ drv_generic_serial_read (buffer, 7);
debug ("rpm: buffer[0]=0x%01x", buffer[0]);
debug ("rpm: buffer[1]=0x%01x", buffer[1]);
@@ -668,96 +430,19 @@ static void plugin_rpm (RESULT *result, RESULT *arg1)
// ****************************************
-// *** internal helper functions ***
-// ****************************************
-
-static void drv_MO_resize (int rows, int cols)
-{
- char *newFB;
- int row, col;
-
- // Layout FB is large enough
- if (rows<=LROWS && cols<=LCOLS)
- return;
-
- // allocate new Layout FB
- newFB=malloc(cols*rows*sizeof(char));
- memset (newFB, ' ', rows*cols*sizeof(char));
-
- // transfer contents
- if (LayoutFB!=NULL) {
- for (row=0; row<LROWS; row++) {
- for (col=0; col<LCOLS; col++) {
- newFB[row*cols+col]=LayoutFB[row*LCOLS+col];
- }
- }
- free (LayoutFB);
- }
-
- LayoutFB = newFB;
- LCOLS = cols;
- LROWS = rows;
-}
-
-
-// ****************************************
// *** widget callbacks ***
// ****************************************
int drv_MO_draw_text (WIDGET *W)
{
- WIDGET_TEXT *T=W->data;
- char *txt, *fb1, *fb2;
- int row, col, len, end;
-
- debug ("drv_MO_draw_text(%s) x=%2d y=%2d value=<%s>", W->name, W->col, W->row, T->buffer);
-
- row=W->row;
- col=W->col;
- txt=T->buffer;
- len=strlen(txt);
- end=col+len;
-
- // maybe grow layout framebuffer
- drv_MO_resize (W->row, W->col+len-1);
-
- fb1 = LayoutFB + row*LCOLS;
- fb2 = DisplayFB + row*DCOLS;
-
- // transfer new text into layout buffer
- memcpy (fb1+col, txt, len);
-
- for (; col<=end; col++) {
- int pos1, pos2, equal;
- if (fb1[col]==fb2[col]) continue;
- drv_MO_goto (row, col);
- for (pos1=col, pos2=pos1, col++, equal=0; col<=end; col++) {
- if (fb1[col]==fb2[col]) {
- // If we find just one equal byte, we don't break, because this
- // would require a goto, which takes several bytes, too.
- if (++equal>5) break;
- } else {
- pos2=col;
- equal=0;
- }
- }
- memcpy (fb2+pos1, fb1+pos1, pos2-pos1+1);
- drv_MO_write (fb2+pos1, pos2-pos1+1);
- }
-
- return 0;
+ return drv_generic_text_draw_text(W, 5, drv_MO_goto, drv_generic_serial_write);
}
int drv_MO_draw_bar (WIDGET *W)
{
- WIDGET_BAR *B=W->data;
-
- debug ("drv_MO_draw_bar(%s) x=%2d y=%2d ", W->name, W->col, W->row);
-
-
- return 0;
+ return drv_generic_text_draw_bar(W, 5, drv_MO_define_char, drv_MO_goto, drv_generic_serial_write);
}
@@ -784,36 +469,36 @@ int drv_MO_init (char *section)
WIDGET_CLASS wc;
int ret;
+ XRES=5;
+ YRES=8;
+ CHARS=8;
+
// start display
if ((ret=drv_MO_start (section))!=0)
return ret;
- // init display framebuffer
- DisplayFB = (char*)malloc(DCOLS*DROWS*sizeof(char));
- memset (DisplayFB, ' ', DROWS*DCOLS*sizeof(char));
+ // initialize generic text driver
+ if ((ret=drv_generic_text_init(Name))!=0)
+ return ret;
+
+ // initialize generic bar driver
+ if ((ret=drv_generic_text_bar_init())!=0)
+ return ret;
- // init layout framebuffer
- LROWS = 0;
- LCOLS = 0;
- LayoutFB=NULL;
- drv_MO_resize (DROWS, DCOLS);
-
- // sanity check
- if (LayoutFB==NULL || DisplayFB==NULL) {
- error ("MatrixOrbital: framebuffer could not be allocated: malloc() failed");
- return -1;
- }
+ // add fixed chars to the bar driver
+ drv_generic_text_bar_add_segment ( 0, 0,255, 32); // ASCII 32 = blank
+ drv_generic_text_bar_add_segment (255,255,255,255); // ASCII 255 = block
+
+ // register text widget
+ wc=Widget_Text;
+ wc.draw=drv_MO_draw_text;
+ widget_register(&wc);
// register bar widget
wc=Widget_Bar;
wc.draw=drv_MO_draw_bar;
widget_register(&wc);
- // register text widget
- wc=Widget_Text;
- wc.draw=drv_MO_draw_text;
- widget_register(&wc);
-
// register plugins
AddFunction ("contrast", 1, plugin_contrast);
AddFunction ("backlight", 1, plugin_backlight);
@@ -827,29 +512,19 @@ int drv_MO_init (char *section)
// close driver & display
int drv_MO_quit (void) {
- info("MatrixOrbital: shutting down.");
-
- debug ("closing port %s", Port);
- close (Device);
- unlock_port(Port);
-
- if (LayoutFB) {
- free(LayoutFB);
- LayoutFB=NULL;
- }
-
- if (DisplayFB) {
- free(DisplayFB);
- DisplayFB=NULL;
- }
+
+ info("%s: shutting down.", Name);
+ drv_generic_serial_close();
+ drv_generic_quit();
return (0);
}
DRIVER drv_MatrixOrbital = {
- name: "MatrixOrbital",
- list: drv_MO_list,
- init: drv_MO_init,
- quit: drv_MO_quit,
+ name: Name,
+ list: drv_MO_list,
+ init: drv_MO_init,
+ quit: drv_MO_quit,
};
+
diff --git a/drv_generic.c b/drv_generic.c
new file mode 100644
index 0000000..3375254
--- /dev/null
+++ b/drv_generic.c
@@ -0,0 +1,292 @@
+/* $Id: drv_generic.c,v 1.1 2004/01/20 04:51:39 reinelt Exp $
+ *
+ * generic driver helper for text- and graphic-based displays
+ *
+ * Copyright 1999, 2000 Michael Reinelt <reinelt@eunet.at>
+ * Copyright 2004 The LCD4Linux Team <lcd4linux-devel@users.sourceforge.net>
+ *
+ * This file is part of LCD4Linux.
+ *
+ * LCD4Linux 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, or (at your option)
+ * any later version.
+ *
+ * LCD4Linux 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ * $Log: drv_generic.c,v $
+ * Revision 1.1 2004/01/20 04:51:39 reinelt
+ * moved generic stuff from drv_MatrixOrbital to drv_generic
+ * implemented new-stylish bars which are nearly finished
+ *
+ */
+
+/*
+ *
+ * exported fuctions:
+ *
+ * Fixme: document me!
+ *
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <termios.h>
+#include <fcntl.h>
+
+#include "debug.h"
+#include "cfg.h"
+#include "plugin.h"
+#include "lock.h"
+#include "widget.h"
+#include "widget_text.h"
+#include "widget_bar.h"
+#include "drv.h"
+#include "drv_generic.h"
+
+
+static char *Driver;
+static char *Port;
+static speed_t Speed;
+static int Device=-1;
+
+
+int DROWS, DCOLS; // display size
+int LROWS, LCOLS; // layout size
+int XRES, YRES; // pixels of one char cell
+int CHARS; // number of user-defineable characters
+
+
+char *LayoutFB = NULL;
+char *DisplayFB = NULL;
+
+
+int drv_generic_serial_open (char *driver, char *port, speed_t speed)
+{
+ int fd;
+ pid_t pid;
+ struct termios portset;
+
+ Driver = driver;
+ Port = port;
+ Speed = speed;
+
+ if ((pid=lock_port(port))!=0) {
+ if (pid==-1)
+ error ("%s: port %s could not be locked", Driver, Port);
+ else
+ error ("%s: port %s is locked by process %d", Driver, Port, pid);
+ return -1;
+ }
+
+ fd = open(Port, O_RDWR | O_NOCTTY | O_NDELAY);
+ if (fd==-1) {
+ error ("%s: open(%s) failed: %s", Driver, Port, strerror(errno));
+ unlock_port(Port);
+ return -1;
+ }
+
+ if (tcgetattr(fd, &portset)==-1) {
+ error ("%s: tcgetattr(%s) failed: %s", Driver, Port, strerror(errno));
+ unlock_port(Port);
+ return -1;
+ }
+
+ cfmakeraw(&portset);
+ cfsetospeed(&portset, Speed);
+ if (tcsetattr(fd, TCSANOW, &portset)==-1) {
+ error ("%s: tcsetattr(%s) failed: %s", Driver, Port, strerror(errno));
+ unlock_port(Port);
+ return -1;
+ }
+
+ Device=fd;
+ return Device;
+}
+
+
+int drv_generic_serial_read (char *string, int len)
+{
+ int run, ret;
+
+ if (Device==-1) return -1;
+ for (run=0; run<10; run++) {
+ ret=read (Device, string, len);
+ if (ret>=0 || errno!=EAGAIN) break;
+ debug ("read(): EAGAIN");
+ usleep(1000);
+ }
+
+ if (ret<0) {
+ error("%s: read(%s, %d) failed: %s", Driver, Port, len, strerror(errno));
+ } else if (ret!=len) {
+ error ("%s: partial read: len=%d ret=%d", Driver, len, ret);
+ }
+
+ return ret;
+}
+
+
+void drv_generic_serial_write (char *string, int len)
+{
+ int run, ret;
+
+ if (Device==-1) return;
+ for (run=0; run<10; run++) {
+ ret=write (Device, string, len);
+ if (ret>=0 || errno!=EAGAIN) break;
+ debug ("write(): EAGAIN");
+ usleep(1000);
+ }
+
+ if (ret<0) {
+ error ("MatrixOrbital: write(%s) failed: %s", Port, strerror(errno));
+ } else if (ret!=len) {
+ error ("MatrixOrbital: partial write: len=%d ret=%d", len, ret);
+ }
+
+ return;
+}
+
+
+int drv_generic_serial_close (void)
+{
+ debug ("%s: closing port %s", Driver, Port);
+ close (Device);
+ unlock_port(Port);
+ return 0;
+}
+
+
+void drv_generic_text_resizeFB (int rows, int cols)
+{
+ char *newFB;
+ int row, col;
+
+ // Fixme: resize Bar FB too!!!!
+
+
+ // Layout FB is large enough
+ if (rows<=LROWS && cols<=LCOLS)
+ return;
+
+ // allocate new Layout FB
+ newFB=malloc(cols*rows*sizeof(char));
+ memset (newFB, ' ', rows*cols*sizeof(char));
+
+ // transfer contents
+ if (LayoutFB!=NULL) {
+ for (row=0; row<LROWS; row++) {
+ for (col=0; col<LCOLS; col++) {
+ newFB[row*cols+col]=LayoutFB[row*LCOLS+col];
+ }
+ }
+ free (LayoutFB);
+ }
+
+ LayoutFB = newFB;
+ LCOLS = cols;
+ LROWS = rows;
+}
+
+
+
+// ****************************************
+// *** widget callbacks ***
+// ****************************************
+
+
+int drv_generic_text_draw_text (WIDGET *W, int goto_len,
+ void (*drv_goto)(int row, int col),
+ void (*drv_write)(char *buffer, int len))
+{
+ WIDGET_TEXT *T=W->data;
+ char *txt, *fb1, *fb2;
+ int row, col, len, end;
+
+ row=W->row;
+ col=W->col;
+ txt=T->buffer;
+ len=strlen(txt);
+ end=col+len;
+
+ // maybe grow layout framebuffer
+ drv_generic_text_resizeFB (row, col+len-1);
+
+ fb1 = LayoutFB + row*LCOLS;
+ fb2 = DisplayFB + row*DCOLS;
+
+ // transfer new text into layout buffer
+ memcpy (fb1+col, txt, len);
+
+ for (; col<=end; col++) {
+ int pos1, pos2, equal;
+ if (fb1[col]==fb2[col]) continue;
+ drv_goto (row, col);
+ for (pos1=col, pos2=pos1, col++, equal=0; col<=end; col++) {
+ if (fb1[col]==fb2[col]) {
+ // If we find just one equal byte, we don't break, because this
+ // would require a goto, which takes several bytes, too.
+ if (++equal>goto_len) break;
+ } else {
+ pos2=col;
+ equal=0;
+ }
+ }
+ memcpy (fb2+pos1, fb1+pos1, pos2-pos1+1);
+ drv_write (fb2+pos1, pos2-pos1+1);
+ }
+
+ return 0;
+}
+
+
+// initialize text driver
+int drv_generic_text_init (char *Driver)
+{
+ // init display framebuffer
+ DisplayFB = (char*)malloc(DCOLS*DROWS*sizeof(char));
+ memset (DisplayFB, ' ', DROWS*DCOLS*sizeof(char));
+
+ // init layout framebuffer
+ LROWS = 0;
+ LCOLS = 0;
+ LayoutFB=NULL;
+ drv_generic_text_resizeFB (DROWS, DCOLS);
+
+ // sanity check
+ if (LayoutFB==NULL || DisplayFB==NULL) {
+ error ("%s: framebuffer could not be allocated: malloc() failed", Driver);
+ return -1;
+ }
+
+ return 0;
+}
+
+
+// close driver
+int drv_generic_quit (void) {
+
+ if (LayoutFB) {
+ free(LayoutFB);
+ LayoutFB=NULL;
+ }
+
+ if (DisplayFB) {
+ free(DisplayFB);
+ DisplayFB=NULL;
+ }
+
+ return (0);
+}
diff --git a/drv_generic.h b/drv_generic.h
new file mode 100644
index 0000000..9194548
--- /dev/null
+++ b/drv_generic.h
@@ -0,0 +1,74 @@
+/* $Id: drv_generic.h,v 1.1 2004/01/20 04:51:39 reinelt Exp $
+ *
+ * generic driver helper for text- and graphic-based displays
+ *
+ * Copyright 1999, 2000 Michael Reinelt <reinelt@eunet.at>
+ * Copyright 2004 The LCD4Linux Team <lcd4linux-devel@users.sourceforge.net>
+ *
+ * This file is part of LCD4Linux.
+ *
+ * LCD4Linux 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, or (at your option)
+ * any later version.
+ *
+ * LCD4Linux 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ * $Log: drv_generic.h,v $
+ * Revision 1.1 2004/01/20 04:51:39 reinelt
+ * moved generic stuff from drv_MatrixOrbital to drv_generic
+ * implemented new-stylish bars which are nearly finished
+ *
+ */
+
+/*
+ *
+ * exported fuctions:
+ *
+ * Fixme: document me!
+ *
+ */
+
+#ifndef _DRV_GENERIC_H_
+#define _DRV_GENERIC_H_
+
+
+#include <termios.h>
+#include "widget.h"
+
+
+extern int DROWS, DCOLS; // display size
+extern int LROWS, LCOLS; // layout size
+extern int XRES, YRES; // pixels of one char cell
+extern int CHARS; // number of user-defineable characters
+
+
+extern char *LayoutFB;
+extern char *DisplayFB;
+
+
+int drv_generic_serial_open (char *driver, char *port, speed_t speed);
+int drv_generic_serial_read (char *string, int len);
+void drv_generic_serial_write (char *string, int len);
+int drv_generic_serial_close (void);
+
+
+int drv_generic_text_init (char *Name);
+void drv_generic_text_resizeFB (int rows, int cols);
+int drv_generic_text_draw_text (WIDGET *W, int goto_len,
+ void (*drv_goto)(int row, int col),
+ void (*drv_write)(char *buffer, int len));
+
+
+int drv_generic_quit (void);
+
+
+#endif
diff --git a/drv_generic_bar.c b/drv_generic_bar.c
new file mode 100644
index 0000000..0bf3f7e
--- /dev/null
+++ b/drv_generic_bar.c
@@ -0,0 +1,471 @@
+/* $Id: drv_generic_bar.c,v 1.1 2004/01/20 04:51:39 reinelt Exp $
+ *
+ * generic driver helper for bar creation
+ *
+ * Copyright 1999, 2000 Michael Reinelt <reinelt@eunet.at>
+ * Copyright 2004 The LCD4Linux Team <lcd4linux-devel@users.sourceforge.net>
+ *
+ * This file is part of LCD4Linux.
+ *
+ * LCD4Linux 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, or (at your option)
+ * any later version.
+ *
+ * LCD4Linux 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ * $Log: drv_generic_bar.c,v $
+ * Revision 1.1 2004/01/20 04:51:39 reinelt
+ * moved generic stuff from drv_MatrixOrbital to drv_generic
+ * implemented new-stylish bars which are nearly finished
+ *
+ */
+
+/*
+ *
+ * exported fuctions:
+ *
+ * Fixme: document me!
+ *
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "debug.h"
+#include "drv.h"
+#include "widget.h"
+#include "widget_bar.h"
+#include "drv_generic.h"
+#include "drv_generic_bar.h"
+
+
+typedef struct {
+ int val1;
+ int val2;
+ DIRECTION dir;
+ int segment;
+} BAR;
+
+typedef struct {
+ int val1;
+ int val2;
+ DIRECTION dir;
+ int used;
+ int ascii;
+} SEGMENT;
+
+
+static int RES;
+
+static int nSegment=0;
+static int fSegment=0;
+static SEGMENT Segment[128];
+
+static BAR *Bar=NULL;
+
+
+int drv_generic_text_bar_init (void)
+{
+ if (Bar) free (Bar);
+
+ if ((Bar=malloc (LROWS*LCOLS*sizeof(BAR)))==NULL) {
+ error ("bar buffer allocation failed: out of memory");
+ return -1;
+ }
+
+ nSegment=0;
+ fSegment=0;
+
+ drv_generic_text_bar_clear();
+
+ return 0;
+}
+
+
+void drv_generic_text_bar_clear(void)
+{
+ int i;
+
+ for (i=0; i<LROWS*LCOLS; i++) {
+ Bar[i].val1 = -1;
+ Bar[i].val2 = -1;
+ Bar[i].dir = 0;
+ Bar[i].segment = -1;
+ }
+
+ for (i=0; i<nSegment;i++) {
+ Segment[i].used = 0;
+ }
+}
+
+
+void drv_generic_text_bar_add_segment(int val1, int val2, DIRECTION dir, int ascii)
+{
+ Segment[fSegment].val1=val1;
+ Segment[fSegment].val2=val2;
+ Segment[fSegment].dir=dir;
+ Segment[fSegment].used=0;
+ Segment[fSegment].ascii=ascii;
+
+ fSegment++;
+ nSegment=fSegment;
+}
+
+
+static void drv_generic_text_bar_create_bar (int row, int col, DIRECTION dir, int len, int val1, int val2)
+{
+ int rev=0;
+
+ switch (dir) {
+ case DIR_WEST:
+ val1 = len-val1;
+ val2 = len-val2;
+ rev = 1;
+
+ case DIR_EAST:
+ while (len > 0 && col < LCOLS) {
+ Bar[row*LCOLS+col].dir=dir;
+ Bar[row*LCOLS+col].segment=-1;
+ if (val1 >= XRES) {
+ Bar[row*LCOLS+col].val1 = rev?0:XRES;
+ val1 -= XRES;
+ } else {
+ Bar[row*LCOLS+col].val1 = rev?XRES-val1:val1;
+ val1 = 0;
+ }
+ if (val2 >= XRES) {
+ Bar[row*LCOLS+col].val2 = rev?0:XRES;
+ val2 -= XRES;
+ } else {
+ Bar[row*LCOLS+col].val2 = rev?XRES-val2:val2;
+ val2 = 0;
+ }
+ len--;
+ col++;
+ }
+ break;
+
+ case DIR_SOUTH:
+ val1 = len-val1;
+ val2 = len-val2;
+ rev = 1;
+
+ case DIR_NORTH:
+ while (len > 0 && row < LROWS) {
+ Bar[row*LCOLS+col].dir=dir;
+ Bar[row*LCOLS+col].segment=-1;
+ if (val1 >= YRES) {
+ Bar[row*LCOLS+col].val1 = rev?0:YRES;
+ val1 -= YRES;
+ } else {
+ Bar[row*LCOLS+col].val1 = rev?YRES-val1:val1;
+ val1 = 0;
+ }
+ if (val2 >= YRES) {
+ Bar[row*LCOLS+col].val2 = rev?0:YRES;
+ val2 -= YRES;
+ } else {
+ Bar[row*LCOLS+col].val2 = rev?YRES-val2:val2;
+ val2 = 0;
+ }
+ len--;
+ row++;
+ }
+ break;
+
+ }
+}
+
+
+static void drv_generic_text_bar_create_segments (void)
+{
+ int i, j, n;
+ int res, l1, l2;
+
+ /* find first unused segment */
+ for (i=fSegment; i<nSegment && Segment[i].used; i++);
+
+ /* pack unused segments */
+ for (j=i+1; j<nSegment; j++) {
+ if (Segment[j].used)
+ Segment[i++]=Segment[j];
+ }
+ nSegment=i;
+
+ /* create needed segments */
+ for (n=0; n<LROWS*LCOLS; n++) {
+ if (Bar[n].dir==0) continue;
+ res=Bar[n].dir & (DIR_EAST|DIR_WEST) ? XRES:YRES;
+ for (i=0; i<nSegment; i++) {
+ if (Segment[i].dir & Bar[n].dir) {
+ l1 = Segment[i].val1; if (l1>RES) l1=RES;
+ l2 = Segment[i].val2; if (l2>RES) l2=RES;
+ if (l1 == Bar[n].val1 && l2 == Bar[n].val2) break;
+ }
+ }
+ if (i==nSegment) {
+ nSegment++;
+ Segment[i].val1=Bar[n].val1;
+ Segment[i].val2=Bar[n].val2;
+ Segment[i].dir=Bar[n].dir;
+ Segment[i].used=0;
+ Segment[i].ascii=-1;
+ }
+ Bar[n].segment=i;
+ }
+}
+
+
+static int drv_generic_text_bar_segment_error (int i, int j)
+{
+ int res;
+ int i1, i2, j1, j2;
+
+ if (i==j) return 65535;
+ if (!(Segment[i].dir & Segment[j].dir)) return 65535;
+
+ res = Segment[i].dir&(DIR_EAST|DIR_WEST) ? XRES:YRES;
+
+ i1=Segment[i].val1; if (i1>res) i1=res;
+ i2=Segment[i].val2; if (i2>res) i2=res;
+ j1=Segment[j].val1; if (j1>res) j1=res;
+ j2=Segment[j].val2; if (j2>res) j2=res;
+
+ if (i1==0 && j1!=0) return 65535;
+ if (i2==0 && j2!=0) return 65535;
+ if (i1==res && j1<res) return 65535;
+ if (i2==res && j2<res) return 65535;
+ if (i1==1 && j1!=1 && i2 > 0) return 65535;
+ if (i2==1 && j2!=1 && j1 > 0) return 65535;
+ if (i1==i2 && j1!=j2) return 65535;
+
+ return (i1-j1)*(i1-j1)+(i2-j2)*(i2-j2);
+}
+
+
+static void drv_generic_text_bar_pack_segments (void)
+{
+ int i, j, n, min;
+ int pack_i, pack_j;
+ int pass1=1;
+ int error[nSegment][nSegment];
+
+ if (nSegment<=fSegment+CHARS) {
+ return;
+ }
+
+ for (i=0; i<nSegment; i++) {
+ for (j=0; j<nSegment; j++) {
+ error[i][j]=drv_generic_text_bar_segment_error(i,j);
+ }
+ }
+
+ while (nSegment>fSegment+CHARS) {
+
+ min=65535;
+ pack_i=-1;
+ pack_j=-1;
+ for (i=fSegment; i<nSegment; i++) {
+ if (pass1 && Segment[i].used) continue;
+ for (j=0; j<nSegment; j++) {
+ if (error[i][j]<min) {
+ min=error[i][j];
+ pack_i=i;
+ pack_j=j;
+ }
+ }
+ }
+ if (pack_i==-1) {
+ if (pass1) {
+ pass1=0;
+ continue;
+ } else {
+ error ("unable to compact bar characters");
+ nSegment=CHARS;
+ break;
+ }
+ }
+
+#if 1
+ debug ("pack_segment: n=%d i=%d j=%d min=%d", nSegment, pack_i, pack_j, min);
+ debug ("Pack_segment: i1=%d i2=%d j1=%d j2=%d\n",
+ Segment[pack_i].val1, Segment[pack_i].val2,
+ Segment[pack_j].val1, Segment[pack_j].val2);
+#endif
+
+ nSegment--;
+ Segment[pack_i]=Segment[nSegment];
+
+ for (i=0; i<nSegment; i++) {
+ error[pack_i][i]=error[nSegment][i];
+ error[i][pack_i]=error[i][nSegment];
+ }
+
+ for (n=0; n<LROWS*LCOLS; n++) {
+ if (Bar[n].segment==pack_i) Bar[n].segment=pack_j;
+ if (Bar[n].segment==nSegment) Bar[n].segment=pack_i;
+ }
+ }
+}
+
+
+static void drv_generic_text_bar_define_chars (void(*defchar)(int ascii, char *matrix))
+{
+ int c, i, j;
+ char buffer[8];
+
+ for (i=fSegment; i<nSegment; i++) {
+ if (Segment[i].used) continue;
+ if (Segment[i].ascii!=-1) continue;
+ for (c=0; c<CHARS; c++) {
+ for (j=fSegment; j<nSegment; j++) {
+ if (Segment[j].ascii==c) break;
+ }
+ if (j==nSegment) break;
+ }
+ Segment[i].ascii=c;
+ switch (Segment[i].dir) {
+ case DIR_EAST:
+ for (j=0; j<4; j++) {
+ buffer[j ]=(1<<Segment[i].val1)-1;
+ buffer[j+4]=(1<<Segment[i].val2)-1;
+ }
+ break;
+ case DIR_WEST:
+ for (j=0; j<4; j++) {
+ buffer[j ]=255<<(XRES-Segment[i].val1);
+ buffer[j+4]=255<<(XRES-Segment[i].val2);
+ }
+ break;
+ case DIR_NORTH:
+ for (j=0; j<Segment[i].val1; j++) {
+ buffer[7-j]=(1<<XRES)-1;
+ }
+ for (; j<YRES; j++) {
+ buffer[7-j]=0;
+ }
+ break;
+ case DIR_SOUTH:
+ for (j=0; j<Segment[i].val1; j++) {
+ buffer[j]=(1<<XRES)-1;
+ }
+ for (; j<YRES; j++) {
+ buffer[j]=0;
+ }
+ break;
+ }
+ defchar(c, buffer);
+ }
+}
+
+
+int drv_generic_text_draw_bar (WIDGET *W, int goto_len,
+ void (*drv_defchar)(int ascii, char *buffer),
+ void (*drv_goto)(int row, int col),
+ void (*drv_write)(char *buffer, int len))
+{
+ WIDGET_BAR *B = W->data;
+ int row, col, len, max, val1, val2;
+ int c, n, s;
+ DIRECTION dir;
+
+ row = W->row;
+ col = W->col;
+ dir = B->direction;
+ len = B->length;
+
+ // maybe grow layout framebuffer
+ // bars *always* grow heading North or East!
+ if (dir==DIR_EAST || dir==DIR_WEST) {
+ drv_generic_text_resizeFB (row, col+len-1);
+ RES = XRES;
+ } else {
+ drv_generic_text_resizeFB (row, col);
+ RES = YRES;
+ }
+ max = len * RES;
+ val1 = B->val1 * (double)(max);
+ val2 = B->val2 * (double)(max);
+
+ if (val1<1) val1=1;
+ else if (val1>max) val1=max;
+
+ if (val2<1) val2=1;
+ else if (val2>max) val2=max;
+
+ // create this bar
+ drv_generic_text_bar_create_bar (row, col, dir, len, val1, val2);
+
+ // process all bars
+ drv_generic_text_bar_create_segments ();
+ drv_generic_text_bar_pack_segments ();
+ drv_generic_text_bar_define_chars(drv_defchar);
+
+ // reset usage flags
+ for (s=0; s<nSegment; s++) {
+ Segment[s].used=0;
+ }
+
+ // set usage flags
+ for (n=0; n<LROWS*LCOLS; n++) {
+ if ((s=Bar[n].segment)!=-1) Segment[s].used=1;
+ }
+
+ // transfer bars into layout buffer
+ for (n=0; n<LCOLS*LROWS; n++) {
+ s=Bar[n].segment;
+ if (s==-1) continue;
+ c=Segment[s].ascii;
+ if (c==-1) continue;
+ if(c==LayoutFB[n]) continue;
+ LayoutFB[n]=c;
+ }
+
+ // transfer differences to the display
+ for (row=0; row<DROWS; row++) {
+ for (col=0; col<DCOLS; col++) {
+ int pos1, pos2, equal;
+ if (LayoutFB[row*LCOLS+col]==DisplayFB[row*DCOLS+col]) continue;
+ drv_goto (row, col);
+ for (pos1=col, pos2=pos1, col++, equal=0; col<DCOLS; col++) {
+ if (LayoutFB[row*LCOLS+col]==DisplayFB[row*DCOLS+col]) {
+ // If we find just one equal byte, we don't break, because this
+ // would require a goto, which takes several bytes, too.
+ if (++equal>goto_len) break;
+ } else {
+ pos2=col;
+ equal=0;
+ }
+ }
+ memcpy (DisplayFB+row*DCOLS+pos1, LayoutFB+row*LCOLS+pos1, pos2-pos1+1);
+ drv_write (DisplayFB+row*DCOLS+pos1, pos2-pos1+1);
+ debug ("Michi: bar(%d,%d) len=%d", row, pos1, pos2-pos1+1);
+ }
+ }
+
+ return 0;
+
+}
+
+int drv_generic_text_bar_peek (int row, int col)
+{
+ int s;
+
+ s=Bar[row*LCOLS+col].segment;
+ if (s==-1) {
+ return -1;
+ } else {
+ return Segment[s].ascii;
+ }
+}
+
diff --git a/drv_generic_bar.h b/drv_generic_bar.h
new file mode 100644
index 0000000..8bd3866
--- /dev/null
+++ b/drv_generic_bar.h
@@ -0,0 +1,43 @@
+/* $Id: drv_generic_bar.h,v 1.1 2004/01/20 04:51:39 reinelt Exp $
+ *
+ * generic driver helper for bar creation
+ *
+ * Copyright 1999, 2000 Michael Reinelt <reinelt@eunet.at>
+ * Copyright 2004 The LCD4Linux Team <lcd4linux-devel@users.sourceforge.net>
+ *
+ * This file is part of LCD4Linux.
+ *
+ * LCD4Linux 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, or (at your option)
+ * any later version.
+ *
+ * LCD4Linux 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ * $Log: drv_generic_bar.h,v $
+ * Revision 1.1 2004/01/20 04:51:39 reinelt
+ * moved generic stuff from drv_MatrixOrbital to drv_generic
+ * implemented new-stylish bars which are nearly finished
+ *
+ */
+
+#ifndef _DRV_GENERIC_BAR_H_
+#define _DRV_GENERIC_BAR_H_
+
+int drv_generic_text_bar_init (void);
+void drv_generic_text_bar_clear(void);
+void drv_generic_text_bar_add_segment(int val1, int val2, DIRECTION dir, int ascii);
+int drv_generic_text_draw_bar (WIDGET *W, int goto_len,
+ void (*drv_defchar)(int ascii, char *buffer),
+ void (*drv_goto)(int row, int col),
+ void (*drv_write)(char *buffer, int len));
+
+#endif
diff --git a/lcd4linux.conf.sample b/lcd4linux.conf.sample
index 4082210..b3ecb18 100644
--- a/lcd4linux.conf.sample
+++ b/lcd4linux.conf.sample
@@ -2,7 +2,7 @@ Display LK204 {
Driver 'MatrixOrbital'
Model 'LK204-24-USB'
Port '/dev/usb/tts/0'
- Port '/dev/tts/0'
+# Port '/dev/tts/0'
Speed 19200
Contrast 256/2
}
@@ -38,7 +38,7 @@ Widget RAM {
Widget Busy {
class 'Text'
expression cpu('busy', 500)
- prefix 'Busy '
+ prefix 'Busy'
postfix '%'
width 10
precision 1
@@ -46,15 +46,23 @@ Widget Busy {
update tick
}
+Widget BusyBar {
+ class 'Bar'
+ expression cpu('busy', 500)
+ length 10
+ direction 'E'
+ update tack
+}
+
Widget Load {
class 'Text'
expression loadavg(1)
prefix 'Load'
postfix loadavg(1)>1.0?'!':' '
width 10
- precision 2
+ precision 1
align 'R'
- update tack
+ update tick
}
@@ -67,7 +75,8 @@ Layout Default {
Col10 'RAM'
}
Row3 {
- Col1 'Busy'
+ Col1 'Busy'
+ Col10 'BusyBar'
}
Row4 {
Col1 'Load'
diff --git a/widget_bar.c b/widget_bar.c
index 7ed6f28..f28c95c 100644
--- a/widget_bar.c
+++ b/widget_bar.c
@@ -1,4 +1,4 @@
-/* $Id: widget_bar.c,v 1.1 2004/01/18 21:25:16 reinelt Exp $
+/* $Id: widget_bar.c,v 1.2 2004/01/20 04:51:39 reinelt Exp $
*
* bar widget handling
*
@@ -21,6 +21,10 @@
*
*
* $Log: widget_bar.c,v $
+ * Revision 1.2 2004/01/20 04:51:39 reinelt
+ * moved generic stuff from drv_MatrixOrbital to drv_generic
+ * implemented new-stylish bars which are nearly finished
+ *
* Revision 1.1 2004/01/18 21:25:16 reinelt
* Framework for bar widget opened
*
@@ -53,9 +57,67 @@ void widget_bar_update (void *Self)
WIDGET *W = (WIDGET*)Self;
WIDGET_BAR *T = W->data;
RESULT result = {0, 0.0, NULL};
+
+ double val1, val2;
+ double min, max;
+
+ // evaluate expressions
+ val1=0.0;
+ if (T->expression1!=NULL && *T->expression1!='\0') {
+ Eval(T->expression1, &result);
+ val1 = R2N(&result);
+ DelResult(&result);
+ }
+
+ val2=0.0;
+ if (T->expression2!=NULL && *T->expression2!='\0') {
+ Eval(T->expression2, &result);
+ val2 = R2N(&result);
+ DelResult(&result);
+ }
+
+ // minimum: if expression is empty, do auto-scaling
+ if (T->expr_min!=NULL && *T->expr_min!='\0') {
+ Eval(T->expr_min, &result);
+ min = R2N(&result);
+ DelResult(&result);
+ } else {
+ min = T->min;
+ if (val1 < min) min = val1;
+ if (val2 < min) min = val2;
+ }
+
+ // maximum: if expression is empty, do auto-scaling
+ if (T->expr_max!=NULL && *T->expr_max!='\0') {
+ Eval(T->expr_max, &result);
+ max = R2N(&result);
+ DelResult(&result);
+ } else {
+ max = T->max;
+ if (val1 > max) max = val1;
+ if (val2 > max) max = val2;
+ }
+
+
+ // calculate bar values
+ T->min=min;
+ T->max=max;
+ if (max>min) {
+ T->val1=(val1-min)/(max-min);
+ T->val2=(val2-min)/(max-min);
+ } else {
+ T->val1=0.0;
+ T->val2=0.0;
+ }
+
+ // finally, draw it!
+ if (W->class->draw)
+ W->class->draw(W);
+
}
+
int widget_bar_init (WIDGET *Self)
{
char *section; char *c;
@@ -71,9 +133,13 @@ int widget_bar_init (WIDGET *Self)
memset (B, 0, sizeof(WIDGET_BAR));
// get raw expressions (we evaluate them ourselves)
- B->expression1 = cfg_get_raw (section, "expression", "''");
- B->expression2 = cfg_get_raw (section, "expression2", "''");
+ B->expression1 = cfg_get_raw (section, "expression", NULL);
+ B->expression2 = cfg_get_raw (section, "expression2", NULL);
+ // minimum and maximum value
+ B->expr_min = cfg_get_raw (section, "min", NULL);
+ B->expr_max = cfg_get_raw (section, "max", NULL);
+
// bar length, default 1
cfg_number (section, "length", 1, 0, 99999, &(B->length));
@@ -107,8 +173,10 @@ int widget_bar_init (WIDGET *Self)
free (section);
Self->data=B;
+ debug ("Michi: widget_bar added...");
+
timer_add (widget_bar_update, Self, B->update, 0);
-
+
return 0;
}
@@ -127,7 +195,7 @@ int widget_bar_quit (WIDGET *Self) {
WIDGET_CLASS Widget_Bar = {
- name: "text",
+ name: "bar",
init: widget_bar_init,
draw: NULL,
quit: widget_bar_quit,
diff --git a/widget_bar.h b/widget_bar.h
index 3c725cc..977df98 100644
--- a/widget_bar.h
+++ b/widget_bar.h
@@ -1,4 +1,4 @@
-/* $Id: widget_bar.h,v 1.1 2004/01/18 21:25:16 reinelt Exp $
+/* $Id: widget_bar.h,v 1.2 2004/01/20 04:51:39 reinelt Exp $
*
* bar widget handling
*
@@ -23,6 +23,10 @@
*
*
* $Log: widget_bar.h,v $
+ * Revision 1.2 2004/01/20 04:51:39 reinelt
+ * moved generic stuff from drv_MatrixOrbital to drv_generic
+ * implemented new-stylish bars which are nearly finished
+ *
* Revision 1.1 2004/01/18 21:25:16 reinelt
* Framework for bar widget opened
*
@@ -32,15 +36,20 @@
#ifndef _WIDGET_BAR_H_
#define _WIDGET_BAR_H_
-typedef enum { DIR_EAST, DIR_WEST, DIR_NORTH, DIR_SOUTH } DIRECTION;
+typedef enum { DIR_EAST=1, DIR_WEST=2, DIR_NORTH=4, DIR_SOUTH=8 } DIRECTION;
typedef struct WIDGET_BAR {
char *expression1; // expression that delivers the value
char *expression2; // expression that delivers the value
+ char *expr_min; // expression that delivers the minimum value
+ char *expr_max; // expression that delivers the maximum value
DIRECTION direction; // bar direction
int length; // bar length
int update; // update interval (msec)
-
+ double val1; // bar value, 0.0 ... 1.0
+ double val2; // bar value, 0.0 ... 1.0
+ double min; // minimum value
+ double max; // maximum value
} WIDGET_BAR;
diff --git a/widget_text.c b/widget_text.c
index 9d99b2c..aa30eec 100644
--- a/widget_text.c
+++ b/widget_text.c
@@ -1,4 +1,4 @@
-/* $Id: widget_text.c,v 1.6 2004/01/15 07:47:02 reinelt Exp $
+/* $Id: widget_text.c,v 1.7 2004/01/20 04:51:39 reinelt Exp $
*
* simple text widget handling
*
@@ -21,6 +21,10 @@
*
*
* $Log: widget_text.c,v $
+ * Revision 1.7 2004/01/20 04:51:39 reinelt
+ * moved generic stuff from drv_MatrixOrbital to drv_generic
+ * implemented new-stylish bars which are nearly finished
+ *
* Revision 1.6 2004/01/15 07:47:02 reinelt
* debian/ postinst and watch added (did CVS forget about them?)
* evaluator: conditional expressions (a?b:c) added
@@ -164,6 +168,7 @@ void widget_text_scroll (void *Self)
}
+
void widget_text_update (void *Self)
{
WIDGET *W = (WIDGET*)Self;