uboot-mediatek: update to 2021.04-rc3 with MediaTek's patches
[openwrt/openwrt.git] / package / boot / uboot-mediatek / patches / 210-cmd-bootmenu-add-ability-to-select-item-by-shortkey.patch
1 From 26d4e2e58bf0007db74b47c783785c3305ea1fa0 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 17/23] cmd: bootmenu: add ability to select item by shortkey
5
6 Add ability to use shortkey to select item for bootmenu command
7
8 Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
9 ---
10 cmd/bootmenu.c | 77 +++++++++++++++++++++++++++++++++++++++++++++-----
11 1 file changed, 70 insertions(+), 7 deletions(-)
12
13 --- a/cmd/bootmenu.c
14 +++ b/cmd/bootmenu.c
15 @@ -11,6 +11,7 @@
16 #include <menu.h>
17 #include <watchdog.h>
18 #include <malloc.h>
19 +#include <linux/ctype.h>
20 #include <linux/delay.h>
21 #include <linux/string.h>
22
23 @@ -38,6 +39,7 @@ struct bootmenu_data {
24 int active; /* active menu entry */
25 int count; /* total count of menu entries */
26 struct bootmenu_entry *first; /* first menu entry */
27 + bool last_choiced;
28 };
29
30 enum bootmenu_key {
31 @@ -46,8 +48,27 @@ enum bootmenu_key {
32 KEY_DOWN,
33 KEY_SELECT,
34 KEY_QUIT,
35 + KEY_CHOICE,
36 };
37
38 +static const char choice_chars[] = {
39 + '1', '2', '3', '4', '5', '6', '7', '8', '9',
40 + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
41 + 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
42 + 'u', 'v', 'w', 'x', 'y', 'z'
43 +};
44 +
45 +static int find_choice(char choice)
46 +{
47 + int i;
48 +
49 + for (i = 0; i < ARRAY_SIZE(choice_chars); i++)
50 + if (tolower(choice) == choice_chars[i])
51 + return i;
52 +
53 + return -1;
54 +}
55 +
56 static char *bootmenu_getoption(unsigned short int n)
57 {
58 char name[MAX_ENV_SIZE];
59 @@ -82,7 +103,7 @@ static void bootmenu_print_entry(void *d
60 }
61
62 static void bootmenu_autoboot_loop(struct bootmenu_data *menu,
63 - enum bootmenu_key *key, int *esc)
64 + enum bootmenu_key *key, int *esc, int *choice)
65 {
66 int i, c;
67
68 @@ -115,6 +136,19 @@ static void bootmenu_autoboot_loop(struc
69 break;
70 default:
71 *key = KEY_NONE;
72 + if (*esc)
73 + break;
74 +
75 + *choice = find_choice(c);
76 + if ((*choice >= 0 &&
77 + *choice < menu->count - 1)) {
78 + *key = KEY_CHOICE;
79 + } else if (c == '0') {
80 + *choice = menu->count - 1;
81 + *key = KEY_CHOICE;
82 + } else {
83 + *key = KEY_NONE;
84 + }
85 break;
86 }
87
88 @@ -136,10 +170,16 @@ static void bootmenu_autoboot_loop(struc
89 }
90
91 static void bootmenu_loop(struct bootmenu_data *menu,
92 - enum bootmenu_key *key, int *esc)
93 + enum bootmenu_key *key, int *esc, int *choice)
94 {
95 int c;
96
97 + if (menu->last_choiced) {
98 + menu->last_choiced = false;
99 + *key = KEY_SELECT;
100 + return;
101 + }
102 +
103 if (*esc == 1) {
104 if (tstc()) {
105 c = getchar();
106 @@ -165,6 +205,14 @@ static void bootmenu_loop(struct bootmen
107 if (c == '\e') {
108 *esc = 1;
109 *key = KEY_NONE;
110 + } else {
111 + *choice = find_choice(c);
112 + if ((*choice >= 0 && *choice < menu->count - 1)) {
113 + *key = KEY_CHOICE;
114 + } else if (c == '0') {
115 + *choice = menu->count - 1;
116 + *key = KEY_CHOICE;
117 + }
118 }
119 break;
120 case 1:
121 @@ -216,16 +264,17 @@ static char *bootmenu_choice_entry(void
122 struct bootmenu_data *menu = data;
123 struct bootmenu_entry *iter;
124 enum bootmenu_key key = KEY_NONE;
125 + int choice = -1;
126 int esc = 0;
127 int i;
128
129 while (1) {
130 if (menu->delay >= 0) {
131 /* Autoboot was not stopped */
132 - bootmenu_autoboot_loop(menu, &key, &esc);
133 + bootmenu_autoboot_loop(menu, &key, &esc, &choice);
134 } else {
135 /* Some key was pressed, so autoboot was stopped */
136 - bootmenu_loop(menu, &key, &esc);
137 + bootmenu_loop(menu, &key, &esc, &choice);
138 }
139
140 switch (key) {
141 @@ -239,6 +288,12 @@ static char *bootmenu_choice_entry(void
142 ++menu->active;
143 /* no menu key selected, regenerate menu */
144 return NULL;
145 + case KEY_CHOICE:
146 + menu->active = choice;
147 + if (!menu->last_choiced) {
148 + menu->last_choiced = true;
149 + return NULL;
150 + }
151 case KEY_SELECT:
152 iter = menu->first;
153 for (i = 0; i < menu->active; ++i)
154 @@ -294,6 +349,7 @@ static struct bootmenu_data *bootmenu_cr
155 menu->delay = delay;
156 menu->active = 0;
157 menu->first = NULL;
158 + menu->last_choiced = false;
159
160 default_str = env_get("bootmenu_default");
161 if (default_str)
162 @@ -311,12 +367,19 @@ static struct bootmenu_data *bootmenu_cr
163 goto cleanup;
164
165 len = sep-option;
166 - entry->title = malloc(len + 1);
167 + entry->title = malloc(len + 4);
168 if (!entry->title) {
169 free(entry);
170 goto cleanup;
171 }
172 - memcpy(entry->title, option, len);
173 +
174 + if (i < ARRAY_SIZE(choice_chars)) {
175 + len = sprintf(entry->title, "%c. %.*s", choice_chars[i],
176 + len, option);
177 + } else {
178 + len = sprintf(entry->title, " %.*s", len, option);
179 + }
180 +
181 entry->title[len] = 0;
182
183 len = strlen(sep + 1);
184 @@ -353,7 +416,7 @@ static struct bootmenu_data *bootmenu_cr
185 if (!entry)
186 goto cleanup;
187
188 - entry->title = strdup("U-Boot console");
189 + entry->title = strdup("0. U-Boot console");
190 if (!entry->title) {
191 free(entry);
192 goto cleanup;