
* In menu_interactive_choice can be used user specified function item_data_choice (instead hardcoded function which read input from standard input)
* Added option to specify user data for menu
* menu_display_statusline will pass pointer to user data (instead pointer to menu)
* This patch is needed for creating ANSI bootmenu
Signed-off-by: Pali Rohár pali.rohar@gmail.com --- No changes in v3
Changes in v2: - Rebased on next
board/ait/cam_enc_4xx/cam_enc_4xx.c | 5 ++-- common/cmd_pxe.c | 3 ++- common/menu.c | 43 +++++++++++++++++++++++------------ include/menu.h | 6 +++-- 4 files changed, 37 insertions(+), 20 deletions(-)
diff --git a/board/ait/cam_enc_4xx/cam_enc_4xx.c b/board/ait/cam_enc_4xx/cam_enc_4xx.c index 32b28f9..5078b01 100644 --- a/board/ait/cam_enc_4xx/cam_enc_4xx.c +++ b/board/ait/cam_enc_4xx/cam_enc_4xx.c @@ -561,7 +561,8 @@ static char *menu_handle(struct menu_display *display) char *s; char temp[6][200];
- m = menu_create(display->title, display->timeout, 1, ait_menu_print); + m = menu_create(display->title, display->timeout, 1, ait_menu_print, + NULL, NULL);
for (i = 0; display->menulist[i]; i++) { sprintf(key, "%d", i + 1); @@ -1097,7 +1098,7 @@ int menu_show(int bootdelay) return MENU_EXIT; }
-void menu_display_statusline(struct menu *m) +void menu_display_statusline(void *data) { char *s1, *s2;
diff --git a/common/cmd_pxe.c b/common/cmd_pxe.c index ee75db9..2dbd49c 100644 --- a/common/cmd_pxe.c +++ b/common/cmd_pxe.c @@ -1280,7 +1280,8 @@ static struct menu *pxe_menu_to_menu(struct pxe_menu *cfg) /* * Create a menu and add items for all the labels. */ - m = menu_create(cfg->title, cfg->timeout, cfg->prompt, label_print); + m = menu_create(cfg->title, cfg->timeout, cfg->prompt, label_print, + NULL, NULL);
if (!m) return NULL; diff --git a/common/menu.c b/common/menu.c index 6b2a2db..8b27c10 100644 --- a/common/menu.c +++ b/common/menu.c @@ -47,6 +47,8 @@ struct menu { char *title; int prompt; void (*item_data_print)(void *); + char *(*item_data_choice)(void *); + void *data; struct list_head items; };
@@ -113,11 +115,11 @@ static inline void *menu_item_destroy(struct menu *m, return NULL; }
-void __menu_display_statusline(struct menu *m) +void __menu_display_statusline(void *menu_data) { return; } -void menu_display_statusline(struct menu *m) +void menu_display_statusline(void *menu_data) __attribute__ ((weak, alias("__menu_display_statusline")));
/* @@ -130,7 +132,7 @@ static inline void menu_display(struct menu *m) puts(m->title); putc('\n'); } - menu_display_statusline(m); + menu_display_statusline(m->data);
menu_items_iter(m, menu_item_print, NULL); } @@ -204,18 +206,25 @@ static inline int menu_interactive_choice(struct menu *m, void **choice)
menu_display(m);
- readret = readline_into_buffer("Enter choice: ", cbuf, - m->timeout / 10); - - if (readret >= 0) { - choice_item = menu_item_by_key(m, cbuf); + if (!m->item_data_choice) { + readret = readline_into_buffer("Enter choice: ", cbuf, + m->timeout / 10); + + if (readret >= 0) { + choice_item = menu_item_by_key(m, cbuf); + if (!choice_item) + printf("%s not found\n", cbuf); + } else + return menu_default_choice(m, choice); + } else { + char *key = m->item_data_choice(m->data); + if (!key) + return menu_default_choice(m, choice); + choice_item = menu_item_by_key(m, key); + }
- if (!choice_item) { - printf("%s not found\n", cbuf); - m->timeout = 0; - } - } else - return menu_default_choice(m, choice); + if (!choice_item) + m->timeout = 0; }
*choice = choice_item->data; @@ -352,7 +361,9 @@ int menu_item_add(struct menu *m, char *item_key, void *item_data) * insufficient memory available to create the menu. */ struct menu *menu_create(char *title, int timeout, int prompt, - void (*item_data_print)(void *)) + void (*item_data_print)(void *), + char *(*item_data_choice)(void *), + void *menu_data) { struct menu *m;
@@ -365,6 +376,8 @@ struct menu *menu_create(char *title, int timeout, int prompt, m->prompt = prompt; m->timeout = timeout; m->item_data_print = item_data_print; + m->item_data_choice = item_data_choice; + m->data = menu_data;
if (title) { m->title = strdup(title); diff --git a/include/menu.h b/include/menu.h index 7af5fdb..00e8975 100644 --- a/include/menu.h +++ b/include/menu.h @@ -21,12 +21,14 @@ struct menu;
struct menu *menu_create(char *title, int timeout, int prompt, - void (*item_data_print)(void *)); + void (*item_data_print)(void *), + char *(*item_data_choice)(void *), + void *menu_data); int menu_default_set(struct menu *m, char *item_key); int menu_get_choice(struct menu *m, void **choice); int menu_item_add(struct menu *m, char *item_key, void *item_data); int menu_destroy(struct menu *m); -void menu_display_statusline(struct menu *m); +void menu_display_statusline(void *menu_data);
#if defined(CONFIG_MENU_SHOW) int menu_show(int bootdelay);