1 From 5a15437610e8e8c68dc347845a83d0cbad80ca08 Mon Sep 17 00:00:00 2001
2 From: Weijie Gao <weijie.gao@mediatek.com>
3 Date: Tue, 19 Jan 2021 10:58:48 +0800
4 Subject: [PATCH 51/71] cmd: bootmenu: add ability to select item by shortkey
6 Add ability to use shortkey to select item for bootmenu command
8 Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
10 cmd/bootmenu.c | 34 ++++++++++++++++++++++++-----
11 common/menu.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++--
12 include/menu.h | 12 +++++++----
13 3 files changed, 93 insertions(+), 11 deletions(-)
17 @@ -87,16 +87,17 @@ static char *bootmenu_choice_entry(void
18 struct bootmenu_data *menu = data;
19 struct bootmenu_entry *iter;
20 enum bootmenu_key key = KEY_NONE;
26 if (menu->delay >= 0) {
27 /* Autoboot was not stopped */
28 - bootmenu_autoboot_loop(menu, &key, &esc);
29 + bootmenu_autoboot_loop(menu, &key, &esc, &choice);
31 /* Some key was pressed, so autoboot was stopped */
32 - bootmenu_loop(menu, &key, &esc);
33 + bootmenu_loop(menu, &key, &esc, &choice);
37 @@ -110,6 +111,12 @@ static char *bootmenu_choice_entry(void
39 /* no menu key selected, regenerate menu */
42 + menu->active = choice;
43 + if (!menu->last_choiced) {
44 + menu->last_choiced = true;
49 for (i = 0; i < menu->active; ++i)
50 @@ -167,6 +174,9 @@ static int prepare_bootmenu_entry(struct
51 unsigned short int i = *index;
52 struct bootmenu_entry *entry = NULL;
53 struct bootmenu_entry *iter = *current;
54 + char *choice_option;
58 while ((option = bootmenu_getoption(i))) {
60 @@ -181,11 +191,24 @@ static int prepare_bootmenu_entry(struct
64 - entry->title = strndup(option, sep - option);
65 + /* Add KEY_CHOICE support: '%d. %s\0' : len --> len + 4 */
66 + len = sep - option + 4;
67 + choice_option = malloc(len);
68 + if (!choice_option) {
73 + if (!get_choice_char(i, &choice_char))
74 + len = snprintf(choice_option, len, "%c. %s", choice_char, option);
76 + len = snprintf(choice_option, len, " %s", option);
77 + entry->title = strndup(choice_option, len);
82 + free(choice_option);
84 entry->command = strdup(sep + 1);
85 if (!entry->command) {
86 @@ -331,6 +354,7 @@ static struct bootmenu_data *bootmenu_cr
90 + menu->last_choiced = false;
92 default_str = env_get("bootmenu_default");
94 @@ -356,9 +380,9 @@ static struct bootmenu_data *bootmenu_cr
96 /* Add Quit entry if entering U-Boot console is disabled */
97 if (!IS_ENABLED(CONFIG_BOOTMENU_DISABLE_UBOOT_CONSOLE))
98 - entry->title = strdup("U-Boot console");
99 + entry->title = strdup("0. U-Boot console");
101 - entry->title = strdup("Quit");
102 + entry->title = strdup("0. Quit");
108 @@ -47,6 +47,33 @@ struct menu {
112 +const char choice_chars[] = {
113 + '1', '2', '3', '4', '5', '6', '7', '8', '9',
114 + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
115 + 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
116 + 'u', 'v', 'w', 'x', 'y', 'z'
119 +static int find_choice(char choice)
123 + for (i = 0; i < ARRAY_SIZE(choice_chars); i++)
124 + if (tolower(choice) == choice_chars[i])
130 +int get_choice_char(int index, char *result)
132 + if (index < ARRAY_SIZE(choice_chars))
133 + *result = choice_chars[index];
140 * An iterator function for menu items. callback will be called for each item
141 * in m, with m, a pointer to the item, and extra being passed to callback. If
142 @@ -426,7 +453,7 @@ int menu_destroy(struct menu *m)
145 void bootmenu_autoboot_loop(struct bootmenu_data *menu,
146 - enum bootmenu_key *key, int *esc)
147 + enum bootmenu_key *key, int *esc, int *choice)
151 @@ -456,6 +483,19 @@ void bootmenu_autoboot_loop(struct bootm
158 + *choice = find_choice(c);
159 + if ((*choice >= 0 &&
160 + *choice < menu->count - 1)) {
162 + } else if (c == '0') {
163 + *choice = menu->count - 1;
171 @@ -475,10 +515,16 @@ void bootmenu_autoboot_loop(struct bootm
174 void bootmenu_loop(struct bootmenu_data *menu,
175 - enum bootmenu_key *key, int *esc)
176 + enum bootmenu_key *key, int *esc, int *choice)
180 + if (menu->last_choiced) {
181 + menu->last_choiced = false;
189 @@ -504,6 +550,14 @@ void bootmenu_loop(struct bootmenu_data
194 + *choice = find_choice(c);
195 + if ((*choice >= 0 && *choice < menu->count - 1)) {
197 + } else if (c == '0') {
198 + *choice = menu->count - 1;
208 * Copyright 2010-2011 Calxeda, Inc.
214 +#include <linux/ctype.h>
218 struct menu *menu_create(char *title, int timeout, int prompt,
219 @@ -18,6 +19,8 @@ int menu_get_choice(struct menu *m, void
220 int menu_item_add(struct menu *m, char *item_key, void *item_data);
221 int menu_destroy(struct menu *m);
222 int menu_default_choice(struct menu *m, void **choice);
223 +/* Add KEY_CHOICE support */
224 +int get_choice_char(int index, char *result);
227 * menu_show() Show a boot menu
228 @@ -40,6 +43,7 @@ struct bootmenu_data {
229 int active; /* active menu entry */
230 int count; /* total count of menu entries */
231 struct bootmenu_entry *first; /* first menu entry */
236 @@ -48,11 +52,11 @@ enum bootmenu_key {
243 void bootmenu_autoboot_loop(struct bootmenu_data *menu,
244 - enum bootmenu_key *key, int *esc);
245 + enum bootmenu_key *key, int *esc, int *choice);
246 void bootmenu_loop(struct bootmenu_data *menu,
247 - enum bootmenu_key *key, int *esc);
249 + enum bootmenu_key *key, int *esc, int *choice);
250 #endif /* __MENU_H__ */