mirror of
https://github.com/netfun2000/lcd4linux.git
synced 2026-02-27 09:44:34 +08:00
dynamic properties for bars; new 'property_valid()' helper
git-svn-id: https://ssl.bulix.org/svn/lcd4linux/trunk@749 3ae390bd-cb1e-0410-b409-cd5a39f66f1f
This commit is contained in:
@@ -278,6 +278,7 @@ drv_MatrixOrbital.c \
|
||||
drv_MilfordInstruments.c \
|
||||
drv_Noritake.c \
|
||||
drv_NULL.c \
|
||||
drv_picoLCD.c \
|
||||
drv_RouterBoard.c \
|
||||
drv_Sample.c \
|
||||
drv_serdisplib.c \
|
||||
@@ -467,6 +468,7 @@ distclean-compile:
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/drv_generic_parport.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/drv_generic_serial.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/drv_generic_text.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/drv_picoLCD.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/drv_serdisplib.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/evaluator.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hash.Po@am__quote@
|
||||
|
||||
@@ -351,6 +351,7 @@ char *cfg_get_raw(const char *section, const char *key, const char *defval)
|
||||
|
||||
if (val != NULL)
|
||||
return val;
|
||||
|
||||
return (char *) defval;
|
||||
}
|
||||
|
||||
|
||||
@@ -491,6 +491,9 @@
|
||||
/* X11 driver */
|
||||
#undef WITH_X11
|
||||
|
||||
/* picoLCD driver */
|
||||
#undef WITH_picoLCD
|
||||
|
||||
/* Define to 1 if the X Window System is missing or not being used. */
|
||||
#undef X_DISPLAY_MISSING
|
||||
|
||||
|
||||
@@ -1344,7 +1344,7 @@ Optional Packages:
|
||||
BeckmannEgle, BWCT, CrystalFontz, Curses, Cwlinux,
|
||||
G15, HD44780, LCD2USB LCDLinux, LCDTerm, LPH7508,
|
||||
LUIse, M50530, MatrixOrbital, MilfordInstruments,
|
||||
Noritake, NULL, PNG, PPM, RouterBoard, Sample,
|
||||
Noritake, NULL, PNG, PPM, picoLCD, RouterBoard, Sample,
|
||||
serdisplib, SimpleLCD, T6963, Trefon, USBLCD,
|
||||
USBHUB, WincorNixdorf, X11
|
||||
--with-plugins=<list> choose which plugins to compile.
|
||||
@@ -7238,9 +7238,10 @@ for driver in $drivers; do
|
||||
MILINST="yes"
|
||||
NORITAKE="yes"
|
||||
NULL="yes"
|
||||
picoLCD="yes"
|
||||
PNG="yes"
|
||||
PPM="yes"
|
||||
ROUTERBOARD="yes"
|
||||
ROUTERBOARD="yes"
|
||||
SAMPLE="yes"
|
||||
SERDISPLIB="yes"
|
||||
SIMPLELCD="yes"
|
||||
@@ -7308,6 +7309,9 @@ for driver in $drivers; do
|
||||
NULL)
|
||||
NULL=$val;
|
||||
;;
|
||||
picoLCD)
|
||||
picoLCD=$val
|
||||
;;
|
||||
PNG)
|
||||
PNG=$val
|
||||
;;
|
||||
@@ -7622,6 +7626,19 @@ _ACEOF
|
||||
|
||||
fi
|
||||
|
||||
if test "$picoLCD" = "yes"; then
|
||||
TEXT="yes"
|
||||
GPIO="yes"
|
||||
SERIAL="yes"
|
||||
#I2C="yes"
|
||||
DRIVERS="$DRIVERS drv_picoLCD.o"
|
||||
|
||||
cat >>confdefs.h <<\_ACEOF
|
||||
#define WITH_picoLCD 1
|
||||
_ACEOF
|
||||
|
||||
fi
|
||||
|
||||
if test "$PNG" = "yes"; then
|
||||
if test "$has_gd" = "true"; then
|
||||
IMAGE="yes"
|
||||
|
||||
+22
-4
@@ -64,7 +64,10 @@
|
||||
|
||||
void property_load(const char *section, const char *name, const char *defval, PROPERTY * prop)
|
||||
{
|
||||
char *expression;
|
||||
|
||||
/* initialize structure */
|
||||
prop->valid = 0;
|
||||
prop->name = NULL;
|
||||
prop->expression = NULL;
|
||||
prop->compiled = NULL;
|
||||
@@ -74,7 +77,16 @@ void property_load(const char *section, const char *name, const char *defval, PR
|
||||
prop->name = strdup(name);
|
||||
|
||||
/* load expression from config, but do not evaluate it */
|
||||
prop->expression = cfg_get_raw(section, name, defval);
|
||||
expression = cfg_get_raw(section, name, NULL);
|
||||
|
||||
if (expression == NULL) {
|
||||
if (defval != NULL && *defval != '\0')
|
||||
debug("Notice: using default value <%s> for property '%s.%s'", defval, section, name);
|
||||
prop->expression = (char *) defval;
|
||||
} else {
|
||||
prop->valid = 1;
|
||||
prop->expression = expression;
|
||||
}
|
||||
|
||||
/* pre-compile the expression */
|
||||
Compile(prop->expression, &prop->compiled);
|
||||
@@ -82,13 +94,18 @@ void property_load(const char *section, const char *name, const char *defval, PR
|
||||
}
|
||||
|
||||
|
||||
int property_valid(PROPERTY * prop)
|
||||
{
|
||||
return prop->valid;
|
||||
}
|
||||
|
||||
|
||||
int property_eval(PROPERTY * prop)
|
||||
{
|
||||
RESULT old;
|
||||
int update = 1;
|
||||
int update;
|
||||
|
||||
/* this is a bit ugly: we need to remember the old value */
|
||||
|
||||
old.type = prop->result.type;
|
||||
old.size = prop->result.size;
|
||||
old.number = prop->result.number;
|
||||
@@ -97,10 +114,11 @@ int property_eval(PROPERTY * prop)
|
||||
DelResult(&prop->result);
|
||||
Eval(prop->compiled, &prop->result);
|
||||
|
||||
/* check if property value has changed */
|
||||
update = 1;
|
||||
if (prop->result.type & R_NUMBER && old.type & R_NUMBER && prop->result.number == old.number) {
|
||||
update = 0;
|
||||
}
|
||||
|
||||
if (prop->result.type & R_STRING && old.type & R_STRING && prop->result.size == old.size) {
|
||||
if (prop->result.string == NULL && old.string == NULL) {
|
||||
update = 0;
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
|
||||
|
||||
typedef struct {
|
||||
int valid;
|
||||
char *name;
|
||||
char *expression;
|
||||
void *compiled;
|
||||
@@ -40,6 +41,7 @@ typedef struct {
|
||||
|
||||
|
||||
void property_load(const char *section, const char *name, const char *defval, PROPERTY * prop);
|
||||
int property_valid(PROPERTY * prop);
|
||||
int property_eval(PROPERTY * prop);
|
||||
double P2N(PROPERTY * prop);
|
||||
char *P2S(PROPERTY * prop);
|
||||
|
||||
+27
-42
@@ -40,7 +40,7 @@
|
||||
|
||||
#include "debug.h"
|
||||
#include "cfg.h"
|
||||
#include "evaluator.h"
|
||||
#include "property.h"
|
||||
#include "timer.h"
|
||||
#include "widget.h"
|
||||
#include "widget_bar.h"
|
||||
@@ -59,26 +59,21 @@ void widget_bar_update(void *Self)
|
||||
double val1, val2;
|
||||
double min, max;
|
||||
|
||||
/* evaluate expressions */
|
||||
val1 = 0.0;
|
||||
if (Bar->tree1 != NULL) {
|
||||
Eval(Bar->tree1, &result);
|
||||
val1 = R2N(&result);
|
||||
DelResult(&result);
|
||||
}
|
||||
/* evaluate properties */
|
||||
property_eval(&Bar->expression1);
|
||||
val1 = P2N(&Bar->expression1);
|
||||
|
||||
val2 = val1;
|
||||
if (Bar->tree2 != NULL) {
|
||||
Eval(Bar->tree2, &result);
|
||||
val2 = R2N(&result);
|
||||
DelResult(&result);
|
||||
if (property_valid(&Bar->expression2)) {
|
||||
property_eval(&Bar->expression2);
|
||||
val2 = P2N(&Bar->expression2);
|
||||
} else {
|
||||
val2 = val1;
|
||||
}
|
||||
|
||||
/* minimum: if expression is empty, do auto-scaling */
|
||||
if (Bar->tree_min != NULL) {
|
||||
Eval(Bar->tree_min, &result);
|
||||
min = R2N(&result);
|
||||
DelResult(&result);
|
||||
if (property_valid(&Bar->expr_min)) {
|
||||
property_eval(&Bar->expr_min);
|
||||
min = P2N(&Bar->expr_min);
|
||||
} else {
|
||||
min = Bar->min;
|
||||
if (val1 < min)
|
||||
@@ -88,10 +83,9 @@ void widget_bar_update(void *Self)
|
||||
}
|
||||
|
||||
/* maximum: if expression is empty, do auto-scaling */
|
||||
if (Bar->tree_max != NULL) {
|
||||
Eval(Bar->tree_max, &result);
|
||||
max = R2N(&result);
|
||||
DelResult(&result);
|
||||
if (property_valid(&Bar->expr_max)) {
|
||||
property_eval(&Bar->expr_max);
|
||||
max = P2N(&Bar->expr_min);
|
||||
} else {
|
||||
max = Bar->max;
|
||||
if (val1 > max)
|
||||
@@ -133,26 +127,17 @@ int widget_bar_init(WIDGET * Self)
|
||||
Bar = malloc(sizeof(WIDGET_BAR));
|
||||
memset(Bar, 0, sizeof(WIDGET_BAR));
|
||||
|
||||
/* get raw expressions (we evaluate them ourselves) */
|
||||
Bar->expression1 = cfg_get_raw(section, "expression", NULL);
|
||||
Bar->expression2 = cfg_get_raw(section, "expression2", NULL);
|
||||
/* load properties */
|
||||
property_load(section, "expression", NULL, &Bar->expression1);
|
||||
property_load(section, "expression2", NULL, &Bar->expression2);
|
||||
property_load(section, "min", NULL, &Bar->expr_min);
|
||||
property_load(section, "max", NULL, &Bar->expr_max);
|
||||
|
||||
/* sanity check */
|
||||
if (Bar->expression1 == NULL || *Bar->expression1 == '\0') {
|
||||
error("widget %s has no expression, using '0.0'", Self->name);
|
||||
Bar->expression1 = "0";
|
||||
/* sanity checks */
|
||||
if (!property_valid(&Bar->expression1)) {
|
||||
error("Warning: widget %s has no expression", section);
|
||||
}
|
||||
|
||||
/* minimum and maximum value */
|
||||
Bar->expr_min = cfg_get_raw(section, "min", NULL);
|
||||
Bar->expr_max = cfg_get_raw(section, "max", NULL);
|
||||
|
||||
/* compile all expressions */
|
||||
Compile(Bar->expression1, &Bar->tree1);
|
||||
Compile(Bar->expression2, &Bar->tree2);
|
||||
Compile(Bar->expr_min, &Bar->tree_min);
|
||||
Compile(Bar->expr_max, &Bar->tree_max);
|
||||
|
||||
/* bar length, default 1 */
|
||||
cfg_number(section, "length", 1, 0, -1, &(Bar->length));
|
||||
|
||||
@@ -213,10 +198,10 @@ int widget_bar_quit(WIDGET * Self)
|
||||
if (Self) {
|
||||
if (Self->data) {
|
||||
WIDGET_BAR *Bar = Self->data;
|
||||
DelTree(Bar->tree1);
|
||||
DelTree(Bar->tree2);
|
||||
DelTree(Bar->tree_min);
|
||||
DelTree(Bar->tree_max);
|
||||
property_free(&Bar->expression1);
|
||||
property_free(&Bar->expression2);
|
||||
property_free(&Bar->expr_min);
|
||||
property_free(&Bar->expr_max);
|
||||
free(Self->data);
|
||||
}
|
||||
Self->data = NULL;
|
||||
|
||||
+6
-8
@@ -28,18 +28,16 @@
|
||||
#ifndef _WIDGET_BAR_H_
|
||||
#define _WIDGET_BAR_H_
|
||||
|
||||
#include "property.h"
|
||||
|
||||
typedef enum { DIR_EAST = 1, DIR_WEST = 2, DIR_NORTH = 4, DIR_SOUTH = 8 } DIRECTION;
|
||||
typedef enum { STYLE_HOLLOW = 1, STYLE_FIRST = 2, STYLE_LAST = 4 } STYLE;
|
||||
|
||||
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 */
|
||||
void *tree1; /* pre-compiled expression that delivers the value */
|
||||
void *tree2; /* pre-compiled expression that delivers the value */
|
||||
void *tree_min; /* pre-compiled expression that delivers the minimum value */
|
||||
void *tree_max; /* pre-compiled expression that delivers the maximum value */
|
||||
PROPERTY expression1; /* value (length) of upper half */
|
||||
PROPERTY expression2; /* value (length) of lower half */
|
||||
PROPERTY expr_min; /* explicit minimum value */
|
||||
PROPERTY expr_max; /* explicit maximum value */
|
||||
DIRECTION direction; /* bar direction */
|
||||
STYLE style; /* bar style (hollow) */
|
||||
int length; /* bar length */
|
||||
|
||||
+6
-1
@@ -89,9 +89,14 @@ int widget_gpo_init(WIDGET * Self)
|
||||
memset(GPO, 0, sizeof(WIDGET_GPO));
|
||||
|
||||
/* load properties */
|
||||
property_load(section, "expression", "0", &GPO->expression);
|
||||
property_load(section, "expression", NULL, &GPO->expression);
|
||||
property_load(section, "update", "1000", &GPO->update);
|
||||
|
||||
/* sanity checks */
|
||||
if (!property_valid(&GPO->expression)) {
|
||||
error("Warning: widget %s has no expression", section);
|
||||
}
|
||||
|
||||
free(section);
|
||||
Self->data = GPO;
|
||||
|
||||
|
||||
@@ -230,6 +230,11 @@ int widget_image_init(WIDGET * Self)
|
||||
property_load(section, "visible", "1", &Image->visible);
|
||||
property_load(section, "inverted", "0", &Image->inverted);
|
||||
|
||||
/* sanity checks */
|
||||
if (!property_valid(&Image->file)) {
|
||||
error("Warning: widget %s has no file", section);
|
||||
}
|
||||
|
||||
free(section);
|
||||
Self->data = Image;
|
||||
|
||||
|
||||
+1
-1
@@ -77,7 +77,7 @@ int widget_keypad_init(WIDGET * Self)
|
||||
memset(keypad, 0, sizeof(WIDGET_KEYPAD));
|
||||
|
||||
/* load properties */
|
||||
property_load(section, "expression", "0", &keypad->expression);
|
||||
property_load(section, "expression", NULL, &keypad->expression);
|
||||
|
||||
/* state: pressed (default), released */
|
||||
c = cfg_get(section, "state", "pressed");
|
||||
|
||||
+9
-6
@@ -161,9 +161,10 @@ void widget_text_update(void *Self)
|
||||
char *string;
|
||||
int update = 0;
|
||||
|
||||
/* evaluate prefix and postfix */
|
||||
/* evaluate properties */
|
||||
update += property_eval(&T->prefix);
|
||||
update += property_eval(&T->postfix);
|
||||
update += property_eval(&T->style);
|
||||
|
||||
/* evaluate value */
|
||||
property_eval(&T->value);
|
||||
@@ -211,9 +212,6 @@ void widget_text_update(void *Self)
|
||||
free(string);
|
||||
}
|
||||
|
||||
/* text style */
|
||||
update += property_eval(&T->style);
|
||||
|
||||
/* something has changed and should be updated */
|
||||
if (update) {
|
||||
/* reset marquee counter if content has changed */
|
||||
@@ -246,9 +244,14 @@ int widget_text_init(WIDGET * Self)
|
||||
|
||||
/* load properties */
|
||||
property_load(section, "prefix", NULL, &Text->prefix);
|
||||
property_load(section, "expression", NULL, &Text->value);
|
||||
property_load(section, "expression", "", &Text->value);
|
||||
property_load(section, "postfix", NULL, &Text->postfix);
|
||||
property_load(section, "style", "'norm'", &Text->style);
|
||||
property_load(section, "style", NULL, &Text->style);
|
||||
|
||||
/* sanity checks */
|
||||
if (!property_valid(&Text->value)) {
|
||||
error("Warning: widget %s has no expression", section);
|
||||
}
|
||||
|
||||
/* field width, default 10 */
|
||||
cfg_number(section, "width", 10, 0, -1, &(Text->width));
|
||||
|
||||
+1
-1
@@ -92,7 +92,7 @@ int widget_timer_init(WIDGET * Self)
|
||||
memset(Timer, 0, sizeof(WIDGET_TIMER));
|
||||
|
||||
/* load properties */
|
||||
property_load(section, "expression", "1", &Timer->expression);
|
||||
property_load(section, "expression", NULL, &Timer->expression);
|
||||
property_load(section, "update", "100", &Timer->update);
|
||||
property_load(section, "active", "1", &Timer->active);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user