public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [PATCH 0/6] ReadKeyStrokeEx always return key state
@ 2018-01-22  8:10 Ruiyu Ni
  2018-01-22  8:10 ` [PATCH 1/6] MdePkg/SimpleTextInEx.h: Fix comments alignment Ruiyu Ni
                   ` (5 more replies)
  0 siblings, 6 replies; 8+ messages in thread
From: Ruiyu Ni @ 2018-01-22  8:10 UTC (permalink / raw)
  To: edk2-devel

Today's implementation only return key state when there is key.
But when user doesn't press any key, the key state cannot be
returned.

The patch changes the ReadKeyStrokeEx() to always return the
key state even there is no key pressed.

Ruiyu Ni (6):
  MdePkg/SimpleTextInEx.h: Fix comments alignment
  MdeModulePkg/ConSplitter: ReadKeyStrokeEx always return key state
  MdeModulePkg/UsbKb: ReadKeyStrokeEx always return key state
  MdeModulePkg/Ps2Kb: ReadKeyStrokeEx always return key state
  IntelFrameworkModule/Ps2Kb: ReadKeyStrokeEx always return key state
  IntelFrameworkModule/ThunkKb: ReadKeyStrokeEx always return key state

 .../Bus/Isa/Ps2KeyboardDxe/Ps2KbdCtrller.c         |  58 +++++---
 .../Bus/Isa/Ps2KeyboardDxe/Ps2KbdTextIn.c          |   6 +-
 .../Bus/Isa/Ps2KeyboardDxe/Ps2Keyboard.h           |  14 +-
 .../Csm/BiosThunk/KeyboardDxe/BiosKeyboard.c       |  14 +-
 .../Csm/BiosThunk/KeyboardDxe/BiosKeyboard.h       |   5 +-
 .../Bus/Isa/Ps2KeyboardDxe/Ps2KbdCtrller.c         |  58 +++++---
 MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KbdTextIn.c |   6 +-
 MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2Keyboard.h  |  14 +-
 MdeModulePkg/Bus/Usb/UsbKbDxe/EfiKey.c             |   4 +-
 MdeModulePkg/Bus/Usb/UsbKbDxe/KeyBoard.c           | 107 ++++++++------
 MdeModulePkg/Bus/Usb/UsbKbDxe/KeyBoard.h           |  14 +-
 .../Universal/Console/ConSplitterDxe/ConSplitter.c | 164 ++++++++++++++++++---
 .../Universal/Console/ConSplitterDxe/ConSplitter.h |   4 +-
 MdePkg/Include/Protocol/SimpleTextInEx.h           |  13 +-
 14 files changed, 348 insertions(+), 133 deletions(-)

-- 
2.15.1.windows.2



^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 1/6] MdePkg/SimpleTextInEx.h: Fix comments alignment
  2018-01-22  8:10 [PATCH 0/6] ReadKeyStrokeEx always return key state Ruiyu Ni
@ 2018-01-22  8:10 ` Ruiyu Ni
  2018-01-22  8:10 ` [PATCH 2/6] MdeModulePkg/ConSplitter: ReadKeyStrokeEx always return key state Ruiyu Ni
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 8+ messages in thread
From: Ruiyu Ni @ 2018-01-22  8:10 UTC (permalink / raw)
  To: edk2-devel; +Cc: Liming Gao

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Ruiyu Ni <ruiyu.ni@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
---
 MdePkg/Include/Protocol/SimpleTextInEx.h | 13 +++++--------
 1 file changed, 5 insertions(+), 8 deletions(-)

diff --git a/MdePkg/Include/Protocol/SimpleTextInEx.h b/MdePkg/Include/Protocol/SimpleTextInEx.h
index 4591bd4779..ffc11c601e 100644
--- a/MdePkg/Include/Protocol/SimpleTextInEx.h
+++ b/MdePkg/Include/Protocol/SimpleTextInEx.h
@@ -5,7 +5,7 @@
   which exposes much more state and modifier information from the input device,
   also allows one to register a notification for a particular keystroke.
 
-  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
   This program and the accompanying materials
   are licensed and made available under the terms and conditions of the BSD License
   which accompanies this distribution.  The full text of the license may be found at
