[PATCH v4 08/11] bootmenu: factor out the user input handling
Masahisa Kojima
masahisa.kojima at linaro.org
Thu Mar 24 14:54:40 CET 2022
This commit moves the user input handling from cmd/bootmenu.c
to common/menu.c to reuse it from other modules.
Signed-off-by: Masahisa Kojima <masahisa.kojima at linaro.org>
---
Newly created in v4.
cmd/bootmenu.c | 149 -------------------------------------------------
common/menu.c | 137 +++++++++++++++++++++++++++++++++++++++++++++
include/menu.h | 20 +++++++
3 files changed, 157 insertions(+), 149 deletions(-)
diff --git a/cmd/bootmenu.c b/cmd/bootmenu.c
index 947b3a49ff..d3591aa4a9 100644
--- a/cmd/bootmenu.c
+++ b/cmd/bootmenu.c
@@ -52,21 +52,6 @@ struct bootmenu_entry {
struct bootmenu_entry *next; /* next menu entry (num+1) */
};
-struct bootmenu_data {
- int delay; /* delay for autoboot */
- int active; /* active menu entry */
- int count; /* total count of menu entries */
- struct bootmenu_entry *first; /* first menu entry */
-};
-
-enum bootmenu_key {
- KEY_NONE = 0,
- KEY_UP,
- KEY_DOWN,
- KEY_SELECT,
- KEY_QUIT,
-};
-
static char *bootmenu_getoption(unsigned short int n)
{
char name[MAX_ENV_SIZE];
@@ -107,140 +92,6 @@ static void bootmenu_print_entry(void *data)
puts(ANSI_COLOR_RESET);
}
-static void bootmenu_autoboot_loop(struct bootmenu_data *menu,
- enum bootmenu_key *key, int *esc)
-{
- int i, c;
-
- if (menu->delay > 0) {
- /* flush input */
- while (tstc())
- getchar();
-
- printf(ANSI_CURSOR_POSITION, menu->count + 5, 1);
- printf(" Hit any key to stop autoboot: %2d ", menu->delay);
- }
-
- while (menu->delay > 0) {
- for (i = 0; i < 100; ++i) {
- if (!tstc()) {
- WATCHDOG_RESET();
- mdelay(10);
- continue;
- }
-
- menu->delay = -1;
- c = getchar();
-
- switch (c) {
- case '\e':
- *esc = 1;
- *key = KEY_NONE;
- break;
- case '\r':
- *key = KEY_SELECT;
- break;
- case 0x3: /* ^C */
- *key = KEY_QUIT;
- break;
- default:
- *key = KEY_NONE;
- break;
- }
-
- break;
- }
-
- if (menu->delay < 0)
- break;
-
- --menu->delay;
- printf("\b\b\b%2d ", menu->delay);
- }
-
- printf(ANSI_CURSOR_POSITION, menu->count + 5, 1);
- puts(ANSI_CLEAR_LINE);
-
- if (menu->delay == 0)
- *key = KEY_SELECT;
-}
-
-static void bootmenu_loop(struct bootmenu_data *menu,
- enum bootmenu_key *key, int *esc)
-{
- int c;
-
- if (*esc == 1) {
- if (tstc()) {
- c = getchar();
- } else {
- WATCHDOG_RESET();
- mdelay(10);
- if (tstc())
- c = getchar();
- else
- c = '\e';
- }
- } else {
- while (!tstc()) {
- WATCHDOG_RESET();
- mdelay(10);
- }
- c = getchar();
- }
-
- switch (*esc) {
- case 0:
- /* First char of ANSI escape sequence '\e' */
- if (c == '\e') {
- *esc = 1;
- *key = KEY_NONE;
- }
- break;
- case 1:
- /* Second char of ANSI '[' */
- if (c == '[') {
- *esc = 2;
- *key = KEY_NONE;
- } else {
- /* Alone ESC key was pressed */
- *key = KEY_QUIT;
- *esc = (c == '\e') ? 1 : 0;
- }
- break;
- case 2:
- case 3:
- /* Third char of ANSI (number '1') - optional */
- if (*esc == 2 && c == '1') {
- *esc = 3;
- *key = KEY_NONE;
- break;
- }
-
- *esc = 0;
-
- /* ANSI 'A' - key up was pressed */
- if (c == 'A')
- *key = KEY_UP;
- /* ANSI 'B' - key down was pressed */
- else if (c == 'B')
- *key = KEY_DOWN;
- /* other key was pressed */
- else
- *key = KEY_NONE;
-
- break;
- }
-
- /* enter key was pressed */
- if (c == '\r')
- *key = KEY_SELECT;
-
- /* ^C was pressed */
- if (c == 0x3)
- *key = KEY_QUIT;
-}
-
static char *bootmenu_choice_entry(void *data)
{
struct bootmenu_data *menu = data;
diff --git a/common/menu.c b/common/menu.c
index b577d80b4f..6dcac035b7 100644
--- a/common/menu.c
+++ b/common/menu.c
@@ -4,11 +4,14 @@
* Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
*/
+#include <ansi.h>
#include <common.h>
#include <cli.h>
#include <malloc.h>
#include <errno.h>
+#include <linux/delay.h>
#include <linux/list.h>
+#include <watchdog.h>
#include "menu.h"
@@ -418,3 +421,137 @@ int menu_destroy(struct menu *m)
return 1;
}
+
+void bootmenu_autoboot_loop(struct bootmenu_data *menu,
+ enum bootmenu_key *key, int *esc)
+{
+ int i, c;
+
+ if (menu->delay > 0) {
+ /* flush input */
+ while (tstc())
+ getchar();
+
+ printf(ANSI_CURSOR_POSITION, menu->count + 5, 1);
+ printf(" Hit any key to stop autoboot: %2d ", menu->delay);
+ }
+
+ while (menu->delay > 0) {
+ for (i = 0; i < 100; ++i) {
+ if (!tstc()) {
+ WATCHDOG_RESET();
+ mdelay(10);
+ continue;
+ }
+
+ menu->delay = -1;
+ c = getchar();
+
+ switch (c) {
+ case '\e':
+ *esc = 1;
+ *key = KEY_NONE;
+ break;
+ case '\r':
+ *key = KEY_SELECT;
+ break;
+ case 0x3: /* ^C */
+ *key = KEY_QUIT;
+ break;
+ default:
+ *key = KEY_NONE;
+ break;
+ }
+
+ break;
+ }
+
+ if (menu->delay < 0)
+ break;
+
+ --menu->delay;
+ printf("\b\b\b%2d ", menu->delay);
+ }
+
+ printf(ANSI_CURSOR_POSITION, menu->count + 5, 1);
+ puts(ANSI_CLEAR_LINE);
+
+ if (menu->delay == 0)
+ *key = KEY_SELECT;
+}
+
+void bootmenu_loop(struct bootmenu_data *menu,
+ enum bootmenu_key *key, int *esc)
+{
+ int c;
+
+ if (*esc == 1) {
+ if (tstc()) {
+ c = getchar();
+ } else {
+ WATCHDOG_RESET();
+ mdelay(10);
+ if (tstc())
+ c = getchar();
+ else
+ c = '\e';
+ }
+ } else {
+ while (!tstc()) {
+ WATCHDOG_RESET();
+ mdelay(10);
+ }
+ c = getchar();
+ }
+
+ switch (*esc) {
+ case 0:
+ /* First char of ANSI escape sequence '\e' */
+ if (c == '\e') {
+ *esc = 1;
+ *key = KEY_NONE;
+ }
+ break;
+ case 1:
+ /* Second char of ANSI '[' */
+ if (c == '[') {
+ *esc = 2;
+ *key = KEY_NONE;
+ } else {
+ /* Alone ESC key was pressed */
+ *key = KEY_QUIT;
+ *esc = (c == '\e') ? 1 : 0;
+ }
+ break;
+ case 2:
+ case 3:
+ /* Third char of ANSI (number '1') - optional */
+ if (*esc == 2 && c == '1') {
+ *esc = 3;
+ *key = KEY_NONE;
+ break;
+ }
+
+ *esc = 0;
+
+ /* ANSI 'A' - key up was pressed */
+ if (c == 'A')
+ *key = KEY_UP;
+ /* ANSI 'B' - key down was pressed */
+ else if (c == 'B')
+ *key = KEY_DOWN;
+ /* other key was pressed */
+ else
+ *key = KEY_NONE;
+
+ break;
+ }
+
+ /* enter key was pressed */
+ if (c == '\r')
+ *key = KEY_SELECT;
+
+ /* ^C was pressed */
+ if (c == 0x3)
+ *key = KEY_QUIT;
+}
diff --git a/include/menu.h b/include/menu.h
index ad5859437e..e74616cae8 100644
--- a/include/menu.h
+++ b/include/menu.h
@@ -35,4 +35,24 @@ int menu_default_choice(struct menu *m, void **choice);
*/
int menu_show(int bootdelay);
+struct bootmenu_data {
+ int delay; /* delay for autoboot */
+ int active; /* active menu entry */
+ int count; /* total count of menu entries */
+ struct bootmenu_entry *first; /* first menu entry */
+};
+
+enum bootmenu_key {
+ KEY_NONE = 0,
+ KEY_UP,
+ KEY_DOWN,
+ KEY_SELECT,
+ KEY_QUIT,
+};
+
+void bootmenu_autoboot_loop(struct bootmenu_data *menu,
+ enum bootmenu_key *key, int *esc);
+void bootmenu_loop(struct bootmenu_data *menu,
+ enum bootmenu_key *key, int *esc);
+
#endif /* __MENU_H__ */
--
2.17.1
More information about the U-Boot
mailing list