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
|
AC_OUTPUT(Makefile
|
||||||
shared/Makefile
|
shared/Makefile
|
||||||
server/Makefile
|
server/Makefile
|
||||||
|
server/commands/Makefile
|
||||||
server/drivers/Makefile
|
server/drivers/Makefile
|
||||||
clients/Makefile
|
clients/Makefile
|
||||||
clients/lcdproc/Makefile
|
clients/lcdproc/Makefile
|
||||||
|
|||||||
+3
-3
@@ -1,5 +1,5 @@
|
|||||||
SUBDIRS=drivers
|
SUBDIRS=drivers commands
|
||||||
sbin_PROGRAMS=LCDd
|
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_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
|
LCDd_LDADD = ../shared/libLCDstuff.a commands/libLCDcommands.a
|
||||||
INCLUDES = -I$(top_srcdir)
|
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.
|
* COPYING file distributed with this package.
|
||||||
*
|
*
|
||||||
* Copyright (c) 1999, William Ferrell, Scott Scriven
|
* Copyright (c) 1999, William Ferrell, Scott Scriven
|
||||||
|
* 2002, Joris Robijn
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* Inits/shuts down client system,
|
* Inits/shuts down client system,
|
||||||
* creates/destroys individual clients,
|
|
||||||
* enqueues/dequeues messages from clients,
|
|
||||||
* and searches for clients in the list.
|
* 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 <string.h>
|
||||||
|
|
||||||
#include "sock.h"
|
#include "sock.h"
|
||||||
|
#include "client.h"
|
||||||
#include "clients.h"
|
#include "clients.h"
|
||||||
#include "client_data.h"
|
|
||||||
#include "shared/report.h"
|
#include "shared/report.h"
|
||||||
#include "render.h"
|
#include "render.h"
|
||||||
|
|
||||||
LinkedList *clients;
|
LinkedList *clientlist;
|
||||||
|
|
||||||
/* Initialize and kill client list...*/
|
/* Initialize and kill client list...*/
|
||||||
int
|
int
|
||||||
client_init ()
|
clients_init ()
|
||||||
{
|
{
|
||||||
debug(RPT_INFO, "client_init()");
|
debug(RPT_INFO, "client_init()");
|
||||||
|
|
||||||
clients = LL_new ();
|
clientlist = LL_new ();
|
||||||
if (!clients) {
|
if (!clientlist) {
|
||||||
report( RPT_ERR, "client_init: Unable to create client list");
|
report( RPT_ERR, "client_init: Unable to create client list");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -46,220 +44,84 @@ client_init ()
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
client_shutdown ()
|
clients_shutdown ()
|
||||||
{
|
{
|
||||||
client *c;
|
Client *c;
|
||||||
|
|
||||||
debug (RPT_INFO, "client_shutdown()");
|
debug (RPT_INFO, "clients_shutdown()");
|
||||||
|
|
||||||
/* Free all client structures...
|
/* Free all client structures... */
|
||||||
* Note that the regular list loop doesn't work here, because
|
for (c=LL_GetFirst (clientlist); c; c=LL_GetNext (clientlist) ) {
|
||||||
* client_destroy() calls LL_Remove()
|
debug (RPT_DEBUG, "clients_shutdown: ...");
|
||||||
*/
|
|
||||||
for (c = LL_Pop (clients); c; c = LL_Pop (clients)) {
|
|
||||||
debug (RPT_DEBUG, "client_shutdown: ...");
|
|
||||||
if (c) {
|
if (c) {
|
||||||
debug (RPT_DEBUG, "client_shutdown: ... %i ...", c->sock);
|
debug (RPT_DEBUG, "clients_shutdown: ... %i ...", c->sock);
|
||||||
if (client_destroy (c) != 0) {
|
if (client_destroy (c) != 0) {
|
||||||
report (RPT_ERR, "client_shutdown: Error freeing client");
|
report (RPT_ERR, "clients_shutdown: Error freeing client");
|
||||||
} else {
|
} else {
|
||||||
debug (RPT_DEBUG, "client_shutdown: Freed client...");
|
debug (RPT_DEBUG, "clients_shutdown: Freed client...");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
debug (RPT_DEBUG, "client_shutdown: No client!");
|
debug (RPT_DEBUG, "clients_shutdown: No client!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Then, free the list...*/
|
/* Then, free the list...*/
|
||||||
LL_Destroy (clients);
|
LL_Destroy (clientlist);
|
||||||
|
|
||||||
debug (RPT_DEBUG, "client_shutdown: done");
|
debug (RPT_DEBUG, "clients_shutdown: done");
|
||||||
|
|
||||||
return 0;
|
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
|
/* A client is identified by the file descriptor
|
||||||
+ associated with it.
|
* associated with it. Find one.
|
||||||
*
|
|
||||||
* 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;
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Copy the string to avoid overwriting the original...*/
|
Client *
|
||||||
dup = strdup (message);
|
clients_find_client_by_sock (int sock)
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
char *str;
|
Client *c;
|
||||||
|
|
||||||
debug(RPT_DEBUG, "client_get_message()");
|
debug(RPT_INFO, "clients_find_client_by_sock(%i)", sock);
|
||||||
|
|
||||||
if (!c)
|
for( c=LL_GetFirst(clientlist); c; c=LL_GetNext(clientlist) ) {
|
||||||
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);*/
|
|
||||||
if (c->sock == sock) {
|
if (c->sock == sock) {
|
||||||
/* debug(RPT_DEBUG, "client_find_sock: ..! %i !..", c->sock);*/
|
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
} while (LL_Next (clients) == 0);
|
}
|
||||||
|
|
||||||
debug (RPT_ERR, "client_find_sock: failed");
|
debug (RPT_ERR, "client_find_sock: failed");
|
||||||
|
|
||||||
|
|||||||
+12
-26
@@ -12,39 +12,25 @@
|
|||||||
#ifndef CLIENTS_H
|
#ifndef CLIENTS_H
|
||||||
#define CLIENTS_H
|
#define CLIENTS_H
|
||||||
|
|
||||||
#include "client_data.h"
|
#include "client.h"
|
||||||
#include "shared/LL.h"
|
#include "shared/LL.h"
|
||||||
|
|
||||||
typedef struct client {
|
/* extern LinkedList *clientlist; Not needed outside ? */
|
||||||
int sock;
|
|
||||||
char addr[64];
|
|
||||||
int backlight_state;
|
|
||||||
LinkedList *messages;
|
|
||||||
client_data *data;
|
|
||||||
|
|
||||||
} client;
|
|
||||||
|
|
||||||
extern LinkedList *clients;
|
|
||||||
|
|
||||||
/* Initialize and kill client list...*/
|
/* Initialize and kill client list...*/
|
||||||
int client_init ();
|
int clients_init ();
|
||||||
int client_shutdown ();
|
int clients_shutdown ();
|
||||||
|
|
||||||
/* Create and destroy clients....*/
|
/* Add/remove clients (return -1 for error) */
|
||||||
client *client_create (int sock);
|
int clients_add_client (Client *c);
|
||||||
int client_destroy (client * c);
|
int clients_remove_client (Client *c);
|
||||||
|
|
||||||
/* Add and remove messages from the client's queue...*/
|
/* List functions */
|
||||||
int client_add_message (client * c, char *message);
|
Client * clients_getfirst ();
|
||||||
char *client_get_message (client * c);
|
Client * clients_getnext ();
|
||||||
|
int clients_client_count ();
|
||||||
/* 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);
|
|
||||||
|
|
||||||
/* Search for a client with a particular filedescriptor...*/
|
/* Search for a client with a particular filedescriptor...*/
|
||||||
client *client_find_sock (int sock);
|
Client * clients_find_client_by_sock (int sock);
|
||||||
|
|
||||||
#endif
|
#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 "drivers.h"
|
||||||
|
|
||||||
#include "client_data.h"
|
#include "client.h"
|
||||||
#include "clients.h"
|
#include "clients.h"
|
||||||
#include "screen.h"
|
#include "screen.h"
|
||||||
#include "widget.h"
|
#include "widget.h"
|
||||||
#include "screenlist.h"
|
#include "screenlist.h"
|
||||||
#include "menus.h"
|
//#include "menus.h"
|
||||||
|
|
||||||
#include "input.h"
|
#include "input.h"
|
||||||
|
|
||||||
#define KeyWanted(a,b) ((a) && strchr((a), (b)))
|
#define KeyWanted(a,b) ((a) && strchr((a), (b)))
|
||||||
#define CurrentScreen screenlist_current
|
#define CurrentScreen screenlist_current
|
||||||
#define FirstClient(a) (client *)LL_GetFirst(a);
|
|
||||||
#define NextClient(a) (client *)LL_GetNext(a);
|
|
||||||
|
|
||||||
int server_input (int key);
|
int server_input (int key);
|
||||||
|
|
||||||
@@ -69,9 +67,9 @@ handle_input ()
|
|||||||
{
|
{
|
||||||
char str[15];
|
char str[15];
|
||||||
int key;
|
int key;
|
||||||
screen *s;
|
Screen * s;
|
||||||
/*widget *w; */
|
/*Widget * w; */
|
||||||
client *c;
|
Client * c;
|
||||||
|
|
||||||
report (RPT_INFO, "handle_input()" );
|
report (RPT_INFO, "handle_input()" );
|
||||||
|
|
||||||
@@ -103,7 +101,7 @@ handle_input ()
|
|||||||
if (KeyWanted(s->keys, key)) {
|
if (KeyWanted(s->keys, key)) {
|
||||||
/* This screen wants this key. Tell it we got one */
|
/* This screen wants this key. Tell it we got one */
|
||||||
snprintf(str, sizeof(str), "key %c\n", key);
|
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 */
|
/* Nobody else gets this key */
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -114,17 +112,17 @@ handle_input ()
|
|||||||
else {
|
else {
|
||||||
/* Give key to clients who want it */
|
/* Give key to clients who want it */
|
||||||
|
|
||||||
c = FirstClient(clients);
|
c = clients_getfirst();
|
||||||
|
|
||||||
while (c) {
|
while (c) {
|
||||||
/* If the client should have this keypress... */
|
/* If the client should have this keypress... */
|
||||||
if(KeyWanted(c->data->client_keys,key)) {
|
if(KeyWanted(c->client_keys,key)) {
|
||||||
/* Send keypress to client */
|
/* Send keypress to client */
|
||||||
snprintf(str, sizeof(str), "key %c\n", key);
|
snprintf(str, sizeof(str), "key %c\n", key);
|
||||||
sock_send_string(c->sock, str);
|
sock_send_string(c->sock, str);
|
||||||
break; /* first come, first serve */
|
break; /* first come, first serve */
|
||||||
};
|
};
|
||||||
c = NextClient(clients);
|
c = clients_getnext();
|
||||||
} /* while clients */
|
} /* while clients */
|
||||||
|
|
||||||
/* Give server a shot at all keys */
|
/* Give server a shot at all keys */
|
||||||
@@ -156,7 +154,8 @@ server_input (int key)
|
|||||||
break;
|
break;
|
||||||
case INPUT_MAIN_MENU_KEY:
|
case INPUT_MAIN_MENU_KEY:
|
||||||
debug (RPT_DEBUG, "got the menu key!");
|
debug (RPT_DEBUG, "got the menu key!");
|
||||||
server_menu ();
|
//server_menu ();
|
||||||
|
report (RPT_ERR, "MENU TEMPORATY DISABLED");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
debug (RPT_DEBUG, "server_input: Unused key \"%c\" (%i)", (char) key, key);
|
debug (RPT_DEBUG, "server_input: Unused key \"%c\" (%i)", (char) key, key);
|
||||||
|
|||||||
+5
-4
@@ -526,7 +526,7 @@ init_sockets ()
|
|||||||
|
|
||||||
/* Now init a bunch of required stuff...*/
|
/* Now init a bunch of required stuff...*/
|
||||||
|
|
||||||
if (client_init () < 0) {
|
if (clients_init () < 0) {
|
||||||
report(RPT_ERR, "Error initializing client list");
|
report(RPT_ERR, "Error initializing client list");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -627,7 +627,7 @@ init_screens ()
|
|||||||
void
|
void
|
||||||
do_mainloop ()
|
do_mainloop ()
|
||||||
{
|
{
|
||||||
screen *s = NULL;
|
Screen *s = NULL;
|
||||||
char *message=NULL;
|
char *message=NULL;
|
||||||
|
|
||||||
report( RPT_INFO, "do_mainloop()" );
|
report( RPT_INFO, "do_mainloop()" );
|
||||||
@@ -708,7 +708,8 @@ do_mainloop ()
|
|||||||
free(message);
|
free(message);
|
||||||
}
|
}
|
||||||
if (s->timeout <= 0) {
|
if (s->timeout <= 0) {
|
||||||
screen_remove (s->parent, s->id);
|
client_remove_screen (s->client, s);
|
||||||
|
screen_destroy (s);
|
||||||
if((message = malloc(256)) == NULL)
|
if((message = malloc(256)) == NULL)
|
||||||
report(RPT_ERR, "Error allocating message string");
|
report(RPT_ERR, "Error allocating message string");
|
||||||
else {
|
else {
|
||||||
@@ -760,7 +761,7 @@ exit_program (int val)
|
|||||||
|
|
||||||
/* Shutdown things if server start was complete */
|
/* Shutdown things if server start was complete */
|
||||||
if( serverStarted ) {
|
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) */
|
screenlist_shutdown (); /* shutdown screens (must come after client_shutdown) */
|
||||||
sock_close_all (); /* close all open sockets (must come after client_shutdown) */
|
sock_close_all (); /* close all open sockets (must come after client_shutdown) */
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,8 +17,6 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "render.h"
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
contains a few things that other parts of the program might want
|
contains a few things that other parts of the program might want
|
||||||
to know about...
|
to know about...
|
||||||
@@ -35,11 +33,6 @@ void exit_program (int val);
|
|||||||
/* But I plan to double the framerate soon, or make it variable...*/
|
/* But I plan to double the framerate soon, or make it variable...*/
|
||||||
/*#define TIME_UNIT (125000/2)*/
|
/*#define TIME_UNIT (125000/2)*/
|
||||||
|
|
||||||
typedef struct screen_size {
|
|
||||||
char *size;
|
|
||||||
int wid, hgt;
|
|
||||||
} screen_size;
|
|
||||||
|
|
||||||
#define DEFAULT_SCREEN_PRIORITY 128
|
#define DEFAULT_SCREEN_PRIORITY 128
|
||||||
#define DEFAULT_SCREEN_DURATION 32
|
#define DEFAULT_SCREEN_DURATION 32
|
||||||
#define DEFAULT_HEARTBEAT HEARTBEAT_ON
|
#define DEFAULT_HEARTBEAT HEARTBEAT_ON
|
||||||
|
|||||||
+187
-300
@@ -6,6 +6,7 @@
|
|||||||
* COPYING file distributed with this package.
|
* COPYING file distributed with this package.
|
||||||
*
|
*
|
||||||
* Copyright (c) 1999, William Ferrell, Scott Scriven
|
* Copyright (c) 1999, William Ferrell, Scott Scriven
|
||||||
|
* 2002, Joris Robijn
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* Handles server-supplied menus defined by a table. Read menu.h for
|
* 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
|
* to handle dynamically-changing menus such as the client list. Tcl/Tk
|
||||||
* has neat ways to do it. Hmm...
|
* 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>
|
#include <stdlib.h>
|
||||||
@@ -26,329 +37,205 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "parse.h"
|
#include "config.h"
|
||||||
#include "sock.h"
|
|
||||||
#include "render.h"
|
|
||||||
#include "main.h"
|
|
||||||
|
|
||||||
#include "drivers.h"
|
|
||||||
#include "menu.h"
|
#include "menu.h"
|
||||||
#include "input.h"
|
#include "shared/report.h"
|
||||||
|
#include "drivers.h"
|
||||||
|
|
||||||
/* FIXME: Implement this where it is supposed to be...*/
|
#include "screen.h"
|
||||||
void
|
|
||||||
framedelay ()
|
|
||||||
|
/* 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 ();
|
Menu *new_item;
|
||||||
parse_all_client_messages ();
|
|
||||||
|
|
||||||
usleep (TIME_UNIT);
|
/* 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;
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
|
||||||
|
/* 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (into_menu) {
|
||||||
|
/* Add the item to the menu */
|
||||||
|
LL_Push (into_menu->data.menu.contents, new_item);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new_item;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
int menu_destroy_item (Menu *menu, MenuItem *item)
|
||||||
draw_heartbeat ()
|
|
||||||
{
|
{
|
||||||
static int timer = 0;
|
/* Is the item a menu ? */
|
||||||
|
if (item->type == MENUITEM_MENU ) {
|
||||||
if (heartbeat) {
|
/* Check if the menu is empty */
|
||||||
/* Set this to pulsate like a real heart beat... */
|
if ( LL_Length(item->data.menu.contents) != 0 ) {
|
||||||
/*drivers_icon (!((timer + 4) & 5), 0); */
|
report (RPT_ERR, "menu not empty, cannot be destroyed");
|
||||||
/*drivers_chr (display_props->width, 1, 0); */
|
return -1;
|
||||||
}
|
}
|
||||||
drivers_flush ();
|
/* Destroy our menu data */
|
||||||
|
if (item->data.menu.text)
|
||||||
timer++;
|
free (item->data.menu.text);
|
||||||
timer &= 0x0f;
|
LL_Destroy (item->data.menu.contents);
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
free (item->id);
|
||||||
|
free (item);
|
||||||
|
|
||||||
draw_menu (menu, &info);
|
/* Remove the item from the menu */
|
||||||
|
LL_Remove (menu->data.menu.contents, item);
|
||||||
/* 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
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 (top != 0)
|
|
||||||
drivers_chr (1, 1, '^');
|
|
||||||
if (bottom < info->length)
|
|
||||||
drivers_chr (1, hgt, 'v');
|
|
||||||
|
|
||||||
draw_heartbeat ();
|
|
||||||
/*drivers_flush(); */
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
MenuItem *menu_find_item (Menu *menu, char *id)
|
||||||
fill_menu_info (Menu menu, menu_info * info)
|
|
||||||
{
|
{
|
||||||
int i;
|
MenuItem * item;
|
||||||
|
for( item = menu_getfirst_item(menu); item; item = menu_getnext_item(menu) ) {
|
||||||
info->selected = 0;
|
if ( strcmp(item->id, id) == 0 ) {
|
||||||
|
return item;
|
||||||
/* count the entries in the menu*/
|
}
|
||||||
for (i = 0; menu[i].text; i++);
|
}
|
||||||
|
return NULL;
|
||||||
info->length = i;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
if (display_props) {
|
||||||
slid_func (menu_item * item)
|
/* Nothing to build if no display size is known */
|
||||||
{
|
report (RPT_ERR, "menu_build_screen: display size unknown");
|
||||||
char str[16];
|
return;
|
||||||
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) {
|
/* First remove all widgets from the screen */
|
||||||
case 'B':
|
for ( w=screen_getfirst_widget(s); w; w=screen_getnext_widget(s) ) {
|
||||||
value = readfunc (MENU_MINUS);
|
/* 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;
|
break;
|
||||||
case 'C':
|
case MENUITEM_SLIDER:
|
||||||
value = readfunc (MENU_PLUS);
|
menu_build_slider_screen (item, s);
|
||||||
break;
|
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);
|
||||||
if (value >= MENU_CLOSE || value < 0 || key == 'A' || key == 'D')
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
return MENU_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
* Copyright (c) 1999, William Ferrell, Scott Scriven
|
||||||
*
|
*
|
||||||
|
* Defines all the menu data and action.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef MENU_H
|
#ifndef MENU_H
|
||||||
#define MENU_H
|
#define MENU_H
|
||||||
|
|
||||||
#if 0
|
#include "shared/LL.h"
|
||||||
/*************************************************************************
|
|
||||||
Menus!
|
|
||||||
|
|
||||||
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
|
typedef enum MenuItemType {
|
||||||
Type -- menu, function, checkbox, slider, mover
|
MENUITEM_NONE = 0,
|
||||||
Data -- Child, ExecFunc, CheckFunc, SlidFunc, ???
|
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.
|
typedef enum CheckboxValue {
|
||||||
--"Menus" will recurse into the "data", assuming it is a child menu.
|
CHECKBOX_OFF = 0, CHECKBOX_ON, CHECKBOX_GRAY
|
||||||
--"Function"-type items will have their function called.
|
} CheckboxValue;
|
||||||
--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.
|
|
||||||
|
|
||||||
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[] = {
|
/* Events that can happen */
|
||||||
"MENU", 0, 0, // Title
|
typedef enum MenuEventType {
|
||||||
"Options", TYPE_MENU, (void *)OptionsMenu,
|
MENUEVENT_SELECT, /* Item has been selected
|
||||||
"Kill LCDproc", TYPE_FUNC, (void *)Shutdown_func,
|
(menu opened, action selected) */
|
||||||
0, 0, 0,
|
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[] = {
|
#define EventFunc(f) MenuEventFuncResult (f) (void *object, MenuEventType event)
|
||||||
"OPTIONS", TYPE_TITL, 0, // Title
|
|
||||||
"24-hour Time", TYPE_CHEK, (void *)Time24_func,
|
|
||||||
"Contrast...", TYPE_SLID, (void *)Contrast_func,
|
|
||||||
0, 0, 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////// 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 (MenuItem*) LL_GetFirst( menu->data.menu.contents );
|
||||||
return MENU_KILL; // or MENU_CLOSE, or MENU_OK, or MENU_ERROR
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
return (MenuItem*) LL_GetNext( menu->data.menu.contents );
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int Contrast_func(int input)
|
MenuItem *menu_find_item (Menu *menu, char *id);
|
||||||
{
|
/* Retrieves the first item from the list of items in the menu. */
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
=====================================================================
|
void menu_build_screen (MenuItem *item, Screen *s);
|
||||||
|
/* Builds the selected menuitem on screen using widgets
|
||||||
|
* Returns the initial state.
|
||||||
|
*/
|
||||||
|
|
||||||
Function return values:
|
void menu_update_screen (MenuItem *item, Screen *s);
|
||||||
MENU_OK Keeps menu open.
|
/* Updates the widgets of the selected menuitem
|
||||||
MENU_CLOSE Closes menu after item is picked.
|
* Returns the new state.
|
||||||
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);
|
|
||||||
|
|
||||||
#endif
|
#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
|
||||||
+7
-12
@@ -24,7 +24,7 @@
|
|||||||
#include "shared/sockets.h"
|
#include "shared/sockets.h"
|
||||||
#include "shared/report.h"
|
#include "shared/report.h"
|
||||||
#include "clients.h"
|
#include "clients.h"
|
||||||
#include "client_functions.h"
|
#include "commands/command_list.h"
|
||||||
#include "parse.h"
|
#include "parse.h"
|
||||||
|
|
||||||
/* This is a big function... TOO big. How to trim....
|
/* This is a big function... TOO big. How to trim....
|
||||||
@@ -38,7 +38,7 @@ parse_all_client_messages ()
|
|||||||
{
|
{
|
||||||
int i; /* int j, len;*/
|
int i; /* int j, len;*/
|
||||||
/*int newtoken, inquote;*/
|
/*int newtoken, inquote;*/
|
||||||
client *c;
|
Client * c;
|
||||||
char *str, *p, *q, *s;
|
char *str, *p, *q, *s;
|
||||||
/* char *tok;*/
|
/* char *tok;*/
|
||||||
int argc;
|
int argc;
|
||||||
@@ -60,16 +60,12 @@ parse_all_client_messages ()
|
|||||||
#define LINE_TERM_CHAR '\0'
|
#define LINE_TERM_CHAR '\0'
|
||||||
#define COMMENT_CHAR '#'
|
#define COMMENT_CHAR '#'
|
||||||
|
|
||||||
/*debug("parse: Rewinding list...");*/
|
for( c=clients_getfirst(); c; c=clients_getnext()) {
|
||||||
LL_Rewind (clients);
|
|
||||||
do {
|
|
||||||
/* Get the next client...*/
|
|
||||||
/*debug("parse: Getting client...");*/
|
|
||||||
c = LL_Get (clients);
|
|
||||||
if (c) {
|
|
||||||
/* And parse all its messages...*/
|
/* And parse all its messages...*/
|
||||||
/*debug(RPT_DEBUG, "parse: Getting messages...");*/
|
/*debug(RPT_DEBUG, "parse: Getting messages...");*/
|
||||||
for (str = client_get_message (c); str; str = client_get_message (c)) {
|
for (str = client_get_message (c); str; str = client_get_message (c)) {
|
||||||
|
|
||||||
debug (RPT_DEBUG, "parse: ...%s", str);
|
debug (RPT_DEBUG, "parse: ...%s", str);
|
||||||
/* Now, split up the string...*/
|
/* Now, split up the string...*/
|
||||||
argc = 0;
|
argc = 0;
|
||||||
@@ -176,14 +172,13 @@ parse_all_client_messages ()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (invalid) {
|
if (invalid) {
|
||||||
snprintf (errmsg, sizeof(errmsg), "huh? Invalid command \"%s\"\n", argv[0]);
|
snprintf (errmsg, sizeof(errmsg), "huh? Invalid command \"%.40s\"\n", argv[0]);
|
||||||
sock_send_string (c->sock, errmsg);
|
sock_send_string (c->sock, errmsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
free (str); /* fixed memory leak?*/
|
free (str); /* fixed memory leak?*/
|
||||||
} /* end for(str...)*/
|
} /* end for(str...)*/
|
||||||
} /* end if (c)*/
|
}
|
||||||
} while (LL_Next (clients) == 0);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
+32
-29
@@ -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);
|
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
|
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;
|
int tmp = 0, tmp_state = 0;
|
||||||
|
|
||||||
report(RPT_INFO, "draw_screen( screen=\"%.40s\", timer=%d ) ==== START RENDERING ====", s->name, timer );
|
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
|
* inherit the backlight state from the parent client. This allows
|
||||||
* the client to override it's childrens settings.
|
* the client to override it's childrens settings.
|
||||||
*/
|
*/
|
||||||
if (s->backlight_state == BACKLIGHT_NOTSET) {
|
if (s->backlight == BACKLIGHT_OPEN) {
|
||||||
if (s->parent) tmp_state = s->parent->backlight_state;
|
if (s->client) tmp_state = s->client->backlight;
|
||||||
} else {
|
} else {
|
||||||
tmp_state = s->backlight_state;
|
tmp_state = s->backlight;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set up backlight to the correct state... */
|
/* Set up backlight to the correct state... */
|
||||||
@@ -126,7 +126,7 @@ draw_screen (screen * s, int timer)
|
|||||||
drivers_output (output_state);
|
drivers_output (output_state);
|
||||||
|
|
||||||
/* Draw a frame... */
|
/* 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"); */
|
/*debug(RPT_DEBUG, "draw_screen done"); */
|
||||||
|
|
||||||
@@ -177,9 +177,9 @@ draw_frame (LinkedList * list,
|
|||||||
#define HorizontalScrolling (fscroll == 'h')
|
#define HorizontalScrolling (fscroll == 'h')
|
||||||
|
|
||||||
char str[BUFSIZE]; /* scratch buffer */
|
char str[BUFSIZE]; /* scratch buffer */
|
||||||
widget *w;
|
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 x, y;
|
||||||
int fx, fy; /* Scrolling offset for the frame... */
|
int fx, fy; /* Scrolling offset for the frame... */
|
||||||
int length, speed;
|
int length, speed;
|
||||||
@@ -191,8 +191,8 @@ draw_frame (LinkedList * list,
|
|||||||
"right=%d, bottom=%d, fwid=%d, fhgt=%d, fspeed=%d, timer=%d )",
|
"right=%d, bottom=%d, fwid=%d, fhgt=%d, fspeed=%d, timer=%d )",
|
||||||
list, fscroll, left,top, right, bottom, fwid, fhgt, fspeed, timer );
|
list, fscroll, left,top, right, bottom, fwid, fhgt, fspeed, timer );
|
||||||
|
|
||||||
wid = right - left; /* This is the size of the visible frame area */
|
vis_width = right - left; /* This is the size of the visible frame area */
|
||||||
hgt = bottom - top;
|
vis_height = bottom - top;
|
||||||
|
|
||||||
fx = 0;
|
fx = 0;
|
||||||
fy = 0;
|
fy = 0;
|
||||||
@@ -220,8 +220,8 @@ draw_frame (LinkedList * list,
|
|||||||
}
|
}
|
||||||
|
|
||||||
fy %= fhgt;
|
fy %= fhgt;
|
||||||
if (fy > fhgt - hgt)
|
if (fy > fhgt - vis_height)
|
||||||
fy = fhgt - hgt;
|
fy = fhgt - vis_height;
|
||||||
|
|
||||||
} else if (HorizontalScrolling) {
|
} else if (HorizontalScrolling) {
|
||||||
/* TODO: Frames don't scroll horizontally yet! */
|
/* TODO: Frames don't scroll horizontally yet! */
|
||||||
@@ -239,7 +239,7 @@ draw_frame (LinkedList * list,
|
|||||||
|
|
||||||
LL_Rewind (list);
|
LL_Rewind (list);
|
||||||
do {
|
do {
|
||||||
w = (widget *) LL_Get (list);
|
w = (Widget *) LL_Get (list);
|
||||||
if (!w)
|
if (!w)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
@@ -247,10 +247,10 @@ draw_frame (LinkedList * list,
|
|||||||
switch (w->type) {
|
switch (w->type) {
|
||||||
case WID_STRING:
|
case WID_STRING:
|
||||||
if (ValidPoint(w) && TextPresent(w)) {
|
if (ValidPoint(w) && TextPresent(w)) {
|
||||||
if ((w->y <= hgt + fy) && (w->y > fy)) {
|
if ((w->y <= vis_height + fy) && (w->y > fy)) {
|
||||||
if (w->x > wid) w->x=wid;
|
if (w->x > vis_width) w->x=vis_width;
|
||||||
strncpy (str, w->text, wid - w->x + 1);
|
strncpy (str, w->text, vis_width - w->x + 1);
|
||||||
str[wid - w->x + 1] = 0;
|
str[vis_width - w->x + 1] = 0;
|
||||||
drivers_string (w->x + left, w->y + top - fy, str);
|
drivers_string (w->x + left, w->y + top - fy, str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -261,9 +261,9 @@ draw_frame (LinkedList * list,
|
|||||||
reset = 0;
|
reset = 0;
|
||||||
}
|
}
|
||||||
if ((w->x > 0) && (w->y > 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 > 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); */
|
/*was: drivers_hbar (w->x + left, w->y + top - fy, w->length); */
|
||||||
/* improvised len and promille */
|
/* improvised len and promille */
|
||||||
int full_len = display_props->width - w->x - left + 1;
|
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...*/
|
case WID_TITLE: /* FIXME: Doesn't work quite right in frames...*/
|
||||||
if (!w->text)
|
if (!w->text)
|
||||||
break;
|
break;
|
||||||
if (wid < 8)
|
if (vis_width < 8)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
memset (str, 255, wid);
|
/*memset (str, 255, width);*/
|
||||||
|
memset (str, '*', vis_width);
|
||||||
|
/* TODO: Use icon function to draw the bar */
|
||||||
|
|
||||||
str[2] = ' ';
|
str[2] = ' ';
|
||||||
length = strlen (w->text);
|
length = strlen (w->text);
|
||||||
if (length <= wid - 6) {
|
if (length <= vis_width - 6) {
|
||||||
memcpy (str + 3, w->text, length);
|
memcpy (str + 3, w->text, length);
|
||||||
str[length + 3] = ' ';
|
str[length + 3] = ' ';
|
||||||
} else /* Scroll the title, if it doesn't fit...*/
|
} else /* Scroll the title, if it doesn't fit...*/
|
||||||
@@ -338,17 +341,17 @@ draw_frame (LinkedList * list,
|
|||||||
x -= 3;
|
x -= 3;
|
||||||
if (x < 0)
|
if (x < 0)
|
||||||
x = 0;
|
x = 0;
|
||||||
if (x > length - (wid - 6))
|
if (x > length - (vis_width - 6))
|
||||||
x = length - (wid - 6);
|
x = length - (vis_width - 6);
|
||||||
|
|
||||||
if (y & 1) /* Scrolling backwards...*/
|
if (y & 1) /* Scrolling backwards...*/
|
||||||
{
|
{
|
||||||
x = (length - (wid - 6)) - x;
|
x = (length - (vis_width - 6)) - x;
|
||||||
}
|
}
|
||||||
strncpy (str + 3, w->text + x, (wid - 6));
|
strncpy (str + 3, w->text + x, (vis_width - 6));
|
||||||
str[wid - 3] = ' ';
|
str[vis_width - 3] = ' ';
|
||||||
}
|
}
|
||||||
str[wid] = 0;
|
str[vis_width] = 0;
|
||||||
|
|
||||||
drivers_string (1 + left, 1 + top, str);
|
drivers_string (1 + left, 1 + top, str);
|
||||||
break;
|
break;
|
||||||
@@ -504,7 +507,7 @@ draw_frame (LinkedList * list,
|
|||||||
new_bottom = bottom;
|
new_bottom = bottom;
|
||||||
if (new_left >= right || new_top >= bottom) { /* Do nothing if it's invisible...*/
|
if (new_left >= right || new_top >= bottom) { /* Do nothing if it's invisible...*/
|
||||||
} else {
|
} else {
|
||||||
draw_frame (w->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;
|
break;
|
||||||
|
|||||||
+6
-3
@@ -17,7 +17,6 @@
|
|||||||
#define HEARTBEAT_OFF 0
|
#define HEARTBEAT_OFF 0
|
||||||
#define HEARTBEAT_ON 1
|
#define HEARTBEAT_ON 1
|
||||||
#define HEARTBEAT_OPEN 2
|
#define HEARTBEAT_OPEN 2
|
||||||
#define HEARTBEAT_SLASH 3
|
|
||||||
|
|
||||||
#define SERVER_SCREEN_NEVER 0
|
#define SERVER_SCREEN_NEVER 0
|
||||||
#define SERVER_SCREEN_NOSCREEN 1
|
#define SERVER_SCREEN_NOSCREEN 1
|
||||||
@@ -26,17 +25,21 @@
|
|||||||
#define BACKLIGHT_OFF 0
|
#define BACKLIGHT_OFF 0
|
||||||
#define BACKLIGHT_ON 1
|
#define BACKLIGHT_ON 1
|
||||||
#define BACKLIGHT_OPEN 2
|
#define BACKLIGHT_OPEN 2
|
||||||
#define BACKLIGHT_NOTSET 3
|
|
||||||
|
|
||||||
#define BACKLIGHT_BLINK 0x100
|
#define BACKLIGHT_BLINK 0x100
|
||||||
#define BACKLIGHT_FLASH 0x200
|
#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 heartbeat;
|
||||||
extern int backlight;
|
extern int backlight;
|
||||||
extern int backlight_state;
|
extern int backlight_state;
|
||||||
extern int backlight_brightness;
|
extern int backlight_brightness;
|
||||||
extern int backlight_off_brightness;
|
extern int backlight_off_brightness;
|
||||||
extern int output_state;
|
extern int output_state;
|
||||||
int draw_screen (screen * s, int timer);
|
int draw_screen (Screen * s, int timer);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+69
-100
@@ -31,34 +31,45 @@
|
|||||||
int default_duration = 0;
|
int default_duration = 0;
|
||||||
int default_timeout = -1;
|
int default_timeout = -1;
|
||||||
|
|
||||||
screen *
|
Screen *
|
||||||
screen_create ()
|
screen_create (char * id, Client * client)
|
||||||
{
|
{
|
||||||
screen *s;
|
Screen *s;
|
||||||
|
|
||||||
s = malloc (sizeof (screen));
|
s = malloc (sizeof (Screen));
|
||||||
if (!s) {
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
s->id = NULL;
|
|
||||||
s->name = NULL;
|
s->name = NULL;
|
||||||
s->priority = DEFAULT_SCREEN_PRIORITY;
|
s->priority = DEFAULT_SCREEN_PRIORITY;
|
||||||
s->duration = default_duration;
|
s->duration = default_duration;
|
||||||
s->heartbeat = DEFAULT_HEARTBEAT;
|
s->backlight = BACKLIGHT_OPEN;
|
||||||
s->wid = display_props->width;
|
s->heartbeat = HEARTBEAT_OPEN;
|
||||||
s->hgt = display_props->height;
|
s->width = display_props->width;
|
||||||
|
s->height = display_props->height;
|
||||||
s->keys = NULL;
|
s->keys = NULL;
|
||||||
s->parent = NULL;
|
s->client = client;
|
||||||
s->widgets = NULL;
|
s->widgetlist = NULL;
|
||||||
s->timeout = default_timeout; /*ignored unless greater than 0.*/
|
s->timeout = default_timeout; /*ignored unless greater than 0.*/
|
||||||
s->backlight_state = BACKLIGHT_NOTSET; /*Lets the screen do it's own*/
|
s->backlight = BACKLIGHT_OPEN; /*Lets the screen do it's own*/
|
||||||
/*or do what the client says.*/
|
/*or do what the client says.*/
|
||||||
|
|
||||||
s->widgets = LL_new ();
|
s->widgetlist = LL_new ();
|
||||||
if (!s->widgets) {
|
if (!s->widgetlist) {
|
||||||
report(RPT_ERR, "screen_create: Error allocating widget list");
|
report(RPT_ERR, "screen_create: Error allocating");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -66,20 +77,18 @@ screen_create ()
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
screen_destroy (screen * s)
|
screen_destroy (Screen * s)
|
||||||
{
|
{
|
||||||
widget *w;
|
Widget *w;
|
||||||
|
|
||||||
if (!s)
|
if (!s)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
LL_Rewind (s->widgets);
|
for (w=LL_GetFirst(s->widgetlist); w; w=LL_GetNext(s->widgetlist)) {
|
||||||
do {
|
|
||||||
/* Free a widget...*/
|
/* Free a widget...*/
|
||||||
w = LL_Get (s->widgets);
|
|
||||||
widget_destroy (w);
|
widget_destroy (w);
|
||||||
} while (LL_Next (s->widgets) == 0);
|
}
|
||||||
LL_Destroy (s->widgets);
|
LL_Destroy (s->widgetlist);
|
||||||
|
|
||||||
if (s->id)
|
if (s->id)
|
||||||
free (s->id);
|
free (s->id);
|
||||||
@@ -93,99 +102,59 @@ screen_destroy (screen * s)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
screen *
|
|
||||||
screen_find (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->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;
|
|
||||||
}
|
|
||||||
} while (LL_Next (c->data->screenlist) == 0);
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
screen_add (client * c, char *id)
|
screen_add_widget (Screen * s, Widget * w)
|
||||||
{
|
{
|
||||||
screen *s;
|
report (RPT_INFO, "screen_add_widget(%s,%s)", s->id, w->id);
|
||||||
|
if (!s)
|
||||||
if (!c)
|
|
||||||
return -1;
|
return -1;
|
||||||
if (!id)
|
if (!w)
|
||||||
return -1;
|
|
||||||
|
|
||||||
/* Make sure this screen doesn't already exist...*/
|
|
||||||
s = screen_find (c, id);
|
|
||||||
if (s) {
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
|
||||||
|
|
||||||
s = screen_create ();
|
LL_Push (s->widgetlist, (void *) w);
|
||||||
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
screen_remove (client * c, char *id)
|
screen_remove_widget (Screen * s, Widget * w)
|
||||||
{
|
{
|
||||||
screen *s;
|
report (RPT_INFO, "screen_remove_widget(%s,%s)", s->id, w->id);
|
||||||
|
|
||||||
if (!c)
|
if (!s)
|
||||||
return -1;
|
return -1;
|
||||||
if (!id)
|
if (!w)
|
||||||
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;
|
return 1;
|
||||||
}
|
|
||||||
/* TODO: Check for errors here?*/
|
|
||||||
LL_Remove (c->data->screenlist, (void *) s);
|
|
||||||
|
|
||||||
/* Now, remove it from the screenlist...*/
|
LL_Remove (s->widgetlist, (void *) w);
|
||||||
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Widget *
|
||||||
|
screen_find_widget (Screen * s, char *id)
|
||||||
|
{
|
||||||
|
Widget * w;
|
||||||
|
|
||||||
|
if (!s)
|
||||||
|
return NULL;
|
||||||
|
if (!id)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
debug (RPT_DEBUG, "screen_find_widget(%s,%s)", s->id, id);
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
/* 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;
|
||||||
|
}
|
||||||
|
|||||||
+40
-17
@@ -13,34 +13,57 @@
|
|||||||
#define SCREEN_H
|
#define SCREEN_H
|
||||||
|
|
||||||
#include "shared/LL.h"
|
#include "shared/LL.h"
|
||||||
#include "clients.h"
|
|
||||||
|
|
||||||
typedef struct screen {
|
typedef struct Screen {
|
||||||
char *id;
|
char *id;
|
||||||
char *name;
|
char *name;
|
||||||
int wid, hgt;
|
int width, height;
|
||||||
int priority;
|
|
||||||
int duration;
|
int duration;
|
||||||
int heartbeat;
|
|
||||||
int timeout;
|
int timeout;
|
||||||
int backlight_state;
|
short int priority;
|
||||||
int cursor;
|
short int heartbeat;
|
||||||
int cursor_x;
|
short int backlight;
|
||||||
int cursor_y;
|
short int cursor;
|
||||||
|
short int cursor_x;
|
||||||
|
short int cursor_y;
|
||||||
char *keys;
|
char *keys;
|
||||||
LinkedList *widgets;
|
LinkedList *widgetlist;
|
||||||
client *parent;
|
struct Client *client;
|
||||||
} screen;
|
} Screen;
|
||||||
|
|
||||||
|
#include "client.h"
|
||||||
|
#include "widget.h"
|
||||||
|
|
||||||
|
|
||||||
extern int default_duration ;
|
extern int default_duration ;
|
||||||
extern int default_priority ;
|
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);
|
/* Destroys a screen */
|
||||||
int screen_remove (client * c, char *id);
|
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
|
#endif
|
||||||
|
|||||||
+25
-25
@@ -28,10 +28,10 @@ int timer = 0;
|
|||||||
|
|
||||||
LinkedList *screenlist;
|
LinkedList *screenlist;
|
||||||
|
|
||||||
int screenlist_add_end (screen * screen);
|
int screenlist_add_end (Screen * screen);
|
||||||
screen *screenlist_next_roll ();
|
Screen *screenlist_next_roll ();
|
||||||
screen *screenlist_prev_roll ();
|
Screen *screenlist_prev_roll ();
|
||||||
screen *screenlist_next_priority ();
|
Screen *screenlist_next_priority ();
|
||||||
|
|
||||||
int compare_priority (void *one, void *two);
|
int compare_priority (void *one, void *two);
|
||||||
int compare_addresses (void *one, void *two);
|
int compare_addresses (void *one, void *two);
|
||||||
@@ -64,7 +64,7 @@ screenlist_shutdown ()
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
screenlist_remove (screen * s)
|
screenlist_remove (Screen * s)
|
||||||
{
|
{
|
||||||
report (RPT_INFO, "screenlist_remove()");
|
report (RPT_INFO, "screenlist_remove()");
|
||||||
|
|
||||||
@@ -75,7 +75,7 @@ screenlist_remove (screen * s)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
screenlist_remove_all (screen * s)
|
screenlist_remove_all (Screen * s)
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
@@ -97,19 +97,19 @@ screenlist_getlist ()
|
|||||||
return screenlist;
|
return screenlist;
|
||||||
}
|
}
|
||||||
|
|
||||||
screen *
|
Screen *
|
||||||
screenlist_current ()
|
screenlist_current ()
|
||||||
{
|
{
|
||||||
char str[256];
|
char str[256];
|
||||||
screen *s;
|
Screen * s;
|
||||||
static screen *old_s = NULL;
|
static Screen * old_s = NULL;
|
||||||
client *c;
|
Client * c;
|
||||||
|
|
||||||
debug( RPT_INFO, "screenlist_current:");
|
debug( RPT_INFO, "screenlist_current:");
|
||||||
|
|
||||||
/*LL_dprint(screenlist);*/
|
/*LL_dprint(screenlist);*/
|
||||||
|
|
||||||
s = (screen *) LL_GetFirst (screenlist);
|
s = (Screen *) LL_GetFirst (screenlist);
|
||||||
|
|
||||||
/* FIXME: Make sure the screen/client exists!*/
|
/* FIXME: Make sure the screen/client exists!*/
|
||||||
if (s != old_s) {
|
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);
|
report (RPT_WARNING, "screenlist: Didn't find screen 0x%8x! Client crashed?", (int) old_s);
|
||||||
} else {
|
} else {
|
||||||
/*debug(RPT_DEBUG, "screenlist_current: ... sending ignore");*/
|
/*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...*/
|
if (c) /* Tell the client we're not listening any more...*/
|
||||||
{
|
{
|
||||||
snprintf (str, sizeof(str), "ignore %s\n", old_s->id);
|
snprintf (str, sizeof(str), "ignore %s\n", old_s->id);
|
||||||
@@ -138,7 +138,7 @@ screenlist_current ()
|
|||||||
}
|
}
|
||||||
if (s) {
|
if (s) {
|
||||||
/*debug(RPT_DEBUG, "screenlist_current: listening to new screen");*/
|
/*debug(RPT_DEBUG, "screenlist_current: listening to new screen");*/
|
||||||
c = s->parent;
|
c = s->client;
|
||||||
if (c) /* Tell the client we're paying attention...*/
|
if (c) /* Tell the client we're paying attention...*/
|
||||||
{
|
{
|
||||||
snprintf (str, sizeof(str), "listen %s\n", s->id);
|
snprintf (str, sizeof(str), "listen %s\n", s->id);
|
||||||
@@ -158,16 +158,16 @@ screenlist_current ()
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
screenlist_add (screen * s)
|
screenlist_add (Screen * s)
|
||||||
{
|
{
|
||||||
/* TODO: Different queueing modes...*/
|
/* TODO: Different queueing modes...*/
|
||||||
return screenlist_add_end (s);
|
return screenlist_add_end (s);
|
||||||
}
|
}
|
||||||
|
|
||||||
screen *
|
Screen *
|
||||||
screenlist_next ()
|
screenlist_next ()
|
||||||
{
|
{
|
||||||
screen *s;
|
Screen *s;
|
||||||
|
|
||||||
/*debug(RPT_DEBUG, "Screenlist_next()");*/
|
/*debug(RPT_DEBUG, "Screenlist_next()");*/
|
||||||
|
|
||||||
@@ -194,10 +194,10 @@ screenlist_next ()
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
screen *
|
Screen *
|
||||||
screenlist_prev ()
|
screenlist_prev ()
|
||||||
{
|
{
|
||||||
screen *s;
|
Screen *s;
|
||||||
|
|
||||||
s = screenlist_current ();
|
s = screenlist_current ();
|
||||||
|
|
||||||
@@ -219,7 +219,7 @@ screenlist_prev ()
|
|||||||
|
|
||||||
/* Adds new screens to the end of the screenlist...*/
|
/* Adds new screens to the end of the screenlist...*/
|
||||||
int
|
int
|
||||||
screenlist_add_end (screen * screen)
|
screenlist_add_end (Screen * screen)
|
||||||
{
|
{
|
||||||
debug (RPT_DEBUG, "screenlist_add_end()");
|
debug (RPT_DEBUG, "screenlist_add_end()");
|
||||||
|
|
||||||
@@ -227,7 +227,7 @@ screenlist_add_end (screen * screen)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Simple round-robin approach to screen cycling...*/
|
/* Simple round-robin approach to screen cycling...*/
|
||||||
screen *
|
Screen *
|
||||||
screenlist_next_roll ()
|
screenlist_next_roll ()
|
||||||
{
|
{
|
||||||
/*debug(RPT_DEBUG, "screenlist_next_roll()");*/
|
/*debug(RPT_DEBUG, "screenlist_next_roll()");*/
|
||||||
@@ -239,7 +239,7 @@ screenlist_next_roll ()
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Strict priority queue approach...*/
|
/* Strict priority queue approach...*/
|
||||||
screen *
|
Screen *
|
||||||
screenlist_next_priority ()
|
screenlist_next_priority ()
|
||||||
{
|
{
|
||||||
/*screen *s, *t;*/
|
/*screen *s, *t;*/
|
||||||
@@ -254,7 +254,7 @@ screenlist_next_priority ()
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Simple round-robin approach to screen cycling...*/
|
/* Simple round-robin approach to screen cycling...*/
|
||||||
screen *
|
Screen *
|
||||||
screenlist_prev_roll ()
|
screenlist_prev_roll ()
|
||||||
{
|
{
|
||||||
/*debug(RPT_DEBUG, "screenlist_prev_roll()");*/
|
/*debug(RPT_DEBUG, "screenlist_prev_roll()");*/
|
||||||
@@ -268,7 +268,7 @@ screenlist_prev_roll ()
|
|||||||
int
|
int
|
||||||
compare_priority (void *one, void *two)
|
compare_priority (void *one, void *two)
|
||||||
{
|
{
|
||||||
screen *a, *b;
|
Screen *a, *b;
|
||||||
|
|
||||||
/*debug(RPT_DEBUG, "compare_priority: %8x %8x", one, two);*/
|
/*debug(RPT_DEBUG, "compare_priority: %8x %8x", one, two);*/
|
||||||
|
|
||||||
@@ -277,8 +277,8 @@ compare_priority (void *one, void *two)
|
|||||||
if (!two)
|
if (!two)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
a = (screen *) one;
|
a = (Screen *) one;
|
||||||
b = (screen *) two;
|
b = (Screen *) two;
|
||||||
|
|
||||||
/*debug(RPT_DEBUG, "compare_priority: done?");*/
|
/*debug(RPT_DEBUG, "compare_priority: done?");*/
|
||||||
|
|
||||||
|
|||||||
+6
-6
@@ -28,13 +28,13 @@ int screenlist_init ();
|
|||||||
int screenlist_shutdown ();
|
int screenlist_shutdown ();
|
||||||
|
|
||||||
LinkedList *screenlist_getlist ();
|
LinkedList *screenlist_getlist ();
|
||||||
screen *screenlist_current ();
|
Screen *screenlist_current ();
|
||||||
|
|
||||||
int screenlist_add (screen * s);
|
int screenlist_add (Screen * s);
|
||||||
screen *screenlist_next ();
|
Screen *screenlist_next ();
|
||||||
screen *screenlist_prev ();
|
Screen *screenlist_prev ();
|
||||||
|
|
||||||
int screenlist_remove (screen * s);
|
int screenlist_remove (Screen * s);
|
||||||
int screenlist_remove_all (screen * s);
|
int screenlist_remove_all (Screen * s);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+43
-40
@@ -23,76 +23,68 @@
|
|||||||
#include "shared/report.h"
|
#include "shared/report.h"
|
||||||
|
|
||||||
#include "drivers.h"
|
#include "drivers.h"
|
||||||
|
|
||||||
#include "clients.h"
|
#include "clients.h"
|
||||||
#include "screen.h"
|
#include "screen.h"
|
||||||
#include "screenlist.h"
|
#include "screenlist.h"
|
||||||
#include "widget.h"
|
#include "widget.h"
|
||||||
|
|
||||||
#include "serverscreens.h"
|
#include "serverscreens.h"
|
||||||
|
|
||||||
screen *server_screen;
|
Screen * server_screen;
|
||||||
char *id = "ClientList";
|
|
||||||
char *name = "Client List";
|
|
||||||
|
|
||||||
char title[256] = "LCDproc Server";
|
char title[256] = "LCDproc Server";
|
||||||
char one[256] = "";
|
char one[256] = "";
|
||||||
char two[256] = "";
|
char two[256] = "";
|
||||||
char three[256] = "";
|
char three[256] = "";
|
||||||
|
|
||||||
#define WidgetXPos(w,a) (w)->x = (a)
|
#define WidgetString(w,a,b,t) {(w)->x=(a);(w)->y=(b);(w)->text=(t);}
|
||||||
#define WidgetYPos(w,a) (w)->y = (a)
|
|
||||||
#define WidgetText(w,a) (w)->text = (a)
|
|
||||||
#define WidgetString(w,a,b,t) {WidgetXPos(w,a);WidgetYPos(w,b);WidgetText(w,t);}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
server_screen_init ()
|
server_screen_init ()
|
||||||
{
|
{
|
||||||
widget *w;
|
Widget * w;
|
||||||
|
|
||||||
debug (RPT_DEBUG, "server_screen_init");
|
debug (RPT_DEBUG, "server_screen_init");
|
||||||
|
|
||||||
server_screen = screen_create ();
|
server_screen = screen_create ("_server_screen", NULL);
|
||||||
|
|
||||||
if (!server_screen) {
|
if (!server_screen) {
|
||||||
report (RPT_ERR, "server_screen_init: Error allocating screen");
|
report (RPT_ERR, "server_screen_init: Error allocating screen");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
server_screen->id = id;
|
server_screen->name = "Server screen";
|
||||||
server_screen->name = name;
|
|
||||||
server_screen->duration = 8; /* 1 second, instead of 4...*/
|
server_screen->duration = 8; /* 1 second, instead of 4...*/
|
||||||
|
server_screen->priority = -1; /* TODO: use priorities good */
|
||||||
|
|
||||||
if (widget_add (server_screen, "title", "title", NULL, 1) != 0) {
|
if ( (w = widget_create ("title", WID_TITLE, server_screen)) == NULL
|
||||||
report (RPT_ERR, "server_screen_init: internal error: could not add title widget");
|
|| screen_add_widget (server_screen, w) != 0
|
||||||
}
|
|| (w = widget_create ("one", WID_STRING, server_screen)) == NULL
|
||||||
if (widget_add (server_screen, "one", "string", NULL, 1) != 0) {
|
|| screen_add_widget (server_screen, w) != 0
|
||||||
report (RPT_ERR, "server_screen_init: internal error: could not add title widget");
|
|| (w = widget_create ("two", WID_STRING, server_screen)) == NULL
|
||||||
}
|
|| screen_add_widget (server_screen, w) != 0
|
||||||
if (widget_add (server_screen, "two", "string", NULL, 1) != 0) {
|
|| (w = widget_create ("three", WID_STRING, server_screen)) == NULL
|
||||||
report (RPT_ERR, "server_screen_init: internal error: could not add title widget");
|
|| screen_add_widget (server_screen, w) != 0
|
||||||
}
|
) {
|
||||||
if (widget_add (server_screen, "three", "string", NULL, 1) != 0) {
|
report (RPT_ERR, "server_screen_init: Can't create widgets");
|
||||||
report (RPT_ERR, "server_screen_init: internal error: could not add title widget");
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now, initialize all the widgets...*/
|
/* Now, initialize all the widgets...*/
|
||||||
if ((w = widget_find (server_screen, "title")) != NULL) {
|
if ((w = screen_find_widget (server_screen, "title")) != NULL) {
|
||||||
WidgetText(w,title);
|
w->text = title;
|
||||||
} else
|
} else
|
||||||
report (RPT_ERR, "server_screen_init: Can't find title");
|
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)
|
WidgetString(w,1,2,one)
|
||||||
else
|
else
|
||||||
report (RPT_ERR, "server_screen_init: Can't find widget one");
|
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)
|
WidgetString(w,1,3,two)
|
||||||
else
|
else
|
||||||
report (RPT_ERR, "server_screen_init: Can't find widget two");
|
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)
|
WidgetString(w,1,4,three)
|
||||||
else
|
else
|
||||||
report (RPT_ERR, "server_screen_init: Can't find widget three");
|
report (RPT_ERR, "server_screen_init: Can't find widget three");
|
||||||
@@ -106,15 +98,15 @@ server_screen_init ()
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
screen_count (client *c) {
|
screen_count (Client * c) {
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
n = 0;
|
n = 0;
|
||||||
LL_Rewind (c->data->screenlist);
|
LL_Rewind (c->screenlist);
|
||||||
do {
|
do {
|
||||||
if (LL_Get (c->data->screenlist) != NULL)
|
if (LL_Get (c->screenlist) != NULL)
|
||||||
n++;
|
n++;
|
||||||
} while (LL_Next (c->data->screenlist) == 0);
|
} while (LL_Next (c->screenlist) == 0);
|
||||||
|
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
@@ -122,7 +114,7 @@ screen_count (client *c) {
|
|||||||
int
|
int
|
||||||
update_server_screen (int timer)
|
update_server_screen (int timer)
|
||||||
{
|
{
|
||||||
client *c;
|
Client * c;
|
||||||
int num_clients;
|
int num_clients;
|
||||||
/*screen *s;*/
|
/*screen *s;*/
|
||||||
int num_screens;
|
int num_screens;
|
||||||
@@ -131,14 +123,22 @@ update_server_screen (int timer)
|
|||||||
/*strcpy(title, "LCDproc Server");*/
|
/*strcpy(title, "LCDproc Server");*/
|
||||||
|
|
||||||
/* Now get info on the number of connected clients...*/
|
/* Now get info on the number of connected clients...*/
|
||||||
num_clients = 0;
|
num_clients = clients_client_count();
|
||||||
|
|
||||||
|
/* ... and screens */
|
||||||
num_screens = 0;
|
num_screens = 0;
|
||||||
LL_Rewind (clients);
|
for (c = clients_getfirst (); c; c = clients_getnext () ) {
|
||||||
do {
|
num_screens += client_screen_count(c);
|
||||||
c = LL_Get (clients);
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
if (c) {
|
if (c) {
|
||||||
num_clients++;
|
num_clients++;
|
||||||
|
num_screens += client_screen_count(c);
|
||||||
|
|
||||||
num_screens += screen_count(c);
|
num_screens += screen_count(c);
|
||||||
|
*/
|
||||||
|
|
||||||
/* LL_Rewind (c->data->screenlist); */
|
/* LL_Rewind (c->data->screenlist); */
|
||||||
/* do { */
|
/* do { */
|
||||||
/* s = LL_Get (c->data->screenlist); */
|
/* s = LL_Get (c->data->screenlist); */
|
||||||
@@ -146,8 +146,11 @@ update_server_screen (int timer)
|
|||||||
/* num_screens++; */
|
/* num_screens++; */
|
||||||
/* } */
|
/* } */
|
||||||
/* } while (LL_Next (c->data->screenlist) == 0); */
|
/* } while (LL_Next (c->data->screenlist) == 0); */
|
||||||
|
|
||||||
|
/*
|
||||||
}
|
}
|
||||||
} while (LL_Next (clients) == 0);
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
/* Format strings for the appropriate size display... */
|
/* Format strings for the appropriate size display... */
|
||||||
if (display_props->height >= 3) {
|
if (display_props->height >= 3) {
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
#include "screen.h"
|
#include "screen.h"
|
||||||
|
|
||||||
extern screen *server_screen;
|
extern Screen * server_screen;
|
||||||
|
|
||||||
int server_screen_init ();
|
int server_screen_init ();
|
||||||
int update_server_screen (int timer);
|
int update_server_screen (int timer);
|
||||||
|
|||||||
+21
-14
@@ -33,8 +33,11 @@
|
|||||||
|
|
||||||
#include "shared/sockets.h"
|
#include "shared/sockets.h"
|
||||||
#include "sock.h"
|
#include "sock.h"
|
||||||
|
#include "client.h"
|
||||||
#include "clients.h"
|
#include "clients.h"
|
||||||
|
#include "screen.h"
|
||||||
#include "shared/report.h"
|
#include "shared/report.h"
|
||||||
|
#include "screenlist.h"
|
||||||
|
|
||||||
extern char bind_addr[64];
|
extern char bind_addr[64];
|
||||||
extern int lcd_port;
|
extern int lcd_port;
|
||||||
@@ -142,7 +145,7 @@ sock_poll_clients ()
|
|||||||
struct sockaddr_in clientname;
|
struct sockaddr_in clientname;
|
||||||
size_t size;
|
size_t size;
|
||||||
struct timeval t;
|
struct timeval t;
|
||||||
client *c;
|
Client * c;
|
||||||
|
|
||||||
debug(RPT_INFO, "sock_poll_clients()");
|
debug(RPT_INFO, "sock_poll_clients()");
|
||||||
|
|
||||||
@@ -162,22 +165,26 @@ sock_poll_clients ()
|
|||||||
if (FD_ISSET (i, &read_fd_set)) {
|
if (FD_ISSET (i, &read_fd_set)) {
|
||||||
if (i == orig_sock) {
|
if (i == orig_sock) {
|
||||||
/* Connection request on original socket. */
|
/* Connection request on original socket. */
|
||||||
int new;
|
int new_sock;
|
||||||
size = sizeof (clientname);
|
size = sizeof (clientname);
|
||||||
new = accept (orig_sock, (struct sockaddr *) &clientname, &size);
|
new_sock = accept (orig_sock, (struct sockaddr *) &clientname, &size);
|
||||||
if (new < 0) {
|
if (new_sock < 0) {
|
||||||
report (RPT_ERR, "sock_poll_clients: Accept error");
|
report (RPT_ERR, "sock_poll_clients: Accept error");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
report (RPT_INFO, "sock_poll_clients: Connect from host %s:%hd on #%d",
|
report (RPT_INFO, "sock_poll_clients: Connect from host %s:%hd on #%d",
|
||||||
inet_ntoa (clientname.sin_addr), ntohs (clientname.sin_port), new);
|
inet_ntoa (clientname.sin_addr), ntohs (clientname.sin_port), new_sock);
|
||||||
FD_SET (new, &active_fd_set);
|
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?)*/
|
/* Create new client */
|
||||||
if (client_create (new) == NULL) {
|
if ((c = client_create (new_sock)) == NULL) {
|
||||||
report( RPT_ERR, "sock_poll_clients: error creating client %i", i);
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -189,10 +196,11 @@ sock_poll_clients ()
|
|||||||
debug (RPT_DEBUG, "sock_poll_clients: ...done");
|
debug (RPT_DEBUG, "sock_poll_clients: ...done");
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
/* TODO: Destroy a "client" here... (done?)*/
|
/* TODO: Destroy a "client" here... (done?)*/
|
||||||
c = client_find_sock (i);
|
c = clients_find_client_by_sock (i);
|
||||||
if (c) {
|
if (c) {
|
||||||
/*sock_send_string(i, "bye\n");*/
|
/*sock_send_string(i, "bye\n");*/
|
||||||
client_destroy (c);
|
client_destroy (c);
|
||||||
|
clients_remove_client (c);
|
||||||
close (i);
|
close (i);
|
||||||
FD_CLR (i, &active_fd_set);
|
FD_CLR (i, &active_fd_set);
|
||||||
report (RPT_INFO, "sock_poll_clients: Closed connection %i", i);
|
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);
|
report (RPT_ERR, "sock_poll_clients: Can't find client %i", i);
|
||||||
}
|
}
|
||||||
} while (err > 0);
|
} while (err > 0);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -212,7 +219,7 @@ read_from_client (int filedes)
|
|||||||
{
|
{
|
||||||
char buffer[MAXMSG];
|
char buffer[MAXMSG];
|
||||||
int nbytes, i;
|
int nbytes, i;
|
||||||
client *c;
|
Client * c;
|
||||||
|
|
||||||
report(RPT_DEBUG, "read_from_client()" );
|
report(RPT_DEBUG, "read_from_client()" );
|
||||||
|
|
||||||
@@ -241,7 +248,7 @@ read_from_client (int filedes)
|
|||||||
if (buffer[i] == 0)
|
if (buffer[i] == 0)
|
||||||
buffer[i] = '\n';
|
buffer[i] = '\n';
|
||||||
/* Enqueue a "client message" here...*/
|
/* Enqueue a "client message" here...*/
|
||||||
c = client_find_sock (filedes);
|
c = clients_find_client_by_sock (filedes);
|
||||||
if (c) {
|
if (c) {
|
||||||
client_add_message (c, buffer);
|
client_add_message (c, buffer);
|
||||||
} else
|
} else
|
||||||
|
|||||||
+59
-270
@@ -23,7 +23,8 @@
|
|||||||
#include "widget.h"
|
#include "widget.h"
|
||||||
#include "render.h"
|
#include "render.h"
|
||||||
|
|
||||||
char *types[] = { "none",
|
char *typenames[] = {
|
||||||
|
"none",
|
||||||
"string",
|
"string",
|
||||||
"hbar",
|
"hbar",
|
||||||
"vbar",
|
"vbar",
|
||||||
@@ -32,32 +33,38 @@ char *types[] = { "none",
|
|||||||
"scroller",
|
"scroller",
|
||||||
"frame",
|
"frame",
|
||||||
"num",
|
"num",
|
||||||
/*"",*/
|
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
static widget *widget_finder (LinkedList * list, char *id);
|
//static widget *widget_finder (LinkedList * list, char *id);
|
||||||
static int widget_remover (LinkedList * list, widget * w);
|
//static int widget_remover (LinkedList * list, widget * w);
|
||||||
|
|
||||||
widget *
|
Widget *
|
||||||
widget_create ()
|
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) {
|
if (!w) {
|
||||||
report (RPT_DEBUG, "widget_create: Error allocating widget");
|
report (RPT_DEBUG, "widget_create: Error allocating");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
w->id = NULL;
|
w->id = strdup(id);
|
||||||
w->type = 0;
|
if (!w->id) {
|
||||||
|
report (RPT_DEBUG, "widget_create: Error allocating");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
w->type = type;
|
||||||
|
w->screen = screen;
|
||||||
w->x = 1;
|
w->x = 1;
|
||||||
w->y = 1;
|
w->y = 1;
|
||||||
w->wid = 0;
|
w->width = 0;
|
||||||
w->hgt = 0;
|
w->height = 0;
|
||||||
w->left = 1;
|
w->left = 1;
|
||||||
w->top = 1;
|
w->top = 1;
|
||||||
w->right = 0;
|
w->right = 0;
|
||||||
@@ -65,22 +72,30 @@ widget_create ()
|
|||||||
w->length = 1;
|
w->length = 1;
|
||||||
w->speed = 1;
|
w->speed = 1;
|
||||||
w->text = NULL;
|
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;
|
return w;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
widget_destroy (widget * w)
|
widget_destroy (Widget * w)
|
||||||
{
|
{
|
||||||
LinkedList *list;
|
debug (RPT_INFO, "widget_destroy(%s)", w->id);
|
||||||
widget *foo;
|
|
||||||
|
|
||||||
if (!w)
|
if (!w)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
debug (RPT_INFO, "widget_destroy(%s)", w->id);
|
|
||||||
|
|
||||||
if (w->id)
|
if (w->id)
|
||||||
free (w->id);
|
free (w->id);
|
||||||
/*debug(RPT_DEBUG, "widget_destroy: id...");*/
|
/*debug(RPT_DEBUG, "widget_destroy: id...");*/
|
||||||
@@ -88,18 +103,13 @@ widget_destroy (widget * w)
|
|||||||
free (w->text);
|
free (w->text);
|
||||||
/*debug(RPT_DEBUG, "widget_destroy: text...");*/
|
/*debug(RPT_DEBUG, "widget_destroy: text...");*/
|
||||||
|
|
||||||
/* TODO: Free kids!*/
|
if (w->type == WID_FRAME) {
|
||||||
if (w->kids) {
|
/* TODO: create a screen for the frame widget */
|
||||||
list = w->kids;
|
}
|
||||||
LL_Rewind (list);
|
|
||||||
do {
|
|
||||||
foo = LL_Get (list);
|
|
||||||
if (foo)
|
|
||||||
widget_destroy (foo);
|
|
||||||
} while (0 == LL_Next (list));
|
|
||||||
|
|
||||||
LL_Destroy (list);
|
/* Free subscreen of frame widget too */
|
||||||
w->kids = NULL;
|
if (w->type == WID_FRAME) {
|
||||||
|
screen_destroy (w->frame_screen);
|
||||||
}
|
}
|
||||||
|
|
||||||
free (w);
|
free (w);
|
||||||
@@ -108,254 +118,33 @@ widget_destroy (widget * w)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
widget *
|
WidgetType
|
||||||
widget_find (screen * s, char *id)
|
widget_typename_to_type (char * typename)
|
||||||
{
|
|
||||||
/*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 wid_type = WID_NONE;
|
||||||
int i;
|
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);
|
for (i = 0; typenames[i]; i++) {
|
||||||
|
if (strcmp (typenames[i], typename) == 0) {
|
||||||
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;
|
|
||||||
wid_type = i;
|
wid_type = i;
|
||||||
break; /* it's valid: skip out...*/
|
break; /* it's valid: skip out...*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return wid_type;
|
||||||
|
}
|
||||||
|
|
||||||
if (!valid) {
|
char *
|
||||||
/* invalid widget type*/
|
widget_type_to_typename (WidgetType t)
|
||||||
sock_send_string (sock, "huh? Invalid widget type\n");
|
{
|
||||||
return 2;
|
return typenames[t];
|
||||||
}
|
}
|
||||||
|
|
||||||
debug (RPT_DEBUG, "widget_add: making widget");
|
Widget *
|
||||||
|
widget_search_subs (Widget * w, char * id)
|
||||||
/* 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...*/
|
|
||||||
if (w->type == WID_FRAME) {
|
if (w->type == WID_FRAME) {
|
||||||
if (!w->kids) {
|
return screen_find_widget (w->frame_screen, id);
|
||||||
w->kids = LL_new ();
|
} else {
|
||||||
if (!w->kids) {
|
return NULL; /* no kids */
|
||||||
report (RPT_ERR, "widget_add: error allocating kids for frame");
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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
|
#ifndef WIDGET_H
|
||||||
#define WIDGET_H
|
#define WIDGET_H
|
||||||
|
|
||||||
#include "screen.h"
|
struct Widget;
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
/* These correspond to the index into the "types" array...*/
|
/* These correspond to the index into the "types" array...*/
|
||||||
#define WID_NONE 0
|
typedef enum WidgetType {
|
||||||
#define WID_STRING 1
|
WID_NONE = 0,
|
||||||
#define WID_HBAR 2
|
WID_STRING,
|
||||||
#define WID_VBAR 3
|
WID_HBAR,
|
||||||
#define WID_ICON 4
|
WID_VBAR,
|
||||||
#define WID_TITLE 5
|
WID_ICON,
|
||||||
#define WID_SCROLLER 6
|
WID_TITLE,
|
||||||
#define WID_FRAME 7
|
WID_SCROLLER,
|
||||||
#define WID_NUM 8
|
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
|
#define WID_MAX_DIR 4
|
||||||
|
|
||||||
extern char *types[];
|
/* Create new widget */
|
||||||
|
Widget * widget_create (char *id, WidgetType type, Screen * screen);
|
||||||
|
|
||||||
widget *widget_create ();
|
/* Destroy a widget */
|
||||||
int widget_destroy (widget * w);
|
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);
|
/* Convert a widget typename to a widget type */
|
||||||
int widget_remove (screen * s, char *id, int sock);
|
char *widget_type_to_typename (WidgetType t);
|
||||||
|
|
||||||
|
/* Search subwidgets of a widget */
|
||||||
|
Widget * widget_search_subs (Widget * w, char * id);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user