- Moved some code from main.c to screenlist.c

- Implemented reloading by sending SIGHUP.
- Now doing 'real 8Hz' rendering and 32Hz input processing.
- Removed noscreen feature (that we rejected).
This commit is contained in:
robijn
2002-08-04 20:58:51 +00:00
parent 8a1933e3b9
commit dc619e596f
15 changed files with 374 additions and 247 deletions
+3 -5
View File
@@ -69,11 +69,9 @@ User=nobody
# if any, and run as this user instead. # if any, and run as this user instead.
#ServerScreen=no #ServerScreen=no
# Enables the built-in server screen [Default: noscreen] # If yes, the the serverscreen will be rotated as a usual info screen. If no,
# yes : always, # it will be a background screen, only visible when no other screens are
# noscreen : when there are no other screens active, # active.
# no : never, the LCD display will be blank when there are
# no screens active.
Foreground=yes Foreground=yes
# The server will stay in the foreground if set to true. # The server will stay in the foreground if set to true.
+6 -1
View File
@@ -25,7 +25,7 @@
#include "shared/report.h" #include "shared/report.h"
#include "render.h" #include "render.h"
LinkedList *clientlist; LinkedList *clientlist = NULL;
/* Initialize and kill client list...*/ /* Initialize and kill client list...*/
int int
@@ -49,6 +49,11 @@ clients_shutdown ()
debug (RPT_DEBUG, "%s()", __FUNCTION__); debug (RPT_DEBUG, "%s()", __FUNCTION__);
if( !clientlist ) {
/* Program shutdown before completed startup */
return -1;
}
/* Free all client structures... */ /* Free all client structures... */
for (c=LL_GetFirst (clientlist); c; c=LL_GetNext (clientlist) ) { for (c=LL_GetFirst (clientlist); c; c=LL_GetNext (clientlist) ) {
debug (RPT_DEBUG, "%s: ...", __FUNCTION__); debug (RPT_DEBUG, "%s: ...", __FUNCTION__);
+1 -1
View File
@@ -24,7 +24,7 @@
#include "config.h" #include "config.h"
#endif #endif
#include "screenlist.h" /* for timer */ #include "main.h" /* for timer */
#include "shared/report.h" #include "shared/report.h"
#include "shared/configfile.h" #include "shared/configfile.h"
+19 -2
View File
@@ -35,7 +35,7 @@ void input_internal_key (char * key);
LinkedList * keylist; LinkedList * keylist;
int init_input() int input_init()
{ {
debug (RPT_DEBUG, "%s()", __FUNCTION__ ); debug (RPT_DEBUG, "%s()", __FUNCTION__ );
@@ -44,17 +44,34 @@ int init_input()
return 0; return 0;
} }
int input_shutdown()
{
if (!keylist) {
/* Program shutdown before completed startup */
return -1;
}
free (keylist);
return 0;
}
int int
handle_input () handle_input ()
{ {
char * key; char * key;
Screen * current_screen;
Client * current_client; Client * current_client;
Client * target; Client * target;
KeyReservation * kr; KeyReservation * kr;
debug (RPT_DEBUG, "%s()", __FUNCTION__ ); debug (RPT_DEBUG, "%s()", __FUNCTION__ );
current_client = screenlist_current()->client; current_screen = screenlist_current();
if( current_screen )
current_client = current_screen->client;
else
current_client = NULL;
/* Handle all keypresses */ /* Handle all keypresses */
while ((key = drivers_get_key ()) != NULL ) { while ((key = drivers_get_key ()) != NULL ) {
+3 -1
View File
@@ -40,8 +40,10 @@ typedef struct KeyReservation {
} KeyReservation; } KeyReservation;
int init_input(); int input_init();
/* Init the input handling system */ /* Init the input handling system */
int input_shutdown();
/* Shut it down */
int input_reserve_key (char * key, bool exclusive, Client * client); int input_reserve_key (char * key, bool exclusive, Client * client);
/* Reserves a key for a client */ /* Reserves a key for a client */
/* Return -1 if reservation of key is not possible */ /* Return -1 if reservation of key is not possible */
+162 -133
View File
@@ -7,6 +7,9 @@
* *
* Copyright (c) 1999, William Ferrell, Scott Scriven * Copyright (c) 1999, William Ferrell, Scott Scriven
* 2001, Joris Robijn * 2001, Joris Robijn
* 2001, Rene Wagner
* 2002, Mike Patnode
* 2002, Guillaume Filion
* *
* *
* Contains main(), plus signal callback functions and a help screen. * Contains main(), plus signal callback functions and a help screen.
@@ -21,6 +24,8 @@
* *
*/ */
#include "config.h"
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
@@ -33,6 +38,11 @@
#include <sys/types.h> #include <sys/types.h>
#include <fcntl.h> #include <fcntl.h>
#ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
#endif
/* TODO: fill in what to include otherwise */
extern char *optarg; extern char *optarg;
extern int optind, optopt, opterr; extern int optind, optopt, opterr;
@@ -52,28 +62,22 @@ extern int optind, optopt, opterr;
#include "drivers.h" #include "drivers.h"
#include "main.h" #include "main.h"
#define MAX_TIMER 0x10000
#define DEFAULT_LCD_PORT LCDPORT #define DEFAULT_LCD_PORT LCDPORT
#define DEFAULT_BIND_ADDR "127.0.0.1" #define DEFAULT_BIND_ADDR "127.0.0.1"
#define DEFAULT_CONFIGFILE "/etc/LCDd.conf" #define DEFAULT_CONFIGFILE "/etc/LCDd.conf"
#define DEFAULT_USER "nobody" #define DEFAULT_USER "nobody"
#define DEFAULT_DRIVER "curses" #define DEFAULT_DRIVER "curses"
#define DEFAULT_DRIVER_PATH #define DEFAULT_DRIVER_PATH
#define DEFAULT_WAITTIME 8
#define MAX_DRIVERS 8 #define MAX_DRIVERS 8
#define DEFAULT_DAEMON_MODE 1 #define DEFAULT_DAEMON_MODE 1
#define DEFAULT_ENABLE_SERVER_SCREEN SERVER_SCREEN_NOSCREEN #define DEFAULT_ROTATE_SERVER_SCREEN 1
#define DEFAULT_REPORTTOSYSLOG 0 #define DEFAULT_REPORTTOSYSLOG 0
#define DEFAULT_REPORTLEVEL RPT_WARNING #define DEFAULT_REPORTLEVEL RPT_WARNING
#define DEFAULT_ADDR "127.0.0.1"
//#define DEFAULT_WAITTIME 8
/* Store some standard defines into vars... */ #define DEFAULT_SCREEN_DURATION 32
char *version = VERSION; #define DEFAULT_HEARTBEAT HEARTBEAT_ON
char *protocol_version = PROTOCOL_VERSION;
char *api_version = API_VERSION;
char *build_date = __DATE__;
/* Socket to bind to... /* Socket to bind to...
@@ -84,7 +88,21 @@ char *build_date = __DATE__;
and which address to bind to at run time. */ and which address to bind to at run time. */
/* Store some standard defines into vars... */
char *version = VERSION;
char *protocol_version = PROTOCOL_VERSION;
char *api_version = API_VERSION;
char *build_date = __DATE__;
/**** Configuration variables ****/ /**** Configuration variables ****/
/* Some variables are settable on the command line. This are variables that
* change the mode of operation. This includes settings that you can use to
* enable debugging: driver selection, report settings, bind address etc.
* All other settings do not need to be settable from the command line. They
* also do not necesarily need to be read in main.c but can better be read in
* in the file concerned.
*/
/* All variables are set to 'unset' values*/ /* All variables are set to 'unset' values*/
#define UNSET_INT -1 #define UNSET_INT -1
@@ -96,19 +114,23 @@ char configfile[256]; /* a lot of space in the executable. */
char user[64]; /* The values will be overwritten anyway... */ char user[64]; /* The values will be overwritten anyway... */
int daemon_mode = UNSET_INT; int daemon_mode = UNSET_INT;
int enable_server_screen = UNSET_INT; int rotate_server_screen = UNSET_INT;
static int reportLevel = UNSET_INT; static int reportLevel = UNSET_INT;
static int reportToSyslog = UNSET_INT; static int reportToSyslog = UNSET_INT;
static int serverStarted = 0;
/* The drivers and their driver parameters*/ /* The drivers and their driver parameters */
char *drivernames[MAX_DRIVERS]; char *drivernames[MAX_DRIVERS];
int num_drivers = 0; int num_drivers = 0;
int stored_argc;
char **stored_argv;
short got_reload_signal = 0;
long int timer = 0;
/**** Local functions ****/ /**** Local functions ****/
void exit_program (int val); void exit_program (int val);
void catch_reload_signal (int val);
void HelpScreen (); void HelpScreen ();
void clear_settings(); void clear_settings();
@@ -123,21 +145,22 @@ int init_drivers();
int init_screens(); int init_screens();
void do_mainloop(); void do_mainloop();
#define ESSENTIAL(f) {int r; if( ( r=(f) )<0 ) { report( RPT_CRIT,"Critical error, abort"); exit_program(0);}}
#define ESSENTIAL(f) {int r; if( ( r=(f) )<0 ) { report( RPT_CRIT,"Critical error, abort"); exit_program(0);}}
int int
main (int argc, char **argv) main (int argc, char **argv)
{ {
/* FIXME: s is getting clobbered - in MANY places!!!
*screen *s = NULL; stored_argc = argc;
*char buf[64]; stored_argv = argv;
*/
signal (SIGINT, exit_program); /* Ctrl-C will cause a clean exit...*/ signal (SIGINT, exit_program); /* Ctrl-C will cause a clean exit...*/
signal (SIGTERM, exit_program); /* and "kill"...*/ signal (SIGTERM, exit_program); /* and "kill"...*/
signal (SIGHUP, exit_program); /* and "kill -HUP" (hangup)...*/
signal (SIGKILL, exit_program); /* and just in case, "kill -KILL" (which cannot be trapped; but oh well)*/ signal (SIGKILL, exit_program); /* and just in case, "kill -KILL" (which cannot be trapped; but oh well)*/
signal (SIGHUP, catch_reload_signal); /* On SIGHUP reread config and restart the drivers ! */
/* Let's see if we can actually get this to work ;) */
/* If no paramaters given, give the help screen. /* If no paramaters given, give the help screen.
*if (argc == 1) *if (argc == 1)
* HelpScreen (); * HelpScreen ();
@@ -188,17 +211,14 @@ main (int argc, char **argv)
report( RPT_INFO, "Set report level to %d, output to %s", reportLevel, (reportToSyslog?"syslog":"stderr") ); report( RPT_INFO, "Set report level to %d, output to %s", reportLevel, (reportToSyslog?"syslog":"stderr") );
/* Startup the server*/ /* Startup the server*/
ESSENTIAL( screenlist_init() );
ESSENTIAL( init_drivers() ); ESSENTIAL( init_drivers() );
ESSENTIAL( init_sockets() ); ESSENTIAL( init_sockets() );
ESSENTIAL( init_input() ); ESSENTIAL( input_init() );
ESSENTIAL( init_menu() ); ESSENTIAL( menuscreens_init() );
ESSENTIAL( init_screens() ); ESSENTIAL( server_screen_init() );
ESSENTIAL( drop_privs(user) ); ESSENTIAL( drop_privs(user) );
/* Store it for exit_program()*/
serverStarted = 1;
#ifndef DEBUG
/* Now, go into daemon mode...*/ /* Now, go into daemon mode...*/
if (daemon_mode) { if (daemon_mode) {
report(RPT_INFO, "Server forking to background"); report(RPT_INFO, "Server forking to background");
@@ -207,13 +227,13 @@ main (int argc, char **argv)
output_GPL_notice(); output_GPL_notice();
report(RPT_INFO, "Server running in foreground"); report(RPT_INFO, "Server running in foreground");
} }
#endif
do_mainloop(); do_mainloop();
/* This loop never stops; we'll get out only with a signal...*/ /* This loop never stops; we'll get out only with a signal...*/
return 0; return 0;
} }
#undef ESSENTIAL
void void
@@ -228,7 +248,7 @@ clear_settings ()
strncpy( configfile, UNSET_STR, sizeof(configfile) ); strncpy( configfile, UNSET_STR, sizeof(configfile) );
strncpy( user, UNSET_STR, sizeof(user) ); strncpy( user, UNSET_STR, sizeof(user) );
daemon_mode = UNSET_INT; daemon_mode = UNSET_INT;
enable_server_screen = UNSET_INT; rotate_server_screen = UNSET_INT;
backlight = UNSET_INT; backlight = UNSET_INT;
default_duration = UNSET_INT; default_duration = UNSET_INT;
@@ -251,11 +271,15 @@ process_command_line (int argc, char **argv)
debug( RPT_DEBUG, "%s( argc=%d, argv=...)", __FUNCTION__, argc ); debug( RPT_DEBUG, "%s( argc=%d, argv=...)", __FUNCTION__, argc );
/* Reset getopt */
optind = 0;
/* analyze options here..*/ /* analyze options here..*/
while ((c = getopt(argc, argv, "a:p:d:hfib:w:c:u:sr:")) > 0) { while ((c = getopt(argc, argv, "a:p:d:hfib:w:c:u:sr:")) > 0) {
/* FIXME: Setting of c in this loop clobbers s! /* FIXME: Setting of c in this loop clobbers s!
* s is set equivalent to c. * s is set equivalent to c.
*/ */
report( RPT_INFO, ">>>> %i", (int) c );
switch(c) { switch(c) {
case 'd': case 'd':
/* Add to a list of drivers to be initialized later...*/ /* Add to a list of drivers to be initialized later...*/
@@ -285,7 +309,7 @@ process_command_line (int argc, char **argv)
strncpy(configfile, optarg, sizeof(configfile)); strncpy(configfile, optarg, sizeof(configfile));
break; break;
case 'i': case 'i':
enable_server_screen = 0; rotate_server_screen = 0;
break; break;
case 'b': case 'b':
if( strcmp( optarg, "on" ) == 0 ) { if( strcmp( optarg, "on" ) == 0 ) {
@@ -374,20 +398,8 @@ process_configfile ( char *configfile )
daemon_mode = !fg; daemon_mode = !fg;
} }
if( enable_server_screen == UNSET_INT ) { if( rotate_server_screen == UNSET_INT ) {
s = config_get_string( "server", "serverscreen", 0, UNSET_STR ); rotate_server_screen = config_get_bool( "server", "serverscreen", 0, UNSET_INT );
if( strcmp( s, "no" ) == 0 ) {
enable_server_screen = SERVER_SCREEN_NEVER;
}
else if( strcmp( s, "noscreen" ) == 0 ) {
enable_server_screen = SERVER_SCREEN_NOSCREEN;
}
else if( strcmp( s, "yes" ) == 0 ) {
enable_server_screen = SERVER_SCREEN_ALWAYS;
}
else if( strcmp( s, UNSET_STR ) != 0 ) {
report( RPT_ERR, "Serverscreen can only be no, noscreen or yes" );
}
} }
if( backlight == UNSET_INT ) { if( backlight == UNSET_INT ) {
@@ -407,10 +419,7 @@ process_configfile ( char *configfile )
} }
if( reportToSyslog == UNSET_INT ) { if( reportToSyslog == UNSET_INT ) {
/* Is the value set in the config file anyway ?*/ reportToSyslog = config_get_bool( "server", "reportToSyslog", 0, UNSET_INT );
if( strcmp( config_get_string( "server", "reportToSyslog", 0, "" ), "" ) != 0 ) {
reportToSyslog = config_get_bool( "server", "reportToSyslog", 0, 0 );
}
} }
if( reportLevel == UNSET_INT ) { if( reportLevel == UNSET_INT ) {
reportLevel = config_get_int( "server", "reportLevel", 0, UNSET_INT ); reportLevel = config_get_int( "server", "reportLevel", 0, UNSET_INT );
@@ -457,8 +466,8 @@ set_default_settings()
if (daemon_mode == UNSET_INT) if (daemon_mode == UNSET_INT)
daemon_mode = DEFAULT_DAEMON_MODE; daemon_mode = DEFAULT_DAEMON_MODE;
if (enable_server_screen == UNSET_INT) if (rotate_server_screen == UNSET_INT)
enable_server_screen = DEFAULT_ENABLE_SERVER_SCREEN; rotate_server_screen = DEFAULT_ROTATE_SERVER_SCREEN;
if (default_duration == UNSET_INT) if (default_duration == UNSET_INT)
default_duration = DEFAULT_SCREEN_DURATION; default_duration = DEFAULT_SCREEN_DURATION;
@@ -631,101 +640,115 @@ init_screens ()
return -1; return -1;
} }
if (enable_server_screen > SERVER_SCREEN_NEVER) { /* Add the server screen */
/* Add the server screen */ if (server_screen_init () < 0) {
if (server_screen_init () < 0) { report(RPT_ERR, "Error initializing server screens");
report(RPT_ERR, "Error initializing server screens"); return -1;
return -1; }
} if (!rotate_server_screen) {
/* Display the server screen only when there are no other screens */
if (enable_server_screen == SERVER_SCREEN_NOSCREEN) { server_screen->priority = 256;
/* Display the server screen only when there are no other screens */
server_screen->priority = 256;
}
} }
return 0; return 0;
} }
#define ESSENTIAL(f) {int r; if( ( r=(f) )<0 ) { report( RPT_CRIT,"Critical error while reloading, abort"); _exit(0);}}
void
do_reload ()
{
drivers_unload_all (); /* Close all drivers */
config_clear();
clear_settings();
/* Reread command line*/
ESSENTIAL( process_command_line (stored_argc, stored_argv) );
/* Reread config file */
if (strcmp(configfile, UNSET_STR)==0)
strncpy (configfile, DEFAULT_CONFIGFILE, sizeof(configfile));
ESSENTIAL( process_configfile (configfile) );
/* Set default values */
set_default_settings();
/* Set reporting values */
ESSENTIAL( set_reporting( "LCDd", reportLevel, (reportToSyslog?RPT_DEST_SYSLOG:RPT_DEST_STDERR) ) );
report( RPT_INFO, "Set report level to %d, output to %s", reportLevel, (reportToSyslog?"syslog":"stderr") );
/* And restart the drivers */
ESSENTIAL( init_drivers() );
}
#undef ESSENTIAL
void void
do_mainloop () do_mainloop ()
{ {
Screen *s = NULL; Screen * s;
char *message=NULL; struct timeval t;
struct timeval last_t;
int sleeptime;
long int process_lag = 0;
long int render_lag = 0;
long int t_diff;
debug( RPT_DEBUG, "%s()", __FUNCTION__ ); debug( RPT_DEBUG, "%s()", __FUNCTION__ );
/*char buf[64];*/ gettimeofday (&t, NULL); /* Get initial time */
/* FIXME: s should still be null from initialization.... what's happening here?!*/
while (1) { while (1) {
sock_poll_clients (); /* poll clients for input*/ /* Get current time */
parse_all_client_messages (); /* analyze input from network clients*/ last_t = t;
handle_input (); /* handle key input from devices*/ gettimeofday (&t, NULL);
t_diff = ((t.tv_sec - last_t.tv_sec) * 1e6 + (t.tv_usec - last_t.tv_usec));
/* TODO: Move this code to screenlist.c... process_lag += t_diff;
* ... it should just say "handle_screens();" if (process_lag > 0) {
* Timer gets reset by screenlist_next() /* Time for a processing stroke */
*/ sock_poll_clients (); /* poll clients for input*/
parse_all_client_messages (); /* analyze input from network clients*/
handle_input (); /* handle key input from devices*/
timer++; /* We've done the job... */
process_lag = 0 - (1e6/PROCESS_FREQ);
if (s && (timer >= s->duration)) /* Note : this does not make a fixed frequency */
screenlist_next ();
/* Just in case it gets out of hand...*/
if (timer >= MAX_TIMER)
timer = 0;
/* Update server screen with the right number
* of clients and screens...
*/
/* TODO: Move this call to every client connection
* and every screen add...
*/
update_server_screen (timer);
/* draw the current scren*/
if ((s = screenlist_current ()) != NULL)
draw_screen (s, timer);
usleep (TIME_UNIT);
/* Check to see if the screen has a timeout value, if it does
* decrese it and then check to see if it has excpired.
* Remove if expired.
*/
if((message = malloc(256)) == NULL)
report(RPT_ERR, "Error allocating message string");
else if (s) {
snprintf(message, 256, "Screen->%s has timeout->%d", s->name, s->timeout);
report(RPT_DEBUG, message);
free(message);
} }
if (s && s->timeout != -1) {
--(s->timeout); render_lag += t_diff;
if((message = malloc(256)) == NULL) if (render_lag > 0) {
report(RPT_ERR, "Error allocating message string"); /* Time for a rendering stroke */
else { timer ++;
snprintf(message, 256, "Timeout matches check, screen %s has timeout->%d", s->name, s->timeout); screenlist_update ();
report(RPT_DEBUG, message); s = screenlist_current ();
free(message);
/* TODO: Move this call to every client connection
* and every screen add...
*/
if( s == server_screen ) {
update_server_screen (timer);
} }
if (s->timeout <= 0) { render_screen (s, timer);
client_remove_screen (s->client, s);
screen_destroy (s); /* We've done the job... */
if((message = malloc(256)) == NULL) if( render_lag > (1e6/RENDER_FREQ) * MAX_RENDER_LAG_FRAMES ) {
report(RPT_ERR, "Error allocating message string"); /* Cause rendering slowdown because too much lag */
else { render_lag = (1e6/RENDER_FREQ) * MAX_RENDER_LAG_FRAMES;
snprintf(message, 256, "Removing screen %s which has timeout->%d", s->name, s->timeout);
report(RPT_DEBUG, message);
free(message);
}
} }
render_lag -= (1e6/RENDER_FREQ);
/* Note: this DOES make a fixed frequency (except with slowdown) */
}
/* Sleep just as long as needed */
sleeptime = min (0-process_lag, 0-render_lag);
if( sleeptime > 0 ) {
usleep (sleeptime);
}
/* Check if a SIGHUP has been caught */
if( got_reload_signal ) {
got_reload_signal = 0;
do_reload ();
} }
} }
@@ -753,10 +776,9 @@ exit_program (int val)
default: snprintf(buf, sizeof(buf), "Server shutting down on signal %d", val); break; default: snprintf(buf, sizeof(buf), "Server shutting down on signal %d", val); break;
/* Other values should not be seen, but just in case.. */ /* Other values should not be seen, but just in case.. */
} }
report(RPT_NOTICE, buf); /* report it */
} }
report(RPT_NOTICE, buf); /* report it */
/* Set emergency reporting and flush all messages if not done already. */ /* Set emergency reporting and flush all messages if not done already. */
if( reportLevel == UNSET_INT ) if( reportLevel == UNSET_INT )
reportLevel = DEFAULT_REPORTLEVEL; reportLevel = DEFAULT_REPORTLEVEL;
@@ -768,14 +790,21 @@ exit_program (int val)
drivers_unload_all (); /* release driver memory and file descriptors */ drivers_unload_all (); /* release driver memory and file descriptors */
/* Shutdown things if server start was complete */ /* Shutdown things if server start was complete */
if( serverStarted ) { clients_shutdown (); /* shutdown clients (must come first) */
clients_shutdown (); /* shutdown clients (must come first) */ menuscreens_shutdown ();
screenlist_shutdown (); /* shutdown screens (must come after client_shutdown) */ screenlist_shutdown (); /* shutdown screens (must come after client_shutdown) */
} input_shutdown (); /* shutdown key input part */
exit (0); _exit (0);
} }
void
catch_reload_signal (int val)
{
debug( RPT_DEBUG, "%s( val=%d )", __FUNCTION__, val );
got_reload_signal = 1;
}
void void
HelpScreen () HelpScreen ()
+14 -10
View File
@@ -21,21 +21,25 @@
contains a few things that other parts of the program might want contains a few things that other parts of the program might want
to know about... to know about...
*/ */
#define DEFAULT_SCREEN_PRIORITY 128
extern char *version; extern char *version;
extern char *protocol_version; extern char *protocol_version;
extern char *build_date; extern char *build_date;
void exit_program (int val); /* You should be able to modify the following freqencies... */
#define RENDER_FREQ 8
/* We want 8 frames per second */
#define PROCESS_FREQ 32
/* And 32 times per second processing of messages and keypresses. */
#define MAX_RENDER_LAG_FRAMES 16
/* Allow the rendering strokes to lag behind this many frames.
* More lag will not be corrected, but will cause slow-down. */
#define TIME_UNIT (1e6/RENDER_FREQ)
/* Variable from stone age, still used a lot. */
/* 1/8th second is a single time unit...*/ extern long int timer;
#define TIME_UNIT 125000 /* 32 bits at 8Hz will overflow in 2 ^ 29 = 5e8 seconds = 17 years.
/* But I plan to double the framerate soon, or make it variable...*/ * Please mail us if you got an overflow :) */
/*#define TIME_UNIT (125000/2)*/
#define DEFAULT_SCREEN_PRIORITY 128
#define DEFAULT_SCREEN_DURATION 32
#define DEFAULT_HEARTBEAT HEARTBEAT_ON
#define DEFAULT_ADDR "127.0.0.1"
#endif #endif
+49 -12
View File
@@ -39,10 +39,10 @@ char * enter_key;
char * up_key; char * up_key;
char * down_key; char * down_key;
Screen * menuscreen; Screen * menuscreen = NULL;
MenuItem * active_menuitem; MenuItem * active_menuitem = NULL;
Menu * main_menu; Menu * main_menu = NULL;
Menu * screens_menu; Menu * screens_menu = NULL;
/* Local prototypes */ /* Local prototypes */
void menuscreen_switch_item (MenuItem * new_menuitem); void menuscreen_switch_item (MenuItem * new_menuitem);
@@ -52,10 +52,8 @@ MenuEventFunc (backlight_handler);
MenuEventFunc (contrast_handler); MenuEventFunc (contrast_handler);
MenuEventFunc (brightness_handler); MenuEventFunc (brightness_handler);
int init_menu() int menuscreens_init()
{ {
active_menuitem = NULL;
debug (RPT_DEBUG, "%s()", __FUNCTION__); debug (RPT_DEBUG, "%s()", __FUNCTION__);
/* Get keys from config file */ /* Get keys from config file */
@@ -80,6 +78,39 @@ int init_menu()
} }
int menuscreens_shutdown()
{
debug (RPT_DEBUG, "%s()", __FUNCTION__ );
if (!menuscreen) {
/* Program shutdown before completed startup */
return -1;
}
/* Quit menu just to make sure */
menuscreen_switch_item (NULL);
/* Destroy the menuscreen */
screen_destroy (menuscreen);
menuscreen = NULL;
screens_menu = NULL;
/* Destroy all menus */
menuitem_destroy (main_menu);
main_menu = NULL;
/* Forget menu's key reservations */
input_release_client_keys (NULL);
free (menu_key);
free (enter_key);
free (up_key);
free (down_key);
return 0;
}
void menuscreen_inform_item_destruction (MenuItem * item) void menuscreen_inform_item_destruction (MenuItem * item)
{ {
MenuItem * i; MenuItem * i;
@@ -108,7 +139,7 @@ void menuscreen_inform_item_modified (MenuItem * item)
bool is_menu_key (char * key) bool is_menu_key (char * key)
{ {
if (strcmp (key, menu_key) == 0) if (menu_key && strcmp (key, menu_key) == 0)
return true; return true;
else else
return false; return false;
@@ -128,12 +159,13 @@ void menuscreen_switch_item (MenuItem * new_menuitem)
active_menuitem = new_menuitem; active_menuitem = new_menuitem;
/* What was the state change ? */ /* What was the state change ? */
if (old_menuitem && !new_menuitem) { if (!old_menuitem && !new_menuitem) {
/* Menu is being quit */ /* Nothing to be done */
} else if (old_menuitem && !new_menuitem) {
/* TODO: send menu to backgr */ /* TODO: send menu to backgr */
if (screenlist_remove (menuscreen) < 0) { if (screenlist_remove (menuscreen) < 0) {
report (RPT_ERR, "%s: Error unqueueing menu screen", __FUNCTION__); report (RPT_ERR, "%s: Error unqueueing menu screen", __FUNCTION__);
return;
} }
} else if (!old_menuitem && new_menuitem) { } else if (!old_menuitem && new_menuitem) {
/* Menu is becoming active */ /* Menu is becoming active */
@@ -142,9 +174,9 @@ void menuscreen_switch_item (MenuItem * new_menuitem)
if (screenlist_add (menuscreen) < 0) { if (screenlist_add (menuscreen) < 0) {
report (RPT_ERR, "%s: Error queueing menu screen", __FUNCTION__); report (RPT_ERR, "%s: Error queueing menu screen", __FUNCTION__);
return;
} }
/* TODO: raise it ! */ /* TODO: raise it ! */
return;
} else { } else {
/* We're left with the usual case: a menu level switch */ /* We're left with the usual case: a menu level switch */
if( old_menuitem->parent != new_menuitem) { if( old_menuitem->parent != new_menuitem) {
@@ -409,6 +441,11 @@ menuscreen_remove_screen (Screen * s)
debug (RPT_DEBUG, "%s( s=[%s] )", __FUNCTION__, s->id); debug (RPT_DEBUG, "%s( s=[%s] )", __FUNCTION__, s->id);
if (s == menuscreen) {
return;
/* To allow to remove the menuscreen itself */
}
m = menu_find_item (screens_menu, s->id, false); m = menu_find_item (screens_menu, s->id, false);
menu_remove_item (screens_menu, m); menu_remove_item (screens_menu, m);
menuitem_destroy (m); menuitem_destroy (m);
+3 -1
View File
@@ -21,7 +21,9 @@
extern Screen * menuscreen; extern Screen * menuscreen;
extern Menu * main_menu; extern Menu * main_menu;
int init_menu(); int menuscreens_init();
int menuscreens_shutdown();
bool is_menu_key (char * key); bool is_menu_key (char * key);
/* This function indicates to the input part whether this key was the /* This function indicates to the input part whether this key was the
+8 -6
View File
@@ -38,6 +38,8 @@
#include "widget.h" #include "widget.h"
#include "render.h" #include "render.h"
int metronome = 0; /* This counter will be increased at every rendering */
int heartbeat = HEARTBEAT_OPEN; int heartbeat = HEARTBEAT_OPEN;
int heartbeat_fallback = HEARTBEAT_ON; /* If no heartbeat setting has been set at all */ int heartbeat_fallback = HEARTBEAT_ON; /* If no heartbeat setting has been set at all */
int backlight = BACKLIGHT_OPEN; int backlight = BACKLIGHT_OPEN;
@@ -50,10 +52,10 @@ static int reset;
#define BUFSIZE 1024 #define BUFSIZE 1024
static int draw_frame (LinkedList * list, char fscroll, int left, int top, int right, int bottom, int fwid, int fhgt, int fspeed, int timer); static int render_frame (LinkedList * list, char fscroll, int left, int top, int right, int bottom, int fwid, int fhgt, int fspeed, long int timer);
int int
draw_screen (Screen * s, int timer) render_screen (Screen * s, long int timer)
{ {
static Screen * old_s = NULL; static Screen * old_s = NULL;
int tmp_state = 0; int tmp_state = 0;
@@ -115,7 +117,7 @@ draw_screen (Screen * s, int timer)
drivers_output (output_state); drivers_output (output_state);
/* Draw a frame... */ /* Draw a frame... */
draw_frame (s->widgetlist, 'v', 0, 0, display_props->width, display_props->height, s->width, s->height, (((s->duration / s->height) < 1) ? 1 : (s->duration / s->height)), timer); render_frame (s->widgetlist, 'v', 0, 0, display_props->width, display_props->height, s->width, s->height, (((s->duration / s->height) < 1) ? 1 : (s->duration / s->height)), timer);
/* Set the cursor */ /* Set the cursor */
drivers_cursor (s->cursor_x, s->cursor_y, s->cursor); drivers_cursor (s->cursor_x, s->cursor_y, s->cursor);
@@ -147,7 +149,7 @@ draw_screen (Screen * s, int timer)
/* Best thing to do is to remove support for frames... but anyway... */ /* Best thing to do is to remove support for frames... but anyway... */
/* */ /* */
static int static int
draw_frame (LinkedList * list, render_frame (LinkedList * list,
char fscroll, /* direction of scrolling */ char fscroll, /* direction of scrolling */
int left, /* left edge of frame */ int left, /* left edge of frame */
int top, /* top edge of frame */ int top, /* top edge of frame */
@@ -156,7 +158,7 @@ draw_frame (LinkedList * list,
int fwid, /* frame width? */ int fwid, /* frame width? */
int fhgt, /* frame height? */ int fhgt, /* frame height? */
int fspeed, /* speed of scrolling... */ int fspeed, /* speed of scrolling... */
int timer) /* ? */ long int timer) /* ? */
{ {
#define VerticalScrolling (fscroll == 'v') #define VerticalScrolling (fscroll == 'v')
@@ -498,7 +500,7 @@ draw_frame (LinkedList * list,
new_bottom = bottom; new_bottom = bottom;
if (new_left >= right || new_top >= bottom) { /* Do nothing if it's invisible...*/ if (new_left >= right || new_top >= bottom) { /* Do nothing if it's invisible...*/
} else { } else {
draw_frame (w->frame_screen->widgetlist, w->length, new_left, new_top, new_right, new_bottom, w->width, w->height, w->speed, timer); render_frame (w->frame_screen->widgetlist, w->length, new_left, new_top, new_right, new_bottom, w->width, w->height, w->speed, timer);
} }
} }
break; break;
+1 -5
View File
@@ -18,10 +18,6 @@
#define HEARTBEAT_ON 1 #define HEARTBEAT_ON 1
#define HEARTBEAT_OPEN 2 #define HEARTBEAT_OPEN 2
#define SERVER_SCREEN_NEVER 0
#define SERVER_SCREEN_NOSCREEN 1
#define SERVER_SCREEN_ALWAYS 2
#define BACKLIGHT_OFF 0 #define BACKLIGHT_OFF 0
#define BACKLIGHT_ON 1 #define BACKLIGHT_ON 1
#define BACKLIGHT_OPEN 2 #define BACKLIGHT_OPEN 2
@@ -39,6 +35,6 @@ extern int backlight;
extern int backlight_brightness; extern int backlight_brightness;
extern int backlight_off_brightness; extern int backlight_off_brightness;
extern int output_state; extern int output_state;
int draw_screen (Screen * s, int timer); int render_screen (Screen * s, long int timer);
#endif #endif
+89 -65
View File
@@ -19,14 +19,18 @@
#include "shared/sockets.h" #include "shared/sockets.h"
#include "shared/report.h" #include "shared/report.h"
#include "screenlist.h" #include "screenlist.h"
#include "render.h"
#include "screen.h" #include "screen.h"
#include "serverscreens.h"
#include "clients.h" #include "clients.h"
#include "main.h" /* for timer */
int screenlist_action = 0; int screenlist_action = 0;
long int current_screen_start_time;
int timer = 0; LinkedList *screenlist = NULL;
Screen * current_screen = NULL;
LinkedList *screenlist;
int screenlist_add_end (Screen * screen); int screenlist_add_end (Screen * screen);
Screen *screenlist_next_roll (); Screen *screenlist_next_roll ();
@@ -46,10 +50,7 @@ screenlist_init ()
report(RPT_ERR, "%s: error allocating list", __FUNCTION__); report(RPT_ERR, "%s: error allocating list", __FUNCTION__);
return -1; return -1;
} }
screenlist_action = 0; screenlist_action = 0;
timer = 0;
return 0; return 0;
} }
@@ -58,6 +59,10 @@ screenlist_shutdown ()
{ {
report (RPT_DEBUG, "%s()", __FUNCTION__); report (RPT_DEBUG, "%s()", __FUNCTION__);
if( !screenlist ) {
/* Program shutdown before completed startup */
return -1;
}
LL_Destroy (screenlist); LL_Destroy (screenlist);
return 0; return 0;
@@ -89,72 +94,91 @@ screenlist_remove_all (Screen * s)
return i; return i;
} }
LinkedList * void
screenlist_getlist () screenlist_update ()
/* Decide if we need to switch to an other screen.
*/
{ {
Screen * s;
report (RPT_DEBUG, "%s()", __FUNCTION__); report (RPT_DEBUG, "%s()", __FUNCTION__);
return screenlist; s = screenlist_current ();
if (!s) {
/* Try to switch to the first screen in the list */
s = LL_GetFirst(screenlist);
if (!s) {
/* There was no screen in the list */
return;
}
screenlist_switch (s);
}
if (timer - current_screen_start_time >= s->duration) {
screenlist_switch( screenlist_next ());
}
/* Check to see if the screen has a timeout value, if it does
* decrese it and then check to see if it has excpired.
* Remove if expired.
*/
if (s && s->timeout != -1) {
--(s->timeout);
report(RPT_DEBUG, "Timeout matches check, screen %s has timeout->%d", s->name, s->timeout);
if (s->timeout <= 0) {
client_remove_screen (s->client, s);
screen_destroy (s);
report(RPT_DEBUG, "Removing screen %s which has timeout->%d", s->name, s->timeout);
}
}
for (s=LL_GetFirst(screenlist); s; s=LL_GetNext(screenlist)) {
report( RPT_DEBUG, "%s: [%s] %d %d", __FUNCTION__, s->id, s->priority, s->duration );
}
}
void
screenlist_switch (Screen * s)
/* Switch to an other screen */
{
Client * c;
char str[256];
if (!s) return;
report (RPT_DEBUG, "%s( s=[%.40s] )", __FUNCTION__, s->id );
if (s == current_screen) {
/* Nothing to be done */
return;
}
if (current_screen) {
c = current_screen->client;
if (c) {
/* Tell the client we're not listening any more...*/
snprintf (str, sizeof(str), "ignore %s\n", current_screen->id);
sock_send_string (c->sock, str);
} else {
/* It's a server screen, no need to inform it. */
}
}
c = s->client;
if (c) {
/* Tell the client we're paying attention...*/
snprintf (str, sizeof(str), "listen %s\n", s->id);
sock_send_string (c->sock, str);
} else {
/* It's a server screen, no need to inform it. */
}
report (RPT_INFO, "%s: switched to screen [%.40s]", __FUNCTION__, s->id );
current_screen = s;
current_screen_start_time = timer;
} }
Screen * Screen *
screenlist_current () screenlist_current ()
{ {
char str[256]; return current_screen;
Screen * s;
static Screen * old_s = NULL;
Client * c;
debug( RPT_DEBUG, "%s()", __FUNCTION__);
/*LL_dprint(screenlist);*/
s = (Screen *) LL_GetFirst (screenlist);
/* FIXME: Make sure the screen/client exists!*/
if (s != old_s) {
/*debug (RPT_DEBUG, "screenlist_current: new screen");*/
timer = 0;
/* Tell the client we're done with the current screen*/
if (old_s) {
/*debug(RPT_DEBUG, "screenlist_current: ignoring old screen");*/
LL_Rewind (screenlist);
if (old_s != LL_Find (screenlist, compare_addresses, old_s)) {
report (RPT_WARNING, "screenlist: Didn't find screen 0x%8x! Client crashed?", (int) old_s);
} else {
/*debug(RPT_DEBUG, "screenlist_current: ... sending ignore");*/
c = old_s->client;
if (c) /* Tell the client we're not listening any more...*/
{
snprintf (str, sizeof(str), "ignore %s\n", old_s->id);
sock_send_string (c->sock, str);
} else /* The server has the display, so do nothing*/
{
;
}
/*debug(RPT_DEBUG, "screenlist_current: ... sent ignore");*/
}
}
if (s) {
/*debug(RPT_DEBUG, "screenlist_current: listening to new screen");*/
c = s->client;
if (c) /* Tell the client we're paying attention...*/
{
snprintf (str, sizeof(str), "listen %s\n", s->id);
sock_send_string (c->sock, str);
} else /* The server has the display, so do nothing*/
{
;
}
}
}
old_s = s;
/*debug(RPT_DEBUG, "screenlist_current: return %8x", s);*/
return s;
} }
int int
@@ -252,7 +276,7 @@ screenlist_next_priority ()
LL_Sort (screenlist, compare_priority); LL_Sort (screenlist, compare_priority);
return screenlist_current (); return LL_Get (screenlist);
} }
/* Simple round-robin approach to screen cycling...*/ /* Simple round-robin approach to screen cycling...*/
+2 -2
View File
@@ -22,12 +22,12 @@
#define RENDER_BACK 13 #define RENDER_BACK 13
extern int screenlist_action; extern int screenlist_action;
extern int timer;
int screenlist_init (); int screenlist_init ();
int screenlist_shutdown (); int screenlist_shutdown ();
LinkedList *screenlist_getlist (); void screenlist_update ();
void screenlist_switch (Screen * s);
Screen *screenlist_current (); Screen *screenlist_current ();
int screenlist_add (Screen * s); int screenlist_add (Screen * s);
+12 -2
View File
@@ -50,7 +50,7 @@ server_screen_init ()
} }
server_screen->name = "Server screen"; server_screen->name = "Server screen";
server_screen->duration = 8; /* 1 second, instead of 4...*/ server_screen->duration = 8; /* 1 second, instead of 4...*/
server_screen->priority = -1; /* TODO: use priorities good */ server_screen->priority = 255;
/* Create all the widgets...*/ /* Create all the widgets...*/
for (line=1; line<=4; line++) { for (line=1; line<=4; line++) {
@@ -83,7 +83,17 @@ server_screen_init ()
} }
int int
update_server_screen (int timer) server_screen_shutdown ()
{
if (!server_screen) return -1;
screenlist_remove (server_screen);
screen_destroy (server_screen);
return 0;
}
int
update_server_screen ()
{ {
Client * c; Client * c;
Widget * w; Widget * w;
+2 -1
View File
@@ -17,7 +17,8 @@
extern Screen * server_screen; extern Screen * server_screen;
int server_screen_init (); int server_screen_init ();
int update_server_screen (int timer); int server_screen_shutdown ();
int update_server_screen ();
int goodbye_screen (); int goodbye_screen ();
#endif #endif