10th and following entries can be selected using letters.
Signed-off-by: Gerd Hoffmann <kraxel(a)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