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