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)