bootmenu: factor out the user input handling
authorMasahisa Kojima <masahisa.kojima@linaro.org>
Thu, 28 Apr 2022 08:09:45 +0000 (17:09 +0900)
committerHeinrich Schuchardt <heinrich.schuchardt@canonical.com>
Sat, 7 May 2022 21:17:26 +0000 (23:17 +0200)
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@linaro.org>
Reviewed-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
cmd/bootmenu.c
common/menu.c
include/menu.h

index ac85767..8859eeb 100644 (file)
@@ -51,21 +51,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];
@@ -97,132 +82,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;
-
-       while (menu->delay > 0) {
-               printf(ANSI_CURSOR_POSITION, menu->count + 5, 3);
-               printf("Hit any key to stop autoboot: %d ", menu->delay);
-               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(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;
index f5fc693..3e876b5 100644 (file)
@@ -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"
 
@@ -421,3 +424,128 @@ 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;
+
+       while (menu->delay > 0) {
+               printf(ANSI_CURSOR_POSITION, menu->count + 5, 3);
+               printf("Hit any key to stop autoboot: %d ", menu->delay);
+               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(ANSI_CURSOR_POSITION ANSI_CLEAR_LINE, menu->count + 5, 1);
+
+       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;
+}
index ad58594..e74616c 100644 (file)
@@ -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__ */