From: Hans de Goede <hdego...@redhat.com> This is a preparation patch for adding getkeystatus() support to the EFI console terminal input driver.
We can get modifier status through the simple_text_input read_key_stroke method, but if a non-modifier key is (also) pressed the read_key_stroke call will consume that key from the firmware's queue. The new grub_console_read_key_stroke() helper buffers upto 1 key-stroke. If it has a non-modifier key buffered, it will return that one, if its buffer is empty, it will fills its buffer by getting a new key-stroke. If called with consume=1 it will empty its buffer after copying the key-data to the callers buffer, this is how getkey() will use it. If called with consume=0 it will keep the last key-stroke buffered, this is how getkeystatus() will call it. This means that if a non-modifier key gets pressed, repeated getkeystatus() calls will return the modifiers of that key-press until it is consumed by a getkey() call. Signed-off-by: Hans de Goede <hdego...@redhat.com> Signed-off-by: Javier Martinez Canillas <javi...@redhat.com> --- grub-core/term/efi/console.c | 51 ++++++++++++++++++++++++++++-------- 1 file changed, 40 insertions(+), 11 deletions(-) diff --git a/grub-core/term/efi/console.c b/grub-core/term/efi/console.c index 16ccd350ee0..11f85e84790 100644 --- a/grub-core/term/efi/console.c +++ b/grub-core/term/efi/console.c @@ -227,27 +227,56 @@ grub_console_getkey_con (struct grub_term_input *term __attribute__ ((unused))) return grub_efi_translate_key(key); } +/* + * When more then just modifiers are pressed, our getkeystatus() consumes a + * press from the queue, this function buffers the press for the regular + * getkey() so that it does not get lost. + */ static int -grub_console_getkey_ex(struct grub_term_input *term) +grub_console_read_key_stroke ( + grub_efi_simple_text_input_ex_interface_t *text_input, + grub_efi_key_data_t *key_data_ret, int *key_ret, + int consume) { - grub_efi_key_data_t key_data; + static grub_efi_key_data_t key_data; grub_efi_status_t status; - grub_efi_uint32_t kss; - int key = -1; + int key; - grub_efi_simple_text_input_ex_interface_t *text_input = term->data; + if (!text_input) + return GRUB_ERR_EOF; - status = efi_call_2 (text_input->read_key_stroke, text_input, &key_data); + key = grub_efi_translate_key (key_data.key); + if (key == GRUB_TERM_NO_KEY) { + status = efi_call_2 (text_input->read_key_stroke, text_input, &key_data); + if (status != GRUB_EFI_SUCCESS) + return GRUB_ERR_EOF; - if (status != GRUB_EFI_SUCCESS) - return GRUB_TERM_NO_KEY; + key = grub_efi_translate_key (key_data.key); + } - kss = key_data.key_state.key_shift_state; - key = grub_efi_translate_key(key_data.key); + *key_data_ret = key_data; + *key_ret = key; + + if (consume) { + key_data.key.scan_code = 0; + key_data.key.unicode_char = 0; + } + + return 0; +} + +static int +grub_console_getkey_ex(struct grub_term_input *term) +{ + grub_efi_key_data_t key_data; + grub_efi_uint32_t kss; + int key = -1; - if (key == GRUB_TERM_NO_KEY) + if (grub_console_read_key_stroke (term->data, &key_data, &key, 1) || + key == GRUB_TERM_NO_KEY) return GRUB_TERM_NO_KEY; + kss = key_data.key_state.key_shift_state; if (kss & GRUB_EFI_SHIFT_STATE_VALID) { if ((kss & GRUB_EFI_LEFT_SHIFT_PRESSED -- 2.24.1 _______________________________________________ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel