aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile.am5
-rw-r--r--Makefile.in12
-rw-r--r--cfg.c75
-rw-r--r--cfg.h37
-rw-r--r--drv_MatrixOrbital.c240
-rw-r--r--expr.c9
-rw-r--r--layout.c10
-rw-r--r--lcd4linux.c9
-rw-r--r--plugin.c9
-rw-r--r--plugin_cfg.c9
-rw-r--r--plugin_cpuinfo.c14
-rw-r--r--plugin_uname.c95
-rw-r--r--widget.c13
-rw-r--r--widget.h16
-rw-r--r--widget_text.c214
15 files changed, 607 insertions, 160 deletions
diff --git a/Makefile.am b/Makefile.am
index 5e2058c..3afc2ed 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,4 +1,4 @@
-## Process this file with automake to produce Makefile.in
+# Process this file with automake to produce Makefile.in
AUTOMAKE_OPTIONS = gnu
CLEANFILES = *~
@@ -25,11 +25,12 @@ layout.c layout.h \
timer.c timer.h \
evaluator.c evaluator.h \
widget.c widget.h \
-widget_text.c widget_text.h \
+widget_text.c \
plugin.c plugin.h \
plugin_math.c \
plugin_string.c \
plugin_cfg.c \
+plugin_uname.c \
plugin_cpuinfo.c \
plugin_i2c_sensors.c \
plugin_xmms.c \
diff --git a/Makefile.in b/Makefile.in
index 483130b..89fcd4a 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -10,6 +10,8 @@
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
+# Process this file with automake to produce Makefile.in
+
SHELL = @SHELL@
@@ -104,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 plugin.c plugin.h plugin_math.c plugin_string.c plugin_cfg.c plugin_cpuinfo.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 plugin.c plugin.h plugin_math.c plugin_string.c plugin_cfg.c plugin_uname.c plugin_cpuinfo.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
#liblcd4linux_la_DEPENDENCIES = @DRIVERS@
@@ -148,7 +150,7 @@ lcd4linux_OBJECTS = lcd4linux.$(OBJEXT) pid.$(OBJEXT) hash.$(OBJEXT) \
parser.$(OBJEXT) processor.$(OBJEXT) layout.$(OBJEXT) timer.$(OBJEXT) \
evaluator.$(OBJEXT) widget.$(OBJEXT) widget_text.$(OBJEXT) \
plugin.$(OBJEXT) plugin_math.$(OBJEXT) plugin_string.$(OBJEXT) \
-plugin_cfg.$(OBJEXT) plugin_cpuinfo.$(OBJEXT) \
+plugin_cfg.$(OBJEXT) plugin_uname.$(OBJEXT) plugin_cpuinfo.$(OBJEXT) \
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) \
@@ -182,9 +184,9 @@ DEP_FILES = .deps/BeckmannEgle.P .deps/Crystalfontz.P .deps/Cwlinux.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_math.P .deps/plugin_string.P \
-.deps/plugin_xmms.P .deps/processor.P .deps/seti.P .deps/socket.P \
-.deps/system.P .deps/timer.P .deps/udelay.P .deps/widget.P \
-.deps/widget_text.P .deps/wifi.P
+.deps/plugin_uname.P .deps/plugin_xmms.P .deps/processor.P .deps/seti.P \
+.deps/socket.P .deps/system.P .deps/timer.P .deps/udelay.P \
+.deps/widget.P .deps/widget_text.P .deps/wifi.P
SOURCES = $(lcd4linux_SOURCES) $(EXTRA_lcd4linux_SOURCES)
OBJECTS = $(lcd4linux_OBJECTS)
diff --git a/cfg.c b/cfg.c
index 7e0becf..df7fa79 100644
--- a/cfg.c
+++ b/cfg.c
@@ -1,4 +1,4 @@
-/* $Id: cfg.c,v 1.26 2004/01/11 18:26:02 reinelt Exp $^
+/* $Id: cfg.c,v 1.27 2004/01/14 11:33:00 reinelt Exp $^
*
* config file stuff
*
@@ -23,6 +23,11 @@
*
*
* $Log: cfg.c,v $
+ * Revision 1.27 2004/01/14 11:33:00 reinelt
+ * new plugin 'uname' which does what it's called
+ * text widget nearly finished
+ * first results displayed on MatrixOrbital
+ *
* Revision 1.26 2004/01/11 18:26:02 reinelt
* further widget and layout processing
*
@@ -161,14 +166,23 @@
* This list was allocated be cfg_list() and must be
* freed by the caller!
*
+ * cfg_get_raw (section, key, defval)
+ * return the a value for a given key in a given section
+ * or <defval> if key does not exist. Does NOT evaluate
+ * the expression. Therefore used to get the expression
+ * itself!
+ *
* cfg_get (section, key, defval)
* return the a value for a given key in a given section
- * or <defval> if key does not exist
+ * or <defval> if key does not exist. The specified
+ * value in the config is treated as a expression and
+ * is evaluated!
*
* cfg_number (section, key, defval, min, int max, *value)
* return the a value for a given key in a given section
* convert it into a number with syntax checking
- * check if its in a given range
+ * check if its in a given range. As it uses cfg_get()
+ * internally, the evaluator is used here, too.
*
*/
@@ -183,6 +197,7 @@
#include <sys/stat.h>
#include "debug.h"
+#include "evaluator.h"
#include "cfg.h"
typedef struct {
@@ -361,7 +376,7 @@ char *l4l_cfg_list (char *section)
}
-char *l4l_cfg_get (char *section, char *key, char *defval)
+char *l4l_cfg_get_raw (char *section, char *key, char *defval)
{
int len;
char *buffer;
@@ -396,33 +411,52 @@ char *l4l_cfg_get (char *section, char *key, char *defval)
}
-int l4l_cfg_number (char *section, char *key, int defval, int min, int max, int *value)
+char *l4l_cfg_get (char *section, char *key, char *defval)
{
- char *s, *e;
+ char *expression;
+ RESULT result = {0, 0.0, NULL};
+ expression=cfg_get_raw(section, key, defval);
+
+ if (expression!=NULL && *expression!='\0') {
+ if (Eval(expression, &result)==0) {
+ return R2S(&result);
+ }
+ }
+ return defval;
+}
+
+
+int l4l_cfg_number (char *section, char *key, int defval, int min, int max, int *value)
+{
+ char *expression;
+ RESULT result = {0, 0.0, NULL};
+
// start with default value
// in case of an (uncatched) error, you have the
// default value set, which may be handy...
*value=defval;
- s=cfg_get(section, key, NULL);
- if (s==NULL) {
+ expression=cfg_get_raw(section, key, NULL);
+ if (expression==NULL) {
return 0;
}
- *value=strtol(s, &e, 0);
- if (*e!='\0') {
- error ("bad %s entry '%s' in %s", key, s, cfg_source());
+ if (Eval(expression, &result)!=0) {
return -1;
}
+ *value=R2N(&result);
+ DelResult(&result);
if (*value<min) {
- error ("bad %s value '%s' in %s, minimum is %d", key, s, cfg_source(), min);
+ error ("bad %s value '%d' in %s, minimum is %d", key, *value, cfg_source(), min);
+ *value=min;
return -1;
}
if (*value>max) {
- error ("bad %s value '%s' in %s, maximum is %d", key, s, cfg_source(), max);
+ error ("bad %s value '%d' in %s, maximum is %d", key, *value, cfg_source(), max);
+ *value=max;
return -1;
}
@@ -637,10 +671,11 @@ char *l4l_cfg_source (void)
}
-int (*cfg_init) (char *source) = l4l_cfg_init;
-char *(*cfg_source) (void) = l4l_cfg_source;
-int (*cfg_cmd) (char *arg) = l4l_cfg_cmd;
-char *(*cfg_list) (char *section) = l4l_cfg_list;
-char *(*cfg_get) (char *section, char *key, char *defval) = l4l_cfg_get;
-int (*cfg_number) (char *section, char *key, int defval,
- int min, int max, int *value) = l4l_cfg_number;
+int (*cfg_init) (char *source) = l4l_cfg_init;
+char *(*cfg_source) (void) = l4l_cfg_source;
+int (*cfg_cmd) (char *arg) = l4l_cfg_cmd;
+char *(*cfg_list) (char *section) = l4l_cfg_list;
+char *(*cfg_get_raw) (char *section, char *key, char *defval) = l4l_cfg_get_raw;
+char *(*cfg_get) (char *section, char *key, char *defval) = l4l_cfg_get;
+int (*cfg_number) (char *section, char *key, int defval,
+ int min, int max, int *value) = l4l_cfg_number;
diff --git a/cfg.h b/cfg.h
index 49895be..ffd01f6 100644
--- a/cfg.h
+++ b/cfg.h
@@ -1,4 +1,4 @@
-/* $Id: cfg.h,v 1.8 2004/01/10 20:22:33 reinelt Exp $
+/* $Id: cfg.h,v 1.9 2004/01/14 11:33:00 reinelt Exp $
*
* config file stuff
*
@@ -22,6 +22,11 @@
*
*
* $Log: cfg.h,v $
+ * Revision 1.9 2004/01/14 11:33:00 reinelt
+ * new plugin 'uname' which does what it's called
+ * text widget nearly finished
+ * first results displayed on MatrixOrbital
+ *
* Revision 1.8 2004/01/10 20:22:33 reinelt
* added new function 'cfg_list()' (not finished yet)
* added layout.c (will replace processor.c someday)
@@ -60,20 +65,22 @@
#ifndef _CFG_H_
#define _CFG_H_
-extern int (*cfg_init) (char *source);
-extern char *(*cfg_source) (void);
-extern int (*cfg_cmd) (char *arg);
-extern char *(*cfg_list) (char *section);
-extern char *(*cfg_get) (char *section, char *key, char *defval);
-extern int (*cfg_number) (char *section, char *key, int defval,
- int min, int max, int *value);
+extern int (*cfg_init) (char *source);
+extern char *(*cfg_source) (void);
+extern int (*cfg_cmd) (char *arg);
+extern char *(*cfg_list) (char *section);
+extern char *(*cfg_get_raw) (char *section, char *key, char *defval);
+extern char *(*cfg_get) (char *section, char *key, char *defval);
+extern int (*cfg_number) (char *section, char *key, int defval,
+ int min, int max, int *value);
-int l4l_cfg_init (char *file);
-char *l4l_cfg_source (void);
-int l4l_cfg_cmd (char *arg);
-char *l4l_cfg_list (char *section);
-char *l4l_cfg_get (char *section, char *key, char *defval);
-int l4l_cfg_number (char *section, char *key, int defval,
- int min, int max, int *value);
+int l4l_cfg_init (char *file);
+char *l4l_cfg_source (void);
+int l4l_cfg_cmd (char *arg);
+char *l4l_cfg_list (char *section);
+char *l4l_cfg_get_raw (char *section, char *key, char *defval);
+char *l4l_cfg_get (char *section, char *key, char *defval);
+int l4l_cfg_number (char *section, char *key, int defval,
+ int min, int max, int *value);
#endif
diff --git a/drv_MatrixOrbital.c b/drv_MatrixOrbital.c
index 5ca694a..2fdf1ef 100644
--- a/drv_MatrixOrbital.c
+++ b/drv_MatrixOrbital.c
@@ -1,4 +1,4 @@
-/* $Id: drv_MatrixOrbital.c,v 1.6 2004/01/11 18:26:02 reinelt Exp $
+/* $Id: drv_MatrixOrbital.c,v 1.7 2004/01/14 11:33:00 reinelt Exp $
*
* new style driver for Matrix Orbital serial display modules
*
@@ -23,6 +23,11 @@
*
*
* $Log: drv_MatrixOrbital.c,v $
+ * Revision 1.7 2004/01/14 11:33:00 reinelt
+ * new plugin 'uname' which does what it's called
+ * text widget nearly finished
+ * first results displayed on MatrixOrbital
+ *
* Revision 1.6 2004/01/11 18:26:02 reinelt
* further widget and layout processing
*
@@ -75,6 +80,7 @@
#include "bar.h"
#include "icon.h"
#include "widget.h"
+#include "widget_text.h"
// these values are hardcoded
@@ -87,11 +93,12 @@ static speed_t Speed;
static int Device=-1;
static int Model;
-static int ROWS, COLS, GPOS;
-static int ICONS, PROTOCOL;
+static int DROWS, DCOLS; // display size
+static int LROWS, LCOLS; // layout size
+static int GPOS, ICONS, PROTOCOL;
-static char *FrameBuffer1=NULL;
-static char *FrameBuffer2=NULL;
+static char *LayoutFB=NULL;
+static char *DisplayFB=NULL;
static int GPO[8];
@@ -239,18 +246,27 @@ static void drv_MO_define_char (int ascii, char *buffer)
}
+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 (FrameBuffer1, ' ', ROWS*COLS*sizeof(char));
+ memset (LayoutFB, ' ', LROWS*LCOLS*sizeof(char));
icon_clear();
bar_clear();
memset(GPO, 0, sizeof(GPO));
if (full) {
- memset (FrameBuffer2, ' ', ROWS*COLS*sizeof(char));
+ memset (DisplayFB, ' ', DROWS*DCOLS*sizeof(char));
switch (PROTOCOL) {
case 1:
drv_MO_write ("\014", 1); // Clear Screen
@@ -273,21 +289,12 @@ static int drv_MO_clear (int full)
return 0;
}
-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_put (int row, int col, char *text)
{
- char *p=FrameBuffer1+row*COLS+col;
+ char *p=LayoutFB+row*DCOLS+col;
char *t=text;
- while (*t && col++<=COLS) {
+ while (*t && col++<=DCOLS) {
*p++=*t++;
}
return 0;
@@ -383,65 +390,62 @@ static int drv_MO_start (char *section)
// read module type
drv_MO_write ("\3767", 2);
usleep(1000);
- drv_MO_read (buffer, 1);
- for (i=0; Models[i].type!=0xff; i++) {
- if (Models[i].type == (int)*buffer) break;
+ if (drv_MO_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);
+
+ // 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);
+ return -1;
+ }
+
+ } else {
+ info ("MatrixOrbital: display detection failed.");
}
- info ("MatrixOrbital: display identifies itself as a '%s' (type 0x%02x)",
- Models[i].name, Models[i].type);
-
- // auto-dedection
- if (Model==-1) Model=i;
- // auto-dedection matches specified model?
- if (Model!=i) {
- error ("MatrixOrbital: %s.Model '%s' from %s does not match dedected Model '%s'",
- section, model, cfg_source(), Models[i].name);
- return -1;
- }
-
// read serial number
drv_MO_write ("\3765", 2);
usleep(100000);
- drv_MO_read (buffer, 2);
- info ("MatrixOrbital: display reports serial number 0x%x", *(short*)buffer);
-
+ if (drv_MO_read (buffer, 2)==2) {
+ info ("MatrixOrbital: display reports serial number 0x%x", *(short*)buffer);
+ }
+
// read version number
drv_MO_write ("\3766", 2);
usleep(100000);
- drv_MO_read (buffer, 1);
- info ("MatrixOrbital: display reports firmware version 0x%x", *buffer);
-
+ if (drv_MO_read (buffer, 1)==1) {
+ info ("MatrixOrbital: display reports firmware version 0x%x", *buffer);
+ }
// initialize global variables
- ROWS = Models[Model].rows;
- COLS = Models[Model].cols;
+ DROWS = Models[Model].rows;
+ DCOLS = Models[Model].cols;
GPOS = Models[Model].gpos;
PROTOCOL = Models[Model].protocol;
-
- // init the framebuffers
- FrameBuffer1 = (char*)malloc(COLS*ROWS*sizeof(char));
- FrameBuffer2 = (char*)malloc(COLS*ROWS*sizeof(char));
- if (FrameBuffer1==NULL || FrameBuffer2==NULL) {
- error ("MatrixOrbital: framebuffer could not be allocated: malloc() failed");
- return -1;
- }
-
// 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(ROWS, COLS, XRES, YRES, CHARS, ICONS, drv_MO_define_char);
+ icon_init(DROWS, DCOLS, XRES, YRES, CHARS, ICONS, drv_MO_define_char);
}
// init Bars
- bar_init(ROWS, COLS, XRES, YRES, CHARS-ICONS);
+ 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
- drv_MO_clear(1);
+ // Fixme: get rid of this function
+ // drv_MO_clear(1);
// Fixme: where to init contrast?
drv_MO_contrast(160);
@@ -463,19 +467,19 @@ static int drv_MO_flush (void)
bar_process(drv_MO_define_char);
- for (row=0; row<ROWS; row++) {
- for (col=0; col<COLS; col++) {
+ 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) {
- FrameBuffer1[row*COLS+col]=(char)c;
+ LayoutFB[row*DCOLS+col]=(char)c;
}
}
- for (col=0; col<COLS; col++) {
- if (FrameBuffer1[row*COLS+col]==FrameBuffer2[row*COLS+col]) continue;
+ 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<COLS; col++) {
- if (FrameBuffer1[row*COLS+col]==FrameBuffer2[row*COLS+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;
@@ -484,11 +488,11 @@ static int drv_MO_flush (void)
equal=0;
}
}
- drv_MO_write (FrameBuffer1+row*COLS+pos1, pos2-pos1+1);
+ drv_MO_write (LayoutFB+row*DCOLS+pos1, pos2-pos1+1);
}
}
- memcpy (FrameBuffer2, FrameBuffer1, ROWS*COLS*sizeof(char));
+ memcpy (DisplayFB, LayoutFB, DROWS*DCOLS*sizeof(char));
switch (PROTOCOL) {
case 1:
@@ -651,6 +655,88 @@ 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;
+}
+
// ****************************************
// *** exported functions ***
@@ -679,9 +765,25 @@ int drv_MO_init (char *section)
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));
+
+ // 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;
+ }
+
// register text widget
wc=Widget_Text;
- wc.draw=NULL; //Fixme
+ wc.draw=drv_MO_draw_text;
widget_register(&wc);
// register plugins
@@ -703,14 +805,14 @@ int drv_MO_quit (void) {
close (Device);
unlock_port(Port);
- if (FrameBuffer1) {
- free(FrameBuffer1);
- FrameBuffer1=NULL;
+ if (LayoutFB) {
+ free(LayoutFB);
+ LayoutFB=NULL;
}
- if (FrameBuffer2) {
- free(FrameBuffer2);
- FrameBuffer2=NULL;
+ if (DisplayFB) {
+ free(DisplayFB);
+ DisplayFB=NULL;
}
return (0);
diff --git a/expr.c b/expr.c
index 1b1c5b7..09a6c33 100644
--- a/expr.c
+++ b/expr.c
@@ -1,4 +1,4 @@
-/* $Id: expr.c,v 1.3 2004/01/12 03:51:01 reinelt Exp $
+/* $Id: expr.c,v 1.4 2004/01/14 11:33:00 reinelt Exp $
*
* expr ('y*') functions
* This is only a workaround to make the Evaluator usable until
@@ -24,6 +24,11 @@
*
*
* $Log: expr.c,v $
+ * Revision 1.4 2004/01/14 11:33:00 reinelt
+ * new plugin 'uname' which does what it's called
+ * text widget nearly finished
+ * first results displayed on MatrixOrbital
+ *
* Revision 1.3 2004/01/12 03:51:01 reinelt
* evaluating the 'Variables' section in the config file
*
@@ -63,7 +68,7 @@ int Expr(int index, char string[EXPR_TXT_LEN], double *val)
sprintf(yn, "y%d", index);
expression = cfg_get(NULL, yn, NULL);
-
+
if (!expression || !*expression) {
error("Empty expression for 'y%d'", index);
errs[index]++;
diff --git a/layout.c b/layout.c
index faa54ee..4f25a7d 100644
--- a/layout.c
+++ b/layout.c
@@ -1,4 +1,4 @@
-/* $Id: layout.c,v 1.5 2004/01/13 08:18:19 reinelt Exp $
+/* $Id: layout.c,v 1.6 2004/01/14 11:33:00 reinelt Exp $
*
* new layouter framework
*
@@ -23,6 +23,11 @@
*
*
* $Log: layout.c,v $
+ * Revision 1.6 2004/01/14 11:33:00 reinelt
+ * new plugin 'uname' which does what it's called
+ * text widget nearly finished
+ * first results displayed on MatrixOrbital
+ *
* Revision 1.5 2004/01/13 08:18:19 reinelt
* timer queues added
* liblcd4linux deactivated turing transformation to new layout
@@ -68,8 +73,7 @@
int layout_addItem (char *name, int row, int col)
{
// allocate widget
- widget_add (name);
-
+ widget_add (name, row-1, col-1);
return 0;
}
diff --git a/lcd4linux.c b/lcd4linux.c
index 0d6290f..76d1f55 100644
--- a/lcd4linux.c
+++ b/lcd4linux.c
@@ -1,4 +1,4 @@
-/* $Id: lcd4linux.c,v 1.60 2004/01/13 08:18:19 reinelt Exp $
+/* $Id: lcd4linux.c,v 1.61 2004/01/14 11:33:00 reinelt Exp $
*
* LCD4Linux
*
@@ -22,6 +22,11 @@
*
*
* $Log: lcd4linux.c,v $
+ * Revision 1.61 2004/01/14 11:33:00 reinelt
+ * new plugin 'uname' which does what it's called
+ * text widget nearly finished
+ * first results displayed on MatrixOrbital
+ *
* Revision 1.60 2004/01/13 08:18:19 reinelt
* timer queues added
* liblcd4linux deactivated turing transformation to new layout
@@ -591,7 +596,7 @@ int main (int argc, char *argv[])
// check the conf to see if quiet startup is wanted
if (!quiet) {
- quiet = atoi(cfg_get(NULL, "Quiet", "0"));
+ cfg_number(NULL, "Quiet", 0, 0, 1, &quiet);
}
// Fixme: compatibility only...
diff --git a/plugin.c b/plugin.c
index 3304a00..6328ea9 100644
--- a/plugin.c
+++ b/plugin.c
@@ -1,4 +1,4 @@
-/* $Id: plugin.c,v 1.10 2004/01/13 10:03:01 reinelt Exp $
+/* $Id: plugin.c,v 1.11 2004/01/14 11:33:00 reinelt Exp $
*
* plugin handler for the Evaluator
*
@@ -22,6 +22,11 @@
*
*
* $Log: plugin.c,v $
+ * Revision 1.11 2004/01/14 11:33:00 reinelt
+ * new plugin 'uname' which does what it's called
+ * text widget nearly finished
+ * first results displayed on MatrixOrbital
+ *
* Revision 1.10 2004/01/13 10:03:01 reinelt
* new util 'hash' for associative arrays
* new plugin 'cpuinfo'
@@ -101,6 +106,7 @@
int plugin_init_math (void);
int plugin_init_string (void);
int plugin_init_cfg (void);
+int plugin_init_uname (void);
int plugin_init_cpuinfo (void);
int plugin_init_i2c_sensors (void);
int plugin_init_xmms (void);
@@ -111,6 +117,7 @@ int plugin_init (void)
plugin_init_math();
plugin_init_string();
plugin_init_cfg();
+ plugin_init_uname();
plugin_init_cpuinfo();
// MR: segfaults here
// plugin_init_i2c_sensors();
diff --git a/plugin_cfg.c b/plugin_cfg.c
index 0b1a229..de10385 100644
--- a/plugin_cfg.c
+++ b/plugin_cfg.c
@@ -1,4 +1,4 @@
-/* $Id: plugin_cfg.c,v 1.1 2004/01/13 10:03:01 reinelt Exp $
+/* $Id: plugin_cfg.c,v 1.2 2004/01/14 11:33:00 reinelt Exp $
*
* plugin for config file access
*
@@ -23,6 +23,11 @@
*
*
* $Log: plugin_cfg.c,v $
+ * Revision 1.2 2004/01/14 11:33:00 reinelt
+ * new plugin 'uname' which does what it's called
+ * text widget nearly finished
+ * first results displayed on MatrixOrbital
+ *
* Revision 1.1 2004/01/13 10:03:01 reinelt
* new util 'hash' for associative arrays
* new plugin 'cpuinfo'
@@ -62,7 +67,7 @@ static void load_variables (void)
if (strchr(key, '.')!=NULL || strchr(key, ':') !=0) {
error ("ignoring variable '%s' from %s: structures not allowed", key, cfg_source());
} else {
- expression=cfg_get (section, key, "");
+ expression=cfg_get_raw (section, key, "");
if (expression!=NULL && *expression!='\0') {
if (Eval(expression, &result)==0) {
debug ("Variable %s = '%s' (%f)", key, R2S(&result), R2N(&result));
diff --git a/plugin_cpuinfo.c b/plugin_cpuinfo.c
index 031429f..60b0880 100644
--- a/plugin_cpuinfo.c
+++ b/plugin_cpuinfo.c
@@ -1,4 +1,4 @@
-/* $Id: plugin_cpuinfo.c,v 1.1 2004/01/13 10:03:01 reinelt Exp $
+/* $Id: plugin_cpuinfo.c,v 1.2 2004/01/14 11:33:00 reinelt Exp $
*
* plugin for /proc/cpuinfo parsing
*
@@ -23,6 +23,11 @@
*
*
* $Log: plugin_cpuinfo.c,v $
+ * Revision 1.2 2004/01/14 11:33:00 reinelt
+ * new plugin 'uname' which does what it's called
+ * text widget nearly finished
+ * first results displayed on MatrixOrbital
+ *
* Revision 1.1 2004/01/13 10:03:01 reinelt
* new util 'hash' for associative arrays
* new plugin 'cpuinfo'
@@ -67,7 +72,8 @@ static void my_cpuinfo (RESULT *result, RESULT *arg1)
stream=fopen("/proc/cpuinfo", "r");
if (stream==NULL) {
error ("fopen(/proc/cpuinfo) failed: %s", strerror(errno));
- goto error;
+ SetResult(&result, R_STRING, "");
+ return;
}
while (!feof(stream)) {
@@ -91,9 +97,7 @@ static void my_cpuinfo (RESULT *result, RESULT *arg1)
hash_set (&CPUinfo, key, val);
}
-
fclose (stream);
-
time(&now);
}
@@ -101,8 +105,6 @@ static void my_cpuinfo (RESULT *result, RESULT *arg1)
val=hash_get(&CPUinfo, key);
if (val==NULL) val="";
- error:
- // val="";
SetResult(&result, R_STRING, val);
}
diff --git a/plugin_uname.c b/plugin_uname.c
new file mode 100644
index 0000000..95ae17e
--- /dev/null
+++ b/plugin_uname.c
@@ -0,0 +1,95 @@
+/* $Id: plugin_uname.c,v 1.1 2004/01/14 11:33:00 reinelt Exp $
+ *
+ * plugin for uname() syscall
+ *
+ * Copyright 2003 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: plugin_uname.c,v $
+ * Revision 1.1 2004/01/14 11:33:00 reinelt
+ * new plugin 'uname' which does what it's called
+ * text widget nearly finished
+ * first results displayed on MatrixOrbital
+ *
+ */
+
+/*
+ * exported functions:
+ *
+ * int plugin_init_uname (void)
+ * adds uname() functions
+ *
+ */
+
+
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/utsname.h>
+
+#include "debug.h"
+#include "plugin.h"
+
+
+
+static void my_uname (RESULT *result, RESULT *arg1)
+{
+ struct utsname utsbuf;
+ char *key, *value;
+
+ key=R2S(arg1);
+
+ if (uname(&utsbuf)!=0) {
+ error("uname() failed: %s", strerror(errno));
+ SetResult(&result, R_STRING, "");
+ return;
+ }
+
+ if (strcasecmp(key, "sysname")==0) {
+ value=utsbuf.sysname;
+ } else if (strcasecmp(key, "nodename")==0) {
+ value=utsbuf.nodename;
+ } else if (strcasecmp(key, "nodename")==0) {
+ value=utsbuf.nodename;
+ } else if (strcasecmp(key, "release")==0) {
+ value=utsbuf.release;
+ } else if (strcasecmp(key, "version")==0) {
+ value=utsbuf.version;
+ } else if (strcasecmp(key, "machine")==0) {
+ value=utsbuf.machine;
+#ifdef _GNU_SOURCE
+ } else if (strcasecmp(key, "domainname")==0) {
+ value=utsbuf.domainname;
+#endif
+ } else {
+ error("uname: unknown field '%s'", key);
+ value="";
+ }
+
+ SetResult(&result, R_STRING, value);
+}
+
+
+int plugin_init_uname (void)
+{
+ AddFunction ("uname", 1, my_uname);
+ return 0;
+}
+
diff --git a/widget.c b/widget.c
index 57a4b5b..b646e38 100644
--- a/widget.c
+++ b/widget.c
@@ -1,4 +1,4 @@
-/* $Id: widget.c,v 1.7 2004/01/13 08:18:20 reinelt Exp $
+/* $Id: widget.c,v 1.8 2004/01/14 11:33:00 reinelt Exp $
*
* generic widget handling
*
@@ -21,6 +21,11 @@
*
*
* $Log: widget.c,v $
+ * Revision 1.8 2004/01/14 11:33:00 reinelt
+ * new plugin 'uname' which does what it's called
+ * text widget nearly finished
+ * first results displayed on MatrixOrbital
+ *
* Revision 1.7 2004/01/13 08:18:20 reinelt
* timer queues added
* liblcd4linux deactivated turing transformation to new layout
@@ -106,7 +111,7 @@ int widget_register (WIDGET_CLASS *widget)
}
-int widget_add (char *name)
+int widget_add (char *name, int row, int col)
{
int i;
char *section;
@@ -125,6 +130,7 @@ int widget_add (char *name)
class=cfg_get(section, "class", NULL);
if (class==NULL || *class=='\0') {
error ("error: widget '%s' has no class!", name);
+ if (class) free (class);
return -1;
}
@@ -136,6 +142,7 @@ int widget_add (char *name)
break;
}
}
+ if (class) free (class);
if (i==nClasses) {
error ("widget '%s': class '%s' not supported");
return -1;
@@ -162,6 +169,8 @@ int widget_add (char *name)
Widget->name = name;
Widget->class = Class;
+ Widget->row = row;
+ Widget->col = col;
if (Class->init!=0) {
Class->init(Widget);
diff --git a/widget.h b/widget.h
index 95a8586..c1b2785 100644
--- a/widget.h
+++ b/widget.h
@@ -1,4 +1,4 @@
-/* $Id: widget.h,v 1.6 2004/01/13 08:18:20 reinelt Exp $
+/* $Id: widget.h,v 1.7 2004/01/14 11:33:00 reinelt Exp $
*
* generic widget handling
*
@@ -23,6 +23,11 @@
*
*
* $Log: widget.h,v $
+ * Revision 1.7 2004/01/14 11:33:00 reinelt
+ * new plugin 'uname' which does what it's called
+ * text widget nearly finished
+ * first results displayed on MatrixOrbital
+ *
* Revision 1.6 2004/01/13 08:18:20 reinelt
* timer queues added
* liblcd4linux deactivated turing transformation to new layout
@@ -59,7 +64,6 @@ struct WIDGET; // forward declaration
typedef struct WIDGET_CLASS {
char *name;
int (*init) (struct WIDGET *Self);
- int (*update) (struct WIDGET *Self); // Fixme: do we really need this?
int (*draw) (struct WIDGET *Self);
int (*quit) (struct WIDGET *Self);
} WIDGET_CLASS;
@@ -68,16 +72,14 @@ typedef struct WIDGET_CLASS {
typedef struct WIDGET{
char *name;
WIDGET_CLASS *class;
+ int row;
+ int col;
void *data;
} WIDGET;
int widget_register (WIDGET_CLASS *widget);
-int widget_add (char *name);
-
-
-// some basic widgets
-WIDGET_CLASS Widget_Text;
+int widget_add (char *name, int row, int col);
#endif
diff --git a/widget_text.c b/widget_text.c
index 4fc1ef8..95401ed 100644
--- a/widget_text.c
+++ b/widget_text.c
@@ -1,4 +1,4 @@
-/* $Id: widget_text.c,v 1.3 2004/01/13 08:18:20 reinelt Exp $
+/* $Id: widget_text.c,v 1.4 2004/01/14 11:33:00 reinelt Exp $
*
* simple text widget handling
*
@@ -21,6 +21,11 @@
*
*
* $Log: widget_text.c,v $
+ * Revision 1.4 2004/01/14 11:33:00 reinelt
+ * new plugin 'uname' which does what it's called
+ * text widget nearly finished
+ * first results displayed on MatrixOrbital
+ *
* Revision 1.3 2004/01/13 08:18:20 reinelt
* timer queues added
* liblcd4linux deactivated turing transformation to new layout
@@ -49,33 +54,150 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
+#include <ctype.h>
#include "debug.h"
#include "cfg.h"
+#include "evaluator.h"
#include "timer.h"
#include "widget.h"
+#include "widget_text.h"
-typedef struct WIDGET_TEXT {
- char *value;
- char *align;
- int width;
- int update;
-} WIDGET_TEXT;
+void widget_text_scroll (void *Self)
+{
+ WIDGET *W = (WIDGET*)Self;
+ WIDGET_TEXT *T = W->data;
+
+ int num, len, pad;
+ char *src, *dst;
+
+ src=T->value;
+ dst=T->buffer;
+ num=0;
+ len=strlen(T->value);
+ switch (T->align) {
+ case ALIGN_LEFT:
+ pad=0;
+ break;
+ case ALIGN_CENTER:
+ pad=(T->width - len)/2;
+ if (pad<0) pad=0;
+ break;
+ case ALIGN_RIGHT:
+ pad=T->width - len;
+ if (pad<0) pad=0;
+ break;
+ case ALIGN_MARQUEE:
+ pad=T->width - T->scroll;
+ T->scroll++;
+ if (T->scroll >= T->width+len) T->scroll=0;
+ break;
+ default: // not reached
+ pad=0;
+ }
+
+ // pad blanks on the beginning
+ while (pad>0) {
+ *(dst++)=' ';
+ num++;
+ pad--;
+ }
+
+ // overread src (marquee)
+ while (pad<0) {
+ src++;
+ pad++;
+ }
+
+ // copy content
+ while (num < T->width) {
+ if (*src=='\0') break;
+ *(dst++)=*(src++);
+ num++;
+ }
+
+ // pad blanks on the end
+ while (num < T->width) {
+ *(dst++)=' ';
+ num++;
+ }
+ *dst='\0';
+
+ // finally, draw it!
+ if (W->class->draw)
+ W->class->draw(W);
+}
+
-void widget_text_callback (void *vSelf)
+void widget_text_update (void *Self)
{
- WIDGET *Self=(WIDGET*)vSelf;
+ WIDGET *W = (WIDGET*)Self;
+ WIDGET_TEXT *T = W->data;
+ RESULT result = {0, 0.0, NULL};
+ char *value;
- debug ("callback: Self->name=%s", Self->name);
+ // evaluate expression
+ Eval(T->expression, &result);
+
+ // string or number?
+ if (T->precision==0xC0DE) {
+ value=strdup(R2S(&result));
+ } else {
+ double number=R2N(&result);
+ int width=T->width;
+ int precision=T->precision;
+ // print zero bytes so we can specify NULL as target
+ // and get the length of the resulting string
+ int size=snprintf (NULL, 0, "%.*f", precision, number);
+ // number does not fit into field width: try to reduce precision
+ if (size>width && precision>0) {
+ int delta=size-width;
+ if (delta>precision) delta=precision;
+ precision-=delta;
+ size-=delta;
+ // zero precision: omit decimal point, too
+ if (precision==0) size--;
+ }
+ // number still doesn't fit: display '*****'
+ if (size>width) {
+ debug ("overflow");
+ value=malloc(width+1);
+ memset (value, '*', width);
+ *(value+width)='\0';
+ } else {
+ value=malloc(size+1);
+ snprintf (value, size+1, "%.*f", precision, number);
+ }
+ }
+
+ // has value changed?
+ if (T->value == NULL || strcmp(T->value, value)!=0) {
+ // free old value
+ if (T->value) free (T->value);
+ T->value=value;
+ // reset marquee counter
+ T->scroll=0;
+ // if there's a marquee scroller active, it has its own
+ // update callback timer, so we do nothing here; otherwise
+ // we simply call this scroll callback directly
+ if (T->align!=ALIGN_MARQUEE) {
+ widget_text_scroll (Self);
+ }
+ } else {
+ // value is the same, so free our buffer
+ free (value);
+ }
+
+ DelResult (&result);
}
-int widget_text_init (WIDGET *Self) {
-
- char *section;
- WIDGET_TEXT *data;
+int widget_text_init (WIDGET *Self)
+{
+ char *section; char *c;
+ WIDGET_TEXT *T;
// prepare config section
// strlen("Widget:")=7
@@ -83,20 +205,65 @@ int widget_text_init (WIDGET *Self) {
strcpy(section, "Widget:");
strcat(section, Self->name);
- data=malloc(sizeof(WIDGET_TEXT));
+ T=malloc(sizeof(WIDGET_TEXT));
+ memset (T, 0, sizeof(WIDGET_TEXT));
+
+ // get raw expression (we evaluate it ourselves)
+ T->expression = cfg_get_raw (section, "expression", "''");
- data->value = cfg_get (section, "value", "''");
- data->align = cfg_get (section, "align", "L");
+ // field width, default 10
+ cfg_number (section, "width", 10, 0, 99999, &(T->width));
- cfg_number (section, "width", 5, 0, 99999, &(data->width));
- cfg_number (section, "update", -1, -1, 99999, &(data->update));
+ // precision: number of digits after the decimal point (default: none)
+ // Note: this is the *maximum* precision on small values,
+ // for larger values the precision may be reduced to fit into the field width.
+ // The default value 0xC0DE is used to distinguish between numbers and strings:
+ // if no precision is given, the result is always treated as a string. If a
+ // precision is specified, the result is treated as a number.
+ cfg_number (section, "precision", 0xC0DE, 0, 80, &(T->precision));
- free (section);
- Self->data=data;
+ // field alignment: Left (default), Center, Right or Marquee
+ c = cfg_get (section, "align", "L");
+ switch (toupper(*c)) {
+ case 'L':
+ T->align=ALIGN_LEFT;
+ break;
+ case 'C':
+ T->align=ALIGN_CENTER;
+ break;
+ case 'R':
+ T->align=ALIGN_RIGHT;
+ break;
+ case 'M':
+ T->align=ALIGN_MARQUEE;
+ break;
+ default:
+ error ("widget %s has unknown alignment '%s', using 'Left'", section, c);
+ T->align=ALIGN_LEFT;
+ }
+ free (c);
+
+ // update interval (msec), default 1 sec
+ cfg_number (section, "update", 1000, 10, 99999, &(T->update));
- debug ("timer_add: Self=%p Self->name=%s", Self, Self->name);
- timer_add (widget_text_callback, Self, 200, 0);
+ // marquee scroller speed: interval (msec), default 500msec
+ if (T->align==ALIGN_MARQUEE) {
+ cfg_number (section, "speed", 500, 10, 99999, &(T->speed));
+ }
+ // buffer
+ T->buffer=malloc(T->width+1);
+
+ free (section);
+ Self->data=T;
+
+ timer_add (widget_text_update, Self, T->update, 0);
+
+ // a marquee scroller has its own timer and callback
+ if (T->align==ALIGN_MARQUEE) {
+ timer_add (widget_text_scroll, Self, T->speed, 0);
+ }
+
return 0;
}
@@ -117,7 +284,6 @@ int widget_text_quit (WIDGET *Self) {
WIDGET_CLASS Widget_Text = {
name: "text",
init: widget_text_init,
- update: NULL,
draw: NULL,
quit: widget_text_quit,
};