@@ -190,13 +190,10 @@ typedef struct {
                   pressed.
 
 
-  @retval EFI_SUCCESS     The keystroke information was
-                          returned.
-
-  @retval EFI_NOT_READY   There was no keystroke data available.
-                          EFI_DEVICE_ERROR The keystroke
-                          information was not returned due to
-                          hardware errors.
+  @retval EFI_SUCCESS      The keystroke information was returned.
+  @retval EFI_NOT_READY    There was no keystroke data available.
+  @retval EFI_DEVICE_ERROR The keystroke information was not returned due to
+                           hardware errors.
 
 
 **/
-- 
2.15.1.windows.2



^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 2/6] MdeModulePkg/ConSplitter: ReadKeyStrokeEx always return key state
  2018-01-22  8:10 [PATCH 0/6] ReadKeyStrokeEx always return key state Ruiyu Ni
  2018-01-22  8:10 ` [PATCH 1/6] MdePkg/SimpleTextInEx.h: Fix comments alignment Ruiyu Ni
@ 2018-01-22  8:10 ` Ruiyu Ni
  2018-02-01  5:35   ` Zeng, Star
  2018-01-22  8:10 ` [PATCH 3/6] MdeModulePkg/UsbKb: " Ruiyu Ni
                   ` (3 subsequent siblings)
  5 siblings, 1 reply; 8+ messages in thread
From: Ruiyu Ni @ 2018-01-22  8:10 UTC (permalink / raw)
  To: edk2-devel; +Cc: Star Zeng, Michael D Kinney

Today's implementation only return key state when there is key.
But when user doesn't press any key, the key state cannot be
returned.

The patch changes the ReadKeyStrokeEx() to always return the
key state even there is no key pressed.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Ruiyu Ni <ruiyu.ni@intel.com>
Cc: Star Zeng <star.zeng@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
---
 .../Universal/Console/ConSplitterDxe/ConSplitter.c | 164 ++++++++++++++++++---
 .../Universal/Console/ConSplitterDxe/ConSplitter.h |   4 +-
 2 files changed, 143 insertions(+), 25 deletions(-)

diff --git a/MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitter.c b/MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitter.c
index e70ff6114a..022fca7cbb 100644
--- a/MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitter.c
+++ b/MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitter.c
@@ -16,7 +16,7 @@
   never removed. Such design ensures sytem function well during none console
   device situation.
 
-Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
 (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
 This program and the accompanying materials
 are licensed and made available under the terms and conditions of the BSD License
@@ -67,6 +67,8 @@ GLOBAL_REMOVE_IF_UNREFERENCED TEXT_IN_SPLITTER_PRIVATE_DATA  mConIn = {
     (LIST_ENTRY *) NULL,
     (LIST_ENTRY *) NULL
   },
+  (EFI_KEY_DATA *) NULL,
+  0,
   0,
   FALSE,
 
@@ -606,6 +608,7 @@ ConSplitterTextInConstructor (
   )
 {
   EFI_STATUS  Status;
+  UINTN       TextInExListCount;
 
   //
   // Allocate buffer for Simple Text Input device
@@ -631,6 +634,19 @@ ConSplitterTextInConstructor (
                   );
   ASSERT_EFI_ERROR (Status);
 
+  //
+  // Allocate buffer for KeyQueue
+  //
+  TextInExListCount = ConInPrivate->TextInExListCount;
+  Status = ConSplitterGrowBuffer (
+             sizeof (EFI_KEY_DATA),
+             &TextInExListCount,
+             (VOID **) &ConInPrivate->KeyQueue
+             );
+  if (EFI_ERROR (Status)) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
   //
   // Allocate buffer for Simple Text Input Ex device
   //
@@ -1968,6 +1984,17 @@ ConSplitterTextInExAddDevice (
         return EFI_OUT_OF_RESOURCES;
       }
     }
+
+    TextInExListCount = Private->TextInExListCount;
+    Status = ConSplitterGrowBuffer (
+               sizeof (EFI_KEY_DATA),
+               &TextInExListCount,
+               (VOID **) &Private->KeyQueue
+               );
+    if (EFI_ERROR (Status)) {
+      return EFI_OUT_OF_RESOURCES;
+    }
+
     Status = ConSplitterGrowBuffer (
               sizeof (EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *),
               &Private->TextInExListCount,
@@ -3445,11 +3472,46 @@ ConSplitterTextInReset (
 
   if (!EFI_ERROR (ReturnStatus)) {
     ToggleStateSyncReInitialization (Private);
+    //
+    // Empty the key queue.
+    //
+    Private->CurrentNumberOfKeys = 0;
   }
 
   return ReturnStatus;
 }
 
+/**
+  Dequeue the saved key from internal key queue.
+
+  @param  Private                  Protocol instance pointer.
+  @param  KeyData                  A pointer to a buffer that is filled in with the
+                                   keystroke state data for the key that was
+                                   pressed.
+  @retval EFI_NOT_FOUND            Queue is empty.
+  @retval EFI_SUCCESS              First key is dequeued and returned.
+**/
+EFI_STATUS
+ConSplitterTextInExDequeueKey (
+  IN  TEXT_IN_SPLITTER_PRIVATE_DATA   *Private,
+  OUT EFI_KEY_DATA                    *KeyData
+  )
+{
+  if (Private->CurrentNumberOfKeys == 0) {
+    return EFI_NOT_FOUND;
+  }
+  //
+  // Return the first saved key.
+  //
+  CopyMem (KeyData, &Private->KeyQueue[0], sizeof (EFI_KEY_DATA));
+  Private->CurrentNumberOfKeys--;
+  CopyMem (
+    &Private->KeyQueue[0],
+    &Private->KeyQueue[1],
+    Private->CurrentNumberOfKeys * sizeof (EFI_KEY_DATA)
+    );
+  return EFI_SUCCESS;
+}
 
 /**
   Reads the next keystroke from the input device. The WaitForKey Event can
@@ -3473,7 +3535,13 @@ ConSplitterTextInPrivateReadKeyStroke (
 {
   EFI_STATUS    Status;
   UINTN         Index;
-  EFI_INPUT_KEY CurrentKey;
+  EFI_KEY_DATA  KeyData;
+
+  Status = ConSplitterTextInExDequeueKey (Private, &KeyData);
+  if (!EFI_ERROR (Status)) {
+    CopyMem (Key, &KeyData.Key, sizeof (EFI_INPUT_KEY));
+    return Status;
+  }
 
   Key->UnicodeChar  = 0;
   Key->ScanCode     = SCAN_NULL;
@@ -3486,15 +3554,15 @@ ConSplitterTextInPrivateReadKeyStroke (
   for (Index = 0; Index < Private->CurrentNumberOfConsoles;) {
     Status = Private->TextInList[Index]->ReadKeyStroke (
                                           Private->TextInList[Index],
-                                          &CurrentKey
+                                          &KeyData.Key
                                           );
     if (!EFI_ERROR (Status)) {
       //
       // If it is not partial keystorke, return the key. Otherwise, continue
       // to read key from THIS physical console input device.
       //
-      if ((CurrentKey.ScanCode != CHAR_NULL) || (CurrentKey.UnicodeChar != SCAN_NULL)) {
-        *Key = CurrentKey;
+      if ((KeyData.Key.ScanCode != CHAR_NULL) || (KeyData.Key.UnicodeChar != SCAN_NULL)) {
+        CopyMem (Key, &KeyData.Key, sizeof (EFI_INPUT_KEY));
         return Status;
       }
     } else {
@@ -3681,6 +3749,10 @@ ConSplitterTextInResetEx (
 
   if (!EFI_ERROR (ReturnStatus)) {
     ToggleStateSyncReInitialization (Private);
+    //
+    // Empty the key queue.
+    //
+    Private->CurrentNumberOfKeys = 0;
   }
 
   return ReturnStatus;
@@ -3714,6 +3786,7 @@ ConSplitterTextInReadKeyStrokeEx (
   TEXT_IN_SPLITTER_PRIVATE_DATA *Private;
   EFI_STATUS                    Status;
   UINTN                         Index;
+  EFI_KEY_STATE                 KeyState;
   EFI_KEY_DATA                  CurrentKeyData;
 
 
@@ -3725,9 +3798,6 @@ ConSplitterTextInReadKeyStrokeEx (
 
   Private->KeyEventSignalState = FALSE;
 
-  KeyData->Key.UnicodeChar  = 0;
-  KeyData->Key.ScanCode     = SCAN_NULL;
-
   //
   // Signal ConnectConIn event on first call in Lazy ConIn mode
   //
@@ -3738,35 +3808,81 @@ ConSplitterTextInReadKeyStrokeEx (
   }
 
   //
-  // if no physical console input device exists, return EFI_NOT_READY;
-  // if any physical console input device has key input,
-  // return the key and EFI_SUCCESS.
+  // Return the first saved key.
+  //
+  Status = ConSplitterTextInExDequeueKey (Private, KeyData);
+  if (!EFI_ERROR (Status)) {
+    return Status;
+  }
+  ASSERT (Private->CurrentNumberOfKeys == 0);
+
+  ZeroMem (&KeyState, sizeof (KeyState));
+
+  //
+  // Iterate through all physical consoles to get key state.
+  // Some physical consoles may return valid key.
+  // Queue the valid keys.
   //
-  for (Index = 0; Index < Private->CurrentNumberOfExConsoles;) {
+  for (Index = 0; Index < Private->CurrentNumberOfExConsoles; Index++) {
+    ZeroMem (&CurrentKeyData, sizeof (EFI_KEY_DATA));
     Status = Private->TextInExList[Index]->ReadKeyStrokeEx (
-                                          Private->TextInExList[Index],
-                                          &CurrentKeyData
-                                          );
+                                             Private->TextInExList[Index],
+                                             &CurrentKeyData
+                                             );
+    if (EFI_ERROR (Status) && (Status != EFI_NOT_READY)) {
+      continue;
+    }
+
+    //
+    // Consolidate the key state from all physical consoles.
+    //
+    if ((CurrentKeyData.KeyState.KeyShiftState & EFI_SHIFT_STATE_VALID) != 0) {
+      KeyState.KeyShiftState |= CurrentKeyData.KeyState.KeyShiftState;
+    }
+    if ((CurrentKeyData.KeyState.KeyToggleState & EFI_TOGGLE_STATE_VALID) != 0) {
+      KeyState.KeyToggleState |= CurrentKeyData.KeyState.KeyToggleState;
+    }
+
     if (!EFI_ERROR (Status)) {
       //
       // If virtual KeyState has been required to be exposed, or it is not
-      // partial keystorke, return the key. Otherwise, continue to read key
-      // from THIS physical console input device.
+      // partial keystorke, queue the key.
+      // It's possible that user presses at multiple keyboards at the same moment,
+      // Private->KeyQueue[] are the storage to save all the keys.
       //
       if ((Private->VirtualKeyStateExported) ||
           (CurrentKeyData.Key.ScanCode != CHAR_NULL) ||
           (CurrentKeyData.Key.UnicodeChar != SCAN_NULL)) {
-        CopyMem (KeyData, &CurrentKeyData, sizeof (CurrentKeyData));
-        return Status;
+        CopyMem (
+          &Private->KeyQueue[Private->CurrentNumberOfKeys],
+          &CurrentKeyData,
+          sizeof (EFI_KEY_DATA)
+          );
+        Private->CurrentNumberOfKeys++;
       }
-    } else {
-      //
-      // Continue to read key from NEXT physical console input device.
-      //
-      Index++;
     }
   }
 
+  //
+  // Consolidate the key state for all keys in Private->KeyQueue[]
+  //
+  for (Index = 0; Index < Private->CurrentNumberOfKeys; Index++) {
+    CopyMem (&Private->KeyQueue[Index].KeyState, &KeyState, sizeof (EFI_KEY_STATE));
+  }
+  
+  //
+  // Return the first saved key.
+  //
+  Status = ConSplitterTextInExDequeueKey (Private, KeyData);
+  if (!EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // Always return the key state even there is no key pressed.
+  //
+  ZeroMem (&KeyData->Key, sizeof (KeyData->Key));
+  CopyMem (&KeyData->KeyState, &KeyState, sizeof (KeyData->KeyState));
   return EFI_NOT_READY;
 }
 
diff --git a/MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitter.h b/MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitter.h
index 9469860bf0..5fde6b0cb4 100644
--- a/MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitter.h
+++ b/MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitter.h
@@ -1,7 +1,7 @@
 /** @file
   Private data structures for the Console Splitter driver
 
-Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
 This program and the accompanying materials
 are licensed and made available under the terms and conditions of the BSD License
 which accompanies this distribution.  The full text of the license may be found at
@@ -129,6 +129,8 @@ typedef struct {
   EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL  **TextInExList;
   UINTN                              TextInExListCount;
   LIST_ENTRY                         NotifyList;
+  EFI_KEY_DATA                       *KeyQueue;
+  UINTN                              CurrentNumberOfKeys;
   //
   // It will be initialized and synced between console input devices
   // for toggle state sync.
-- 
2.15.1.windows.2



^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 3/6] MdeModulePkg/UsbKb: ReadKeyStrokeEx always return key state
  2018-01-22  8:10 [PATCH 0/6] ReadKeyStrokeEx always return key state Ruiyu Ni
  2018-01-22  8:10 ` [PATCH 1/6] MdePkg/SimpleTextInEx.h: Fix comments alignment Ruiyu Ni
  2018-01-22  8:10 ` [PATCH 2/6] MdeModulePkg/ConSplitter: ReadKeyStrokeEx always return key state Ruiyu Ni
@ 2018-01-22  8:10 ` Ruiyu Ni
  2018-01-22  8:10 ` [PATCH 4/6] MdeModulePkg/Ps2Kb: " Ruiyu Ni
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 8+ messages in thread
From: Ruiyu Ni @ 2018-01-22  8:10 UTC (permalink / raw)
  To: edk2-devel; +Cc: Star Zeng, Michael D Kinney

Today's implementation only return key state when there is key.
But when user doesn't press any key, the key state cannot be
returned.

The patch changes the ReadKeyStrokeEx() to always return the
key state even there is no key pressed.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Ruiyu Ni <ruiyu.ni@intel.com>
Cc: Star Zeng <star.zeng@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
---
 MdeModulePkg/Bus/Usb/UsbKbDxe/EfiKey.c   |   4 +-
 MdeModulePkg/Bus/Usb/UsbKbDxe/KeyBoard.c | 107 ++++++++++++++++++-------------
 MdeModulePkg/Bus/Usb/UsbKbDxe/KeyBoard.h |  14 +++-
 3 files changed, 77 insertions(+), 48 deletions(-)

diff --git a/MdeModulePkg/Bus/Usb/UsbKbDxe/EfiKey.c b/MdeModulePkg/Bus/Usb/UsbKbDxe/EfiKey.c
index fb2bf3fd81..722350f609 100644
--- a/MdeModulePkg/Bus/Usb/UsbKbDxe/EfiKey.c
+++ b/MdeModulePkg/Bus/Usb/UsbKbDxe/EfiKey.c
@@ -2,7 +2,7 @@
   USB Keyboard Driver that manages USB keyboard and produces Simple Text Input
   Protocol and Simple Text Input Ex Protocol.
 
-Copyright (c) 2004 - 2017, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
 This program and the accompanying materials
 are licensed and made available under the terms and conditions of the BSD License
 which accompanies this distribution.  The full text of the license may be found at
@@ -607,6 +607,8 @@ USBKeyboardReadKeyStrokeWorker (
   }
 
   if (IsQueueEmpty (&UsbKeyboardDevice->EfiKeyQueue)) {
+    ZeroMem (&KeyData->Key, sizeof (KeyData->Key));
+    InitializeKeyState (UsbKeyboardDevice, &KeyData->KeyState);
     return EFI_NOT_READY;
   }
 
diff --git a/MdeModulePkg/Bus/Usb/UsbKbDxe/KeyBoard.c b/MdeModulePkg/Bus/Usb/UsbKbDxe/KeyBoard.c
index 91913d4e54..d140311c52 100644
--- a/MdeModulePkg/Bus/Usb/UsbKbDxe/KeyBoard.c
+++ b/MdeModulePkg/Bus/Usb/UsbKbDxe/KeyBoard.c
@@ -1,7 +1,7 @@
 /** @file
   Helper functions for USB Keyboard Driver.
 
-Copyright (c) 2004 - 2016, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
 This program and the accompanying materials
 are licensed and made available under the terms and conditions of the BSD License
 which accompanies this distribution.  The full text of the license may be found at
@@ -1484,6 +1484,65 @@ USBParseKey (
   return EFI_NOT_READY;
 }
 
+/**
+  Initialize the key state.
+
+  @param  UsbKeyboardDevice     The USB_KB_DEV instance.
+  @param  KeyState              A pointer to receive the key state information.
+**/
+VOID
+InitializeKeyState (
+  IN  USB_KB_DEV           *UsbKeyboardDevice,
+  OUT EFI_KEY_STATE        *KeyState
+  )
+{
+  KeyState->KeyShiftState  = EFI_SHIFT_STATE_VALID;
+  KeyState->KeyToggleState = EFI_TOGGLE_STATE_VALID;
+
+  if (UsbKeyboardDevice->LeftCtrlOn) {
+    KeyState->KeyShiftState |= EFI_LEFT_CONTROL_PRESSED;
+  }
+  if (UsbKeyboardDevice->RightCtrlOn) {
+    KeyState->KeyShiftState |= EFI_RIGHT_CONTROL_PRESSED;
+  }
+  if (UsbKeyboardDevice->LeftAltOn) {
+    KeyState->KeyShiftState |= EFI_LEFT_ALT_PRESSED;
+  }
+  if (UsbKeyboardDevice->RightAltOn) {
+    KeyState->KeyShiftState |= EFI_RIGHT_ALT_PRESSED;
+  }
+  if (UsbKeyboardDevice->LeftShiftOn) {
+    KeyState->KeyShiftState |= EFI_LEFT_SHIFT_PRESSED;
+  }
+  if (UsbKeyboardDevice->RightShiftOn) {
+    KeyState->KeyShiftState |= EFI_RIGHT_SHIFT_PRESSED;
+  }
+  if (UsbKeyboardDevice->LeftLogoOn) {
+    KeyState->KeyShiftState |= EFI_LEFT_LOGO_PRESSED;
+  }
+  if (UsbKeyboardDevice->RightLogoOn) {
+    KeyState->KeyShiftState |= EFI_RIGHT_LOGO_PRESSED;
+  }
+  if (UsbKeyboardDevice->MenuKeyOn) {
+    KeyState->KeyShiftState |= EFI_MENU_KEY_PRESSED;
+  }
+  if (UsbKeyboardDevice->SysReqOn) {
+    KeyState->KeyShiftState |= EFI_SYS_REQ_PRESSED;
+  }
+
+  if (UsbKeyboardDevice->ScrollOn) {
+    KeyState->KeyToggleState |= EFI_SCROLL_LOCK_ACTIVE;
+  }
+  if (UsbKeyboardDevice->NumLockOn) {
+    KeyState->KeyToggleState |= EFI_NUM_LOCK_ACTIVE;
+  }
+  if (UsbKeyboardDevice->CapsOn) {
+    KeyState->KeyToggleState |= EFI_CAPS_LOCK_ACTIVE;
+  }
+  if (UsbKeyboardDevice->IsSupportPartialKey) {
+    KeyState->KeyToggleState |= EFI_KEY_STATE_EXPOSED;
+  }
+}
 
 /**
   Converts USB Keycode ranging from 0x4 to 0x65 to EFI_INPUT_KEY.
@@ -1619,52 +1678,8 @@ UsbKeyCodeToEfiInputKey (
   //
   // Save Shift/Toggle state
   //
-  KeyData->KeyState.KeyShiftState  = EFI_SHIFT_STATE_VALID;
-  KeyData->KeyState.KeyToggleState = EFI_TOGGLE_STATE_VALID;
+  InitializeKeyState (UsbKeyboardDevice, &KeyData->KeyState);
 
-  if (UsbKeyboardDevice->LeftCtrlOn) {
-    KeyData->KeyState.KeyShiftState |= EFI_LEFT_CONTROL_PRESSED;
-  }
-  if (UsbKeyboardDevice->RightCtrlOn) {
-    KeyData->KeyState.KeyShiftState |= EFI_RIGHT_CONTROL_PRESSED;
-  }
-  if (UsbKeyboardDevice->LeftAltOn) {
-    KeyData->KeyState.KeyShiftState |= EFI_LEFT_ALT_PRESSED;
-  }
-  if (UsbKeyboardDevice->RightAltOn) {
-    KeyData->KeyState.KeyShiftState |= EFI_RIGHT_ALT_PRESSED;
-  }
-  if (UsbKeyboardDevice->LeftShiftOn) {
-    KeyData->KeyState.KeyShiftState |= EFI_LEFT_SHIFT_PRESSED;
-  }
-  if (UsbKeyboardDevice->RightShiftOn) {
-    KeyData->KeyState.KeyShiftState |= EFI_RIGHT_SHIFT_PRESSED;
-  }
-  if (UsbKeyboardDevice->LeftLogoOn) {
-    KeyData->KeyState.KeyShiftState |= EFI_LEFT_LOGO_PRESSED;
-  }
-  if (UsbKeyboardDevice->RightLogoOn) {
-    KeyData->KeyState.KeyShiftState |= EFI_RIGHT_LOGO_PRESSED;
-  }
-  if (UsbKeyboardDevice->MenuKeyOn) {
-    KeyData->KeyState.KeyShiftState |= EFI_MENU_KEY_PRESSED;
-  }
-  if (UsbKeyboardDevice->SysReqOn) {
-    KeyData->KeyState.KeyShiftState |= EFI_SYS_REQ_PRESSED;
-  }
-
-  if (UsbKeyboardDevice->ScrollOn) {
-    KeyData->KeyState.KeyToggleState |= EFI_SCROLL_LOCK_ACTIVE;
-  }
-  if (UsbKeyboardDevice->NumLockOn) {
-    KeyData->KeyState.KeyToggleState |= EFI_NUM_LOCK_ACTIVE;
-  }
-  if (UsbKeyboardDevice->CapsOn) {
-    KeyData->KeyState.KeyToggleState |= EFI_CAPS_LOCK_ACTIVE;
-  }
-  if (UsbKeyboardDevice->IsSupportPartialKey) {
-    KeyData->KeyState.KeyToggleState |= EFI_KEY_STATE_EXPOSED;
-  }
   //
   // Signal KeyNotify process event if this key pressed matches any key registered.
   //
diff --git a/MdeModulePkg/Bus/Usb/UsbKbDxe/KeyBoard.h b/MdeModulePkg/Bus/Usb/UsbKbDxe/KeyBoard.h
index b3eb3e462f..87f2132eac 100644
--- a/MdeModulePkg/Bus/Usb/UsbKbDxe/KeyBoard.h
+++ b/MdeModulePkg/Bus/Usb/UsbKbDxe/KeyBoard.h
@@ -1,7 +1,7 @@
 /** @file
   Function prototype for USB Keyboard Driver.
 
-Copyright (c) 2004 - 2013, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
 This program and the accompanying materials
 are licensed and made available under the terms and conditions of the BSD License
 which accompanies this distribution.  The full text of the license may be found at
@@ -317,4 +317,16 @@ SetKeyLED (
   IN  USB_KB_DEV    *UsbKeyboardDevice
   );
 
+/**
+  Initialize the key state.
+
+  @param  UsbKeyboardDevice     The USB_KB_DEV instance.
+  @param  KeyState              A pointer to receive the key state information.
+**/
+VOID
+InitializeKeyState (
+  IN  USB_KB_DEV           *UsbKeyboardDevice,
+  OUT EFI_KEY_STATE        *KeyState
+  );
+
 #endif
-- 
2.15.1.windows.2



^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 4/6] MdeModulePkg/Ps2Kb: ReadKeyStrokeEx always return key state
  2018-01-22  8:10 [PATCH 0/6] ReadKeyStrokeEx always return key state Ruiyu Ni
                   ` (2 preceding siblings ...)
  2018-01-22  8:10 ` [PATCH 3/6] MdeModulePkg/UsbKb: " Ruiyu Ni
@ 2018-01-22  8:10 ` Ruiyu Ni
  2018-01-22  8:10 ` [PATCH 5/6] IntelFrameworkModule/Ps2Kb: " Ruiyu Ni
  2018-01-22  8:10 ` [PATCH 6/6] IntelFrameworkModule/ThunkKb: " Ruiyu Ni
  5 siblings, 0 replies; 8+ messages in thread
