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:
@@ -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
@@ -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
@@ -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);
|
||||
}
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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},
|
||||
};
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
@@ -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) */
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -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"
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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) {
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user