summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKay Sievers <kay@vrfy.org>2013-08-19 22:51:07 +0200
committerKay Sievers <kay@vrfy.org>2013-08-19 22:51:07 +0200
commitd49c2a9ceb7f611c2ff189ad67571c84fa3bf9de (patch)
tree0a5783b0eff9cc314c4f454eb85c1c5cb1f878aa
parentd22065f810a32ebea8ba15668daa6df3ddc602ca (diff)
move all key press handling into key_read()
Avoid mixing the API calls of: EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL EFI_SIMPLE_TEXT_INPUT_PROTOCOL Always wait for the key and read the key with the same API.
-rw-r--r--src/efi/gummiboot.c50
1 files changed, 28 insertions, 22 deletions
diff --git a/src/efi/gummiboot.c b/src/efi/gummiboot.c
index 3ea06c6..1fd438a 100644
--- a/src/efi/gummiboot.c
+++ b/src/efi/gummiboot.c
@@ -288,7 +288,7 @@ static VOID efivar_set_time_usec(CHAR16 *name, UINT64 usec) {
#define KEYCHAR(k) ((k) & 0xffff)
#define CHAR_CTRL(c) ((c) - 'a' + 1)
-static EFI_STATUS key_read(UINT64 *key) {
+static EFI_STATUS key_read(UINT64 *key, BOOLEAN wait) {
#define EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL_GUID \
{ 0xdd9e7534, 0x7762, 0x4698, { 0x8c, 0x14, 0xf5, 0x85, 0x17, 0xa6, 0x25, 0xaa } }
@@ -351,26 +351,33 @@ static EFI_STATUS key_read(UINT64 *key) {
static BOOLEAN checked;
EFI_KEY_DATA keydata;
UINT32 shift = 0;
+ UINTN index;
EFI_STATUS err;
if (!checked) {
err = LibLocateProtocol(&EfiSimpleTextInputExProtocolGuid, (VOID **)&TextInputEx);
if (EFI_ERROR(err))
TextInputEx = NULL;
+
checked = TRUE;
}
if (!TextInputEx) {
EFI_INPUT_KEY k;
+ /* fallback for firmware which does not support SIMPLE_TEXT_INPUT_EX_PROTOCOL */
+ if (wait)
+ uefi_call_wrapper(BS->WaitForEvent, 3, 1, &ST->ConIn->WaitForKey, &index);
err = uefi_call_wrapper(ST->ConIn->ReadKeyStroke, 2, ST->ConIn, &k);
if (EFI_ERROR(err))
return err;
+
*key = KEYPRESS(0, k.ScanCode, k.UnicodeChar);
return 0;
}
-
+ if (wait)
+ uefi_call_wrapper(BS->WaitForEvent, 3, 1, &TextInputEx->WaitForKeyEx, &index);
err = uefi_call_wrapper(TextInputEx->ReadKeyStrokeEx, 2, TextInputEx, &keydata);
if (EFI_ERROR(err))
return err;
@@ -431,7 +438,6 @@ static BOOLEAN line_edit(CHAR16 *line_in, CHAR16 **line_out, UINTN x_max, UINTN
enter = FALSE;
exit = FALSE;
while (!exit) {
- UINTN index;
EFI_STATUS err;
UINT64 key;
UINTN i;
@@ -450,9 +456,7 @@ static BOOLEAN line_edit(CHAR16 *line_in, CHAR16 **line_out, UINTN x_max, UINTN
uefi_call_wrapper(ST->ConOut->OutputString, 2, ST->ConOut, print);
uefi_call_wrapper(ST->ConOut->SetCursorPosition, 3, ST->ConOut, cursor, y_pos);
- uefi_call_wrapper(BS->WaitForEvent, 3, 1, &ST->ConIn->WaitForKey, &index);
-
- err = key_read(&key);
+ err = key_read(&key, TRUE);
if (EFI_ERROR(err))
continue;
@@ -641,8 +645,7 @@ static UINTN entry_lookup_key(Config *config, UINTN start, CHAR16 key) {
}
static VOID print_status(Config *config, CHAR16 *loaded_image_path) {
- UINTN index;
- EFI_INPUT_KEY key;
+ UINT64 key;
UINTN i;
CHAR16 *s;
CHAR8 *b;
@@ -704,13 +707,12 @@ static VOID print_status(Config *config, CHAR16 *loaded_image_path) {
}
Print(L"\n--- press key ---\n\n");
- uefi_call_wrapper(BS->WaitForEvent, 3, 1, &ST->ConIn->WaitForKey, &index);
- uefi_call_wrapper(ST->ConIn->ReadKeyStroke, 2, ST->ConIn, &key);
+ key_read(&key, TRUE);
for (i = 0; i < config->entry_count; i++) {
ConfigEntry *entry;
- if (key.ScanCode == SCAN_ESC || key.UnicodeChar == 'q')
+ if (key == KEYPRESS(0, SCAN_ESC, 0) || key == KEYPRESS(0, 0, 'q'))
break;
entry = config->entries[i];
@@ -744,8 +746,7 @@ static VOID print_status(Config *config, CHAR16 *loaded_image_path) {
Print(L"internal call yes\n");
Print(L"\n--- press key ---\n\n");
- uefi_call_wrapper(BS->WaitForEvent, 3, 1, &ST->ConIn->WaitForKey, &index);
- uefi_call_wrapper(ST->ConIn->ReadKeyStroke, 2, ST->ConIn, &key);
+ key_read(&key, TRUE);
}
uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut);
@@ -818,6 +819,7 @@ static BOOLEAN menu_run(Config *config, ConfigEntry **chosen_entry, CHAR16 *load
INT16 idx;
BOOLEAN exit = FALSE;
BOOLEAN run = TRUE;
+ BOOLEAN wait = FALSE;
console_text_mode();
uefi_call_wrapper(ST->ConIn->Reset, 2, ST->ConIn, FALSE);
@@ -957,22 +959,26 @@ static BOOLEAN menu_run(Config *config, ConfigEntry **chosen_entry, CHAR16 *load
uefi_call_wrapper(ST->ConOut->OutputString, 2, ST->ConOut, clearline+1 + x + len);
}
- err = key_read(&key);
- if (err != EFI_SUCCESS) {
- UINTN index;
-
+ err = key_read(&key, wait);
+ if (EFI_ERROR(err)) {
+ /* timeout reached */
if (timeout_remain == 0) {
exit = TRUE;
break;
}
+
+ /* sleep and update status */
if (timeout_remain > 0) {
uefi_call_wrapper(BS->Stall, 1, 100 * 1000);
timeout_remain--;
continue;
}
- uefi_call_wrapper(BS->WaitForEvent, 3, 1, &ST->ConIn->WaitForKey, &index);
+
+ /* timeout disabled, wait for next key */
+ wait = TRUE;
continue;
}
+
timeout_remain = -1;
/* clear status after keystroke */
@@ -2175,14 +2181,14 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
/* select entry or show menu when key is pressed or timeout is set */
if (config.timeout_sec == 0) {
- EFI_INPUT_KEY k;
+ UINT64 key;
- err = uefi_call_wrapper(ST->ConIn->ReadKeyStroke, 2, ST->ConIn, &k);
- if (err == EFI_SUCCESS) {
+ err = key_read(&key, FALSE);
+ if (!EFI_ERROR(err)) {
INT16 idx;
/* find matching key in config entries */
- idx = entry_lookup_key(&config, config.idx_default, k.UnicodeChar);
+ idx = entry_lookup_key(&config, config.idx_default, KEYCHAR(key));
if (idx >= 0)
config.idx_default = idx;
else