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