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:
@@ -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
|
||||
Reference in New Issue
Block a user