]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
boot: Handle shift and logo keys too 22582/head
authorJan Janssen <medhefgo@web.de>
Mon, 21 Feb 2022 12:45:06 +0000 (13:45 +0100)
committerJan Janssen <medhefgo@web.de>
Tue, 22 Feb 2022 15:34:55 +0000 (16:34 +0100)
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.

src/boot/efi/console.c
src/boot/efi/console.h
src/boot/efi/missing_efi.h

index cd5c8b63480eb9041595cf6b3851f902469832ff..937ad7ddfd052aee0103b1e263c51aa76c3e6602 100644 (file)
@@ -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;
 
index c27c19b39fb53c983fb889b94bc440694f0f3cf2..cada643077e16338876c066f68cbd40b07db70b8 100644 (file)
@@ -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 {
index b0bd00365f45240d930e6b9b1318207a2ddc5055..f9700e342294143e7142fa5cd8990309d3f63e4b 100644 (file)
 #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;