:: [maemo-leste] [PATCH v2] bootmenu: …
Top Page
Delete this message
Reply to this message
Author: Pali Rohár
Date:  
To: Simon Glass, Thirupathaiah Annapureddy, Heinrich Schuchardt, Pavel Machek
CC: u-boot, maemo-leste
Old-Topics: [maemo-leste] [PATCH] bootmenu: Allow to quit it via CTRL+C
Subject: [maemo-leste] [PATCH v2] bootmenu: Allow to quit it via ESC/CTRL+C
When ESC/CTRL+C is pressed interrupt bootmenu and jump into U-Boot console.
As the last entry in bootmenu is always U-Boot console just choose the last
entry when ESC or CTRL+C is pressed.

ESC key is detected when either no other character appears after '\e'
within 10ms or when non-'[' appears after '\e'.

It is useful when bootmenu is part of boot process and you want to
interrupt boot process by scripts which control U-Boot (serial) console.

Signed-off-by: Pali Rohár <pali@???>

---
Changes in v2:
* Added support also for ESC key
---
cmd/bootmenu.c | 42 +++++++++++++++++++++++++++++++++++-------
1 file changed, 35 insertions(+), 7 deletions(-)

diff --git a/cmd/bootmenu.c b/cmd/bootmenu.c
index 1ba7b622e5..409ef9a848 100644
--- a/cmd/bootmenu.c
+++ b/cmd/bootmenu.c
@@ -45,6 +45,7 @@ enum bootmenu_key {
     KEY_UP,
     KEY_DOWN,
     KEY_SELECT,
+    KEY_QUIT,
 };


 static char *bootmenu_getoption(unsigned short int n)
@@ -109,6 +110,9 @@ static void bootmenu_autoboot_loop(struct bootmenu_data *menu,
             case '\r':
                 *key = KEY_SELECT;
                 break;
+            case 0x3: /* ^C */
+                *key = KEY_QUIT;
+                break;
             default:
                 *key = KEY_NONE;
                 break;
@@ -136,13 +140,25 @@ static void bootmenu_loop(struct bootmenu_data *menu,
 {
     int c;


-    while (!tstc()) {
-        WATCHDOG_RESET();
-        mdelay(10);
+    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();
     }


-    c = getchar();
-
     switch (*esc) {
     case 0:
         /* First char of ANSI escape sequence '\e' */
@@ -157,7 +173,9 @@ static void bootmenu_loop(struct bootmenu_data *menu,
             *esc = 2;
             *key = KEY_NONE;
         } else {
-            *esc = 0;
+        /* Alone ESC key was pressed */
+            *key = KEY_QUIT;
+            *esc = (c == '\e') ? 1 : 0;
         }
         break;
     case 2:
@@ -187,6 +205,10 @@ static void bootmenu_loop(struct bootmenu_data *menu,
     /* 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)
@@ -222,6 +244,12 @@ static char *bootmenu_choice_entry(void *data)
             for (i = 0; i < menu->active; ++i)
                 iter = iter->next;
             return iter->key;
+        case KEY_QUIT:
+            /* Quit by choosing the last entry - U-Boot console */
+            iter = menu->first;
+            while (iter->next)
+                iter = iter->next;
+            return iter->key;
         default:
             break;
         }
@@ -389,7 +417,7 @@ static void menu_display_statusline(struct menu *m)
     printf(ANSI_CURSOR_POSITION, menu->count + 5, 1);
     puts(ANSI_CLEAR_LINE);
     printf(ANSI_CURSOR_POSITION, menu->count + 6, 1);
-    puts("  Press UP/DOWN to move, ENTER to select");
+    puts("  Press UP/DOWN to move, ENTER to select, ESC/CTRL+C to quit");
     puts(ANSI_CLEAR_LINE_TO_END);
     printf(ANSI_CURSOR_POSITION, menu->count + 7, 1);
     puts(ANSI_CLEAR_LINE);
-- 
2.20.1