[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