lcdexec: parameter support using widgets; hidden behind compile time option
This commit is contained in:
@@ -33,6 +33,7 @@ v.0.5dev (ongoing development)
|
|||||||
* picolcd driver: overhaul USB init for more portability (M. Dolze)
|
* picolcd driver: overhaul USB init for more portability (M. Dolze)
|
||||||
+ curses driver: new option DrawBorder (Bruno Schwander)
|
+ curses driver: new option DrawBorder (Bruno Schwander)
|
||||||
* avoid sending duplicate "success" messages in response to menu_add_item
|
* avoid sending duplicate "success" messages in response to menu_add_item
|
||||||
|
+ lcdexec: parameter support using widgets; hidden behind compile time option
|
||||||
|
|
||||||
v.0.5.2
|
v.0.5.2
|
||||||
* fix switching on/off the Load screen in lcdproc client using the menu
|
* fix switching on/off the Load screen in lcdproc client using the menu
|
||||||
|
|||||||
+146
-14
@@ -40,6 +40,7 @@ typedef struct ProcInfo {
|
|||||||
time_t starttime; /**< start time of the process */
|
time_t starttime; /**< start time of the process */
|
||||||
time_t endtime; /**< finishing time of the process */
|
time_t endtime; /**< finishing time of the process */
|
||||||
int status; /**< exit status of the process */
|
int status; /**< exit status of the process */
|
||||||
|
int feedback; /**< what info to show to the user */
|
||||||
int shown; /**< tell if the info has been shown to the user */
|
int shown; /**< tell if the info has been shown to the user */
|
||||||
} ProcInfo;
|
} ProcInfo;
|
||||||
|
|
||||||
@@ -342,8 +343,9 @@ static int process_response(char *str)
|
|||||||
free(str2);
|
free(str2);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (strcmp(argv[1], "select") == 0) {
|
if ((strcmp(argv[1], "select") == 0) ||
|
||||||
MenuEntry *exec;
|
(strcmp(argv[1], "leave") == 0)) {
|
||||||
|
MenuEntry *entry;
|
||||||
|
|
||||||
if (argc < 3) {
|
if (argc < 3) {
|
||||||
report(RPT_WARNING, "Server gave invalid response");
|
report(RPT_WARNING, "Server gave invalid response");
|
||||||
@@ -351,16 +353,85 @@ static int process_response(char *str)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Find the id */
|
/* Find the entry by id */
|
||||||
exec = menu_find_by_id(main_menu, atoi(argv[2]));
|
entry = menu_find_by_id(main_menu, atoi(argv[2]));
|
||||||
if (exec == NULL) {
|
if (entry == NULL) {
|
||||||
report(RPT_WARNING, "Could not find the item id given by the server");
|
report(RPT_WARNING, "Could not find the item id given by the server");
|
||||||
free(str2);
|
free(str2);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
/* The id has been found */
|
|
||||||
exec_command(exec);
|
/* The id has been found.
|
||||||
|
* We trigger on the following conditions:
|
||||||
|
* - command entry without args
|
||||||
|
* - last arg of a command entry with args */
|
||||||
|
if (((entry->type == MT_EXEC) && (entry->children == NULL)) ||
|
||||||
|
((entry->type & MT_ARG_ANY) && (entry->next == NULL))) {
|
||||||
|
|
||||||
|
// last arg => get parent entry
|
||||||
|
if ((entry->type & MT_ARG_ANY) && (entry->next == NULL))
|
||||||
|
entry = entry->parent;
|
||||||
|
|
||||||
|
if (entry->type == MT_EXEC)
|
||||||
|
exec_command(entry);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
#if defined(LCDEXEC_PARAMS)
|
||||||
|
else if ((strcmp(argv[1], "plus") == 0) ||
|
||||||
|
(strcmp(argv[1], "minus") == 0) ||
|
||||||
|
(strcmp(argv[1], "update") == 0)) {
|
||||||
|
MenuEntry *entry;
|
||||||
|
|
||||||
|
if (argc < 4) {
|
||||||
|
report(RPT_WARNING, "Server gave invalid response");
|
||||||
|
free(str2);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Find the entry by id */
|
||||||
|
entry = menu_find_by_id(main_menu, atoi(argv[2]));
|
||||||
|
if (entry == NULL) {
|
||||||
|
report(RPT_WARNING, "Could not find the item id given by the server");
|
||||||
|
free(str2);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (entry->type) {
|
||||||
|
case MT_ARG_SLIDER:
|
||||||
|
entry->data.slider.value = atoi(argv[3]);
|
||||||
|
break;
|
||||||
|
case MT_ARG_RING:
|
||||||
|
entry->data.ring.value = atoi(argv[3]);
|
||||||
|
break;
|
||||||
|
case MT_ARG_NUMERIC:
|
||||||
|
entry->data.numeric.value = atoi(argv[3]);
|
||||||
|
break;
|
||||||
|
case MT_ARG_ALPHA:
|
||||||
|
entry->data.alpha.value = realloc(entry->data.alpha.value,
|
||||||
|
strlen(argv[3]));
|
||||||
|
strcpy(entry->data.alpha.value, argv[3]);
|
||||||
|
break;
|
||||||
|
case MT_ARG_IP:
|
||||||
|
entry->data.ip.value = realloc(entry->data.ip.value,
|
||||||
|
strlen(argv[3]));
|
||||||
|
strcpy(entry->data.ip.value, argv[3]);
|
||||||
|
break;
|
||||||
|
case MT_ARG_CHECKBOX:
|
||||||
|
if ((entry->data.checkbox.allow_gray) &&
|
||||||
|
(strcasecmp(argv[3], "gray") == 0))
|
||||||
|
entry->data.checkbox.value = 2;
|
||||||
|
else if (strcasecmp(argv[3], "on") == 0)
|
||||||
|
entry->data.checkbox.value = 1;
|
||||||
|
else
|
||||||
|
entry->data.checkbox.value = 0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
report(RPT_WARNING, "Illegal menu entry type for event");
|
||||||
|
free(str2);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
else {
|
else {
|
||||||
; /* Ignore other menuevents */
|
; /* Ignore other menuevents */
|
||||||
}
|
}
|
||||||
@@ -401,18 +472,64 @@ static int exec_command(MenuEntry *cmd)
|
|||||||
const char *argv[4];
|
const char *argv[4];
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
ProcInfo *p;
|
ProcInfo *p;
|
||||||
|
#if defined(LCDEXEC_PARAMS)
|
||||||
|
char *envp[cmd->numChildren+1];
|
||||||
|
MenuEntry *arg;
|
||||||
|
int i;
|
||||||
|
#endif
|
||||||
|
|
||||||
report(RPT_NOTICE, "Executing: %s", command);
|
/* set argument vector */
|
||||||
|
|
||||||
argv[0] = default_shell;
|
argv[0] = default_shell;
|
||||||
argv[1] = "-c";
|
argv[1] = "-c";
|
||||||
argv[2] = command;
|
argv[2] = command;
|
||||||
argv[3] = NULL;
|
argv[3] = NULL;
|
||||||
|
|
||||||
|
#if defined(LCDEXEC_PARAMS)
|
||||||
|
/* set environment vector: allocate & fill contents */
|
||||||
|
for (arg = cmd->children, i = 0; arg != NULL; arg = arg->next, i++) {
|
||||||
|
char buf[1025];
|
||||||
|
|
||||||
|
switch (arg->type) {
|
||||||
|
case MT_ARG_SLIDER:
|
||||||
|
snprintf(buf, 1024, "%s=%d", arg->name, arg->data.slider.value);
|
||||||
|
break;
|
||||||
|
case MT_ARG_RING:
|
||||||
|
snprintf(buf, 1024, "%s=%s", arg->name, arg->data.ring.strings[arg->data.ring.value]);
|
||||||
|
break;
|
||||||
|
case MT_ARG_NUMERIC:
|
||||||
|
snprintf(buf, 1024, "%s=%d", arg->name, arg->data.numeric.value);
|
||||||
|
break;
|
||||||
|
case MT_ARG_ALPHA:
|
||||||
|
snprintf(buf, 1024, "%s=%s", arg->name, arg->data.alpha.value);
|
||||||
|
break;
|
||||||
|
case MT_ARG_IP:
|
||||||
|
snprintf(buf, 1024, "%s=%s", arg->name, arg->data.ip.value);
|
||||||
|
break;
|
||||||
|
case MT_ARG_CHECKBOX:
|
||||||
|
snprintf(buf, 1024, "%s=%d", arg->name, arg->data.checkbox.value);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* error ? */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
buf[1024] ='\0';
|
||||||
|
envp[i] = strdup(buf);
|
||||||
|
|
||||||
|
debug(RPT_DEBUG, "Environment: %s", envp[i]);
|
||||||
|
}
|
||||||
|
envp[cmd->numChildren] = NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
debug(RPT_DEBUG, "Executing '%s' via Shell %s", command, default_shell);
|
||||||
|
|
||||||
switch (pid = fork()) {
|
switch (pid = fork()) {
|
||||||
case 0:
|
case 0:
|
||||||
/* We're the child: execute the command */
|
/* We're the child: execute the command */
|
||||||
|
#if defined(LCDEXEC_PARAMS)
|
||||||
|
execve(argv[0], (char **) argv, envp);
|
||||||
|
#else
|
||||||
execv(argv[0], (char **) argv);
|
execv(argv[0], (char **) argv);
|
||||||
|
#endif
|
||||||
exit(0);
|
exit(0);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -422,15 +539,23 @@ static int exec_command(MenuEntry *cmd)
|
|||||||
p->cmd = cmd;
|
p->cmd = cmd;
|
||||||
p->pid = pid;
|
p->pid = pid;
|
||||||
p->starttime = time(NULL);
|
p->starttime = time(NULL);
|
||||||
|
p->feedback = cmd->data.exec.feedback;
|
||||||
/* prepend it to existing queue atomically */
|
/* prepend it to existing queue atomically */
|
||||||
p->next = proc_queue;
|
p->next = proc_queue;
|
||||||
proc_queue = p;
|
proc_queue = p;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case -1:
|
case -1:
|
||||||
report(RPT_ERR, "Could not fork");
|
report(RPT_ERR, "Could not fork");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(LCDEXEC_PARAMS)
|
||||||
|
/* free envp's contents */
|
||||||
|
for (i = 0; envp[i] != NULL; i++)
|
||||||
|
free(envp[i]);
|
||||||
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
@@ -441,11 +566,15 @@ static int show_procinfo_msg(ProcInfo *p)
|
|||||||
{
|
{
|
||||||
if ((p != NULL) && (lcd_wid > 0) && (lcd_hgt > 0)) {
|
if ((p != NULL) && (lcd_wid > 0) && (lcd_hgt > 0)) {
|
||||||
if (p->endtime > 0) {
|
if (p->endtime > 0) {
|
||||||
|
/* nothing to do => the quick way out (successful) */
|
||||||
|
if ((p->shown) || (!p->feedback))
|
||||||
|
return 1;
|
||||||
|
|
||||||
sock_printf(sock, "screen_add [%u]\n", p->pid);
|
sock_printf(sock, "screen_add [%u]\n", p->pid);
|
||||||
sock_printf(sock, "screen_set [%u] -name {lcdexec [%u]}"
|
sock_printf(sock, "screen_set [%u] -name {lcdexec [%u]}"
|
||||||
" -priority alert -timeout %d"
|
" -priority alert -timeout %d"
|
||||||
" -heartbeat off\n",
|
" -heartbeat off\n",
|
||||||
p->pid, p->pid, 8*8);
|
p->pid, p->pid, 6*8);
|
||||||
|
|
||||||
if (lcd_hgt > 2) {
|
if (lcd_hgt > 2) {
|
||||||
sock_printf(sock, "widget_add [%u] t title\n", p->pid);
|
sock_printf(sock, "widget_add [%u] t title\n", p->pid);
|
||||||
@@ -472,8 +601,9 @@ static int show_procinfo_msg(ProcInfo *p)
|
|||||||
p->pid, WTERMSIG(p->status));
|
p->pid, WTERMSIG(p->status));
|
||||||
}
|
}
|
||||||
|
|
||||||
sock_printf(sock, "widget_set [%u] s3 1 4 {Exec time: %lds}\n",
|
if (lcd_hgt > 3)
|
||||||
p->pid, p->endtime - p->starttime);
|
sock_printf(sock, "widget_set [%u] s3 1 4 {Exec time: %lds}\n",
|
||||||
|
p->pid, p->endtime - p->starttime);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
sock_printf(sock, "widget_add [%u] s1 string\n", p->pid);
|
sock_printf(sock, "widget_add [%u] s1 string\n", p->pid);
|
||||||
@@ -496,9 +626,10 @@ static int show_procinfo_msg(ProcInfo *p)
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 1;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -560,3 +691,4 @@ static int main_loop(void)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* EOF */
|
||||||
|
|||||||
@@ -38,6 +38,8 @@ Entry=MenuC
|
|||||||
DisplayName="You can say A"
|
DisplayName="You can say A"
|
||||||
# the exec=... line tells that it is a command
|
# the exec=... line tells that it is a command
|
||||||
Exec="echo a"
|
Exec="echo a"
|
||||||
|
# show a temporary feedback screen upon completion [default: no; legal: yes, no]
|
||||||
|
Feedback= yes
|
||||||
|
|
||||||
[CmdB]
|
[CmdB]
|
||||||
DisplayName="Or you can say B"
|
DisplayName="Or you can say B"
|
||||||
@@ -55,20 +57,77 @@ DisplayName=P
|
|||||||
Exec="echo P"
|
Exec="echo P"
|
||||||
|
|
||||||
[CmdQ]
|
[CmdQ]
|
||||||
DisplayName=Q
|
DisplayName="Show environment"
|
||||||
Exec="echo Q"
|
Exec="env"
|
||||||
|
# When lcdexec is compiled with compiler option -DLCDEXEC_PARAMS
|
||||||
|
# you can change parameters for commands within lcdexec.
|
||||||
|
# Parameters are handed to the program as environment variables;
|
||||||
|
# so they can be easily used in the Exec=... line as $XXX
|
||||||
|
# (e.g. "echo $SLIDER_ARG").
|
||||||
|
# Please note a little issue with parameters: after changing the
|
||||||
|
# last parameter of a command the command gets executed automatically.
|
||||||
|
# This is IMHO noti ideal. I'm open for ideas to improve it.
|
||||||
|
# Here's how they are defined:
|
||||||
|
#Parameter=SLIDER_ARG
|
||||||
|
#Parameter=RING_ARG
|
||||||
|
#Parameter=NUMERIC_ARG
|
||||||
|
#Parameter=ALPHA_ARG
|
||||||
|
#Parameter=CHECKBOX_ARG
|
||||||
|
#Parameter=IP_ARG
|
||||||
|
#
|
||||||
|
#[SLIDER_ARG]
|
||||||
|
#DisplayName="Slider"
|
||||||
|
## Type of argument widget [legal: Slider, Checkbox, Ring, Numeric, Alpha, IP]
|
||||||
|
#Type=Slider
|
||||||
|
## inital value of the argument
|
||||||
|
#Value=5
|
||||||
|
## options depending on the widget type
|
||||||
|
#MinValue=0
|
||||||
|
#MaxValue=10
|
||||||
|
#
|
||||||
|
#[CHECKBOX_ARG]
|
||||||
|
#DisplayName="Checkbox"
|
||||||
|
#Type=Checkbox
|
||||||
|
#Value=on
|
||||||
|
#AllowGray=no
|
||||||
|
#
|
||||||
|
#[RING_ARG]
|
||||||
|
#DisplayName="Ring"
|
||||||
|
#Type=Ring
|
||||||
|
#Value=0
|
||||||
|
## list of alternative strings
|
||||||
|
#String=Eins
|
||||||
|
#String=Zwei
|
||||||
|
#String=Drei
|
||||||
|
#
|
||||||
|
#[NUMERIC_ARG]
|
||||||
|
#DisplayName="Numeric"
|
||||||
|
#Type=Numeric
|
||||||
|
#Value=5
|
||||||
|
#MinValue=0
|
||||||
|
#MaxValue=10
|
||||||
|
#
|
||||||
|
#[ALPHA_ARG]
|
||||||
|
#DisplayName="Alpha"
|
||||||
|
#Type=Alpha
|
||||||
|
## range of characters allowed [default: "ABCDEFGHIJKLMNOPQRSTUVWXYZ"]
|
||||||
|
#AllowedChars = "+-0123456789ABCDEF"
|
||||||
|
#Value=5
|
||||||
|
#MinLength=0
|
||||||
|
#MaxLength=10
|
||||||
|
#
|
||||||
|
#[IP_ARG]
|
||||||
|
#DisplayName="IP"
|
||||||
|
#Type=IP
|
||||||
|
#Value=10.230.2.2
|
||||||
|
#v6=no
|
||||||
|
|
||||||
|
|
||||||
# Further Extensions:
|
# Ideas for further extensions:
|
||||||
# - shell selectable in command sections
|
# - shell selectable in command sections
|
||||||
# - type definitions instead implicit depending on Exec/Entry
|
# - type definitions instead implicit depending on Exec/Entry
|
||||||
# (the latter only as fallback)
|
# (the latter only as fallback)
|
||||||
# - use input for parameters e.g. IP-Adresses, Sliders
|
# - display configurable result of a command on the display
|
||||||
# e.g. Exec="ifconfig ${IF} ${IP} netmask ${MASK} broadcast ${BCAST}"
|
|
||||||
# where
|
|
||||||
# - ${IF} is the result of a selection input screen
|
|
||||||
# - ${IP}, ${MASK}n ${BCAST} are the results of IP input screens
|
|
||||||
# - display result if a command on the display
|
|
||||||
# - jump to other menus depending on the output/result of a command
|
# - jump to other menus depending on the output/result of a command
|
||||||
|
|
||||||
# EOF
|
# EOF
|
||||||
|
|||||||
+400
-63
@@ -20,14 +20,21 @@
|
|||||||
|
|
||||||
#include "menu.h"
|
#include "menu.h"
|
||||||
|
|
||||||
|
/* names for boolean and tristate values */
|
||||||
|
static char *boolValueName[] = { "false", "true" };
|
||||||
|
#if defined(LCDEXEC_PARAMS)
|
||||||
|
static char *triGrayValueName[] = { "off", "on", "gray" };
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* recursively read the menu hierarchy */
|
/* recursively read the menu hierarchy */
|
||||||
MenuEntry *menu_read(MenuEntry *parent, const char *name)
|
MenuEntry *menu_read(MenuEntry *parent, const char *name)
|
||||||
{
|
{
|
||||||
static int id = 0;
|
static int id = 0;
|
||||||
|
|
||||||
if (config_has_section(name)) {
|
if (config_has_section(name)) {
|
||||||
MenuEntry *me = calloc(1, sizeof(MenuEntry));
|
MenuEntry *me = calloc(1, sizeof(MenuEntry)); // auto-NULL elements
|
||||||
|
|
||||||
if (me == NULL)
|
if (me == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
// set common entries
|
// set common entries
|
||||||
@@ -36,55 +43,158 @@ MenuEntry *menu_read(MenuEntry *parent, const char *name)
|
|||||||
if (me->name == NULL) {
|
if (me->name == NULL) {
|
||||||
//menu_free(me);
|
//menu_free(me);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
me->displayname = strdup(config_get_string(name, "DisplayName", 0, name));
|
me->displayname = strdup(config_get_string(name, "DisplayName", 0, name));
|
||||||
if (me->name == NULL) {
|
if (me->displayname == NULL) {
|
||||||
//menu_free(me);
|
//menu_free(me);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
me->entries = NULL;
|
me->parent = parent;
|
||||||
me->next = NULL;
|
me->next = NULL;
|
||||||
me->command = NULL;
|
me->children = NULL;
|
||||||
|
me->numChildren = 0;
|
||||||
|
|
||||||
if (config_get_string(name, "Entry", 0, NULL) != NULL) {
|
if (config_get_string(name, "Entry", 0, NULL) != NULL) {
|
||||||
MenuEntry **addr = &me->entries;
|
MenuEntry **addr = &me->children;
|
||||||
const char *entryname;
|
const char *entryname;
|
||||||
int index = 0;
|
|
||||||
|
|
||||||
// it is a sub-menu
|
// it is a sub-menu
|
||||||
me->type = menu;
|
me->type = MT_MENU;
|
||||||
|
|
||||||
while ((entryname = config_get_string(name, "Entry", index++, NULL)) != NULL) {
|
// read menu entries
|
||||||
|
while ((entryname = config_get_string(name, "Entry", me->numChildren, NULL)) != NULL) {
|
||||||
MenuEntry *entry = menu_read(me, entryname);
|
MenuEntry *entry = menu_read(me, entryname);
|
||||||
|
|
||||||
if (entry == NULL) {
|
if (entry == NULL) {
|
||||||
//menu_free(me);
|
//menu_free(me);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
me->numChildren++;
|
||||||
|
|
||||||
*addr = entry;
|
*addr = entry;
|
||||||
addr = &entry->next;
|
addr = &entry->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (config_get_string(name, "Exec", 0, NULL) != NULL) {
|
else if (config_get_string(name, "Exec", 0, NULL) != NULL) {
|
||||||
|
#if defined(LCDEXEC_PARAMS)
|
||||||
|
MenuEntry **addr = &me->children;
|
||||||
|
const char *entryname;
|
||||||
|
#endif
|
||||||
// it's a command to execute
|
// it's a command to execute
|
||||||
me->type = exec;
|
me->type = MT_EXEC;
|
||||||
|
|
||||||
me->command = strdup(config_get_string(name, "Exec", 0, ""));
|
me->data.exec.command = strdup(config_get_string(name, "Exec", 0, ""));
|
||||||
if (me->command == NULL) {
|
if (me->data.exec.command == NULL) {
|
||||||
//menu_free(me);
|
//menu_free(me);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
me->data.exec.feedback = config_get_bool(name, "Feedback", 0, 0);
|
||||||
|
|
||||||
|
#if defined(LCDEXEC_PARAMS)
|
||||||
|
// try to read parameters
|
||||||
|
while ((entryname = config_get_string(name, "Parameter", me->numChildren, NULL)) != NULL) {
|
||||||
|
MenuEntry *entry = menu_read(me, entryname);
|
||||||
|
|
||||||
|
if (entry == NULL) {
|
||||||
|
//menu_free(me);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
me->numChildren++;
|
||||||
|
|
||||||
|
*addr = entry;
|
||||||
|
addr = &entry->next;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
#if defined(LCDEXEC_PARAMS)
|
||||||
|
else if (config_get_string(name, "Type", 0, NULL) != NULL) {
|
||||||
|
// it's a command parameter
|
||||||
|
const char *type;
|
||||||
|
|
||||||
|
type = config_get_string(name, "Type", 0, "");
|
||||||
|
|
||||||
|
if (strcasecmp(type, "slider") == 0) {
|
||||||
|
char buf[35];
|
||||||
|
|
||||||
|
me->type = MT_ARG_SLIDER;
|
||||||
|
|
||||||
|
me->data.slider.value = config_get_int(name, "Value", 0, 0);
|
||||||
|
me->data.slider.minval = config_get_int(name, "MinValue", 0, 0);
|
||||||
|
me->data.slider.maxval = config_get_int(name, "MaxValue", 0, 1000);
|
||||||
|
|
||||||
|
sprintf(buf, "%d", me->data.slider.minval);
|
||||||
|
me->data.slider.mintext = strdup(config_get_string(name, "MinText", 0, buf));
|
||||||
|
sprintf(buf, "%d", me->data.slider.maxval);
|
||||||
|
me->data.slider.maxtext = strdup(config_get_string(name, "MaxText", 0, buf));
|
||||||
|
|
||||||
|
me->data.slider.stepsize = config_get_int(name, "StepSize", 0, 1);
|
||||||
|
}
|
||||||
|
else if (strcasecmp(type, "ring") == 0) {
|
||||||
|
const char *tmp;
|
||||||
|
int numStrings = 0;
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
me->type = MT_ARG_RING;
|
||||||
|
|
||||||
|
me->data.ring.value = config_get_int(name, "Value", 0, 0);
|
||||||
|
numStrings = config_has_key(name, "String");
|
||||||
|
me->data.ring.strings = calloc(sizeof(char *), numStrings+1);
|
||||||
|
me->data.ring.strings[numStrings] = NULL;
|
||||||
|
|
||||||
|
while ((tmp = config_get_string(name, "String", i, NULL)) != NULL) {
|
||||||
|
me->data.ring.strings[i] = strdup(tmp);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
me->data.ring.strings[i] = NULL;
|
||||||
|
}
|
||||||
|
else if (strcasecmp(type, "numeric") == 0) {
|
||||||
|
me->type = MT_ARG_NUMERIC;
|
||||||
|
|
||||||
|
me->data.numeric.value = config_get_int(name, "Value", 0, 0);
|
||||||
|
me->data.numeric.minval = config_get_int(name, "MinValue", 0, 0);
|
||||||
|
me->data.numeric.maxval = config_get_int(name, "MaxValue", 0, 1000);
|
||||||
|
}
|
||||||
|
else if (strcasecmp(type, "alpha") == 0) {
|
||||||
|
me->type = MT_ARG_ALPHA;
|
||||||
|
|
||||||
|
me->data.alpha.value = strdup(config_get_string(name, "Value", 0, ""));
|
||||||
|
me->data.alpha.minlen = config_get_int(name, "MinLength", 0, 0);
|
||||||
|
me->data.alpha.maxlen = config_get_int(name, "MaxLength", 0, 100);
|
||||||
|
me->data.alpha.allowed_chars = strdup(config_get_string(name, "AllowedChars", 0, "ABCDEFGHIJKLMNOPQRSTUVWXYZ"));
|
||||||
|
}
|
||||||
|
else if (strcasecmp(type, "ip") == 0) {
|
||||||
|
me->type = MT_ARG_IP;
|
||||||
|
|
||||||
|
me->data.ip.value = strdup(config_get_string(name, "Value", 0, ""));
|
||||||
|
me->data.ip.v6 = config_get_bool(name, "Value", 0, 0);
|
||||||
|
}
|
||||||
|
else if (strcasecmp(type, "checkbox") == 0) {
|
||||||
|
me->type = MT_ARG_CHECKBOX;
|
||||||
|
|
||||||
|
me->data.checkbox.allow_gray = config_get_bool(name, "AllowGray", 0, 0);
|
||||||
|
me->data.checkbox.value = (me->data.checkbox.allow_gray)
|
||||||
|
? config_get_tristate(name, "Value", 0, "gray", 0)
|
||||||
|
: config_get_bool(name, "Value", 0, 0);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
report(RPT_DEBUG, "illegal parameter type");
|
||||||
|
//menu_free(me);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
else {
|
else {
|
||||||
|
report(RPT_DEBUG, "unknown menu entry type");
|
||||||
//menu_free(me);
|
//menu_free(me);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return me;
|
return me;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -105,34 +215,169 @@ int menu_sock_send(MenuEntry *me, MenuEntry *parent, int sock)
|
|||||||
switch (me->type) {
|
switch (me->type) {
|
||||||
MenuEntry *entry;
|
MenuEntry *entry;
|
||||||
|
|
||||||
case menu:
|
case MT_MENU:
|
||||||
// don't create a separate entry for the main menu
|
// don't create a separate entry for the main menu
|
||||||
if ((parent != NULL) && (me->id != 0)) {
|
if ((parent != NULL) && (me->id != 0)) {
|
||||||
if (sock_printf(sock, "menu_add_item \"%s\" \"%d\" menu \"%s\"\n",
|
if (sock_printf(sock, "menu_add_item \"%s\" \"%d\" menu \"%s\"\n",
|
||||||
parent_id, me->id, me->displayname) < 0)
|
parent_id, me->id, me->displayname) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// recursively do it for the menu's sub-menus
|
// recursively do it for the menu's sub-menus
|
||||||
for (entry = me->entries; entry != NULL; entry = entry->next) {
|
for (entry = me->children; entry != NULL; entry = entry->next) {
|
||||||
if (menu_sock_send(entry, me, sock) < 0)
|
if (menu_sock_send(entry, me, sock) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case exec:
|
case MT_EXEC:
|
||||||
|
#if defined(LCDEXEC_PARAMS)
|
||||||
|
if (me->children == NULL) {
|
||||||
|
if (sock_printf(sock, "menu_add_item \"%s\" \"%d\" action \"%s\"\n",
|
||||||
|
parent_id, me->id, me->displayname) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (sock_printf(sock, "menu_set_item \"%s\" \"%d\" -menu_result quit\n",
|
||||||
|
parent_id, me->id) < 0)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if ((parent != NULL) && (me->id != 0)) {
|
||||||
|
if (sock_printf(sock, "menu_add_item \"%s\" \"%d\" menu \"%s\"\n",
|
||||||
|
parent_id, me->id, me->displayname) < 0)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// (recursively) do it for the entry's parameters
|
||||||
|
for (entry = me->children; entry != NULL; entry = entry->next) {
|
||||||
|
if (menu_sock_send(entry, me, sock) < 0)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
if (sock_printf(sock, "menu_add_item \"%s\" \"%d\" action \"%s\"\n",
|
if (sock_printf(sock, "menu_add_item \"%s\" \"%d\" action \"%s\"\n",
|
||||||
parent_id, me->id, me->displayname) < 0)
|
parent_id, me->id, me->displayname) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (sock_printf(sock, "menu_set_item \"%s\" \"%d\" -menu_result quit\n",
|
if (sock_printf(sock, "menu_set_item \"%s\" \"%d\" -menu_result quit\n",
|
||||||
parent_id, me->id) < 0)
|
parent_id, me->id) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
case unknown:
|
#if defined(LCDEXEC_PARAMS)
|
||||||
|
case MT_ARG_SLIDER:
|
||||||
|
if (sock_printf(sock, "menu_add_item \"%s\" \"%d\" slider -text \"%s\""
|
||||||
|
" -value %d -minvalue %d -maxvalue %d"
|
||||||
|
" -mintext \"%s\" -maxtext \"%s\" -stepsize %d\n",
|
||||||
|
parent_id, me->id, me->displayname,
|
||||||
|
me->data.slider.value,
|
||||||
|
me->data.slider.minval,
|
||||||
|
me->data.slider.maxval,
|
||||||
|
me->data.slider.mintext,
|
||||||
|
me->data.slider.maxtext,
|
||||||
|
me->data.slider.stepsize) <0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (me->next == NULL) {
|
||||||
|
if (sock_printf(sock, "menu_set_item \"%s\" \"%d\" -next _quit_\n",
|
||||||
|
parent_id, me->id) < 0)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MT_ARG_RING:
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
char *tmp = strdup("");
|
||||||
|
|
||||||
|
// join all strings with TAB as separator
|
||||||
|
for (i = 0; me->data.ring.strings[i] != NULL; i++) {
|
||||||
|
tmp = realloc(tmp, strlen(tmp) + 1 +
|
||||||
|
strlen(me->data.ring.strings[i]) + 1);
|
||||||
|
if (tmp[0] != '\0')
|
||||||
|
strcat(tmp, "\t");
|
||||||
|
strcat(tmp, me->data.ring.strings[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sock_printf(sock, "menu_add_item \"%s\" \"%d\" ring -text \"%s\""
|
||||||
|
" -value %d -strings \"%s\"\n",
|
||||||
|
parent_id, me->id, me->displayname,
|
||||||
|
me->data.ring.value,
|
||||||
|
tmp) < 0)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (me->next == NULL) {
|
||||||
|
if (sock_printf(sock, "menu_set_item \"%s\" \"%d\" -next _quit_\n",
|
||||||
|
parent_id, me->id) < 0)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MT_ARG_NUMERIC:
|
||||||
|
if (sock_printf(sock, "menu_add_item \"%s\" \"%d\" numeric -text \"%s\""
|
||||||
|
" -value %d -minvalue %d -maxvalue %d\n",
|
||||||
|
parent_id, me->id, me->displayname,
|
||||||
|
me->data.numeric.value,
|
||||||
|
me->data.numeric.minval,
|
||||||
|
me->data.numeric.maxval) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (me->next == NULL) {
|
||||||
|
if (sock_printf(sock, "menu_set_item \"%s\" \"%d\" -next _quit_\n",
|
||||||
|
parent_id, me->id) < 0)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MT_ARG_ALPHA:
|
||||||
|
if (sock_printf(sock, "menu_add_item \"%s\" \"%d\" alpha -text \"%s\""
|
||||||
|
" -value \"%s\" -minlength %d -maxlength %d"
|
||||||
|
" -allow_caps false -allow_noncaps false"
|
||||||
|
" -allow_numbers false -allowed_extra \"%s\"\n",
|
||||||
|
parent_id, me->id, me->displayname,
|
||||||
|
me->data.alpha.value,
|
||||||
|
me->data.alpha.minlen,
|
||||||
|
me->data.alpha.maxlen,
|
||||||
|
me->data.alpha.allowed_chars) <0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (me->next == NULL) {
|
||||||
|
if (sock_printf(sock, "menu_set_item \"%s\" \"%d\" -next _quit_\n",
|
||||||
|
parent_id, me->id) < 0)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MT_ARG_IP:
|
||||||
|
if (sock_printf(sock, "menu_add_item \"%s\" \"%d\" ip -text \"%s\""
|
||||||
|
" -value \"%s\" -v6 %s\n",
|
||||||
|
parent_id, me->id, me->displayname,
|
||||||
|
me->data.ip.value,
|
||||||
|
boolValueName[me->data.ip.v6]) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (me->next == NULL) {
|
||||||
|
if (sock_printf(sock, "menu_set_item \"%s\" \"%d\" -next _quit_\n",
|
||||||
|
parent_id, me->id) < 0)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MT_ARG_CHECKBOX:
|
||||||
|
if (sock_printf(sock, "menu_add_item \"%s\" \"%d\" checkbox -text \"%s\""
|
||||||
|
" -value %s -allow_gray %s\n",
|
||||||
|
parent_id, me->id, me->displayname,
|
||||||
|
triGrayValueName[me->data.checkbox.value],
|
||||||
|
boolValueName[me->data.checkbox.allow_gray]) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (me->next == NULL) {
|
||||||
|
if (sock_printf(sock, "menu_set_item \"%s\" \"%d\" -next _quit_\n",
|
||||||
|
parent_id, me->id) < 0)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -144,16 +389,16 @@ MenuEntry *menu_find_by_id(MenuEntry *me, int id)
|
|||||||
if (me->id == id)
|
if (me->id == id)
|
||||||
return me;
|
return me;
|
||||||
|
|
||||||
if (me->type == menu) {
|
if ((me->type == MT_MENU) || (me->type == MT_EXEC)) {
|
||||||
MenuEntry *entry;
|
MenuEntry *entry;
|
||||||
|
|
||||||
for (entry = me->entries; entry != NULL; entry = entry->next) {
|
for (entry = me->children; entry != NULL; entry = entry->next) {
|
||||||
MenuEntry *result = menu_find_by_id(entry, id);
|
MenuEntry *result = menu_find_by_id(entry, id);
|
||||||
|
|
||||||
if (result != NULL)
|
if (result != NULL)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -162,8 +407,8 @@ MenuEntry *menu_find_by_id(MenuEntry *me, int id)
|
|||||||
/* return command of a menu entry */
|
/* return command of a menu entry */
|
||||||
const char *menu_command(MenuEntry *me)
|
const char *menu_command(MenuEntry *me)
|
||||||
{
|
{
|
||||||
if ((me != NULL) && (me->type == exec))
|
if ((me != NULL) && (me->type == MT_EXEC))
|
||||||
return me->command;
|
return me->data.exec.command;
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -176,22 +421,55 @@ void menu_free(MenuEntry *me)
|
|||||||
switch (me->type) {
|
switch (me->type) {
|
||||||
MenuEntry *entry;
|
MenuEntry *entry;
|
||||||
|
|
||||||
case menu:
|
case MT_EXEC:
|
||||||
for (entry = me->entries; entry != NULL; ) {
|
if (me->data.exec.command != NULL)
|
||||||
|
free(me->data.exec.command);
|
||||||
|
me->data.exec.command = NULL;
|
||||||
|
/* fall through */
|
||||||
|
case MT_MENU:
|
||||||
|
for (entry = me->children; entry != NULL; ) {
|
||||||
MenuEntry *old = entry;
|
MenuEntry *old = entry;
|
||||||
|
|
||||||
entry = entry->next;
|
entry = entry->next;
|
||||||
old->next = NULL;
|
old->next = NULL;
|
||||||
menu_free(old);
|
menu_free(old);
|
||||||
}
|
}
|
||||||
me->entries = NULL;
|
me->children = NULL;
|
||||||
break;
|
break;
|
||||||
case exec:
|
#if defined(LCDEXEC_PARAMS)
|
||||||
if (me->command != NULL)
|
case MT_ARG_SLIDER:
|
||||||
free(me->command);
|
if (me->data.slider.mintext != NULL)
|
||||||
me->command = NULL;
|
free(me->data.slider.mintext);
|
||||||
|
me->data.slider.mintext = NULL;
|
||||||
|
if (me->data.slider.maxtext != NULL)
|
||||||
|
free(me->data.slider.maxtext);
|
||||||
|
me->data.slider.maxtext = NULL;
|
||||||
break;
|
break;
|
||||||
case unknown:
|
case MT_ARG_RING:
|
||||||
|
if (me->data.ring.strings != NULL) {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; me->data.ring.strings[i] != NULL; i++)
|
||||||
|
free(me->data.ring.strings[i]);
|
||||||
|
|
||||||
|
free(me->data.ring.strings);
|
||||||
|
me->data.ring.strings = NULL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MT_ARG_ALPHA:
|
||||||
|
if (me->data.alpha.value != NULL)
|
||||||
|
free(me->data.alpha.value);
|
||||||
|
me->data.alpha.value = NULL;
|
||||||
|
if (me->data.alpha.allowed_chars != NULL)
|
||||||
|
free(me->data.alpha.allowed_chars);
|
||||||
|
me->data.alpha.allowed_chars = NULL;
|
||||||
|
break;
|
||||||
|
case MT_ARG_IP:
|
||||||
|
if (me->data.ip.value != NULL)
|
||||||
|
free(me->data.ip.value);
|
||||||
|
me->data.ip.value = NULL;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -199,12 +477,12 @@ void menu_free(MenuEntry *me)
|
|||||||
if (me->name != NULL)
|
if (me->name != NULL)
|
||||||
free(me->name);
|
free(me->name);
|
||||||
me->name = NULL;
|
me->name = NULL;
|
||||||
|
|
||||||
if (me->displayname != NULL)
|
if (me->displayname != NULL)
|
||||||
free(me->displayname);
|
free(me->displayname);
|
||||||
me->displayname = NULL;
|
me->displayname = NULL;
|
||||||
|
|
||||||
me->type = unknown;
|
me->type = MT_UNKNOWN;
|
||||||
|
|
||||||
free(me);
|
free(me);
|
||||||
}
|
}
|
||||||
@@ -220,31 +498,90 @@ void menu_dump(MenuEntry *me)
|
|||||||
report(RPT_DEBUG, "[%s]", me->name);
|
report(RPT_DEBUG, "[%s]", me->name);
|
||||||
if (me->displayname != NULL)
|
if (me->displayname != NULL)
|
||||||
report(RPT_DEBUG, "DisplayName=\"%s\"", me->displayname);
|
report(RPT_DEBUG, "DisplayName=\"%s\"", me->displayname);
|
||||||
|
|
||||||
switch (me->type) {
|
switch (me->type) {
|
||||||
MenuEntry *entry;
|
MenuEntry *entry;
|
||||||
|
|
||||||
case menu:
|
case MT_MENU:
|
||||||
for (entry = me->entries; entry != NULL; entry = entry->next)
|
// dump menu entry references
|
||||||
|
for (entry = me->children; entry != NULL; entry = entry->next)
|
||||||
report(RPT_DEBUG, "Entry=%s", entry->name);
|
report(RPT_DEBUG, "Entry=%s", entry->name);
|
||||||
|
report(RPT_DEBUG, "");
|
||||||
|
|
||||||
|
// recursively walk through sub-menus
|
||||||
|
for (entry = me->children; entry != NULL; entry = entry->next)
|
||||||
|
menu_dump(entry);
|
||||||
break;
|
break;
|
||||||
case exec:
|
|
||||||
report(RPT_DEBUG, "Exec=\"%s\"", me->command);
|
case MT_EXEC:
|
||||||
|
report(RPT_DEBUG, "Exec=\"%s\"", me->data.exec.command);
|
||||||
|
report(RPT_DEBUG, "Feedback=%s", boolValueName[me->data.exec.feedback]);
|
||||||
|
#if defined(LCDEXEC_PARAMS)
|
||||||
|
// dump entry's parameter referencess
|
||||||
|
for (entry = me->children; entry != NULL; entry = entry->next)
|
||||||
|
report(RPT_DEBUG, "Parameter=%s", entry->name);
|
||||||
|
report(RPT_DEBUG, "");
|
||||||
|
|
||||||
|
// dump entry's parameters
|
||||||
|
for (entry = me->children; entry != NULL; entry = entry->next)
|
||||||
|
menu_dump(entry);
|
||||||
|
#else
|
||||||
|
report(RPT_DEBUG, "");
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
case unknown:
|
#if defined(LCDEXEC_PARAMS)
|
||||||
|
case MT_ARG_SLIDER:
|
||||||
|
report(RPT_DEBUG, "Type=slider");
|
||||||
|
report(RPT_DEBUG, "Value=%d", me->data.slider.value);
|
||||||
|
report(RPT_DEBUG, "MinValue=%d", me->data.slider.minval);
|
||||||
|
report(RPT_DEBUG, "MaxValue=%d", me->data.slider.maxval);
|
||||||
|
report(RPT_DEBUG, "Stepsize=%d", me->data.slider.stepsize);
|
||||||
|
report(RPT_DEBUG, "MinText=%s", me->data.slider.mintext);
|
||||||
|
report(RPT_DEBUG, "MaxText=%s", me->data.slider.maxtext);
|
||||||
|
report(RPT_DEBUG, "");
|
||||||
|
break;
|
||||||
|
case MT_ARG_RING:
|
||||||
|
report(RPT_DEBUG, "Type=ring");
|
||||||
|
report(RPT_DEBUG, "Value: %d", me->data.ring.value);
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; me->data.ring.strings[i] != NULL; i++)
|
||||||
|
report(RPT_DEBUG, "String=\"%s\"", me->data.ring.strings[i]);
|
||||||
|
}
|
||||||
|
report(RPT_DEBUG, "");
|
||||||
|
break;
|
||||||
|
case MT_ARG_NUMERIC:
|
||||||
|
report(RPT_DEBUG, "Type=numeric");
|
||||||
|
report(RPT_DEBUG, "Value=%d", me->data.numeric.value);
|
||||||
|
report(RPT_DEBUG, "MinValue=%d", me->data.numeric.minval);
|
||||||
|
report(RPT_DEBUG, "MaxValue=%d", me->data.numeric.maxval);
|
||||||
|
report(RPT_DEBUG, "");
|
||||||
|
break;
|
||||||
|
case MT_ARG_ALPHA:
|
||||||
|
report(RPT_DEBUG, "Type:=lpha");
|
||||||
|
report(RPT_DEBUG, "Value=\"%s\"", me->data.alpha.value);
|
||||||
|
report(RPT_DEBUG, "AllowedChars=\"%s\"", me->data.alpha.allowed_chars);
|
||||||
|
report(RPT_DEBUG, "");
|
||||||
|
break;
|
||||||
|
case MT_ARG_IP:
|
||||||
|
report(RPT_DEBUG, "Type=ip");
|
||||||
|
report(RPT_DEBUG, "Value=\"%s\"", me->data.ip.value);
|
||||||
|
report(RPT_DEBUG, "V6=%s", boolValueName[me->data.ip.v6]);
|
||||||
|
report(RPT_DEBUG, "");
|
||||||
|
break;
|
||||||
|
case MT_ARG_CHECKBOX:
|
||||||
|
report(RPT_DEBUG, "Type=ip");
|
||||||
|
report(RPT_DEBUG, "Value=%s", triGrayValueName[me->data.checkbox.value]);
|
||||||
|
report(RPT_DEBUG, "AllowGray=%s", boolValueName[me->data.checkbox.allow_gray]);
|
||||||
|
report(RPT_DEBUG, "");
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
report(RPT_DEBUG, "ERROR: unknown menu entry type");
|
report(RPT_DEBUG, "ERROR: unknown menu entry type");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
report(RPT_DEBUG, "");
|
|
||||||
|
|
||||||
// recursively walk through sub-menus
|
|
||||||
if (me->type == menu) {
|
|
||||||
MenuEntry *entry;
|
|
||||||
|
|
||||||
for (entry = me->entries; entry != NULL; entry = entry->next)
|
|
||||||
menu_dump(entry);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+57
-8
@@ -24,9 +24,19 @@
|
|||||||
|
|
||||||
/** Symbolic names for the types of a MenuEntry */
|
/** Symbolic names for the types of a MenuEntry */
|
||||||
typedef enum {
|
typedef enum {
|
||||||
unknown = 0, /**< Unknown MenuEntry type. */
|
MT_UNKNOWN = 0x00, /**< Unknown MenuEntry type. */
|
||||||
menu = 1, /**< MenuEntry representing a menu. */
|
MT_MENU = 0x01, /**< MenuEntry representing a menu. */
|
||||||
exec = 2, /**< MenuEntry representing an executable command. */
|
MT_EXEC = 0x02, /**< MenuEntry representing an executable command. */
|
||||||
|
|
||||||
|
MT_ARG_ANY = 0x10, /**< Mask denoting a parameter of any type */
|
||||||
|
#if defined(LCDEXEC_PARAMS)
|
||||||
|
MT_ARG_SLIDER = 0x11, /**< MenuEntry representing a slider parameter. */
|
||||||
|
MT_ARG_RING = 0x12, /**< MenuEntry representing a ring parameter. */
|
||||||
|
MT_ARG_NUMERIC = 0x13, /**< MenuEntry representing a numeric input parameter. */
|
||||||
|
MT_ARG_ALPHA = 0x14, /**< MenuEntry representing a alpha input parameter. */
|
||||||
|
MT_ARG_IP = 0x15, /**< MenuEntry representing a IP input parameter. */
|
||||||
|
MT_ARG_CHECKBOX = 0x16, /**< MenuEntry representing a checkbox input parameter. */
|
||||||
|
#endif
|
||||||
} MenuType;
|
} MenuType;
|
||||||
|
|
||||||
|
|
||||||
@@ -35,13 +45,52 @@ typedef struct menu_entry {
|
|||||||
char *displayname; /**< isible name of the entry. */
|
char *displayname; /**< isible name of the entry. */
|
||||||
int id; /**< Internal ID of the entry. */
|
int id; /**< Internal ID of the entry. */
|
||||||
MenuType type; /**< Type of the entry. */
|
MenuType type; /**< Type of the entry. */
|
||||||
|
struct menu_entry *parent; /**< Parent menu entry */
|
||||||
|
int numChildren; /**< # of child entries */
|
||||||
|
|
||||||
// variables necessary for type menu
|
// variables necessary for multiple types
|
||||||
struct menu_entry *entries; /**< Subordinate menu entries (for MenuType \c menu). */
|
struct menu_entry *children; /**< Subordinate menu entries (for MenuType \c MT_MENU & \c MT_EXEC). */
|
||||||
struct menu_entry *next; /**< Next sibling menu entry (for MenuType \c menu). */
|
struct menu_entry *next; /**< Next sibling menu entry (for MenuType \c MT_MENU). */
|
||||||
|
|
||||||
// variables necessary for type exec
|
union {
|
||||||
char *command; /**< Command to execute (for MenuType \c exec). */
|
struct { // elements necessary for type MT_EXEC
|
||||||
|
char *command; /**< Command to execute (for MenuType \c exec). */
|
||||||
|
int feedback; /**< Feedback option (for MenuType \c exec). */
|
||||||
|
} exec;
|
||||||
|
#if defined(LCDEXEC_PARAMS)
|
||||||
|
struct { // elements necessary for type MT_ARG_SLIDER
|
||||||
|
int value;
|
||||||
|
int minval;
|
||||||
|
int maxval;
|
||||||
|
int stepsize;
|
||||||
|
char *mintext;
|
||||||
|
char *maxtext;
|
||||||
|
} slider;
|
||||||
|
struct { // elements necessary for type MT_ARG_RING
|
||||||
|
int value;
|
||||||
|
char **strings;
|
||||||
|
} ring;
|
||||||
|
struct { // elements necessary for type MT_ARG_NUMERIC
|
||||||
|
int value;
|
||||||
|
int minval;
|
||||||
|
int maxval;
|
||||||
|
} numeric;
|
||||||
|
struct { // elements necessary for type MT_ARG_ALPHA
|
||||||
|
char *value;
|
||||||
|
int minlen;
|
||||||
|
int maxlen;
|
||||||
|
char *allowed_chars;
|
||||||
|
} alpha;
|
||||||
|
struct { // elements necessary for type MT_ARG_IP
|
||||||
|
char *value;
|
||||||
|
int v6;
|
||||||
|
} ip;
|
||||||
|
struct { // elements necessary for type MT_ARG_CHECKBOX
|
||||||
|
int value;
|
||||||
|
int allow_gray;
|
||||||
|
} checkbox;
|
||||||
|
#endif
|
||||||
|
} data;
|
||||||
} MenuEntry;
|
} MenuEntry;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+9
-1
@@ -94,7 +94,7 @@ is the hostname of the system \fIlcdexec\fP is running on.
|
|||||||
Set the shell to use when executing programs.
|
Set the shell to use when executing programs.
|
||||||
If not given, \fBlcdexec\fP tries to read the environment variable \fISHELL\fP.
|
If not given, \fBlcdexec\fP tries to read the environment variable \fISHELL\fP.
|
||||||
If that fails, it defaults to \fB/bin/sh\fP.
|
If that fails, it defaults to \fB/bin/sh\fP.
|
||||||
Please note that the shell given here must understand the option \fB-c\fP
|
Please note that the shell given here must understand the option \fB\-c\fP
|
||||||
followed by the command line to execute.
|
followed by the command line to execute.
|
||||||
.PP
|
.PP
|
||||||
|
|
||||||
@@ -119,6 +119,11 @@ Sections containing an \fBExec=\fP option are command entries.
|
|||||||
.B DisplayName=\fIname\fP
|
.B DisplayName=\fIname\fP
|
||||||
The name of the menu entry to be displayed on the LCD.
|
The name of the menu entry to be displayed on the LCD.
|
||||||
If this option is not given, the the section header name is used (without the square brackets).
|
If this option is not given, the the section header name is used (without the square brackets).
|
||||||
|
.TP 8
|
||||||
|
.B Feedback=\fIbool\fP
|
||||||
|
In command entries, this option tells whether to inform the user of the completion of
|
||||||
|
commands using an alert screen on the display.
|
||||||
|
If not given, it defaults to \fBno\fB.
|
||||||
.PP
|
.PP
|
||||||
|
|
||||||
.SH FILES
|
.SH FILES
|
||||||
@@ -178,14 +183,17 @@ Entry=RebootNow
|
|||||||
[Shutdown5min]
|
[Shutdown5min]
|
||||||
DisplayName="Shutdown in 5 minutes"
|
DisplayName="Shutdown in 5 minutes"
|
||||||
Exec="shutdown -h +5"
|
Exec="shutdown -h +5"
|
||||||
|
Feedback=yes
|
||||||
|
|
||||||
[Reboot5min]
|
[Reboot5min]
|
||||||
DisplayName="Reboot in 5 minutes"
|
DisplayName="Reboot in 5 minutes"
|
||||||
Exec="shutdown -r +5"
|
Exec="shutdown -r +5"
|
||||||
|
Feedback=yes
|
||||||
|
|
||||||
[CanclShutdown]
|
[CanclShutdown]
|
||||||
DisplayName="Cancel shutdown/reboot"
|
DisplayName="Cancel shutdown/reboot"
|
||||||
Exec="shutdown -c"
|
Exec="shutdown -c"
|
||||||
|
Feedback=yes
|
||||||
|
|
||||||
[ShutdownNow]
|
[ShutdownNow]
|
||||||
DisplayName="Shutdown now"
|
DisplayName="Shutdown now"
|
||||||
|
|||||||
Reference in New Issue
Block a user