diff --git a/clients/lcdexec/lcdexec.c b/clients/lcdexec/lcdexec.c index c8725b3..b840ee5 100644 --- a/clients/lcdexec/lcdexec.c +++ b/clients/lcdexec/lcdexec.c @@ -366,10 +366,10 @@ static int process_response(char *str) * - 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))) { + ((entry->type & MT_ARGUMENT) && (entry->next == NULL))) { // last arg => get parent entry - if ((entry->type & MT_ARG_ANY) && (entry->next == NULL)) + if ((entry->type & MT_ARGUMENT) && (entry->next == NULL)) entry = entry->parent; if (entry->type == MT_EXEC) diff --git a/clients/lcdexec/lcdexec.conf b/clients/lcdexec/lcdexec.conf index 0932e5c..17fcb5c 100644 --- a/clients/lcdexec/lcdexec.conf +++ b/clients/lcdexec/lcdexec.conf @@ -64,9 +64,11 @@ Exec="env" # 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. +# Please note: command with parameters get an action entry +# added to the parameter menu automatically. +# Activating this entry will execute the program. +# This is IMHO not ideal, but the best idea I could come up with +# I'm open for ideas to improve it. # Here's how they are defined: #Parameter=SLIDER_ARG #Parameter=RING_ARG diff --git a/clients/lcdexec/menu.c b/clients/lcdexec/menu.c index 2e7e90e..77957cf 100644 --- a/clients/lcdexec/menu.c +++ b/clients/lcdexec/menu.c @@ -32,7 +32,7 @@ MenuEntry *menu_read(MenuEntry *parent, const char *name) { static int id = 0; - if (config_has_section(name)) { + if ((name != NULL) && (config_has_section(name))) { MenuEntry *me = calloc(1, sizeof(MenuEntry)); // auto-NULL elements if (me == NULL) @@ -108,6 +108,10 @@ MenuEntry *menu_read(MenuEntry *parent, const char *name) *addr = entry; addr = &entry->next; } + + // automagically add an "Apply ?" action + if ((me->numChildren > 0) && (addr != NULL)) + *addr = menu_read(me, NULL); #endif } #if defined(LCDEXEC_PARAMS) @@ -195,6 +199,39 @@ MenuEntry *menu_read(MenuEntry *parent, const char *name) return me; } + else { + /* the magic stuff: if name is NULL and parent is an EXEC entry, + * then generate an Action entry with the name "Apply" */ + if ((name == NULL) && (parent != NULL) && (parent->type = MT_EXEC)) { + MenuEntry *me = calloc(1, sizeof(MenuEntry)); // auto-NULL elements + + if (me == NULL) + return NULL; + // set common entries + me->id = id++; + me->name = malloc(strlen(parent->name) + 10); + if (me->name == NULL) { + //menu_free(me); + return NULL; + } + strcpy(me->name, "Apply_"); + strcat(me->name, parent->name); + + me->displayname = strdup("Apply!"); + if (me->displayname == NULL) { + //menu_free(me); + return NULL; + } + + me->parent = parent; + me->next = NULL; + me->children = NULL; + me->numChildren = 0; + me->type = MT_ARG_ACTION | MT_AUTOMATIC; + + return me; + } + } return NULL; } @@ -372,6 +409,15 @@ int menu_sock_send(MenuEntry *me, MenuEntry *parent, int sock) return -1; } break; + case MT_ARG_ACTION | MT_AUTOMATIC: + 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; + break; #endif default: return -1; @@ -494,6 +540,10 @@ void menu_free(MenuEntry *me) void menu_dump(MenuEntry *me) { if (me != NULL) { + /* the quick way out */ + if (me->type & MT_AUTOMATIC) + return; + report(RPT_DEBUG, "# menu ID: %d", me->id); report(RPT_DEBUG, "[%s]", me->name); if (me->displayname != NULL) diff --git a/clients/lcdexec/menu.h b/clients/lcdexec/menu.h index 33609d5..fd698f9 100644 --- a/clients/lcdexec/menu.h +++ b/clients/lcdexec/menu.h @@ -24,18 +24,19 @@ /** Symbolic names for the types of a MenuEntry */ typedef enum { - MT_UNKNOWN = 0x00, /**< Unknown MenuEntry type. */ - MT_MENU = 0x01, /**< MenuEntry representing a menu. */ - MT_EXEC = 0x02, /**< MenuEntry representing an executable command. */ - - MT_ARG_ANY = 0x10, /**< Mask denoting a parameter of any type */ + MT_UNKNOWN = 0x00, /**< Unknown MenuEntry type. */ + MT_MENU = 0x10, /**< MenuEntry representing a menu. */ + MT_EXEC = 0x20, /**< MenuEntry representing an executable command. */ + MT_ARGUMENT = 0x40, /**< Mask denoting a parameter of any type */ + MT_AUTOMATIC = 0x80, /**< BitFlag denoting automatically generated entries */ #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. */ + MT_ARG_SLIDER = 0x41, /**< MenuEntry representing a slider parameter. */ + MT_ARG_RING = 0x42, /**< MenuEntry representing a ring parameter. */ + MT_ARG_NUMERIC = 0x43, /**< MenuEntry representing a numeric input parameter. */ + MT_ARG_ALPHA = 0x44, /**< MenuEntry representing a alpha input parameter. */ + MT_ARG_IP = 0x45, /**< MenuEntry representing a IP input parameter. */ + MT_ARG_CHECKBOX = 0x46, /**< MenuEntry representing a checkbox input parameter. */ + MT_ARG_ACTION = 0x47, /**< MenuEntry representing a checkbox input parameter. */ #endif } MenuType;