Patchwork [U-Boot,v4,1/4] menu: Add support for user defined item choice function

login
register
mail settings
Submitter Anatolij Gustschin
Date March 24, 2013, 12:50 a.m.
Message ID <1364086240-13412-1-git-send-email-agust@denx.de>
Download mbox | patch
Permalink /patch/230359/
State Accepted
Delegated to: Anatolij Gustschin
Headers show

Comments

Anatolij Gustschin - March 24, 2013, 12:50 a.m.
From: Pali Rohár <pali.rohar@gmail.com>

Selecting menu items is currently done in menu_interactive_choice()
by reading the user input strings from standard input.

Extend menu_interactive_choice() to support user defined function
for selecting menu items. This function and its argument can be
specified when creating the menu.

Signed-off-by: Pali Rohár <pali.rohar@gmail.com>
Signed-off-by: Anatolij Gustschin <agust@denx.de>
---
Changes in v4:
 - slightly rename the new item choice callback and its argument
 - add documentation for added item choice callback
 - search for menu item key only if the choice callback
   returned a key (not NULL)
 - do not change menu_display_statusline() function argument
   (previous patch changed this menu API function but didn't
    update documentation for this change. This change is
    actually not needed, menu item data can be obtained by
    exported menu_default_choice())
 - revise commit log

No changes in v3

Changes in v2:
  - Rebased on next

 board/ait/cam_enc_4xx/cam_enc_4xx.c |    3 +-
 common/cmd_pxe.c                    |    3 +-
 common/menu.c                       |   42 +++++++++++++++++++++++++---------
 doc/README.menu                     |    4 ++-
 include/menu.h                      |    4 ++-
 5 files changed, 41 insertions(+), 15 deletions(-)
Anatolij Gustschin - March 28, 2013, 3:26 p.m.
On Sun, 24 Mar 2013 01:50:40 +0100
Anatolij Gustschin <agust@denx.de> wrote:

> From: Pali Rohár <pali.rohar@gmail.com>
> 
> Selecting menu items is currently done in menu_interactive_choice()
> by reading the user input strings from standard input.
> 
> Extend menu_interactive_choice() to support user defined function
> for selecting menu items. This function and its argument can be
> specified when creating the menu.
> 
> Signed-off-by: Pali Rohár <pali.rohar@gmail.com>
> Signed-off-by: Anatolij Gustschin <agust@denx.de>
> ---
> Changes in v4:
>  - slightly rename the new item choice callback and its argument
>  - add documentation for added item choice callback
>  - search for menu item key only if the choice callback
>    returned a key (not NULL)
>  - do not change menu_display_statusline() function argument
>    (previous patch changed this menu API function but didn't
>     update documentation for this change. This change is
>     actually not needed, menu item data can be obtained by
>     exported menu_default_choice())
>  - revise commit log
> 
> No changes in v3
> 
> Changes in v2:
>   - Rebased on next
> 
>  board/ait/cam_enc_4xx/cam_enc_4xx.c |    3 +-
>  common/cmd_pxe.c                    |    3 +-
>  common/menu.c                       |   42 +++++++++++++++++++++++++---------
>  doc/README.menu                     |    4 ++-
>  include/menu.h                      |    4 ++-
>  5 files changed, 41 insertions(+), 15 deletions(-)

applied to staging/agust@denx.de. Thanks.

Anatolij

Patch

diff --git a/board/ait/cam_enc_4xx/cam_enc_4xx.c b/board/ait/cam_enc_4xx/cam_enc_4xx.c
index 32b28f9..644c445 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);
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..322b75e 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_choice)(void *);
+	void *item_choice_data;
 	struct list_head items;
 };
 
@@ -204,18 +206,26 @@  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 (!m->item_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);
-				m->timeout = 0;
+			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
-			return menu_default_choice(m, choice);
+		} else {
+			char *key = m->item_choice(m->item_choice_data);
+
+			if (key)
+				choice_item = menu_item_by_key(m, key);
+		}
+
+		if (!choice_item)
+			m->timeout = 0;
 	}
 
 	*choice = choice_item->data;
@@ -348,11 +358,19 @@  int menu_item_add(struct menu *m, char *item_key, void *item_data)
  * what must be entered to select an item, the item_data_print function should
  * make it obvious what the key for each entry is.
  *
+ * item_choice - If not NULL, will be called when asking the user to choose an
+ * item. Returns a key string corresponding to the choosen item or NULL if
+ * no item has been selected.
+ *
+ * item_choice_data - Will be passed as the argument to the item_choice function
+ *
  * Returns a pointer to the menu if successful, or NULL if there is
  * 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_choice)(void *),
+				void *item_choice_data)
 {
 	struct menu *m;
 
@@ -365,6 +383,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_choice = item_choice;
+	m->item_choice_data = item_choice_data;
 
 	if (title) {
 		m->title = strdup(title);
diff --git a/doc/README.menu b/doc/README.menu
index 6ce6bba..c949398 100644
--- a/doc/README.menu
+++ b/doc/README.menu
@@ -51,7 +51,9 @@  struct menu;
  * menu_create() - Creates a menu handle with default settings
  */
 struct menu *menu_create(char *title, int timeout, int prompt,
-				void (*item_data_print)(void *));
+				void (*item_data_print)(void *),
+				char *(*item_choice)(void *),
+				void *item_choice_data);
 
 /*
  * menu_item_add() - Adds or replaces a menu item
diff --git a/include/menu.h b/include/menu.h
index 7af5fdb..f4dd5af 100644
--- a/include/menu.h
+++ b/include/menu.h
@@ -21,7 +21,9 @@ 
 struct menu;
 
 struct menu *menu_create(char *title, int timeout, int prompt,
-				void (*item_data_print)(void *));
+				void (*item_data_print)(void *),
+				char *(*item_choice)(void *),
+				void *item_choice_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);