Switch get_raw_keystroke() to return ax instead of ah, so it returns both scan code and ascii code of the key pressed.
Add get_keystroke_full() function which passes up ax to the caller.
The get_keystroke() function continues to return the scancode only like it did before. It is a thin wrapper around get_keystroke_full() now though.
Signed-off-by: Gerd Hoffmann kraxel@redhat.com --- src/util.h | 1 + src/boot.c | 16 ++++++++++++++-- 2 files changed, 15 insertions(+), 2 deletions(-)
diff --git a/src/util.h b/src/util.h index 9c06850353a4..e2afc80c425a 100644 --- a/src/util.h +++ b/src/util.h @@ -36,6 +36,7 @@ int bootprio_find_pci_rom(struct pci_device *pci, int instance); int bootprio_find_named_rom(const char *name, int instance); struct usbdevice_s; int bootprio_find_usb(struct usbdevice_s *usbdev, int lun); +int get_keystroke_full(int msec); int get_keystroke(int msec);
// bootsplash.c diff --git a/src/boot.c b/src/boot.c index 9f82f3ca0c3e..013d407a6449 100644 --- a/src/boot.c +++ b/src/boot.c @@ -441,12 +441,13 @@ get_raw_keystroke(void) memset(&br, 0, sizeof(br)); br.flags = F_IF; call16_int(0x16, &br); - return br.ah; + return br.ax; }
// Read a keystroke - waiting up to 'msec' milliseconds. +// returns both scancode and ascii code. int -get_keystroke(int msec) +get_keystroke_full(int msec) { u32 end = irqtimer_calc(msec); for (;;) { @@ -458,6 +459,17 @@ get_keystroke(int msec) } }
+// Read a keystroke - waiting up to 'msec' milliseconds. +// returns scancode only. +int +get_keystroke(int msec) +{ + int keystroke = get_keystroke_full(msec); + + if (keystroke < 0) + return keystroke; + return keystroke >> 8; +}
/**************************************************************** * Boot menu and BCV execution
10th and following entries can be selected using letters.
Signed-off-by: Gerd Hoffmann kraxel@redhat.com --- src/boot.c | 60 ++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 42 insertions(+), 18 deletions(-)
diff --git a/src/boot.c b/src/boot.c index 013d407a6449..5acf94fe64ca 100644 --- a/src/boot.c +++ b/src/boot.c @@ -477,6 +477,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) @@ -509,12 +517,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"); @@ -526,30 +537,43 @@ interactive_bootmenu(void) // multiple times and immediately booting the primary boot device. int esc_accepted_time = irqtimer_calc(menukey == 1 ? 1500 : 0); for (;;) { - scan_code = get_keystroke(1000); - if (scan_code == 1 && !irqtimer_check(esc_accepted_time)) + int keystroke = get_keystroke_full(1000); + if (keystroke == 0x011b && !irqtimer_check(esc_accepted_time)) continue; - if (tpm_can_show_menu() && scan_code == 20 /* t */) { + if (keystroke < 0) // timeout + continue; + + scan_code = keystroke >> 8; + int key_ascii = keystroke & 0xff; + if (tpm_can_show_menu() && key_ascii == 't') { 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 (key_ascii == 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
On Wed, May 15, 2019 at 10:07:38AM +0200, Gerd Hoffmann wrote:
Switch get_raw_keystroke() to return ax instead of ah, so it returns both scan code and ascii code of the key pressed.
Add get_keystroke_full() function which passes up ax to the caller.
The get_keystroke() function continues to return the scancode only like it did before. It is a thin wrapper around get_keystroke_full() now though.
Thanks, the series looks good to me.
-Kevin
On Wed, May 15, 2019 at 09:19:58AM -0400, Kevin O'Connor wrote:
On Wed, May 15, 2019 at 10:07:38AM +0200, Gerd Hoffmann wrote:
Switch get_raw_keystroke() to return ax instead of ah, so it returns both scan code and ascii code of the key pressed.
Add get_keystroke_full() function which passes up ax to the caller.
The get_keystroke() function continues to return the scancode only like it did before. It is a thin wrapper around get_keystroke_full() now though.
Thanks, the series looks good to me.
Pushed now.
cheers, Gerd