From: Ruiyu Ni @ 2018-01-22  8:10 UTC (permalink / raw)
  To: edk2-devel; +Cc: Star Zeng, Michael D Kinney

Today's implementation only return key state when there is key.
But when user doesn't press any key, the key state cannot be
returned.

The patch changes the ReadKeyStrokeEx() to always return the
key state even there is no key pressed.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Ruiyu Ni <ruiyu.ni@intel.com>
Cc: Star Zeng <star.zeng@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
---
 .../Bus/Isa/Ps2KeyboardDxe/Ps2KbdCtrller.c         | 58 ++++++++++++++--------
 MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KbdTextIn.c |  6 ++-
 MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2Keyboard.h  | 14 +++++-
 3 files changed, 54 insertions(+), 24 deletions(-)

diff --git a/MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KbdCtrller.c b/MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KbdCtrller.c
index f92521046f..4def6d9271 100644
--- a/MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KbdCtrller.c
+++ b/MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KbdCtrller.c
@@ -1,7 +1,7 @@
 /** @file
   Routines that access 8042 keyboard controller
 
-Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
 This program and the accompanying materials
 are licensed and made available under the terms and conditions of the BSD License
 which accompanies this distribution.  The full text of the license may be found at
@@ -1104,6 +1104,38 @@ UpdateStatusLights (
   return Status;
 }
 
+/**
+  Initialize the key state.
+
+  @param  ConsoleIn     The KEYBOARD_CONSOLE_IN_DEV instance.
+  @param  KeyState      A pointer to receive the key state information.
+**/
+VOID
+InitializeKeyState (
+  IN  KEYBOARD_CONSOLE_IN_DEV *ConsoleIn,
+  OUT EFI_KEY_STATE           *KeyState
+  )
+{
+  KeyState->KeyShiftState  = EFI_SHIFT_STATE_VALID
+                           | (ConsoleIn->LeftCtrl   ? EFI_LEFT_CONTROL_PRESSED  : 0)
+                           | (ConsoleIn->RightCtrl  ? EFI_RIGHT_CONTROL_PRESSED : 0)
+                           | (ConsoleIn->LeftAlt    ? EFI_LEFT_ALT_PRESSED      : 0)
+                           | (ConsoleIn->RightAlt   ? EFI_RIGHT_ALT_PRESSED     : 0)
+                           | (ConsoleIn->LeftShift  ? EFI_LEFT_SHIFT_PRESSED    : 0)
+                           | (ConsoleIn->RightShift ? EFI_RIGHT_SHIFT_PRESSED   : 0)
+                           | (ConsoleIn->LeftLogo   ? EFI_LEFT_LOGO_PRESSED     : 0)
+                           | (ConsoleIn->RightLogo  ? EFI_RIGHT_LOGO_PRESSED    : 0)
+                           | (ConsoleIn->Menu       ? EFI_MENU_KEY_PRESSED      : 0)
+                           | (ConsoleIn->SysReq     ? EFI_SYS_REQ_PRESSED       : 0)
+                           ;
+  KeyState->KeyToggleState = EFI_TOGGLE_STATE_VALID
+                           | (ConsoleIn->CapsLock   ? EFI_CAPS_LOCK_ACTIVE :   0)
+                           | (ConsoleIn->NumLock    ? EFI_NUM_LOCK_ACTIVE :    0)
+                           | (ConsoleIn->ScrollLock ? EFI_SCROLL_LOCK_ACTIVE : 0)
+                           | (ConsoleIn->IsSupportPartialKey ? EFI_KEY_STATE_EXPOSED : 0)
+                           ;
+}
+
 /**
   Get scancode from scancode buffer and translate into EFI-scancode and unicode defined by EFI spec.
 
@@ -1316,27 +1348,9 @@ KeyGetchar (
   //
   // Save the Shift/Toggle state
   //
-  KeyData.KeyState.KeyShiftState = (UINT32) (EFI_SHIFT_STATE_VALID
-                                 | (ConsoleIn->LeftCtrl   ? EFI_LEFT_CONTROL_PRESSED  : 0)
-                                 | (ConsoleIn->RightCtrl  ? EFI_RIGHT_CONTROL_PRESSED : 0)
-                                 | (ConsoleIn->LeftAlt    ? EFI_LEFT_ALT_PRESSED      : 0)
-                                 | (ConsoleIn->RightAlt   ? EFI_RIGHT_ALT_PRESSED     : 0)
-                                 | (ConsoleIn->LeftShift  ? EFI_LEFT_SHIFT_PRESSED    : 0)
-                                 | (ConsoleIn->RightShift ? EFI_RIGHT_SHIFT_PRESSED   : 0)
-                                 | (ConsoleIn->LeftLogo   ? EFI_LEFT_LOGO_PRESSED     : 0)
-                                 | (ConsoleIn->RightLogo  ? EFI_RIGHT_LOGO_PRESSED    : 0)
-                                 | (ConsoleIn->Menu       ? EFI_MENU_KEY_PRESSED      : 0)
-                                 | (ConsoleIn->SysReq     ? EFI_SYS_REQ_PRESSED       : 0)
-                                 );
-  KeyData.KeyState.KeyToggleState = (EFI_KEY_TOGGLE_STATE) (EFI_TOGGLE_STATE_VALID
-                                  | (ConsoleIn->CapsLock   ? EFI_CAPS_LOCK_ACTIVE :   0)
-                                  | (ConsoleIn->NumLock    ? EFI_NUM_LOCK_ACTIVE :    0)
-                                  | (ConsoleIn->ScrollLock ? EFI_SCROLL_LOCK_ACTIVE : 0)
-                                  | (ConsoleIn->IsSupportPartialKey ? EFI_KEY_STATE_EXPOSED : 0)
-                                  );
-
-  KeyData.Key.ScanCode            = SCAN_NULL;
-  KeyData.Key.UnicodeChar         = CHAR_NULL;
+  InitializeKeyState (ConsoleIn, &KeyData.KeyState);
+  KeyData.Key.ScanCode    = SCAN_NULL;
+  KeyData.Key.UnicodeChar = CHAR_NULL;
 
   //
   // Key Pad "/" shares the same scancode as that of "/" except Key Pad "/" has E0 prefix
diff --git a/MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KbdTextIn.c b/MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KbdTextIn.c
index 04e3365f9e..5986eca5f3 100644
--- a/MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KbdTextIn.c
+++ b/MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KbdTextIn.c
@@ -2,7 +2,7 @@
   Routines implements SIMPLE_TEXT_IN protocol's interfaces based on 8042 interfaces
   provided by Ps2KbdCtrller.c.
 
-Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
 This program and the accompanying materials
 are licensed and made available under the terms and conditions of the BSD License
 which accompanies this distribution.  The full text of the license may be found at
@@ -165,6 +165,10 @@ KeyboardReadKeyStrokeWorker (
     Status = EFI_DEVICE_ERROR;
   } else {
     Status = PopEfikeyBufHead (&ConsoleInDev->EfiKeyQueue, KeyData);
+    if (Status == EFI_NOT_READY) {
+      ZeroMem (&KeyData->Key, sizeof (KeyData->Key));
+      InitializeKeyState (ConsoleInDev, &KeyData->KeyState);
+    }
   }
 
   gBS->RestoreTPL (OldTpl);
diff --git a/MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2Keyboard.h b/MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2Keyboard.h
index d772a979bf..b6a4f3c6b9 100644
--- a/MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2Keyboard.h
+++ b/MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2Keyboard.h
@@ -1,7 +1,7 @@
 /** @file
   PS/2 keyboard driver header file
 
-Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
 This program and the accompanying materials
 are licensed and made available under the terms and conditions of the BSD License
 which accompanies this distribution.  The full text of the license may be found at
@@ -566,4 +566,16 @@ IsKeyRegistered (
   IN EFI_KEY_DATA  *InputData
   );
 
+/**
+  Initialize the key state.
+
+  @param  ConsoleIn     The KEYBOARD_CONSOLE_IN_DEV instance.
+  @param  KeyState      A pointer to receive the key state information.
+**/
+VOID
+InitializeKeyState (
+  IN  KEYBOARD_CONSOLE_IN_DEV *ConsoleIn,
+  OUT EFI_KEY_STATE           *KeyState
+  );
+
 #endif
-- 
2.15.1.windows.2



^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 5/6] IntelFrameworkModule/Ps2Kb: ReadKeyStrokeEx always return key state
  2018-01-22  8:10 [PATCH 0/6] ReadKeyStrokeEx always return key state Ruiyu Ni
                   ` (3 preceding siblings ...)
  2018-01-22  8:10 ` [PATCH 4/6] MdeModulePkg/Ps2Kb: " Ruiyu Ni
@ 2018-01-22  8:10 ` Ruiyu Ni
  2018-01-22  8:10 ` [PATCH 6/6] IntelFrameworkModule/ThunkKb: " Ruiyu Ni
  5 siblings, 0 replies; 8+ messages in thread
From: Ruiyu Ni @ 2018-01-22  8:10 UTC (permalink / raw)
  To: edk2-devel; +Cc: Star Zeng, Michael D Kinney

Today's implementation only return key state when there is a key.
But when user doesn't press any key, the key state cannot be
returned.

The patch changes the ReadKeyStrokeEx() to always return the
key state even there is no key pressed.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Ruiyu Ni <ruiyu.ni@intel.com>
Cc: Star Zeng <star.zeng@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
---
 .../Bus/Isa/Ps2KeyboardDxe/Ps2KbdCtrller.c         | 58 ++++++++++++++--------
 .../Bus/Isa/Ps2KeyboardDxe/Ps2KbdTextIn.c          |  6 ++-
 .../Bus/Isa/Ps2KeyboardDxe/Ps2Keyboard.h           | 14 +++++-
 3 files changed, 54 insertions(+), 24 deletions(-)

