diff mbox

[U-Boot,1/2] menu: Added support to use user defined functions

Message ID 1338136729-3907-2-git-send-email-pali.rohar@gmail.com
State Changes Requested
Delegated to: Marek Vasut
Headers show

Commit Message

Pali Rohár May 27, 2012, 4:38 p.m. UTC
* 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>
---
 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(-)

Comments

Marek Vasut June 3, 2012, 9:59 a.m. UTC | #1
Dear Pali Rohár,

Please CC proper custodians in order to get reviews next time.

[...]

> --- 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 *),

Where is this item_data_choice() used?

> +				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);

Best regards,
Marek Vasut
Pali Rohár June 3, 2012, 10:05 a.m. UTC | #2
On Sunday 03 June 2012 11:59:16 Marek Vasut wrote:
> > --- 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 *),
> 
> Where is this item_data_choice() used?

This is alternative function for menu entry choice. It is used in 
function menu_interactive_choice. If item_data_choice is NULL 
default code with readline_into_buffer is used.

ANSI bootmenu command (in next patch) is using its own function.
Marek Vasut June 3, 2012, 10:27 a.m. UTC | #3
Dear Pali Rohár,

> On Sunday 03 June 2012 11:59:16 Marek Vasut wrote:
> > > --- 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 *),
> > 
> > Where is this item_data_choice() used?
> 
> This is alternative function for menu entry choice. It is used in
> function menu_interactive_choice. If item_data_choice is NULL
> default code with readline_into_buffer is used.
> 
> ANSI bootmenu command (in next patch) is using its own function.

Hm so why not make this ANSI stuff one plugin and the other bootmenu stuff 
another plugin (which will be default). Then you won't have to check if anything 
is null.

Best regards,
Marek Vasut
diff mbox

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..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 b3c1f67..346e275 100644
--- a/common/cmd_pxe.c
+++ b/common/cmd_pxe.c
@@ -1198,7 +1198,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 aa16c9a..470eb9f 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);
 }
@@ -230,20 +232,27 @@  static inline int menu_interactive_choice(struct menu *m, void **choice)
 
 		menu_display(m);
 
-		readret = readline_into_buffer("Enter choice: ", cbuf,
-				m->timeout);
-
-		if (readret >= 0) {
-			choice_item = menu_item_by_key(m, cbuf);
-
-			if (!choice_item) {
-				printf("%s not found\n", cbuf);
-				m->timeout = 0;
+		if (!m->item_data_choice) {
+			readret = readline_into_buffer("Enter choice: ", cbuf,
+					m->timeout);
+
+			if (readret >= 0) {
+				choice_item = menu_item_by_key(m, cbuf);
+				if (!choice_item)
+					printf("%s not found\n", cbuf);
+			} else {
+				puts("^C\n");
+				return -EINTR;
 			}
 		} else {
-			puts("^C\n");
-			return -EINTR;
+			char *key = m->item_data_choice(m->data);
+			if (!key)
+				return -EINTR;
+			choice_item = menu_item_by_key(m, key);
 		}
+
+		if (!choice_item)
+			m->timeout = 0;
 	}
 
 	*choice = choice_item->data;
@@ -380,7 +389,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;
 
@@ -393,6 +404,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);