Massive changes (first commit), including but not limited to:

* Ability to specify port and address to bind to
* By default, binds only to 127.0.0.1 port 13666
* Client commands now return usage when no options given
* New driver command: getinfo
* Added comments all over the place
* Used #defines to further document code
* Used #defines to set up compile-time defaults, etc.
* Cleaned up client command argument analysis in client_functions.c
* Beginning support of syslog
* Some bug fixes
This commit is contained in:
ddouthitt
2001-09-21 21:08:10 +00:00
parent 909f9791cf
commit 6a0e23dc3e
22 changed files with 1767 additions and 785 deletions
+1 -1
View File
@@ -153,7 +153,7 @@ main (int argc, char **argv)
usleep (500000); // wait for the server to start up usleep (500000); // wait for the server to start up
sock = sock_connect (server, port); sock = sock_connect (server, port);
if (sock <= 0) { if (sock <= 0) {
printf ("Error connecting to server %s on port %i.\n", server, port); printf ("Error connecting to LCD server %s on port %i.\nCheck to see that the server is running and operating normally.\n", server, port);
return 0; return 0;
} }
sock_send_string (sock, "hello\n"); sock_send_string (sock, "hello\n");
+11 -5
View File
@@ -16,6 +16,12 @@
#include "screen.h" #include "screen.h"
#include "screenlist.h" #include "screenlist.h"
#define ResetScreenList(a) LL_Rewind(a)
#define NewScreen LL_new
#define NextScreen(a) (screen *)LL_Get(a)
#define MoreScreens(a) (LL_Next(a) == 0)
#define DestroyScreenList(a) LL_Destroy(a)
int int
client_data_init (client_data * d) client_data_init (client_data * d)
{ {
@@ -26,7 +32,7 @@ client_data_init (client_data * d)
d->name = NULL; d->name = NULL;
d->client_keys = NULL; d->client_keys = NULL;
d->screenlist = LL_new (); d->screenlist = NewScreen();
if (!d->screenlist) { if (!d->screenlist) {
fprintf (stderr, "client_data_init: Error allocating screenlist\n"); fprintf (stderr, "client_data_init: Error allocating screenlist\n");
return -1; return -1;
@@ -64,9 +70,9 @@ client_data_destroy (client_data * d)
// Clean up the screenlist... // Clean up the screenlist...
debug ("client_data_destroy: Cleaning screenlist\n"); debug ("client_data_destroy: Cleaning screenlist\n");
LL_Rewind (d->screenlist); ResetScreenList (d->screenlist);
do { do {
s = (screen *) LL_Get (d->screenlist); s = NextScreen(d->screenlist);
if (s) { if (s) {
debug ("client_data_destroy: removing screen %s\n", s->id); debug ("client_data_destroy: removing screen %s\n", s->id);
@@ -80,8 +86,8 @@ client_data_destroy (client_data * d)
// Free its memory... // Free its memory...
screen_destroy (s); screen_destroy (s);
} }
} while (LL_Next (d->screenlist) == 0); } while (MoreScreens(d->screenlist));
LL_Destroy (d->screenlist); DestroyScreenList(d->screenlist);
// TODO: clean up the rest of the data... // TODO: clean up the rest of the data...
+474 -175
View File
File diff suppressed because it is too large Load Diff
+13 -9
View File
@@ -15,7 +15,9 @@
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h> #include <unistd.h>
#include <string.h> #include <string.h>
#include <syslog.h>
#include "sock.h"
#include "clients.h" #include "clients.h"
#include "client_data.h" #include "client_data.h"
#include "shared/debug.h" #include "shared/debug.h"
@@ -40,7 +42,6 @@ client_init ()
int int
client_shutdown () client_shutdown ()
{ {
// TODO: Close all connections first...
client *c; client *c;
debug ("client_shutdown()\n"); debug ("client_shutdown()\n");
@@ -52,7 +53,7 @@ client_shutdown ()
debug ("client_shutdown: ...\n"); debug ("client_shutdown: ...\n");
if (c) { if (c) {
debug ("client_shutdown: ... %i ...\n", c->sock); debug ("client_shutdown: ... %i ...\n", c->sock);
if (0 != client_destroy (c)) { if (client_destroy (c) != 0) {
fprintf (stderr, "client_shutdown: Error freeing client\n"); fprintf (stderr, "client_shutdown: Error freeing client\n");
} else { } else {
debug ("client_shutdown: Freed client...\n"); debug ("client_shutdown: Freed client...\n");
@@ -70,6 +71,9 @@ client_shutdown ()
return 0; return 0;
} }
// A client is identified by the file descriptor
// associated with it.
//
// Create and destroy clients.... // Create and destroy clients....
client * client *
client_create (int sock) client_create (int sock)
@@ -117,7 +121,6 @@ client_create (int sock)
int int
client_destroy (client * c) client_destroy (client * c)
{ {
// TODO: Close the socket connection here?
int err; int err;
char *str; char *str;
@@ -136,17 +139,18 @@ client_destroy (client * c)
} }
} }
// close socket...
if (c->sock) {
// sock_send_string (c->sock, "bye\n");
close(c->sock);
syslog(LOG_NOTICE, "closed socket for #%d\n", c->sock);
}
err = LL_Destroy (c->messages); err = LL_Destroy (c->messages);
// Free client's other data // Free client's other data
client_data_destroy (c->data); client_data_destroy (c->data);
/*
// FIXME? Should the connection get closed here or elsewhere?
if(c->sock) close(c->sock);
c->sock = 0;
*/
// Remove the client from the clients list... // Remove the client from the clients list...
LL_Remove (clients, c); LL_Remove (clients, c);
+1
View File
@@ -6,6 +6,7 @@
typedef struct client { typedef struct client {
int sock; int sock;
char addr[64];
LL *messages; LL *messages;
client_data *data; client_data *data;
+364 -84
View File
@@ -1,10 +1,24 @@
/*
* Matrix Orbital driver
*
* For the Matrix Orbital LCD* LKD* VFD* and VKD* displays
*
* September 16, 2001
*
* NOTE: GLK displays have a different driver.
*
*/
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <unistd.h> #include <unistd.h>
#include <sys/types.h>
#include <sys/time.h>
#include <termios.h> #include <termios.h>
#include <fcntl.h> #include <fcntl.h>
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include <syslog.h>
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
# include "config.h" # include "config.h"
@@ -16,6 +30,26 @@
#include "shared/debug.h" #include "shared/debug.h"
#include "shared/str.h" #include "shared/str.h"
#define DEFAULT_CONTRAST 140
#define DEFAULT_DEVICE "/dev/lcd"
#define DEFAULT_SPEED B19200
#define DEFAULT_LINEWRAP 1
#define DEFAULT_AUTOSCROLL 1
#define DEFAULT_CURSORBLINK 0
#define GENERIC (void *) -1
#define IS_LCD_DISPLAY (MtxOrb_type == MTXORB_LCD)
#define IS_LKD_DISPLAY (MtxOrb_type == MTXORB_LKD)
#define IS_VFD_DISPLAY (MtxOrb_type == MTXORB_VFD)
#define IS_VKD_DISPLAY (MtxOrb_type == MTXORB_VKD)
#define NotEnoughArgs (i + 1 > argc)
// NOTE: This does not appear to make use of the
// hbar and vbar functions present in the LKD202-25.
// Why I do not know.
static int custom = 0; static int custom = 0;
static enum {MTXORB_LCD, MTXORB_LKD, MTXORB_VFD, MTXORB_VKD} MtxOrb_type; static enum {MTXORB_LCD, MTXORB_LKD, MTXORB_VFD, MTXORB_VKD} MtxOrb_type;
@@ -65,25 +99,102 @@ static void MtxOrb_linewrap (int on);
static void MtxOrb_autoscroll (int on); static void MtxOrb_autoscroll (int on);
static void MtxOrb_cursorblink (int on); static void MtxOrb_cursorblink (int on);
int
MtxOrb_set_type (char * str) {
char c;
c = str[0];
if (c == 'l') {
if (strcmp(str, "lcd") == 0) {
return MTXORB_LCD;
} else if (strcmp(str, "lkd") == 0) {
return MTXORB_LKD;
} else {
fprintf (stderr, "MtxOrb_init: unknwon display type %s; must be one of lcd, lkd, vfd, or vkd\n", str);
}
} else if (c == 'v') {
if (strcmp (str, "vfd") == 0) {
return MTXORB_VFD;
} else if (strcmp (str, "vkd") == 0) {
return MTXORB_VKD;
} else {
fprintf (stderr, "MtxOrb_init: unknwon display type %s; must be one of lcd, lkd, vfd, or vkd\n", str);
}
} else {
fprintf (stderr, "MtxOrb_init: unknwon display type %s; must be one of lcd, lkd, vfd, or vkd\n", str);
}
return (-1);
}
int
MtxOrb_get_speed (char *arg) {
int speed;
switch (atoi(arg)) {
case 1200: speed = B1200; break;
case 2400: speed = B2400; break;
case 9600: speed = B9600; break;
case 19200: speed = B19200; break;
default:
speed = DEFAULT_SPEED;
fprintf (stderr, "MtxOrb_init: argument must be 1200, 2400, 9600 or 19200. Using default value");
switch (speed) {
case B1200: fprintf(stderr, " of 1200 baud.\n"); break;
case B2400: fprintf(stderr, " of 2400 baud.\n"); break;
case B9600: fprintf(stderr, " of 9600 baud.\n"); break;
case B19200: fprintf(stderr, " of 19200 baud.\n"); break;
default: fprintf(stderr, ".\n"); break;
}
}
return speed;
}
void
MtxOrb_usage (void) {
printf ("LCDproc Matrix-Orbital LCD driver\n"
"\t-d\t--device\tSelect the output device to use [/dev/lcd]\n"
// "\t-t\t--type\t\tSelect the LCD type (size) [20x4]\n"
// "\t-b\t--backlight\tSelect the backlight state [on]\n"
"\t-c\t--contrast\tSet the initial contrast [140]\n"
"\t-s\t--speed\t\tSet the communication speed [19200]\n"
"\t-h\t--help\t\tShow this help information\n"
"\t-t\t--type\t\tdisplay type: lcd, lkd, vfd, vkd\n");
}
int
MtxOrb_set_contrast (char * str) {
int contrast;
contrast = atoi (str);
if ((contrast < 0) || (contrast > 255)) {
fprintf(stderr, "MtxOrb_init: argument must between 0 and 255 (found %s). Using default contrast value of %d.\n", str, DEFAULT_CONTRAST);
contrast = DEFAULT_CONTRAST;
}
return contrast;
}
// TODO: Get rid of this variable? // TODO: Get rid of this variable?
lcd_logical_driver *MtxOrb; lcd_logical_driver *MtxOrb; // set by MtxOrb_init(); doesn't seem to be used anywhere
// TODO: Get the frame buffers working right // TODO: Get the frame buffers working right
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
// Opens com port and sets baud correctly... // Opens com port and sets baud correctly...
// //
// Called to initialize driver settings
//
int int
MtxOrb_init (lcd_logical_driver * driver, char *args) MtxOrb_init (lcd_logical_driver * driver, char *args)
{ {
char *argv[64]; char *argv[64]; // Notice: 64 arguments - overflows?
int argc; int argc;
struct termios portset; struct termios portset;
int i; int i;
int tmp; int tmp;
int contrast = 140; int contrast = DEFAULT_CONTRAST;
char device[256] = "/dev/lcd"; char device[256] = DEFAULT_DEVICE;
int speed = B19200; int speed = DEFAULT_SPEED;
MtxOrb_type = MTXORB_LKD ; // Assume it's an LCD w/keypad MtxOrb_type = MTXORB_LKD ; // Assume it's an LCD w/keypad
MtxOrb = driver; MtxOrb = driver;
@@ -166,10 +277,19 @@ MtxOrb_init (lcd_logical_driver * driver, char *args)
// Set up io port correctly, and open it... // Set up io port correctly, and open it...
fd = open (device, O_RDWR | O_NOCTTY | O_NDELAY); fd = open (device, O_RDWR | O_NOCTTY | O_NDELAY);
if (fd == -1) { if (fd == -1) {
fprintf (stderr, "MtxOrb_init: failed (%s)\n", strerror (errno)); switch (errno) {
return -1; case ENOENT: fprintf(stderr, "MtxOrb_init: %s device file missing!\n", device);
break;
case EACCES: fprintf(stderr, "MtxOrb_init: %s device could not be opened...\n", device);
fprintf(stderr, "MtxOrb_init: perhaps you should run LCDd as root?\n");
break;
default: fprintf (stderr, "MtxOrb_init: failed (%s)\n", strerror (errno));
break;
} }
//else fprintf(stderr, "MtxOrb_init: opened device %s\n", device); return -1;
} else
syslog(LOG_INFO, "opened Matrix Orbital display on %s\n", device);
tcgetattr (fd, &portset); tcgetattr (fd, &portset);
// We use RAW mode // We use RAW mode
@@ -193,29 +313,32 @@ MtxOrb_init (lcd_logical_driver * driver, char *args)
// Do it... // Do it...
tcsetattr (fd, TCSANOW, &portset); tcsetattr (fd, TCSANOW, &portset);
// Set display-specific stuff.. /*
MtxOrb_linewrap (1); * Configure display
MtxOrb_autoscroll (1); */
MtxOrb_cursorblink (0);
MtxOrb_linewrap (DEFAULT_LINEWRAP);
MtxOrb_autoscroll (DEFAULT_AUTOSCROLL);
MtxOrb_cursorblink (DEFAULT_CURSORBLINK);
MtxOrb_contrast (contrast);
if (!driver->framebuf) { if (!driver->framebuf) {
fprintf (stderr, "MtxOrb_init: No frame buffer.\n"); fprintf (stderr, "MtxOrb_init: No frame buffer.\n");
driver->close (); driver->close ();
return -1; return -1;
} }
// Set the functions the driver supports...
// driver->clear = (void *)-1; /*
driver->clear = MtxOrb_clear; * Configure the display functions
driver->string = (void *) -1; */
// driver->chr = MtxOrb_chr;
driver->chr = (void *) -1; driver->clear = MtxOrb_clear; // was GENERIC
driver->string = GENERIC;
driver->chr = MtxOrb_chr; // was GENERIC
driver->vbar = MtxOrb_vbar; driver->vbar = MtxOrb_vbar;
driver->init_vbar = MtxOrb_init_vbar; driver->init_vbar = MtxOrb_init_vbar; // was GENERIC
// driver->init_vbar = (void *)-1;
driver->hbar = MtxOrb_hbar; driver->hbar = MtxOrb_hbar;
driver->init_hbar = MtxOrb_init_hbar; driver->init_hbar = MtxOrb_init_hbar; // was GENERIC
// driver->init_hbar = (void *)-1;
driver->num = MtxOrb_num; driver->num = MtxOrb_num;
driver->init_num = MtxOrb_init_num; driver->init_num = MtxOrb_init_num;
@@ -231,8 +354,7 @@ MtxOrb_init (lcd_logical_driver * driver, char *args)
driver->draw_frame = MtxOrb_draw_frame; driver->draw_frame = MtxOrb_draw_frame;
driver->getkey = MtxOrb_getkey; driver->getkey = MtxOrb_getkey;
driver->getinfo = MtxOrb_getinfo;
MtxOrb_contrast (contrast);
return fd; return fd;
} }
@@ -243,11 +365,15 @@ MtxOrb_init (lcd_logical_driver * driver, char *args)
// forget bar caracter not in use anymore and reuse the // forget bar caracter not in use anymore and reuse the
// slot for another bar caracter. // slot for another bar caracter.
// //
// Why not just use Matrix Orbital's "clear screen" function or output a "^L"?
// This reliance on drv_base_clear seems suspicious... especially as
// using a (void *) -1 in the driver structure does the same thing...
//
void void
MtxOrb_clear () MtxOrb_clear ()
{ {
// REMOVE: fprintf(stderr, "GLU: MtxOrb_clear.\n"); drv_base_clear (); // do we need this?
drv_base_clear (); write(fd, "\x0FEX", 2); // instant clear...
clear = 1; clear = 1;
} }
@@ -280,7 +406,7 @@ MtxOrb_flush_box (int lft, int top, int rgt, int bot)
// printf("Flush (%i,%i)-(%i,%i)\n", lft, top, rgt, bot); // printf("Flush (%i,%i)-(%i,%i)\n", lft, top, rgt, bot);
for (y = top; y <= bot; y++) { for (y = top; y <= bot; y++) {
sprintf (out, "%cG%c%c", 254, lft, y); sprintf (out, "\x0FEG%c%c", lft, y);
write (fd, out, 4); write (fd, out, 4);
write (fd, lcd.framebuf + (y * lcd.wid) + lft, rgt - lft + 1); write (fd, lcd.framebuf + (y * lcd.wid) + lft, rgt - lft + 1);
@@ -295,9 +421,25 @@ MtxOrb_flush_box (int lft, int top, int rgt, int bot)
void void
MtxOrb_chr (int x, int y, char c) MtxOrb_chr (int x, int y, char c)
{ {
y--; char out[10];
x--;
// validate x and y
if (y > lcd.hgt)
y = lcd.hgt;
if (x > lcd.wid)
x = lcd.wid;
if (y < 1)
y = 1;
if (x < 1)
x = 1;
// write immediately to screen... this code was taken
// from the LK202-25; should work for others, yes?
sprintf(out, "\x0FEG%c%c%c", x, y, c);
write (fd, out, 4);
// write to frame buffer
y--; x--;
lcd.framebuf[(y * lcd.wid) + x] = c; lcd.framebuf[(y * lcd.wid) + x] = c;
} }
@@ -310,34 +452,48 @@ int
MtxOrb_contrast (int contrast) MtxOrb_contrast (int contrast)
{ {
char out[4]; char out[4];
static int status = 140;
if ( ((MtxOrb_type == MTXORB_LCD) || (MtxOrb_type == MTXORB_LKD)) && // validate contrast value
(contrast > 0) ) { if (contrast > 255)
status = contrast; contrast = 255;
sprintf (out, "%cP%c", 254, status); if (contrast < 0)
contrast = 0;
if (IS_LCD_DISPLAY || IS_LKD_DISPLAY) {
sprintf (out, "\x0FEP%c", contrast);
write (fd, out, 3); write (fd, out, 3);
} }
return contrast;
return status;
} }
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
// Sets the backlight on or off -- can be done quickly for // Sets the backlight on or off -- can be done quickly for
// an intermediate brightness... // an intermediate brightness...
// WARN: off switches vfd/vkd displays off
// -> so it's maybe the best to start LCDd with -b on
// //
// WARNING: off switches vfd/vkd displays off entirely
// so maybe it is best to start LCDd with -b on
//
// WARNING: there seems to be a movement afoot to add more
// functions than just on/off to this..
#define BACKLIGHT_OFF 0
#define BACKLIGHT_ON 1
void void
MtxOrb_backlight (int on) MtxOrb_backlight (int on)
{ {
char out[4]; switch (on) {
if (on) { case BACKLIGHT_ON:
sprintf (out, "%cB%c", 254, 0); write (fd, "\x0FE" "F", 2);
write (fd, out, 3); break;
} else { case BACKLIGHT_OFF:
sprintf (out, "%cF", 254); if (IS_VKD_DISPLAY || IS_VFD_DISPLAY)
write (fd, out, 2); ; // turns display off entirely (whoops!)
else
write (fd, "\x0FE" "B" "\x000", 3);
break;
default: // ignored...
break;
} }
} }
@@ -350,21 +506,24 @@ void
MtxOrb_output (int on) MtxOrb_output (int on)
{ {
char out[5]; char out[5];
if ( ((MtxOrb_type == MTXORB_LCD) || (MtxOrb_type == MTXORB_VFD)) ) {
if (on) { if (IS_LCD_DISPLAY || IS_VFD_DISPLAY) {
sprintf (out, "%cW", 254); // LCD and VFD displays only have one output port
} else { (on) ?
sprintf (out, "%cV", 254); write (fd, "\x0FEW", 2) :
} write (fd, "\x0FEV", 2);
write (fd, out, 2);
} else { } else {
int i; int i;
for(i=0; i<6; i++) {
if ( on & (1 << i) ) { // Other displays have six output ports;
sprintf (out, "%cW%c", 254, i+1); // the value "on" is a binary value determining which
} else { // ports are turned on (1) and off (0).
sprintf (out, "%cV%c", 254, i+1);
} on = on & 077; // strip to six bits
for(i = 0; i < 6; i++) {
(on & (1 << i)) ?
sprintf (out, "\x0FEW%c", i + 1) :
sprintf (out, "\x0FEV%c", i + 1);
write (fd, out, 3); write (fd, out, 3);
} }
} }
@@ -376,12 +535,7 @@ MtxOrb_output (int on)
static void static void
MtxOrb_linewrap (int on) MtxOrb_linewrap (int on)
{ {
char out[4]; (on) ? write (fd, "\x0FE" "C", 2) : write (fd, "\x0FE" "D", 2);
if (on)
sprintf (out, "%cC", 254);
else
sprintf (out, "%cD", 254);
write (fd, out, 2);
} }
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
@@ -390,12 +544,7 @@ MtxOrb_linewrap (int on)
static void static void
MtxOrb_autoscroll (int on) MtxOrb_autoscroll (int on)
{ {
char out[4]; (on) ? write (fd, "\x0FEQ", 2) : write (fd, "\x0FER", 2);
if (on)
sprintf (out, "%cQ", 254);
else
sprintf (out, "%cR", 254);
write (fd, out, 2);
} }
// TODO: make sure this doesn't mess up non-VFD displays // TODO: make sure this doesn't mess up non-VFD displays
@@ -405,12 +554,7 @@ MtxOrb_autoscroll (int on)
static void static void
MtxOrb_cursorblink (int on) MtxOrb_cursorblink (int on)
{ {
char out[4]; (on) ? write (fd, "\x0FES", 2) : write (fd, "\x0FET", 2);
if (on)
sprintf (out, "%cS", 254);
else
sprintf (out, "%cT", 254);
write (fd, out, 2);
} }
//// TODO: Might not be needed anymore... //// TODO: Might not be needed anymore...
@@ -420,6 +564,7 @@ MtxOrb_cursorblink (int on)
void void
MtxOrb_init_vbar () MtxOrb_init_vbar ()
{ {
// Isn't this function supposed to go away?
MtxOrb_init_all (vbar); MtxOrb_init_all (vbar);
} }
@@ -430,9 +575,132 @@ MtxOrb_init_vbar ()
void void
MtxOrb_init_hbar () MtxOrb_init_hbar ()
{ {
// Isn't this function supposed to go away?
MtxOrb_init_all (hbar); MtxOrb_init_all (hbar);
} }
/////////////////////////////////////////////////////////////////
// Returns string with general information about the display
//
char *
MtxOrb_getinfo (void)
{
char in = 0;
static char info[255];
char tmp[255], buf[64];
int i = 0;
fd_set rfds;
struct timeval tv;
int retval;
memset(info, '\0', sizeof(info));
strcpy(info, "Matrix Orbital Driver ");
/*
* Read type of display
*/
write(fd, "\x0FE" "7", 2);
/* Watch fd to see when it has input. */
FD_ZERO(&rfds);
FD_SET(fd, &rfds);
/* Wait the specified amount of time. */
tv.tv_sec = 0; // seconds
tv.tv_usec = 500; // microseconds
retval = select(1, &rfds, NULL, NULL, &tv);
if (retval) {
if (read (fd, &in, 1) < 0) {
syslog(LOG_WARNING, "MatrixOrbital driver: unable to read data");
} else {
switch (in) {
case '\x01': strcat(info, "LCD0821 "); break;
case '\x03': strcat(info, "LCD2021 "); break;
case '\x04': strcat(info, "LCD1641 "); break;
case '\x05': strcat(info, "LCD2041 "); break;
case '\x06': strcat(info, "LCD4021 "); break;
case '\x07': strcat(info, "LCD4041 "); break;
case '\x08': strcat(info, "LK202-25 "); break;
case '\x09': strcat(info, "LK204-25 "); break;
case '\x0A': strcat(info, "LK404-55 "); break;
case '\x0B': strcat(info, "VFD2021 "); break;
case '\x0C': strcat(info, "VFD2041 "); break;
case '\x0D': strcat(info, "VFD4021 "); break;
case '\x0E': strcat(info, "VK202-25 "); break;
case '\x0F': strcat(info, "VK204-25 "); break;
case '\x10': strcat(info, "GLC12232 "); break;
case '\x11': strcat(info, "GLC12864 "); break;
case '\x12': strcat(info, "GLC128128 "); break;
case '\x13': strcat(info, "GLC24064 "); break;
case '\x14': strcat(info, "GLK12864-25 "); break;
case '\x15': strcat(info, "GLK24064-25 "); break;
case '\x21': strcat(info, "GLK128128-25 "); break;
case '\x22': strcat(info, "GLK12232-25 "); break;
case '\x31': strcat(info, "LK404-AT "); break;
case '\x32': strcat(info, "VFD1621 "); break;
case '\x33': strcat(info, "LK402-12 "); break;
case '\x34': strcat(info, "LK162-12 "); break;
case '\x35': strcat(info, "LK204-25PC "); break;
default: //sprintf(tmp, "Unknown (%X) ", in); strcat(info, tmp);
break;
}
}
} else
syslog(LOG_WARNING, "MatrixOrbital driver: unable to read device type");
/*
* Read serial number of display
*/
memset(tmp, '\0', sizeof(tmp));
write(fd, "\x0FE" "5", 2);
/* Wait the specified amount of time. */
tv.tv_sec = 0; // seconds
tv.tv_usec = 500; // microseconds
retval = select(1, &rfds, NULL, NULL, &tv);
if (retval) {
if (read (fd, &tmp, 2) < 0) {
syslog(LOG_WARNING, "MatrixOrbital driver: unable to read data");
} else {
sprintf(buf, "Serial No: %ld ", (long int) tmp);
strcat(info, buf);
}
} else
syslog(LOG_WARNING, "MatrixOrbital driver: unable to read device serial number");
/*
* Read firmware revision number
*/
memset(tmp, '\0', sizeof(tmp));
write(fd, "\x0FE" "6", 2);
/* Wait the specified amount of time. */
tv.tv_sec = 0; // seconds
tv.tv_usec = 500; // microseconds
retval = select(1, &rfds, NULL, NULL, &tv);
if (retval) {
if (read (fd, &tmp, 2) < 0) {
syslog(LOG_WARNING, "MatrixOrbital driver: unable to read data");
} else {
sprintf(buf, "Firmware Rev. %ld ", (long int) tmp);
strcat(info, buf);
}
} else
syslog(LOG_WARNING, "MatrixOrbital driver: unable to read device firmware revision");
return info;
}
// TODO: Finish the support for bar growing reverse way. // TODO: Finish the support for bar growing reverse way.
// TODO: Need a "y" as input also !!! // TODO: Need a "y" as input also !!!
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
@@ -447,9 +715,9 @@ MtxOrb_vbar (int x, int len)
int y; int y;
// TODO: REMOVE THE NEXT LINE FOR TESTING ONLY... // REMOVE THE NEXT LINE FOR TESTING ONLY...
// len=-len; // len=-len;
// TODO: REMOVE THE PREVIOUS LINE FOR TESTING ONLY... // REMOVE THE PREVIOUS LINE FOR TESTING ONLY...
if (len > 0) { if (len > 0) {
for (y = lcd.hgt; y > 0 && len > 0; y--) { for (y = lcd.hgt; y > 0 && len > 0; y--) {
@@ -518,10 +786,8 @@ MtxOrb_hbar (int x, int y, int len)
void void
MtxOrb_init_num () MtxOrb_init_num ()
{ {
char out[3];
if (custom != bign) { if (custom != bign) {
sprintf (out, "%cn", 254); write (fd, "\x0FEn", 2);
write (fd, out, 2);
custom = bign; custom = bign;
} }
} }
@@ -535,7 +801,7 @@ void
MtxOrb_num (int x, int num) MtxOrb_num (int x, int num)
{ {
char out[5]; char out[5];
sprintf (out, "%c#%c%c", 254, x, num); sprintf (out, "\x0FE#%c%c", x, num);
write (fd, out, 4); write (fd, out, 4);
} }
@@ -560,7 +826,7 @@ MtxOrb_set_char (int n, char *dat)
if (!dat) if (!dat)
return; return;
sprintf (out, "%cN%c", 254, n); sprintf (out, "\x0FEN%c", n);
write (fd, out, 3); write (fd, out, 3);
for (row = 0; row < lcd.cellhgt; row++) { for (row = 0; row < lcd.cellhgt; row++) {
@@ -636,7 +902,7 @@ MtxOrb_draw_frame (char *dat)
write(fd, dat, lcd.wid*lcd.hgt); write(fd, dat, lcd.wid*lcd.hgt);
*/ */
for (i = 0; i < lcd.hgt; i++) { for (i = 0; i < lcd.hgt; i++) {
sprintf (out, "%cG%c%c", 254, 1, i + 1); sprintf (out, "\x0FEG\x001%c", i + 1);
write (fd, out, 4); write (fd, out, 4);
write (fd, dat + (lcd.wid * i), lcd.wid); write (fd, dat + (lcd.wid * i), lcd.wid);
} }
@@ -650,6 +916,7 @@ char
MtxOrb_getkey () MtxOrb_getkey ()
{ {
char in = 0; char in = 0;
read (fd, &in, 1); read (fd, &in, 1);
return in; return in;
} }
@@ -802,6 +1069,17 @@ MtxOrb_ask_bar (int type)
return (pos); return (pos);
} }
/////////////////////////////////////////////////////////////
// Does the heartbeat...
//
char
MtxOrb_heartbeat (int timer)
{
MtxOrb_icon (!((timer + 4) & 5), 0);
MtxOrb_chr (lcd.wid, 1, 0);
return (char) 0;
}
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
// Sets up a well known character for use. // Sets up a well known character for use.
// //
@@ -1044,6 +1322,8 @@ MtxOrb_set_known_char (int car, int type)
// TODO: Remove this code wich was use for developpement. // TODO: Remove this code wich was use for developpement.
// PS: There might be reference to this code left, so keep it for some time. // PS: There might be reference to this code left, so keep it for some time.
//
// MtxOrb_init_hbar and MtxOrb_init_vbar use it; it's prototyped in MtxOrb.h ...
void void
MtxOrb_init_all (int type) MtxOrb_init_all (int type)
{ {
+3 -1
View File
@@ -22,9 +22,11 @@ void MtxOrb_set_char (int n, char *dat);
void MtxOrb_icon (int which, char dest); void MtxOrb_icon (int which, char dest);
void MtxOrb_draw_frame (char *dat); void MtxOrb_draw_frame (char *dat);
char MtxOrb_getkey (); char MtxOrb_getkey ();
char * MtxOrb_getinfo ();
void MtxOrb_init_all (int type);
int MtxOrb_ask_bar (int type); int MtxOrb_ask_bar (int type);
void MtxOrb_set_known_char (int car, int type); void MtxOrb_set_known_char (int car, int type);
// Isn't this function supposed to go away?
void MtxOrb_init_all (int type);
#endif #endif
+17 -4
View File
@@ -1,3 +1,17 @@
/*
* Joystick input driver for LCDd
*
* Only two unique functions are defined:
*
* joy_getkey
* joy_close
*
* All others are at their defaults.
*
* The code here is configured for a Gravis Gamepad (2 axis, 4 button)
*
*/
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <unistd.h> #include <unistd.h>
@@ -9,6 +23,9 @@
#include <sys/types.h> #include <sys/types.h>
#include <linux/joystick.h> #include <linux/joystick.h>
#ifndef JSIOCGNAME
#define JSIOCGNAME(len) _IOC(_IOC_READ, 'j', 0x13, len) /* get identifier string */
#endif
#include "shared/debug.h" #include "shared/debug.h"
#include "shared/str.h" #include "shared/str.h"
@@ -18,10 +35,6 @@
#include "lcd.h" #include "lcd.h"
#include "joy.h" #include "joy.h"
//////////////////////////////////////////////////////////////////////////
////////////////////// Base "class" to derive from ///////////////////////
//////////////////////////////////////////////////////////////////////////
lcd_logical_driver *joy; lcd_logical_driver *joy;
int fd; int fd;
+59 -1
View File
@@ -11,6 +11,7 @@
#endif #endif
#include "shared/LL.h" #include "shared/LL.h"
#include "shared/debug.h"
#include "lcd.h" #include "lcd.h"
@@ -68,6 +69,15 @@
#include "glk.h" #include "glk.h"
#endif #endif
// Make program more readable and understandable;
// hide details...
#define ResetList(a) LL_Rewind(a)
#define GetDriverData(a) ((lcd_logical_driver *)LL_Get(a))
#define NextDriver(a) (LL_Next(a))
#define MoreDrivers(a) (LL_Next(a) == 0)
#define DriverPresent(a) (a)
#define FunctionPresent(a) ((a) != 0)
// TODO: Make a Windows server, and clients...? // TODO: Make a Windows server, and clients...?
lcd_logical_driver lcd; lcd_logical_driver lcd;
@@ -120,7 +130,9 @@ lcd_physical_driver drivers[] = {
LL *list; LL *list;
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// This sets up which driver to use and initializes stuff. // This function initializes a few basics as well as the
// "base" array. To initialize a specific driver, use the
// lcd_add_driver() function.
// //
int int
lcd_init (char *args) lcd_init (char *args)
@@ -134,8 +146,12 @@ lcd_init (char *args)
return -1; return -1;
} }
// This sets up functions which call all drivers in
// round-robin fashion
lcd_drv_init (NULL, NULL); lcd_drv_init (NULL, NULL);
// "base" driver is a special driver which is always
// loaded...
err = lcd_add_driver ("base", args); err = lcd_add_driver ("base", args);
lcd.wid = 20; lcd.wid = 20;
@@ -162,6 +178,10 @@ lcd_init (char *args)
// TODO: lcd_remove_driver() // TODO: lcd_remove_driver()
// This initializes the specified driver and sends parameters to
// it. This is the function which calls, for example,
// MtxOrb_init. The specifics come from the drivers[] array.
//
int int
lcd_add_driver (char *driver, char *args) lcd_add_driver (char *driver, char *args)
{ {
@@ -177,6 +197,8 @@ lcd_add_driver (char *driver, char *args)
//printf("Found driver: %s (%s)\n", drivers[i].name, driver); //printf("Found driver: %s (%s)\n", drivers[i].name, driver);
// This creates an instance of the lcd structure specific to the
// driver... it is passed to the driver's init routine...
add = malloc (sizeof (lcd_logical_driver)); add = malloc (sizeof (lcd_logical_driver));
if (!add) { if (!add) {
printf ("Couldn't allocate driver \"%s\".\n", driver); printf ("Couldn't allocate driver \"%s\".\n", driver);
@@ -204,6 +226,7 @@ lcd_add_driver (char *driver, char *args)
LL_Push (list, (void *) add); LL_Push (list, (void *) add);
// This is where the driver itself is actually called;
return drivers[i].init (add, args); return drivers[i].init (add, args);
} }
} }
@@ -241,6 +264,9 @@ lcd_shutdown ()
return 0; return 0;
} }
// This sets up all of the "wrapper" driver functions
// which call all of the drivers in turn.
//
int int
lcd_drv_init (struct lcd_logical_driver *driver, char *args) lcd_drv_init (struct lcd_logical_driver *driver, char *args)
{ {
@@ -290,6 +316,7 @@ lcd_drv_init (struct lcd_logical_driver *driver, char *args)
lcd.draw_frame = lcd_drv_draw_frame; lcd.draw_frame = lcd_drv_draw_frame;
lcd.getkey = lcd_drv_getkey; lcd.getkey = lcd_drv_getkey;
lcd.getinfo = lcd_drv_getinfo;
return 1; // 1 is arbitrary. (must be 1 or more) return 1; // 1 is arbitrary. (must be 1 or more)
} }
@@ -713,3 +740,34 @@ lcd_drv_getkey ()
return 0; return 0;
} }
#define MAX_INFO_BUF 1024
char *
lcd_drv_getinfo ()
{
static char info[MAX_INFO_BUF];
char *p;
lcd_logical_driver *driver;
memset(info, '\0', sizeof(info));
ResetList(list);
do {
driver = GetDriverData(list);
if (DriverPresent(driver)) {
if (FunctionPresent(driver->getinfo)) {
p = (char *) driver->getinfo ();
if (strlen(p) + strlen(info) < (MAX_INFO_BUF - 2)) {
strcat(info, p);
}
strcat(info, "\n");
}
}
} while (MoreDrivers(list));
return info;
}
+4
View File
@@ -52,6 +52,9 @@ typedef struct lcd_logical_driver {
// Returns 0 for "no key pressed", or (A-Z). // Returns 0 for "no key pressed", or (A-Z).
char (*getkey) (); char (*getkey) ();
// Returns pointer to static string.
char * (*getinfo) ();
// more? // more?
} lcd_logical_driver; } lcd_logical_driver;
@@ -83,5 +86,6 @@ void lcd_drv_icon (int which, char dest);
void lcd_drv_flush_box (int lft, int top, int rgt, int bot); void lcd_drv_flush_box (int lft, int top, int rgt, int bot);
void lcd_drv_draw_frame (); void lcd_drv_draw_frame ();
char lcd_drv_getkey (); char lcd_drv_getkey ();
char *lcd_drv_getinfo ();
#endif #endif
+95 -30
View File
@@ -24,9 +24,49 @@
E-Z Ignored E-Z Ignored
*/ */
// These are the keys for a (likely) properly functioning LK202-25...
// #define KEY_UP 'I'
// #define KEY_DOWN 'J'
// #define KEY_LEFT 'O'
// #define KEY_RIGHT 'E'
// #define KEY_F1 'N'
// #define KEY_F2 'M'
// #define KEY_ENTER 'H'
// These are the keys for my (possibly) broken LK202-25...
#define KEY_UP 'I'
#define KEY_DOWN 'F'
#define KEY_LEFT 'K'
#define KEY_RIGHT 'A'
#define KEY_F1 'N'
// #define KEY_F2 'M'
// #define KEY_ENTER 'H'
// TODO: Generalize these into each driver...
//
// Really, what this comes down to, is different settings for
// different displays. Unless you want to recompile for all
// the defaults, these key settings must be in the driver.
//
// But then, which driver is active and which screen takes which
// input and... (sigh).
//
#define PAUSE_KEY KEY_F1
#define BACK_KEY KEY_LEFT
#define FORWARD_KEY KEY_RIGHT
#define MAIN_MENU_KEY KEY_DOWN
// This seems somewhat arbitrary, but it IS the original settings:
//
// #define PAUSE_KEY 'A'
// #define BACK_KEY 'B'
// #define FORWARD_KEY 'C'
// #define MAIN_MENU_KEY 'D'
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <syslog.h>
#include "shared/sockets.h" #include "shared/sockets.h"
#include "shared/debug.h" #include "shared/debug.h"
@@ -42,6 +82,11 @@
#include "input.h" #include "input.h"
#define KeyWanted(a,b) ((a) && strchr((a), (b)))
#define CurrentScreen screenlist_current
#define FirstClient(a) (client *)LL_GetFirst(a);
#define NextClient(a) (client *)LL_GetNext(a);
int server_input (int key); int server_input (int key);
// FIXME! The server tends to crash when "E" is pressed.. (?!) // FIXME! The server tends to crash when "E" is pressed.. (?!)
@@ -51,46 +96,65 @@ int server_input (int key);
int int
handle_input () handle_input ()
{ {
char str[256]; char str[15];
int key; int key;
screen *s; screen *s;
widget *w; widget *w;
client *c; client *c;
key = lcd.getkey (); if ((key = lcd.getkey ()) == 0)
if (!key)
return 0; return 0;
debug ("handle_input(%c)\n", (char) key); //debug ("handle_input(%c)\n", (char) key);
// Sequence:
// Does the current screen want the key?
// IfTrue: handle and quit
// IfFalse:
// Let ALL clients handle it if they want
// Let Server handle it, too
//
// This leads to a unique situation:
// First: multiple clients may handle the same key in multiple ways
// Second: the server may handle the key differently yet
//
// Solution: Only the current screen can handle the key press.
// Alternately, only one client can handle the key press.
if (key) {
// TODO: Interpret and translate keys! // TODO: Interpret and translate keys!
// Give current screen a shot at the key first // Give current screen a shot at the key first
s = screenlist_current (); s = CurrentScreen ();
if( s->keys && strchr( s->keys, key ) ) {
if (KeyWanted(s->keys, key)) {
// This screen wants this key. Tell it we got one // This screen wants this key. Tell it we got one
sprintf(str, "key %c\n", key); snprintf(str, sizeof(str), "key %c\n", key);
sock_send_string(s->parent->sock, str); sock_send_string(s->parent->sock, str);
// Nobody else gets this key // Nobody else gets this key
} else {
// Give key to clients who want it
c = (client *)LL_GetFirst(clients);
while(c) {
// If the client should have this keypress...
if( c->data->client_keys && strchr(c->data->client_keys, key) ) {
// Send keypress to client
sprintf(str, "key %c\n", key);
sock_send_string(c->sock, str);
};
c = (client *)LL_GetNext(clients);
} // while clients
// Give server a shot at all keys
server_input (key);
} }
};
// if the current screen doesn't want it,
// ignore the key...
// else {
// // Give key to clients who want it
//
// c = FirstClient(clients);
//
// while (c) {
// // If the client should have this keypress...
// if(KeyWanted(c->data->client_keys,key)) {
// // Send keypress to client
// snprintf(str, sizeof(str), "key %c\n", key);
// sock_send_string(c->sock, str);
// break; // first come, first serve
// };
// c = NextClient(clients);
// } // while clients
//
// // Give server a shot at all keys
// server_input (key);
// }
return 0; return 0;
} }
@@ -99,23 +163,24 @@ int
server_input (int key) server_input (int key)
{ {
debug ("server_input(%c)\n", (char) key); debug ("server_input(%c)\n", (char) key);
syslog(LOG_DEBUG, "key %d pressed on device", key);
switch (key) { switch ((char) key) {
case 'A': case PAUSE_KEY:
if (screenlist_action == SCR_HOLD) if (screenlist_action == SCR_HOLD)
screenlist_action = 0; screenlist_action = 0;
else else
screenlist_action = SCR_HOLD; screenlist_action = SCR_HOLD;
break; break;
case 'B': case BACK_KEY:
screenlist_action = SCR_BACK; screenlist_action = SCR_BACK;
screenlist_prev (); screenlist_prev ();
break; break;
case 'C': case FORWARD_KEY:
screenlist_action = SCR_SKIP; screenlist_action = SCR_SKIP;
screenlist_next (); screenlist_next ();
break; break;
case 'D': case MAIN_MENU_KEY:
debug ("got the menu key!\n"); debug ("got the menu key!\n");
server_menu (); server_menu ();
break; break;
+121 -12
View File
@@ -18,6 +18,10 @@
#include <string.h> #include <string.h>
#include <signal.h> #include <signal.h>
#include <unistd.h> #include <unistd.h>
#include <pwd.h>
#include <errno.h>
#include <sys/types.h>
#include <syslog.h>
#include "shared/debug.h" #include "shared/debug.h"
@@ -32,10 +36,30 @@
#include "input.h" #include "input.h"
#include "main.h" #include "main.h"
#define MAX_TIMER 0x10000
#define DEFAULT_USER "nobody"
char *version = VERSION; char *version = VERSION;
char *protocol_version = PROTOCOL_VERSION; char *protocol_version = PROTOCOL_VERSION;
char *build_date = __DATE__; char *build_date = __DATE__;
/* Socket to bind to...
Using loopback is much more secure; it means that this port is
accessible only to programs running locally on the same host as LCDd.
Using variables for these means that (later) we can select which port
and which address to bind to at run time. */
char bind_addr[64] = "127.0.0.1";
int lcd_port = LCDPORT;
// The parameter structure and args[] should
// be removed when getopt(3) is implemented,
// as there won't be any need for them then.
typedef struct parameter {
char *sh, *lg; // short and long versions
} parameter;
// This is currently only a list of available arguments, but doesn't // This is currently only a list of available arguments, but doesn't
// really *do* anything. It just helps to figure out which parameters // really *do* anything. It just helps to figure out which parameters
@@ -54,6 +78,34 @@ static parameter args[] = {
void exit_program (int val); void exit_program (int val);
void HelpScreen (); void HelpScreen ();
// At this point, this function will only succeed;
// all other options will stop the program.
// However, it may not always be thus; so we prepared
// for this possibility by making it return an int.
//
int drop_privs(char *user) {
struct passwd *pwent;
if (getuid() == 0 || geteuid() == 0) {
if ((pwent = getpwnam(user)) == NULL) {
if (errno) {
perror("LCDd: getpwnam");
exit(1);
} else {
fprintf(stderr, "user %s not a valid user!", user);
exit(1);
}
} else {
if (setuid(pwent->pw_uid) < 0) {
fprintf(stderr, "unable to switch to user %s\n", user);
perror("LCDd: setuid");
exit(1);
}
}
}
return 0;
}
int int
main (int argc, char **argv) main (int argc, char **argv)
{ {
@@ -64,6 +116,7 @@ main (int argc, char **argv)
int disable_server_screen = 1; int disable_server_screen = 1;
screen *s = NULL; screen *s = NULL;
char *str, *ing; // strings for commandline handling char *str, *ing; // strings for commandline handling
char *user = DEFAULT_USER;
// Ctrl-C will cause a clean exit... // Ctrl-C will cause a clean exit...
signal (SIGINT, exit_program); signal (SIGINT, exit_program);
@@ -86,14 +139,31 @@ main (int argc, char **argv)
// Now, go into daemon mode... // Now, go into daemon mode...
#ifndef DEBUG #ifndef DEBUG
openlog("LCDd", LOG_PID, LOG_DAEMON);
syslog(LOG_NOTICE, "server version %s starting up (protocol version %s)",
version, protocol_version);
syslog(LOG_NOTICE, "server built on %s",
build_date);
if (daemon_mode) { if (daemon_mode) {
int child; int child;
syslog(LOG_NOTICE, "server forking to background");
if ((child = fork ()) != 0) { if ((child = fork ()) != 0) {
usleep (1500000); // Wait for child to initialize usleep (1500000); // Wait for child to initialize
exit (0); /* PARENT EXITS */ exit (0); /* PARENT EXITS */
} }
// This line removed because it eats error messages... // This line removed because it eats error messages...
//setsid(); /* RELEASE TTY */ //setsid(); /* RELEASE TTY */
//
// After this point, as a daemon, no error messages should
// go to the console unless drastic; rather, they should go to syslog
//
// However, option processing is not yet done, nor is any initialization (!)
// So we must wait until the main loop.
} else {
syslog(LOG_NOTICE, "server running in foreground");
} }
#endif #endif
@@ -195,13 +265,20 @@ main (int argc, char **argv)
} }
} }
// Now init a bunch of required stuff... // switch to a different user for the real work...
if (lcd_port >= 1024)
drop_privs(user);
if (sock_create_server () <= 0) { if (sock_create_server (&bind_addr, lcd_port) <= 0) {
printf ("Error opening socket.\n"); printf ("Error opening socket.\n");
return 1; return 1;
} }
if (lcd_port > 1024)
drop_privs(user);
// Now init a bunch of required stuff...
if (client_init () < 0) { if (client_init () < 0) {
printf ("Error initializing client list\n"); printf ("Error initializing client list\n");
return 1; return 1;
@@ -218,29 +295,48 @@ main (int argc, char **argv)
} else if (disable_server_screen) { } else if (disable_server_screen) {
server_screen->priority = 256; server_screen->priority = 256;
} }
// Probably a better place to fork
//
// Main loop... // Main loop...
syslog(LOG_NOTICE, "using %dx%d LCD with cells %dx%d",
lcd.wid, lcd.hgt, lcd.cellwid, lcd.cellhgt);
while (1) { while (1) {
sock_poll_clients (); sock_poll_clients (); // poll clients for input
parse_all_client_messages (); parse_all_client_messages (); // analyze input from network clients
handle_input (); handle_input (); // handle key input from devices
// TODO: Move this code to screenlist.c... // TODO: Move this code to screenlist.c...
// ... it should just say "handle_screens();" // ... it should just say "handle_screens();"
// Timer gets reset by screenlist_next() // Timer gets reset by screenlist_next()
timer++; timer++;
// this line's here because s was getting overwritten at one time... // this line's here because s was getting overwritten at one time...
//s = screenlist_current(); //s = screenlist_current();
if (s && (timer >= s->duration)) { if (s && (timer >= s->duration)) {
screenlist_next (); screenlist_next ();
} }
// Just in case it gets out of hand...
if (timer >= 0x10000)
timer = 0;
update_server_screen (timer);
s = screenlist_current ();
// render something here... // Just in case it gets out of hand...
if (s) 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); draw_screen (s, timer);
else else
no_screen_screen (timer); no_screen_screen (timer);
@@ -257,9 +353,22 @@ main (int argc, char **argv)
void void
exit_program (int val) exit_program (int val)
{ {
char buf[64];
// TODO: These things shouldn't be so interdependent. The order // TODO: These things shouldn't be so interdependent. The order
// things are shut down in shouldn't matter... // things are shut down in shouldn't matter...
strcpy(buf, "server shutting down on ");
switch(val) {
case 1: strcat(buf, "SIGHUP"); break;
case 2: strcat(buf, "SIGINT"); break;
case 15: strcat(buf, "SIGTERM"); break;
default: sprintf(buf, "server shutting down on signal %d", val); break;
// Other values should not be seen, but just in case..
}
// Make note in the logs...
syslog(LOG_NOTICE, buf);
// Say goodbye! // Say goodbye!
goodbye_screen (); goodbye_screen ();
// Can go anywhere... // Can go anywhere...
+3 -3
View File
@@ -26,8 +26,8 @@ typedef struct screen_size {
int wid, hgt; int wid, hgt;
} screen_size; } screen_size;
typedef struct parameter { #define DEFAULT_SCREEN_PRIORITY 128
char *sh, *lg; // short and long versions #define DEFAULT_SCREEN_DURATION 32
} parameter; #define DEFAULT_HEARTBEAT 1
#endif #endif
+1 -1
View File
@@ -303,7 +303,7 @@ slid_func (menu_item * item)
value = readfunc (MENU_READ); value = readfunc (MENU_READ);
if (value < 0 || value >= MENU_CLOSE) if (value < 0 || value >= MENU_CLOSE)
return value; return value;
sprintf (str, "%i", value); snprintf (str, sizeof(str), "%i", value);
if (lcd.hgt >= 4) { if (lcd.hgt >= 4) {
lcd.string (8, 4, str); lcd.string (8, 4, str);
value = (lcd.wid * lcd.cellwid * value / 256); value = (lcd.wid * lcd.cellwid * value / 256);
+1 -1
View File
@@ -260,7 +260,7 @@ Server_screen_func (int input)
if (server_screen->priority < 256) if (server_screen->priority < 256)
server_screen->priority = 256; server_screen->priority = 256;
else else
server_screen->priority = 128; server_screen->priority = DEFAULT_SCREEN_PRIORITY;
} }
return (MENU_OK | (server_screen->priority < 256)); return (MENU_OK | (server_screen->priority < 256));
+96 -54
View File
@@ -20,21 +20,32 @@
#include "client_functions.h" #include "client_functions.h"
#include "parse.h" #include "parse.h"
// This is a big function... TOO big. How to trim....
// TODO: Simplify... simplify...
int int
parse_all_client_messages () parse_all_client_messages ()
{ {
int i, j; int i, j, len;
int newtoken, inquote; int newtoken, inquote;
client *c; client *c;
char *str; char *str, *p, *q, *s;
// char *tok; // char *tok;
int argc; int argc;
char *argv[256]; char *argv[256];
char delimiters[] = " \0"; char delimiters[] = " ";
char leftquote[] = "\0\"'`([{\0"; char leftquote[] = "\"'`([{";
char rightquote[] = "\0\"'`)]}\0"; char rightquote[] = "\"'`)]}";
char errmsg[256]; char errmsg[256];
int invalid = 0; int invalid = 0;
int quoteindex;
for (i = 0; i <= 256; i++) {
argv[i] == NULL;
}
#define SEPARATOR_CHAR ' '
#define LINE_TERM_CHAR '\0'
#define COMMENT_CHAR '#'
//debug("parse: Rewinding list...\n"); //debug("parse: Rewinding list...\n");
LL_Rewind (clients); LL_Rewind (clients);
@@ -48,76 +59,107 @@ parse_all_client_messages ()
for (str = client_get_message (c); str; str = client_get_message (c)) { for (str = client_get_message (c); str; str = client_get_message (c)) {
debug ("parse: ...%s\n", str); debug ("parse: ...%s\n", str);
// Now, split up the string... // Now, split up the string...
//len = strlen(str);
argc = 0; argc = 0;
newtoken = 1; i = 0;
inquote = 0; q = p = str;
for (i = 0; str[i]; i++) {
if (inquote) // Scan for the end of the quote if (*p == COMMENT_CHAR) {
{ continue; // found a comment line - skip it...
if (str[i] == rightquote[inquote]) { // Found the end of the quote
inquote = 0;
str[i] = 0;
newtoken = 1;
} }
} else // Normal operation; split at delimiters
{ //fprintf(stderr, "starting string scan...\n");
for (j = 1; leftquote[j]; j++) {
// Found the beginning of a new quote... do {
if (str[i] == leftquote[j]) { // bypass initial white space...
inquote = j; while ((*p == SEPARATOR_CHAR) && (*p)) {
str[i] = 0; p++;
continue; q++;
} }
// If (*p) is null here, we reached the end of
// an empty parameter... so one of two things
// is true:
//
// 1. There is nothing but white space on this line (odd..)
// 2. This is trailing white space (odd... but allowable)
if (*p == LINE_TERM_CHAR) {
break;
// if there are no arguments, argc == 0 and will fail
// appropriately...
//
// if this is trailing white space, ignore the argc++ at the
// end and claim this as the end...
} }
for (j = 0; delimiters[j]; j++) {
// Break into a new string... // Handle quoted strings...
if (str[i] == delimiters[j]) { if ((s = strchr(leftquote, *p)) != NULL) {
str[i] = 0; quoteindex = s - leftquote;
newtoken = 1; //fprintf(stderr, "found <%c> at index [%d] = <%c>\n", *p, quoteindex, leftquote[quoteindex]);
continue; q = ++p; // past open quote...
while ((rightquote[quoteindex] != *p) && (*p != LINE_TERM_CHAR)) {
p++;
} }
} if (*p == LINE_TERM_CHAR) {
} // We just sucked up the rest of the command line: ERROR!!
if (newtoken && str[i]) { snprintf (errmsg, sizeof(errmsg), "huh? unterminated string! missing ending %c\n",
newtoken = 0; rightquote[quoteindex]);
argv[argc] = str + i;
argc++;
} else {
}
}
if (inquote) {
sprintf (errmsg, "huh? Unterminated string: missing %c\n", rightquote[inquote]);
sock_send_string (c->sock, errmsg); sock_send_string (c->sock, errmsg);
continue; continue;
} else {
*p = LINE_TERM_CHAR; // terminate string
p++; // bypass to next character
// Note that next character could be a EndOfLine (null)
// if the string was last on the line, or it could be
// something else... is it a blank?
if (*p != SEPARATOR_CHAR && *p != LINE_TERM_CHAR) {
sock_send_string (c->sock, "huh? improperly terminated string! (missing whitespace)\n");
continue;
} }
/* }
for(tok = strtok(str, delimiters);
tok; // Otherwise, normal string...
tok=strtok(NULL, delimiters)) } else {
{ while (*p != SEPARATOR_CHAR && *p != LINE_TERM_CHAR)
argv[argc] = tok; p++;
}
// Not end of line?
if (*p) {
*p = LINE_TERM_CHAR;
//fprintf(stderr, "found new token: %s\n", q);
argv[i++] = q;
q = ++p;
} else {
//fprintf(stderr, "found new token: %s\n", q);
argv[i++] = q;
}
// At the end of this statement,
// *p will be '\0' if end of input reached;
// otherwise, it is the first character of the
// next part of the string.
argc++; argc++;
} } while (*p);
*/
//fprintf(stderr, "exiting string scan...\n");
argv[argc] = NULL; argv[argc] = NULL;
if (argc < 1) if (argc < 1)
continue; continue;
// Now find and call the appropriate function... // Now find and call the appropriate function...
// debug("parse: Finding function...\n");
invalid = 1; invalid = 1;
for (i = 0; commands[i].keyword; i++) { for (i = 0; commands[i].keyword; i++) {
// debug("(checking %s)\n", commands[i].keyword);
if (0 == strcmp (argv[0], commands[i].keyword)) { if (0 == strcmp (argv[0], commands[i].keyword)) {
// debug("(FOUND %s)\n", commands[i].keyword);
invalid = commands[i].function (c, argc, argv); invalid = commands[i].function (c, argc, argv);
// debug("parse: Returned %i...\n", err); break; // found our function - don't continue on...
} }
} }
if (invalid) { if (invalid) {
// FIXME: Check for buffer overflows here... snprintf (errmsg, sizeof(errmsg), "huh? Invalid command \"%s\"\n", argv[0]);
sprintf (errmsg, "huh? Invalid command \"%s\"\n", argv[0]);
sock_send_string (c->sock, errmsg); sock_send_string (c->sock, errmsg);
} }
+65 -15
View File
@@ -11,6 +11,10 @@
THIS FILE IS MESSY! Anyone care to rewrite it nicely? Please?? :) THIS FILE IS MESSY! Anyone care to rewrite it nicely? Please?? :)
NOTE: (from David Douthitt) Multiple screen sizes? Multiple simultaneous
screens? Horrors of horrors... next thing you know it'll be making coffee...
Better believe it'll take a while to do...
*/ */
#include <string.h> #include <string.h>
@@ -59,16 +63,28 @@ draw_screen (screen * s, int timer)
reset = 0; reset = 0;
old_s = s; old_s = s;
// Clear the LCD screen...
lcd.clear (); lcd.clear ();
switch (backlight_state) { // lcd.backlight --
//
// This should be in a separate function altogether.
// Perhaps several: lcd.backlight_off, lcd.backlight_on,
// lcd.backlight_brightness, lcd.backlight_flash ...
//
// Set up backlight to the correct state...
// NOTE: dirty stripping of other options...
switch (backlight_state & 1) {
// Backlight off (easy)
case BACKLIGHT_OFF: case BACKLIGHT_OFF:
lcd.backlight (backlight_off_brightness); lcd.backlight (BACKLIGHT_OFF);
break; break;
// Backlight on (easy)
case BACKLIGHT_ON: case BACKLIGHT_ON:
lcd.backlight (backlight_brightness); lcd.backlight (BACKLIGHT_ON);
break; break;
default: default:
// Backlight flash: check timer and flip backlight as appropriate
if (backlight_state & BACKLIGHT_FLASH) { if (backlight_state & BACKLIGHT_FLASH) {
tmp = (!((timer & 7) == 7)); tmp = (!((timer & 7) == 7));
if (backlight_state & 1) if (backlight_state & 1)
@@ -77,6 +93,8 @@ draw_screen (screen * s, int timer)
else else
lcd.backlight (!tmp ? backlight_brightness : backlight_off_brightness); lcd.backlight (!tmp ? backlight_brightness : backlight_off_brightness);
//lcd.backlight(backlight_brightness * ((timer&7) == 7)); //lcd.backlight(backlight_brightness * ((timer&7) == 7));
// Backlight blink: check timer and flip backlight as appropriate
} else if (backlight_state & BACKLIGHT_BLINK) { } else if (backlight_state & BACKLIGHT_BLINK) {
tmp = (!((timer & 14) == 14)); tmp = (!((timer & 14) == 14));
if (backlight_state & 1) if (backlight_state & 1)
@@ -89,25 +107,31 @@ draw_screen (screen * s, int timer)
break; break;
} }
// Output ports from LCD - outputs depend on the current screen
lcd.output (output_state); lcd.output (output_state);
// Draw a frame...
draw_frame (s->widgets, 'v', 0, 0, lcd.wid, lcd.hgt, s->wid, s->hgt, s->duration / s->hgt, timer); draw_frame (s->widgets, 'v', 0, 0, lcd.wid, lcd.hgt, s->wid, s->hgt, s->duration / s->hgt, timer);
//debug("draw_screen done\n"); //debug("draw_screen done\n");
if (heartbeat) { if (heartbeat) {
if ((s->heartbeat == 1) || heartbeat == HEART_ON) { if ((s->heartbeat == HEART_ON) || heartbeat == HEART_ON) {
// Set this to pulsate like a real heart beat... // Set this to pulsate like a real heart beat...
// (binary is fun... :) // (binary is fun... :)
// lcd.heartbeat ();
lcd.icon (!((timer + 4) & 5), 0); lcd.icon (!((timer + 4) & 5), 0);
lcd.chr (lcd.wid, 1, 0); lcd.chr (lcd.wid, 1, 0);
} }
if ((s->heartbeat == 2) && heartbeat != HEART_OFF) { // else
char *phases = "-\\|/"; // This seems unnecessary... heartbeat is nicer...
lcd.chr (lcd.wid, 1, phases[timer & 3]); // if ((s->heartbeat == HEART_OPEN) && heartbeat != HEART_OFF) {
} // char *phases = "-\\|/";
// lcd.chr (lcd.wid, 1, phases[timer & 3]);
// }
} }
// flush display out, frame and all...
lcd.flush (); lcd.flush ();
//debug("draw_screen: %8x, %i\n", s, timer); //debug("draw_screen: %8x, %i\n", s, timer);
@@ -116,9 +140,25 @@ draw_screen (screen * s, int timer)
} }
// The following function is positively ghastly (as was mentioned above!)
// Best thing to do is to remove support for frames... but anyway...
//
static int static int
draw_frame (LL * list, char fscroll, int left, int top, int right, int bottom, int fwid, int fhgt, int fspeed, int timer) draw_frame (LL * list,
char fscroll, // direction of scrolling
int left, // left edge of frame
int top, // top edge of frame
int right, // right edge of frame
int bottom, // bottom edge of frame
int fwid, // frame width?
int fhgt, // frame height?
int fspeed, // speed of scrolling...
int timer) // ?
{ {
#define VerticalScrolling (fscroll == 'v')
#define HorizontalScrolling (fscroll == 'h')
char str[BUFSIZE]; // scratch buffer char str[BUFSIZE]; // scratch buffer
widget *w; widget *w;
@@ -135,18 +175,22 @@ draw_frame (LL * list, char fscroll, int left, int top, int right, int bottom, i
fx = 0; fx = 0;
fy = 0; fy = 0;
if (fscroll == 'v') { if (VerticalScrolling) {
if (fspeed > 0) if (fspeed > 0)
fy = (timer - fspeed) / fspeed; fy = (timer - fspeed) / fspeed;
if (fspeed < 0) else if (fspeed < 0)
fy = (-fspeed) * timer; fy = (-fspeed) * timer;
if (fy < 0) if (fy < 0)
fy = 0; fy = 0;
// Make sure the whole frame gets displayed, at least... // Make sure the whole frame gets displayed, at least...
// ...by setting the action to RENDER_HOLD if no other action
// is currently defined...
if (!screenlist_action) if (!screenlist_action)
screenlist_action = RENDER_HOLD; screenlist_action = RENDER_HOLD;
if ((fy) > fhgt - 1) { if ((fy) > fhgt - 1) {
// Release hold after it has been displayed // Release hold after it has been displayed
if (!screenlist_action || screenlist_action == RENDER_HOLD) if (!screenlist_action || screenlist_action == RENDER_HOLD)
@@ -156,8 +200,9 @@ draw_frame (LL * list, char fscroll, int left, int top, int right, int bottom, i
fy %= fhgt; fy %= fhgt;
if (fy > fhgt - hgt) if (fy > fhgt - hgt)
fy = fhgt - hgt; fy = fhgt - hgt;
} else if (fscroll == 'h') { // TODO: Frames don't scroll horizontally yet!
} else if (HorizontalScrolling) {
// TODO: Frames don't scroll horizontally yet!
} }
//debug("draw_screen: %8x, %i\n", s, timer); //debug("draw_screen: %8x, %i\n", s, timer);
@@ -166,6 +211,11 @@ draw_frame (LL * list, char fscroll, int left, int top, int right, int bottom, i
//debug("draw_frame: %8x, %i\n", frame, timer); //debug("draw_frame: %8x, %i\n", frame, timer);
#define PositiveX(a) ((a)->x > 0)
#define PositiveY(a) ((a)->y > 0)
#define ValidPoint(a) (PositiveX(a) && PositiveY(a))
#define TextPresent(a) ((a)->text)
LL_Rewind (list); LL_Rewind (list);
do { do {
w = (widget *) LL_Get (list); w = (widget *) LL_Get (list);
@@ -175,9 +225,9 @@ draw_frame (LL * list, char fscroll, int left, int top, int right, int bottom, i
// TODO: Make this cleaner and more flexible! // TODO: Make this cleaner and more flexible!
switch (w->type) { switch (w->type) {
case WID_STRING: case WID_STRING:
if ((w->x > 0) && (w->y > 0) && (w->text)) { if (ValidPoint(w) && TextPresent(w)) {
if ((w->y <= hgt + fy) && (w->y > fy)) { if ((w->y <= hgt + fy) && (w->y > fy)) {
if (w->x > wid) { w->x=wid; }; if (w->x > wid) w->x=wid;
strncpy (str, w->text, wid - w->x + 1); strncpy (str, w->text, wid - w->x + 1);
str[wid - w->x + 1] = 0; str[wid - w->x + 1] = 0;
lcd.string (w->x + left, w->y + top - fy, str); lcd.string (w->x + left, w->y + top - fy, str);
+4 -3
View File
@@ -11,6 +11,7 @@
#include "widget.h" #include "widget.h"
#include "screenlist.h" #include "screenlist.h"
#include "screen.h" #include "screen.h"
#include "main.h"
int default_priority = 128 ; int default_priority = 128 ;
int default_duration = 64 ; // About 8 seconds int default_duration = 64 ; // About 8 seconds
@@ -28,9 +29,9 @@ screen_create ()
s->id = NULL; s->id = NULL;
s->name = NULL; s->name = NULL;
s->priority = default_priority ; s->priority = DEFAULT_SCREEN_PRIORITY;
s->duration = default_duration ; s->duration = DEFAULT_SCREEN_DURATION;
s->heartbeat = 1; s->heartbeat = DEFAULT_HEARTBEAT;
s->wid = lcd.wid; s->wid = lcd.wid;
s->hgt = lcd.hgt; s->hgt = lcd.hgt;
s->keys = NULL; s->keys = NULL;
+2 -2
View File
@@ -112,7 +112,7 @@ screenlist_current ()
c = old_s->parent; c = old_s->parent;
if (c) // Tell the client we're not listening any more... if (c) // Tell the client we're not listening any more...
{ {
sprintf (str, "ignore %s\n", old_s->id); snprintf (str, sizeof(str), "ignore %s\n", old_s->id);
sock_send_string (c->sock, str); sock_send_string (c->sock, str);
} else // The server has the display, so do nothing } else // The server has the display, so do nothing
{ {
@@ -125,7 +125,7 @@ screenlist_current ()
c = s->parent; c = s->parent;
if (c) // Tell the client we're paying attention... if (c) // Tell the client we're paying attention...
{ {
sprintf (str, "listen %s\n", s->id); snprintf (str, sizeof(str), "listen %s\n", s->id);
sock_send_string (c->sock, str); sock_send_string (c->sock, str);
} else // The server has the display, so do nothing } else // The server has the display, so do nothing
{ {
+61 -44
View File
@@ -26,6 +26,11 @@ char one[256] = "";
char two[256] = ""; char two[256] = "";
char three[256] = ""; char three[256] = "";
#define WidgetXPos(w,a) (w)->x = (a)
#define WidgetYPos(w,a) (w)->y = (a)
#define WidgetText(w,a) (w)->text = (a)
#define WidgetString(w,a,b,t) {WidgetXPos(w,a);WidgetYPos(w,b);WidgetText(w,t);}
int int
server_screen_init () server_screen_init ()
{ {
@@ -44,46 +49,39 @@ server_screen_init ()
server_screen->name = name; server_screen->name = name;
server_screen->duration = 8; // 1 second, instead of 4... server_screen->duration = 8; // 1 second, instead of 4...
// TODO: Error-checking? if (widget_add (server_screen, "title", "title", NULL, 1) != 0) {
widget_add (server_screen, "title", "title", NULL, 1); fprintf (stderr, "server_screen_init: internal error: could not add title widget\n");
widget_add (server_screen, "one", "string", NULL, 1); }
widget_add (server_screen, "two", "string", NULL, 1); if (widget_add (server_screen, "one", "string", NULL, 1) != 0) {
widget_add (server_screen, "three", "string", NULL, 1); fprintf (stderr, "server_screen_init: internal error: could not add title widget\n");
}
if (widget_add (server_screen, "two", "string", NULL, 1) != 0) {
fprintf (stderr, "server_screen_init: internal error: could not add title widget\n");
}
if (widget_add (server_screen, "three", "string", NULL, 1) != 0) {
fprintf (stderr, "server_screen_init: internal error: could not add title widget\n");
}
// Now, initialize all the widgets... // Now, initialize all the widgets...
w = widget_find (server_screen, "title"); if ((w = widget_find (server_screen, "title")) != NULL) {
if (w) { WidgetText(w,title);
w->text = title; } else
} else {
fprintf (stderr, "server_screen_init: Can't find title\n"); fprintf (stderr, "server_screen_init: Can't find title\n");
}
w = widget_find (server_screen, "one"); if ((w = widget_find (server_screen, "one")) != NULL)
if (w) { WidgetString(w,1,2,one)
w->x = 1; else
w->y = 2;
w->text = one;
} else {
fprintf (stderr, "server_screen_init: Can't find widget one\n"); fprintf (stderr, "server_screen_init: Can't find widget one\n");
}
w = widget_find (server_screen, "two"); if ((w = widget_find (server_screen, "two")) != NULL)
if (w) { WidgetString(w,1,3,two)
w->x = 1; else
w->y = 3;
w->text = two;
} else {
fprintf (stderr, "server_screen_init: Can't find widget two\n"); fprintf (stderr, "server_screen_init: Can't find widget two\n");
}
w = widget_find (server_screen, "three"); if ((w = widget_find (server_screen, "three")) != NULL)
if (w) { WidgetString(w,1,4,three)
w->x = 1; else
w->y = 4;
w->text = three;
} else {
fprintf (stderr, "server_screen_init: Can't find widget three\n"); fprintf (stderr, "server_screen_init: Can't find widget three\n");
}
// And enqueue the screen // And enqueue the screen
screenlist_add (server_screen); screenlist_add (server_screen);
@@ -93,6 +91,20 @@ server_screen_init ()
return 0; return 0;
} }
static int
screen_count (client *c) {
int n;
n = 0;
LL_Rewind (c->data->screenlist);
do {
if (LL_Get (c->data->screenlist) != NULL)
n++;
} while (LL_Next (c->data->screenlist) == 0);
return n;
}
int int
update_server_screen (int timer) update_server_screen (int timer)
{ {
@@ -112,24 +124,31 @@ update_server_screen (int timer)
c = LL_Get (clients); c = LL_Get (clients);
if (c) { if (c) {
num_clients++; num_clients++;
LL_Rewind (c->data->screenlist); num_screens += screen_count(c);
do { // LL_Rewind (c->data->screenlist);
s = LL_Get (c->data->screenlist); // do {
if (s) { // s = LL_Get (c->data->screenlist);
num_screens++; // if (s) {
} // num_screens++;
} while (LL_Next (c->data->screenlist) == 0); // }
// } while (LL_Next (c->data->screenlist) == 0);
} }
} while (LL_Next (clients) == 0); } while (LL_Next (clients) == 0);
// Format strings for the appropriate size display...
//
if (lcd.hgt >= 3) { if (lcd.hgt >= 3) {
sprintf (one, "Clients: %i", num_clients); snprintf (one, sizeof(one), "Clients: %i", num_clients);
sprintf (two, "Screens: %i", num_screens); snprintf (two, sizeof(two), "Screens: %i", num_screens);
} else { } else {
if (lcd.wid >= 20) if (lcd.wid >= 20)
sprintf (one, "%i Client%s, %i Screen%s", num_clients, (num_clients == 1) ? "" : "s", num_screens, (num_screens == 1) ? "" : "s"); snprintf (one, sizeof(one), "%i Client%s, %i Screen%s", num_clients,
(num_clients == 1) ? "" : "s", num_screens,
(num_screens == 1) ? "" : "s");
else // 16x2 size else // 16x2 size
sprintf (one, "%i Cli%s, %i Scr%s", num_clients, (num_clients == 1) ? "" : "s", num_screens, (num_screens == 1) ? "" : "s"); snprintf (one, sizeof(one), "%i Cli%s, %i Scr%s", num_clients,
(num_clients == 1) ? "" : "s", num_screens,
(num_screens == 1) ? "" : "s");
} }
return 0; return 0;
@@ -140,9 +159,7 @@ no_screen_screen (int timer)
{ {
lcd.clear (); lcd.clear ();
lcd.string (1, 1, "Error: No screen!"); lcd.string (1, 1, "Error: No screen!");
lcd.flush (); lcd.flush ();
return 0; return 0;
+46 -18
View File
@@ -17,6 +17,10 @@
#include "sock.h" #include "sock.h"
#include "clients.h" #include "clients.h"
#include "shared/debug.h" #include "shared/debug.h"
#include "syslog.h"
extern char bind_addr[64];
extern int lcd_port;
/************************************************** /**************************************************
LCDproc sockets code... LCDproc sockets code...
@@ -34,7 +38,7 @@ int read_from_client (int filedes);
// Creates a socket in internet space // Creates a socket in internet space
int int
sock_create_inet_socket (unsigned short int port) sock_create_inet_socket (char * addr, unsigned int port)
{ {
struct sockaddr_in name; struct sockaddr_in name;
int sock; int sock;
@@ -46,6 +50,7 @@ sock_create_inet_socket (unsigned short int port)
sock = socket (PF_INET, SOCK_STREAM, 0); sock = socket (PF_INET, SOCK_STREAM, 0);
if (sock < 0) { if (sock < 0) {
perror ("Error creating socket"); perror ("Error creating socket");
syslog(LOG_ALERT, "could not create socket", port);
return -1; return -1;
} }
@@ -53,10 +58,14 @@ sock_create_inet_socket (unsigned short int port)
//debug("Binding Inet Socket\n"); //debug("Binding Inet Socket\n");
name.sin_family = AF_INET; name.sin_family = AF_INET;
name.sin_port = htons (port); name.sin_port = htons (port);
name.sin_addr.s_addr = htonl (INADDR_ANY); inet_aton(addr, &name.sin_addr);
if (bind (sock, (struct sockaddr *) &name, sizeof (name)) < 0) { if (bind (sock, (struct sockaddr *) &name, sizeof (name)) < 0) {
perror ("Error binding socket"); perror ("Error binding socket");
syslog(LOG_ALERT, "could not bind to port %d", port);
return -1; return -1;
} else {
syslog(LOG_NOTICE, "listening for queries on port %d", port);
} }
return sock; return sock;
@@ -65,14 +74,14 @@ sock_create_inet_socket (unsigned short int port)
//int StartSocketServer() //int StartSocketServer()
int int
sock_create_server () sock_create_server (char *bind_addr, int lcd_port)
{ {
int sock; int sock;
debug ("sock_create_server()\n"); debug ("sock_create_server()\n");
/* Create the socket and set it up to accept connections. */ /* Create the socket and set it up to accept connections. */
sock = sock_create_inet_socket (LCDPORT); sock = sock_create_inet_socket (bind_addr, lcd_port);
if (sock < 0) { if (sock < 0) {
perror ("sock_create_server: Error creating socket"); perror ("sock_create_server: Error creating socket");
return -1; return -1;
@@ -80,6 +89,7 @@ sock_create_server ()
if (listen (sock, 1) < 0) { if (listen (sock, 1) < 0) {
perror ("sock_create_server: Listen error"); perror ("sock_create_server: Listen error");
syslog(LOG_ALERT, "error in attempting to listen to port");
return -1; return -1;
} }
@@ -107,6 +117,8 @@ sock_create_server ()
return sock; return sock;
} }
// Service all clients with input pending...
int int
sock_poll_clients () sock_poll_clients ()
{ {
@@ -140,9 +152,12 @@ sock_poll_clients ()
new = accept (orig_sock, (struct sockaddr *) &clientname, &size); new = accept (orig_sock, (struct sockaddr *) &clientname, &size);
if (new < 0) { if (new < 0) {
perror ("sock_poll_clients: Accept error"); perror ("sock_poll_clients: Accept error");
syslog(LOG_WARNING, "error in accepting client");
return -1; return -1;
} }
debug ("sock_poll_clients: connect from host %s, port %hd.\n", inet_ntoa (clientname.sin_addr), ntohs (clientname.sin_port)); debug ("sock_poll_clients: connect from host %s, port %hd.\n", inet_ntoa (clientname.sin_addr), ntohs (clientname.sin_port));
syslog(LOG_NOTICE, "connect from host %s:%hd on #%d",
inet_ntoa (clientname.sin_addr), ntohs (clientname.sin_port), new);
FD_SET (new, &active_fd_set); FD_SET (new, &active_fd_set);
fcntl (new, F_SETFL, O_NONBLOCK); fcntl (new, F_SETFL, O_NONBLOCK);
@@ -168,6 +183,7 @@ sock_poll_clients ()
close (i); close (i);
FD_CLR (i, &active_fd_set); FD_CLR (i, &active_fd_set);
debug ("sock_poll_clients: Closed connection %i\n", i); debug ("sock_poll_clients: Closed connection %i\n", i);
syslog(LOG_NOTICE, "closed connection #%i", i);
} else } else
fprintf (stderr, "sock_poll_clients: Can't find client %i\n", i); fprintf (stderr, "sock_poll_clients: Can't find client %i\n", i);
} }
@@ -186,22 +202,22 @@ read_from_client (int filedes)
int nbytes, i; int nbytes, i;
client *c; client *c;
// nbytes = read (filedes, buffer, MAXMSG); //nbytes = read (filedes, buffer, MAXMSG);
//debug("read_from_client(%i): reading...\n", filedes); //debug("read_from_client(%i): reading...\n", filedes);
nbytes = sock_recv (filedes, buffer, MAXMSG); //nbytes = sock_recv (filedes, buffer, MAXMSG);
//debug("read_from_client(%i): ...done\n", filedes); //debug("read_from_client(%i): ...done\n", filedes);
debug ("read_from_client(%i): %i bytes\n", filedes, nbytes); //debug ("read_from_client(%i): %i bytes\n", filedes, nbytes);
if (nbytes < 0) // Read error? No data available? errno = 0;
{ if ((nbytes = sock_recv (filedes, buffer, MAXMSG)) < 0) {
// TODO: check errno here! if (errno != EAGAIN)
//fprintf (stderr,"read_from_client: Read error\n"); fprintf (stderr, "read_from_client: (fd %d) %s\n", filedes, strerror(errno));
return 0; return 0;
} else if (nbytes == 0) // EOF } else if (nbytes == 0) // EOF
return -1; return -1;
else if (nbytes > (MAXMSG - (MAXMSG / 8))) // Very noisy client... else if (nbytes > (MAXMSG - (MAXMSG / 8))) // Very noisy client...
{ {
sock_send_string (filedes, "huh? Shut up!\n"); sock_send_string (filedes, "huh? Too much data received... quiet down!\n");
return -1; return -1;
} else // Data Read } else // Data Read
{ {
@@ -229,16 +245,28 @@ read_from_client (int filedes)
int int
sock_close_all () sock_close_all ()
{ {
int i; int fd;
debug ("sock_close_all()\n"); debug ("sock_close_all()\n");
for (i = 0; i < FD_SETSIZE; i++) { for (fd = 0; fd < FD_SETSIZE; fd++) {
// TODO: Destroy a "client" here...? Nope. // TODO: Destroy a "client" here...? Nope.
sock_send_string (i, "bye\n");
close (i); // Instead of using STDIN_FILENO, STDOUT_FILENO,
FD_CLR (i, &active_fd_set); // and STDERR_FILENO, one could use "fd = 4" in the
debug ("sock_close_all: Closed connection %i\n", i); // for() call - but this would probably not be good
// practice...
if ( fd == STDIN_FILENO ||
fd == STDOUT_FILENO ||
fd == STDERR_FILENO)
continue;
else {
//sock_send_string (fd, "bye\n");
close (fd);
FD_CLR (fd, &active_fd_set);
debug ("sock_close_all: Closed connection %i\n", fd);
}
} }
return 0; return 0;
+8 -5
View File
@@ -167,6 +167,7 @@ widget_add (screen * s, char *id, char *type, char *in, int sock)
s->heartbeat = 1; s->heartbeat = 1;
return 0; return 0;
} }
// Make sure this screen doesn't already exist... // Make sure this screen doesn't already exist...
w = widget_find (s, id); w = widget_find (s, id);
if (w) { if (w) {
@@ -193,13 +194,16 @@ widget_add (screen * s, char *id, char *type, char *in, int sock)
} }
} }
} }
// Make sure it's a valid widget type // Make sure it's a valid widget type
for (i = 1; types[i]; i++) { for (i = 1; types[i]; i++) {
if (0 == strcmp (types[i], type)) { if (0 == strcmp (types[i], type)) {
valid = 1; valid = 1;
wid_type = i; wid_type = i;
break; // it's valid: skip out...
} }
} }
if (!valid) { if (!valid) {
// invalid widget type // invalid widget type
sock_send_string (sock, "huh? Invalid widget type\n"); sock_send_string (sock, "huh? Invalid widget type\n");
@@ -233,6 +237,7 @@ widget_add (screen * s, char *id, char *type, char *in, int sock)
} }
} }
} }
// TODO: Check for errors here? // TODO: Check for errors here?
LL_Push (list, (void *) w); LL_Push (list, (void *) w);
@@ -266,15 +271,13 @@ widget_remove (screen * s, char *id, int sock)
return 1; return 1;
} }
/* // TODO: Check for errors here?
// TODO: Check for errors here? // TODO: Make this work with frames...
// TODO: Make this work with frames...
// LL_Remove(list, (void *)w); // LL_Remove(list, (void *)w);
// TODO: Check for errors here? // TODO: Check for errors here?
// widget_destroy(w); // widget_destroy(w);
*/
return widget_remover (list, w); return widget_remover (list, w);