diff --git a/IntelFrameworkModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KbdCtrller.c b/IntelFrameworkModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KbdCtrller.c
index b528b89ac4..48d8efd516 100644
--- a/IntelFrameworkModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KbdCtrller.c
+++ b/IntelFrameworkModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KbdCtrller.c
@@ -1,7 +1,7 @@
 /** @file
   Routines that access 8042 keyboard controller
 
-Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
 This program and the accompanying materials
 are licensed and made available under the terms and conditions of the BSD License
 which accompanies this distribution.  The full text of the license may be found at
@@ -1140,6 +1140,38 @@ UpdateStatusLights (
   return Status;
 }
 
+/**
+  Initialize the key state.
+
+  @param  ConsoleIn     The KEYBOARD_CONSOLE_IN_DEV instance.
+  @param  KeyState      A pointer to receive the key state information.
+**/
+VOID
+InitializeKeyState (
+  IN  KEYBOARD_CONSOLE_IN_DEV *ConsoleIn,
+  OUT EFI_KEY_STATE           *KeyState
+  )
+{
+  KeyState->KeyShiftState  = EFI_SHIFT_STATE_VALID
+                           | (ConsoleIn->LeftCtrl   ? EFI_LEFT_CONTROL_PRESSED  : 0)
+                           | (ConsoleIn->RightCtrl  ? EFI_RIGHT_CONTROL_PRESSED : 0)
+                           | (ConsoleIn->LeftAlt    ? EFI_LEFT_ALT_PRESSED      : 0)
+                           | (ConsoleIn->RightAlt   ? EFI_RIGHT_ALT_PRESSED     : 0)
+                           | (ConsoleIn->LeftShift  ? EFI_LEFT_SHIFT_PRESSED    : 0)
+                           | (ConsoleIn->RightShift ? EFI_RIGHT_SHIFT_PRESSED   : 0)
+                           | (ConsoleIn->LeftLogo   ? EFI_LEFT_LOGO_PRESSED     : 0)
+                           | (ConsoleIn->RightLogo  ? EFI_RIGHT_LOGO_PRESSED    : 0)
+                           | (ConsoleIn->Menu       ? EFI_MENU_KEY_PRESSED      : 0)
+                           | (ConsoleIn->SysReq     ? EFI_SYS_REQ_PRESSED       : 0)
+                           ;
+  KeyState->KeyToggleState = EFI_TOGGLE_STATE_VALID
+                           | (ConsoleIn->CapsLock   ? EFI_CAPS_LOCK_ACTIVE :   0)
+                           | (ConsoleIn->NumLock    ? EFI_NUM_LOCK_ACTIVE :    0)
+                           | (ConsoleIn->ScrollLock ? EFI_SCROLL_LOCK_ACTIVE : 0)
+                           | (ConsoleIn->IsSupportPartialKey ? EFI_KEY_STATE_EXPOSED : 0)
+                           ;
+}
+
 /**
   Get scancode from scancode buffer and translate into EFI-scancode and unicode defined by EFI spec.
 
@@ -1352,27 +1384,9 @@ KeyGetchar (
   //
   // Save the Shift/Toggle state
   //
-  KeyData.KeyState.KeyShiftState = (UINT32) (EFI_SHIFT_STATE_VALID
-                                 | (ConsoleIn->LeftCtrl   ? EFI_LEFT_CONTROL_PRESSED  : 0)
-                                 | (ConsoleIn->RightCtrl  ? EFI_RIGHT_CONTROL_PRESSED : 0)
-                                 | (ConsoleIn->LeftAlt    ? EFI_LEFT_ALT_PRESSED      : 0)
-                                 | (ConsoleIn->RightAlt   ? EFI_RIGHT_ALT_PRESSED     : 0)
-                                 | (ConsoleIn->LeftShift  ? EFI_LEFT_SHIFT_PRESSED    : 0)
-                                 | (ConsoleIn->RightShift ? EFI_RIGHT_SHIFT_PRESSED   : 0)
-                                 | (ConsoleIn->LeftLogo   ? EFI_LEFT_LOGO_PRESSED     : 0)
-                                 | (ConsoleIn->RightLogo  ? EFI_RIGHT_LOGO_PRESSED    : 0)
-                                 | (ConsoleIn->Menu       ? EFI_MENU_KEY_PRESSED      : 0)
-                                 | (ConsoleIn->SysReq     ? EFI_SYS_REQ_PRESSED       : 0)
-                                 );
-  KeyData.KeyState.KeyToggleState = (EFI_KEY_TOGGLE_STATE) (EFI_TOGGLE_STATE_VALID
-                                  | (ConsoleIn->CapsLock   ? EFI_CAPS_LOCK_ACTIVE :   0)
-                                  | (ConsoleIn->NumLock    ? EFI_NUM_LOCK_ACTIVE :    0)
-                                  | (ConsoleIn->ScrollLock ? EFI_SCROLL_LOCK_ACTIVE : 0)
-                                  | (ConsoleIn->IsSupportPartialKey ? EFI_KEY_STATE_EXPOSED : 0)
-                                  );
-
-  KeyData.Key.ScanCode            = SCAN_NULL;
-  KeyData.Key.UnicodeChar         = CHAR_NULL;
+  InitializeKeyState (ConsoleIn, &KeyData.KeyState);
+  KeyData.Key.ScanCode    = SCAN_NULL;
+  KeyData.Key.UnicodeChar = CHAR_NULL;
 
   //
   // Key Pad "/" shares the same scancode as that of "/" except Key Pad "/" has E0 prefix
diff --git a/IntelFrameworkModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KbdTextIn.c b/IntelFrameworkModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KbdTextIn.c
index 76779553cd..401b0e8c20 100644
--- a/IntelFrameworkModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KbdTextIn.c
+++ b/IntelFrameworkModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KbdTextIn.c
@@ -2,7 +2,7 @@
   Routines implements SIMPLE_TEXT_IN protocol's interfaces based on 8042 interfaces
   provided by Ps2KbdCtrller.c.
 
-Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
 This program and the accompanying materials
 are licensed and made available under the terms and conditions of the BSD License
 which accompanies this distribution.  The full text of the license may be found at
@@ -165,6 +165,10 @@ KeyboardReadKeyStrokeWorker (
     Status = EFI_DEVICE_ERROR;
   } else {
     Status = PopEfikeyBufHead (&ConsoleInDev->EfiKeyQueue, KeyData);
+    if (Status == EFI_NOT_READY) {
+      ZeroMem (&KeyData->Key, sizeof (KeyData->Key));
+      InitializeKeyState (ConsoleInDev, &KeyData->KeyState);
+    }
   }
 
   gBS->RestoreTPL (OldTpl);
diff --git a/IntelFrameworkModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2Keyboard.h b/IntelFrameworkModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2Keyboard.h
index 76fb498868..613f176401 100644
--- a/IntelFrameworkModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2Keyboard.h
+++ b/IntelFrameworkModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2Keyboard.h
@@ -1,7 +1,7 @@
 /** @file
   PS/2 keyboard driver header file
 
-Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
 This program and the accompanying materials
 are licensed and made available under the terms and conditions of the BSD License
 which accompanies this distribution.  The full text of the license may be found at
@@ -566,4 +566,16 @@ IsKeyRegistered (
   IN EFI_KEY_DATA  *InputData
   );
 
+/**
+  Initialize the key state.
+
+  @param  ConsoleIn     The KEYBOARD_CONSOLE_IN_DEV instance.
+  @param  KeyState      A pointer to receive the key state information.
+**/
+VOID
+InitializeKeyState (
+  IN  KEYBOARD_CONSOLE_IN_DEV *ConsoleIn,
+  OUT EFI_KEY_STATE           *KeyState
+  );
+
 #endif
