X-Git-Url: http://git.ozlabs.org/?p=petitboot;a=blobdiff_plain;f=ui%2Fncurses%2Fnc-menu.c;h=e28168edd4cf6d253e10e4c2f04fa3939fd25192;hp=04207597db289245eef8e2f44372837f53265667;hb=1a9af828d9ad0da0efa7af286db78c8904344e6b;hpb=ac0f1324b64f7310c31aecb5dbf23b3ae0d5a3e0 diff --git a/ui/ncurses/nc-menu.c b/ui/ncurses/nc-menu.c index 0420759..e28168e 100644 --- a/ui/ncurses/nc-menu.c +++ b/ui/ncurses/nc-menu.c @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include "config.h" + #define _GNU_SOURCE #include @@ -94,6 +96,7 @@ struct pmenu_item *pmenu_item_setup(struct pmenu *menu, struct pmenu_item *i, unsigned int index, const char *name) { assert(i); + assert(name); if (!i) return NULL; @@ -114,6 +117,67 @@ struct pmenu_item *pmenu_item_setup(struct pmenu *menu, struct pmenu_item *i, return i; } +static int pmenu_item_get_index(const struct pmenu_item *item) +{ + unsigned int i; + + for (i = 0; i < item->pmenu->item_count; i++) + if (item->pmenu->items[i] == item->nci) + return i; + + pb_log("%s: not found: %p %s\n", __func__, item, + (item ? item->nci->name.str : "(null)")); + return -1; +} + +/** + * pmenu_item_replace - Replace the menu item with a new one. + * + * Use this routine to change a menu item's text. + */ + +int pmenu_item_replace(struct pmenu_item *i, const char *name) +{ + struct pmenu *menu; + ITEM *nci; + int index; + + assert(name); + assert(i->nci); + + menu = i->pmenu; + index = pmenu_item_get_index(i); + + if (index < 0) { + assert(0 && "get_index failed"); + return -1; + } + + nci = new_item(name, NULL); + + if (!nci) { + assert(0 && "new_item failed"); + return -1; + } + + set_item_userptr(nci, i); + + menu->scr.unpost(&menu->scr); + set_menu_items(menu->ncm, NULL); + + // FIXME: need to assure item name is a talloc string. + /* talloc_free((char *)item_name(i->nci)); */ + + free_item(i->nci); + menu->items[index] = nci; + i->nci = nci; + + set_menu_items(menu->ncm, menu->items); + menu->scr.post(&menu->scr); + + return 0; +} + /** * pmenu_move_cursor - Move the cursor. * @req: An ncurses request or char to send to menu_driver(). @@ -129,69 +193,58 @@ static void pmenu_move_cursor(struct pmenu *menu, int req) * pmenu_process_key - Process a user keystroke. */ -static void pmenu_process_key(struct nc_scr *scr) +static void pmenu_process_key(struct nc_scr *scr, int key) { struct pmenu *menu = pmenu_from_scr(scr); struct pmenu_item *item = pmenu_find_selected(menu); nc_scr_status_free(&menu->scr); - while (1) { - int c = getch(); - - if (c == ERR) - return; - - /* DBGS("%d (%o)\n", c, c); */ - - if (menu->hot_key) - c = menu->hot_key(menu, item, c); - - switch (c) { - case 27: /* ESC */ - if (menu->on_exit) - menu->on_exit(menu); - nc_flush_keys(); - return; - - case KEY_PPAGE: - pmenu_move_cursor(menu, REQ_SCR_UPAGE); - break; - case KEY_NPAGE: - pmenu_move_cursor(menu, REQ_SCR_DPAGE); - break; - case KEY_HOME: - pmenu_move_cursor(menu, REQ_FIRST_ITEM); - break; - case KEY_END: - pmenu_move_cursor(menu, REQ_LAST_ITEM); - break; - case KEY_UP: - pmenu_move_cursor(menu, REQ_UP_ITEM); - break; - case KEY_DOWN: - case '\t': - pmenu_move_cursor(menu, REQ_DOWN_ITEM); - break; - case KEY_LEFT: - case 'e': - if (item->on_edit) - item->on_edit(item); - break; - case 'o': - DBGS("on_open: %p\n", menu->on_open); - if (menu->on_open) - menu->on_open(menu); - break; - case '\n': - case '\r': - if (item->on_execute) - item->on_execute(item); - break; - default: - menu_driver(menu->ncm, c); - break; - } + if (menu->hot_key) + key = menu->hot_key(menu, item, key); + + switch (key) { + case 27: /* ESC */ + if (menu->on_exit) + menu->on_exit(menu); + nc_flush_keys(); + return; + + case KEY_PPAGE: + pmenu_move_cursor(menu, REQ_SCR_UPAGE); + break; + case KEY_NPAGE: + pmenu_move_cursor(menu, REQ_SCR_DPAGE); + break; + case KEY_HOME: + pmenu_move_cursor(menu, REQ_FIRST_ITEM); + break; + case KEY_END: + pmenu_move_cursor(menu, REQ_LAST_ITEM); + break; + case KEY_UP: + pmenu_move_cursor(menu, REQ_UP_ITEM); + break; + case KEY_DOWN: + pmenu_move_cursor(menu, REQ_DOWN_ITEM); + break; + case 'e': + if (item->on_edit) + item->on_edit(item); + break; + case 'o': + DBGS("on_open: %p\n", menu->on_open); + if (menu->on_open) + menu->on_open(menu); + break; + case '\n': + case '\r': + if (item->on_execute) + item->on_execute(item); + break; + default: + menu_driver(menu->ncm, key); + break; } } @@ -230,19 +283,6 @@ unsigned int pmenu_grow(struct pmenu *menu, unsigned int count) return tmp; } -static int pmenu_item_get_index(const struct pmenu_item *item) -{ - unsigned int i; - - for (i = 0; i < item->pmenu->item_count; i++) - if (item->pmenu->items[i] == item->nci) - return i; - - pb_log("%s: not found: %p %s\n", __func__, item, - (item ? item->nci->name.str : "(null)")); - return -1; -} - /** * pmenu_remove - Remove an item from the item array. * @@ -264,6 +304,9 @@ int pmenu_remove(struct pmenu *menu, struct pmenu_item *item) if (index < 0) return -1; + free_item(item->nci); + talloc_free(item); + /* Note that items array has a null terminator. */ menu->insert_pt--; @@ -351,7 +394,7 @@ void pmenu_delete(struct pmenu *menu) menu->scr.sig = pb_removed_sig; for (i = item_count(menu->ncm); i; i--) - free_item(menu->items[i]); + free_item(menu->items[i - 1]); free_menu(menu->ncm); delwin(menu->scr.sub_ncw);