diff options
| author | reinelt <reinelt@3ae390bd-cb1e-0410-b409-cd5a39f66f1f> | 2004-01-23 04:54:04 +0000 | 
|---|---|---|
| committer | reinelt <reinelt@3ae390bd-cb1e-0410-b409-cd5a39f66f1f> | 2004-01-23 04:54:04 +0000 | 
| commit | 3ebce612bcbf403d54e628207b540b75395f5637 (patch) | |
| tree | 5b8fc83964c3ad2b1abf1064507596b02d16b92d | |
| parent | c817553542fbdd8687c56509d206dede574ffe69 (diff) | |
| download | lcd4linux-3ebce612bcbf403d54e628207b540b75395f5637.tar.gz | |
[lcd4linux @ 2004-01-23 04:53:23 by reinelt]
icon widget added (not finished yet!)
git-svn-id: https://ssl.bulix.org/svn/lcd4linux/trunk@336 3ae390bd-cb1e-0410-b409-cd5a39f66f1f
| -rw-r--r-- | Makefile.am | 5 | ||||
| -rw-r--r-- | Makefile.in | 30 | ||||
| -rw-r--r-- | drv_Crystalfontz.c | 30 | ||||
| -rw-r--r-- | drv_HD44780.c | 8 | ||||
| -rw-r--r-- | drv_MatrixOrbital.c | 17 | ||||
| -rw-r--r-- | drv_generic_text.c | 153 | ||||
| -rw-r--r-- | drv_generic_text.h | 13 | ||||
| -rw-r--r-- | lcd4linux.conf.sample | 18 | ||||
| -rw-r--r-- | widget.c | 7 | ||||
| -rw-r--r-- | widget_bar.c | 77 | ||||
| -rw-r--r-- | widget_icon.c | 183 | ||||
| -rw-r--r-- | widget_icon.h | 46 | ||||
| -rw-r--r-- | widget_text.c | 47 | 
13 files changed, 484 insertions, 150 deletions
| diff --git a/Makefile.am b/Makefile.am index 89d3d42..199575e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -24,9 +24,10 @@ processor.c processor.h \  layout.c layout.h \  timer.c timer.h \  evaluator.c evaluator.h \ -widget.c widget.h \ +widget.c      widget.h \  widget_text.c widget_text.h \ -widget_bar.c widget_bar.h \ +widget_bar.c  widget_bar.h \ +widget_icon.c widget_icon.h \  plugin.c plugin.h \  plugin_math.c \  plugin_string.c \ diff --git a/Makefile.in b/Makefile.in index d2ceea4..d2b0024 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 drv_generic_serial.c  drv_generic_serial.h drv_generic_parport.c drv_generic_parport.h drv_generic_text.c    drv_generic_text.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 widget_icon.c widget_icon.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_serial.c  drv_generic_serial.h drv_generic_parport.c drv_generic_parport.h drv_generic_text.c    drv_generic_text.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@ @@ -149,18 +149,19 @@ X_PRE_LIBS = @X_PRE_LIBS@  lcd4linux_OBJECTS =  lcd4linux.$(OBJEXT) pid.$(OBJEXT) hash.$(OBJEXT) \  parser.$(OBJEXT) processor.$(OBJEXT) layout.$(OBJEXT) timer.$(OBJEXT) \  evaluator.$(OBJEXT) widget.$(OBJEXT) widget_text.$(OBJEXT) \ -widget_bar.$(OBJEXT) plugin.$(OBJEXT) plugin_math.$(OBJEXT) \ -plugin_string.$(OBJEXT) plugin_cfg.$(OBJEXT) plugin_uname.$(OBJEXT) \ -plugin_loadavg.$(OBJEXT) plugin_proc_stat.$(OBJEXT) \ -plugin_cpuinfo.$(OBJEXT) plugin_meminfo.$(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) \ -expr.$(OBJEXT) mail2.$(OBJEXT) socket.$(OBJEXT) imon.$(OBJEXT) \ -display.$(OBJEXT) drv.$(OBJEXT) drv_generic_serial.$(OBJEXT) \ -drv_generic_parport.$(OBJEXT) drv_generic_text.$(OBJEXT) \ -debug.$(OBJEXT) cfg.$(OBJEXT) lock.$(OBJEXT) pixmap.$(OBJEXT) \ -bar.$(OBJEXT) icon.$(OBJEXT) fontmap.$(OBJEXT) udelay.$(OBJEXT) +widget_bar.$(OBJEXT) widget_icon.$(OBJEXT) plugin.$(OBJEXT) \ +plugin_math.$(OBJEXT) plugin_string.$(OBJEXT) plugin_cfg.$(OBJEXT) \ +plugin_uname.$(OBJEXT) plugin_loadavg.$(OBJEXT) \ +plugin_proc_stat.$(OBJEXT) plugin_cpuinfo.$(OBJEXT) \ +plugin_meminfo.$(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) expr.$(OBJEXT) mail2.$(OBJEXT) \ +socket.$(OBJEXT) imon.$(OBJEXT) display.$(OBJEXT) drv.$(OBJEXT) \ +drv_generic_serial.$(OBJEXT) drv_generic_parport.$(OBJEXT) \ +drv_generic_text.$(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) @@ -192,7 +193,8 @@ DEP_FILES =  .deps/BeckmannEgle.P .deps/Crystalfontz.P .deps/Cwlinux.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 \  .deps/socket.P .deps/system.P .deps/timer.P .deps/udelay.P \ -.deps/widget.P .deps/widget_bar.P .deps/widget_text.P .deps/wifi.P +.deps/widget.P .deps/widget_bar.P .deps/widget_icon.P \ +.deps/widget_text.P .deps/wifi.P  SOURCES = $(lcd4linux_SOURCES) $(EXTRA_lcd4linux_SOURCES)  OBJECTS = $(lcd4linux_OBJECTS) diff --git a/drv_Crystalfontz.c b/drv_Crystalfontz.c index bff3ccd..112119d 100644 --- a/drv_Crystalfontz.c +++ b/drv_Crystalfontz.c @@ -1,4 +1,4 @@ -/* $Id: drv_Crystalfontz.c,v 1.2 2004/01/22 07:57:45 reinelt Exp $ +/* $Id: drv_Crystalfontz.c,v 1.3 2004/01/23 04:53:34 reinelt Exp $   *   * new style driver for Crystalfontz display modules   * @@ -23,6 +23,9 @@   *   *   * $Log: drv_Crystalfontz.c,v $ + * Revision 1.3  2004/01/23 04:53:34  reinelt + * icon widget added (not finished yet!) + *   * Revision 1.2  2004/01/22 07:57:45  reinelt   * several bugs fixed where segfaulting on layout>display   * Crystalfontz driver optimized, 632 display already works @@ -51,6 +54,7 @@  #include "widget.h"  #include "widget_text.h"  #include "widget_bar.h" +#include "widget_icon.h"  #include "drv.h"  #include "drv_generic_text.h"  #include "drv_generic_serial.h" @@ -59,12 +63,11 @@  static char Name[]="Crystalfontz";  static int Model; - -// Fixme: do we need PROTOCOL? -static int GPOS, ICONS, PROTOCOL; +static int Protocol;  // Fixme:  // static int GPO[8]; +static int GPOS;  typedef struct { @@ -143,7 +146,7 @@ static int drv_CF_start (char *section)    DROWS    = Models[Model].rows;    DCOLS    = Models[Model].cols;    GPOS     = Models[Model].gpos; -  PROTOCOL = Models[Model].protocol; +  Protocol = Models[Model].protocol;    // open serial port    if (drv_generic_serial_open(section, Name)<0) return -1; @@ -210,6 +213,12 @@ int drv_CF_draw_text (WIDGET *W)  } +int drv_CF_draw_icon (WIDGET *W) +{ +  return drv_generic_text_draw_icon(W, drv_CF_define_char, drv_CF_goto, drv_generic_serial_write); +} + +  int drv_CF_draw_bar (WIDGET *W)  {    return drv_generic_text_draw_bar(W, 4, drv_CF_define_char, drv_CF_goto, drv_generic_serial_write); @@ -249,9 +258,13 @@ int drv_CF_init (char *section)      return ret;    // initialize generic text driver -  if ((ret=drv_generic_text_init(Name))!=0) +  if ((ret=drv_generic_text_init(section, Name))!=0)      return ret; +  // initialize generic icon driver +  if ((ret=drv_generic_text_icon_init())!=0) +    return ret; +      // initialize generic bar driver    if ((ret=drv_generic_text_bar_init())!=0)      return ret; @@ -269,6 +282,11 @@ int drv_CF_init (char *section)    wc.draw=drv_CF_draw_bar;    widget_register(&wc); +  // register icon widget +  wc=Widget_Icon; +  wc.draw=drv_CF_draw_icon; +  widget_register(&wc); +      // register plugins    AddFunction ("contrast",  1, plugin_contrast);    AddFunction ("backlight", 1, plugin_backlight); diff --git a/drv_HD44780.c b/drv_HD44780.c index 3201a55..8fffb5b 100644 --- a/drv_HD44780.c +++ b/drv_HD44780.c @@ -1,4 +1,4 @@ -/* $Id: drv_HD44780.c,v 1.3 2004/01/22 07:57:45 reinelt Exp $ +/* $Id: drv_HD44780.c,v 1.4 2004/01/23 04:53:48 reinelt Exp $   *   * new style driver for HD44780-based displays   * @@ -29,6 +29,9 @@   *   *   * $Log: drv_HD44780.c,v $ + * Revision 1.4  2004/01/23 04:53:48  reinelt + * icon widget added (not finished yet!) + *   * Revision 1.3  2004/01/22 07:57:45  reinelt   * several bugs fixed where segfaulting on layout>display   * Crystalfontz driver optimized, 632 display already works @@ -97,7 +100,6 @@ static char Name[]="HD44780";  #define T_CLEAR 1640 // Clear Display -static int Icons;  static int Bits=0;  static int GPO=0;  static int Controllers = 0; @@ -448,7 +450,7 @@ int drv_HD_init (char *section)      return ret;    // initialize generic text driver -  if ((ret=drv_generic_text_init(Name))!=0) +  if ((ret=drv_generic_text_init(section, Name))!=0)      return ret;    // initialize generic bar driver diff --git a/drv_MatrixOrbital.c b/drv_MatrixOrbital.c index d7adab1..7549502 100644 --- a/drv_MatrixOrbital.c +++ b/drv_MatrixOrbital.c @@ -1,4 +1,4 @@ -/* $Id: drv_MatrixOrbital.c,v 1.16 2004/01/22 07:57:45 reinelt Exp $ +/* $Id: drv_MatrixOrbital.c,v 1.17 2004/01/23 04:53:50 reinelt Exp $   *   * new style driver for Matrix Orbital serial display modules   * @@ -23,6 +23,9 @@   *   *   * $Log: drv_MatrixOrbital.c,v $ + * Revision 1.17  2004/01/23 04:53:50  reinelt + * icon widget added (not finished yet!) + *   * Revision 1.16  2004/01/22 07:57:45  reinelt   * several bugs fixed where segfaulting on layout>display   * Crystalfontz driver optimized, 632 display already works @@ -118,11 +121,11 @@  static char Name[]="MatrixOrbital";  static int Model; - -static int GPOS, ICONS, PROTOCOL; +static int Protocol;  // Fixme:  // static int GPO[8]; +static int GPOS;  typedef struct { @@ -257,9 +260,9 @@ static int drv_MO_start (char *section)    DROWS    = Models[Model].rows;    DCOLS    = Models[Model].cols;    GPOS     = Models[Model].gpos; -  PROTOCOL = Models[Model].protocol; +  Protocol = Models[Model].protocol; -  if (PROTOCOL==2)  +  if (Protocol==2)       drv_generic_serial_write ("\376\130", 2);  // Clear Screen    else       drv_generic_serial_write ("\014", 1);  // Clear Screen @@ -333,7 +336,7 @@ static void plugin_gpo (RESULT *result, RESULT *arg1, RESULT *arg2)      val=0.0;    } -  switch (PROTOCOL) { +  switch (Protocol) {    case 1:      if (num==0) {        if (val>=1.0) { @@ -462,7 +465,7 @@ int drv_MO_init (char *section)      return ret;    // initialize generic text driver -  if ((ret=drv_generic_text_init(Name))!=0) +  if ((ret=drv_generic_text_init(section, Name))!=0)      return ret;    // initialize generic bar driver diff --git a/drv_generic_text.c b/drv_generic_text.c index 87e22ae..ebc8559 100644 --- a/drv_generic_text.c +++ b/drv_generic_text.c @@ -1,4 +1,4 @@ -/* $Id: drv_generic_text.c,v 1.4 2004/01/22 07:57:45 reinelt Exp $ +/* $Id: drv_generic_text.c,v 1.5 2004/01/23 04:53:54 reinelt Exp $   *   * generic driver helper for text-based displays   * @@ -23,6 +23,9 @@   *   *   * $Log: drv_generic_text.c,v $ + * Revision 1.5  2004/01/23 04:53:54  reinelt + * icon widget added (not finished yet!) + *   * Revision 1.4  2004/01/22 07:57:45  reinelt   * several bugs fixed where segfaulting on layout>display   * Crystalfontz driver optimized, 632 display already works @@ -62,6 +65,7 @@  #include "plugin.h"  #include "widget.h"  #include "widget_text.h" +#include "widget_icon.h"  #include "widget_bar.h"  #include "drv.h"  #include "drv_generic_text.h" @@ -82,17 +86,19 @@ typedef struct {    int ascii;  } SEGMENT; +static char *Section=NULL; +static char *Driver=NULL; -static char   *Driver;  int DROWS, DCOLS; // display size  int LROWS, LCOLS; // layout size  int XRES,  YRES;  // pixels of one char cell  int CHARS, CHAR0; // number of user-defineable characters, ASCII of first char +int ICONS;        // number of user-defineable characters reserved for icons -char *LayoutFB  = NULL; -char *DisplayFB = NULL; -static BAR *Bar = NULL; +char *LayoutFB    = NULL; +char *DisplayFB   = NULL; +static BAR *BarFB = NULL;  static int nSegment=0;  static int fSegment=0; @@ -135,7 +141,7 @@ void drv_generic_text_resizeFB (int rows, int cols)    // resize Bar buffer -  if (Bar) { +  if (BarFB) {      newBar=malloc (rows*cols*sizeof(BAR)); @@ -149,12 +155,12 @@ void drv_generic_text_resizeFB (int rows, int cols)      // transfer contents      for (row=0; row<LROWS; row++) {        for (col=0; col<LCOLS; col++) { -	newBar[row*cols+col]=Bar[row*LCOLS+col]; +	newBar[row*cols+col]=BarFB[row*LCOLS+col];        }      } -    free (Bar); -    Bar=newBar; +    free (BarFB); +    BarFB=newBar;    }    LCOLS    = cols; @@ -167,13 +173,13 @@ 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; +  WIDGET_TEXT *Text=W->data;    char *txt, *fb1, *fb2;    int row, col, len, end;    row=W->row;    col=W->col; -  txt=T->buffer; +  txt=Text->buffer;    len=strlen(txt);    end=col+len; @@ -211,6 +217,34 @@ int drv_generic_text_draw_text (WIDGET *W, int goto_len,  // **************************************** +// *** generic icon handling            *** +// **************************************** + +int drv_generic_text_draw_icon (WIDGET *W, +				void (*drv_defchar)(int ascii, char *buffer), +				void (*drv_goto)(int row, int col),  +				void (*drv_write)(char *buffer, int len)) +{ +  WIDGET_ICON *Icon = W->data; +  int row, col; +   +  row = W->row; +  col = W->col; +   +  // maybe grow layout framebuffer +  drv_generic_text_resizeFB (row+1, col+1); +   +  // maybe redefine icon +  if (Icon->curmap!=Icon->prvmap) { +    debug ("Michi: I'm redefining me..."); +  } +   +  return 0; +   +} + + +// ****************************************  // *** generic bar handling             ***  // **************************************** @@ -219,10 +253,10 @@ static 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; +    BarFB[i].val1    = -1; +    BarFB[i].val2    = -1; +    BarFB[i].dir     =  0; +    BarFB[i].segment = -1;    }    for (i=0; i<nSegment;i++) { @@ -243,20 +277,20 @@ static void drv_generic_text_bar_create_bar (int row, int col, DIRECTION dir, in    case DIR_EAST:      while (len > 0 && col < LCOLS) { -      Bar[row*LCOLS+col].dir=dir; -      Bar[row*LCOLS+col].segment=-1; +      BarFB[row*LCOLS+col].dir=dir; +      BarFB[row*LCOLS+col].segment=-1;        if (val1 >= XRES) { -	Bar[row*LCOLS+col].val1 = rev?0:XRES; +	BarFB[row*LCOLS+col].val1 = rev?0:XRES;  	val1 -= XRES;        } else { -	Bar[row*LCOLS+col].val1 = rev?XRES-val1:val1; +	BarFB[row*LCOLS+col].val1 = rev?XRES-val1:val1;  	val1 = 0;        }        if (val2 >= XRES) { -	Bar[row*LCOLS+col].val2 = rev?0:XRES; +	BarFB[row*LCOLS+col].val2 = rev?0:XRES;  	val2 -= XRES;        } else { -	Bar[row*LCOLS+col].val2 = rev?XRES-val2:val2; +	BarFB[row*LCOLS+col].val2 = rev?XRES-val2:val2;  	val2 = 0;        }        len--; @@ -271,20 +305,20 @@ static void drv_generic_text_bar_create_bar (int row, int col, DIRECTION dir, in    case DIR_NORTH:      while (len > 0 && row < LROWS) { -      Bar[row*LCOLS+col].dir=dir; -      Bar[row*LCOLS+col].segment=-1; +      BarFB[row*LCOLS+col].dir=dir; +      BarFB[row*LCOLS+col].segment=-1;        if (val1 >= YRES) { -	Bar[row*LCOLS+col].val1 = rev?0:YRES; +	BarFB[row*LCOLS+col].val1 = rev?0:YRES;  	val1 -= YRES;        } else { -	Bar[row*LCOLS+col].val1 = rev?YRES-val1:val1; +	BarFB[row*LCOLS+col].val1 = rev?YRES-val1:val1;  	val1 = 0;        }        if (val2 >= YRES) { -	Bar[row*LCOLS+col].val2 = rev?0:YRES; +	BarFB[row*LCOLS+col].val2 = rev?0:YRES;  	val2 -= YRES;        } else { -	Bar[row*LCOLS+col].val2 = rev?YRES-val2:val2; +	BarFB[row*LCOLS+col].val2 = rev?YRES-val2:val2;  	val2 = 0;        }        len--; @@ -313,24 +347,24 @@ static void drv_generic_text_bar_create_segments (void)    /* 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; +    if (BarFB[n].dir==0) continue; +    res=BarFB[n].dir & (DIR_EAST|DIR_WEST) ? XRES:YRES;      for (i=0; i<nSegment; i++) { -      if (Segment[i].dir & Bar[n].dir) { +      if (Segment[i].dir & BarFB[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 (l1 == BarFB[n].val1 && l2 == BarFB[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].val1=BarFB[n].val1; +      Segment[i].val2=BarFB[n].val2; +      Segment[i].dir=BarFB[n].dir;        Segment[i].used=0;        Segment[i].ascii=-1;      } -    Bar[n].segment=i; +    BarFB[n].segment=i;    }  } @@ -369,7 +403,7 @@ static void drv_generic_text_bar_pack_segments (void)    int pass1=1;    int error[nSegment][nSegment]; -  if (nSegment<=fSegment+CHARS) { +  if (nSegment<=fSegment+CHARS-ICONS) {      return;    } @@ -379,7 +413,7 @@ static void drv_generic_text_bar_pack_segments (void)      }    } -  while (nSegment>fSegment+CHARS) { +  while (nSegment>fSegment+CHARS-ICONS) {      min=65535;      pack_i=-1; @@ -400,7 +434,7 @@ static void drv_generic_text_bar_pack_segments (void)  	continue;        } else {  	error ("unable to compact bar characters"); -	nSegment=CHARS; +	nSegment=CHARS-ICONS;  	break;        }      }  @@ -421,8 +455,8 @@ static void drv_generic_text_bar_pack_segments (void)      }      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; +      if (BarFB[n].segment==pack_i)   BarFB[n].segment=pack_j; +      if (BarFB[n].segment==nSegment) BarFB[n].segment=pack_i;      }    }  } @@ -436,7 +470,7 @@ static void drv_generic_text_bar_define_chars (void(*defchar)(int ascii, char *m    for (i=fSegment; i<nSegment; i++) {      if (Segment[i].used) continue;      if (Segment[i].ascii!=-1) continue; -    for (c=0; c<CHARS; c++) { +    for (c=0; c<CHARS-ICONS; c++) {        for (j=fSegment; j<nSegment; j++) {  	if (Segment[j].ascii==c) break;        } @@ -483,15 +517,15 @@ int drv_generic_text_draw_bar (WIDGET *W, int goto_len,  			       void (*drv_goto)(int row, int col),   			       void (*drv_write)(char *buffer, int len))  { -  WIDGET_BAR *B = W->data; +  WIDGET_BAR *Bar = W->data;    int row, col, len, res, max, val1, val2;    int c, n, s;    DIRECTION dir;    row = W->row;    col = W->col; -  dir = B->direction; -  len = B->length; +  dir = Bar->direction; +  len = Bar->length;    // maybe grow layout framebuffer    // bars *always* grow heading North or East! @@ -503,8 +537,8 @@ int drv_generic_text_draw_bar (WIDGET *W, int goto_len,    res  = dir & (DIR_EAST|DIR_WEST)?XRES:YRES;    max  = len * res; -  val1 = B->val1 * (double)(max); -  val2 = B->val2 * (double)(max); +  val1 = Bar->val1 * (double)(max); +  val2 = Bar->val2 * (double)(max);    if      (val1<1)   val1=1;    else if (val1>max) val1=max; @@ -527,12 +561,12 @@ int drv_generic_text_draw_bar (WIDGET *W, int goto_len,    // set usage flags    for (n=0; n<LROWS*LCOLS; n++) { -    if ((s=Bar[n].segment)!=-1) Segment[s].used=1; +    if ((s=BarFB[n].segment)!=-1) Segment[s].used=1;    }    // transfer bars into layout buffer    for (n=0; n<LCOLS*LROWS; n++) { -    s=Bar[n].segment; +    s=BarFB[n].segment;      if (s==-1) continue;      c=Segment[s].ascii;      if (c==-1) continue; @@ -571,9 +605,10 @@ int drv_generic_text_draw_bar (WIDGET *W, int goto_len,  // *** generic init/quit                ***  // **************************************** -int drv_generic_text_init (char *driver) +int drv_generic_text_init (char *section, char *driver)  { +  Section=section;    Driver=driver;    // init display framebuffer @@ -596,11 +631,21 @@ int drv_generic_text_init (char *driver)  } +int drv_generic_text_icon_init (void) +{ +  if (cfg_number(Section, "Icons", 0, 0, CHARS, &ICONS)<0) return -1; +  if (ICONS>0) { +    info ("%s: reserving %d of %d user-defined characters for icons", Driver, ICONS, CHARS); +  } +  return 0; +} + +  int drv_generic_text_bar_init (void)  { -  if (Bar) free (Bar); +  if (BarFB) free (BarFB); -  if ((Bar=malloc (LROWS*LCOLS*sizeof(BAR)))==NULL) { +  if ((BarFB=malloc (LROWS*LCOLS*sizeof(BAR)))==NULL) {      error ("bar buffer allocation failed: out of memory");      return -1;    } @@ -639,9 +684,9 @@ int drv_generic_text_quit (void) {      DisplayFB=NULL;    } -  if (Bar) { -    free (Bar); -    Bar=NULL; +  if (BarFB) { +    free (BarFB); +    BarFB=NULL;    }    return (0); diff --git a/drv_generic_text.h b/drv_generic_text.h index e1468f5..46e93d6 100644 --- a/drv_generic_text.h +++ b/drv_generic_text.h @@ -1,4 +1,4 @@ -/* $Id: drv_generic_text.h,v 1.2 2004/01/22 07:57:45 reinelt Exp $ +/* $Id: drv_generic_text.h,v 1.3 2004/01/23 04:53:55 reinelt Exp $   *   * generic driver helper for text-based displays   * @@ -23,6 +23,9 @@   *   *   * $Log: drv_generic_text.h,v $ + * Revision 1.3  2004/01/23 04:53:55  reinelt + * icon widget added (not finished yet!) + *   * Revision 1.2  2004/01/22 07:57:45  reinelt   * several bugs fixed where segfaulting on layout>display   * Crystalfontz driver optimized, 632 display already works @@ -53,18 +56,22 @@ extern int DROWS, DCOLS; // display size  extern int LROWS, LCOLS; // layout size  extern int XRES,  YRES;  // pixels of one char cell  extern int CHARS, CHAR0; // number of user-defineable characters, ASCII of first char - +extern int ICONS;        // number of user-defineable characters reserved for icons  extern char *LayoutFB;  extern char *DisplayFB; -int  drv_generic_text_init      (char *Name); +int  drv_generic_text_init      (char *section, char *driver); +  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_text_icon_init  (void); +  int  drv_generic_text_bar_init  (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,  diff --git a/lcd4linux.conf.sample b/lcd4linux.conf.sample index d228c3e..fda6b67 100644 --- a/lcd4linux.conf.sample +++ b/lcd4linux.conf.sample @@ -9,6 +9,7 @@ Display LK204 {  Display CF632 { +    Icons 2      Driver 'Crystalfontz'      Model '632'      Port '/dev/tts/0' @@ -101,6 +102,22 @@ Widget LoadBar {  } +Widget Heartbeat { +    class 'Icon' +    speed 100 +    Bitmap { +	Row1 '.....|.....' +	Row2 '.*.*.|.*.*.' +	Row3 '*****|*.*.*' +	Row4 '*****|*...*' +	Row5 '.***.|.*.*.' +	Row6 '.***.|.*.*.' +	Row7 '..*..|..*..' +	Row8 '.....|.....' +    } +} + +  Layout Default {      Row1 {  	Col1  'OS' @@ -122,6 +139,7 @@ Layout Default {  Layout L16x2 {      Row1 {  	Col1  'Busy' +	Col10 'Heartbeat'  	Col11 'BusyBar'      }      Row2 { @@ -1,4 +1,4 @@ -/* $Id: widget.c,v 1.8 2004/01/14 11:33:00 reinelt Exp $ +/* $Id: widget.c,v 1.9 2004/01/23 04:53:57 reinelt Exp $   *   * generic widget handling   * @@ -21,6 +21,9 @@   *   *   * $Log: widget.c,v $ + * Revision 1.9  2004/01/23 04:53:57  reinelt + * icon widget added (not finished yet!) + *   * Revision 1.8  2004/01/14 11:33:00  reinelt   * new plugin 'uname' which does what it's called   * text widget nearly finished @@ -149,7 +152,7 @@ int widget_add (char *name, int row, int col)    }    // do NOT use realloc here because there may be pointers to the old -  // memory area, which would point to nirvana if realloc moves the area +  // memory area, which would point to nowhere if realloc moves the area    if (Widgets==NULL) {      Widgets=malloc(MAX_WIDGETS*sizeof(WIDGET));      if (Widgets==NULL) { diff --git a/widget_bar.c b/widget_bar.c index ab93ea5..1e7c0cd 100644 --- a/widget_bar.c +++ b/widget_bar.c @@ -1,4 +1,4 @@ -/* $Id: widget_bar.c,v 1.4 2004/01/20 14:25:12 reinelt Exp $ +/* $Id: widget_bar.c,v 1.5 2004/01/23 04:54:00 reinelt Exp $   *   * bar widget handling   * @@ -21,6 +21,9 @@   *   *   * $Log: widget_bar.c,v $ + * Revision 1.5  2004/01/23 04:54:00  reinelt + * icon widget added (not finished yet!) + *   * Revision 1.4  2004/01/20 14:25:12  reinelt   * some reorganization   * moved drv_generic to drv_generic_serial @@ -63,7 +66,7 @@  void widget_bar_update (void *Self)  {    WIDGET      *W = (WIDGET*)Self; -  WIDGET_BAR *T = W->data; +  WIDGET_BAR *Bar = W->data;    RESULT result = {0, 0.0, NULL};    double val1, val2; @@ -71,50 +74,50 @@ void widget_bar_update (void *Self)    // evaluate expressions    val1 = 0.0; -  if (T->expression1!=NULL && *T->expression1!='\0') { -    Eval(T->expression1, &result);  +  if (Bar->expression1!=NULL && *Bar->expression1!='\0') { +    Eval(Bar->expression1, &result);       val1 = R2N(&result);       DelResult(&result);    }    val2 = val1; -  if (T->expression2!=NULL && *T->expression2!='\0') { -    Eval(T->expression2, &result);  +  if (Bar->expression2!=NULL && *Bar->expression2!='\0') { +    Eval(Bar->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);  +  if (Bar->expr_min!=NULL && *Bar->expr_min!='\0') { +    Eval(Bar->expr_min, &result);       min = R2N(&result);       DelResult(&result);    } else { -    min = T->min; +    min = Bar->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);  +  if (Bar->expr_max!=NULL && *Bar->expr_max!='\0') { +    Eval(Bar->expr_max, &result);       max = R2N(&result);       DelResult(&result);    } else { -    max = T->max; +    max = Bar->max;      if (val1 > max) max = val1;      if (val2 > max) max = val2;    }    // calculate bar values -  T->min=min; -  T->max=max; +  Bar->min=min; +  Bar->max=max;    if (max>min) { -    T->val1=(val1-min)/(max-min); -    T->val2=(val2-min)/(max-min); +    Bar->val1=(val1-min)/(max-min); +    Bar->val2=(val2-min)/(max-min);    } else { -    T->val1=0.0; -    T->val2=0.0; +    Bar->val1=0.0; +    Bar->val2=0.0;    }    // finally, draw it! @@ -128,7 +131,7 @@ void widget_bar_update (void *Self)  int widget_bar_init (WIDGET *Self)   {    char *section; char *c; -  WIDGET_BAR *B; +  WIDGET_BAR *Bar;    // prepare config section    // strlen("Widget:")=7 @@ -136,57 +139,57 @@ int widget_bar_init (WIDGET *Self)    strcpy(section, "Widget:");    strcat(section, Self->name); -  B=malloc(sizeof(WIDGET_BAR)); -  memset (B, 0, sizeof(WIDGET_BAR)); +  Bar=malloc(sizeof(WIDGET_BAR)); +  memset (Bar, 0, sizeof(WIDGET_BAR));    // get raw expressions (we evaluate them ourselves) -  B->expression1 = cfg_get_raw (section, "expression",  NULL); -  B->expression2 = cfg_get_raw (section, "expression2", NULL); +  Bar->expression1 = cfg_get_raw (section, "expression",  NULL); +  Bar->expression2 = cfg_get_raw (section, "expression2", NULL);    // sanity check -  if (B->expression1==NULL || *B->expression1=='\0') { +  if (Bar->expression1==NULL || *Bar->expression1=='\0') {      error ("widget %s has no expression, using '0.0'", Self->name); -    B->expression1="0"; +    Bar->expression1="0";    }    // minimum and maximum value -  B->expr_min = cfg_get_raw (section, "min", NULL); -  B->expr_max = cfg_get_raw (section, "max", NULL); +  Bar->expr_min = cfg_get_raw (section, "min", NULL); +  Bar->expr_max = cfg_get_raw (section, "max", NULL);    // bar length, default 1 -  cfg_number (section, "length", 1,  0, 99999, &(B->length)); +  cfg_number (section, "length", 1,  0, 99999, &(Bar->length));    // direction: East (default), West, North, South    c = cfg_get (section, "direction",  "E");    switch (toupper(*c)) {    case 'E': -    B->direction=DIR_EAST; +    Bar->direction=DIR_EAST;      break;    case 'W': -    B->direction=DIR_WEST; +    Bar->direction=DIR_WEST;      break;    case 'N': -    B->direction=DIR_NORTH; +    Bar->direction=DIR_NORTH;      break;    case 'S': -    B->direction=DIR_SOUTH; +    Bar->direction=DIR_SOUTH;      break;    default:      error ("widget %s has unknown direction '%s', using 'East'", Self->name, c); -    B->direction=DIR_EAST; +    Bar->direction=DIR_EAST;    }    free (c);    // update interval (msec), default 1 sec -  cfg_number (section, "update", 1000, 10, 99999, &(B->update)); +  cfg_number (section, "update", 1000, 10, 99999, &(Bar->update));    // buffer -  // B->buffer=malloc(B->width+1); +  // Bar->buffer=malloc(Bar->width+1);    free (section); -  Self->data=B; +  Self->data=Bar; -  timer_add (widget_bar_update, Self, B->update, 0); +  timer_add (widget_bar_update, Self, Bar->update, 0);    return 0;  } diff --git a/widget_icon.c b/widget_icon.c new file mode 100644 index 0000000..e30fbfe --- /dev/null +++ b/widget_icon.c @@ -0,0 +1,183 @@ +/* $Id: widget_icon.c,v 1.1 2004/01/23 04:54:03 reinelt Exp $ + * + * icon widget handling + * + * Copyright 2003,2004 Michael Reinelt <reinelt@eunet.at> + * Copyright 2004 The LCD4Linux Team <lcd4linux-devel@users.sourceforge.net> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * + * $Log: widget_icon.c,v $ + * Revision 1.1  2004/01/23 04:54:03  reinelt + * icon widget added (not finished yet!) + * + */ + +/*  + * exported functions: + * + * WIDGET_CLASS Widget_Icon + *   the icon widget + * + */ + + +#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_icon.h" + +// icons always are 8 pixels high  +#define YRES 8 + +static void widget_icon_read_bitmap (char *section, WIDGET_ICON *Icon) +{ +  int row, n; +  char  key[15]; +  char *val, *v; +  char *map; +   +  for (row=0; row<YRES; row++) { +    snprintf (key, sizeof(key), "Bitmap.Row%d", row+1); +    val=cfg_get(section, key, "");  +    map=Icon->bitmap+row; +    n=0; +    for (v=val; *v!='\0'; v++) { +      if (n>=Icon->maxmap) { +	Icon->maxmap++; +	Icon->bitmap=realloc(Icon->bitmap, Icon->maxmap*YRES*sizeof(char)); +	memset (Icon->bitmap+n*YRES, 0, YRES*sizeof(char)); +	map=Icon->bitmap+n*YRES+row; +      } +      switch (*v) { +      case '|': +	n++; +	map+=YRES; +	break; +      case '*': +	(*map)<<=1; +	(*map)|=1; +	break; +      default: +	(*map)<<=1; +      } +    } +  } +} + + +void widget_icon_update (void *Self) +{ +  WIDGET      *W = (WIDGET*)Self; +  WIDGET_ICON *Icon = W->data; +  RESULT result = {0, 0.0, NULL}; +   +  // evaluate expressions +  Icon->speed = 100; +  if (Icon->speed_expr!=NULL && *Icon->speed_expr!='\0') { +    Eval(Icon->speed_expr, &result);  +    Icon->speed = R2N(&result);  +    if (Icon->speed<10) Icon->speed=10; +    DelResult(&result); +  } +   +  // rotate icon bitmap +  Icon->curmap++; +  if (Icon->curmap >= Icon->maxmap) +    Icon->curmap=0; +   +  // finally, draw it! +  if (W->class->draw) +    W->class->draw(W); + +  // store currently visible bitmap +  Icon->prvmap=Icon->curmap; +   +  // add a new one-shot timer +  timer_add (widget_icon_update, Self, Icon->speed, 1); +   +} + + + +int widget_icon_init (WIDGET *Self)  +{ +  char *section; +  WIDGET_ICON *Icon; +   +  // prepare config section +  // strlen("Widget:")=7 +  section=malloc(strlen(Self->name)+8); +  strcpy(section, "Widget:"); +  strcat(section, Self->name); +   +  Icon=malloc(sizeof(WIDGET_ICON)); +  memset (Icon, 0, sizeof(WIDGET_ICON)); + +  // get raw expressions (we evaluate them ourselves) +  Icon->speed_expr = cfg_get_raw (section, "speed",  NULL); +   +  // sanity check +  if (Icon->speed_expr==NULL || *Icon->speed_expr=='\0') { +    error ("Icon %s has no speed, using '100'", Self->name); +    Icon->speed_expr="100"; +  } +   +  // read bitmap +  widget_icon_read_bitmap (section, Icon); +   +  free (section); +  Self->data=Icon; +   +  // as the speed is evaluatod on every call, we use 'one-shot'-timers.  +  // The timer will be reactivated on every call to widget_icon_update().  +  // We do the initial call here... +  Icon->prvmap=-1; +  widget_icon_update(Self); + +  return 0; +} + + +int widget_icon_quit (WIDGET *Self)  +{ +  WIDGET_ICON *Icon = Self->data; +   +  if (Self->data) { +    if (Icon->bitmap) free (Icon->bitmap);  +    free (Self->data); +    Self->data=NULL; +  } +   +  return 0; +   +} + + + +WIDGET_CLASS Widget_Icon = { +  name:   "icon", +  init:   widget_icon_init, +  draw:   NULL, +  quit:   widget_icon_quit, +}; diff --git a/widget_icon.h b/widget_icon.h new file mode 100644 index 0000000..88bad6c --- /dev/null +++ b/widget_icon.h @@ -0,0 +1,46 @@ +/* $Id: widget_icon.h,v 1.1 2004/01/23 04:54:04 reinelt Exp $ + * + * icon widget handling + * + * Copyright 2003,2004 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: widget_icon.h,v $ + * Revision 1.1  2004/01/23 04:54:04  reinelt + * icon widget added (not finished yet!) + * + */ + + +#ifndef _WIDGET_ICON_H_ +#define _WIDGET_ICON_H_ + +typedef struct WIDGET_ICON { +  char *speed_expr; // expression for update interval +  int   speed;      // update interval (msec) +  int   curmap;     // current bitmap sequence +  int   prvmap;     // previous bitmap sequence  +  int   maxmap;     // number of bitmap sequences +  char *bitmap;     // bitmaps of (animated) icon +} WIDGET_ICON; + +extern WIDGET_CLASS Widget_Icon; + +#endif diff --git a/widget_text.c b/widget_text.c index f20105c..52c3003 100644 --- a/widget_text.c +++ b/widget_text.c @@ -1,4 +1,4 @@ -/* $Id: widget_text.c,v 1.8 2004/01/22 07:57:45 reinelt Exp $ +/* $Id: widget_text.c,v 1.9 2004/01/23 04:54:04 reinelt Exp $   *   * simple text widget handling   * @@ -21,6 +21,9 @@   *   *   * $Log: widget_text.c,v $ + * Revision 1.9  2004/01/23 04:54:04  reinelt + * icon widget added (not finished yet!) + *   * Revision 1.8  2004/01/22 07:57:45  reinelt   * several bugs fixed where segfaulting on layout>display   * Crystalfontz driver optimized, 632 display already works @@ -283,7 +286,7 @@ void widget_text_update (void *Self)  int widget_text_init (WIDGET *Self)   {    char *section; char *c; -  WIDGET_TEXT *T; +  WIDGET_TEXT *Text;    // prepare config section    // strlen("Widget:")=7 @@ -291,18 +294,18 @@ int widget_text_init (WIDGET *Self)    strcpy(section, "Widget:");    strcat(section, Self->name); -  T=malloc(sizeof(WIDGET_TEXT)); -  memset (T, 0, sizeof(WIDGET_TEXT)); +  Text=malloc(sizeof(WIDGET_TEXT)); +  memset (Text, 0, sizeof(WIDGET_TEXT));    // get raw pre- and postfix (we evaluate it ourselves) -  T->prefix  = cfg_get_raw (section, "prefix",  NULL); -  T->postfix = cfg_get_raw (section, "postfix", NULL); +  Text->prefix  = cfg_get_raw (section, "prefix",  NULL); +  Text->postfix = cfg_get_raw (section, "postfix", NULL);    // get raw expression (we evaluate it ourselves) -  T->expression = cfg_get_raw (section, "expression",  "''"); +  Text->expression = cfg_get_raw (section, "expression",  "''");    // field width, default 10 -  cfg_number (section, "width", 10,  0, 99999, &(T->width)); +  cfg_number (section, "width", 10,  0, 99999, &(Text->width));    // precision: number of digits after the decimal point (default: none)    // Note: this is the *maximum* precision on small values, @@ -310,48 +313,48 @@ int widget_text_init (WIDGET *Self)    // 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)); +  cfg_number (section, "precision", 0xC0DE, 0, 80, &(Text->precision));    // field alignment: Left (default), Center, Right or Marquee    c = cfg_get (section, "align",  "L");    switch (toupper(*c)) {    case 'L': -    T->align=ALIGN_LEFT; +    Text->align=ALIGN_LEFT;      break;    case 'C': -    T->align=ALIGN_CENTER; +    Text->align=ALIGN_CENTER;      break;    case 'R': -    T->align=ALIGN_RIGHT; +    Text->align=ALIGN_RIGHT;      break;    case 'M': -    T->align=ALIGN_MARQUEE; +    Text->align=ALIGN_MARQUEE;      break;    default:      error ("widget %s has unknown alignment '%s', using 'Left'", section, c); -    T->align=ALIGN_LEFT; +    Text->align=ALIGN_LEFT;    }    free (c);    // update interval (msec), default 1 sec -  cfg_number (section, "update", 1000, 10, 99999, &(T->update)); +  cfg_number (section, "update", 1000, 10, 99999, &(Text->update));    // marquee scroller speed: interval (msec), default 500msec -  if (T->align==ALIGN_MARQUEE) { -    cfg_number (section, "speed", 500, 10, 99999, &(T->speed)); +  if (Text->align==ALIGN_MARQUEE) { +    cfg_number (section, "speed", 500, 10, 99999, &(Text->speed));    }    // buffer -  T->buffer=malloc(T->width+1); +  Text->buffer=malloc(Text->width+1);    free (section); -  Self->data=T; +  Self->data=Text; -  timer_add (widget_text_update, Self, T->update, 0); +  timer_add (widget_text_update, Self, Text->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); +  if (Text->align==ALIGN_MARQUEE) { +    timer_add (widget_text_scroll, Self, Text->speed, 0);    }    return 0; | 