-- 
2.15.1.windows.2



^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 6/6] IntelFrameworkModule/ThunkKb: ReadKeyStrokeEx always return key state
  2018-01-22  8:10 [PATCH 0/6] ReadKeyStrokeEx always return key state Ruiyu Ni
                   ` (4 preceding siblings ...)
  2018-01-22  8:10 ` [PATCH 5/6] IntelFrameworkModule/Ps2Kb: " Ruiyu Ni
@ 2018-01-22  8:10 ` Ruiyu Ni
  5 siblings, 0 replies; 8+ messages in thread
From: Ruiyu Ni @ 2018-01-22  8:10 UTC (permalink / raw)
  To: edk2-devel; +Cc: Star Zeng, Michael D Kinney

Today's implementation only return key state when there is a key.
But when user doesn't press any key, the key state cannot be
returned.

The patch changes the ReadKeyStrokeEx() to always return the
key state even there is no key pressed.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Ruiyu Ni <ruiyu.ni@intel.com>
Cc: Star Zeng <star.zeng@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
---
 .../Csm/BiosThunk/KeyboardDxe/BiosKeyboard.c               | 14 ++++++++++++--
 .../Csm/BiosThunk/KeyboardDxe/BiosKeyboard.h               |  5 +++--
 2 files changed, 15 insertions(+), 4 deletions(-)

diff --git a/IntelFrameworkModulePkg/Csm/BiosThunk/KeyboardDxe/BiosKeyboard.c b/IntelFrameworkModulePkg/Csm/BiosThunk/KeyboardDxe/BiosKeyboard.c
index ec525891dc..ac8e2364c8 100644
--- a/IntelFrameworkModulePkg/Csm/BiosThunk/KeyboardDxe/BiosKeyboard.c
+++ b/IntelFrameworkModulePkg/Csm/BiosThunk/KeyboardDxe/BiosKeyboard.c
@@ -1,7 +1,7 @@
 /** @file
   ConsoleOut Routines that speak VGA.
 
-Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
 
 This program and the accompanying materials
 are licensed and made available under the terms and conditions
@@ -269,7 +269,9 @@ BiosKeyboardDriverBindingStart (
   BiosKeyboardPrivate->StatusRegisterAddress      = KEYBOARD_8042_STATUS_REGISTER;
   BiosKeyboardPrivate->CommandRegisterAddress     = KEYBOARD_8042_COMMAND_REGISTER;
   BiosKeyboardPrivate->ExtendedKeyboard           = TRUE;
-  
+
+  BiosKeyboardPrivate->KeyState.KeyShiftState     = 0;
+  BiosKeyboardPrivate->KeyState.KeyToggleState    = 0;
   BiosKeyboardPrivate->Queue.Front                = 0;
   BiosKeyboardPrivate->Queue.Rear                 = 0;
   BiosKeyboardPrivate->QueueForNotify.Front       = 0;
@@ -978,6 +980,8 @@ KeyboardReadKeyStrokeWorker (
   //
   Status = CheckQueue (&BiosKeyboardPrivate->Queue);
   if (EFI_ERROR (Status)) {
+    ZeroMem (&KeyData->Key, sizeof (KeyData->Key));
+    CopyMem (&KeyData->KeyState, &BiosKeyboardPrivate->KeyState, sizeof (EFI_KEY_STATE));
     gBS->RestoreTPL (OldTpl);
     return EFI_NOT_READY;
   }
@@ -1986,6 +1990,12 @@ BiosKeyboardTimerHandler (
   }
 
   Enqueue (&BiosKeyboardPrivate->Queue, &KeyData);
+
+  //
+  // Save the current key state
+  //
+  CopyMem (&BiosKeyboardPrivate->KeyState, &KeyData.KeyState, sizeof (EFI_KEY_STATE));
+
   //
   // Leave critical section and return
   //
diff --git a/IntelFrameworkModulePkg/Csm/BiosThunk/KeyboardDxe/BiosKeyboard.h b/IntelFrameworkModulePkg/Csm/BiosThunk/KeyboardDxe/BiosKeyboard.h
index c64ec0095e..5300eaa0ab 100644
--- a/IntelFrameworkModulePkg/Csm/BiosThunk/KeyboardDxe/BiosKeyboard.h
+++ b/IntelFrameworkModulePkg/Csm/BiosThunk/KeyboardDxe/BiosKeyboard.h
@@ -1,6 +1,6 @@
 /** @file
 
-Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
 
 This program and the accompanying materials
 are licensed and made available under the terms and conditions
@@ -220,7 +220,8 @@ typedef struct {
   UINT16                                      StatusRegisterAddress;
   UINT16                                      CommandRegisterAddress;
   BOOLEAN                                     ExtendedKeyboard;
-  
+
+  EFI_KEY_STATE                               KeyState;
   //
   // Buffer storing EFI_KEY_DATA
   //
-- 
2.15.1.windows.2



^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH 2/6] MdeModulePkg/ConSplitter: ReadKeyStrokeEx always return key state
  2018-01-22  8:10 ` [PATCH 2/6] MdeModulePkg/ConSplitter: ReadKeyStrokeEx always return key state Ruiyu Ni
