15a2072
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
15a2072
From: Hans de Goede <hdegoede@redhat.com>
15a2072
Date: Mon, 26 Mar 2018 16:15:53 +0200
15a2072
Subject: [PATCH] Accept ESC, F8 and holding SHIFT as user interrupt keys
15a2072
15a2072
On some devices the ESC key is the hotkey to enter the BIOS/EFI setup
15a2072
screen, making it really hard to time pressing it right. Besides that
15a2072
ESC is also pretty hard to discover for a user who does not know it
15a2072
will unhide the menu.
15a2072
15a2072
This commit makes F8, which used to be the hotkey to show the Windows
15a2072
boot menu during boot for a long long time, also interrupt sleeps /
15a2072
stop the menu countdown.
15a2072
15a2072
This solves the ESC gets into the BIOS setup and also somewhat solves
15a2072
the discoverability issue, but leaves the timing issue unresolved.
15a2072
15a2072
This commit fixes the timing issue by also adding support for keeping
15a2072
SHIFT pressed during boot to stop the menu countdown. This matches
15a2072
what Ubuntu is doing, which should also help with discoverability.
15a2072
15a2072
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
15a2072
---
15a2072
 grub-core/commands/sleep.c |  2 +-
15a2072
 grub-core/kern/term.c      | 16 ++++++++++++++++
15a2072
 grub-core/normal/menu.c    |  2 +-
15a2072
 include/grub/term.h        |  1 +
15a2072
 4 files changed, 19 insertions(+), 2 deletions(-)
15a2072
15a2072
diff --git a/grub-core/commands/sleep.c b/grub-core/commands/sleep.c
15a2072
index e77e7900fac..a1370b710c9 100644
15a2072
--- a/grub-core/commands/sleep.c
15a2072
+++ b/grub-core/commands/sleep.c
15a2072
@@ -55,7 +55,7 @@ grub_interruptible_millisleep (grub_uint32_t ms)
15a2072
   start = grub_get_time_ms ();
15a2072
 
15a2072
   while (grub_get_time_ms () - start < ms)
15a2072
-    if (grub_getkey_noblock () == GRUB_TERM_ESC)
15a2072
+    if (grub_key_is_interrupt (grub_getkey_noblock ()))
15a2072
       return 1;
15a2072
 
15a2072
   return 0;
15a2072
diff --git a/grub-core/kern/term.c b/grub-core/kern/term.c
15a2072
index 93bd3378d18..6cae4c23e7a 100644
15a2072
--- a/grub-core/kern/term.c
15a2072
+++ b/grub-core/kern/term.c
15a2072
@@ -138,6 +138,22 @@ grub_getkeystatus (void)
15a2072
   return status;
15a2072
 }
15a2072
 
15a2072
+int
15a2072
+grub_key_is_interrupt (int key)
15a2072
+{
15a2072
+  /* ESC sometimes is the BIOS setup hotkey and may be hard to discover, also
15a2072
+     check F8, which was the key to get the Windows bootmenu for a long time. */
15a2072
+  if (key == GRUB_TERM_ESC || key == GRUB_TERM_KEY_F8)
15a2072
+    return 1;
15a2072
+
15a2072
+  /* Pressing keys at the right time during boot is hard to time, also allow
15a2072
+     interrupting sleeps / the menu countdown by keeping shift pressed. */
15a2072
+  if (grub_getkeystatus() & (GRUB_TERM_STATUS_LSHIFT|GRUB_TERM_STATUS_RSHIFT))
15a2072
+    return 1;
15a2072
+
15a2072
+  return 0;
15a2072
+}
15a2072
+
15a2072
 void
15a2072
 grub_refresh (void)
15a2072
 {
15a2072
diff --git a/grub-core/normal/menu.c b/grub-core/normal/menu.c
15a2072
index 5e2f5283d3d..6cb2a071490 100644
15a2072
--- a/grub-core/normal/menu.c
15a2072
+++ b/grub-core/normal/menu.c
15a2072
@@ -655,7 +655,7 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot)
15a2072
 	      if (entry >= 0)
15a2072
 		break;
15a2072
 	    }
15a2072
-	  if (key == GRUB_TERM_ESC)
15a2072
+	  if (grub_key_is_interrupt (key))
15a2072
 	    {
15a2072
 	      timeout = -1;
15a2072
 	      break;
15a2072
diff --git a/include/grub/term.h b/include/grub/term.h
15a2072
index c215133383f..2b079c29b80 100644
15a2072
--- a/include/grub/term.h
15a2072
+++ b/include/grub/term.h
15a2072
@@ -328,6 +328,7 @@ void grub_putcode (grub_uint32_t code, struct grub_term_output *term);
15a2072
 int EXPORT_FUNC(grub_getkey) (void);
15a2072
 int EXPORT_FUNC(grub_getkey_noblock) (void);
15a2072
 int EXPORT_FUNC(grub_getkeystatus) (void);
15a2072
+int EXPORT_FUNC(grub_key_is_interrupt) (int key);
15a2072
 void grub_cls (void);
15a2072
 void EXPORT_FUNC(grub_refresh) (void);
15a2072
 void grub_puts_terminal (const char *str, struct grub_term_output *term);