diff options
author | Jan Janssen <medhefgo@web.de> | 2022-02-21 13:45:06 +0100 |
---|---|---|
committer | Jan Janssen <medhefgo@web.de> | 2022-02-22 16:34:55 +0100 |
commit | 3f9973bf368475d1f2f7f587e7af728dd6d84e10 (patch) | |
tree | a331a12a2e68387718dc317a68fe9976a143d0f4 /src | |
parent | 1cb5d7857b205023a0473ec13df154ae2e254066 (diff) | |
download | systemd-3f9973bf368475d1f2f7f587e7af728dd6d84e10.tar.gz |
boot: Handle shift and logo keys too
Some firmware supports sending input events for shift and logo keys.
Previously, we would suppress these with EFI_NOT_READY unless
some other key was pressed alongside, but it is really the job of the
caller to decide how to handle these.
Note that for keys that already have a printable shift representation
the reported input event will not have the shift key bits set
(Shift+a is reported as A). Should some firmware turn out to violate the
spec here we can always remove that part.
Diffstat (limited to 'src')
-rw-r--r-- | src/boot/efi/console.c | 22 | ||||
-rw-r--r-- | src/boot/efi/console.h | 11 | ||||
-rw-r--r-- | src/boot/efi/missing_efi.h | 4 |
3 files changed, 22 insertions, 15 deletions
diff --git a/src/boot/efi/console.c b/src/boot/efi/console.c index cd5c8b6348..937ad7ddfd 100644 --- a/src/boot/efi/console.c +++ b/src/boot/efi/console.c @@ -124,29 +124,27 @@ EFI_STATUS console_key_read(UINT64 *key, UINT64 timeout_usec) { * The two may be out of sync on some firmware, giving us double input. */ if (conInEx) { EFI_KEY_DATA keydata; - UINT64 keypress; UINT32 shift = 0; err = conInEx->ReadKeyStrokeEx(conInEx, &keydata); if (EFI_ERROR(err)) return err; - /* do not distinguish between left and right keys */ - if (keydata.KeyState.KeyShiftState & EFI_SHIFT_STATE_VALID) { - if (keydata.KeyState.KeyShiftState & (EFI_RIGHT_CONTROL_PRESSED|EFI_LEFT_CONTROL_PRESSED)) + if (FLAGS_SET(keydata.KeyState.KeyShiftState, EFI_SHIFT_STATE_VALID)) { + /* Do not distinguish between left and right keys (set both flags). */ + if (keydata.KeyState.KeyShiftState & EFI_SHIFT_PRESSED) + shift |= EFI_SHIFT_PRESSED; + if (keydata.KeyState.KeyShiftState & EFI_CONTROL_PRESSED) shift |= EFI_CONTROL_PRESSED; - if (keydata.KeyState.KeyShiftState & (EFI_RIGHT_ALT_PRESSED|EFI_LEFT_ALT_PRESSED)) + if (keydata.KeyState.KeyShiftState & EFI_ALT_PRESSED) shift |= EFI_ALT_PRESSED; + if (keydata.KeyState.KeyShiftState & EFI_LOGO_PRESSED) + shift |= EFI_LOGO_PRESSED; } /* 32 bit modifier keys + 16 bit scan code + 16 bit unicode */ - keypress = KEYPRESS(shift, keydata.Key.ScanCode, keydata.Key.UnicodeChar); - if (keypress > 0) { - *key = keypress; - return EFI_SUCCESS; - } - - return EFI_NOT_READY; + *key = KEYPRESS(shift, keydata.Key.ScanCode, keydata.Key.UnicodeChar); + return EFI_SUCCESS; } else if (!EFI_ERROR(BS->CheckEvent(ST->ConIn->WaitForKey))) { EFI_INPUT_KEY k; diff --git a/src/boot/efi/console.h b/src/boot/efi/console.h index c27c19b39f..cada643077 100644 --- a/src/boot/efi/console.h +++ b/src/boot/efi/console.h @@ -3,10 +3,15 @@ #include "missing_efi.h" -#define EFI_CONTROL_PRESSED (EFI_RIGHT_CONTROL_PRESSED|EFI_LEFT_CONTROL_PRESSED) -#define EFI_ALT_PRESSED (EFI_RIGHT_ALT_PRESSED|EFI_LEFT_ALT_PRESSED) +enum { + EFI_SHIFT_PRESSED = EFI_RIGHT_SHIFT_PRESSED|EFI_LEFT_SHIFT_PRESSED, + EFI_CONTROL_PRESSED = EFI_RIGHT_CONTROL_PRESSED|EFI_LEFT_CONTROL_PRESSED, + EFI_ALT_PRESSED = EFI_RIGHT_ALT_PRESSED|EFI_LEFT_ALT_PRESSED, + EFI_LOGO_PRESSED = EFI_RIGHT_LOGO_PRESSED|EFI_LEFT_LOGO_PRESSED, +}; + #define KEYPRESS(keys, scan, uni) ((((UINT64)keys) << 32) | (((UINT64)scan) << 16) | (uni)) -#define KEYCHAR(k) ((k) & 0xffff) +#define KEYCHAR(k) ((CHAR16)(k)) #define CHAR_CTRL(c) ((c) - 'a' + 1) enum { diff --git a/src/boot/efi/missing_efi.h b/src/boot/efi/missing_efi.h index b0bd00365f..f9700e3422 100644 --- a/src/boot/efi/missing_efi.h +++ b/src/boot/efi/missing_efi.h @@ -13,10 +13,14 @@ #define SimpleTextInputExProtocol ((EFI_GUID)EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL_GUID) #define EFI_SHIFT_STATE_VALID 0x80000000 +#define EFI_RIGHT_SHIFT_PRESSED 0x00000001 +#define EFI_LEFT_SHIFT_PRESSED 0x00000002 #define EFI_RIGHT_CONTROL_PRESSED 0x00000004 #define EFI_LEFT_CONTROL_PRESSED 0x00000008 #define EFI_RIGHT_ALT_PRESSED 0x00000010 #define EFI_LEFT_ALT_PRESSED 0x00000020 +#define EFI_RIGHT_LOGO_PRESSED 0x00000040 +#define EFI_LEFT_LOGO_PRESSED 0x00000080 struct _EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL; |