On 05/03/2015 10:27, Paolo Bonzini wrote:
F11 and F12 are trapped by some terminal emulators, and sgabios does not always recognize function keys very well.
Real-world machines often provide replacements for function keys for use on the serial console: ESC+1...ESC+0 for F1...F10, ESC+SHIFT+1 and ESC+SHIFT+2 for F11...F12. Accept all of them, which can be useful in case the user has set boot-menu-key.
The behavior is disabled if ESC is configured to trigger the menu. Chromebooks use this configuration.
Signed-off-by: Paolo Bonzini pbonzini@redhat.com
v1->v2: disable new behavior if ESC triggers the boot menu [Kevin]
src/boot.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 47 insertions(+), 5 deletions(-)
diff --git a/src/boot.c b/src/boot.c index f23e9e1..0572ff1 100644 --- a/src/boot.c +++ b/src/boot.c @@ -422,7 +422,21 @@ 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. +static int +get_keystroke_ascii(int msec) +{
- u32 end = irqtimer_calc(msec);
- for (;;) {
if (check_for_keystroke())
return get_raw_keystroke() & 255;
if (irqtimer_check(end))
return -1;
yield_toirq();
- }
}
// Read a keystroke - waiting up to 'msec' milliseconds. @@ -432,7 +446,7 @@ get_keystroke(int msec) u32 end = irqtimer_calc(msec); for (;;) { if (check_for_keystroke())
return get_raw_keystroke();
return get_raw_keystroke() >> 8; if (irqtimer_check(end)) return -1; yield_toirq();
@@ -446,6 +460,35 @@ get_keystroke(int msec)
#define DEFAULT_BOOTMENU_WAIT 2500
+static int +get_bootmenu_keystroke(bool esc_sequence) +{
- u32 menutime = romfile_loadint("etc/boot-menu-wait", DEFAULT_BOOTMENU_WAIT);
- int scan_code = get_keystroke(menutime);
- if (esc_sequence && scan_code == 0x01) {
while (get_keystroke(0) >= 0)
;
int ascii = get_keystroke_ascii(menutime * 2);
switch (ascii) {
case '1' ... '9':
scan_code = 0x3a + ascii - '0';
break;
case '0':
scan_code = 0x3a + 10;
break;
case '!':
scan_code = 0x85;
break;
case '@':
scan_code = 0x86;
break;
default:
break;
}
- }
- return scan_code;
+}
// Show IPL option menu. void interactive_bootmenu(void) @@ -460,12 +503,11 @@ interactive_bootmenu(void)
char *bootmsg = romfile_loadfile("etc/boot-menu-message", NULL); int menukey = romfile_loadint("etc/boot-menu-key", 0x86);
- printf("%s", bootmsg ?: "\nPress F12 for boot menu.\n\n");
- printf("%s", bootmsg ?: "\nPress ESC+@ or F12 for boot menu.\n\n"); free(bootmsg);
- u32 menutime = romfile_loadint("etc/boot-menu-wait", DEFAULT_BOOTMENU_WAIT); enable_bootsplash();
- int scan_code = get_keystroke(menutime);
- int scan_code = get_bootmenu_keystroke(menukey != 1); disable_bootsplash(); if (scan_code != menukey) return;
Ping?
paolo