From 0ccbe0bc2248f4467d8af979618a866cb98c7215 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Mon, 28 May 2018 17:33:36 +0200 Subject: [menu] Add --hidden option to create hotkey-only entries --- src/core/menu.c | 13 +++++++++++-- src/hci/commands/menu_cmd.c | 13 ++++++++++++- src/hci/tui/menu_ui.c | 13 +++++++++++++ src/include/ipxe/menu.h | 4 +++- 4 files changed, 39 insertions(+), 4 deletions(-) diff --git a/src/core/menu.c b/src/core/menu.c index ab5b0c7f5..abad59999 100644 --- a/src/core/menu.c +++ b/src/core/menu.c @@ -80,6 +80,7 @@ struct menu * create_menu ( const char *name, const char *title ) { strcpy ( title_copy, title ); menu->title = title_copy; INIT_LIST_HEAD ( &menu->items ); + INIT_LIST_HEAD ( &menu->hidden_items ); /* Add to list of menus */ list_add_tail ( &menu->list, &menus ); @@ -102,7 +103,7 @@ struct menu * create_menu ( const char *name, const char *title ) { */ struct menu_item * add_menu_item ( struct menu *menu, const char *label, const char *text, int shortcut, - int is_default ) { + int is_default, int is_hidden ) { size_t label_len; size_t text_len; size_t len; @@ -135,7 +136,11 @@ struct menu_item * add_menu_item ( struct menu *menu, const char *label, item->is_default = is_default; /* Add to list of items */ - list_add_tail ( &item->list, &menu->items ); + if ( is_hidden ) { + list_add_tail ( &item->list, &menu->hidden_items ); + } else { + list_add_tail ( &item->list, &menu->items ); + } return item; } @@ -157,6 +162,10 @@ void destroy_menu ( struct menu *menu ) { list_del ( &item->list ); free ( item ); } + list_for_each_entry_safe ( item, tmp, &menu->hidden_items, list ) { + list_del ( &item->list ); + free ( item ); + } /* Free menu */ free ( menu ); diff --git a/src/hci/commands/menu_cmd.c b/src/hci/commands/menu_cmd.c index 76bce8695..c8692f1a7 100644 --- a/src/hci/commands/menu_cmd.c +++ b/src/hci/commands/menu_cmd.c @@ -118,6 +118,8 @@ struct item_options { int is_default; /** Use as a separator */ int is_gap; + /** Don't show; hotkey only */ + int is_hidden; }; /** "item" option list */ @@ -130,6 +132,8 @@ static struct option_descriptor item_opts[] = { struct item_options, is_default, parse_flag ), OPTION_DESC ( "gap", 'g', no_argument, struct item_options, is_gap, parse_flag ), + OPTION_DESC ( "hidden", 'i', no_argument, + struct item_options, is_hidden, parse_flag ), }; /** "item" command descriptor */ @@ -160,6 +164,12 @@ static int item_exec ( int argc, char **argv ) { if ( ! opts.is_gap ) label = argv[optind++]; /* May be NULL */ + /* Hidden entry without label and shortcut is pointless */ + if ( opts.is_hidden && ( ! opts.key || ! label || ! *label ) ) { + rc = -EINVAL; + goto err_invalid_argument; + } + /* Parse text, if present */ if ( optind < argc ) { text = concat_args ( &argv[optind] ); @@ -175,7 +185,7 @@ static int item_exec ( int argc, char **argv ) { /* Add menu item */ item = add_menu_item ( menu, label, ( text ? text : "" ), - opts.key, opts.is_default ); + opts.key, opts.is_default, opts.is_hidden ); if ( ! item ) { rc = -ENOMEM; goto err_add_menu_item; @@ -188,6 +198,7 @@ static int item_exec ( int argc, char **argv ) { err_parse_menu: free ( text ); err_parse_text: + err_invalid_argument: err_parse_options: return rc; } diff --git a/src/hci/tui/menu_ui.c b/src/hci/tui/menu_ui.c index f9dd9d100..cb4edbbc8 100644 --- a/src/hci/tui/menu_ui.c +++ b/src/hci/tui/menu_ui.c @@ -217,6 +217,8 @@ static int menu_loop ( struct menu_ui *ui, struct menu_item **selected ) { break; default: i = 0; + + /* Check for shortcut. Visible items */ list_for_each_entry ( item, &ui->menu->items, list ) { if ( ! ( item->shortcut && @@ -231,6 +233,16 @@ static int menu_loop ( struct menu_ui *ui, struct menu_item **selected ) { move = +1; } } + + /* Hidden items */ + list_for_each_entry ( item, &ui->menu->hidden_items, + list ) { + if ( item->shortcut && + ( item->shortcut == key ) ) { + *selected = item; + goto hidden_entry_selected; + } + } break; } } @@ -259,6 +271,7 @@ static int menu_loop ( struct menu_ui *ui, struct menu_item **selected ) { } while ( ( rc == 0 ) && ! chosen ); + hidden_entry_selected: return rc; } diff --git a/src/include/ipxe/menu.h b/src/include/ipxe/menu.h index 3cc99be48..33965cfdf 100644 --- a/src/include/ipxe/menu.h +++ b/src/include/ipxe/menu.h @@ -21,6 +21,8 @@ struct menu { const char *title; /** Menu items */ struct list_head items; + /** Hidden menu items, accessible via hotkey only */ + struct list_head hidden_items; }; /** A menu item */ @@ -40,7 +42,7 @@ struct menu_item { extern struct menu * create_menu ( const char *name, const char *title ); extern struct menu_item * add_menu_item ( struct menu *menu, const char *label, const char *text, int shortcut, - int is_default ); + int is_default, int is_hidden ); extern void destroy_menu ( struct menu *menu ); extern struct menu * find_menu ( const char *name ); extern int show_menu ( struct menu *menu, unsigned long timeout, -- cgit v1.2.3-55-g7522