From 117c5d0ed6da9a43d6c8f25c0faf78721a05e209 Mon Sep 17 00:00:00 2001 From: marschap Date: Mon, 30 Apr 2007 13:06:06 +0000 Subject: [PATCH] new config options TitleSpeed= and Heartbeat= --- ChangeLog | 2 + LCDd.conf | 49 ++++++---- docs/lcdproc-user/configuration.docbook | 114 ++++++++++++++++++------ server/main.c | 70 +++++++++++---- server/menuitem.h | 1 + server/menuscreens.c | 52 +++++++---- server/render.c | 57 +++++++++--- server/render.h | 35 ++++---- 8 files changed, 270 insertions(+), 110 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5af7d6a..7cd9d0b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -12,6 +12,8 @@ v.0.5dev (ongoing development) * glk driver: bignum support fixed * update local snprintf to the last one, which is GPL - server core: cleanup - remove unnecessary cruft + * server core: refactor renderin code + + LCDd: config options TitleSpeed= and Heartbeat= v.0.5.2 * fix switching on/off the Load screen in lcdproc client using the menu diff --git a/LCDd.conf b/LCDd.conf index 17c3f19..5842e7b 100644 --- a/LCDd.conf +++ b/LCDd.conf @@ -28,6 +28,14 @@ ## Server section with all kinds of settings for the LCDd server ## [server] +# Where can we find the driver modules ? +# IMPORTANT: Make sure to change this setting to reflect your +# specific setup! Otherwise LCDd won't be able to find +# the driver modules and will thus not be able to +# function properly. +# NOTE: Always place a slash as last character ! +DriverPath=server/drivers/ + # Tells the server to load the given drivers. Multiple lines can be given. # The name of the driver is case sensitive and determines the section # where to look for further configuration options of the specific driver @@ -43,6 +51,14 @@ # serialVFD, sli, stv5730, svga, t6963, text, tyan, ula200, xosd Driver=curses +# Where can we find the driver modules ? +# IMPORTANT: Make sure to change this setting to reflect your +# specific setup! Otherwise LCDd won't be able to find +# the driver modules and will thus not be able to +# function properly. +# NOTE: Always place a slash as last character ! +DriverPath=server/drivers/ + # Tells the driver to bind to the given interface Bind=127.0.0.1 @@ -55,29 +71,13 @@ Port=13666 # Should we report to syslog instead of stderr ? Default: no #ReportToSyslog=yes -# Sets the default time in seconds to displays a screen. -WaitTime=5 - # User to run as. LCDd will drop its root priviledges, # if any, and run as this user instead. User=nobody -# If yes, the the serverscreen will be rotated as a usual info screen. If no, -# it will be a background screen, only visible when no other screens are -# active. -#ServerScreen=no - # The server will stay in the foreground if set to true. #Foreground=no -# Where can we find the driver modules ? -# IMPORTANT: Make sure to change this setting to reflect your -# specific setup! Otherwise LCDd won't be able to find -# the driver modules and will thus not be able to -# function properly. -# NOTE: Always place a slash as last character ! -DriverPath=server/drivers/ - # Hello message: each entry represents a display line; default: builtin #Hello=" Welcome to" #Hello=" LCDproc!" @@ -86,6 +86,23 @@ DriverPath=server/drivers/ #GoodBye="Thanks for using" #GoodBye=" LCDproc!" +# Sets the default time in seconds to displays a screen. +WaitTime=5 + +# If yes, the the serverscreen will be rotated as a usual info screen. If no, +# it will be a background screen, only visible when no other screens are +# active. +#ServerScreen=no + +# set master backlight setting [default: open; legal: off, open, on] +#Backlight=open + +# set master heartbeat setting [default: open; legal: off, open, on] +#Heartbeat=open + +# set title scrolling speed [default: 10; legal: 0-10] +#TitleSpeed=10 + # The "...Key=" lines define what the server does with keypresses that # don't go to any client. # These are the defaults: diff --git a/docs/lcdproc-user/configuration.docbook b/docs/lcdproc-user/configuration.docbook index 277f098..0bb1a39 100644 --- a/docs/lcdproc-user/configuration.docbook +++ b/docs/lcdproc-user/configuration.docbook @@ -170,17 +170,6 @@ settings for the LCDproc server LCDd. - - - WaitTime= - SECONDS - - - Sets the default time in seconds to display a screen. - If not specified the default value for SECONDS is 4. - - - User= @@ -203,23 +192,6 @@ settings for the LCDproc server LCDd. - - - ServerScreen= - - - yes - no - - - - - Include the server screen, that shows the number of active clients and screens, - into the screen rotation scheme when other screens exist. - Defaults to yes. - - - Foreground= @@ -302,11 +274,95 @@ settings for the LCDproc server LCDd. + + + WaitTime= + SECONDS + + + Sets the default time in seconds to display a screen. + If not specified the default value for SECONDS is 4. + + + + + + ServerScreen= + + + yes + no + + + + + Include the server screen, that shows the number of active clients and screens, + into the screen rotation scheme when other screens exist. + Defaults to yes. + + + + + + Backlight= + + + off + open + on + + + + + Set the master backlight setting. + If set to the default value open, then the backlight setting + of the display can be influenced by the clients. + When set to off or on, the backlight + is set to the appropriate value without the clients being able to change + the value. + + + + + + Heartbeat= + + + off + open + on + + + + + Set the master heartbeat, the oscillating icon in the top right corner + of the display, setting. + If set to the default value open, then the heartbeat setting + of the display can be influenced by the clients. + When set to off or on, the heartbeat + is turned on or off without the clients being able to change the value. + + + + + + TitleSpeed= + SPEED + + + Set the speed how fast cwover-long title lines shall scroll. + Legal values are 0 to 10, + where 0 means that no scrolling takes place + and 10 stands for fastest scrolling. + Default is 10, where no artificial delay is inserted. + + + -The …Key= lines define what the server does with keypresses that +The …Key= lines define what the server does with keypresses that don't go to any client. diff --git a/server/main.c b/server/main.c index affc890..9944115 100644 --- a/server/main.c +++ b/server/main.c @@ -270,6 +270,8 @@ clear_settings(void) foreground_mode = UNSET_INT; rotate_server_screen = UNSET_INT; backlight = UNSET_INT; + heartbeat = UNSET_INT; + titlespeed = UNSET_INT; default_duration = UNSET_INT; report_dest = UNSET_INT; @@ -394,9 +396,6 @@ process_command_line(int argc, char **argv) static int process_configfile(char *configfile) { - const char *s; - /*char buf[64];*/ - debug(RPT_DEBUG, "%s()", __FUNCTION__); /* Read server settings*/ @@ -437,21 +436,52 @@ process_configfile(char *configfile) } if (backlight == UNSET_INT) { - s = config_get_string("server", "backlight", 0, UNSET_STR); - if (strcmp(s, "on") == 0) { - backlight = BACKLIGHT_ON; - } - else if (strcmp(s, "off") == 0) { - backlight = BACKLIGHT_OFF; - } - else if (strcmp(s, "open") == 0) { - backlight = BACKLIGHT_OPEN; - } - else if (strcmp(s, UNSET_STR) != 0) { - report(RPT_WARNING, "Backlight state should be on, off or open"); + const char *s = config_get_string("server", "Backlight", 0, NULL); + + if (s != NULL) { + if ((strcasecmp(s, "on") == 0) || (strcasecmp(s, "yes") == 0)) { + backlight = BACKLIGHT_ON; + } + else if (strcasecmp(s, "off") == 0) { + backlight = BACKLIGHT_OFF; + } + if ((strcasecmp(s, "off") == 0) || (strcasecmp(s, "no") == 0)) { + backlight = BACKLIGHT_OPEN; + } + else { + report(RPT_WARNING, "Backlight state should be on, off or open"); + } } } + if (heartbeat == UNSET_INT) { + const char *s = config_get_string("server", "Heartbeat", 0, NULL); + + if (s != NULL) { + if ((strcasecmp(s, "on") == 0) || (strcasecmp(s, "yes") == 0)) { + heartbeat = HEARTBEAT_ON; + } + else if (strcasecmp(s, "off") == 0) { + heartbeat = HEARTBEAT_OFF; + } + if ((strcasecmp(s, "off") == 0) || (strcasecmp(s, "no") == 0)) { + heartbeat = HEARTBEAT_OPEN; + } + else { + report(RPT_WARNING, "Heartbeat state should be on, off or open"); + } + } + } + + if (titlespeed == UNSET_INT) { + int speed = config_get_int("server", "TitleSpeed", 0, TITLESPEED_DEFAULT); + + /* set titlespeed */ + titlespeed = (speed <= TITLESPEED_NO) + ? TITLESPEED_NO + : min(speed, TITLESPEED_MAX); + } + if (report_dest == UNSET_INT) { int rs = config_get_bool("server", "reportToSyslog", 0, UNSET_INT); @@ -471,9 +501,9 @@ process_configfile(char *configfile) if (num_drivers == 0) { /* read the drivernames*/ - while(1) { - s = config_get_string("server", "driver", num_drivers, NULL); - if (!s) + while (1) { + const char *s = config_get_string("server", "driver", num_drivers, NULL); + if (s == NULL) break; if (s[0] != 0) { drivernames[num_drivers] = malloc(strlen(s)+1); @@ -510,6 +540,10 @@ set_default_settings(void) default_duration = DEFAULT_SCREEN_DURATION; if (backlight == UNSET_INT) backlight = BACKLIGHT_OPEN; + if (heartbeat == UNSET_INT) + heartbeat = HEARTBEAT_OPEN; + if (titlespeed == UNSET_INT) + titlespeed = TITLESPEED_DEFAULT; if (report_dest == UNSET_INT) report_dest = DEFAULT_REPORTDEST; diff --git a/server/menuitem.h b/server/menuitem.h index 9ef3801..1a281e2 100644 --- a/server/menuitem.h +++ b/server/menuitem.h @@ -36,6 +36,7 @@ #endif #define max(a,b) (((a) > (b)) ? (a) : (b)) +#define min(a,b) (((a) < (b)) ? (a) : (b)) /********************************************************************* * Data definitions of the menustuff diff --git a/server/menuscreens.c b/server/menuscreens.c index 94cb072..95c5367 100644 --- a/server/menuscreens.c +++ b/server/menuscreens.c @@ -41,6 +41,7 @@ /* Next include files are needed for settings that we can modify */ #include "render.h" + char *menu_key; char *enter_key; char *up_key; @@ -67,6 +68,7 @@ void menuscreen_create_menu(void); Menu *menuscreen_get_main(void); MenuEventFunc(heartbeat_handler); MenuEventFunc(backlight_handler); +MenuEventFunc(titlespeed_handler); MenuEventFunc(contrast_handler); MenuEventFunc(brightness_handler); @@ -447,14 +449,20 @@ void menuscreen_create_menu(void) menu_add_item(main_menu, screens_menu); #endif /*LCDPROC_TESTMENUS*/ - /* menu's client is NULL since we're in the server */ + /* add option menu contents: + * menu's client is NULL since we're in the server */ checkbox = menuitem_create_checkbox("heartbeat", heartbeat_handler, "Heartbeat", NULL, true, heartbeat); menu_add_item(options_menu, checkbox); - /* menu's client is NULL since we're in the server */ checkbox = menuitem_create_checkbox("backlight", backlight_handler, "Backlight", NULL, true, backlight); menu_add_item(options_menu, checkbox); + slider = menuitem_create_slider("titlespeed", titlespeed_handler, + "TitleSpeed", NULL, "0", "10", TITLESPEED_NO, TITLESPEED_MAX, 1, titlespeed); + menu_add_item(options_menu, slider); + + /* add driver specific option menus for each driver: + * menu's client is NULL since we're in the server */ for (driver = drivers_getfirst(); driver; driver = drivers_getnext()) { int contrast_avail = (driver->get_contrast && driver->set_contrast) ? 1 : 0; int brightness_avail = (driver->get_brightness && driver->set_brightness) ? 1 : 0; @@ -534,11 +542,10 @@ MenuEventFunc (heartbeat_handler) debug(RPT_DEBUG, "%s(item=[%s], event=%d)", __FUNCTION__, ((item != NULL) ? item->id : "(null)"), event); - if (event == MENUEVENT_UPDATE) { + if ((item != NULL) && (event == MENUEVENT_UPDATE)) { /* Set heartbeat setting */ heartbeat = item->data.checkbox.value; - report(RPT_INFO, "Menu: set heartbeat to %d", - item->data.checkbox.value); + report(RPT_INFO, "Menu: set heartbeat to %d", heartbeat); } return 0; } @@ -548,12 +555,23 @@ MenuEventFunc (backlight_handler) debug(RPT_DEBUG, "%s(item=[%s], event=%d)", __FUNCTION__, ((item != NULL) ? item->id : "(null)"), event); - if (event == MENUEVENT_UPDATE) - { + if ((item != NULL) && (event == MENUEVENT_UPDATE)) { /* Set backlight setting */ backlight = item->data.checkbox.value; - report(RPT_INFO, "Menu: set backlight to %d", - item->data.checkbox.value); + report(RPT_INFO, "Menu: set backlight to %d", backlight); + } + return 0; +} + +MenuEventFunc (titlespeed_handler) +{ + debug(RPT_DEBUG, "%s(item=[%s], event=%d)", __FUNCTION__, + ((item != NULL) ? item->id : "(null)"), event); + + if ((item != NULL) && ((event == MENUEVENT_MINUS) || (event == MENUEVENT_PLUS))) { + /* set titlespeed setting */ + titlespeed = item->data.slider.value; + report(RPT_INFO, "Menu: set titlespeed to %d", titlespeed); } return 0; } @@ -563,11 +581,9 @@ MenuEventFunc (contrast_handler) debug(RPT_DEBUG, "%s(item=[%s], event=%d)", __FUNCTION__, ((item != NULL) ? item->id : "(null)"), event); - /* This function can be called by one of several drivers that - * support contrast ! - * We need to check the menu association to see which driver. */ - if (event == MENUEVENT_MINUS || event == MENUEVENT_PLUS) { - /* Determine the driver */ + /* This function can be called by one of several drivers that support contrast */ + if ((item != NULL) && ((event == MENUEVENT_MINUS) || (event == MENUEVENT_PLUS))) { + /* Determine the driver by following the menu's association */ Driver *driver = item->parent->data.menu.association; if (driver != NULL) { @@ -584,11 +600,9 @@ MenuEventFunc (brightness_handler) debug(RPT_DEBUG, "%s(item=[%s], event=%d)", __FUNCTION__, ((item != NULL) ? item->id : "(null)"), event); - /* This function can be called by one of several drivers that - * support brightness ! - * We need to check the menu association to see which driver. */ - if (event == MENUEVENT_MINUS || event == MENUEVENT_PLUS) { - /* Determine the driver */ + /* This function can be called by one of several drivers that support brightness ! */ + if ((item != NULL) && ((event == MENUEVENT_MINUS) || (event == MENUEVENT_PLUS))) { + /* Determine the driver by following the menu's association */ Driver *driver = item->parent->data.menu.association; if (driver != NULL) { diff --git a/server/render.c b/server/render.c index f39929a..4a07563 100644 --- a/server/render.c +++ b/server/render.c @@ -39,18 +39,22 @@ #include "widget.h" #include "render.h" +#define BUFSIZE 1024 /* larger than display width => large enough */ + + int heartbeat = HEARTBEAT_OPEN; static int heartbeat_fallback = HEARTBEAT_ON; /* If no heartbeat setting has been set at all */ + int backlight = BACKLIGHT_OPEN; static int backlight_fallback = BACKLIGHT_ON; /* If no backlight setting has been set at all */ + +int titlespeed = 1; + int output_state = 0; char *server_msg_text; int server_msg_expire = 0; -#define BUFSIZE 1024 /* larger than display width => large enough */ - - static int render_frame(LinkedList *list, int left, int top, int right, int bottom, int fwid, int fhgt, char fscroll, int fspeed, long timer); static int render_string(Widget *w, int left, int top, int right, int bottom, int fy); static int render_hbar(Widget *w, int left, int top, int right, int bottom, int fy); @@ -352,40 +356,67 @@ render_title(Widget *w, int left, int top, int right, int bottom, long timer) if ((w != NULL) && (w->text != NULL) && (vis_width >= 8)) { char str[BUFSIZE]; int length = strlen(w->text); + int width = vis_width - 6; int x; + /* calculate delay from titlespeed: <=0 -> 0, [1 - infty] -> [10 - 1] */ + int delay = (titlespeed <= TITLESPEED_NO) + ? TITLESPEED_NO + : max(TITLESPEED_MIN, TITLESPEED_MAX - titlespeed); + /* display leading fillers */ drivers_icon(w->x + left, w->y + top, ICON_BLOCK_FILLED); drivers_icon(w->x + left + 1, w->y + top, ICON_BLOCK_FILLED); length = min(length, sizeof(str)); - if (length <= vis_width - 6) { + if ((length <= width) || (delay == 0)) { + + /* copy test starting from the beginning */ + length = min(length, width); strncpy(str, w->text, length); str[length] = '\0'; + /* set x value for trailing fillers */ x = length + 4; } else { /* Scroll the title, if it doesn't fit... */ - int speed = 1; - int offset = timer / speed; - int reverse = offset / length; + int offset = timer; + int reverse; + /* if the delay is "too large" increase cycle length */ + if ((delay != 0) && (delay < length / (length - width))) + offset /= delay; + + /* reverse direction every length ticks */ + reverse = (offset / length) & 1; + + /* restrict offset to cycle length */ offset %= length; offset = max(offset, 0); - if (offset > length - (vis_width - 6)) - offset = length - (vis_width - 6); - if (reverse & 1) /* Scrolling backwards... */ - offset = (length - (vis_width - 6)) - offset; - length = abs(vis_width - 6); - length = min(length, sizeof(str)); + /* if the delay is "low enough" slow down as requested */ + if ((delay != 0) && (delay >= length / (length - width))) + offset /= delay; + + /* restrict offset to the max. allowed offset: length - width */ + offset = min(offset, length - width); + + /* scroll backward by mirroring offset at max. offset */ + if (reverse) + offset = (length - width) - offset; + + /* copy test starting from offset */ + length = min(width, sizeof(str)); strncpy(str, w->text + offset, length); str[length] = '\0'; + /* set x value for trailing fillers */ x = vis_width - 2; } + /* display text */ drivers_string(w->x + 3 + left, w->y + top, str); + /* display trailing fillers */ for ( ; x < vis_width; x++) { drivers_icon(w->x + x + left, w->y + top, ICON_BLOCK_FILLED); } diff --git a/server/render.h b/server/render.h index dab56aa..84cd250 100644 --- a/server/render.h +++ b/server/render.h @@ -14,31 +14,36 @@ #include "screen.h" -#define HEARTBEAT_OFF 0 -#define HEARTBEAT_ON 1 -#define HEARTBEAT_OPEN 2 +#define HEARTBEAT_OFF 0 +#define HEARTBEAT_ON 1 +#define HEARTBEAT_OPEN 2 -#define BACKLIGHT_OFF 0 -#define BACKLIGHT_ON 1 -#define BACKLIGHT_OPEN 2 +#define BACKLIGHT_OFF 0 +#define BACKLIGHT_ON 1 +#define BACKLIGHT_OPEN 2 -#define BACKLIGHT_BLINK 0x100 -#define BACKLIGHT_FLASH 0x200 +#define BACKLIGHT_BLINK 0x100 +#define BACKLIGHT_FLASH 0x200 -#define CURSOR_OFF 0 -#define CURSOR_DEFAULT_ON 1 -#define CURSOR_BLOCK 4 -#define CURSOR_UNDER 5 +#define CURSOR_OFF 0 +#define CURSOR_DEFAULT_ON 1 +#define CURSOR_BLOCK 4 +#define CURSOR_UNDER 5 + +#define TITLESPEED_NO 0 /* needs to be (TITLESPEED_MIN - 1) */ +#define TITLESPEED_MIN 1 +#define TITLESPEED_MAX 10 +#define TITLESPEED_DEFAULT 10 /* = no delay */ extern int heartbeat; extern int backlight; +extern int titlespeed; extern int output_state; +/* Render the given screen. */ int render_screen(Screen *s, long timer); - /* Renders the given screen. */ +/* Display a short message, which must be shorter than 16 chars, in a corner */ int server_msg(const char *text, int expire); - /* Displays a short message in a corner. Message must be shorter - * than 16 chars. */ #endif