|
|
8631a2 |
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
|
8631a2 |
From: Hans de Goede <hdegoede@redhat.com>
|
|
|
8631a2 |
Date: Wed, 6 Jun 2018 15:54:44 +0200
|
|
|
8631a2 |
Subject: [PATCH] EFI: console: Add grub_console_read_key_stroke() helper
|
|
|
8631a2 |
function
|
|
|
8631a2 |
|
|
|
8631a2 |
This is a preparation patch for adding getkeystatus() support to the
|
|
|
8631a2 |
EFI console terminal input driver.
|
|
|
8631a2 |
|
|
|
8631a2 |
We can get modifier status through the simple_text_input read_key_stroke
|
|
|
8631a2 |
method, but if a non-modifier key is (also) pressed the read_key_stroke
|
|
|
8631a2 |
call will consume that key from the firmware's queue.
|
|
|
8631a2 |
|
|
|
8631a2 |
The new grub_console_read_key_stroke() helper buffers upto 1 key-stroke.
|
|
|
8631a2 |
If it has a non-modifier key buffered, it will return that one, if its
|
|
|
8631a2 |
buffer is empty, it will fills its buffer by getting a new key-stroke.
|
|
|
8631a2 |
|
|
|
8631a2 |
If called with consume=1 it will empty its buffer after copying the
|
|
|
8631a2 |
key-data to the callers buffer, this is how getkey() will use it.
|
|
|
8631a2 |
|
|
|
8631a2 |
If called with consume=0 it will keep the last key-stroke buffered, this
|
|
|
8631a2 |
is how getkeystatus() will call it. This means that if a non-modifier
|
|
|
8631a2 |
key gets pressed, repeated getkeystatus() calls will return the modifiers
|
|
|
8631a2 |
of that key-press until it is consumed by a getkey() call.
|
|
|
8631a2 |
|
|
|
8631a2 |
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
|
|
|
8631a2 |
---
|
|
|
8631a2 |
grub-core/term/efi/console.c | 51 ++++++++++++++++++++++++++++++++++----------
|
|
|
8631a2 |
1 file changed, 40 insertions(+), 11 deletions(-)
|
|
|
8631a2 |
|
|
|
8631a2 |
diff --git a/grub-core/term/efi/console.c b/grub-core/term/efi/console.c
|
|
|
030dc3 |
index 051633d71e9..3d36c5c701b 100644
|
|
|
8631a2 |
--- a/grub-core/term/efi/console.c
|
|
|
8631a2 |
+++ b/grub-core/term/efi/console.c
|
|
|
8631a2 |
@@ -157,27 +157,56 @@ grub_console_getkey_con (struct grub_term_input *term __attribute__ ((unused)))
|
|
|
8631a2 |
return grub_efi_translate_key(key);
|
|
|
8631a2 |
}
|
|
|
8631a2 |
|
|
|
8631a2 |
+/*
|
|
|
8631a2 |
+ * When more then just modifiers are pressed, our getkeystatus() consumes a
|
|
|
8631a2 |
+ * press from the queue, this function buffers the press for the regular
|
|
|
8631a2 |
+ * getkey() so that it does not get lost.
|
|
|
8631a2 |
+ */
|
|
|
8631a2 |
+static int
|
|
|
8631a2 |
+grub_console_read_key_stroke (
|
|
|
8631a2 |
+ grub_efi_simple_text_input_ex_interface_t *text_input,
|
|
|
8631a2 |
+ grub_efi_key_data_t *key_data_ret, int *key_ret,
|
|
|
8631a2 |
+ int consume)
|
|
|
8631a2 |
+{
|
|
|
8631a2 |
+ static grub_efi_key_data_t key_data;
|
|
|
8631a2 |
+ grub_efi_status_t status;
|
|
|
8631a2 |
+ int key;
|
|
|
8631a2 |
+
|
|
|
8631a2 |
+ if (!text_input)
|
|
|
8631a2 |
+ return GRUB_ERR_EOF;
|
|
|
8631a2 |
+
|
|
|
8631a2 |
+ key = grub_efi_translate_key (key_data.key);
|
|
|
8631a2 |
+ if (key == GRUB_TERM_NO_KEY) {
|
|
|
8631a2 |
+ status = efi_call_2 (text_input->read_key_stroke, text_input, &key_data);
|
|
|
8631a2 |
+ if (status != GRUB_EFI_SUCCESS)
|
|
|
8631a2 |
+ return GRUB_ERR_EOF;
|
|
|
8631a2 |
+
|
|
|
8631a2 |
+ key = grub_efi_translate_key (key_data.key);
|
|
|
8631a2 |
+ }
|
|
|
8631a2 |
+
|
|
|
8631a2 |
+ *key_data_ret = key_data;
|
|
|
8631a2 |
+ *key_ret = key;
|
|
|
8631a2 |
+
|
|
|
8631a2 |
+ if (consume) {
|
|
|
8631a2 |
+ key_data.key.scan_code = 0;
|
|
|
8631a2 |
+ key_data.key.unicode_char = 0;
|
|
|
8631a2 |
+ }
|
|
|
8631a2 |
+
|
|
|
8631a2 |
+ return 0;
|
|
|
8631a2 |
+}
|
|
|
8631a2 |
+
|
|
|
8631a2 |
static int
|
|
|
8631a2 |
grub_console_getkey_ex(struct grub_term_input *term)
|
|
|
8631a2 |
{
|
|
|
8631a2 |
grub_efi_key_data_t key_data;
|
|
|
8631a2 |
- grub_efi_status_t status;
|
|
|
8631a2 |
grub_efi_uint32_t kss;
|
|
|
8631a2 |
int key = -1;
|
|
|
8631a2 |
|
|
|
8631a2 |
- grub_efi_simple_text_input_ex_interface_t *text_input = term->data;
|
|
|
8631a2 |
-
|
|
|
8631a2 |
- status = efi_call_2 (text_input->read_key_stroke, text_input, &key_data);
|
|
|
8631a2 |
-
|
|
|
8631a2 |
- if (status != GRUB_EFI_SUCCESS)
|
|
|
8631a2 |
+ if (grub_console_read_key_stroke (term->data, &key_data, &key, 1) ||
|
|
|
8631a2 |
+ key == GRUB_TERM_NO_KEY)
|
|
|
8631a2 |
return GRUB_TERM_NO_KEY;
|
|
|
8631a2 |
|
|
|
8631a2 |
kss = key_data.key_state.key_shift_state;
|
|
|
8631a2 |
- key = grub_efi_translate_key(key_data.key);
|
|
|
8631a2 |
-
|
|
|
8631a2 |
- if (key == GRUB_TERM_NO_KEY)
|
|
|
8631a2 |
- return GRUB_TERM_NO_KEY;
|
|
|
8631a2 |
-
|
|
|
8631a2 |
if (kss & GRUB_EFI_SHIFT_STATE_VALID)
|
|
|
8631a2 |
{
|
|
|
8631a2 |
if ((kss & GRUB_EFI_LEFT_SHIFT_PRESSED
|