@ 2018-02-01  5:35   ` Zeng, Star
  0 siblings, 0 replies; 8+ messages in thread
From: Zeng, Star @ 2018-02-01  5:35 UTC (permalink / raw)
  To: Ni, Ruiyu, edk2-devel@lists.01.org; +Cc: Kinney, Michael D, Zeng, Star

Hi Ruiyu,

One comment:
ConSplitterTextInPrivateReadKeyStroke() needs filter out partial key from ConSplitterTextInExDequeueKey().

With the comment above handled, Reviewed-by: Star Zeng <star.zeng@intel.com> to this patch series.


Thanks,
Star
-----Original Message-----
From: Ni, Ruiyu 
Sent: Monday, January 22, 2018 4:10 PM
To: edk2-devel@lists.01.org
Cc: Zeng, Star <star.zeng@intel.com>; Kinney, Michael D <michael.d.kinney@intel.com>
Subject: [PATCH 2/6] MdeModulePkg/ConSplitter: ReadKeyStrokeEx always return key state

Today's implementation only return key state when there is key.
But when user doesn't press any key, the key state cannot be
returned.

The patch changes the ReadKeyStrokeEx() to always return the
key state even there is no key pressed.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Ruiyu Ni <ruiyu.ni@intel.com>
Cc: Star Zeng <star.zeng@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
---
 .../Universal/Console/ConSplitterDxe/ConSplitter.c | 164 ++++++++++++++++++---
 .../Universal/Console/ConSplitterDxe/ConSplitter.h |   4 +-
 2 files changed, 143 insertions(+), 25 deletions(-)

diff --git a/MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitter.c b/MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitter.c
index e70ff6114a..022fca7cbb 100644
--- a/MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitter.c
+++ b/MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitter.c
@@ -16,7 +16,7 @@
   never removed. Such design ensures sytem function well during none console
   device situation.
 
-Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
 (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
 This program and the accompanying materials
 are licensed and made available under the terms and conditions of the BSD License
@@ -67,6 +67,8 @@ GLOBAL_REMOVE_IF_UNREFERENCED TEXT_IN_SPLITTER_PRIVATE_DATA  mConIn = {
     (LIST_ENTRY *) NULL,
     (LIST_ENTRY *) NULL
   },
+  (EFI_KEY_DATA *) NULL,
+  0,
   0,
   FALSE,
 
@@ -606,6 +608,7 @@ ConSplitterTextInConstructor (
   )
 {
   EFI_STATUS  Status;
+  UINTN       TextInExListCount;
 
   //
   // Allocate buffer for Simple Text Input device
@@ -631,6 +634,19 @@ ConSplitterTextInConstructor (
                   );
   ASSERT_EFI_ERROR (Status);
 
+  //
+  // Allocate buffer for KeyQueue
+  //
+  TextInExListCount = ConInPrivate->TextInExListCount;
+  Status = ConSplitterGrowBuffer (
+             sizeof (EFI_KEY_DATA),
+             &TextInExListCount,
+             (VOID **) &ConInPrivate->KeyQueue
+             );
+  if (EFI_ERROR (Status)) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
   //
   // Allocate buffer for Simple Text Input Ex device
   //
@@ -1968,6 +1984,17 @@ ConSplitterTextInExAddDevice (
         return EFI_OUT_OF_RESOURCES;
       }
     }
+
+    TextInExListCount = Private->TextInExListCount;
+    Status = ConSplitterGrowBuffer (
+               sizeof (EFI_KEY_DATA),
+               &TextInExListCount,
+               (VOID **) &Private->KeyQueue
+               );
+    if (EFI_ERROR (Status)) {
+      return EFI_OUT_OF_RESOURCES;
+    }
+
     Status = ConSplitterGrowBuffer (
               sizeof (EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *),
               &Private->TextInExListCount,
@@ -3445,11 +3472,46 @@ ConSplitterTextInReset (
 
   if (!EFI_ERROR (ReturnStatus)) {
     ToggleStateSyncReInitialization (Private);
+    //
+    // Empty the key queue.
+    //
+    Private->CurrentNumberOfKeys = 0;
   }
 
   return ReturnStatus;
 }
 
+/**
+  Dequeue the saved key from internal key queue.
+
+  @param  Private                  Protocol instance pointer.
+  @param  KeyData                  A pointer to a buffer that is filled in with the
+                                   keystroke state data for the key that was
+                                   pressed.
+  @retval EFI_NOT_FOUND            Queue is empty.
+  @retval EFI_SUCCESS              First key is dequeued and returned.
+**/
+EFI_STATUS
+ConSplitterTextInExDequeueKey (
+  IN  TEXT_IN_SPLITTER_PRIVATE_DATA   *Private,
+  OUT EFI_KEY_DATA                    *KeyData
+  )
+{
+  if (Private->CurrentNumberOfKeys == 0) {
+    return EFI_NOT_FOUND;
+  }
+  //
+  // Return the first saved key.
+  //
+  CopyMem (KeyData, &Private->KeyQueue[0], sizeof (EFI_KEY_DATA));
+  Private->CurrentNumberOfKeys--;
+  CopyMem (
+    &Private->KeyQueue[0],
+    &Private->KeyQueue[1],
+    Private->CurrentNumberOfKeys * sizeof (EFI_KEY_DATA)
+    );
+  return EFI_SUCCESS;
+}
 
 /**
   Reads the next keystroke from the input device. The WaitForKey Event can
@@ -3473,7 +3535,13 @@ ConSplitterTextInPrivateReadKeyStroke (
 {
   EFI_STATUS    Status;
   UINTN         Index;
-  EFI_INPUT_KEY CurrentKey;
+  EFI_KEY_DATA  KeyData;
+
+  Status = ConSplitterTextInExDequeueKey (Private, &KeyData);
+  if (!EFI_ERROR (Status)) {
+    CopyMem (Key, &KeyData.Key, sizeof (EFI_INPUT_KEY));
+    return Status;
+  }
 
   Key->UnicodeChar  = 0;
   Key->ScanCode     = SCAN_NULL;
@@ -3486,15 +3554,15 @@ ConSplitterTextInPrivateReadKeyStroke (
   for (Index = 0; Index < Private->CurrentNumberOfConsoles;) {
     Status = Private->TextInList[Index]->ReadKeyStroke (
                                           Private->TextInList[Index],
-                                          &CurrentKey
+                                          &KeyData.Key
                                           );
     if (!EFI_ERROR (Status)) {
       //
       // If it is not partial keystorke, return the key. Otherwise, continue
       // to read key from THIS physical console input device.
       //
-      if ((CurrentKey.ScanCode != CHAR_NULL) || (CurrentKey.UnicodeChar != SCAN_NULL)) {
-        *Key = CurrentKey;
+      if ((KeyData.Key.ScanCode != CHAR_NULL) || (KeyData.Key.UnicodeChar != SCAN_NULL)) {
+        CopyMem (Key, &KeyData.Key, sizeof (EFI_INPUT_KEY));
         return Status;
       }
     } else {
@@ -3681,6 +3749,10 @@ ConSplitterTextInResetEx (
 
   if (!EFI_ERROR (ReturnStatus)) {
     ToggleStateSyncReInitialization (Private);
+    //
+    // Empty the key queue.
+    //
+    Private->CurrentNumberOfKeys = 0;
   }
 
   return ReturnStatus;
@@ -3714,6 +3786,7 @@ ConSplitterTextInReadKeyStrokeEx (
   TEXT_IN_SPLITTER_PRIVATE_DATA *Private;
   EFI_STATUS                    Status;
   UINTN                         Index;
+  EFI_KEY_STATE                 KeyState;
   EFI_KEY_DATA                  CurrentKeyData;
 
 
@@ -3725,9 +3798,6 @@ ConSplitterTextInReadKeyStrokeEx (
 
   Private->KeyEventSignalState = FALSE;
 
-  KeyData->Key.UnicodeChar  = 0;
-  KeyData->Key.ScanCode     = SCAN_NULL;
-
   //
   // Signal ConnectConIn event on first call in Lazy ConIn mode
   //
@@ -3738,35 +3808,81 @@ ConSplitterTextInReadKeyStrokeEx (
   }
 
   //
-  // if no physical console input device exists, return EFI_NOT_READY;
-  // if any physical console input device has key input,
-  // return the key and EFI_SUCCESS.
+  // Return the first saved key.
+  //
+  Status = ConSplitterTextInExDequeueKey (Private, KeyData);
+  if (!EFI_ERROR (Status)) {
+    return Status;
+  }
+  ASSERT (Private->CurrentNumberOfKeys == 0);
+
+  ZeroMem (&KeyState, sizeof (KeyState));
+
+  //
+  // Iterate through all physical consoles to get key state.
+  // Some physical consoles may return valid key.
+  // Queue the valid keys.
   //
-  for (Index = 0; Index < Private->CurrentNumberOfExConsoles;) {
+  for (Index = 0; Index < Private->CurrentNumberOfExConsoles; Index++) {
+    ZeroMem (&CurrentKeyData, sizeof (EFI_KEY_DATA));
     Status = Private->TextInExList[Index]->ReadKeyStrokeEx (
-                                          Private->TextInExList[Index],
-                                          &CurrentKeyData
-                                          );
+                                             Private->TextInExList[Index],
+                                             &CurrentKeyData
+                                             );
+    if (EFI_ERROR (Status) && (Status != EFI_NOT_READY)) {
+      continue;
+    }
+
+    //
+    // Consolidate the key state from all physical consoles.
+    //
+    if ((CurrentKeyData.KeyState.KeyShiftState & EFI_SHIFT_STATE_VALID) != 0) {
+      KeyState.KeyShiftState |= CurrentKeyData.KeyState.KeyShiftState;
+    }
+    if ((CurrentKeyData.KeyState.KeyToggleState & EFI_TOGGLE_STATE_VALID) != 0) {
+      KeyState.KeyToggleState |= CurrentKeyData.KeyState.KeyToggleState;
+    }
+
     if (!EFI_ERROR (Status)) {
       //
       // If virtual KeyState has been required to be exposed, or it is not
-      // partial keystorke, return the key. Otherwise, continue to read key
-      // from THIS physical console input device.
+      // partial keystorke, queue the key.
+      // It's possible that user presses at multiple keyboards at the same moment,
+      // Private->KeyQueue[] are the storage to save all the keys.
       //
       if ((Private->VirtualKeyStateExported) ||
           (CurrentKeyData.Key.ScanCode != CHAR_NULL) ||
           (CurrentKeyData.Key.UnicodeChar != SCAN_NULL)) {
-        CopyMem (KeyData, &CurrentKeyData, sizeof (CurrentKeyData));
-        return Status;
+        CopyMem (
+          &Private->KeyQueue[Private->CurrentNumberOfKeys],
+          &CurrentKeyData,
+          sizeof (EFI_KEY_DATA)
+          );
+        Private->CurrentNumberOfKeys++;
       }
-    } else {
-      //
-      // Continue to read key from NEXT physical console input device.
-      //
-      Index++;
     }
   }
 
+  //
+  // Consolidate the key state for all keys in Private->KeyQueue[]
+  //
+  for (Index = 0; Index < Private->CurrentNumberOfKeys; Index++) {
+    CopyMem (&Private->KeyQueue[Index].KeyState, &KeyState, sizeof (EFI_KEY_STATE));
+  }
+  
+  //
+  // Return the first saved key.
+  //
+  Status = ConSplitterTextInExDequeueKey (Private, KeyData);
+  if (!EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // Always return the key state even there is no key pressed.
+  //
+  ZeroMem (&KeyData->Key, sizeof (KeyData->Key));
+  CopyMem (&KeyData->KeyState, &KeyState, sizeof (KeyData->KeyState));
   return EFI_NOT_READY;
 }
 
diff --git a/MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitter.h b/MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitter.h
index 9469860bf0..5fde6b0cb4 100644
--- a/MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitter.h
+++ b/MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitter.h
@@ -1,7 +1,7 @@
 /** @file
   Private data structures for the Console Splitter driver
 
-Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
 This program and the accompanying materials
 are licensed and made available under the terms and conditions of the BSD License
 which accompanies this distribution.  The full text of the license may be found at
@@ -129,6 +129,8 @@ typedef struct {
   EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL  **TextInExList;
   UINTN                              TextInExListCount;
   LIST_ENTRY                         NotifyList;
+  EFI_KEY_DATA                       *KeyQueue;
+  UINTN                              CurrentNumberOfKeys;
   //
   // It will be initialized and synced between console input devices
   // for toggle state sync.
-- 
2.15.1.windows.2



^ permalink raw reply related	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2018-02-01  5:29 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-01-22  8:10 [PATCH 0/6] ReadKeyStrokeEx always return key state Ruiyu Ni
2018-01-22  8:10 ` [PATCH 1/6] MdePkg/SimpleTextInEx.h: Fix comments alignment Ruiyu Ni
2018-01-22  8:10 ` [PATCH 2/6] MdeModulePkg/ConSplitter: ReadKeyStrokeEx always return key state Ruiyu Ni
2018-02-01  5:35   ` Zeng, Star
2018-01-22  8:10 ` [PATCH 3/6] MdeModulePkg/UsbKb: " Ruiyu Ni
2018-01-22  8:10 ` [PATCH 4/6] MdeModulePkg/Ps2Kb: " Ruiyu Ni
2018-01-22  8:10 ` [PATCH 5/6] IntelFrameworkModule/Ps2Kb: " Ruiyu Ni
2018-01-22  8:10 ` [PATCH 6/6] IntelFrameworkModule/ThunkKb: " Ruiyu Ni

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox