[SeaBIOS] [PATCH v2] bootmenu: add support for more than 9 entries

Gerd Hoffmann posted 1 patch 5 years ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/seabios tags/patchew/20190411200120.4594-1-kraxel@redhat.com
src/util.h |  1 +
src/boot.c | 49 ++++++++++++++++++++++++++++++++++---------------
src/kbd.c  | 19 +++++++++++++++++--
3 files changed, 52 insertions(+), 17 deletions(-)
[SeaBIOS] [PATCH v2] bootmenu: add support for more than 9 entries
Posted by Gerd Hoffmann 5 years ago
10th and following entries can be selected using letters.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 src/util.h |  1 +
 src/boot.c | 49 ++++++++++++++++++++++++++++++++++---------------
 src/kbd.c  | 19 +++++++++++++++++--
 3 files changed, 52 insertions(+), 17 deletions(-)

diff --git a/src/util.h b/src/util.h
index 9c06850353a4..c8e3b818d23e 100644
--- a/src/util.h
+++ b/src/util.h
@@ -189,6 +189,7 @@ void handle_15c2(struct bregs *regs);
 void process_key(u8 key);
 u8 enqueue_key(u16 keycode);
 u16 ascii_to_keycode(u8 ascii);
+u16 ascii_to_scancode(u8 ascii);
 
 // misc.c
 extern int HaveRunPost;
diff --git a/src/boot.c b/src/boot.c
index 9f82f3ca0c3e..43160f8ee5b9 100644
--- a/src/boot.c
+++ b/src/boot.c
@@ -465,6 +465,14 @@ get_keystroke(int msec)
 
 #define DEFAULT_BOOTMENU_WAIT 2500
 
+static const char menuchars[] = {
+    '1', '2', '3', '4', '5', '6', '7', '8', '9',
+    'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i',
+    'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r',
+    's', /* skip t (tpm menu) */
+    'u', 'v', 'w', 'x', 'y', 'z'
+};
+
 // Show IPL option menu.
 void
 interactive_bootmenu(void)
@@ -497,12 +505,15 @@ interactive_bootmenu(void)
 
     // Show menu items
     int maxmenu = 0;
-    struct bootentry_s *pos;
+    struct bootentry_s *pos, *boot = NULL;
     hlist_for_each_entry(pos, &BootList, node) {
         char desc[77];
-        maxmenu++;
-        printf("%d. %s\n", maxmenu
+        if (maxmenu >= ARRAY_SIZE(menuchars)) {
+            break;
+        }
+        printf("%c. %s\n", menuchars[maxmenu]
                , strtcpy(desc, pos->description, ARRAY_SIZE(desc)));
+        maxmenu++;
     }
     if (tpm_can_show_menu()) {
         printf("\nt. TPM Configuration\n");
@@ -521,23 +532,31 @@ interactive_bootmenu(void)
             printf("\n");
             tpm_menu();
         }
-        if (scan_code >= 1 && scan_code <= maxmenu+1)
+        if (scan_code == 1) {
+            // ESC
+            printf("\n");
+            return;
+        }
+
+        maxmenu = 0;
+        hlist_for_each_entry(pos, &BootList, node) {
+            if (maxmenu >= ARRAY_SIZE(menuchars))
+                break;
+            if (scan_code == ascii_to_scancode(menuchars[maxmenu])) {
+                boot = pos;
+                break;
+            }
+            maxmenu++;
+        }
+        if (boot)
             break;
     }
     printf("\n");
-    if (scan_code == 0x01)
-        // ESC
-        return;
 
     // Find entry and make top priority.
-    int choice = scan_code - 1;
-    hlist_for_each_entry(pos, &BootList, node) {
-        if (! --choice)
-            break;
-    }
-    hlist_del(&pos->node);
-    pos->priority = 0;
-    hlist_add_head(&pos->node, &BootList);
+    hlist_del(&boot->node);
+    boot->priority = 0;
+    hlist_add_head(&boot->node, &BootList);
 }
 
 // BEV (Boot Execution Vector) list
diff --git a/src/kbd.c b/src/kbd.c
index 15e5ae789cd3..f54d9fe94287 100644
--- a/src/kbd.c
+++ b/src/kbd.c
@@ -271,12 +271,12 @@ handle_16(struct bregs *regs)
 
 #define none 0
 
-static struct scaninfo {
+struct scaninfo {
     u16 normal;
     u16 shift;
     u16 control;
     u16 alt;
-} scan_to_keycode[] VAR16 = {
+} scan_to_keycode[] VARFSEG = {
     {   none,   none,   none,   none },
     { 0x011b, 0x011b, 0x011b, 0x01f0 }, /* escape */
     { 0x0231, 0x0221,   none, 0x7800 }, /* 1! */
@@ -390,6 +390,21 @@ u16 ascii_to_keycode(u8 ascii)
     return 0;
 }
 
+u16 ascii_to_scancode(u8 ascii)
+{
+    int i;
+
+    for (i = 0; i < ARRAY_SIZE(scan_to_keycode); i++) {
+        if ((GET_GLOBAL(scan_to_keycode[i].normal) & 0xff) == ascii)
+            return i;
+        if ((GET_GLOBAL(scan_to_keycode[i].shift) & 0xff) == ascii)
+            return i;
+        if ((GET_GLOBAL(scan_to_keycode[i].control) & 0xff) == ascii)
+            return i;
+    }
+    return 0;
+}
+
 // Handle a ps2 style scancode read from the keyboard.
 static void
 kbd_set_flag(int key_release, u16 set_bit0, u8 set_bit1, u16 toggle_bit)
-- 
2.18.1
_______________________________________________
SeaBIOS mailing list -- seabios@seabios.org
To unsubscribe send an email to seabios-leave@seabios.org
[SeaBIOS] Re: [PATCH v2] bootmenu: add support for more than 9 entries
Posted by Kevin O'Connor 5 years ago
On Thu, Apr 11, 2019 at 10:01:20PM +0200, Gerd Hoffmann wrote:
> 10th and following entries can be selected using letters.

Ah, using an array of charcters makes sense.  Looks fine to me.

Thanks,
-Kevin
_______________________________________________
SeaBIOS mailing list -- seabios@seabios.org
To unsubscribe send an email to seabios-leave@seabios.org
[SeaBIOS] Re: [PATCH v2] bootmenu: add support for more than 9 entries
Posted by Kevin O'Connor 5 years ago
On Thu, Apr 11, 2019 at 10:01:20PM +0200, Gerd Hoffmann wrote:
> 10th and following entries can be selected using letters.
[...]
> --- a/src/boot.c
> +++ b/src/boot.c
> @@ -465,6 +465,14 @@ get_keystroke(int msec)
>  
>  #define DEFAULT_BOOTMENU_WAIT 2500
>  
> +static const char menuchars[] = {
> +    '1', '2', '3', '4', '5', '6', '7', '8', '9',
> +    'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i',
> +    'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r',
> +    's', /* skip t (tpm menu) */
> +    'u', 'v', 'w', 'x', 'y', 'z'
> +};

FYI, one thing that occurred to me is that the get_raw_keystroke()
command actually has the ascii value of the key (in regs->al) and is
currently discarding it.  Might be simpler to return the ascii value
directly instead of having to loop through the scan_to_keycode table.

-Kevin
_______________________________________________
SeaBIOS mailing list -- seabios@seabios.org
To unsubscribe send an email to seabios-leave@seabios.org
[SeaBIOS] Re: [PATCH v2] bootmenu: add support for more than 9 entries
Posted by Gerd Hoffmann 5 years ago
On Fri, Apr 12, 2019 at 12:38:03AM -0400, Kevin O'Connor wrote:
> On Thu, Apr 11, 2019 at 10:01:20PM +0200, Gerd Hoffmann wrote:
> > 10th and following entries can be selected using letters.
> [...]
> > --- a/src/boot.c
> > +++ b/src/boot.c
> > @@ -465,6 +465,14 @@ get_keystroke(int msec)
> >  
> >  #define DEFAULT_BOOTMENU_WAIT 2500
> >  
> > +static const char menuchars[] = {
> > +    '1', '2', '3', '4', '5', '6', '7', '8', '9',
> > +    'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i',
> > +    'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r',
> > +    's', /* skip t (tpm menu) */
> > +    'u', 'v', 'w', 'x', 'y', 'z'
> > +};
> 
> FYI, one thing that occurred to me is that the get_raw_keystroke()
> command actually has the ascii value of the key (in regs->al) and is
> currently discarding it.  Might be simpler to return the ascii value
> directly instead of having to loop through the scan_to_keycode table.

Looping through the scan_to_keycode() table has the advantage that the
modifier state is ignored.  So it doesn't matter whenever you press 'a'
or 'A' (shift or capslock active), both will work ...

cheers,
  Gerd
_______________________________________________
SeaBIOS mailing list -- seabios@seabios.org
To unsubscribe send an email to seabios-leave@seabios.org
[SeaBIOS] Re: [PATCH v2] bootmenu: add support for more than 9 entries
Posted by Gerd Hoffmann 5 years ago
> > > +static const char menuchars[] = {
> > > +    '1', '2', '3', '4', '5', '6', '7', '8', '9',
> > > +    'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i',
> > > +    'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r',
> > > +    's', /* skip t (tpm menu) */
> > > +    'u', 'v', 'w', 'x', 'y', 'z'
> > > +};
> > 
> > FYI, one thing that occurred to me is that the get_raw_keystroke()
> > command actually has the ascii value of the key (in regs->al) and is
> > currently discarding it.  Might be simpler to return the ascii value
> > directly instead of having to loop through the scan_to_keycode table.
> 
> Looping through the scan_to_keycode() table has the advantage that the
> modifier state is ignored.  So it doesn't matter whenever you press 'a'
> or 'A' (shift or capslock active), both will work ...

Tried updating get_keystroke() nevertheless, it looks nicer after all,
and can maybe used elsewhere too to make the code more readable.

cheers,
  Gerd
_______________________________________________
SeaBIOS mailing list -- seabios@seabios.org
To unsubscribe send an email to seabios-leave@seabios.org