Big changes in code of clients, screens and widgets.

- Moved and altered code to create, destroy and manipulate clients, screens
  and widgets in an OO-like manner.
- Moved command execution code to a commands directory, splitting commands to
  what subject they are concerned.
- Menus are temporary disabled while working on new menu structure.
This commit is contained in:
robijn
2002-04-26 00:00:31 +00:00
parent 1e4ab6d501
commit 726f2f995e
43 changed files with 3161 additions and 3510 deletions
+1
View File
@@ -159,6 +159,7 @@ LCD_DRIVERS_SELECT
AC_OUTPUT(Makefile
shared/Makefile
server/Makefile
server/commands/Makefile
server/drivers/Makefile
clients/Makefile
clients/lcdproc/Makefile
+3 -3
View File
@@ -1,5 +1,5 @@
SUBDIRS=drivers
SUBDIRS=drivers commands
sbin_PROGRAMS=LCDd
LCDd_SOURCES= client_data.c client_data.h client_functions.c client_functions.h client_menu.h clients.c clients.h input.c input.h main.c main.h menu.c menu.h menus.c menus.h parse.c parse.h render.c render.h screen.c screen.h screenlist.c screenlist.h serverscreens.c serverscreens.h sock.c sock.h widget.c widget.h configfile.c configfile.h drivers.c drivers.h driver.c driver.h
LCDd_LDADD = ../shared/libLCDstuff.a
LCDd_SOURCES= client.c client.h clients.c clients.h client_menu.h input.c input.h main.c main.h event.h menu.c menu.h menuscreens.c menuscreens.h parse.c parse.h render.c render.h screen.c screen.h screenlist.c screenlist.h serverscreens.c serverscreens.h sock.c sock.h widget.c widget.h configfile.c configfile.h drivers.c drivers.h driver.c driver.h
LCDd_LDADD = ../shared/libLCDstuff.a commands/libLCDcommands.a
INCLUDES = -I$(top_srcdir)
+263
View File
@@ -0,0 +1,263 @@
/*
* client_data.h
* This file is part of LCDd, the lcdproc server.
*
* This file is released under the GNU General Public License. Refer to the
* COPYING file distributed with this package.
*
* Copyright (c) 1999, William Ferrell, Scott Scriven
* 2002, Joris Robijn
*
*/
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include "config.h"
#include "client.h"
#include "screenlist.h"
#include "render.h"
#include "shared/report.h"
#include "shared/LL.h"
Client * client_create (int sock)
{
Client *c;
debug (RPT_DEBUG, "new_client(%i)", sock);
/* Allocate new client...*/
c = malloc (sizeof (Client));
if (!c) {
report (RPT_ERR, "client_create: Error allocating");
return NULL;
}
/* Init struct members*/
c->sock = sock;
c->messages = NULL;
c->backlight = BACKLIGHT_OPEN;
c->heartbeat = HEARTBEAT_OPEN;
/*Set up message list...*/
c->messages = LL_new ();
if (!c->messages) {
report (RPT_ERR, "client_create: Error allocating");
free (c);
return NULL;
}
c->ack = 0;
c->name = NULL;
c->client_keys = NULL;
c->screenlist = LL_new();
if (!c->screenlist) {
report( RPT_ERR, "client_create: Error allocating");
return NULL;
}
return c;
}
int
client_destroy (Client * c)
{
//int err;
Screen *s;
debug (RPT_INFO, "client_destroy()");
if (!c)
return -1;
client_close_sock (c);
/*Free client's other data*/
c->ack = 0;
/* Clean up the name...*/
if (c->name)
free (c->name);
/* Clean up the key list...*/
//if (d->client_keys)
// free (d->client_keys);
/* Clean up the screenlist...*/
debug( RPT_DEBUG, "client_data_destroy: Cleaning screenlist");
for( s=LL_GetFirst (c->screenlist); s; s=LL_GetNext(c->screenlist) ) {
debug( RPT_DEBUG, "client_data_destroy: removing screen %s", s->id);
/* FIXME? This shouldn't be handled here...
* Now, remove it from the screenlist...*/
if (screenlist_remove_all (s) < 0) {
/* Not a serious error..*/
report( RPT_ERR, "client_data_destroy: Error dequeueing screen");
return 0;
}
/* Free its memory...*/
screen_destroy (s);
/* Note that the screen is not removed from the list because
* the list will be destroyed anyway...
*/
}
LL_Destroy( c->screenlist);
/* Remove structure */
free (c);
return 0;
}
void client_close_sock (Client * c)
{
char *str;
if (c->sock == EOF )
return;
/*Eat the rest of the incoming requests...*/
debug (RPT_DEBUG, "client_destroy: get_messages");
while ((str = client_get_message (c))) {
if (str) {
debug (RPT_DEBUG, "client_destroy: kill message %s", str);
free (str);
}
}
/*close socket...*/
if (c->sock) {
/*sock_send_string (c->sock, "bye\n");*/
close(c->sock);
report(RPT_NOTICE, "closed socket for #%d", c->sock);
}
c->sock = EOF;
}
/*Add and remove messages from the client's queue...*/
int
client_add_message (Client * c, char *message)
{
int err = 0;
char *dup;
char *str, *cp;
char delimiters[] = "\n\r\0";
/* int len;*/
debug(RPT_DEBUG, "client_add_message(%s)", message);
if (!c)
return -1;
if (!message)
return -1;
/* len = strlen(message);
* if(len < 1) return 0;
*/
/* Copy the string to avoid overwriting the original...*/
dup = strdup (message);
if (!dup) {
report(RPT_ERR, "client_add_message: Error allocating");
return -1;
}
/* Now split the string into lines and enqueue each one...*/
for (str = strtok (dup, delimiters); str; str = strtok (NULL, delimiters)) {
cp = strdup (str);
debug (RPT_DEBUG, "client_add_message: %s", cp);
err += LL_Enqueue (c->messages, (void *) cp);
}
/*debug(RPT_DEBUG, "client_add_message(%s): %i errors", message, err);*/
free (dup); /* Fixed memory leak...*/
/* Err is the number of errors encountered...*/
return err;
}
/* Woo-hoo! A simple function. :)*/
char *
client_get_message (Client * c)
{
char *str;
debug(RPT_DEBUG, "client_get_message()");
if (!c)
return NULL;
str = (char *) LL_Dequeue (c->messages);
/*debug(RPT_DEBUG, "client_get_message: \"%s\"", str);*/
return str;
}
Screen *
client_find_screen (Client * c, char *id)
{
Screen *s;
if (!c)
return NULL;
if (!id)
return NULL;
debug (RPT_INFO, "client_find_screen(%s)", id);
LL_Rewind (c->screenlist);
do {
s = LL_Get (c->screenlist);
if ((s) && (0 == strcmp (s->id, id))) {
debug (RPT_DEBUG, "client_find_screen: Found %s", id);
return s;
}
} while (LL_Next (c->screenlist) == 0);
return NULL;
}
int
client_add_screen (Client * c, Screen * s)
{
/* TODO: Check for errors here?*/
LL_Push (c->screenlist, (void *) s);
/* Now, add it to the screenlist...*/
if (screenlist_add (s) < 0) {
report (RPT_ERR, "client_add_screen: Error queueing new screen");
return -1;
}
return 0;
}
int
client_remove_screen (Client * c, Screen * s)
{
if (!c)
return -1;
if (!s)
return -1;
/* TODO: Check for errors here?*/
LL_Remove (c->screenlist, (void *) s);
/* Now, remove it from the screenlist...*/
if (screenlist_remove_all (s) < 0) {
/* Not a serious error..*/
report (RPT_ERR, "client_remove_screen: Error dequeueing screen");
return 0;
}
return 0;
}
int client_screen_count (Client * c)
{
return LL_Length(c->screenlist);
}
+59
View File
@@ -0,0 +1,59 @@
#ifndef CLIENT_H
#define CLIENT_H
#include "shared/LL.h"
#include <stdio.h>
#define CLIENT_NAME_SIZE 256
typedef struct Client {
char *name;
int ack;
int sock;
char addr[64];
int backlight;
int heartbeat;
LinkedList *messages;
/* and other stuff... doesn't matter yet*/
LinkedList *screenlist;
/* TO BE REMOVED */
char *client_keys;
/* list of requested keys */
//LinkedList *keylist;
/* list of client supplied menus */
//LinkedList *menulist;
} Client;
#include "screen.h"
/* When a new client connects, set up a new client data struct */
Client * client_create (int sock);
/* Destroys the client data */
int client_destroy (Client * c);
/* Close the socket */
void client_close_sock (Client * c);
/* Add message to the client's queue...*/
int client_add_message (Client * c, char *message);
/* Get message from queue */
char * client_get_message (Client * c);
/* Find a named screen for the client */
Screen * client_find_screen (Client * c, char *id);
int client_add_screen (Client * c, Screen * s);
int client_remove_screen (Client * c, Screen * s);
int client_screen_count (Client * c);
#endif
-102
View File
@@ -1,102 +0,0 @@
/*
* client_data.c
* This file is part of LCDd, the lcdproc server.
*
* This file is released under the GNU General Public License. Refer to the
* COPYING file distributed with this package.
*
* Copyright (c) 1999, William Ferrell, Scott Scriven
*
*
* Creates and destroys a client's data structures. These are mainly
* its name, screen list, and menu list.
*
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "shared/report.h"
#include "client_data.h"
#include "screen.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
client_data_init (client_data * d)
{
if (!d)
return -1;
d->ack = 0;
d->name = NULL;
d->client_keys = NULL;
d->screenlist = NewScreen();
if (!d->screenlist) {
report( RPT_ERR, "client_data_init: Error allocating screenlist");
return -1;
}
/* TODO: this section... (client menus)
d->menulist = LL_new();
if(!d->menulist)
{
report( RPT_ERR, "client_data_init: Error allocating menulist");
return -1;
}
*/
return 0;
}
int
client_data_destroy (client_data * d)
{
screen *s;
report( RPT_INFO, "client_data_destroy");
if (!d)
return -1;
d->ack = 0;
/* Clean up the name...*/
if (d->name)
free (d->name);
/* Clean up the key list...*/
if (d->client_keys)
free (d->client_keys);
/* Clean up the screenlist...*/
debug( RPT_DEBUG, "client_data_destroy: Cleaning screenlist");
ResetScreenList (d->screenlist);
do {
s = NextScreen(d->screenlist);
if (s) {
debug( RPT_DEBUG, "client_data_destroy: removing screen %s", s->id);
/* FIXME? This shouldn't be handled here...
* Now, remove it from the screenlist...*/
if (screenlist_remove_all (s) < 0) {
/* Not a serious error..*/
report( RPT_ERR, "client_data_destroy: Error dequeueing screen");
return 0;
}
/* Free its memory...*/
screen_destroy (s);
}
} while (MoreScreens(d->screenlist));
DestroyScreenList(d->screenlist);
/* TODO: clean up the rest of the data...*/
return 0;
}
-35
View File
@@ -1,35 +0,0 @@
/*
* client_data.h
* This file is part of LCDd, the lcdproc server.
*
* This file is released under the GNU General Public License. Refer to the
* COPYING file distributed with this package.
*
* Copyright (c) 1999, William Ferrell, Scott Scriven
*
*/
#ifndef CLIENT_DATA_H
#define CLIENT_DATA_H
#include "shared/LL.h"
#define CLIENT_NAME_SIZE 256
typedef struct client_data {
int ack;
char *name;
/* and other stuff... doesn't matter yet*/
LinkedList *screenlist;
/* list of requested keys...*/
char *client_keys ;
LinkedList *menulist;
} client_data;
/* sets up an existing (empty) client_data struct*/
int client_data_init (client_data * d);
/* destroys members of a client's data*/
int client_data_destroy (client_data * d);
#endif
File diff suppressed because it is too large Load Diff
-51
View File
@@ -1,51 +0,0 @@
/*
* client_functions.h
* This file is part of LCDd, the lcdproc server.
*
* This file is released under the GNU General Public License. Refer to the
* COPYING file distributed with this package.
*
* Copyright (c) 1999, William Ferrell, Scott Scriven
*
*/
#ifndef CLIENT_FUNCTION_H
#define CLIENT_FUNCTION_H
/*
The function list for clients is stored in a table, and the items each
point to a function to call, defined below.
*/
typedef struct client_function {
char *keyword;
int (*function) (client * c, int argc, char **argv);
} client_function;
/* FIXME? Do these really need to be visible from other sources?*/
int test_func_func (client * c, int argc, char **argv);
int hello_func (client * c, int argc, char **argv);
int client_set_func (client * c, int argc, char **argv);
int client_add_key_func (client * c, int argc, char **argv);
int client_del_key_func (client * c, int argc, char **argv);
int screen_add_key_func (client * c, int argc, char **argv);
int screen_del_key_func (client * c, int argc, char **argv);
int screen_add_func (client * c, int argc, char **argv);
int screen_del_func (client * c, int argc, char **argv);
int screen_set_func (client * c, int argc, char **argv);
int widget_add_func (client * c, int argc, char **argv);
int widget_del_func (client * c, int argc, char **argv);
int widget_set_func (client * c, int argc, char **argv);
int menu_add_func (client * c, int argc, char **argv);
int menu_del_func (client * c, int argc, char **argv);
int menu_set_func (client * c, int argc, char **argv);
int menu_add_item_func (client * c, int argc, char **argv);
int menu_del_item_func (client * c, int argc, char **argv);
int menu_set_item_func (client * c, int argc, char **argv);
int backlight_func (client * c, int argc, char **argv);
int output_func (client * c, int argc, char **argv);
int noop_func (client * c, int argc, char **argv);
extern client_function commands[];
#endif
+59 -197
View File
@@ -6,14 +6,12 @@
* COPYING file distributed with this package.
*
* Copyright (c) 1999, William Ferrell, Scott Scriven
* 2002, Joris Robijn
*
*
* Inits/shuts down client system,
* creates/destroys individual clients,
* enqueues/dequeues messages from clients,
* and searches for clients in the list.
*
* :)
* On short: manages the list of clients that are connected.
*
*/
@@ -23,21 +21,21 @@
#include <string.h>
#include "sock.h"
#include "client.h"
#include "clients.h"
#include "client_data.h"
#include "shared/report.h"
#include "render.h"
LinkedList *clients;
LinkedList *clientlist;
/* Initialize and kill client list...*/
int
client_init ()
clients_init ()
{
debug(RPT_INFO, "client_init()");
clients = LL_new ();
if (!clients) {
clientlist = LL_new ();
if (!clientlist) {
report( RPT_ERR, "client_init: Unable to create client list");
return -1;
}
@@ -46,220 +44,84 @@ client_init ()
}
int
client_shutdown ()
clients_shutdown ()
{
client *c;
Client *c;
debug (RPT_INFO, "client_shutdown()");
debug (RPT_INFO, "clients_shutdown()");
/* Free all client structures...
* Note that the regular list loop doesn't work here, because
* client_destroy() calls LL_Remove()
*/
for (c = LL_Pop (clients); c; c = LL_Pop (clients)) {
debug (RPT_DEBUG, "client_shutdown: ...");
/* Free all client structures... */
for (c=LL_GetFirst (clientlist); c; c=LL_GetNext (clientlist) ) {
debug (RPT_DEBUG, "clients_shutdown: ...");
if (c) {
debug (RPT_DEBUG, "client_shutdown: ... %i ...", c->sock);
debug (RPT_DEBUG, "clients_shutdown: ... %i ...", c->sock);
if (client_destroy (c) != 0) {
report (RPT_ERR, "client_shutdown: Error freeing client");
report (RPT_ERR, "clients_shutdown: Error freeing client");
} else {
debug (RPT_DEBUG, "client_shutdown: Freed client...");
debug (RPT_DEBUG, "clients_shutdown: Freed client...");
}
} else {
debug (RPT_DEBUG, "client_shutdown: No client!");
debug (RPT_DEBUG, "clients_shutdown: No client!");
}
}
/* Then, free the list...*/
LL_Destroy (clients);
LL_Destroy (clientlist);
debug (RPT_DEBUG, "client_shutdown: done");
debug (RPT_DEBUG, "clients_shutdown: done");
return 0;
}
int
clients_add_client (Client *c)
{
/* Add the client to the clients list... */
return LL_Push (clientlist, c);
}
int
clients_remove_client (Client *c)
{
/* Remove the client from the clients list... */
return (LL_Remove (clientlist, c) == NULL)?-1:0;
}
Client *
clients_getfirst ()
{
return (Client *) LL_GetFirst(clientlist);
}
Client *
clients_getnext ()
{
return (Client *) LL_GetNext(clientlist);
}
int
clients_client_count ()
{
return LL_Length(clientlist);
}
/* A client is identified by the file descriptor
+ associated with it.
*
* Create and destroy clients....
*/
client *
client_create (int sock)
{
client *c;
debug (RPT_DEBUG, "client_create(%i)", sock);
/* Allocate new client...*/
c = malloc (sizeof (client));
if (!c) {
report (RPT_ERR, "client_create: error allocating new client");
return NULL;
}
/* Init struct members*/
c->sock = 0;
c->data = NULL;
c->messages = NULL;
c->sock = sock;
c->backlight_state = backlight; /*By default we get the server setting*/
/*Set up message list...*/
c->messages = LL_new ();
if (!c->messages) {
report (RPT_ERR, "client_create: error allocating message list");
free (c);
return NULL;
}
/*TODO: allocate and init client data...*/
c->data = malloc (sizeof (client_data));
if (!c->data) {
report (RPT_ERR, "client_create: error allocating client data");
free (c->messages);
free (c);
return NULL;
} else if (client_data_init (c->data) < 0) {
return NULL;
}
/*TODO: Check for errors while adding the client to the list?*/
LL_Push (clients, (void *) c);
return c;
}
int
client_destroy (client * c)
{
int err;
char *str;
debug (RPT_INFO, "client_destroy()");
if (!c)
return -1;
/*Eat the rest of the incoming requests...*/
debug (RPT_DEBUG, "client_destroy: get_messages");
while ((str = client_get_message (c))) {
if (str) {
debug (RPT_DEBUG, "client_destroy: kill message %s", str);
free (str);
}
}
/*close socket...*/
if (c->sock) {
/*sock_send_string (c->sock, "bye\n");*/
close(c->sock);
report(RPT_NOTICE, "closed socket for #%d", c->sock);
}
err = LL_Destroy (c->messages);
/*Free client's other data*/
client_data_destroy (c->data);
/*Remove the client from the clients list...*/
LL_Remove (clients, c);
free (c);
return 0;
}
/*Add and remove messages from the client's queue...*/
int
client_add_message (client * c, char *message)
{
int err = 0;
char *dup;
char *str, *cp;
char delimiters[] = "\n\r\0";
/* int len;*/
debug(RPT_DEBUG, "client_add_message(%s)", message);
if (!c)
return -1;
if (!message)
return -1;
/* len = strlen(message);
* if(len < 1) return 0;
* associated with it. Find one.
*/
/* Copy the string to avoid overwriting the original...*/
dup = strdup (message);
if (!dup) {
report(RPT_ERR, "client_add_message: Error allocating new string");
return -1;
}
/* Now split the string into lines and enqueue each one...*/
for (str = strtok (dup, delimiters); str; str = strtok (NULL, delimiters)) {
cp = strdup (str);
debug (RPT_DEBUG, "client_add_message: %s", cp);
err += LL_Enqueue (c->messages, (void *) cp);
}
/*debug(RPT_DEBUG, "client_add_message(%s): %i errors", message, err);*/
free (dup); /* Fixed memory leak...*/
/* Err is the number of errors encountered...*/
return err;
}
/* Woo-hoo! A simple function. :)*/
char *
client_get_message (client * c)
Client *
clients_find_client_by_sock (int sock)
{
char *str;
Client *c;
debug(RPT_DEBUG, "client_get_message()");
debug(RPT_INFO, "clients_find_client_by_sock(%i)", sock);
if (!c)
return NULL;
str = (char *) LL_Dequeue (c->messages);
/*debug(RPT_DEBUG, "client_get_message: \"%s\"", str);*/
return str;
}
/* Get and set the client's data...*/
int
client_set (client * c, void *data)
{
/* You know, I really doubt this function will be useful...*/
return 0;
}
void *
client_get (client * c)
{
/* But this one might be handy...*/
return NULL;
}
client *
client_find_sock (int sock)
{
client *c;
/* debug(RPT_INFO, "client_find_sock(%i)", sock);*/
LL_Rewind (clients);
do {
c = (client *) LL_Get (clients);
/* debug(RPT_DEBUG, "client_find_sock: ... %i ...", c->sock);*/
for( c=LL_GetFirst(clientlist); c; c=LL_GetNext(clientlist) ) {
if (c->sock == sock) {
/* debug(RPT_DEBUG, "client_find_sock: ..! %i !..", c->sock);*/
return c;
}
} while (LL_Next (clients) == 0);
}
debug (RPT_ERR, "client_find_sock: failed");
+12 -26
View File
@@ -12,39 +12,25 @@
#ifndef CLIENTS_H
#define CLIENTS_H
#include "client_data.h"
#include "client.h"
#include "shared/LL.h"
typedef struct client {
int sock;
char addr[64];
int backlight_state;
LinkedList *messages;
client_data *data;
} client;
extern LinkedList *clients;
/* extern LinkedList *clientlist; Not needed outside ? */
/* Initialize and kill client list...*/
int client_init ();
int client_shutdown ();
int clients_init ();
int clients_shutdown ();
/* Create and destroy clients....*/
client *client_create (int sock);
int client_destroy (client * c);
/* Add/remove clients (return -1 for error) */
int clients_add_client (Client *c);
int clients_remove_client (Client *c);
/* Add and remove messages from the client's queue...*/
int client_add_message (client * c, char *message);
char *client_get_message (client * c);
/* Get and set the client's data...
* Not used at all yet, and may never be. Oh, well.
*/
int client_set (client * c, void *data);
void *client_get (client * c);
/* List functions */
Client * clients_getfirst ();
Client * clients_getnext ();
int clients_client_count ();
/* Search for a client with a particular filedescriptor...*/
client *client_find_sock (int sock);
Client * clients_find_client_by_sock (int sock);
#endif
+354
View File
@@ -0,0 +1,354 @@
/*
* client_commands.c
* This file is part of LCDd, the lcdproc server.
*
* This file is released under the GNU General Public License. Refer to the
* COPYING file distributed with this package.
*
* Copyright (c) 1999, William Ferrell, Scott Scriven
* 2002, Joris Robijn
*
*
* This contains definitions for all the functions which clients can run.
* The functions here are to be called only from parse.c's interpreter.
*
* The client's available function set is defined here, as is the syntax
* for each command.
*
* This particular file defines actions concerning clients.
*
*/
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include "shared/report.h"
#include "shared/sockets.h"
#include "drivers.h"
#include "render.h"
#include "client.h"
/***************************************************************
* Debugging only.. prints out a list of arguments it receives
*/
int
test_func_func (Client * c, int argc, char **argv)
{
int i;
char str[256];
for (i = 0; i < argc; i++) {
snprintf (str, sizeof(str), "test_func_func: %i -> %s\n", i, argv[i]);
report (RPT_INFO, str);
sock_send_string (c->sock, str);
}
return 0;
}
/***************************************************************
* The client must say "hello" before doing anything else.
*
* It returns a string of info about the server to the client
*
* usage: hello
*/
int
hello_func (Client * c, int argc, char **argv)
{
char str[256];
/* TODO: Give *real* info about the server/lcd...*/
if (argc > 1) {
sock_send_string (c->sock, "huh? extra parameters ignored\n");
}
debug(RPT_INFO, "Hello!");
memset(str, '\0', sizeof(str));
snprintf (str, sizeof(str), "connect LCDproc %s protocol %s lcd wid %i hgt %i cellwid %i cellhgt %i\n",
VERSION, PROTOCOL_VERSION, display_props->width, display_props->height, display_props->cellwidth, display_props->cellheight);
/* lcdproc (client) depends on the above format...
* snprintf (str, sizeof(str), "connect LCDproc %s protocol %s LCD %ix%i with cells %ix%i\n",
* version, protocol_version, lcd.wid, lcd.hgt, lcd.cellwid, lcd.cellhgt);
*/
sock_send_string (c->sock, str);
c->ack = 1;
return 0;
}
/***************************************************
* sets info about the client, such as its name
*
* usage: client_set -name <id>
*/
int
client_set_func (Client * c, int argc, char **argv)
{
int i;
char str[16], buf[80];
memset(str, '\0', sizeof(str));
if (!c->ack)
return 1;
if (argc != 3) {
switch (argc) {
case 1:
sock_send_string (c->sock, "huh? usage: client_set -name <name>\n");
break;
case 2:
sock_send_string (c->sock, "huh? Not enough parameters\n");
break;
default:
sock_send_string (c->sock, "huh? Too many parameters\n");
break;
}
return 0;
}
i = 1;
do {
char *p;
/* This bit of code means that "-name" is the same as "name"...*/
p = argv[i];
if (*p == '-')
p++;
/* Handle the "name" parameter*/
if (strcmp (p, "name") == 0) {
i++;
if (argv[i] == '\0') {
snprintf (buf, sizeof(buf), "huh? internal error: no parameter #%d\n", i);
sock_send_string (c->sock, buf);
continue;
}
if (strlen(argv[i]) > sizeof(str) -1) {
sock_send_string (c->sock, "huh? name too long\n");
} else {
strncpy(str, argv[i], sizeof(str) - 1);
debug(RPT_DEBUG, "client_set: name=\"%s\"", argv[i]);
/* set the name...*/
if (c->name)
free (c->name);
if ((c->name = strdup (str)) == NULL) {
sock_send_string(c->sock, "huh? error allocating memory!\n");
} else {
sock_send_string(c->sock, "success\n");
i++; /* bypass argument (name string)*/
}
}
} else {
snprintf (buf, sizeof(buf), "huh? invalid parameter (%s)\n", p);
sock_send_string (c->sock, buf);
}
} while (++i < argc);
return 0;
}
/******************************************************************
* Tells the server the client would like to accept keypresses
* of a particular type
*
* usage: client_add_key <keylist>
*/
int
client_add_key_func (Client * c, int argc, char **argv)
{
char * keys ;
if (!c->ack)
return 1;
if (argc != 2) {
switch (argc) {
case 1:
sock_send_string (c->sock, "huh? usage: client_add_key <keylist>\n");
break;
default:
sock_send_string (c->sock, "huh? Too many parameters...\n");
break;
}
return 0;
}
keys = argv[1];
debug(RPT_DEBUG, "client_add_key: current client will handle key(s) %s", keys);
if (!c->client_keys) {
/* No keys list, create a new one*/
c->client_keys = strdup( keys );
} else {
/* Add supplied keys to existing list
* NOTE: There could be duplicates in the resulting list
* That's OK, it's the existence of the key in the list
* that's important. We'll be more careful in the delete
* key function.
*/
char * new ;
int new_len = strlen(c->client_keys) + strlen(keys) + 1 ;
new = realloc( c->client_keys, new_len );
if( new ) {
c->client_keys = new ;
strcat( new, keys );
} else {
sock_send_string(c->sock, "huh? could not allocate memory for new keys\n");
return 0;
}
}
if (c->client_keys) {
sock_send_string(c->sock, "success\n");
} else {
sock_send_string(c->sock, "huh? failed\n");
}
return 0;
}
/*********************************************************************
* Tells the server the client would NOT like to accept keypresses
* of a particular type
*
* usage: client_del_key <keylist>
*/
int
client_del_key_func (Client * c, int argc, char **argv)
{
char * keys ;
if (!c->ack)
return 1;
if (argc != 2) {
if (argc == 1) {
sock_send_string (c->sock, "huh? usage: client_del_key <keylist>\n");
return 0;
} else {
sock_send_string (c->sock, "huh? Too many parameters...\n");
return 0;
}
}
keys = argv[1] ;
debug(RPT_DEBUG, "client_del_key: Deleting key(s) %s from client_keys", keys);
if (c->client_keys) {
/* Client has keys, remove keys from the list
* NOTE: We let malloc/realloc remember the length
* of the allocated storage. If keys are later
* added, realloc (in add_key above) will make
* sure there is enough space at c->data->client_keys
*/
char * from ;
char * to ;
to = from = c->client_keys ;
while( *from ) {
/* Is this key to be deleted from the list?*/
if( strchr( keys, *from ) ) {
/* Yes, skip it*/
++from ;
} else {
/* No, save it*/
*to++ = *from++ ;
}
}
}
sock_send_string(c->sock, "success\n");
return 0;
}
/***************************************************************************
* Toggles the backlight, if enabled.
*
* usage: backlight <on|off|toggle|blink|flash>
*/
int
backlight_func (Client * c, int argc, char **argv)
{
if (!c->ack)
return 1;
if (argc != 2) {
switch (argc) {
case 1:
sock_send_string (c->sock, "huh? usage: backlight <on|off|toggle|blink|flash>\n");
break;
default:
sock_send_string (c->sock, "huh? Too many parameters...\n");
break;
}
return 0;
}
debug (RPT_DEBUG, "backlight(%s)", argv[1]);
//backlight = (backlight && 1); /* only preserves ON/OFF bit*/
if (strcmp ("on", argv[1]) == 0) {
c->backlight = BACKLIGHT_ON;
} else if (strcmp ("off", argv[1]) == 0) {
c->backlight = BACKLIGHT_OFF;
} else if (strcmp ("toggle", argv[1]) == 0) {
if (c->backlight == BACKLIGHT_ON)
c->backlight = BACKLIGHT_OFF;
else if (c->backlight == BACKLIGHT_OFF)
c->backlight = BACKLIGHT_ON;
} else if (strcmp ("blink", argv[1]) == 0) {
c->backlight |= BACKLIGHT_BLINK;
} else if (strcmp ("flash", argv[1]) == 0) {
c->backlight |= BACKLIGHT_FLASH;
}
sock_send_string(c->sock, "success\n");
return 0;
}
/****************************************************************************
* info_func
*
* usage: info
*/
int
info_func (Client * c, int argc, char **argv)
{
char str[1024];
if (argc > 1) {
sock_send_string (c->sock, "huh? Extra arguments ignored...\n");
}
memset(str, '\0', sizeof(str));
snprintf (str, sizeof(str)-1, (char*) drivers_get_info());
sock_send_string (c->sock, str);
return 0;
}
+22
View File
@@ -0,0 +1,22 @@
/*
* client_commands.h
* This file is part of LCDd, the lcdproc server.
*
* This file is released under the GNU General Public License. Refer to the
* COPYING file distributed with this package.
*
* Copyright (c) 1999, William Ferrell, Scott Scriven
* 2002, Joris Robijn
*
*/
#ifndef COMMANDS_CLIENT_H
#define COMMANDS_CLIENT_H
int hello_func (Client * c, int argc, char **argv);
int client_set_func (Client * c, int argc, char **argv);
int client_add_key_func (Client * c, int argc, char **argv);
int client_del_key_func (Client * c, int argc, char **argv);
int backlight_func (Client * c, int argc, char **argv);
#endif
+55
View File
@@ -0,0 +1,55 @@
/*
* commands/command_list.c
* This file is part of LCDd, the lcdproc server.
*
* This file is released under the GNU General Public License. Refer to the
* COPYING file distributed with this package.
*
* Copyright (c) 1999, William Ferrell, Scott Scriven
*
*
* This contains definitions for all the functions which clients can run.
* The functions here are to be called only from parse.c's interpreter.
*
* The client's available function set is defined here, as is the syntax
* for each command.
*
*/
#include "command_list.h"
#include "server_commands.h"
#include "client_commands.h"
#include "screen_commands.h"
#include "widget_commands.h"
#include "menu_commands.h"
#include <stdlib.h>
client_function commands[] = {
{"test_func", test_func_func},
{"hello", hello_func},
{"client_set", client_set_func},
{"client_add_key", client_add_key_func},
{"client_del_key", client_del_key_func},
/* {"screen_add_key", screen_add_key_func}, */
/* {"screen_del_key", screen_del_key_func}, */
{"screen_add", screen_add_func},
{"screen_del", screen_del_func},
{"screen_set", screen_set_func},
{"widget_add", widget_add_func},
{"widget_del", widget_del_func},
{"widget_set", widget_set_func},
{"menu_add", menu_add_func},
{"menu_del", menu_del_func},
{"menu_set", menu_set_func},
{"menu_add_item", menu_add_item_func},
{"menu_del_item", menu_del_item_func},
{"menu_set_item", menu_set_item_func},
/* Misc stuff...*/
{"backlight", backlight_func},
{"output", output_func},
{"noop", noop_func},
{"info", info_func},
{"sleep", sleep_func},
{NULL, NULL},
};
+31
View File
@@ -0,0 +1,31 @@
/*
* commands/command_list.h
* This file is part of LCDd, the lcdproc server.
*
* This file is released under the GNU General Public License. Refer to the
* COPYING file distributed with this package.
*
* Copyright (c) 1999, William Ferrell, Scott Scriven
*
*/
#ifndef COMMANDS_COMMAND_LIST_H
#define COMMANDS_COMMAND_LIST_H
#include "../client.h"
/*
The function list for clients is stored in a table, and the items each
point to a function to call, defined below.
*/
typedef struct client_function {
char *keyword;
int (*function) (Client * c, int argc, char **argv);
} client_function;
/* FIXME? Do these really need to be visible from other sources?*/
extern client_function commands[];
#endif
+139
View File
@@ -0,0 +1,139 @@
/*
* menu_commands.c
* This file is part of LCDd, the lcdproc server.
*
* This file is released under the GNU General Public License. Refer to the
* COPYING file distributed with this package.
*
* Copyright (c) 1999, William Ferrell, Scott Scriven
* 2002, Joris Robijn
*
*
* This contains definitions for all the functions which clients can run.
* The functions here are to be called only from parse.c's interpreter.
*
* The client's available function set is defined here, as is the syntax
* for each command.
*
* This particular file defines actions concerning client supplied menus.
*
*/
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include "shared/report.h"
#include "shared/sockets.h"
#include "client.h"
/*************************************************************
* Adds a menu to the client; handled by the server...
*
* usage: menu_add ...?
*/
int
menu_add_func (Client * c, int argc, char **argv)
{
if (!c->ack)
return 1;
sock_send_string (c->sock, "huh? Not implemented yet.\n");
return 0;
}
/****************************************************************
* Removes a client's menu and all contents from the server
*
* usage: menu_del ...?
*/
int
menu_del_func (Client * c, int argc, char **argv)
{
if (!c->ack)
return 1;
sock_send_string (c->sock, "huh? Not implemented yet.\n");
return 0;
}
/***********************************************************************
* Sets info about a menu, but not its items
*
* For example, should the menu be top-level, or buried somewhere?
*
* usage: menu_set ...?
*/
int
menu_set_func (Client * c, int argc, char **argv)
{
if (!c->ack)
return 1;
sock_send_string (c->sock, "huh? Not implemented yet.\n");
return 0;
}
/*************************************************************************
* Adds an item to a menu
*
* usage: menu_add_item ...?
*/
int
menu_add_item_func (Client * c, int argc, char **argv)
{
if (!c->ack)
return 1;
sock_send_string (c->sock, "huh? Not implemented yet.\n");
return 0;
}
/*************************************************************************
* Deletes an item from a menu
*
+ usage: menu_del_item ...?
*/
int
menu_del_item_func (Client * c, int argc, char **argv)
{
if (!c->ack)
return 1;
sock_send_string (c->sock, "huh? Not implemented yet.\n");
return 0;
}
/**************************************************************************
* Sets the info about a menu item
*
* For example, text displayed, widget type, value, etc...
*
* usage: menu_set_item ...?
*/
int
menu_set_item_func (Client * c, int argc, char **argv)
{
if (!c->ack)
return 1;
sock_send_string (c->sock, "huh? Not implemented yet.\n");
return 0;
}
+23
View File
@@ -0,0 +1,23 @@
/*
* menu_commands.h
* This file is part of LCDd, the lcdproc server.
*
* This file is released under the GNU General Public License. Refer to the
* COPYING file distributed with this package.
*
* Copyright (c) 1999, William Ferrell, Scott Scriven
* 2002, Joris Robijn
*
*/
#ifndef COMMANDS_MENU_H
#define COMMANDS_MENU_H
int menu_add_func (Client * c, int argc, char **argv);
int menu_del_func (Client * c, int argc, char **argv);
int menu_set_func (Client * c, int argc, char **argv);
int menu_add_item_func (Client * c, int argc, char **argv);
int menu_del_item_func (Client * c, int argc, char **argv);
int menu_set_item_func (Client * c, int argc, char **argv);
#endif
+542
View File
@@ -0,0 +1,542 @@
/*
* screens_commands.c
* This file is part of LCDd, the lcdproc server.
*
* This file is released under the GNU General Public License. Refer to the
* COPYING file distributed with this package.
*
* Copyright (c) 1999, William Ferrell, Scott Scriven
* 2002, Joris Robijn
*
*
* This contains definitions for all the functions which clients can run.
* The functions here are to be called only from parse.c's interpreter.
*
* The client's available function set is defined here, as is the syntax
* for each command.
*
* This particular file defines actions concerning screens.
*
*/
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include "shared/report.h"
#include "shared/sockets.h"
#include "client.h"
#include "screen.h"
#include "render.h"
/***************************************************************
* Tells the server the client has another screen to offer
*
* usage: screen_add <id>
*/
int
screen_add_func (Client * c, int argc, char **argv)
{
int err = 0;
Screen * s;
if (!c->ack)
return 1;
if (argc != 2) {
switch (argc) {
case 1:
sock_send_string (c->sock, "huh? Usage: screen_add <screenid>\n");
break;
default:
sock_send_string (c->sock, "huh? Too many parameters...\n");
break;
}
return 0;
}
debug(RPT_DEBUG, "screen_add: Adding screen %s", argv[1]);
s = client_find_screen (c, argv[1]);
if (s) {
sock_send_string(c->sock, "huh? Screen already exists\n");
return 0;
}
s = screen_create (argv[1], c);
if (!s) {
report(RPT_ERR, "screen_add_func: Error creating screen");
sock_send_string (c->sock, "huh? failed to create screen\n");
return 0;
}
err = client_add_screen (c, s);
if (err == 0) {
sock_send_string(c->sock, "success\n");
} else {
report(RPT_WARNING, "screen_add_func: Error adding screen");
sock_send_string (c->sock, "huh? Failed to add screen\n");
}
report(RPT_NOTICE, "added a screen (%s) to the display", s->id);
return 0;
}
/****************************************************************
* Client requests that the server forget about a screen
*
* usage: screen_del <screenid>
*/
int
screen_del_func (Client * c, int argc, char **argv)
{
int err = 0;
Screen * s;
if (!c->ack)
return 1;
if (argc != 2) {
if (argc == 1)
sock_send_string (c->sock, "huh? Usage: screen_del <screenid>\n");
else
sock_send_string (c->sock, "huh? Too many parameters...\n");
return 0;
}
debug (RPT_DEBUG, "screen_del: Deleting screen %s", argv[1]);
s = client_find_screen (c, argv[1]);
if (!s) {
sock_send_string(c->sock, "huh? Unknown screen id\n");
return 0;
}
err = client_remove_screen (c, s);
if ( err == 0 )
sock_send_string(c->sock, "success\n");
else if (err < 0) {
report(RPT_WARNING, "screen_del_func: Error removing screen");
sock_send_string(c->sock, "huh? Failed to remove screen\n");
} else
sock_send_string (c->sock, "huh? Unknown screen id\n");
report(RPT_NOTICE, "removed a screen (%s) from the display", argv[1]);
return 0;
}
/***************************************************************
* Configures info about a particular screen, such as its
* name, priority, or duration
*
* usage: screen_set <id> [ -priority <int> ] [ -name <name> ] [ -duration <int> ]
* [ -wid <width> ] [ -hgt <height> ] [ -heartbeat <type> ] [ -cursor <type> ]
* [ -cursor_x <xpos> ] [ -cursor_y <ypos> ]
*/
int
screen_set_func (Client * c, int argc, char **argv)
{
int i;
int number;
char *id;
Screen * s;
if (!c->ack)
return 1;
if (argc == 1) {
sock_send_string (c->sock, "huh? Usage: screen_set <id> [ -priority <int> ] [ -name <name> ] [ -duration <int> ] [ -wid <width> ] [ -hgt <height> ] [ -heartbeat <type> ]\n");
return 0;
} else if (argc == 2) {
sock_send_string (c->sock, "huh? What do you want to set?\n");
return 0;
}
id = argv[1];
s = client_find_screen (c, id);
if (!s) {
sock_send_string (c->sock, "huh? Unknown screen id\n");
return 0;
}
/* Handle the rest of the parameters*/
for (i = 2; i < argc; i++) {
char *p;
/* The following code allows us to use p for comparisions,
* ignoring a (valid) single leading '-' - reduces string comparisons
* by half.
*/
p = argv[i];
if (*p == '-')
p++;
/* Handle the "name" parameter*/
if (strcmp (p, "name") == 0) {
if (argc > i + 1) {
i++;
debug (RPT_DEBUG, "screen_set: name=\"%s\"", argv[i]);
/* set the name...*/
if (s->name)
free (s->name);
s->name = strdup (argv[i]);
sock_send_string(c->sock, "success\n");
} else {
sock_send_string (c->sock, "huh? -name requires a parameter\n");
}
}
/* Handle the "priority" parameter*/
else if (strcmp (p, "priority") == 0) {
if (argc > i + 1) {
i++;
debug (RPT_DEBUG, "screen_set: priority=\"%s\"", argv[i]);
/* set the priority...*/
number = atoi (argv[i]);
if (number > 0)
s->priority = number;
sock_send_string(c->sock, "success\n");
} else {
sock_send_string (c->sock, "huh? -priority requires a parameter\n");
}
}
/* Handle the "duration" parameter*/
else if (strcmp (p, "duration") == 0) {
if (argc > i + 1) {
i++;
debug (RPT_DEBUG, "screen_set: duration=\"%s\"", argv[i]);
/* set the duration...*/
number = atoi (argv[i]);
if (number > 0)
s->duration = number;
sock_send_string(c->sock, "success\n");
} else {
sock_send_string (c->sock, "huh? -duration requires a parameter\n");
}
}
/* Handle the "heartbeat" parameter*/
else if (strcmp (p, "heartbeat") == 0) {
if (argc > i + 1) {
i++;
debug (RPT_DEBUG, "screen_set: heartbeat=\"%s\"", argv[i]);
/* set the heartbeat type...*/
if (0 == strcmp (argv[i], "on"))
s->heartbeat = HEARTBEAT_ON;
else if (0 == strcmp (argv[i], "off"))
s->heartbeat = HEARTBEAT_OFF;
else if (0 == strcmp (argv[i], "open"))
s->heartbeat = HEARTBEAT_OPEN;
sock_send_string(c->sock, "success\n");
} else {
sock_send_string (c->sock, "huh? -heartbeat requires a parameter\n");
}
}
/* Handle the "wid" parameter*/
else if (strcmp (p, "wid") == 0) {
if (argc > i + 1) {
i++;
debug (RPT_DEBUG, "screen_set: wid=\"%s\"", argv[i]);
/* set the duration...*/
number = atoi (argv[i]);
if (number > 0)
s->width = number;
sock_send_string(c->sock, "success\n");
} else {
sock_send_string (c->sock, "huh? -wid requires a parameter\n");
}
}
/* Handle the "hgt" parameter*/
else if (strcmp (p, "hgt") == 0) {
if (argc > i + 1) {
i++;
debug (RPT_DEBUG, "screen_set: hgt=\"%s\"", argv[i]);
/* set the duration...*/
number = atoi (argv[i]);
if (number > 0)
s->height = number;
sock_send_string(c->sock, "success\n");
} else {
sock_send_string (c->sock, "huh? -hgt requires a parameter\n");
}
}
/* Handle the "timeout" parameter*/
else if (strcmp (p, "timeout") == 0) {
if (argc > i + 1) {
i++;
debug (RPT_DEBUG, "screen_set: timeout=\"%s\"", argv[i]);
/* set the duration...*/
number = atoi (argv[i]);
/* Add the timeout value (count of TIME_UNITS)
* to struct, TIME_UNIT is 1/8th of a second
*/
if (number > 0) {
s->timeout = number;
report(RPT_NOTICE, "Timeout set.");
}
sock_send_string(c->sock, "success\n");
} else {
sock_send_string (c->sock, "huh? -timeout requires a parameter\n");
}
}
/* Handle the "backlight" parameter*/
else if (strcmp (p, "backlight") == 0) {
if (argc > i + 1) {
i++;
debug (RPT_DEBUG, "screen_set: backlight=\"%s\"", argv[i]);
/* set the backlight status based on what the client has set*/
switch(c->backlight) {
case BACKLIGHT_OPEN:
if (strcmp ("on", argv[i]) == 0)
s->backlight = BACKLIGHT_ON;
if (strcmp ("off", argv[i]) == 0)
s->backlight = BACKLIGHT_OFF;
if (strcmp ("toggle", argv[i]) == 0) {
if (s->backlight == BACKLIGHT_ON)
s->backlight = BACKLIGHT_OFF;
else if (s-backlight == BACKLIGHT_OFF)
s->backlight = BACKLIGHT_ON;
}
if (strcmp ("blink", argv[i]) == 0)
s->backlight |= BACKLIGHT_BLINK;
if (strcmp ("flash", argv[i]) == 0)
s->backlight |= BACKLIGHT_FLASH;
break;
default:
/*If the backlight is not OPEN then inherit its state*/
s->backlight = c->backlight;
break;
}
sock_send_string(c->sock, "success\n");
} else {
sock_send_string (c->sock, "huh? -backlight requires a parameter\n");
}
}
/* Handle the "cursor" parameter */
else if (strcmp (p, "cursor") == 0) {
if (argc > i + 1) {
i++;
debug (RPT_DEBUG, "screen_set: cursor=\"%s\"", argv[i]);
/* set the heartbeat type...*/
if (0 == strcmp (argv[i], "off"))
s->heartbeat = CURSOR_OFF;
if (0 == strcmp (argv[i], "on"))
s->cursor = CURSOR_DEFAULT_ON;
if (0 == strcmp (argv[i], "under"))
s->cursor = CURSOR_UNDER;
if (0 == strcmp (argv[i], "block"))
s->cursor = CURSOR_BLOCK;
sock_send_string(c->sock, "success\n");
} else {
sock_send_string (c->sock, "huh? -cursor requires a parameter\n");
}
}
/* Handle the "cursor_x" parameter */
else if (strcmp (p, "cursor_x") == 0) {
if (argc > i + 1) {
i++;
debug (RPT_DEBUG, "screen_set: cursor_x=\"%s\"", argv[i]);
/* set the position...*/
number = atoi (argv[i]);
if (number > 0 && number <= s->width) {
s->cursor_x = number;
sock_send_string(c->sock, "success\n");
}
else {
sock_send_string(c->sock, "huh? Cursor position outside screen\n");
}
} else {
sock_send_string (c->sock, "huh? -cursor_x requires a parameter\n");
}
}
/* Handle the "cursor_y" parameter */
else if (strcmp (p, "cursor_y") == 0) {
if (argc > i + 1) {
i++;
debug (RPT_DEBUG, "screen_set: cursor_y=\"%s\"", argv[i]);
/* set the position...*/
number = atoi (argv[i]);
if (number > 0 && number <= s->height) {
s->cursor_y = number;
sock_send_string(c->sock, "success\n");
}
else {
sock_send_string(c->sock, "huh? Cursor position outside screen\n");
}
} else {
sock_send_string (c->sock, "huh? -cursor_y requires a parameter\n");
}
}
else sock_send_string (c->sock, "huh? invalid parameter\n");
}/* done checking argv*/
return 0;
}
/**********************************************************************
* Tells the server the client would like to accept keypresses
* of a particular type when the given screen is active on the display
*
* screen_add_key <screenid> <keylist>
*/
int
screen_add_key_func (Client * c, int argc, char **argv)
{
/*widget * w ;*/ /* Keys are stored on a WID_KEYS widget */
Screen * s ; /* Attached to a specific screen */
char * id ; /* Screen ID */
char * keys ; /* Keys wanted */
if (!c->ack)
return 1;
if (argc != 3) {
switch (argc) {
case 1:
sock_send_string (c->sock, "huh? Usage: screen_add_key <screenid> <keylist>\n");
break;
case 2:
sock_send_string (c->sock, "huh? You must specify a key list\n");
break;
default:
sock_send_string (c->sock, "huh? Too many parameters...\n");
break;
}
return 0;
}
id = argv[1];
keys = argv[2];
debug(RPT_DEBUG, "screen_add_key: Adding key(s) %s to screen %s", keys, id);
/* Find the screen*/
s = client_find_screen (c, id);
if (!s) {
sock_send_string (c->sock, "huh? Unknown screen id\n");
return 0;
}
/* Save the keys*/
if (!s->keys) {
/* Save supplied key list*/
s->keys = strdup( keys );
} else {
/* Add supplied keys to existing list
* NOTE: There could be duplicates in the resulting list
* That's OK, it's the existence of the key in the list
* that's important. We'll be more careful in the delete
* key function.
*/
char * new_keys ;
new_keys = realloc( s->keys, strlen(s->keys) + strlen(keys) +1 );
if (new_keys) {
strcpy (new_keys, s->keys);
strcat (new_keys, keys );
free (s->keys);
s->keys = new_keys;
} else {
report (RPT_WARNING, "screen_add_key: Allocation error");
sock_send_string(c->sock, "huh? Could not add new keys\n");
return 0;
}
}
if (!s->keys) {
sock_send_string(c->sock, "huh? failed\n");
} else
sock_send_string(c->sock, "success\n");
return 0;
}
/*************************************************************************
* Tells the server the client would NOT like to accept keypresses
* of a particular type when the given screen is active on the display
*
* usage: screen_del_key <screenid> <keylist>
*/
int
screen_del_key_func (Client * c, int argc, char **argv)
{
/*widget * w ;*/ /* Keys are stored on a WID_KEYS widget */
Screen * s ; /* Attached to a specific screen */
char * id ; /* Screen ID */
char * keys ; /* Keys wanted */
if (!c->ack)
return 1;
if (argc != 3) {
switch (argc) {
case 1:
sock_send_string (c->sock, "huh? Usage: screen_del_key <screenid> <keylist>\n");
break;
case 2:
sock_send_string (c->sock, "huh? You must specify a key list\n");
break;
default:
sock_send_string (c->sock, "huh? Too many parameters\n");
break;
}
return 0;
}
id = argv[1] ;
keys = argv[2] ;
debug(RPT_DEBUG, "screen_del_key: Deleting key(s) %s from screen %s", keys, id);
/* Find the screen*/
s = client_find_screen (c, id);
if (!s) {
sock_send_string (c->sock, "huh? Unknown screen id\n");
return 0;
}
/* Do we have keys?*/
if (s->keys) {
/* Have keys, remove keys from the list
* NOTE: We let malloc/realloc remember the length
* of the allocated storage. If keys are later
* added, realloc (in add_key above) will make
* sure there is enough space at s->keys
*/
char * from ;
char * to ;
to = from = s->keys ;
while( *from ) {
/* Is this key to be deleted from the list?*/
if( strchr( keys, *from ) ) {
/* Yes, skip it*/
++from ;
} else {
/* No, save it*/
*to++ = *from++ ;
}
}
to = '\0'; /* terminates the new keys string...*/
}
sock_send_string(c->sock, "success\n");
return 0;
}
+22
View File
@@ -0,0 +1,22 @@
/*
* screen_commands.h
* This file is part of LCDd, the lcdproc server.
*
* This file is released under the GNU General Public License. Refer to the
* COPYING file distributed with this package.
*
* Copyright (c) 1999, William Ferrell, Scott Scriven
* 2002, Joris Robijn
*
*/
#ifndef COMMANDS_SCREEN_H
#define COMMANDS_SCREEN_H
int screen_add_func (Client * c, int argc, char **argv);
int screen_del_func (Client * c, int argc, char **argv);
int screen_set_func (Client * c, int argc, char **argv);
int screen_add_key_func (Client * c, int argc, char **argv);
int screen_del_key_func (Client * c, int argc, char **argv);
#endif
+210
View File
@@ -0,0 +1,210 @@
/*
* server_commands.c
* This file is part of LCDd, the lcdproc server.
*
* This file is released under the GNU General Public License. Refer to the
* COPYING file distributed with this package.
*
* Copyright (c) 1999, William Ferrell, Scott Scriven
* 2002, Joris Robijn
*
*
* This contains definitions for all the functions which clients can run.
* The functions here are to be called only from parse.c's interpreter.
*
* The client's available function set is defined here, as is the syntax
* for each command.
*
* This particular file defines actions concerning the server settings.
*
*/
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include "shared/report.h"
#include "shared/sockets.h"
#include "client.h"
#include "render.h"
/****************************************************************************
* Sets the state of the output port (such as on MtxOrb LCDs)
*
* usage: output <on|off|int>
*/
#define ALL_OUTPUTS_ON -1
#define ALL_OUTPUTS_OFF 0
int
output_func (Client * c, int argc, char **argv)
{
/*int rc = 0;*/
char str[128];
if (argc != 2) {
if (argc == 1)
sock_send_string (c->sock, "huh? usage: output <on|off|num> -- num may be decimal, hex, or octal\n");
else
sock_send_string (c->sock, "huh? Too many parameters...\n");
return 0;
}
if (0 == strcmp (argv[1], "on"))
output_state = ALL_OUTPUTS_ON;
else if (0 == strcmp (argv[1], "off"))
output_state = ALL_OUTPUTS_OFF;
else {
long out;
char *endptr, *p;
/* Note that there is no valid range set for
* output_state; thus a value in the 12 digits
* is not considered out of range.
*/
errno = 0;
/* errno is set here, because if strtol does not result in
* ERANGE (out of range error) it will not set errno (!).
* At least, this is the case with glibc 2.1.3 ...
*/
p = argv[1];
out = strtol(p, &endptr, 0);
/* From the man page for strtol(3)
*
* In particular, if *nptr is not `\0' but **endptr is
* `\0' on return, the entire string is valid.
*
* In this case, argv[1] is *nptr, and &endptr is **endptr.
*/
if (errno) {
int space;
strcat(str, "huh? number argument: ");
space = sizeof(str) - 3 - strlen(str);
strncat(str, strerror(errno), space);
strcat(str, "\n");
sock_send_string (c->sock, str);
return 0;
} else if (*p != '\0' && *endptr == '\0') {
output_state = out;
} else {
sock_send_string (c->sock, "huh? invalid parameter...\n");
return 0;
}
}
sock_send_string(c->sock, "success\n");
/* Makes sense to me to set the output immediately;
* however, the outputs are currently set in
* draw_screen(screen * s, int timer)
* Whatever for? */
/* drivers_output (output_state); */
report(RPT_NOTICE, "output states changed");
return 0;
}
/*******************************************************************************
* sleep_func
*
* usage: sleep <seconds>
*/
int
sleep_func (Client * c, int argc, char **argv)
{
int secs;
long out;
char *endptr, *p;
char str[120];
#define MAX_SECS 60
#define MIN_SECS 1
if (argc != 2) {
if (argc == 1)
sock_send_string (c->sock, "huh? usage: sleep <secs>\n");
else
sock_send_string (c->sock, "huh? Too many parameters...\n");
return 0;
}
errno = 0;
/* errno is set here, because if strtol does not result in
* ERANGE (out of range error) it will not set errno (!).
* At least, this is the case with glibc 2.1.3 ...
*/
p = argv[1];
out = strtol(p, &endptr, 0);
/* From the man page for strtol(3)
*
* In particular, if *nptr is not `\0' but **endptr is
* `\0' on return, the entire string is valid.
*
* In this case, argv[1] is *nptr, and &endptr is **endptr.
*/
if (errno) {
int space;
strcat(str, "huh? number argument: ");
space = sizeof(str) - 3 - strlen(str);
strncat(str, strerror(errno), space);
strcat(str, "\n");
sock_send_string (c->sock, str);
return 0;
} else if (*p != '\0' && *endptr == '\0') {
secs = out;
out = out > MAX_SECS ? MAX_SECS : out;
out = out < MIN_SECS ? MIN_SECS : out;
} else {
sock_send_string (c->sock, "huh? invalid parameter...\n");
return 0;
}
/* Repeat until no more remains - should normally be zero
* on exit the first time...*/
snprintf(str, sizeof(str), "sleeping %d seconds\n", secs);
sock_send_string (c->sock, str);
/* whoops.... if this takes place as planned, ALL screens
* will "freeze" for the alloted time...
*
* while ((secs = sleep(secs)) > 0)
*/ ;
sock_send_string (c->sock, "huh? ignored (not fully implemented)\n");
return 0;
}
/*****************************************************************************
* Does nothing, returns "noop complete" message
*
* This is useful for shell scripts or programs that want to talk
* with LCDproc and not get deadlocked. Send a noop after each
* command and look for the "noop complete" message.
*/
int
noop_func (Client * c, int argc, char **argv)
{
sock_send_string (c->sock, "noop complete\n");
return 0;
}
+22
View File
@@ -0,0 +1,22 @@
/*
* server_commands.h
* This file is part of LCDd, the lcdproc server.
*
* This file is released under the GNU General Public License. Refer to the
* COPYING file distributed with this package.
*
* Copyright (c) 1999, William Ferrell, Scott Scriven
* 2002, Joris Robijn
*
*/
#ifndef COMMANDS_SERVER_H
#define COMMANDS_SERVER_H
int output_func (Client * c, int argc, char **argv);
int test_func_func (Client * c, int argc, char **argv);
int noop_func (Client * c, int argc, char **argv);
int info_func (Client * c, int argc, char **argv);
int sleep_func (Client * c, int argc, char **argv);
#endif
+465
View File
@@ -0,0 +1,465 @@
/*
* widget_commands.c
* This file is part of LCDd, the lcdproc server.
*
* This file is released under the GNU General Public License. Refer to the
* COPYING file distributed with this package.
*
* Copyright (c) 1999, William Ferrell, Scott Scriven
* 2002, Joris Robijn
*
*
* This contains definitions for all the functions which clients can run.
* The functions here are to be called only from parse.c's interpreter.
*
* The client's available function set is defined here, as is the syntax
* for each command.
*
* This particular file defines actions concerning widgets.
*
*/
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include "shared/report.h"
#include "shared/sockets.h"
#include "client.h"
#include "screen.h"
#include "widget.h"
/*************************************************************************
* Adds a widget to a screen, but doesn't give it a value
*
* usage: widget_add <screenid> <widgetid> <widgettype> [ -in <id> ]
*/
int
widget_add_func (Client * c, int argc, char **argv)
{
int err;
char *sid;
char *wid;
WidgetType wtype;
Screen * s;
Widget * w;
if (!c->ack)
return 1;
if ((argc < 4) || (argc > 6)) {
sock_send_string (c->sock, "huh? Usage: widget_add <screenid> <widgetid> <widgettype> [ -in <id> ]\n");
return 0;
}
sid = argv[1];
wid = argv[2];
s = client_find_screen (c, sid);
if (!s) {
sock_send_string (c->sock, "huh? Invalid screen id\n");
return 0;
}
/* Find widget type */
wtype = widget_typename_to_type (argv[3]);
if (wtype == WID_NONE) {
sock_send_string (c->sock, "huh? Invalid widget type\n");
return 0;
}
/* Check for additional flags...*/
if (argc > 4) {
char *p;
p = argv[4];
if (*p == '-')
p++;
/* Handle the "in" flag to place widgets in a container...*/
if (strcmp (p, "in")) {
char * frame_name;
if (argc < 6) {
sock_send_string (c->sock, "huh? Specify a frame to place widget in\n");
return 0;
}
/* Now we replace s with the framescreen.
* This way it will not be plaed in the normal screen
* but in the framescreen.
*/
frame_name = malloc (strlen("frame_") + strlen(argv[5]) + 1);
strcpy (frame_name, "frame_");
strcat (frame_name, argv[5]);
s = screen_create (frame_name, c);
if (!s) {
report(RPT_WARNING, "widget_add_func: Error creating framescreen");
sock_send_string(c->sock, "huh? Failed\n");
return 0;
}
free (frame_name);
}
}
/* Create the widget */
w = widget_create (wid, wtype, s);
if (!w) {
report(RPT_WARNING, "widget_add_func: Error adding widget");
sock_send_string(c->sock, "huh? Failed\n");
return 0;
}
/* Add the widget to the screen */
err = screen_add_widget (s, w);
if (err == 0)
sock_send_string(c->sock, "success\n");
else {
report(RPT_WARNING, "widget_add_func: Error adding widget");
sock_send_string(c->sock, "huh? Failed\n");
}
return 0;
}
/*******************************************************************
* Removes a widget from a screen, and forgets about it
*
* usage: widget_del <screenid> <widgetid>
*/
int
widget_del_func (Client * c, int argc, char **argv)
{
int err = 0;
char *sid;
char *wid;
Screen * s;
Widget * w;
if (!c->ack)
return 1;
if (argc != 3) {
switch (argc) {
case 1:
sock_send_string (c->sock, "huh? Usage: widget_del <screenid> <widgetid>\n");
break;
case 2:
sock_send_string (c->sock, "huh? Specify a widget #id\n");
break;
default:
sock_send_string (c->sock, "huh? Too many parameters...\n");
break;
}
return 0;
}
sid = argv[1];
wid = argv[2];
debug (RPT_DEBUG, "screen_del: Deleting widget %s.%s", sid, wid);
s = client_find_screen (c, sid);
if (!s) {
sock_send_string (c->sock, "huh? Invalid screen id\n");
return 0;
}
w = screen_find_widget (s, wid);
if (!w) {
sock_send_string (c->sock, "huh? Invalid widget id\n");
return 0;
}
err = screen_remove_widget (s, w);
if (err == 0)
sock_send_string(c->sock, "success\n");
else {
report( RPT_WARNING, "widget_del_func: Error removing widget");
sock_send_string(c->sock, "huh? Failed\n");
}
return 0;
}
/********************************************************************
* Configures information about a widget, such as its size, shape,
* contents, position, speed, etc...
*
* Ack! This is long!
*
* widget_set <screenid> <widgetid> <widget-SPECIFIC-data>
*/
int
widget_set_func (Client * c, int argc, char **argv)
{
int i;
char * wid;
char * sid;
int x, y;
int left, top, right, bottom;
int length, direction;
int width, height;
int speed;
Screen * s;
Widget * w;
if (!c->ack)
return 1;
/* If there weren't enough parameters...
* We can't test for too many, since each widget may have a
* different number - plus, if the argument count is wrong, what ELSE
* could be wrong...?
*/
if (argc < 4) {
sock_send_string (c->sock, "huh? Usage: widget_set <screenid> <widgetid> <widget-SPECIFIC-data>\n");
return 0;
}
/* Find screen */
sid = argv[1];
s = client_find_screen (c, sid);
if (!s) {
sock_send_string (c->sock, "huh? Unknown screen id\n");
return 0;
}
/* Find widget */
wid = argv[2];
w = screen_find_widget (s, wid);
if (!w) {
sock_send_string (c->sock, "huh? Unknown widget id\n");
/* Client Debugging...*/
{
int i;
report( RPT_WARNING, "huh? Unknown widget id (%s)", argv[2]);
for (i = 0; i < argc; i++)
report( RPT_WARNING, " %.40s ", argv[i]);
}
return 0;
}
i = 3;
switch (w->type) {
case WID_STRING: /* String takes "x y text"*/
if (argc != i + 3)
sock_send_string (c->sock, "huh? Wrong number of arguments\n");
else {
if ((!isdigit ((unsigned int) argv[i][0])) ||
(!isdigit ((unsigned int) argv[i + 1][0]))) {
sock_send_string (c->sock, "huh? Invalid coordinates\n");
} else /* Set all the data...*/
{
x = atoi (argv[i]);
y = atoi (argv[i + 1]);
w->x = x;
w->y = y;
if (w->text)
free (w->text);
w->text = strdup (argv[i + 2]);
if (!w->text) {
debug (RPT_DEBUG, "Widget %s set to %s", wid, w->text);
report( RPT_WARNING, "widget_set_func: Allocation error");
return -1;
}
debug (RPT_DEBUG, "Widget %s set to %s", wid, w->text);
sock_send_string(c->sock, "success\n");
}
}
break;
case WID_HBAR: /* Hbar takes "x y length"*/
if (argc != i + 3)
sock_send_string (c->sock, "huh? Wrong number of arguments\n");
else {
if ((!isdigit ((unsigned int) argv[i][0])) ||
(!isdigit ((unsigned int) argv[i + 1][0]))) {
sock_send_string (c->sock, "huh? Invalid coordinates\n");
} else {
x = atoi (argv[i]);
y = atoi (argv[i + 1]);
length = atoi (argv[i + 2]);
w->x = x;
w->y = y;
w->length = length;
}
debug (RPT_DEBUG, "Widget %s set to %i", wid, w->length);
sock_send_string(c->sock, "success\n");
}
break;
case WID_VBAR: /* Vbar takes "x y length"*/
if (argc != i + 3)
sock_send_string (c->sock, "huh? Wrong number of arguments\n");
else {
if ((!isdigit ((unsigned int) argv[i][0])) ||
(!isdigit ((unsigned int) argv[i + 1][0]))) {
sock_send_string (c->sock, "huh? Invalid coordinates\n");
} else {
x = atoi (argv[i]);
y = atoi (argv[i + 1]);
length = atoi (argv[i + 2]);
w->x = x;
w->y = y;
w->length = length;
}
debug (RPT_DEBUG, "Widget %s set to %i", wid, w->length);
sock_send_string(c->sock, "success\n");
}
break;
case WID_ICON: /* Icon takes "x y binary_data"*/
if (argc != i + 3)
sock_send_string (c->sock, "huh? Wrong number of arguments\n");
else {
if ((!isdigit ((unsigned int) argv[i][0])) ||
(!isdigit ((unsigned int) argv[i + 1][0]))) {
sock_send_string (c->sock, "huh? Invalid coordinates\n");
} else {
x = atoi (argv[i]);
y = atoi (argv[i + 1]);
w->x = x;
w->y = y;
/* TODO: Parse binary data and copy it to widget's data...*/
}
}
sock_send_string (c->sock, "huh? Widget type not yet implemented\n");
break;
case WID_TITLE: /* title takes "text"*/
if (argc != i + 1)
sock_send_string (c->sock, "huh? Wrong number of arguments\n");
else {
if (w->text)
free (w->text);
w->text = strdup (argv[i]);
if (!w->text) {
report( RPT_WARNING, "widget_set_func: Allocation error");
return -1;
}
debug (RPT_DEBUG, "Widget %s set to %s", wid, w->text);
sock_send_string(c->sock, "success\n");
}
break;
case WID_SCROLLER: /* Scroller takes "left top right bottom direction speed text"*/
if (argc != i + 7) {
sock_send_string (c->sock, "huh? Wrong number of arguments\n");
} else {
if ((!isdigit ((unsigned int) argv[i][0])) ||
(!isdigit ((unsigned int) argv[i + 1][0])) ||
(!isdigit ((unsigned int) argv[i + 2][0])) ||
(!isdigit ((unsigned int) argv[i + 3][0]))) {
sock_send_string (c->sock, "huh? Invalid coordinates\n");
} else {
left = atoi (argv[i]);
/*debug("left: %d",left);*/
top = atoi (argv[i + 1]);
/*debug("top: %d",top);*/
right = atoi (argv[i + 2]);
/*debug("right: %d",right);*/
bottom = atoi (argv[i + 3]);
/*debug("bottom: %d",bottom);*/
direction = (int) (argv[i + 4][0]);
/*debug("dir: %c",(char)direction);*/
speed = atoi (argv[i + 5]);
/*debug("speed: %d",speed);*/
/* Direction must be v or h*/
if (((char) direction != 'h') && ((char) direction != 'v')) {
sock_send_string (c->sock, "huh? Invalid direction\n");
} else {
w->left = left;
w->top = top;
w->right = right;
w->bottom = bottom;
w->length = direction;
w->speed = speed;
if (w->text)
free (w->text);
w->text = strdup (argv[i + 6]);
if (!w->text) {
sock_send_string(c->sock, "huh? Failed\n");
report( RPT_WARNING, "widget_set_func: Allocation error");
return -1;
}
debug (RPT_DEBUG, "Widget %s set to %s", wid, w->text);
sock_send_string(c->sock, "success\n");
}
}
}
break;
case WID_FRAME: /* Frame takes "left top right bottom wid hgt direction speed"*/
if (argc != i + 8) {
sock_send_string (c->sock, "huh? Wrong number of arguments\n");
} else {
if ((!isdigit ((unsigned int) argv[i][0])) ||
(!isdigit ((unsigned int) argv[i + 1][0])) ||
(!isdigit ((unsigned int) argv[i + 2][0])) ||
(!isdigit ((unsigned int) argv[i + 3][0])) ||
(!isdigit ((unsigned int) argv[i + 4][0])) ||
(!isdigit ((unsigned int) argv[i + 5][0]))) {
sock_send_string (c->sock, "huh? Invalid coordinates\n");
} else {
left = atoi (argv[i]);
/*debug("left: %d",left);*/
top = atoi (argv[i + 1]);
/*debug("top: %d",top);*/
right = atoi (argv[i + 2]);
/*debug("right: %d",right);*/
bottom = atoi (argv[i + 3]);
/*debug("bottom: %d",bottom);*/
width = atoi (argv[i + 4]);
/*debug("right: %d",right);*/
height = atoi (argv[i + 5]);
/*debug("bottom: %d",bottom);*/
direction = (int) (argv[i + 6][0]);
/*debug("dir: %c",(char)direction);*/
speed = atoi (argv[i + 7]);
/*debug("speed: %d",speed);*/
/* Direction must be v or h*/
if (((char) direction != 'h') && ((char) direction != 'v')) {
sock_send_string (c->sock, "huh? Invalid direction\n");
} else {
w->left = left;
w->top = top;
w->right = right;
w->bottom = bottom;
w->width = width;
w->height = height;
w->length = direction;
w->speed = speed;
debug (RPT_DEBUG, "Widget %s set to (%i,%i)-(%i,%i) %ix%i", wid, left, top, right, bottom, width, height);
sock_send_string(c->sock, "success\n");
}
}
}
break;
case WID_NUM: /* Num takes "x num"*/
if (argc != i + 2)
sock_send_string (c->sock, "huh? Wrong number of arguments\n");
else {
if (!isdigit ((unsigned int) argv[i][0])) {
sock_send_string (c->sock, "huh? Invalid coordinates\n");
} else if (!isdigit ((unsigned int) argv[i + 1][0])) {
sock_send_string (c->sock, "huh? Invalid number\n");
} else {
x = atoi (argv[i]);
y = atoi (argv[i + 1]);
w->x = x;
w->y = y;
}
debug (RPT_DEBUG, "Widget %s set to %i", wid, w->y);
sock_send_string(c->sock, "success\n");
}
break;
case WID_NONE:
default:
sock_send_string (c->sock, "huh? Widget has no type\n");
break;
}
return 0;
}
+20
View File
@@ -0,0 +1,20 @@
/*
* widget_commands.h
* This file is part of LCDd, the lcdproc server.
*
* This file is released under the GNU General Public License. Refer to the
* COPYING file distributed with this package.
*
* Copyright (c) 1999, William Ferrell, Scott Scriven
* 2002, Joris Robijn
*
*/
#ifndef COMMANDS_WIDGET_H
#define COMMANDS_WIDGET_H
int widget_add_func (Client * c, int argc, char **argv);
int widget_del_func (Client * c, int argc, char **argv);
int widget_set_func (Client * c, int argc, char **argv);
#endif
+11 -12
View File
@@ -43,19 +43,17 @@
#include "drivers.h"
#include "client_data.h"
#include "client.h"
#include "clients.h"
#include "screen.h"
#include "widget.h"
#include "screenlist.h"
#include "menus.h"
//#include "menus.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);
@@ -69,9 +67,9 @@ handle_input ()
{
char str[15];
int key;
screen *s;
/*widget *w; */
client *c;
Screen * s;
/*Widget * w; */
Client * c;
report (RPT_INFO, "handle_input()" );
@@ -103,7 +101,7 @@ handle_input ()
if (KeyWanted(s->keys, key)) {
/* This screen wants this key. Tell it we got one */
snprintf(str, sizeof(str), "key %c\n", key);
sock_send_string(s->parent->sock, str);
sock_send_string(s->client->sock, str);
/* Nobody else gets this key */
}
@@ -114,17 +112,17 @@ handle_input ()
else {
/* Give key to clients who want it */
c = FirstClient(clients);
c = clients_getfirst();
while (c) {
/* If the client should have this keypress... */
if(KeyWanted(c->data->client_keys,key)) {
if(KeyWanted(c->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);
c = clients_getnext();
} /* while clients */
/* Give server a shot at all keys */
@@ -156,7 +154,8 @@ server_input (int key)
break;
case INPUT_MAIN_MENU_KEY:
debug (RPT_DEBUG, "got the menu key!");
server_menu ();
//server_menu ();
report (RPT_ERR, "MENU TEMPORATY DISABLED");
break;
default:
debug (RPT_DEBUG, "server_input: Unused key \"%c\" (%i)", (char) key, key);
+7 -6
View File
@@ -391,7 +391,7 @@ process_configfile ( char *configfile )
report( RPT_ERR, "Serverscreen can only be no, noscreen or yes" );
}
}
if( backlight == UNSET_INT ) {
s = config_get_string( "server", "backlight", 0, UNSET_STR );
if( strcmp( s, "on" ) == 0 ) {
@@ -526,7 +526,7 @@ init_sockets ()
/* Now init a bunch of required stuff...*/
if (client_init () < 0) {
if (clients_init () < 0) {
report(RPT_ERR, "Error initializing client list");
return -1;
}
@@ -614,7 +614,7 @@ init_screens ()
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;
@@ -627,7 +627,7 @@ init_screens ()
void
do_mainloop ()
{
screen *s = NULL;
Screen *s = NULL;
char *message=NULL;
report( RPT_INFO, "do_mainloop()" );
@@ -708,7 +708,8 @@ do_mainloop ()
free(message);
}
if (s->timeout <= 0) {
screen_remove (s->parent, s->id);
client_remove_screen (s->client, s);
screen_destroy (s);
if((message = malloc(256)) == NULL)
report(RPT_ERR, "Error allocating message string");
else {
@@ -760,7 +761,7 @@ exit_program (int val)
/* Shutdown things if server start was complete */
if( serverStarted ) {
client_shutdown (); /* shutdown clients (must come first) */
clients_shutdown (); /* shutdown clients (must come first) */
screenlist_shutdown (); /* shutdown screens (must come after client_shutdown) */
sock_close_all (); /* close all open sockets (must come after client_shutdown) */
}
-7
View File
@@ -17,8 +17,6 @@
#include "config.h"
#endif
#include "render.h"
/*
contains a few things that other parts of the program might want
to know about...
@@ -35,11 +33,6 @@ void exit_program (int val);
/* But I plan to double the framerate soon, or make it variable...*/
/*#define TIME_UNIT (125000/2)*/
typedef struct screen_size {
char *size;
int wid, hgt;
} screen_size;
#define DEFAULT_SCREEN_PRIORITY 128
#define DEFAULT_SCREEN_DURATION 32
#define DEFAULT_HEARTBEAT HEARTBEAT_ON
+188 -301
View File
@@ -6,6 +6,7 @@
* COPYING file distributed with this package.
*
* Copyright (c) 1999, William Ferrell, Scott Scriven
* 2002, Joris Robijn
*
*
* Handles server-supplied menus defined by a table. Read menu.h for
@@ -19,6 +20,16 @@
* to handle dynamically-changing menus such as the client list. Tcl/Tk
* has neat ways to do it. Hmm...
*
* NEW DESCRIPTION
*
* Handles a menu and all actions that can be performed on it.
*
* Menus are similar to "pull-down" menus, but have some extra features.
* They can contain "normal" menu items, checkboxes, sliders, "movers",
* etc..
*
* The servermenu is created from servermenu.c
*
*/
#include <stdlib.h>
@@ -26,329 +37,205 @@
#include <string.h>
#include <unistd.h>
#include "parse.h"
#include "sock.h"
#include "render.h"
#include "main.h"
#include "config.h"
#include "drivers.h"
#include "menu.h"
#include "input.h"
#include "shared/report.h"
#include "drivers.h"
/* FIXME: Implement this where it is supposed to be...*/
void
framedelay ()
#include "screen.h"
/* Internal menu item drawing functions */
void menu_build_menu_screen (MenuItem *item, Screen *s);
void menu_build_slider_screen (MenuItem *item, Screen *s);
void menu_build_numeric_screen (MenuItem *item, Screen *s);
void menu_build_string_screen (MenuItem *item, Screen *s);
void menu_update_menu_screen (MenuItem *item, Screen *s);
void menu_update_slider_screen (MenuItem *item, Screen *s);
void menu_update_numeric_screen (MenuItem *item, Screen *s);
void menu_update_string_screen (MenuItem *item, Screen *s);
MenuItem *menu_create_add_item (Menu *into_menu, int type, char *id,
EventFunc(*event_func))
{
sock_poll_clients ();
parse_all_client_messages ();
Menu *new_item;
usleep (TIME_UNIT);
}
static void
draw_heartbeat ()
{
static int timer = 0;
if (heartbeat) {
/* Set this to pulsate like a real heart beat... */
/*drivers_icon (!((timer + 4) & 5), 0); */
/*drivers_chr (display_props->width, 1, 0); */
/* Allocate space and fill struct */
new_item = malloc (sizeof(MenuItem));
if (!new_item) {
report (RPT_ERR, "menu_add_new_item: Could not allocate memory");
return NULL;
}
drivers_flush ();
new_item->type = type;
new_item->id = strdup (id);
if (!new_item->id) {
report (RPT_ERR, "menu_add_new_item: Could not allocate memory");
return NULL;
}
new_item->event_func = event_func;
timer++;
timer &= 0x0f;
}
static int PAD = 255;
typedef struct menu_info {
int selected;
int length;
} menu_info;
static int draw_menu (Menu menu, menu_info * info);
static int fill_menu_info (Menu menu, menu_info * info);
static int menu_handle_action (menu_item * item);
static int slid_func (menu_item * item);
int
do_menu (Menu menu)
{
menu_info info;
int key = 0;
int status = MENU_OK;
int done = 0;
int (*func) ();
int (*readfunc) (int);
if (!menu)
return MENU_ERROR;
fill_menu_info (menu, &info);
while (!done) {
/* Keep the cursor off titles... (?) */
while (menu[info.selected].type == TYPE_TITL) {
info.selected++;
/* If the title is the last thing in the menu... */
if (!menu[info.selected].text)
info.selected -= 2;
}
draw_menu (menu, &info);
/* FIXME: This should use a better keypress interface, which */
/* FIXME: handles things according to keybindings... */
for (key = drivers_getkey (); key == 0; key = drivers_getkey ()) {
/* sleep for 1/8th second... */
framedelay ();
/* do the heartbeat... */
draw_heartbeat ();
/* Check for client input... */
}
printf( "Received key: %c\n", key );
/* Handle the key according to the keybindings... */
switch (key) {
case 'D':
done = 1;
break;
case 'B':
if (info.selected > 0)
info.selected--;
while (menu[info.selected].type == TYPE_TITL) {
if (info.selected > 0)
info.selected--;
else
break;
}
break;
case INPUT_FORWARD_KEY:
if (menu[info.selected + 1].text)
info.selected++;
break;
case INPUT_PAUSE_KEY:
switch (menu[info.selected].type) {
case TYPE_MENU:
status = do_menu (menu[info.selected].data);
break;
case TYPE_FUNC:
func = menu[info.selected].data;
if (func)
status = func ();
break;
case TYPE_CHEK:
readfunc = menu[info.selected].data;
if (readfunc)
status = readfunc (MENU_CHECK);
status &= 0xffff0000;
break;
case TYPE_SLID:
func = menu[info.selected].data;
if (func)
status = slid_func (&menu[info.selected]);
break;
default:
break;
}
switch (status) {
case MENU_OK:
break;
case MENU_CLOSE:
return MENU_OK;
case MENU_QUIT:
return MENU_QUIT;
/* case MENU_KILL:
* return MENU_KILL;
*/
case MENU_ERROR:
return MENU_ERROR;
}
/* status = menu_handle_action(&menu[info.selected]);*/
/* TODO: It should now do special stuff for "mover" widgets,
* TODO: and handle the return code appropriately.
*/
break;
default:
break;
}
/* Clear the type specific data part */
memset ( &(new_item->data), 0, sizeof(new_item->data));
if (type == MENUITEM_MENU ) {
/* We have created a menu, create our needed data */
new_item->data.menu.parent = into_menu;
LL_new (new_item->data.menu.contents);
}
return status;
}
static int
draw_menu (Menu menu, menu_info * info)
{
int i;
int x = 1, y = 1;
int top = 0, bottom = 0;
int (*readfunc) (int);
/* these should maybe be removed: */
int wid = display_props->width, hgt = display_props->height;
if (!menu)
return MENU_ERROR;
drivers_clear ();
/* Scroll down until the selected item is centered, if possible...*/
top = info->selected - (hgt / 2);
if (top < 0)
top = 0;
bottom = top + hgt;
if (bottom > info->length)
bottom = info->length;
top = bottom - hgt;
if (top < 0)
top = 0;
/* Draw all visible items...*/
for (i = top; i < bottom; i++, y++) {
if (i == info->selected)
drivers_chr (2, y, '>');
switch (menu[i].type) {
case TYPE_TITL:
drivers_chr (1, y, PAD);
drivers_chr (2, y, PAD);
drivers_string (4, y, menu[i].text);
for (x = strlen (menu[i].text) + 5; x <= wid; x++)
drivers_chr (x, y, PAD);
break;
case TYPE_MENU:
drivers_string (3, y, menu[i].text);
drivers_chr (wid, y, '>');
break;
case TYPE_FUNC:
drivers_string (3, y, menu[i].text);
break;
case TYPE_CHEK:
if (menu[i].data) {
readfunc = menu[i].data;
if (readfunc (MENU_READ))
drivers_chr (wid, y, 'Y');
else
drivers_chr (wid, y, 'N');
}
drivers_string (3, y, menu[i].text);
break;
case TYPE_SLID:
drivers_string (3, y, menu[i].text);
break;
case TYPE_MOVE:
break;
default:
break;
}
if (into_menu) {
/* Add the item to the menu */
LL_Push (into_menu->data.menu.contents, new_item);
}
if (top != 0)
drivers_chr (1, 1, '^');
if (bottom < info->length)
drivers_chr (1, hgt, 'v');
return new_item;
}
draw_heartbeat ();
/*drivers_flush(); */
int menu_destroy_item (Menu *menu, MenuItem *item)
{
/* Is the item a menu ? */
if (item->type == MENUITEM_MENU ) {
/* Check if the menu is empty */
if ( LL_Length(item->data.menu.contents) != 0 ) {
report (RPT_ERR, "menu not empty, cannot be destroyed");
return -1;
}
/* Destroy our menu data */
if (item->data.menu.text)
free (item->data.menu.text);
LL_Destroy (item->data.menu.contents);
}
free (item->id);
free (item);
/* Remove the item from the menu */
LL_Remove (menu->data.menu.contents, item);
return 0;
}
static int
fill_menu_info (Menu menu, menu_info * info)
MenuItem *menu_find_item (Menu *menu, char *id)
{
int i;
info->selected = 0;
/* count the entries in the menu*/
for (i = 0; menu[i].text; i++);
info->length = i;
return 0;
MenuItem * item;
for( item = menu_getfirst_item(menu); item; item = menu_getnext_item(menu) ) {
if ( strcmp(item->id, id) == 0 ) {
return item;
}
}
return NULL;
}
static int
menu_handle_action (menu_item * item)
/******** MENU SCREEN BUILD FUNCTIONS ********/
void menu_build_screen (MenuItem *item, Screen *s)
{
return MENU_OK;
}
Widget * w;
static int
slid_func (menu_item * item)
{
char str[16];
int key = 0;
int value = 0;
int x, y = 1;
int (*readfunc) (int);
readfunc = item->data;
/*drivers_init_hbar (); OBSOLETE */
while (key != 'A' && key != 'D') {
/* Draw the title... */
drivers_clear ();
drivers_chr (1, y, PAD);
drivers_chr (2, y, PAD);
drivers_string (4, y, item->text);
for (x = strlen (item->text) + 5; x <= display_props->width; x++)
drivers_chr (x, y, PAD);
/* Draw the slider now...*/
value = readfunc (MENU_READ);
if (value < 0 || value >= MENU_CLOSE)
return value;
snprintf (str, sizeof(str), "%i", value);
if (display_props->height >= 4) {
int promille;
drivers_string (8, 4, str);
value = (display_props->width * display_props->cellwidth * value / 256);
promille = (long) 100 * value / 256;
drivers_hbar (1, 3, display_props->width, promille, BAR_PATTERN_FILLED);
} else {
int promille;
drivers_string (17, 2, str);
value = ((display_props->width - 4) * display_props->cellwidth * value / 256);
promille = (long) 100 * value / 256;
drivers_hbar (1, 2, display_props->width, promille, BAR_PATTERN_FILLED);
}
/*drivers_flush(); */
for (key = drivers_getkey (); key == 0; key = drivers_getkey ()) {
/* do the heartbeat... */
draw_heartbeat ();
/* sleep for 1/8th second... */
framedelay ();
/* Check for client input... */
}
switch (key) {
case 'B':
value = readfunc (MENU_MINUS);
break;
case 'C':
value = readfunc (MENU_PLUS);
break;
}
if (value >= MENU_CLOSE || value < 0 || key == 'A' || key == 'D')
return value;
if (display_props) {
/* Nothing to build if no display size is known */
report (RPT_ERR, "menu_build_screen: display size unknown");
return;
}
return MENU_OK;
/* First remove all widgets from the screen */
for ( w=screen_getfirst_widget(s); w; w=screen_getnext_widget(s) ) {
/* We know these widgets don't have subwidgets */
screen_remove_widget (s, w);
widget_destroy (w);
}
switch (item->type) {
case MENUITEM_MENU:
menu_build_menu_screen (item, s);
break;
case MENUITEM_SLIDER:
menu_build_slider_screen (item, s);
break;
case MENUITEM_NUMERIC_INPUT:
menu_build_slider_screen (item, s);
break;
case MENUITEM_STRING_INPUT:
menu_build_slider_screen (item, s);
break;
default:
report (RPT_ERR, "menu_build_screen: given menuitem cannot be active");
return;
}
menu_update_screen (item, s);
}
void menu_build_menu_screen (MenuItem *item, Screen *s)
{
Widget * w;
int linenr;
for (linenr=1; linenr<display_props->width; linenr++) {
char buf[8];
snprintf (buf, sizeof(buf)-1, "line%d", linenr);
buf[sizeof(buf)-1] = 0;
w = widget_create (buf, WID_STRING, s);
/* (buf will be copied) */
w->text = strdup("");
screen_add_widget (s, w);
}
}
void menu_build_slider_screen (MenuItem *item, Screen *s)
{
}
void menu_build_numeric_screen (MenuItem *item, Screen *s)
{
}
void menu_build_string_screen (MenuItem *item, Screen *s)
{
}
void menu_build_password_screen (MenuItem *item, Screen *s)
{
}
/******** MENU SCREEN UPDATE FUNCTIONS ********/
void menu_update_screen (MenuItem *item, Screen *s) {
switch (item->type) {
case MENUITEM_MENU:
menu_update_menu_screen (item, s);
break;
case MENUITEM_SLIDER:
menu_update_slider_screen (item, s);
break;
case MENUITEM_NUMERIC_INPUT:
menu_update_slider_screen (item, s);
break;
case MENUITEM_STRING_INPUT:
menu_update_slider_screen (item, s);
break;
default:
report (RPT_ERR, "menu_update_screen: given menuitem cannot be active");
}
}
void menu_update_menu_screen (MenuItem *item, Screen *s)
{
}
void menu_update_slider_screen (MenuItem *item, Screen *s)
{
}
void menu_update_numeric_screen (MenuItem *item, Screen *s)
{
}
void menu_update_string_screen (MenuItem *item, Screen *s)
{
}
+157 -111
View File
@@ -7,140 +7,186 @@
*
* Copyright (c) 1999, William Ferrell, Scott Scriven
*
* Defines all the menu data and action.
*/
#ifndef MENU_H
#define MENU_H
#if 0
/*************************************************************************
Menus!
#include "shared/LL.h"
This is how the LCDproc menu stuff works...
#include "screen.h"
Each item has three values:
/*********************************************************************
* Data definitions of the menustuff
* Do not modify attributes from your code, but call functions.
*/
Title -- Text
Type -- menu, function, checkbox, slider, mover
Data -- Child, ExecFunc, CheckFunc, SlidFunc, ???
typedef enum MenuItemType {
MENUITEM_NONE = 0,
MENUITEM_TITLE,
MENUITEM_MENU,
MENUITEM_ACTION,
MENUITEM_CHECKBOX,
MENUITEM_SLIDER,
MENUITEM_NUMERIC_INPUT,
MENUITEM_STRING_INPUT,
} MenuItemType;
When an item is picked, do_menu() decides what to do based on type.
--"Menus" will recurse into the "data", assuming it is a child menu.
--"Function"-type items will have their function called.
--CheckBox-type items will have their function called with a "read"
parameter to get an on/off signal, and called with a "set" signal when
picked.
--Sliders will have the same "read" thing, and the "set" function will
take a plus or minus parameter.
--The Movers will act like a label until picked, and then the +/- keys
will both rearrange the menu, and send the item a signal of some sort
to indicate what happened. It will act like a label again after the
user presses Enter again.
typedef enum CheckboxValue {
CHECKBOX_OFF = 0, CHECKBOX_ON, CHECKBOX_GRAY
} CheckboxValue;
The "Data" field will really be a "void *", which is the "generic"
data type in C...
Anyway, this sort of thing would be declared this way:
========================================================================
/* Return codes from an event value */
typedef enum MenuEventFuncResult {
MENUEVENTRES_ERROR = -1, /* Something has gone wrong */
MENUEVENTRES_OK = 0, /* Event handled OK */
MENUEVENTRES_CLOSE, /* Event handled OK, close the menu now */
MENUEVENTRES_QUIT /* Event handled OK, close ALL menus now */
} MenuEventFuncResult;
menu_item MainMenu[] = {
"MENU", 0, 0, // Title
"Options", TYPE_MENU, (void *)OptionsMenu,
"Kill LCDproc", TYPE_FUNC, (void *)Shutdown_func,
0, 0, 0,
};
/* Events that can happen */
typedef enum MenuEventType {
MENUEVENT_SELECT, /* Item has been selected
(menu opened, action selected) */
MENUEVENT_UPDATE, /* Item has been modified
(checkbox, numeric, string, password) */
MENUEVENT_PLUS, /* Item has been modified in positive direction
(slider moved) */
MENUEVENT_MINUS /* Item has been modified in negative direction
(slider moved) */
} MenuEventType;
menu_item OptionsMenu[] = {
"OPTIONS", TYPE_TITL, 0, // Title
"24-hour Time", TYPE_CHEK, (void *)Time24_func,
"Contrast...", TYPE_SLID, (void *)Contrast_func,
0, 0, 0,
};
#define EventFunc(f) MenuEventFuncResult (f) (void *object, MenuEventType event)
///////////////// Elsewhere, we declare these...
typedef struct MenuItem {
int type; /* Type as defined above */
char *id; /* Internal name for client supplied menus */
EventFunc (*event_func);
/* Defines event_func to be an event function */
union data {
struct menu {
char *text; /* Visible name of the submenu */
int current_item_index; /* At what menuitem is the selector */
struct MenuItem *parent; /* Parent of this menu */
LinkedList *contents; /* What's in this menu */
} menu;
struct checkbox {
char *text; /* Visible name of item */
CheckboxValue value; /* Current value */
int allowgray; /* is CHECKBOX_GRAY allowed ? */
} checkbox;
struct slider {
char *text; /* Visible name of item */
char *lefttext; /* Text at minimal value */
char *righttext;/* Text at minimal value */
int value; /* Current value */
int minvalue;
int maxvalue;
int stepsize;
} slider;
struct numeric {
char *text; /* Visible name of item */
int value; /* Current value */
int maxvalue;
int minvalue;
} numeric;
struct string {
char *text; /* Visible name of item */
char *value; /* Current value (in a buffer) */
char passwordchar; /* For passwords */
int maxlength;
} string;
struct password {
char *text; /* Visible name of item */
char *value; /* Current value (in a buffer) */
int maxlength; /* Max allowed length */
} password;
} data;
} MenuItem;
void Shutdown_func()
#define Menu MenuItem
/* A Menu is a MenuItem too.
* This definition is only for better understanding of this code.
*/
/*********************************************************************
* Functions to use the menustuff
*/
MenuItem *menu_create_add_item (Menu *into_menu, int type, char *name,
EventFunc(*event_func));
/* Creates a new item and adds it to the given menu.
* All attributes if the new item are cleared.
* into_menu What menu should it be in.
* type: type as defined above (determines also how the attributes will
* be filled).
* name: internal name of the item. Never visible. String will be
* copied.
* event_func: the event function that should be called upon actions on this
* item. see event.h.
* The data part of the new item is filled with 0's.
*
* Return value: the new item, of NULL on error.
*
* If you create a new menu, the menu data will automatically be allocated,
* and the contents pointer set to this menu.
*
* To initialize data for the data part, do things like:
*
* yourname = menu_create_add_item (m, MENUITEM_STRING_INPUT, "YourName",
* yourname_change_handler);
* yourname->data.text = strdup ("Your name");
* yourname->data.maxlength = 10;
* yourname->data.value = malloc (10+1); <--- maxlength + 1
* yourname->data.value[0] = 0; <--- clear the string
*
* The data NEEDS to be initialized immediately (at least before it's first
* used).
*
*/
int menu_destroy_item (Menu *menu, MenuItem *item);
/* Deletes item from menu and removes item from memory
*
* If the item is a menu, the menu data will also be deallocated.
*
* Return value: 0 for OK, -1 for error (eg. submenus not empty)
*
* To destroy the data in the data struct, do things like:
*
* free (yourname->data.value);
* free (yourname->data.text);
* menu_destroy_item (yourname);
*/
static inline MenuItem *menu_getfirst_item (Menu *menu)
/* Retrieves the first item from the list of items in the menu. */
{
// Do something here...
return MENU_KILL; // or MENU_CLOSE, or MENU_OK, or MENU_ERROR
return (MenuItem*) LL_GetFirst( menu->data.menu.contents );
}
int Time24_func(int input)
static inline MenuItem *menu_getnext_item (Menu *menu)
/* Retrieves the next item from the list of items in the menu.
* No other menu calls should be made between menu_first_item() and
* this function, to keep the list-cursor where it is. */
{
if(input == MENU_READ) return status;
if(input == MENU_CHECK) toggle_status(); // does something.
return (status | MENU_OK);
// The status is "or"-ed with the MENU value to let do_menu()
// know what to do after selecting the item. (two return
// values in one. :)
// Also, "MENU_OK" happens to be zero, so it does not matter
// unless you want something else (like MENU_CLOSE)
return (MenuItem*) LL_GetNext( menu->data.menu.contents );
}
int Contrast_func(int input)
{
if(input == MENU_READ) return status;
if(input == MENU_PLUS) increment_status(); // does something.
if(input == MENU_MINUS) decrement_status();// does something.
return (status | MENU_OK);
}
MenuItem *menu_find_item (Menu *menu, char *id);
/* Retrieves the first item from the list of items in the menu. */
=====================================================================
void menu_build_screen (MenuItem *item, Screen *s);
/* Builds the selected menuitem on screen using widgets
* Returns the initial state.
*/
Function return values:
MENU_OK Keeps menu open.
MENU_CLOSE Closes menu after item is picked.
Leaves the parent menus open.
MENU_QUIT Closes all menus after item is picked.
Like a normal pulldown menu.
MENU_KILL Same as MENU_QUIT, so far.
MENU_ERROR Um, for errors? :)
Also, functions for sliders and checkboxes should return a status value
binary OR-ed with the MENU_ return value. Checkboxes should return 0 or 1,
and sliders should return 0-255.
**************************************************************************/
#endif
/* Return codes from selected menu items...*/
#define MENU_ERROR -0x7FFF0000
#define MENU_OK 0
#define MENU_CLOSE 0x10000
#define MENU_QUIT 0x20000
#define MENU_KILL 0x20000
/* Menu item Types...*/
#define TYPE_TITL 0
#define TYPE_MENU 1
#define TYPE_FUNC 2
#define TYPE_CHEK 3
#define TYPE_SLID 4
#define TYPE_MOVE 5
#define CLIENT_MENU 0x100
#define CLIENT_FUNC 0x101
#define CLIENT_CHEK 0x102
#define CLIENT_SLID 0x103
#define CLIENT_MOVE 0x104
/* User actions, sent to item-handling functions as input.*/
#define MENU_SELECT 1
#define MENU_CHECK 2
#define MENU_PLUS 3
#define MENU_MINUS 4
#define MENU_READ 5
typedef struct menu_item {
char *text;
int type;
void *data;
} menu_item;
#define Menu menu_item *
int do_menu (Menu menu);
void menu_update_screen (MenuItem *item, Screen *s);
/* Updates the widgets of the selected menuitem
* Returns the new state.
*/
#endif
-381
View File
@@ -1,381 +0,0 @@
/*
* menus.c
* This file is part of LCDd, the lcdproc server.
*
* This file is released under the GNU General Public License. Refer to the
* COPYING file distributed with this package.
*
* Copyright (c) 1999, William Ferrell, Scott Scriven
*
*
* Defines the default menus the server provides. Also includes the
* plug-in functions attached to menu items...
*
* So far, all menus are static, and not dynamically generated. I'll
* have to find a way to fix this, since many menu items will be dynamic.
* (clients connected, screens available, etc...)
*
*/
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include "shared/report.h"
#include "drivers.h"
#include "drivers.h"
#include "main.h"
#include "menus.h"
#include "render.h"
#include "serverscreens.h"
int Shutdown_func ();
int System_halt_func ();
int Reboot_func ();
int Close_func ();
int OK_func ();
int Time24_func (int input);
int Heartbeat_func (int input);
int Backlight_func (int input);
int Server_screen_func (int input);
int Contrast_func (int input);
int Backlight_Brightness_func (int input);
int Backlight_Off_Brightness_func (int input);
int Backlight_Off_func ();
int Backlight_On_func ();
int Backlight_Open_func ();
menu_item main_menu[] = {
{"LCDproc", 0, 0}, /* Title*/
{"Options", TYPE_MENU, (void *) options_menu},
{"Screens", TYPE_MENU, (void *) screens_menu},
{"Shutdown", TYPE_MENU, (void *) shutdown_menu},
{0, 0, 0},
};
menu_item options_menu[] = {
{"OPTIONS", TYPE_TITL, 0}, /* Title*/
/* "24-hour Time", TYPE_CHEK, (void *)Time24_func,*/
{"Contrast...", TYPE_SLID, (void *) Contrast_func},
{"Backlight", TYPE_MENU, (void *) Backlight_menu},
{"Heartbeat", TYPE_CHEK, (void *) Heartbeat_func},
/* { "Backlight...", TYPE_SLID, (void *)Backlight_func},
* "OK", TYPE_FUNC, (void *)OK_func,
* "Close Menu", TYPE_FUNC, (void *)Close_func,
* "Exit Program", TYPE_FUNC, (void *)Shutdown_func,
* "Another Title",TYPE_TITL, 0,
* "Main menu?", TYPE_MENU, (void *)main_menu,
* "Nothing!", TYPE_FUNC, 0,
*/
{0, 0, 0},
};
menu_item screens_menu[] = {
{"SCREENS", TYPE_TITL, 0}, /* Title*/
{"Server Scr", TYPE_CHEK, (void *) Server_screen_func},
{0, 0, 0},
};
menu_item shutdown_menu[] = {
{"Shut Down...", TYPE_TITL, 0}, /* Title*/
{"Kill LCDproc", TYPE_FUNC, (void *) Shutdown_func},
{"System halt", TYPE_FUNC, (void *) System_halt_func},
{"Reboot", TYPE_FUNC, (void *) Reboot_func},
{0, 0, 0},
};
menu_item Backlight_menu[] = {
{"BACKLIGHT MENU", TYPE_TITL, 0}, /* Title*/
{"Brightness...", TYPE_SLID, (void *) Backlight_Brightness_func},
{"\"Off\" Brightness", TYPE_SLID, (void *) Backlight_Off_Brightness_func},
{"Backlight Mode:", TYPE_FUNC, 0}, /* Label*/
{" - Off", TYPE_FUNC, Backlight_Off_func},
{" - On", TYPE_FUNC, Backlight_On_func},
{" - Open", TYPE_FUNC, Backlight_Open_func},
{0, 0, 0},
};
/************************************************************************
* Plug-in functions for menu items
*/
/* Exits the program.*/
int
Shutdown_func ()
{
exit_program (0);
return MENU_KILL;
}
/* Shuts down the system, if possible*/
int
System_halt_func ()
{
int err;
uid_t id;
id = geteuid ();
err = system ("init 0");
if (err < 0)
return MENU_KILL;
if (err == 127)
return MENU_KILL;
/* If we're root, exit*/
if (id == 0)
exit_program (0);
/* Otherwise, assume shutdown will fail; and show more stats.*/
return MENU_KILL;
}
/* Shuts down the system and restarts it*/
int
Reboot_func ()
{
int err;
uid_t id;
id = geteuid ();
err = system ("init 6");
if (err < 0)
return MENU_KILL;
if (err == 127)
return MENU_KILL;
/* If we're root, exit*/
if (id == 0)
exit_program (0);
/* Otherwise, assume shutdown will fail; and show more stats.*/
return MENU_KILL;
}
int
Close_func ()
{
return MENU_CLOSE;
}
int
OK_func ()
{
return MENU_OK;
}
int
Time24_func (int input)
{
static int status = 0;
if (input == MENU_READ)
return status;
if (input == MENU_CHECK)
status ^= 1; /* does something.*/
return (status | MENU_OK);
/* The status is "or"-ed with the MENU value to let do_menu()
* know what to do after selecting the item. (two return
* values in one. :)
*/
/* Also, "MENU_OK" happens to be zero, so it does not matter
* unless you want something else (like MENU_CLOSE)
*/
}
int
Heartbeat_func (int input)
{
if (input == MENU_READ)
return (heartbeat != HEARTBEAT_OFF);
if (input == MENU_CHECK) {
if (heartbeat)
heartbeat = HEARTBEAT_OFF;
else
heartbeat = HEARTBEAT_OPEN;
}
return ((heartbeat != HEARTBEAT_OFF) | MENU_OK);
}
int
Backlight_func (int input)
{
int status = 128;
switch (backlight) {
case BACKLIGHT_OFF:
if (input == MENU_READ)
status = 0;
if (input == MENU_PLUS) {
backlight = BACKLIGHT_OPEN;
status = 128;
}
if (input == MENU_MINUS) {
status = 0;
}
break;
case BACKLIGHT_ON:
if (input == MENU_READ)
status = 255;
if (input == MENU_PLUS) {
status = 255;
}
if (input == MENU_MINUS) {
backlight = BACKLIGHT_OPEN;
status = 128;
}
break;
case BACKLIGHT_OPEN:
if (input == MENU_READ)
status = 128;
if (input == MENU_PLUS) {
backlight = BACKLIGHT_ON;
backlight_state = BACKLIGHT_ON;
status = 255;
}
if (input == MENU_MINUS) {
backlight = BACKLIGHT_OFF;
backlight_state = BACKLIGHT_OFF;
status = 0;
}
break;
}
/*
if(input == MENU_READ) return (backlight != BACKLIGHT_OFF);
if(input == MENU_CHECK)
{
if(backlight) backlight = BACKLIGHT_OFF;
else backlight = BACKLIGHT_OPEN;
}
*/
drivers_backlight (backlight_state & BACKLIGHT_ON);
return (status | MENU_OK);
}
int
Server_screen_func (int input)
{
if (input == MENU_READ)
return (server_screen->priority < 256);
if (input == MENU_CHECK) {
if (server_screen->priority < 256)
server_screen->priority = 256;
else
server_screen->priority = DEFAULT_SCREEN_PRIORITY;
}
return (MENU_OK | (server_screen->priority < 256));
}
int
Contrast_func (int input)
{
static int status = 500;
status = drivers_get_contrast ();
if (input == MENU_READ)
return status;
if (input == MENU_PLUS)
status += 5; /* does something.*/
if (input == MENU_MINUS)
status -= 5; /* does something.*/
if (status < 0)
status = 0;
if (status > 1000)
status = 1000;
drivers_set_contrast (status);
return (status | MENU_OK);
}
void
server_menu ()
{
debug (RPT_DEBUG, "server_menu()");
do_menu (main_menu);
}
int
Backlight_Brightness_func (int input)
{
int status = backlight_brightness;
if (input == MENU_READ)
return status;
if (input == MENU_PLUS)
status += 5; /* does something.*/
if (input == MENU_MINUS)
status -= 5; /* does something.*/
if (status < 0)
status = 0;
if (status > 255)
status = 255;
drivers_backlight (status);
backlight_brightness = status;
return (status | MENU_OK);
}
int
Backlight_Off_Brightness_func (int input)
{
int status = backlight_off_brightness;
if (input == MENU_READ)
return status;
if (input == MENU_PLUS)
status += 5; /* does something.*/
if (input == MENU_MINUS)
status -= 5; /* does something.*/
if (status < 0)
status = 0;
if (status > 255)
status = 255;
drivers_backlight (status);
backlight_off_brightness = status;
return (status | MENU_OK);
}
int
Backlight_Off_func ()
{
backlight_state = BACKLIGHT_OFF;
backlight = BACKLIGHT_OFF;
drivers_backlight (backlight_off_brightness);
return MENU_OK;
}
int
Backlight_On_func ()
{
backlight_state = BACKLIGHT_ON;
backlight = BACKLIGHT_ON;
drivers_backlight (backlight_brightness * (backlight_state & BACKLIGHT_ON));
return MENU_OK;
}
int
Backlight_Open_func ()
{
backlight = BACKLIGHT_OPEN;
return MENU_OK;
}
-27
View File
@@ -1,27 +0,0 @@
/*
* menus.h
* This file is part of LCDd, the lcdproc server.
*
* This file is released under the GNU General Public License. Refer to the
* COPYING file distributed with this package.
*
* Copyright (c) 1999, William Ferrell, Scott Scriven
*
*/
#ifndef MENUS_H
#define MENUS_H
#include "menu.h"
/* These probably don't need to be defined here... */
extern menu_item main_menu[];
extern menu_item options_menu[];
extern menu_item screens_menu[];
extern menu_item shutdown_menu[];
extern menu_item Backlight_menu[];
/* Brings up the main menu... */
void server_menu ();
#endif
+18
View File
@@ -0,0 +1,18 @@
/*
* menuscreens.c
* This file is part of LCDd, the lcdproc server.
*
* This file is released under the GNU General Public License. Refer to the
* COPYING file distributed with this package.
*
* Copyright (c) 1999, William Ferrell, Scott Scriven
* 2002, Joris Robijn
*
*
* Creates the server menu screen (s).
* Handles the keypresses for this screen.
*
*/
#include "menuscreens.h"
+22
View File
@@ -0,0 +1,22 @@
/*
* menuscreens.h
* This file is part of LCDd, the lcdproc server.
*
* This file is released under the GNU General Public License. Refer to the
* COPYING file distributed with this package.
*
* Copyright (c) 1999, William Ferrell, Scott Scriven
*
* Creates all menuscreens, menus and handles the keypresses for the
* menuscreens.
*/
#ifndef MENUSCREENS_H
#define MENUSCREENS_H
#include "menu.h"
MenuEventFuncResult menuscreen_key_handler ();
/* This handler should be called by the real handler for the event */
#endif
+104 -109
View File
@@ -24,7 +24,7 @@
#include "shared/sockets.h"
#include "shared/report.h"
#include "clients.h"
#include "client_functions.h"
#include "commands/command_list.h"
#include "parse.h"
/* This is a big function... TOO big. How to trim....
@@ -38,7 +38,7 @@ parse_all_client_messages ()
{
int i; /* int j, len;*/
/*int newtoken, inquote;*/
client *c;
Client * c;
char *str, *p, *q, *s;
/* char *tok;*/
int argc;
@@ -60,130 +60,125 @@ parse_all_client_messages ()
#define LINE_TERM_CHAR '\0'
#define COMMENT_CHAR '#'
/*debug("parse: Rewinding list...");*/
LL_Rewind (clients);
do {
/* Get the next client...*/
/*debug("parse: Getting client...");*/
c = LL_Get (clients);
if (c) {
/* And parse all its messages...*/
/*debug(RPT_DEBUG, "parse: Getting messages...");*/
for (str = client_get_message (c); str; str = client_get_message (c)) {
debug (RPT_DEBUG, "parse: ...%s", str);
/* Now, split up the string...*/
argc = 0;
i = 0;
q = p = str;
for( c=clients_getfirst(); c; c=clients_getnext()) {
if (*p == COMMENT_CHAR) {
continue; /* found a comment line - skip it...*/
/* And parse all its messages...*/
/*debug(RPT_DEBUG, "parse: Getting messages...");*/
for (str = client_get_message (c); str; str = client_get_message (c)) {
debug (RPT_DEBUG, "parse: ...%s", str);
/* Now, split up the string...*/
argc = 0;
i = 0;
q = p = str;
if (*p == COMMENT_CHAR) {
continue; /* found a comment line - skip it...*/
}
debug (RPT_DEBUG, "starting string scan...");
do {
/* bypass initial white space...*/
while ((*p == SEPARATOR_CHAR) && (*p)) {
p++;
q++;
}
debug (RPT_DEBUG, "starting string scan...");
/* 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)
*/
do {
/* bypass initial white space...*/
while ((*p == SEPARATOR_CHAR) && (*p)) {
p++;
q++;
}
/* If (*p) is null here, we reached the end of
* an empty parameter... so one of two things
* is true:
if (*p == LINE_TERM_CHAR) {
break;
/* if there are no arguments, argc == 0 and will fail
* appropriately...
*
* 1. There is nothing but white space on this line (odd..)
* 2. This is trailing white space (odd... but allowable)
* if this is trailing white space, ignore the argc++ at the
* end and claim this as the end...
*/
}
/* Handle quoted strings...*/
if ((s = strchr(leftquote, *p)) != NULL) {
quoteindex = s - leftquote;
/*debug(RPT_DEBUG, "found <%c> at index [%d] = <%c>", *p, quoteindex, leftquote[quoteindex]);*/
q = ++p; /* past open quote...*/
while ((rightquote[quoteindex] != *p) && (*p != LINE_TERM_CHAR)) {
p++;
}
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...
/* We just sucked up the rest of the command line: ERROR!!*/
snprintf (errmsg, sizeof(errmsg), "huh? unterminated string! missing ending %c\n",
rightquote[quoteindex]);
sock_send_string (c->sock, errmsg);
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?
*/
}
/* Handle quoted strings...*/
if ((s = strchr(leftquote, *p)) != NULL) {
quoteindex = s - leftquote;
/*debug(RPT_DEBUG, "found <%c> at index [%d] = <%c>", *p, quoteindex, leftquote[quoteindex]);*/
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!!*/
snprintf (errmsg, sizeof(errmsg), "huh? unterminated string! missing ending %c\n",
rightquote[quoteindex]);
sock_send_string (c->sock, errmsg);
if (*p != SEPARATOR_CHAR && *p != LINE_TERM_CHAR) {
sock_send_string (c->sock, "huh? improperly terminated string! (missing whitespace)\n");
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;
}
}
/* Otherwise, normal string...*/
} else {
while (*p != SEPARATOR_CHAR && *p != LINE_TERM_CHAR)
p++;
}
/* Not end of line?*/
if (*p) {
*p = LINE_TERM_CHAR;
/*debug(RPT_DEBUG, "found new token: %s", q);*/
argv[i++] = q;
q = ++p;
} else {
/*debug(RPT_DEBUG, "found new token: %s", 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++;
} while (*p);
/*debug(RPT_DEBUG, "exiting string scan...");*/
argv[argc] = NULL;
if (argc < 1)
continue;
/* Now find and call the appropriate function...*/
invalid = 1;
for (i = 0; commands[i].keyword; i++) {
if (0 == strcmp (argv[0], commands[i].keyword)) {
invalid = commands[i].function (c, argc, argv);
break; /* found our function - don't continue on...*/
}
/* Otherwise, normal string...*/
} else {
while (*p != SEPARATOR_CHAR && *p != LINE_TERM_CHAR)
p++;
}
if (invalid) {
snprintf (errmsg, sizeof(errmsg), "huh? Invalid command \"%s\"\n", argv[0]);
sock_send_string (c->sock, errmsg);
/* Not end of line?*/
if (*p) {
*p = LINE_TERM_CHAR;
/*debug(RPT_DEBUG, "found new token: %s", q);*/
argv[i++] = q;
q = ++p;
} else {
/*debug(RPT_DEBUG, "found new token: %s", 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.
*/
free (str); /* fixed memory leak?*/
} /* end for(str...)*/
} /* end if (c)*/
} while (LL_Next (clients) == 0);
argc++;
} while (*p);
/*debug(RPT_DEBUG, "exiting string scan...");*/
argv[argc] = NULL;
if (argc < 1)
continue;
/* Now find and call the appropriate function...*/
invalid = 1;
for (i = 0; commands[i].keyword; i++) {
if (0 == strcmp (argv[0], commands[i].keyword)) {
invalid = commands[i].function (c, argc, argv);
break; /* found our function - don't continue on...*/
}
}
if (invalid) {
snprintf (errmsg, sizeof(errmsg), "huh? Invalid command \"%.40s\"\n", argv[0]);
sock_send_string (c->sock, errmsg);
}
free (str); /* fixed memory leak?*/
} /* end for(str...)*/
}
return 0;
}
+34 -31
View File
@@ -53,9 +53,9 @@ static int reset;
static int draw_frame (LinkedList * list, char fscroll, int left, int top, int right, int bottom, int fwid, int fhgt, int fspeed, int timer);
int
draw_screen (screen * s, int timer)
draw_screen (Screen * s, int timer)
{
static screen *old_s = NULL;
static Screen * old_s = NULL;
int tmp = 0, tmp_state = 0;
report(RPT_INFO, "draw_screen( screen=\"%.40s\", timer=%d ) ==== START RENDERING ====", s->name, timer );
@@ -82,10 +82,10 @@ draw_screen (screen * s, int timer)
* inherit the backlight state from the parent client. This allows
* the client to override it's childrens settings.
*/
if (s->backlight_state == BACKLIGHT_NOTSET) {
if (s->parent) tmp_state = s->parent->backlight_state;
if (s->backlight == BACKLIGHT_OPEN) {
if (s->client) tmp_state = s->client->backlight;
} else {
tmp_state = s->backlight_state;
tmp_state = s->backlight;
}
/* Set up backlight to the correct state... */
@@ -126,7 +126,7 @@ draw_screen (screen * s, int timer)
drivers_output (output_state);
/* Draw a frame... */
draw_frame (s->widgets, 'v', 0, 0, display_props->width, display_props->height, s->wid, s->hgt, (((s->duration / s->hgt) < 1) ? 1 : (s->duration / s->hgt)), timer);
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);
/*debug(RPT_DEBUG, "draw_screen done"); */
@@ -176,12 +176,12 @@ draw_frame (LinkedList * list,
#define VerticalScrolling (fscroll == 'v')
#define HorizontalScrolling (fscroll == 'h')
char str[BUFSIZE]; /* scratch buffer */
widget *w;
char str[BUFSIZE]; /* scratch buffer */
Widget * w;
int wid, hgt; /* Width and height of visible frame area */
int vis_width, vis_height; /* Width and height of visible frame area */
int x, y;
int fx, fy; /* Scrolling offset for the frame... */
int fx, fy; /* Scrolling offset for the frame... */
int length, speed;
/*int lines; */
@@ -191,8 +191,8 @@ draw_frame (LinkedList * list,
"right=%d, bottom=%d, fwid=%d, fhgt=%d, fspeed=%d, timer=%d )",
list, fscroll, left,top, right, bottom, fwid, fhgt, fspeed, timer );
wid = right - left; /* This is the size of the visible frame area */
hgt = bottom - top;
vis_width = right - left; /* This is the size of the visible frame area */
vis_height = bottom - top;
fx = 0;
fy = 0;
@@ -220,8 +220,8 @@ draw_frame (LinkedList * list,
}
fy %= fhgt;
if (fy > fhgt - hgt)
fy = fhgt - hgt;
if (fy > fhgt - vis_height)
fy = fhgt - vis_height;
} else if (HorizontalScrolling) {
/* TODO: Frames don't scroll horizontally yet! */
@@ -239,7 +239,7 @@ draw_frame (LinkedList * list,
LL_Rewind (list);
do {
w = (widget *) LL_Get (list);
w = (Widget *) LL_Get (list);
if (!w)
return -1;
@@ -247,10 +247,10 @@ draw_frame (LinkedList * list,
switch (w->type) {
case WID_STRING:
if (ValidPoint(w) && TextPresent(w)) {
if ((w->y <= hgt + fy) && (w->y > fy)) {
if (w->x > wid) w->x=wid;
strncpy (str, w->text, wid - w->x + 1);
str[wid - w->x + 1] = 0;
if ((w->y <= vis_height + fy) && (w->y > fy)) {
if (w->x > vis_width) w->x=vis_width;
strncpy (str, w->text, vis_width - w->x + 1);
str[vis_width - w->x + 1] = 0;
drivers_string (w->x + left, w->y + top - fy, str);
}
}
@@ -261,9 +261,9 @@ draw_frame (LinkedList * list,
reset = 0;
}
if ((w->x > 0) && (w->y > 0)) {
if ((w->y <= hgt + fy) && (w->y > fy)) {
if ((w->y <= vis_height + fy) && (w->y > fy)) {
if (w->length > 0) {
if ((w->length / display_props->cellwidth) < wid - w->x + 1) {
if ((w->length / display_props->cellwidth) < vis_width - w->x + 1) {
/*was: drivers_hbar (w->x + left, w->y + top - fy, w->length); */
/* improvised len and promille */
int full_len = display_props->width - w->x - left + 1;
@@ -311,13 +311,16 @@ draw_frame (LinkedList * list,
case WID_TITLE: /* FIXME: Doesn't work quite right in frames...*/
if (!w->text)
break;
if (wid < 8)
if (vis_width < 8)
break;
memset (str, 255, wid);
/*memset (str, 255, width);*/
memset (str, '*', vis_width);
/* TODO: Use icon function to draw the bar */
str[2] = ' ';
length = strlen (w->text);
if (length <= wid - 6) {
if (length <= vis_width - 6) {
memcpy (str + 3, w->text, length);
str[length + 3] = ' ';
} else /* Scroll the title, if it doesn't fit...*/
@@ -338,17 +341,17 @@ draw_frame (LinkedList * list,
x -= 3;
if (x < 0)
x = 0;
if (x > length - (wid - 6))
x = length - (wid - 6);
if (x > length - (vis_width - 6))
x = length - (vis_width - 6);
if (y & 1) /* Scrolling backwards...*/
{
x = (length - (wid - 6)) - x;
x = (length - (vis_width - 6)) - x;
}
strncpy (str + 3, w->text + x, (wid - 6));
str[wid - 3] = ' ';
strncpy (str + 3, w->text + x, (vis_width - 6));
str[vis_width - 3] = ' ';
}
str[wid] = 0;
str[vis_width] = 0;
drivers_string (1 + left, 1 + top, str);
break;
@@ -504,7 +507,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->kids, w->length, new_left, new_top, new_right, new_bottom, w->wid, w->hgt, w->speed, timer);
draw_frame (w->frame_screen->widgetlist, w->length, new_left, new_top, new_right, new_bottom, w->width, w->height, w->speed, timer);
}
}
break;
+6 -3
View File
@@ -17,7 +17,6 @@
#define HEARTBEAT_OFF 0
#define HEARTBEAT_ON 1
#define HEARTBEAT_OPEN 2
#define HEARTBEAT_SLASH 3
#define SERVER_SCREEN_NEVER 0
#define SERVER_SCREEN_NOSCREEN 1
@@ -26,17 +25,21 @@
#define BACKLIGHT_OFF 0
#define BACKLIGHT_ON 1
#define BACKLIGHT_OPEN 2
#define BACKLIGHT_NOTSET 3
#define BACKLIGHT_BLINK 0x100
#define BACKLIGHT_FLASH 0x200
#define CURSOR_OFF 0
#define CURSOR_DEFAULT_ON 1
#define CURSOR_BLOCK 4
#define CURSOR_UNDER 5
extern int heartbeat;
extern int backlight;
extern int backlight_state;
extern int backlight_brightness;
extern int backlight_off_brightness;
extern int output_state;
int draw_screen (screen * s, int timer);
int draw_screen (Screen * s, int timer);
#endif
+78 -109
View File
@@ -31,34 +31,45 @@
int default_duration = 0;
int default_timeout = -1;
screen *
screen_create ()
Screen *
screen_create (char * id, Client * client)
{
screen *s;
Screen *s;
s = malloc (sizeof (screen));
s = malloc (sizeof (Screen));
if (!s) {
report(RPT_ERR, "screen_create: Error allocating new screen");
report(RPT_ERR, "screen_create: Error allocating");
return NULL;
}
if (!id) {
report (RPT_ERR, "screen_create: Need id string");
return NULL;
}
/* Client can be NULL for serverscreens and other client-less screens */
s->id = strdup(id);
if (!s->id) {
report(RPT_ERR, "screen_create: Error allocating");
return NULL;
}
s->id = NULL;
s->name = NULL;
s->priority = DEFAULT_SCREEN_PRIORITY;
s->duration = default_duration;
s->heartbeat = DEFAULT_HEARTBEAT;
s->wid = display_props->width;
s->hgt = display_props->height;
s->backlight = BACKLIGHT_OPEN;
s->heartbeat = HEARTBEAT_OPEN;
s->width = display_props->width;
s->height = display_props->height;
s->keys = NULL;
s->parent = NULL;
s->widgets = NULL;
s->timeout = default_timeout; /*ignored unless greater than 0.*/
s->backlight_state = BACKLIGHT_NOTSET; /*Lets the screen do it's own*/
s->client = client;
s->widgetlist = NULL;
s->timeout = default_timeout; /*ignored unless greater than 0.*/
s->backlight = BACKLIGHT_OPEN; /*Lets the screen do it's own*/
/*or do what the client says.*/
s->widgets = LL_new ();
if (!s->widgets) {
report(RPT_ERR, "screen_create: Error allocating widget list");
s->widgetlist = LL_new ();
if (!s->widgetlist) {
report(RPT_ERR, "screen_create: Error allocating");
return NULL;
}
@@ -66,20 +77,18 @@ screen_create ()
}
int
screen_destroy (screen * s)
screen_destroy (Screen * s)
{
widget *w;
Widget *w;
if (!s)
return -1;
LL_Rewind (s->widgets);
do {
for (w=LL_GetFirst(s->widgetlist); w; w=LL_GetNext(s->widgetlist)) {
/* Free a widget...*/
w = LL_Get (s->widgets);
widget_destroy (w);
} while (LL_Next (s->widgets) == 0);
LL_Destroy (s->widgets);
}
LL_Destroy (s->widgetlist);
if (s->id)
free (s->id);
@@ -93,99 +102,59 @@ screen_destroy (screen * s)
return 0;
}
screen *
screen_find (client * c, char *id)
int
screen_add_widget (Screen * s, Widget * w)
{
screen *s;
report (RPT_INFO, "screen_add_widget(%s,%s)", s->id, w->id);
if (!s)
return -1;
if (!w)
return 1;
if (!c)
LL_Push (s->widgetlist, (void *) w);
return 0;
}
int
screen_remove_widget (Screen * s, Widget * w)
{
report (RPT_INFO, "screen_remove_widget(%s,%s)", s->id, w->id);
if (!s)
return -1;
if (!w)
return 1;
LL_Remove (s->widgetlist, (void *) w);
return 0;
}
Widget *
screen_find_widget (Screen * s, char *id)
{
Widget * w;
if (!s)
return NULL;
if (!id)
return NULL;
debug (RPT_INFO, "client_find_screen(%s)", id);
debug (RPT_DEBUG, "screen_find_widget(%s,%s)", s->id, id);
LL_Rewind (c->data->screenlist);
do {
s = LL_Get (c->data->screenlist);
if ((s) && (0 == strcmp (s->id, id))) {
debug (RPT_DEBUG, "client_find_screen: Found %s", id);
return s;
for ( w=LL_GetFirst(s->widgetlist); w; w=LL_GetNext(s->widgetlist) ) {
if (0 == strcmp (w->id, id)) {
debug (RPT_DEBUG, "screen_find_widget: Found %s", id);
return w;
}
} while (LL_Next (c->data->screenlist) == 0);
/* Search subscreens recursively */
if (w->type == WID_FRAME) {
w = widget_search_subs (w, id);
if (w)
return w;
}
}
debug (RPT_DEBUG, "screen_find_widget: Not found");
return NULL;
}
int
screen_add (client * c, char *id)
{
screen *s;
if (!c)
return -1;
if (!id)
return -1;
/* Make sure this screen doesn't already exist...*/
s = screen_find (c, id);
if (s) {
return 1;
}
s = screen_create ();
if (!s) {
report (RPT_ERR, "screen_add: Error creating screen");
return -1;
}
s->parent = c;
s->id = strdup (id);
if (!s->id) {
report (RPT_ERR, "screen_add: Error allocating name");
return -1;
}
/* TODO: Check for errors here?*/
LL_Push (c->data->screenlist, (void *) s);
/* Now, add it to the screenlist...*/
if (screenlist_add (s) < 0) {
report (RPT_ERR, "screen_add: Error queueing new screen");
return -1;
}
return 0;
}
int
screen_remove (client * c, char *id)
{
screen *s;
if (!c)
return -1;
if (!id)
return -1;
/* Make sure this screen *does* exist...*/
s = screen_find (c, id);
if (!s) {
report (RPT_ERR, "screen_remove: Error finding screen %s", id);
return 1;
}
/* TODO: Check for errors here?*/
LL_Remove (c->data->screenlist, (void *) s);
/* Now, remove it from the screenlist...*/
if (screenlist_remove_all (s) < 0) {
/* Not a serious error..*/
report (RPT_ERR, "screen_remove: Error dequeueing screen");
return 0;
}
/* TODO: Check for errors here too?*/
screen_destroy (s);
return 0;
}
+40 -17
View File
@@ -13,34 +13,57 @@
#define SCREEN_H
#include "shared/LL.h"
#include "clients.h"
typedef struct screen {
typedef struct Screen {
char *id;
char *name;
int wid, hgt;
int priority;
int width, height;
int duration;
int heartbeat;
int timeout;
int backlight_state;
int cursor;
int cursor_x;
int cursor_y;
short int priority;
short int heartbeat;
short int backlight;
short int cursor;
short int cursor_x;
short int cursor_y;
char *keys;
LinkedList *widgets;
client *parent;
} screen;
LinkedList *widgetlist;
struct Client *client;
} Screen;
#include "client.h"
#include "widget.h"
extern int default_duration ;
extern int default_priority ;
screen *screen_create ();
int screen_destroy (screen * s);
screen *screen_find (client * c, char *id);
/* Creates a new screen */
Screen * screen_create (char * id, Client * client);
int screen_add (client * c, char *id);
int screen_remove (client * c, char *id);
/* Destroys a screen */
int screen_destroy (Screen * s);
/* Add a widget to a screen */
int screen_add_widget (Screen * s, Widget * w);
/* Remove a widget from a screen (does not destroy it) */
int screen_remove_widget (Screen * s, Widget * w);
/* List functions */
static inline Widget * screen_getfirst_widget (Screen * s)
{
return LL_GetFirst(s->widgetlist);
}
static inline Widget * screen_getnext_widget (Screen * s)
{
return LL_GetNext(s->widgetlist);
}
/* Find a widget in a screen */
Widget *screen_find_widget (Screen * s, char *id);
#endif
+25 -25
View File
@@ -28,10 +28,10 @@ int timer = 0;
LinkedList *screenlist;
int screenlist_add_end (screen * screen);
screen *screenlist_next_roll ();
screen *screenlist_prev_roll ();
screen *screenlist_next_priority ();
int screenlist_add_end (Screen * screen);
Screen *screenlist_next_roll ();
Screen *screenlist_prev_roll ();
Screen *screenlist_next_priority ();
int compare_priority (void *one, void *two);
int compare_addresses (void *one, void *two);
@@ -64,7 +64,7 @@ screenlist_shutdown ()
}
int
screenlist_remove (screen * s)
screenlist_remove (Screen * s)
{
report (RPT_INFO, "screenlist_remove()");
@@ -75,7 +75,7 @@ screenlist_remove (screen * s)
}
int
screenlist_remove_all (screen * s)
screenlist_remove_all (Screen * s)
{
int i = 0;
@@ -97,19 +97,19 @@ screenlist_getlist ()
return screenlist;
}
screen *
Screen *
screenlist_current ()
{
char str[256];
screen *s;
static screen *old_s = NULL;
client *c;
Screen * s;
static Screen * old_s = NULL;
Client * c;
debug( RPT_INFO, "screenlist_current:");
/*LL_dprint(screenlist);*/
s = (screen *) LL_GetFirst (screenlist);
s = (Screen *) LL_GetFirst (screenlist);
/* FIXME: Make sure the screen/client exists!*/
if (s != old_s) {
@@ -124,7 +124,7 @@ screenlist_current ()
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->parent;
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);
@@ -138,7 +138,7 @@ screenlist_current ()
}
if (s) {
/*debug(RPT_DEBUG, "screenlist_current: listening to new screen");*/
c = s->parent;
c = s->client;
if (c) /* Tell the client we're paying attention...*/
{
snprintf (str, sizeof(str), "listen %s\n", s->id);
@@ -158,16 +158,16 @@ screenlist_current ()
}
int
screenlist_add (screen * s)
screenlist_add (Screen * s)
{
/* TODO: Different queueing modes...*/
return screenlist_add_end (s);
}
screen *
Screen *
screenlist_next ()
{
screen *s;
Screen *s;
/*debug(RPT_DEBUG, "Screenlist_next()");*/
@@ -194,10 +194,10 @@ screenlist_next ()
return s;
}
screen *
Screen *
screenlist_prev ()
{
screen *s;
Screen *s;
s = screenlist_current ();
@@ -219,7 +219,7 @@ screenlist_prev ()
/* Adds new screens to the end of the screenlist...*/
int
screenlist_add_end (screen * screen)
screenlist_add_end (Screen * screen)
{
debug (RPT_DEBUG, "screenlist_add_end()");
@@ -227,7 +227,7 @@ screenlist_add_end (screen * screen)
}
/* Simple round-robin approach to screen cycling...*/
screen *
Screen *
screenlist_next_roll ()
{
/*debug(RPT_DEBUG, "screenlist_next_roll()");*/
@@ -239,7 +239,7 @@ screenlist_next_roll ()
}
/* Strict priority queue approach...*/
screen *
Screen *
screenlist_next_priority ()
{
/*screen *s, *t;*/
@@ -254,7 +254,7 @@ screenlist_next_priority ()
}
/* Simple round-robin approach to screen cycling...*/
screen *
Screen *
screenlist_prev_roll ()
{
/*debug(RPT_DEBUG, "screenlist_prev_roll()");*/
@@ -268,7 +268,7 @@ screenlist_prev_roll ()
int
compare_priority (void *one, void *two)
{
screen *a, *b;
Screen *a, *b;
/*debug(RPT_DEBUG, "compare_priority: %8x %8x", one, two);*/
@@ -277,8 +277,8 @@ compare_priority (void *one, void *two)
if (!two)
return 0;
a = (screen *) one;
b = (screen *) two;
a = (Screen *) one;
b = (Screen *) two;
/*debug(RPT_DEBUG, "compare_priority: done?");*/
+6 -6
View File
@@ -28,13 +28,13 @@ int screenlist_init ();
int screenlist_shutdown ();
LinkedList *screenlist_getlist ();
screen *screenlist_current ();
Screen *screenlist_current ();
int screenlist_add (screen * s);
screen *screenlist_next ();
screen *screenlist_prev ();
int screenlist_add (Screen * s);
Screen *screenlist_next ();
Screen *screenlist_prev ();
int screenlist_remove (screen * s);
int screenlist_remove_all (screen * s);
int screenlist_remove (Screen * s);
int screenlist_remove_all (Screen * s);
#endif
+43 -40
View File
@@ -23,76 +23,68 @@
#include "shared/report.h"
#include "drivers.h"
#include "clients.h"
#include "screen.h"
#include "screenlist.h"
#include "widget.h"
#include "serverscreens.h"
screen *server_screen;
char *id = "ClientList";
char *name = "Client List";
Screen * server_screen;
char title[256] = "LCDproc Server";
char one[256] = "";
char two[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);}
#define WidgetString(w,a,b,t) {(w)->x=(a);(w)->y=(b);(w)->text=(t);}
int
server_screen_init ()
{
widget *w;
Widget * w;
debug (RPT_DEBUG, "server_screen_init");
server_screen = screen_create ();
server_screen = screen_create ("_server_screen", NULL);
if (!server_screen) {
report (RPT_ERR, "server_screen_init: Error allocating screen");
return -1;
}
server_screen->id = id;
server_screen->name = name;
server_screen->name = "Server screen";
server_screen->duration = 8; /* 1 second, instead of 4...*/
server_screen->priority = -1; /* TODO: use priorities good */
if (widget_add (server_screen, "title", "title", NULL, 1) != 0) {
report (RPT_ERR, "server_screen_init: internal error: could not add title widget");
}
if (widget_add (server_screen, "one", "string", NULL, 1) != 0) {
report (RPT_ERR, "server_screen_init: internal error: could not add title widget");
}
if (widget_add (server_screen, "two", "string", NULL, 1) != 0) {
report (RPT_ERR, "server_screen_init: internal error: could not add title widget");
}
if (widget_add (server_screen, "three", "string", NULL, 1) != 0) {
report (RPT_ERR, "server_screen_init: internal error: could not add title widget");
if ( (w = widget_create ("title", WID_TITLE, server_screen)) == NULL
|| screen_add_widget (server_screen, w) != 0
|| (w = widget_create ("one", WID_STRING, server_screen)) == NULL
|| screen_add_widget (server_screen, w) != 0
|| (w = widget_create ("two", WID_STRING, server_screen)) == NULL
|| screen_add_widget (server_screen, w) != 0
|| (w = widget_create ("three", WID_STRING, server_screen)) == NULL
|| screen_add_widget (server_screen, w) != 0
) {
report (RPT_ERR, "server_screen_init: Can't create widgets");
return -1;
}
/* Now, initialize all the widgets...*/
if ((w = widget_find (server_screen, "title")) != NULL) {
WidgetText(w,title);
if ((w = screen_find_widget (server_screen, "title")) != NULL) {
w->text = title;
} else
report (RPT_ERR, "server_screen_init: Can't find title");
if ((w = widget_find (server_screen, "one")) != NULL)
if ((w = screen_find_widget (server_screen, "one")) != NULL)
WidgetString(w,1,2,one)
else
report (RPT_ERR, "server_screen_init: Can't find widget one");
if ((w = widget_find (server_screen, "two")) != NULL)
if ((w = screen_find_widget (server_screen, "two")) != NULL)
WidgetString(w,1,3,two)
else
report (RPT_ERR, "server_screen_init: Can't find widget two");
if ((w = widget_find (server_screen, "three")) != NULL)
if ((w = screen_find_widget (server_screen, "three")) != NULL)
WidgetString(w,1,4,three)
else
report (RPT_ERR, "server_screen_init: Can't find widget three");
@@ -106,15 +98,15 @@ server_screen_init ()
}
static int
screen_count (client *c) {
screen_count (Client * c) {
int n;
n = 0;
LL_Rewind (c->data->screenlist);
LL_Rewind (c->screenlist);
do {
if (LL_Get (c->data->screenlist) != NULL)
if (LL_Get (c->screenlist) != NULL)
n++;
} while (LL_Next (c->data->screenlist) == 0);
} while (LL_Next (c->screenlist) == 0);
return n;
}
@@ -122,7 +114,7 @@ screen_count (client *c) {
int
update_server_screen (int timer)
{
client *c;
Client * c;
int num_clients;
/*screen *s;*/
int num_screens;
@@ -131,14 +123,22 @@ update_server_screen (int timer)
/*strcpy(title, "LCDproc Server");*/
/* Now get info on the number of connected clients...*/
num_clients = 0;
num_clients = clients_client_count();
/* ... and screens */
num_screens = 0;
LL_Rewind (clients);
do {
c = LL_Get (clients);
for (c = clients_getfirst (); c; c = clients_getnext () ) {
num_screens += client_screen_count(c);
}
/*
if (c) {
num_clients++;
num_screens += client_screen_count(c);
num_screens += screen_count(c);
*/
/* LL_Rewind (c->data->screenlist); */
/* do { */
/* s = LL_Get (c->data->screenlist); */
@@ -146,8 +146,11 @@ update_server_screen (int timer)
/* num_screens++; */
/* } */
/* } while (LL_Next (c->data->screenlist) == 0); */
/*
}
} while (LL_Next (clients) == 0);
}
*/
/* Format strings for the appropriate size display... */
if (display_props->height >= 3) {
+1 -1
View File
@@ -14,7 +14,7 @@
#include "screen.h"
extern screen *server_screen;
extern Screen * server_screen;
int server_screen_init ();
int update_server_screen (int timer);
+21 -14
View File
@@ -33,8 +33,11 @@
#include "shared/sockets.h"
#include "sock.h"
#include "client.h"
#include "clients.h"
#include "screen.h"
#include "shared/report.h"
#include "screenlist.h"
extern char bind_addr[64];
extern int lcd_port;
@@ -142,7 +145,7 @@ sock_poll_clients ()
struct sockaddr_in clientname;
size_t size;
struct timeval t;
client *c;
Client * c;
debug(RPT_INFO, "sock_poll_clients()");
@@ -162,22 +165,26 @@ sock_poll_clients ()
if (FD_ISSET (i, &read_fd_set)) {
if (i == orig_sock) {
/* Connection request on original socket. */
int new;
int new_sock;
size = sizeof (clientname);
new = accept (orig_sock, (struct sockaddr *) &clientname, &size);
if (new < 0) {
new_sock = accept (orig_sock, (struct sockaddr *) &clientname, &size);
if (new_sock < 0) {
report (RPT_ERR, "sock_poll_clients: Accept error");
return -1;
}
report (RPT_INFO, "sock_poll_clients: Connect from host %s:%hd on #%d",
inet_ntoa (clientname.sin_addr), ntohs (clientname.sin_port), new);
FD_SET (new, &active_fd_set);
inet_ntoa (clientname.sin_addr), ntohs (clientname.sin_port), new_sock);
FD_SET (new_sock, &active_fd_set);
fcntl (new, F_SETFL, O_NONBLOCK);
fcntl (new_sock, F_SETFL, O_NONBLOCK);
/* TODO: Create new "client" here... (done?)*/
if (client_create (new) == NULL) {
report( RPT_ERR, "sock_poll_clients: error creating client %i", i);
/* Create new client */
if ((c = client_create (new_sock)) == NULL) {
report( RPT_ERR, "sock_poll_clients: Error creating client %i", i);
return -1;
}
if (clients_add_client (c) != 0) {
report( RPT_ERR, "sock_poll_clients: Could not add client %i", i);
return -1;
}
} else {
@@ -189,10 +196,11 @@ sock_poll_clients ()
debug (RPT_DEBUG, "sock_poll_clients: ...done");
if (err < 0) {
/* TODO: Destroy a "client" here... (done?)*/
c = client_find_sock (i);
c = clients_find_client_by_sock (i);
if (c) {
/*sock_send_string(i, "bye\n");*/
client_destroy (c);
clients_remove_client (c);
close (i);
FD_CLR (i, &active_fd_set);
report (RPT_INFO, "sock_poll_clients: Closed connection %i", i);
@@ -200,7 +208,6 @@ sock_poll_clients ()
report (RPT_ERR, "sock_poll_clients: Can't find client %i", i);
}
} while (err > 0);
}
}
}
@@ -212,7 +219,7 @@ read_from_client (int filedes)
{
char buffer[MAXMSG];
int nbytes, i;
client *c;
Client * c;
report(RPT_DEBUG, "read_from_client()" );
@@ -241,7 +248,7 @@ read_from_client (int filedes)
if (buffer[i] == 0)
buffer[i] = '\n';
/* Enqueue a "client message" here...*/
c = client_find_sock (filedes);
c = clients_find_client_by_sock (filedes);
if (c) {
client_add_message (c, buffer);
} else
+59 -270
View File
@@ -23,7 +23,8 @@
#include "widget.h"
#include "render.h"
char *types[] = { "none",
char *typenames[] = {
"none",
"string",
"hbar",
"vbar",
@@ -32,32 +33,38 @@ char *types[] = { "none",
"scroller",
"frame",
"num",
/*"",*/
NULL,
};
static widget *widget_finder (LinkedList * list, char *id);
static int widget_remover (LinkedList * list, widget * w);
//static widget *widget_finder (LinkedList * list, char *id);
//static int widget_remover (LinkedList * list, widget * w);
widget *
widget_create ()
Widget *
widget_create (char *id, WidgetType type, Screen * screen)
{
widget *w;
Widget * w;
report (RPT_INFO, "widget_create()");
report (RPT_INFO, "widget_create(%s,%d)", id, type);
w = malloc (sizeof (widget));
/* Create it */
w = malloc (sizeof (Widget));
if (!w) {
report (RPT_DEBUG, "widget_create: Error allocating widget");
report (RPT_DEBUG, "widget_create: Error allocating");
return NULL;
}
w->id = NULL;
w->type = 0;
w->id = strdup(id);
if (!w->id) {
report (RPT_DEBUG, "widget_create: Error allocating");
return NULL;
}
w->type = type;
w->screen = screen;
w->x = 1;
w->y = 1;
w->wid = 0;
w->hgt = 0;
w->width = 0;
w->height = 0;
w->left = 1;
w->top = 1;
w->right = 0;
@@ -65,22 +72,30 @@ widget_create ()
w->length = 1;
w->speed = 1;
w->text = NULL;
w->kids = NULL;
//w->kids = NULL;
if (w->type == WID_FRAME) {
/* create a screen for the frame widget */
char * frame_name;
frame_name = malloc (strlen("frame_") + strlen(id) + 1);
strcpy (frame_name, "frame_");
strcat (frame_name, id);
w->frame_screen = screen_create (frame_name, screen->client);
free (frame_name); /* not needed anymore */
}
return w;
}
int
widget_destroy (widget * w)
widget_destroy (Widget * w)
{
LinkedList *list;
widget *foo;
debug (RPT_INFO, "widget_destroy(%s)", w->id);
if (!w)
return -1;
debug (RPT_INFO, "widget_destroy(%s)", w->id);
if (w->id)
free (w->id);
/*debug(RPT_DEBUG, "widget_destroy: id...");*/
@@ -88,18 +103,13 @@ widget_destroy (widget * w)
free (w->text);
/*debug(RPT_DEBUG, "widget_destroy: text...");*/
/* TODO: Free kids!*/
if (w->kids) {
list = w->kids;
LL_Rewind (list);
do {
foo = LL_Get (list);
if (foo)
widget_destroy (foo);
} while (0 == LL_Next (list));
if (w->type == WID_FRAME) {
/* TODO: create a screen for the frame widget */
}
LL_Destroy (list);
w->kids = NULL;
/* Free subscreen of frame widget too */
if (w->type == WID_FRAME) {
screen_destroy (w->frame_screen);
}
free (w);
@@ -108,254 +118,33 @@ widget_destroy (widget * w)
return 0;
}
widget *
widget_find (screen * s, char *id)
{
/*widget *w, *err;*/
if (!s)
return NULL;
if (!id)
return NULL;
debug (RPT_DEBUG, "widget_find(%s)", id);
return widget_finder (s->widgets, id);
}
widget *
widget_finder (LinkedList * list, char *id)
{
widget *w, *err;
if (!list)
return NULL;
if (!id)
return NULL;
debug (RPT_DEBUG, "widget_finder(%s)", id);
LL_Rewind (list);
do {
/*debug(RPT_DEBUG, "widget_finder: Iteration");*/
w = LL_Get (list);
if (w) {
/*debug(RPT_DEBUG, "widget_finder: ...");*/
if (0 == strcmp (w->id, id)) {
debug (RPT_DEBUG, "widget_finder: Found %s", id);
return w;
}
/* Search kids recursively*/
/*debug(RPT_DEBUG, "widget_finder: ...");*/
if (w->type == WID_FRAME) {
err = widget_finder (w->kids, id);
if (err)
return err;
}
/*debug(RPT_DEBUG, "widget_finder: ...");*/
}
} while (LL_Next (list) == 0);
return NULL;
}
int
widget_add (screen * s, char *id, char *type, char *in, int sock)
WidgetType
widget_typename_to_type (char * typename)
{
WidgetType wid_type = WID_NONE;
int i;
int valid = 0;
int wid_type = 0;
widget *w, *parent;
LinkedList *list;
report (RPT_INFO, "widget_add(%s, %s, %s)", id, type, in);
if (!s)
return -1;
if (!id)
return -1;
list = s->widgets;
if (0 == strcmp (id, "heartbeat")) {
s->heartbeat = HEARTBEAT_ON; /* was 1*/
return 0;
}
/* Make sure this screen doesn't already exist...*/
w = widget_find (s, id);
if (w) {
/* already exists*/
sock_send_string (sock, "huh? You already have a widget with that id#\n");
return 1;
}
/* Make sure the container, if any, is real*/
if (in) {
parent = widget_find (s, in);
if (!parent) {
/* no frame to use as parent*/
sock_send_string (sock, "huh? Frame doesn't exist\n");
return 3;
} else {
if (parent->type == WID_FRAME) {
list = parent->kids;
if (!list)
report (RPT_DEBUG, "widget_add: Parent has no kids");
} else {
/* no frame to use as parent*/
sock_send_string (sock, "huh? Not a frame\n");
return 4;
}
}
}
/* Make sure it's a valid widget type*/
for (i = 1; types[i]; i++) {
if (0 == strcmp (types[i], type)) {
valid = 1;
for (i = 0; typenames[i]; i++) {
if (strcmp (typenames[i], typename) == 0) {
wid_type = i;
break; /* it's valid: skip out...*/
}
}
return wid_type;
}
if (!valid) {
/* invalid widget type*/
sock_send_string (sock, "huh? Invalid widget type\n");
return 2;
}
char *
widget_type_to_typename (WidgetType t)
{
return typenames[t];
}
debug (RPT_DEBUG, "widget_add: making widget");
/* Now, make it...*/
w = widget_create ();
if (!w) {
report (RPT_ERR, "widget_add: Error creating widget");
return -1;
}
w->id = strdup (id);
if (!w->id) {
report (RPT_ERR, "widget_add: Error allocating id");
return -1;
}
w->type = wid_type;
/* Set up the container's widget list...*/
Widget *
widget_search_subs (Widget * w, char * id)
{
if (w->type == WID_FRAME) {
if (!w->kids) {
w->kids = LL_new ();
if (!w->kids) {
report (RPT_ERR, "widget_add: error allocating kids for frame");
return -1;
}
}
return screen_find_widget (w->frame_screen, id);
} else {
return NULL; /* no kids */
}
/* TODO: Check for errors here?*/
LL_Push (list, (void *) w);
return 0;
}
int
widget_remove (screen * s, char *id, int sock)
{
widget *w;
LinkedList *list;
report (RPT_INFO, "widget_remove(%s)", id);
if (!s)
return -1;
if (!id)
return -1;
list = s->widgets;
if (0 == strcmp (id, "heartbeat")) {
s->heartbeat = HEARTBEAT_OFF; /* was 0*/
return 0;
}
/* Make sure this screen *does* exist...*/
w = widget_find (s, id);
if (!w) {
sock_send_string (sock, "huh? You don't have a widget with that id#\n");
report (RPT_ERR, "widget_remove: Error finding widget %s", id);
return 1;
}
/* TODO: Check for errors here?
* TODO: Make this work with frames...
* LL_Remove(list, (void *)w);
*/
/* TODO: Check for errors here?
* widget_destroy(w);
*/
return widget_remover (list, w);
/* return 0;*/
}
int
widget_remover (LinkedList * list, widget * w)
{
widget *foo, *bar;
int err;
debug (RPT_DEBUG, "widget_remover");
if (!list)
return 0;
if (!w)
return 0;
/* Search through the list...*/
LL_Rewind (list);
do {
/* Test each item*/
foo = LL_Get (list);
if (foo) {
/* Frames require recursion to search and/or destroy*/
if (foo->type == WID_FRAME) {
/* If removing a frame, kill all its kids, too...*/
if (foo == w) {
if (!foo->kids) {
debug (RPT_DEBUG, "widget_remover: frame has no kids");
} else /* Kill the kids...*/
{
LL_Rewind (foo->kids);
do {
bar = LL_Get (foo->kids);
err = widget_remover (foo->kids, bar);
} while (0 == LL_Next (foo->kids));
/* Then kill the parent...*/
LL_Remove (list, (void *) w);
widget_destroy (w);
}
} else /* Otherwise, search the frame recursively...*/
{
if (!foo->kids) {
debug (RPT_DEBUG, "widget_remover: frame has no kids");
} else
err = widget_remover (foo->kids, w);
}
} else /* If not a frame, remove it if it matches...*/
{
if (foo == w) {
LL_Remove (list, (void *) w);
widget_destroy (w);
}
}
}
} while (0 == LL_Next (list));
return 0;
}
+39 -29
View File
@@ -12,42 +12,52 @@
#ifndef WIDGET_H
#define WIDGET_H
#include "screen.h"
typedef struct widget {
char *id;
int type;
/* some sort of data here...*/
int x, y; /* Position*/
int wid, hgt; /* Size*/
int left, top, right, bottom; /* bounding rectangle*/
int length; /* size or direction*/
int speed; /* For scroller...*/
char *text; /* text or binary data*/
LinkedList *kids; /* Frames can contain more widgets...*/
} widget;
struct Widget;
/* These correspond to the index into the "types" array...*/
#define WID_NONE 0
#define WID_STRING 1
#define WID_HBAR 2
#define WID_VBAR 3
#define WID_ICON 4
#define WID_TITLE 5
#define WID_SCROLLER 6
#define WID_FRAME 7
#define WID_NUM 8
typedef enum WidgetType {
WID_NONE = 0,
WID_STRING,
WID_HBAR,
WID_VBAR,
WID_ICON,
WID_TITLE,
WID_SCROLLER,
WID_FRAME,
WID_NUM
} WidgetType;
typedef struct Widget {
char *id;
WidgetType type;
Screen * screen; /* What screen is this widget in ? */
int x, y; /* Position */
int width, height; /* Visible size */
int left, top, right, bottom; /* bounding rectangle */
int length; /* size or direction */
int speed; /* For scroller... */
char *text; /* text or binary data */
struct Screen * frame_screen; /* frame widget get an associated screen */
//LinkedList *kids; /* Frames can contain more widgets...*/
} Widget;
#include "screen.h"
#define WID_MAX_DIR 4
extern char *types[];
/* Create new widget */
Widget * widget_create (char *id, WidgetType type, Screen * screen);
widget *widget_create ();
int widget_destroy (widget * w);
/* Destroy a widget */
int widget_destroy (Widget * w);
widget *widget_find (screen * s, char *id);
/* Convert a widget typename to a widget type */
WidgetType widget_typename_to_type (char * typename);
int widget_add (screen * s, char *id, char *type, char *in, int sock);
int widget_remove (screen * s, char *id, int sock);
/* Convert a widget typename to a widget type */
char *widget_type_to_typename (WidgetType t);
/* Search subwidgets of a widget */
Widget * widget_search_subs (Widget * w, char * id);
#endif