summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJan Janssen <medhefgo@web.de>2022-02-21 13:45:06 +0100
committerJan Janssen <medhefgo@web.de>2022-02-22 16:34:55 +0100
commit3f9973bf368475d1f2f7f587e7af728dd6d84e10 (patch)
treea331a12a2e68387718dc317a68fe9976a143d0f4 /src
parent1cb5d7857b205023a0473ec13df154ae2e254066 (diff)
downloadsystemd-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.c22
-rw-r--r--src/boot/efi/console.h11
-rw-r--r--src/boot/efi/missing_efi.h4
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;