- 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:
@@ -69,11 +69,9 @@ User=nobody
|
||||
# if any, and run as this user instead.
|
||||
|
||||
#ServerScreen=no
|
||||
# Enables the built-in server screen [Default: noscreen]
|
||||
# yes : always,
|
||||
# noscreen : when there are no other screens active,
|
||||
# no : never, the LCD display will be blank when there are
|
||||
# no screens active.
|
||||
# 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.
|
||||
|
||||
Foreground=yes
|
||||
# The server will stay in the foreground if set to true.
|
||||
|
||||
+6
-1
@@ -25,7 +25,7 @@
|
||||
#include "shared/report.h"
|
||||
#include "render.h"
|
||||
|
||||
LinkedList *clientlist;
|
||||
LinkedList *clientlist = NULL;
|
||||
|
||||
/* Initialize and kill client list...*/
|
||||
int
|
||||
@@ -49,6 +49,11 @@ clients_shutdown ()
|
||||
|
||||
debug (RPT_DEBUG, "%s()", __FUNCTION__);
|
||||
|
||||
if( !clientlist ) {
|
||||
/* Program shutdown before completed startup */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Free all client structures... */
|
||||
for (c=LL_GetFirst (clientlist); c; c=LL_GetNext (clientlist) ) {
|
||||
debug (RPT_DEBUG, "%s: ...", __FUNCTION__);
|
||||
|
||||
+1
-1
@@ -24,7 +24,7 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "screenlist.h" /* for timer */
|
||||
#include "main.h" /* for timer */
|
||||
|
||||
#include "shared/report.h"
|
||||
#include "shared/configfile.h"
|
||||
|
||||
+19
-2
@@ -35,7 +35,7 @@ void input_internal_key (char * key);
|
||||
LinkedList * keylist;
|
||||
|
||||
|
||||
int init_input()
|
||||
int input_init()
|
||||
{
|
||||
debug (RPT_DEBUG, "%s()", __FUNCTION__ );
|
||||
|
||||
@@ -44,17 +44,34 @@ int init_input()
|
||||
return 0;
|
||||
}
|
||||
|
||||
int input_shutdown()
|
||||
{
|
||||
if (!keylist) {
|
||||
/* Program shutdown before completed startup */
|
||||
return -1;
|
||||
}
|
||||
|
||||
free (keylist);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
handle_input ()
|
||||
{
|
||||
char * key;
|
||||
Screen * current_screen;
|
||||
Client * current_client;
|
||||
Client * target;
|
||||
KeyReservation * kr;
|
||||
|
||||
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 */
|
||||
while ((key = drivers_get_key ()) != NULL ) {
|
||||
|
||||
+3
-1
@@ -40,8 +40,10 @@ typedef struct KeyReservation {
|
||||
} KeyReservation;
|
||||
|
||||
|
||||
int init_input();
|
||||
int input_init();
|
||||
/* Init the input handling system */
|
||||
int input_shutdown();
|
||||
/* Shut it down */
|
||||
int input_reserve_key (char * key, bool exclusive, Client * client);
|
||||
/* Reserves a key for a client */
|
||||
/* Return -1 if reservation of key is not possible */
|
||||
|
||||
+162
-133
@@ -7,6 +7,9 @@
|
||||
*
|
||||
* Copyright (c) 1999, William Ferrell, Scott Scriven
|
||||
* 2001, Joris Robijn
|
||||
* 2001, Rene Wagner
|
||||
* 2002, Mike Patnode
|
||||
* 2002, Guillaume Filion
|
||||
*
|
||||
*
|
||||
* Contains main(), plus signal callback functions and a help screen.
|
||||
@@ -21,6 +24,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
@@ -33,6 +38,11 @@
|
||||
#include <sys/types.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 int optind, optopt, opterr;
|
||||
|
||||
@@ -52,28 +62,22 @@ extern int optind, optopt, opterr;
|
||||
#include "drivers.h"
|
||||
#include "main.h"
|
||||
|
||||
#define MAX_TIMER 0x10000
|
||||
|
||||
#define DEFAULT_LCD_PORT LCDPORT
|
||||
#define DEFAULT_BIND_ADDR "127.0.0.1"
|
||||
#define DEFAULT_CONFIGFILE "/etc/LCDd.conf"
|
||||
#define DEFAULT_USER "nobody"
|
||||
#define DEFAULT_DRIVER "curses"
|
||||
#define DEFAULT_DRIVER_PATH
|
||||
#define DEFAULT_WAITTIME 8
|
||||
#define MAX_DRIVERS 8
|
||||
#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_REPORTLEVEL RPT_WARNING
|
||||
#define DEFAULT_ADDR "127.0.0.1"
|
||||
|
||||
|
||||
/* Store some standard defines into vars... */
|
||||
char *version = VERSION;
|
||||
char *protocol_version = PROTOCOL_VERSION;
|
||||
char *api_version = API_VERSION;
|
||||
char *build_date = __DATE__;
|
||||
|
||||
//#define DEFAULT_WAITTIME 8
|
||||
#define DEFAULT_SCREEN_DURATION 32
|
||||
#define DEFAULT_HEARTBEAT HEARTBEAT_ON
|
||||
|
||||
/* Socket to bind to...
|
||||
|
||||
@@ -84,7 +88,21 @@ char *build_date = __DATE__;
|
||||
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 ****/
|
||||
/* 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*/
|
||||
#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... */
|
||||
|
||||
int daemon_mode = UNSET_INT;
|
||||
int enable_server_screen = UNSET_INT;
|
||||
int rotate_server_screen = UNSET_INT;
|
||||
|
||||
static int reportLevel = 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];
|
||||
int num_drivers = 0;
|
||||
int stored_argc;
|
||||
char **stored_argv;
|
||||
short got_reload_signal = 0;
|
||||
|
||||
long int timer = 0;
|
||||
|
||||
/**** Local functions ****/
|
||||
void exit_program (int val);
|
||||
void catch_reload_signal (int val);
|
||||
void HelpScreen ();
|
||||
|
||||
void clear_settings();
|
||||
@@ -123,21 +145,22 @@ int init_drivers();
|
||||
int init_screens();
|
||||
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
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
/* FIXME: s is getting clobbered - in MANY places!!!
|
||||
*screen *s = NULL;
|
||||
*char buf[64];
|
||||
*/
|
||||
|
||||
stored_argc = argc;
|
||||
stored_argv = argv;
|
||||
|
||||
signal (SIGINT, exit_program); /* Ctrl-C will cause a clean exit...*/
|
||||
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 (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 (argc == 1)
|
||||
* 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") );
|
||||
|
||||
/* Startup the server*/
|
||||
ESSENTIAL( screenlist_init() );
|
||||
ESSENTIAL( init_drivers() );
|
||||
ESSENTIAL( init_sockets() );
|
||||
ESSENTIAL( init_input() );
|
||||
ESSENTIAL( init_menu() );
|
||||
ESSENTIAL( init_screens() );
|
||||
ESSENTIAL( input_init() );
|
||||
ESSENTIAL( menuscreens_init() );
|
||||
ESSENTIAL( server_screen_init() );
|
||||
ESSENTIAL( drop_privs(user) );
|
||||
|
||||
/* Store it for exit_program()*/
|
||||
serverStarted = 1;
|
||||
|
||||
#ifndef DEBUG
|
||||
/* Now, go into daemon mode...*/
|
||||
if (daemon_mode) {
|
||||
report(RPT_INFO, "Server forking to background");
|
||||
@@ -207,13 +227,13 @@ main (int argc, char **argv)
|
||||
output_GPL_notice();
|
||||
report(RPT_INFO, "Server running in foreground");
|
||||
}
|
||||
#endif
|
||||
|
||||
do_mainloop();
|
||||
/* This loop never stops; we'll get out only with a signal...*/
|
||||
|
||||
return 0;
|
||||
}
|
||||
#undef ESSENTIAL
|
||||
|
||||
|
||||
void
|
||||
@@ -228,7 +248,7 @@ clear_settings ()
|
||||
strncpy( configfile, UNSET_STR, sizeof(configfile) );
|
||||
strncpy( user, UNSET_STR, sizeof(user) );
|
||||
daemon_mode = UNSET_INT;
|
||||
enable_server_screen = UNSET_INT;
|
||||
rotate_server_screen = UNSET_INT;
|
||||
backlight = 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 );
|
||||
|
||||
/* Reset getopt */
|
||||
optind = 0;
|
||||
|
||||
/* analyze options here..*/
|
||||
while ((c = getopt(argc, argv, "a:p:d:hfib:w:c:u:sr:")) > 0) {
|
||||
/* FIXME: Setting of c in this loop clobbers s!
|
||||
* s is set equivalent to c.
|
||||
*/
|
||||
report( RPT_INFO, ">>>> %i", (int) c );
|
||||
switch(c) {
|
||||
case 'd':
|
||||
/* 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));
|
||||
break;
|
||||
case 'i':
|
||||
enable_server_screen = 0;
|
||||
rotate_server_screen = 0;
|
||||
break;
|
||||
case 'b':
|
||||
if( strcmp( optarg, "on" ) == 0 ) {
|
||||
@@ -374,20 +398,8 @@ process_configfile ( char *configfile )
|
||||
daemon_mode = !fg;
|
||||
}
|
||||
|
||||
if( enable_server_screen == UNSET_INT ) {
|
||||
s = config_get_string( "server", "serverscreen", 0, UNSET_STR );
|
||||
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( rotate_server_screen == UNSET_INT ) {
|
||||
rotate_server_screen = config_get_bool( "server", "serverscreen", 0, UNSET_INT );
|
||||
}
|
||||
|
||||
if( backlight == UNSET_INT ) {
|
||||
@@ -407,10 +419,7 @@ process_configfile ( char *configfile )
|
||||
}
|
||||
|
||||
if( reportToSyslog == UNSET_INT ) {
|
||||
/* Is the value set in the config file anyway ?*/
|
||||
if( strcmp( config_get_string( "server", "reportToSyslog", 0, "" ), "" ) != 0 ) {
|
||||
reportToSyslog = config_get_bool( "server", "reportToSyslog", 0, 0 );
|
||||
}
|
||||
reportToSyslog = config_get_bool( "server", "reportToSyslog", 0, UNSET_INT );
|
||||
}
|
||||
if( reportLevel == UNSET_INT ) {
|
||||
reportLevel = config_get_int( "server", "reportLevel", 0, UNSET_INT );
|
||||
@@ -457,8 +466,8 @@ set_default_settings()
|
||||
|
||||
if (daemon_mode == UNSET_INT)
|
||||
daemon_mode = DEFAULT_DAEMON_MODE;
|
||||
if (enable_server_screen == UNSET_INT)
|
||||
enable_server_screen = DEFAULT_ENABLE_SERVER_SCREEN;
|
||||
if (rotate_server_screen == UNSET_INT)
|
||||
rotate_server_screen = DEFAULT_ROTATE_SERVER_SCREEN;
|
||||
|
||||
if (default_duration == UNSET_INT)
|
||||
default_duration = DEFAULT_SCREEN_DURATION;
|
||||
@@ -631,101 +640,115 @@ init_screens ()
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (enable_server_screen > SERVER_SCREEN_NEVER) {
|
||||
/* Add the server screen */
|
||||
if (server_screen_init () < 0) {
|
||||
report(RPT_ERR, "Error initializing server screens");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (enable_server_screen == SERVER_SCREEN_NOSCREEN) {
|
||||
/* Display the server screen only when there are no other screens */
|
||||
server_screen->priority = 256;
|
||||
}
|
||||
/* Add the server screen */
|
||||
if (server_screen_init () < 0) {
|
||||
report(RPT_ERR, "Error initializing server screens");
|
||||
return -1;
|
||||
}
|
||||
if (!rotate_server_screen) {
|
||||
/* Display the server screen only when there are no other screens */
|
||||
server_screen->priority = 256;
|
||||
}
|
||||
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
|
||||
do_mainloop ()
|
||||
{
|
||||
Screen *s = NULL;
|
||||
char *message=NULL;
|
||||
Screen * s;
|
||||
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__ );
|
||||
|
||||
/*char buf[64];*/
|
||||
gettimeofday (&t, NULL); /* Get initial time */
|
||||
|
||||
/* FIXME: s should still be null from initialization.... what's happening here?!*/
|
||||
while (1) {
|
||||
sock_poll_clients (); /* poll clients for input*/
|
||||
parse_all_client_messages (); /* analyze input from network clients*/
|
||||
handle_input (); /* handle key input from devices*/
|
||||
/* Get current time */
|
||||
last_t = t;
|
||||
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...
|
||||
* ... it should just say "handle_screens();"
|
||||
* Timer gets reset by screenlist_next()
|
||||
*/
|
||||
process_lag += t_diff;
|
||||
if (process_lag > 0) {
|
||||
/* 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++;
|
||||
|
||||
if (s && (timer >= s->duration))
|
||||
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);
|
||||
/* We've done the job... */
|
||||
process_lag = 0 - (1e6/PROCESS_FREQ);
|
||||
/* Note : this does not make a fixed frequency */
|
||||
}
|
||||
if (s && s->timeout != -1) {
|
||||
|
||||
--(s->timeout);
|
||||
if((message = malloc(256)) == NULL)
|
||||
report(RPT_ERR, "Error allocating message string");
|
||||
else {
|
||||
snprintf(message, 256, "Timeout matches check, screen %s has timeout->%d", s->name, s->timeout);
|
||||
report(RPT_DEBUG, message);
|
||||
free(message);
|
||||
render_lag += t_diff;
|
||||
if (render_lag > 0) {
|
||||
/* Time for a rendering stroke */
|
||||
timer ++;
|
||||
screenlist_update ();
|
||||
s = screenlist_current ();
|
||||
|
||||
/* TODO: Move this call to every client connection
|
||||
* and every screen add...
|
||||
*/
|
||||
if( s == server_screen ) {
|
||||
update_server_screen (timer);
|
||||
}
|
||||
if (s->timeout <= 0) {
|
||||
client_remove_screen (s->client, s);
|
||||
screen_destroy (s);
|
||||
if((message = malloc(256)) == NULL)
|
||||
report(RPT_ERR, "Error allocating message string");
|
||||
else {
|
||||
snprintf(message, 256, "Removing screen %s which has timeout->%d", s->name, s->timeout);
|
||||
report(RPT_DEBUG, message);
|
||||
free(message);
|
||||
}
|
||||
render_screen (s, timer);
|
||||
|
||||
/* We've done the job... */
|
||||
if( render_lag > (1e6/RENDER_FREQ) * MAX_RENDER_LAG_FRAMES ) {
|
||||
/* Cause rendering slowdown because too much lag */
|
||||
render_lag = (1e6/RENDER_FREQ) * MAX_RENDER_LAG_FRAMES;
|
||||
}
|
||||
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;
|
||||
/* 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. */
|
||||
if( reportLevel == UNSET_INT )
|
||||
reportLevel = DEFAULT_REPORTLEVEL;
|
||||
@@ -768,14 +790,21 @@ exit_program (int val)
|
||||
drivers_unload_all (); /* release driver memory and file descriptors */
|
||||
|
||||
/* Shutdown things if server start was complete */
|
||||
if( serverStarted ) {
|
||||
clients_shutdown (); /* shutdown clients (must come first) */
|
||||
screenlist_shutdown (); /* shutdown screens (must come after client_shutdown) */
|
||||
}
|
||||
clients_shutdown (); /* shutdown clients (must come first) */
|
||||
menuscreens_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
|
||||
HelpScreen ()
|
||||
|
||||
+14
-10
@@ -21,21 +21,25 @@
|
||||
contains a few things that other parts of the program might want
|
||||
to know about...
|
||||
*/
|
||||
#define DEFAULT_SCREEN_PRIORITY 128
|
||||
|
||||
extern char *version;
|
||||
extern char *protocol_version;
|
||||
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...*/
|
||||
#define TIME_UNIT 125000
|
||||
/* But I plan to double the framerate soon, or make it variable...*/
|
||||
/*#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"
|
||||
extern long int timer;
|
||||
/* 32 bits at 8Hz will overflow in 2 ^ 29 = 5e8 seconds = 17 years.
|
||||
* Please mail us if you got an overflow :) */
|
||||
|
||||
#endif
|
||||
|
||||
+49
-12
@@ -39,10 +39,10 @@ char * enter_key;
|
||||
char * up_key;
|
||||
char * down_key;
|
||||
|
||||
Screen * menuscreen;
|
||||
MenuItem * active_menuitem;
|
||||
Menu * main_menu;
|
||||
Menu * screens_menu;
|
||||
Screen * menuscreen = NULL;
|
||||
MenuItem * active_menuitem = NULL;
|
||||
Menu * main_menu = NULL;
|
||||
Menu * screens_menu = NULL;
|
||||
|
||||
/* Local prototypes */
|
||||
void menuscreen_switch_item (MenuItem * new_menuitem);
|
||||
@@ -52,10 +52,8 @@ MenuEventFunc (backlight_handler);
|
||||
MenuEventFunc (contrast_handler);
|
||||
MenuEventFunc (brightness_handler);
|
||||
|
||||
int init_menu()
|
||||
int menuscreens_init()
|
||||
{
|
||||
active_menuitem = NULL;
|
||||
|
||||
debug (RPT_DEBUG, "%s()", __FUNCTION__);
|
||||
|
||||
/* 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)
|
||||
{
|
||||
MenuItem * i;
|
||||
@@ -108,7 +139,7 @@ void menuscreen_inform_item_modified (MenuItem * item)
|
||||
|
||||
bool is_menu_key (char * key)
|
||||
{
|
||||
if (strcmp (key, menu_key) == 0)
|
||||
if (menu_key && strcmp (key, menu_key) == 0)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
@@ -128,12 +159,13 @@ void menuscreen_switch_item (MenuItem * new_menuitem)
|
||||
active_menuitem = new_menuitem;
|
||||
|
||||
/* What was the state change ? */
|
||||
if (old_menuitem && !new_menuitem) {
|
||||
/* Menu is being quit */
|
||||
|
||||
if (!old_menuitem && !new_menuitem) {
|
||||
/* Nothing to be done */
|
||||
} else if (old_menuitem && !new_menuitem) {
|
||||
/* TODO: send menu to backgr */
|
||||
if (screenlist_remove (menuscreen) < 0) {
|
||||
report (RPT_ERR, "%s: Error unqueueing menu screen", __FUNCTION__);
|
||||
return;
|
||||
}
|
||||
} else if (!old_menuitem && new_menuitem) {
|
||||
/* Menu is becoming active */
|
||||
@@ -142,9 +174,9 @@ void menuscreen_switch_item (MenuItem * new_menuitem)
|
||||
|
||||
if (screenlist_add (menuscreen) < 0) {
|
||||
report (RPT_ERR, "%s: Error queueing menu screen", __FUNCTION__);
|
||||
return;
|
||||
}
|
||||
/* TODO: raise it ! */
|
||||
return;
|
||||
} else {
|
||||
/* We're left with the usual case: a menu level switch */
|
||||
if( old_menuitem->parent != new_menuitem) {
|
||||
@@ -409,6 +441,11 @@ menuscreen_remove_screen (Screen * s)
|
||||
|
||||
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);
|
||||
menu_remove_item (screens_menu, m);
|
||||
menuitem_destroy (m);
|
||||
|
||||
@@ -21,7 +21,9 @@
|
||||
extern Screen * menuscreen;
|
||||
extern Menu * main_menu;
|
||||
|
||||
int init_menu();
|
||||
int menuscreens_init();
|
||||
|
||||
int menuscreens_shutdown();
|
||||
|
||||
bool is_menu_key (char * key);
|
||||
/* This function indicates to the input part whether this key was the
|
||||
|
||||
+8
-6
@@ -38,6 +38,8 @@
|
||||
#include "widget.h"
|
||||
#include "render.h"
|
||||
|
||||
int metronome = 0; /* This counter will be increased at every rendering */
|
||||
|
||||
int heartbeat = HEARTBEAT_OPEN;
|
||||
int heartbeat_fallback = HEARTBEAT_ON; /* If no heartbeat setting has been set at all */
|
||||
int backlight = BACKLIGHT_OPEN;
|
||||
@@ -50,10 +52,10 @@ static int reset;
|
||||
|
||||
#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
|
||||
draw_screen (Screen * s, int timer)
|
||||
render_screen (Screen * s, long int timer)
|
||||
{
|
||||
static Screen * old_s = NULL;
|
||||
int tmp_state = 0;
|
||||
@@ -115,7 +117,7 @@ draw_screen (Screen * s, int timer)
|
||||
drivers_output (output_state);
|
||||
|
||||
/* 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 */
|
||||
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... */
|
||||
/* */
|
||||
static int
|
||||
draw_frame (LinkedList * list,
|
||||
render_frame (LinkedList * list,
|
||||
char fscroll, /* direction of scrolling */
|
||||
int left, /* left edge of frame */
|
||||
int top, /* top edge of frame */
|
||||
@@ -156,7 +158,7 @@ draw_frame (LinkedList * list,
|
||||
int fwid, /* frame width? */
|
||||
int fhgt, /* frame height? */
|
||||
int fspeed, /* speed of scrolling... */
|
||||
int timer) /* ? */
|
||||
long int timer) /* ? */
|
||||
{
|
||||
|
||||
#define VerticalScrolling (fscroll == 'v')
|
||||
@@ -498,7 +500,7 @@ draw_frame (LinkedList * list,
|
||||
new_bottom = bottom;
|
||||
if (new_left >= right || new_top >= bottom) { /* Do nothing if it's invisible...*/
|
||||
} 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;
|
||||
|
||||
+1
-5
@@ -18,10 +18,6 @@
|
||||
#define HEARTBEAT_ON 1
|
||||
#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_ON 1
|
||||
#define BACKLIGHT_OPEN 2
|
||||
@@ -39,6 +35,6 @@ extern int backlight;
|
||||
extern int backlight_brightness;
|
||||
extern int backlight_off_brightness;
|
||||
extern int output_state;
|
||||
int draw_screen (Screen * s, int timer);
|
||||
int render_screen (Screen * s, long int timer);
|
||||
|
||||
#endif
|
||||
|
||||
+89
-65
@@ -19,14 +19,18 @@
|
||||
#include "shared/sockets.h"
|
||||
#include "shared/report.h"
|
||||
#include "screenlist.h"
|
||||
#include "render.h"
|
||||
#include "screen.h"
|
||||
#include "serverscreens.h"
|
||||
#include "clients.h"
|
||||
|
||||
#include "main.h" /* for timer */
|
||||
|
||||
int screenlist_action = 0;
|
||||
long int current_screen_start_time;
|
||||
|
||||
int timer = 0;
|
||||
|
||||
LinkedList *screenlist;
|
||||
LinkedList *screenlist = NULL;
|
||||
Screen * current_screen = NULL;
|
||||
|
||||
int screenlist_add_end (Screen * screen);
|
||||
Screen *screenlist_next_roll ();
|
||||
@@ -46,10 +50,7 @@ screenlist_init ()
|
||||
report(RPT_ERR, "%s: error allocating list", __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
screenlist_action = 0;
|
||||
timer = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -58,6 +59,10 @@ screenlist_shutdown ()
|
||||
{
|
||||
report (RPT_DEBUG, "%s()", __FUNCTION__);
|
||||
|
||||
if( !screenlist ) {
|
||||
/* Program shutdown before completed startup */
|
||||
return -1;
|
||||
}
|
||||
LL_Destroy (screenlist);
|
||||
|
||||
return 0;
|
||||
@@ -89,72 +94,91 @@ screenlist_remove_all (Screen * s)
|
||||
return i;
|
||||
}
|
||||
|
||||
LinkedList *
|
||||
screenlist_getlist ()
|
||||
void
|
||||
screenlist_update ()
|
||||
/* Decide if we need to switch to an other screen.
|
||||
*/
|
||||
{
|
||||
Screen * s;
|
||||
|
||||
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 *
|
||||
screenlist_current ()
|
||||
{
|
||||
char str[256];
|
||||
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;
|
||||
return current_screen;
|
||||
}
|
||||
|
||||
int
|
||||
@@ -252,7 +276,7 @@ screenlist_next_priority ()
|
||||
|
||||
LL_Sort (screenlist, compare_priority);
|
||||
|
||||
return screenlist_current ();
|
||||
return LL_Get (screenlist);
|
||||
}
|
||||
|
||||
/* Simple round-robin approach to screen cycling...*/
|
||||
|
||||
+2
-2
@@ -22,12 +22,12 @@
|
||||
#define RENDER_BACK 13
|
||||
|
||||
extern int screenlist_action;
|
||||
extern int timer;
|
||||
|
||||
int screenlist_init ();
|
||||
int screenlist_shutdown ();
|
||||
|
||||
LinkedList *screenlist_getlist ();
|
||||
void screenlist_update ();
|
||||
void screenlist_switch (Screen * s);
|
||||
Screen *screenlist_current ();
|
||||
|
||||
int screenlist_add (Screen * s);
|
||||
|
||||
+12
-2
@@ -50,7 +50,7 @@ server_screen_init ()
|
||||
}
|
||||
server_screen->name = "Server screen";
|
||||
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...*/
|
||||
for (line=1; line<=4; line++) {
|
||||
@@ -83,7 +83,17 @@ server_screen_init ()
|
||||
}
|
||||
|
||||
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;
|
||||
Widget * w;
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
extern Screen * server_screen;
|
||||
|
||||
int server_screen_init ();
|
||||
int update_server_screen (int timer);
|
||||
int server_screen_shutdown ();
|
||||
int update_server_screen ();
|
||||
int goodbye_screen ();
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user