/** \file server/commands/menu_commands.c * Implements handlers for client commands concerning menus. * * 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 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, Selene Scriven * 2002, Joris Robijn * 2004, F5 Networks, Inc. - IP-address input * 2005, Peter Marschall - error checks, ... */ #include #include #include #include #include #include #include #include #include "shared/report.h" #include "shared/sockets.h" #include "menu.h" #include "menuitem.h" #include "menuscreens.h" #include "menu_commands.h" #include "client.h" /* Local functions */ MenuEventFunc(menu_commands_handler); int set_predecessor(MenuItem *item, char *itemid, Client *client); int set_successor(MenuItem *item, char *itemid, Client *client); /** small utility for debug output of command line. */ static char *argv2string(int argc, char **argv) { char *rtn = NULL; unsigned int len; unsigned int i; for (i = len = 0; i < argc; i++) len += strlen(argv[i]) + 1; rtn = malloc(len + 1); if (rtn != NULL) { rtn[0] = '\0'; for (i = 0; i < argc; i++) { strcat(rtn, argv[i]); strcat(rtn, " "); } } return rtn; } /** * Adds an item to a menu. * *\verbatim * Usage: menu_add_item [] *\endverbatim * * You should use "" as id for the client's main menu. This menu will be * created automatically when you add an item to it the first time. * * You (currently?) cannot create a menu in the main level yourself. * The names you use for items should be unique for your client. * The text is the visible text for the item. * * The following types are available: * - menu * - action * - checkbox * - ring (a kind of listbox of one line) * - slider * - numeric * - alpha * - ip */ int menu_add_item_func(Client *c, int argc, char **argv) { char *menu_id; char *item_id; char *text = NULL; Menu *menu = NULL; MenuItem *item; MenuItemType itemtype; debug(RPT_DEBUG, "%s(Client [%d], %s, %s)", __FUNCTION__, c->sock, argv[1], argv[2]); if (c->state != ACTIVE) return 1; if (c->name == NULL) { sock_send_error(c->sock, "You need to give your client a name first\n"); return 0; } if (argc < 4) { sock_send_error(c->sock, "Usage: menu_add_item []\n"); return 0; } menu_id = argv[1]; item_id = argv[2]; /* Does the client have a menu already ? */ if (c->menu == NULL) { /* We need to create it */ report(RPT_INFO, "Client [%d] is using the menu", c->sock); c->menu = menu_create("_client_menu_", menu_commands_handler, c->name, c); if (c->menu == NULL) { sock_send_error(c->sock, "Cannot create menu\n"); return 1; } menu_add_item(main_menu, c->menu); } /* use either the given menu or the client's main menu if none was specified */ menu = (menu_id[0] != '\0') ? menu_find_item(c->menu, menu_id, true) : c->menu; if (menu == NULL) { sock_send_error(c->sock, "Cannot find menu id\n"); return 0; } item = menu_find_item(c->menu, item_id, true); if (item != NULL) { sock_send_error(c->sock, "Item id already in use\n"); return 0; } /* Find menuitem type */ itemtype = menuitem_typename_to_type(argv[3]); if (itemtype == -1) { sock_send_error(c->sock, "Invalid menuitem type\n"); return 0; } /* Is a text given (options don't count)? */ if ((argc >= 5) && (argv[4][0] != '-')) { text = argv[4]; } else { text = ""; } /* Create the menuitem */ switch (itemtype) { case MENUITEM_MENU: item = menu_create(item_id, menu_commands_handler, text, c); break; case MENUITEM_ACTION: item = menuitem_create_action(item_id, menu_commands_handler, text, c, MENURESULT_NONE); break; case MENUITEM_CHECKBOX: item = menuitem_create_checkbox(item_id, menu_commands_handler, text, c, false, false); break; case MENUITEM_RING: item = menuitem_create_ring(item_id, menu_commands_handler, text, c, "", 0); break; case MENUITEM_SLIDER: item = menuitem_create_slider(item_id, menu_commands_handler, text, c, "", "", 0, 100, 1, 25); break; case MENUITEM_NUMERIC: item = menuitem_create_numeric(item_id, menu_commands_handler, text, c, 0, 100, 0); break; case MENUITEM_ALPHA: item = menuitem_create_alpha(item_id, menu_commands_handler, text, c, 0, 0, 10, true, false, true, "-./", ""); break; case MENUITEM_IP: item = menuitem_create_ip(item_id, menu_commands_handler, text, c, 0, "192.168.1.245"); break; default: assert(!"unexpected menuitem type"); } menu_add_item(menu, item); menuscreen_inform_item_modified(menu); /* call menu_set_item() with a temporarily allocated argv * to process the remaining options */ if ((argc > 5) || (argv[4][0] == '-')) { // menu_add_item [] // menu_set_item {