]> git.proxmox.com Git - mirror_edk2.git/commitdiff
Update to support EFI_SIMPLE_INPUT_EX protocol
authorqhuang8 <qhuang8@6f19259b-4bc3-4df7-8a09-765794883524>
Fri, 19 Oct 2007 02:36:33 +0000 (02:36 +0000)
committerqhuang8 <qhuang8@6f19259b-4bc3-4df7-8a09-765794883524>
Fri, 19 Oct 2007 02:36:33 +0000 (02:36 +0000)
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@4180 6f19259b-4bc3-4df7-8a09-765794883524

Nt32Pkg/WinNtGopDxe/WinNtGop.h
Nt32Pkg/WinNtGopDxe/WinNtGopDriver.c
Nt32Pkg/WinNtGopDxe/WinNtGopDxe.inf
Nt32Pkg/WinNtGopDxe/WinNtGopInput.c
Nt32Pkg/WinNtGopDxe/WinNtGopScreen.c

index 077e68105d526a082abb4c183c57f1852da52aad..ac4defe11cb6e655fd1808d5a5278b54a5b10de3 100644 (file)
@@ -23,23 +23,40 @@ Abstract:
 #ifndef _WIN_NT_GOP_H_\r
 #define _WIN_NT_GOP_H_\r
 \r
-//@MT:#include "EfiWinNT.h"\r
-//@MT:#include "Tiano.h"\r
-//@MT:#include "EfiDriverLib.h"\r
 \r
-//\r
-// Driver Consumed Protocols\r
-//\r
-//@MT:#include EFI_PROTOCOL_DEFINITION (DevicePath)\r
-//@MT:#include EFI_PROTOCOL_DEFINITION (WinNtIo)\r
+#include <Uefi.h>\r
+#include <WinNtDxe.h>\r
+\r
+#include <Guid/EventGroup.h>\r
+#include <Protocol/WinNtIo.h>\r
+#include <Protocol/ComponentName.h>\r
+#include <Protocol/SimpleTextIn.h>\r
+#include <Protocol/SimpleTextInEx.h>\r
+#include <Protocol/DriverBinding.h>\r
+#include <Protocol/GraphicsOutput.h>\r
+\r
+#include <Library/DebugLib.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/UefiDriverEntryPoint.h>\r
+#include <Library/UefiLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
 \r
 //\r
-// Driver Produced Protocols\r
-//\r
-//@MT:#include EFI_PROTOCOL_DEFINITION (DriverBinding)\r
-//@MT:#include EFI_PROTOCOL_DEFINITION (ComponentName)\r
-//@MT:#include EFI_PROTOCOL_DEFINITION (GraphicsOutput)\r
-//@MT:#include "LinkedList.h"\r
+// WM_SYSKEYDOWN/WM_SYSKEYUP Notification\r
+// lParam\r
+// bit 24: Specifies whether the key is an extended key, \r
+// such as the right-hand ALT and CTRL keys that appear on \r
+// an enhanced 101- or 102-key keyboard. \r
+// The value is 1 if it is an extended key; otherwise, it is 0.\r
+// bit 29:Specifies the context code. \r
+// The value is 1 if the ALT key is down while the key is pressed/released; \r
+// it is 0 if the WM_SYSKEYDOWN message is posted to the active window \r
+// because no window has the keyboard focus.\r
+#define GOP_EXTENDED_KEY         (0x1 << 24)\r
+#define GOP_ALT_KEY_PRESSED      (0x1 << 29)\r
+\r
 \r
 #define MAX_Q 256\r
 \r
@@ -54,6 +71,16 @@ typedef struct {
 \r
 #define GOP_PRIVATE_DATA_SIGNATURE  EFI_SIGNATURE_32 ('S', 'g', 'o', 'N')\r
 \r
+#define WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY_SIGNATURE EFI_SIGNATURE_32 ('W', 'g', 'S', 'n')\r
+\r
+typedef struct _WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY {\r
+  UINTN                                 Signature;\r
+  EFI_HANDLE                            NotifyHandle;\r
+  EFI_KEY_DATA                          KeyData;\r
+  EFI_KEY_NOTIFY_FUNCTION               KeyNotificationFn;\r
+  LIST_ENTRY                            NotifyEntry;\r
+} WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY;\r
+\r
 #define GRAPHICS_OUTPUT_INVALIDE_MODE_NUMBER 0xffff\r
 \r
 typedef struct {\r
@@ -110,6 +137,22 @@ typedef struct {
   CRITICAL_SECTION              QCriticalSection;\r
   GOP_QUEUE_FIXED               Queue;\r
 \r
+  EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL SimpleTextInEx;\r
+  EFI_KEY_STATE                     KeyState;\r
+  LIST_ENTRY                        NotifyList;\r
+  BOOLEAN                           LeftShift;\r
+  BOOLEAN                           RightShift;  \r
+  BOOLEAN                           LeftAlt;\r
+  BOOLEAN                           RightAlt;\r
+  BOOLEAN                           LeftCtrl;\r
+  BOOLEAN                           RightCtrl;\r
+  BOOLEAN                           LeftLogo;\r
+  BOOLEAN                           RightLogo;\r
+  BOOLEAN                           Menu;\r
+  BOOLEAN                           SysReq;  \r
+  BOOLEAN                           NumLock;\r
+  BOOLEAN                           ScrollLock;\r
+  BOOLEAN                           CapsLock;  \r
 } GOP_PRIVATE_DATA;\r
 \r
 #define GOP_PRIVATE_DATA_FROM_THIS(a)  \\r
@@ -118,6 +161,9 @@ typedef struct {
 #define GOP_PRIVATE_DATA_FROM_TEXT_IN_THIS(a)  \\r
          CR(a, GOP_PRIVATE_DATA, SimpleTextIn, GOP_PRIVATE_DATA_SIGNATURE)\r
 \r
+#define GOP_PRIVATE_DATA_FROM_TEXT_IN_EX_THIS(a)  \\r
+         CR(a, GOP_PRIVATE_DATA, SimpleTextInEx, GOP_PRIVATE_DATA_SIGNATURE)\r
+\r
 //\r
 // Global Protocol Variables\r
 //\r
@@ -125,6 +171,8 @@ extern EFI_DRIVER_BINDING_PROTOCOL   gWinNtGopDriverBinding;
 extern EFI_COMPONENT_NAME_PROTOCOL   gWinNtGopComponentName;\r
 extern EFI_COMPONENT_NAME2_PROTOCOL  gWinNtGopComponentName2;\r
 \r
+extern EFI_GUID                      gSimpleTextInExNotifyGuid;\r
+\r
 //\r
 // Gop Hardware abstraction internal worker functions\r
 //\r
index 5f1f2c1cf073f10004d23e5889a2ea75fdb2db3c..ae29da7850b14c823d5bd2c7f653302819722d51 100644 (file)
@@ -21,33 +21,46 @@ Abstract:
 \r
 \r
 **/\r
+#include "WinNtGop.h"\r
 \r
-//\r
-// The package level header files this module uses\r
-//\r
-#include <Uefi.h>\r
-#include <WinNtDxe.h>\r
-//\r
-// The protocols, PPI and GUID defintions for this module\r
-//\r
-#include <Guid/EventGroup.h>\r
-#include <Protocol/WinNtIo.h>\r
-#include <Protocol/ComponentName.h>\r
-#include <Protocol/SimpleTextIn.h>\r
-#include <Protocol/DriverBinding.h>\r
-#include <Protocol/GraphicsOutput.h>\r
-//\r
-// The Library classes this module consumes\r
-//\r
-#include <Library/DebugLib.h>\r
-#include <Library/BaseLib.h>\r
-#include <Library/UefiDriverEntryPoint.h>\r
-#include <Library/UefiLib.h>\r
-#include <Library/BaseMemoryLib.h>\r
-#include <Library/UefiBootServicesTableLib.h>\r
-#include <Library/MemoryAllocationLib.h>\r
+STATIC\r
+EFI_STATUS\r
+FreeNotifyList (\r
+  IN OUT LIST_ENTRY           *ListHead\r
+  )\r
+/*++\r
 \r
-#include "WinNtGop.h"\r
+Routine Description:\r
+\r
+Arguments:\r
+\r
+  ListHead   - The list head\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS           - Free the notify list successfully\r
+  EFI_INVALID_PARAMETER - ListHead is invalid.\r
+\r
+--*/\r
+{\r
+  WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY *NotifyNode;\r
+\r
+  if (ListHead == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+  while (!IsListEmpty (ListHead)) {\r
+    NotifyNode = CR (\r
+                   ListHead->ForwardLink, \r
+                   WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY, \r
+                   NotifyEntry, \r
+                   WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY_SIGNATURE\r
+                   );\r
+    RemoveEntryList (ListHead->ForwardLink);\r
+    gBS->FreePool (NotifyNode);\r
+  }\r
+  \r
+  return EFI_SUCCESS;\r
+}\r
 \r
 EFI_DRIVER_BINDING_PROTOCOL gWinNtGopDriverBinding = {\r
   WinNtGopDriverBindingSupported,\r
@@ -188,6 +201,7 @@ WinNtGopDriverBindingStart (
   Private = NULL;\r
   Private = AllocatePool (sizeof (GOP_PRIVATE_DATA));\r
   if (Private == NULL) {\r
+    Status = EFI_OUT_OF_RESOURCES;\r
     goto Done;\r
   }\r
   //\r
@@ -230,6 +244,8 @@ WinNtGopDriverBindingStart (
                   &Private->GraphicsOutput,\r
                   &gEfiSimpleTextInProtocolGuid,\r
                   &Private->SimpleTextIn,\r
+                  &gEfiSimpleTextInputExProtocolGuid,\r
+                  &Private->SimpleTextInEx,\r
                   NULL\r
                   );\r
 \r
@@ -251,6 +267,13 @@ Done:
         FreeUnicodeStringTable (Private->ControllerNameTable);\r
       }\r
 \r
+      if (Private->SimpleTextIn.WaitForKey != NULL) {\r
+        gBS->CloseEvent (Private->SimpleTextIn.WaitForKey);\r
+      }\r
+      if (Private->SimpleTextInEx.WaitForKeyEx != NULL) {\r
+        gBS->CloseEvent (Private->SimpleTextInEx.WaitForKeyEx);\r
+      }\r
+      FreeNotifyList (&Private->NotifyList);\r
       FreePool (Private);\r
     }\r
   }\r
@@ -313,6 +336,8 @@ WinNtGopDriverBindingStop (
                   &Private->GraphicsOutput,\r
                   &gEfiSimpleTextInProtocolGuid,\r
                   &Private->SimpleTextIn,\r
+                  &gEfiSimpleTextInputExProtocolGuid,\r
+                  &Private->SimpleTextInEx,\r
                   NULL\r
                   );\r
   if (!EFI_ERROR (Status)) {\r
@@ -335,8 +360,13 @@ WinNtGopDriverBindingStop (
     // Free our instance data\r
     //\r
     FreeUnicodeStringTable (Private->ControllerNameTable);\r
+    Status = gBS->CloseEvent (Private->SimpleTextIn.WaitForKey);\r
+    ASSERT_EFI_ERROR (Status);\r
+    Status = gBS->CloseEvent (Private->SimpleTextInEx.WaitForKeyEx);\r
+    ASSERT_EFI_ERROR (Status);\r
+    FreeNotifyList (&Private->NotifyList);\r
 \r
-    FreePool (Private);\r
+    gBS->FreePool (Private);\r
 \r
   }\r
 \r
index 0397e323fdce534ce772e691db40c60ecd17a14f..2b8e4689dad136a0870d51265b7cab509b773d93 100644 (file)
@@ -46,6 +46,7 @@
 \r
 [Packages]\r
   MdePkg/MdePkg.dec\r
+  MdeModulePkg/MdeModulePkg.dec\r
   Nt32Pkg/Nt32Pkg.dec\r
 \r
 \r
 [Guids]\r
   gEfiEventExitBootServicesGuid                 # SOMETIMES_CONSUMED  Create Event: EVENT_GROUP_GUID\r
   gEfiWinNtGopGuid                              # ALWAYS_CONSUMED\r
-\r
+  gSimpleTextInExNotifyGuid                     # ALWAYS_CONSUMED\r
 \r
 [Protocols]\r
   gEfiGraphicsOutputProtocolGuid                # PROTOCOL BY_START\r
   gEfiSimpleTextInProtocolGuid                  # PROTOCOL BY_START\r
+  gEfiSimpleTextInputExProtocolGuid             # PROTOCOL BY_START\r
   gEfiWinNtIoProtocolGuid                       # PROTOCOL TO_START\r
 \r
index a604dad4e5d3c92a068442abf6ef2fa2499c8682..0ea802355d29de52f378951815b2167f72eda1ea 100644 (file)
@@ -28,30 +28,6 @@ Abstract:
 \r
 **/\r
 \r
-//\r
-// The package level header files this module uses\r
-//\r
-#include <Uefi.h>\r
-#include <WinNtDxe.h>\r
-//\r
-// The protocols, PPI and GUID defintions for this module\r
-//\r
-#include <Guid/EventGroup.h>\r
-#include <Protocol/WinNtIo.h>\r
-#include <Protocol/ComponentName.h>\r
-#include <Protocol/SimpleTextIn.h>\r
-#include <Protocol/DriverBinding.h>\r
-#include <Protocol/GraphicsOutput.h>\r
-//\r
-// The Library classes this module consumes\r
-//\r
-#include <Library/DebugLib.h>\r
-#include <Library/BaseLib.h>\r
-#include <Library/UefiDriverEntryPoint.h>\r
-#include <Library/UefiLib.h>\r
-#include <Library/BaseMemoryLib.h>\r
-#include <Library/UefiBootServicesTableLib.h>\r
-#include <Library/MemoryAllocationLib.h>\r
 \r
 #include "WinNtGop.h"\r
 \r
@@ -182,33 +158,149 @@ GopPrivateCheckQ (
   return EFI_SUCCESS;\r
 }\r
 \r
-//\r
-// Simple Text In implementation.\r
-//\r
+STATIC\r
+BOOLEAN\r
+GopPrivateIsKeyRegistered (\r
+  IN EFI_KEY_DATA  *RegsiteredData,\r
+  IN EFI_KEY_DATA  *InputData\r
+  )\r
+/*++\r
 \r
+Routine Description:\r
 \r
-/**\r
-  TODO: Add function description\r
+Arguments:\r
 \r
-  @param  This                  TODO: add argument description\r
-  @param  ExtendedVerification  TODO: add argument description\r
+  RegsiteredData    - A pointer to a buffer that is filled in with the keystroke \r
+                      state data for the key that was registered.\r
+  InputData         - A pointer to a buffer that is filled in with the keystroke \r
+                      state data for the key that was pressed.\r
 \r
-  @retval EFI_SUCCESS           TODO: Add description for return value\r
+Returns:\r
+  TRUE              - Key be pressed matches a registered key.\r
+  FLASE             - Match failed. \r
+  \r
+--*/\r
+{\r
+  ASSERT (RegsiteredData != NULL && InputData != NULL);\r
+  \r
+  if ((RegsiteredData->Key.ScanCode    != InputData->Key.ScanCode) ||\r
+      (RegsiteredData->Key.UnicodeChar != InputData->Key.UnicodeChar)) {\r
+    return FALSE;  \r
+  }      \r
+  \r
+  //\r
+  // Assume KeyShiftState/KeyToggleState = 0 in Registered key data means these state could be ignored.\r
+  //\r
+  if (RegsiteredData->KeyState.KeyShiftState != 0 &&\r
+      RegsiteredData->KeyState.KeyShiftState != InputData->KeyState.KeyShiftState) {\r
+    return FALSE;    \r
+  }   \r
+  if (RegsiteredData->KeyState.KeyToggleState != 0 &&\r
+      RegsiteredData->KeyState.KeyToggleState != InputData->KeyState.KeyToggleState) {\r
+    return FALSE;    \r
+  }     \r
+  \r
+  return TRUE;\r
 \r
-**/\r
+}\r
+\r
+\r
+STATIC\r
+VOID\r
+GopPrivateInvokeRegisteredFunction (\r
+  IN GOP_PRIVATE_DATA                     *Private,\r
+  IN EFI_KEY_DATA                         *KeyData\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  This function updates the status light of NumLock, ScrollLock and CapsLock.\r
+\r
+Arguments:\r
+\r
+  Private       - The private structure of WinNt Gop device.\r
+  KeyData       - A pointer to a buffer that is filled in with the keystroke \r
+                  state data for the key that was pressed.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS   - The status light is updated successfully.\r
+\r
+--*/  \r
+{ \r
+  LIST_ENTRY                          *Link;\r
+  WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY  *CurrentNotify;\r
+  \r
+  for (Link = Private->NotifyList.ForwardLink; Link != &Private->NotifyList; Link = Link->ForwardLink) {\r
+    CurrentNotify = CR (\r
+                      Link, \r
+                      WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY, \r
+                      NotifyEntry, \r
+                      WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY_SIGNATURE\r
+                      );\r
+    if (GopPrivateIsKeyRegistered (&CurrentNotify->KeyData, KeyData)) { \r
+      CurrentNotify->KeyNotificationFn (KeyData);\r
+    }\r
+  }    \r
+}\r
+\r
+STATIC\r
 EFI_STATUS\r
-EFIAPI\r
-WinNtGopSimpleTextInReset (\r
-  IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL          *This,\r
-  IN BOOLEAN                              ExtendedVerification\r
+GopPrivateUpdateStatusLight (\r
+  IN GOP_PRIVATE_DATA                     *Private\r
   )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  This function updates the status light of NumLock, ScrollLock and CapsLock.\r
+\r
+Arguments:\r
+\r
+  Private       - The private structure of WinNt console In/Out.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS   - The status light is updated successfully.\r
+\r
+--*/  \r
+{ \r
+  //\r
+  // BUGBUG:Only SendInput/keybd_event function can toggle \r
+  // NumLock, CapsLock and ScrollLock keys.\r
+  // Neither of these functions is included in EFI_WIN_NT_THUNK_PROTOCOL.\r
+  // Thus, return immediately without operation.\r
+  //\r
+  return EFI_SUCCESS;\r
+  \r
+}\r
+\r
+\r
+STATIC\r
+EFI_STATUS\r
+GopPrivateResetWorker (\r
+  IN GOP_PRIVATE_DATA                     *Private\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  This function is a worker function for SimpleTextIn/SimpleTextInEx.Reset().\r
+\r
+Arguments:\r
+\r
+  Private     - WinNT GOP private structure\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS - Reset successfully\r
+\r
+--*/\r
 {\r
-  GOP_PRIVATE_DATA  *Private;\r
   EFI_INPUT_KEY     Key;\r
   EFI_TPL           OldTpl;\r
 \r
-  Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_THIS (This);\r
-\r
   //\r
   // Enter critical section\r
   //\r
@@ -220,36 +312,64 @@ WinNtGopSimpleTextInReset (
   while (GopPrivateDeleteQ (Private, &Key) == EFI_SUCCESS)\r
     ;\r
 \r
+  Private->LeftShift               = FALSE;\r
+  Private->RightShift              = FALSE;\r
+  Private->LeftAlt                 = FALSE;\r
+  Private->RightAlt                = FALSE;\r
+  Private->LeftCtrl                = FALSE;\r
+  Private->RightCtrl               = FALSE;\r
+  Private->LeftLogo                = FALSE;\r
+  Private->RightLogo               = FALSE;\r
+  Private->Menu                    = FALSE;\r
+  Private->SysReq                  = FALSE;\r
+  \r
+  Private->CapsLock                = FALSE;\r
+  Private->NumLock                 = FALSE;\r
+  Private->ScrollLock              = FALSE;\r
+  \r
+  Private->KeyState.KeyShiftState  = EFI_SHIFT_STATE_VALID;\r
+  Private->KeyState.KeyToggleState = EFI_TOGGLE_STATE_VALID;\r
+\r
   //\r
   // Leave critical section and return\r
   //\r
   gBS->RestoreTPL (OldTpl);\r
+\r
   return EFI_SUCCESS;\r
 }\r
 \r
+STATIC\r
+EFI_STATUS\r
+GopPrivateReadKeyStrokeWorker (\r
+  IN GOP_PRIVATE_DATA                   *Private,\r
+  OUT EFI_KEY_DATA                      *KeyData\r
+  )\r
+/*++\r
 \r
-/**\r
-  TODO: Add function description\r
+  Routine Description:\r
+    Reads the next keystroke from the input device. The WaitForKey Event can \r
+    be used to test for existance of a keystroke via WaitForEvent () call.\r
 \r
-  @param  This                  TODO: add argument description\r
-  @param  Key                   TODO: add argument description\r
+  Arguments:\r
+    Private    - The private structure of WinNt Gop device.\r
+    KeyData    - A pointer to a buffer that is filled in with the keystroke \r
+                 state data for the key that was pressed.\r
 \r
-  @return TODO: add return values\r
+  Returns:\r
+    EFI_SUCCESS           - The keystroke information was returned.\r
+    EFI_NOT_READY         - There was no keystroke data availiable.\r
+    EFI_DEVICE_ERROR      - The keystroke information was not returned due to \r
+                            hardware errors.\r
+    EFI_INVALID_PARAMETER - KeyData is NULL.                        \r
 \r
-**/\r
-STATIC\r
-EFI_STATUS\r
-EFIAPI\r
-WinNtGopSimpleTextInReadKeyStroke (\r
-  IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL          *This,\r
-  OUT EFI_INPUT_KEY                       *Key\r
-  )\r
+--*/\r
 {\r
-  GOP_PRIVATE_DATA  *Private;\r
-  EFI_STATUS        Status;\r
-  EFI_TPL           OldTpl;\r
+  EFI_STATUS                      Status;\r
+  EFI_TPL                         OldTpl;  \r
 \r
-  Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_THIS (This);\r
+  if (KeyData == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
 \r
   //\r
   // Enter critical section\r
@@ -261,7 +381,66 @@ WinNtGopSimpleTextInReadKeyStroke (
     //\r
     // If a Key press exists try and read it.\r
     //\r
-    Status = GopPrivateDeleteQ (Private, Key);\r
+    Status = GopPrivateDeleteQ (Private, &KeyData->Key);\r
+    if (!EFI_ERROR (Status)) {\r
+      //\r
+      // Record Key shift state and toggle state\r
+      //      \r
+      if (Private->LeftCtrl) {\r
+        Private->KeyState.KeyShiftState  |= EFI_LEFT_CONTROL_PRESSED;\r
+      }                                    \r
+      if (Private->RightCtrl) {\r
+        Private->KeyState.KeyShiftState  |= EFI_RIGHT_CONTROL_PRESSED;\r
+      }                                    \r
+      if (Private->LeftAlt) {                \r
+        Private->KeyState.KeyShiftState  |= EFI_LEFT_ALT_PRESSED;\r
+      }                                    \r
+      if (Private->RightAlt) {                \r
+        Private->KeyState.KeyShiftState  |= EFI_RIGHT_ALT_PRESSED;\r
+      }                                      \r
+      if (Private->LeftShift) {          \r
+        Private->KeyState.KeyShiftState  |= EFI_LEFT_SHIFT_PRESSED;\r
+      }                                    \r
+      if (Private->RightShift) {         \r
+        Private->KeyState.KeyShiftState  |= EFI_RIGHT_SHIFT_PRESSED;\r
+      }                                    \r
+      if (Private->LeftLogo) {           \r
+        Private->KeyState.KeyShiftState  |= EFI_LEFT_LOGO_PRESSED;\r
+      }                                    \r
+      if (Private->RightLogo) {          \r
+        Private->KeyState.KeyShiftState  |= EFI_RIGHT_LOGO_PRESSED;\r
+      }                                    \r
+      if (Private->Menu) {               \r
+        Private->KeyState.KeyShiftState  |= EFI_MENU_KEY_PRESSED;\r
+      }                                    \r
+      if (Private->SysReq) {             \r
+        Private->KeyState.KeyShiftState  |= EFI_SYS_REQ_PRESSED;\r
+      }  \r
+      if (Private->CapsLock) {\r
+        Private->KeyState.KeyToggleState |= EFI_CAPS_LOCK_ACTIVE;\r
+      }\r
+      if (Private->NumLock) {\r
+        Private->KeyState.KeyToggleState |= EFI_NUM_LOCK_ACTIVE;\r
+      }\r
+      if (Private->ScrollLock) {\r
+        Private->KeyState.KeyToggleState |= EFI_SCROLL_LOCK_ACTIVE;\r
+      }\r
+      \r
+      KeyData->KeyState.KeyShiftState  = Private->KeyState.KeyShiftState;\r
+      KeyData->KeyState.KeyToggleState = Private->KeyState.KeyToggleState;\r
+      \r
+      Private->KeyState.KeyShiftState  = EFI_SHIFT_STATE_VALID;\r
+      Private->KeyState.KeyToggleState = EFI_TOGGLE_STATE_VALID;\r
+  \r
+      //\r
+      // Leave critical section and return\r
+      //\r
+      gBS->RestoreTPL (OldTpl);\r
+      \r
+      GopPrivateInvokeRegisteredFunction (Private, KeyData);\r
+      \r
+      return EFI_SUCCESS;\r
+    }\r
   }\r
 \r
   //\r
@@ -270,6 +449,70 @@ WinNtGopSimpleTextInReadKeyStroke (
   gBS->RestoreTPL (OldTpl);\r
 \r
   return Status;\r
+\r
+}\r
+\r
+\r
+//\r
+// Simple Text In implementation.\r
+//\r
+\r
+\r
+/**\r
+  TODO: Add function description\r
+\r
+  @param  This                  TODO: add argument description\r
+  @param  ExtendedVerification  TODO: add argument description\r
+\r
+  @retval EFI_SUCCESS           TODO: Add description for return value\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+WinNtGopSimpleTextInReset (\r
+  IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL          *This,\r
+  IN BOOLEAN                              ExtendedVerification\r
+  )\r
+{\r
+  GOP_PRIVATE_DATA  *Private;\r
+\r
+  Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_THIS (This);\r
+\r
+  return GopPrivateResetWorker (Private);\r
+}\r
+\r
+\r
+/**\r
+  TODO: Add function description\r
+\r
+  @param  This                  TODO: add argument description\r
+  @param  Key                   TODO: add argument description\r
+\r
+  @return TODO: add return values\r
+\r
+**/\r
+STATIC\r
+EFI_STATUS\r
+EFIAPI\r
+WinNtGopSimpleTextInReadKeyStroke (\r
+  IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL          *This,\r
+  OUT EFI_INPUT_KEY                       *Key\r
+  )\r
+{\r
+  GOP_PRIVATE_DATA  *Private;\r
+  EFI_STATUS        Status;\r
+  EFI_KEY_DATA      KeyData;\r
+\r
+  Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_THIS (This);\r
+\r
+  Status = GopPrivateReadKeyStrokeWorker (Private, &KeyData);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  CopyMem (Key, &KeyData.Key, sizeof (EFI_INPUT_KEY));\r
+  \r
+  return EFI_SUCCESS;  \r
 }\r
 \r
 \r
@@ -323,6 +566,302 @@ WinNtGopSimpleTextInWaitForKey (
   gBS->RestoreTPL (OldTpl);\r
 }\r
 \r
+//\r
+// Simple Text Input Ex protocol functions\r
+//\r
+\r
+STATIC\r
+EFI_STATUS\r
+EFIAPI\r
+WinNtGopSimpleTextInExResetEx (\r
+  IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL  *This,\r
+  IN BOOLEAN                            ExtendedVerification\r
+  )\r
+/*++\r
+\r
+  Routine Description:\r
+    Reset the input device and optionaly run diagnostics\r
+\r
+  Arguments:\r
+    This                 - Protocol instance pointer.\r
+    ExtendedVerification - Driver may perform diagnostics on reset.\r
+\r
+  Returns:\r
+    EFI_SUCCESS           - The device was reset.\r
+\r
+--*/\r
+{\r
+  GOP_PRIVATE_DATA *Private;\r
+\r
+  Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_EX_THIS (This);\r
+  \r
+  return GopPrivateResetWorker (Private);\r
+}\r
+\r
+STATIC\r
+EFI_STATUS\r
+EFIAPI\r
+WinNtGopSimpleTextInExReadKeyStrokeEx (\r
+  IN  EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,\r
+  OUT EFI_KEY_DATA                      *KeyData\r
+  )\r
+/*++\r
+\r
+  Routine Description:\r
+    Reads the next keystroke from the input device. The WaitForKey Event can \r
+    be used to test for existance of a keystroke via WaitForEvent () call.\r
+\r
+  Arguments:\r
+    This       - Protocol instance pointer.\r
+    KeyData    - A pointer to a buffer that is filled in with the keystroke \r
+                 state data for the key that was pressed.\r
+\r
+  Returns:\r
+    EFI_SUCCESS           - The keystroke information was returned.\r
+    EFI_NOT_READY         - There was no keystroke data availiable.\r
+    EFI_DEVICE_ERROR      - The keystroke information was not returned due to \r
+                            hardware errors.\r
+    EFI_INVALID_PARAMETER - KeyData is NULL.                        \r
+\r
+--*/\r
+{\r
+  GOP_PRIVATE_DATA *Private;\r
+\r
+  if (KeyData == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_EX_THIS (This);\r
+  \r
+  return GopPrivateReadKeyStrokeWorker (Private, KeyData);\r
+\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+WinNtGopSimpleTextInExSetState (\r
+  IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL  *This,\r
+  IN EFI_KEY_TOGGLE_STATE               *KeyToggleState\r
+  )\r
+/*++\r
+\r
+  Routine Description:\r
+    Set certain state for the input device.\r
+\r
+  Arguments:\r
+    This                  - Protocol instance pointer.\r
+    KeyToggleState        - A pointer to the EFI_KEY_TOGGLE_STATE to set the \r
+                            state for the input device.\r
+                          \r
+  Returns:                \r
+    EFI_SUCCESS           - The device state was set successfully.\r
+    EFI_DEVICE_ERROR      - The device is not functioning correctly and could \r
+                            not have the setting adjusted.\r
+    EFI_UNSUPPORTED       - The device does not have the ability to set its state.\r
+    EFI_INVALID_PARAMETER - KeyToggleState is NULL.                       \r
+\r
+--*/   \r
+{\r
+  EFI_STATUS                      Status;\r
+  GOP_PRIVATE_DATA                *Private;\r
+\r
+  if (KeyToggleState == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_EX_THIS (This);\r
+\r
+  if (((Private->KeyState.KeyToggleState & EFI_TOGGLE_STATE_VALID) != EFI_TOGGLE_STATE_VALID) ||\r
+      ((*KeyToggleState & EFI_TOGGLE_STATE_VALID) != EFI_TOGGLE_STATE_VALID)) {\r
+    return EFI_UNSUPPORTED;  \r
+  }\r
+\r
+  Private->ScrollLock = FALSE;\r
+  Private->NumLock    = FALSE;\r
+  Private->CapsLock   = FALSE;\r
+\r
+  if ((*KeyToggleState & EFI_SCROLL_LOCK_ACTIVE) == EFI_SCROLL_LOCK_ACTIVE) {\r
+    Private->ScrollLock = TRUE;\r
+  } \r
+  if ((*KeyToggleState & EFI_NUM_LOCK_ACTIVE) == EFI_NUM_LOCK_ACTIVE) {\r
+    Private->NumLock = TRUE;\r
+  }\r
+  if ((*KeyToggleState & EFI_CAPS_LOCK_ACTIVE) == EFI_CAPS_LOCK_ACTIVE) {\r
+    Private->CapsLock = TRUE;\r
+  }\r
+\r
+  Status = GopPrivateUpdateStatusLight (Private);  \r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+\r
+  Private->KeyState.KeyToggleState = *KeyToggleState;\r
+  return EFI_SUCCESS;\r
+  \r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+WinNtGopSimpleTextInExRegisterKeyNotify (\r
+  IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL  *This,\r
+  IN EFI_KEY_DATA                       *KeyData,\r
+  IN EFI_KEY_NOTIFY_FUNCTION            KeyNotificationFunction,\r
+  OUT EFI_HANDLE                        *NotifyHandle\r
+  )\r
+/*++\r
+\r
+  Routine Description:\r
+    Register a notification function for a particular keystroke for the input device.\r
+\r
+  Arguments:\r
+    This                    - Protocol instance pointer.\r
+    KeyData                 - A pointer to a buffer that is filled in with the keystroke \r
+                              information data for the key that was pressed.\r
+    KeyNotificationFunction - Points to the function to be called when the key \r
+                              sequence is typed specified by KeyData.                        \r
+    NotifyHandle            - Points to the unique handle assigned to the registered notification.                          \r
+\r
+  Returns:\r
+    EFI_SUCCESS             - The notification function was registered successfully.\r
+    EFI_OUT_OF_RESOURCES    - Unable to allocate resources for necesssary data structures.\r
+    EFI_INVALID_PARAMETER   - KeyData or NotifyHandle is NULL.                       \r
+                              \r
+--*/   \r
+{\r
+  EFI_STATUS                         Status;\r
+  GOP_PRIVATE_DATA                   *Private;\r
+  WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY *CurrentNotify;\r
+  LIST_ENTRY                         *Link;\r
+  WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY *NewNotify;      \r
+\r
+  if (KeyData == NULL || NotifyHandle == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }  \r
+\r
+  Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_EX_THIS (This);\r
+\r
+  //\r
+  // Return EFI_SUCCESS if the (KeyData, NotificationFunction) is already registered.\r
+  //\r
+  for (Link = Private->NotifyList.ForwardLink; Link != &Private->NotifyList; Link = Link->ForwardLink) {\r
+    CurrentNotify = CR (\r
+                      Link, \r
+                      WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY, \r
+                      NotifyEntry, \r
+                      WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY_SIGNATURE\r
+                      );\r
+    if (GopPrivateIsKeyRegistered (&CurrentNotify->KeyData, KeyData)) { \r
+      if (CurrentNotify->KeyNotificationFn == KeyNotificationFunction) {\r
+        *NotifyHandle = CurrentNotify->NotifyHandle;\r
+        return EFI_SUCCESS;\r
+      }\r
+    }\r
+  }    \r
+  \r
+  //\r
+  // Allocate resource to save the notification function\r
+  //  \r
+  NewNotify = (WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY *) AllocateZeroPool (sizeof (WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY));\r
+  if (NewNotify == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  NewNotify->Signature         = WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY_SIGNATURE;     \r
+  NewNotify->KeyNotificationFn = KeyNotificationFunction;\r
+  CopyMem (&NewNotify->KeyData, KeyData, sizeof (KeyData));\r
+  InsertTailList (&Private->NotifyList, &NewNotify->NotifyEntry);\r
+\r
+  //\r
+  // Use gSimpleTextInExNotifyGuid to get a valid EFI_HANDLE\r
+  //  \r
+  Status = gBS->InstallMultipleProtocolInterfaces (\r
+                  &NewNotify->NotifyHandle,\r
+                  &gSimpleTextInExNotifyGuid,\r
+                  NULL,\r
+                  NULL\r
+                  );\r
+  ASSERT_EFI_ERROR (Status);\r
+  \r
+  *NotifyHandle = NewNotify->NotifyHandle;  \r
+  \r
+  return EFI_SUCCESS;\r
+  \r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+WinNtGopSimpleTextInExUnregisterKeyNotify (\r
+  IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL  *This,\r
+  IN EFI_HANDLE                         NotificationHandle\r
+  )\r
+/*++\r
+\r
+  Routine Description:\r
+    Remove a registered notification function from a particular keystroke.\r
+\r
+  Arguments:\r
+    This                    - Protocol instance pointer.    \r
+    NotificationHandle      - The handle of the notification function being unregistered.\r
+\r
+  Returns:\r
+    EFI_SUCCESS             - The notification function was unregistered successfully.\r
+    EFI_INVALID_PARAMETER   - The NotificationHandle is invalid.\r
+    EFI_NOT_FOUND           - Can not find the matching entry in database.  \r
+                              \r
+--*/   \r
+{\r
+  EFI_STATUS                         Status;\r
+  GOP_PRIVATE_DATA                   *Private;\r
+  LIST_ENTRY                         *Link;\r
+  WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY *CurrentNotify;\r
+\r
+  if (NotificationHandle == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  } \r
+  \r
+  Status = gBS->OpenProtocol (\r
+                  NotificationHandle,\r
+                  &gSimpleTextInExNotifyGuid,\r
+                  NULL,\r
+                  NULL,\r
+                  NULL,\r
+                  EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_EX_THIS (This);\r
+\r
+  for (Link = Private->NotifyList.ForwardLink; Link != &Private->NotifyList; Link = Link->ForwardLink) {\r
+    CurrentNotify = CR (\r
+                      Link, \r
+                      WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY, \r
+                      NotifyEntry, \r
+                      WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY_SIGNATURE\r
+                      );       \r
+    if (CurrentNotify->NotifyHandle == NotificationHandle) {\r
+      //\r
+      // Remove the notification function from NotifyList and free resources\r
+      //\r
+      RemoveEntryList (&CurrentNotify->NotifyEntry);      \r
+      Status = gBS->UninstallMultipleProtocolInterfaces (\r
+                      CurrentNotify->NotifyHandle,\r
+                      &gSimpleTextInExNotifyGuid,\r
+                      NULL,\r
+                      NULL\r
+                      );\r
+      ASSERT_EFI_ERROR (Status);\r
+      gBS->FreePool (CurrentNotify);            \r
+      return EFI_SUCCESS;\r
+    }\r
+  }\r
+\r
+  //\r
+  // Can not find the specified Notification Handle\r
+  //\r
+  return EFI_NOT_FOUND;\r
+}\r
 \r
 /**\r
   TODO: Add function description\r
@@ -355,10 +894,32 @@ WinNtGopInitializeSimpleTextInForWindow (
                   &Private->SimpleTextIn.WaitForKey\r
                   );\r
 \r
+  \r
+  Private->SimpleTextInEx.Reset               = WinNtGopSimpleTextInExResetEx;\r
+  Private->SimpleTextInEx.ReadKeyStrokeEx     = WinNtGopSimpleTextInExReadKeyStrokeEx;\r
+  Private->SimpleTextInEx.SetState            = WinNtGopSimpleTextInExSetState;\r
+  Private->SimpleTextInEx.RegisterKeyNotify   = WinNtGopSimpleTextInExRegisterKeyNotify;\r
+  Private->SimpleTextInEx.UnregisterKeyNotify = WinNtGopSimpleTextInExUnregisterKeyNotify;\r
+\r
+  Private->SimpleTextInEx.Reset (&Private->SimpleTextInEx, FALSE);\r
+  \r
+  InitializeListHead (&Private->NotifyList);\r
+\r
+  Status = gBS->CreateEvent (\r
+                  EVT_NOTIFY_WAIT,\r
+                  TPL_NOTIFY,\r
+                  WinNtGopSimpleTextInWaitForKey,\r
+                  Private,\r
+                  &Private->SimpleTextInEx.WaitForKeyEx\r
+                  );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+\r
   return Status;\r
 }\r
 \r
 \r
+\r
 /**\r
   TODO: Add function description\r
 \r
index e0270712288a51030739a503fa683583a10dd324..58ddb1c6568e7d4cdc30f498d4d4ab76bb02450a 100644 (file)
@@ -21,30 +21,6 @@ Abstract:
 \r
 \r
 **/\r
-//\r
-// The package level header files this module uses\r
-//\r
-#include <Uefi.h>\r
-#include <WinNtDxe.h>\r
-//\r
-// The protocols, PPI and GUID defintions for this module\r
-//\r
-#include <Guid/EventGroup.h>\r
-#include <Protocol/WinNtIo.h>\r
-#include <Protocol/ComponentName.h>\r
-#include <Protocol/SimpleTextIn.h>\r
-#include <Protocol/DriverBinding.h>\r
-#include <Protocol/GraphicsOutput.h>\r
-//\r
-// The Library classes this module consumes\r
-//\r
-#include <Library/DebugLib.h>\r
-#include <Library/BaseLib.h>\r
-#include <Library/UefiDriverEntryPoint.h>\r
-#include <Library/UefiLib.h>\r
-#include <Library/BaseMemoryLib.h>\r
-#include <Library/UefiBootServicesTableLib.h>\r
-#include <Library/MemoryAllocationLib.h>\r
 \r
 #include "WinNtGop.h"\r
 \r
@@ -77,6 +53,110 @@ KillNtGopThread (
   IN VOID       *Context\r
   );\r
 \r
+STATIC\r
+VOID\r
+WinNtGopConvertParamToEfiKeyShiftState (\r
+  IN  GOP_PRIVATE_DATA  *Private,\r
+  IN  WPARAM            *wParam,\r
+  IN  BOOLEAN           Flag\r
+  )\r
+{\r
+  switch (*wParam) {\r
+  //\r
+  // BUGBUG: Only GetAsyncKeyState() and GetKeyState() can distinguish\r
+  // left and right Ctrl, and Shift key. \r
+  // Neither of the two is defined in EFI_WIN_NT_THUNK_PROTOCOL. \r
+  // Therefor, we can not set the correct Shift state here.\r
+  // \r
+  case VK_SHIFT:  \r
+    Private->LeftShift  = Flag;\r
+    break;  \r
+  case VK_CONTROL:\r
+    Private->LeftCtrl   = Flag;\r
+    break;\r
+  case VK_LWIN:      \r
+    Private->LeftLogo   = Flag;\r
+    break;\r
+  case VK_RWIN:      \r
+    Private->RightLogo  = Flag;\r
+    break;\r
+  case VK_APPS:      \r
+    Private->Menu       = Flag;\r
+    break;\r
+  //\r
+  // BUGBUG: PrintScreen/SysRq can not trigger WM_KEYDOWN message,\r
+  // so SySReq shift state is not supported here.\r
+  //\r
+  case VK_PRINT:  \r
+    Private->SysReq     = Flag;\r
+    break;\r
+  }\r
+}\r
+\r
+STATIC\r
+VOID\r
+WinNtGopConvertParamToEfiKey (\r
+  IN  GOP_PRIVATE_DATA  *Private,\r
+  IN  WPARAM            *wParam,\r
+  IN  EFI_INPUT_KEY     *Key\r
+  )\r
+{\r
+  switch (*wParam) {\r
+  case VK_HOME:       Key->ScanCode = SCAN_HOME;       break;\r
+  case VK_END:        Key->ScanCode = SCAN_END;        break;\r
+  case VK_LEFT:       Key->ScanCode = SCAN_LEFT;       break;\r
+  case VK_RIGHT:      Key->ScanCode = SCAN_RIGHT;      break;\r
+  case VK_UP:         Key->ScanCode = SCAN_UP;         break;\r
+  case VK_DOWN:       Key->ScanCode = SCAN_DOWN;       break;\r
+  case VK_DELETE:     Key->ScanCode = SCAN_DELETE;     break;\r
+  case VK_INSERT:     Key->ScanCode = SCAN_INSERT;     break;\r
+  case VK_PRIOR:      Key->ScanCode = SCAN_PAGE_UP;    break;\r
+  case VK_NEXT:       Key->ScanCode = SCAN_PAGE_DOWN;  break;\r
+  case VK_ESCAPE:     Key->ScanCode = SCAN_ESC;        break;\r
+                         \r
+  case VK_F1:         Key->ScanCode = SCAN_F1;         break;\r
+  case VK_F2:         Key->ScanCode = SCAN_F2;         break;\r
+  case VK_F3:         Key->ScanCode = SCAN_F3;         break;\r
+  case VK_F4:         Key->ScanCode = SCAN_F4;         break;\r
+  case VK_F5:         Key->ScanCode = SCAN_F5;         break;\r
+  case VK_F6:         Key->ScanCode = SCAN_F6;         break;\r
+  case VK_F7:         Key->ScanCode = SCAN_F7;         break;\r
+  case VK_F8:         Key->ScanCode = SCAN_F8;         break;\r
+  case VK_F9:         Key->ScanCode = SCAN_F9;         break;\r
+  case VK_F11:        Key->ScanCode = SCAN_F11;        break;\r
+  case VK_F12:        Key->ScanCode = SCAN_F12;        break;\r
+\r
+  case VK_F13:        Key->ScanCode = SCAN_F13;        break;\r
+  case VK_F14:        Key->ScanCode = SCAN_F14;        break;\r
+  case VK_F15:        Key->ScanCode = SCAN_F15;        break;\r
+  case VK_F16:        Key->ScanCode = SCAN_F16;        break;\r
+  case VK_F17:        Key->ScanCode = SCAN_F17;        break;\r
+  case VK_F18:        Key->ScanCode = SCAN_F18;        break;\r
+  case VK_F19:        Key->ScanCode = SCAN_F19;        break;\r
+  case VK_F20:        Key->ScanCode = SCAN_F20;        break;\r
+  case VK_F21:        Key->ScanCode = SCAN_F21;        break;\r
+  case VK_F22:        Key->ScanCode = SCAN_F22;        break;\r
+  case VK_F23:        Key->ScanCode = SCAN_F23;        break;\r
+  case VK_F24:        Key->ScanCode = SCAN_F24;        break;\r
+\r
+  //\r
+  // Set toggle state\r
+  //    \r
+  case VK_NUMLOCK:     \r
+    Private->NumLock    = !Private->NumLock;\r
+    break;\r
+  case VK_SCROLL:\r
+    Private->ScrollLock = !Private->ScrollLock;\r
+    break;  \r
+  case VK_CAPITAL:\r
+    Private->CapsLock   = !Private->CapsLock;\r
+    break;  \r
+  }\r
+  \r
+  WinNtGopConvertParamToEfiKeyShiftState (Private, wParam, TRUE);  \r
+}\r
+\r
+\r
 //\r
 // GOP Protocol Member Functions\r
 //\r
@@ -127,7 +207,7 @@ WinNtGopQuerytMode (
   (*Info)->Version = 0;\r
   (*Info)->HorizontalResolution = Private->ModeData[ModeNumber].HorizontalResolution;\r
   (*Info)->VerticalResolution   = Private->ModeData[ModeNumber].VerticalResolution;\r
-  (*Info)->PixelFormat = PixelBlueGreenRedReserved8BitPerColor;\r
+  (*Info)->PixelFormat = PixelBltOnly;\r
   (*Info)->PixelsPerScanLine = (*Info)->HorizontalResolution;\r
 \r
   return EFI_SUCCESS;\r
@@ -615,6 +695,8 @@ WinNtGopThreadWindowProc (
 \r
   //\r
   // F10 and the ALT key do not create a WM_KEYDOWN message, thus this special case\r
+  // WM_SYSKEYDOWN is posted when F10 is pressed or \r
+  // holds down ALT key and then presses another key.\r
   //\r
   case WM_SYSKEYDOWN:\r
     Key.ScanCode = 0;\r
@@ -625,36 +707,53 @@ WinNtGopThreadWindowProc (
       GopPrivateAddQ (Private, Key);\r
       return 0;\r
     }\r
-    break;\r
 \r
-  case WM_KEYDOWN:\r
-    Key.ScanCode = 0;\r
-    switch (wParam) {\r
-    case VK_HOME:       Key.ScanCode = SCAN_HOME;       break;\r
-    case VK_END:        Key.ScanCode = SCAN_END;        break;\r
-    case VK_LEFT:       Key.ScanCode = SCAN_LEFT;       break;\r
-    case VK_RIGHT:      Key.ScanCode = SCAN_RIGHT;      break;\r
-    case VK_UP:         Key.ScanCode = SCAN_UP;         break;\r
-    case VK_DOWN:       Key.ScanCode = SCAN_DOWN;       break;\r
-    case VK_DELETE:     Key.ScanCode = SCAN_DELETE;     break;\r
-    case VK_INSERT:     Key.ScanCode = SCAN_INSERT;     break;\r
-    case VK_PRIOR:      Key.ScanCode = SCAN_PAGE_UP;    break;\r
-    case VK_NEXT:       Key.ScanCode = SCAN_PAGE_DOWN;  break;\r
-    case VK_ESCAPE:     Key.ScanCode = SCAN_ESC;        break;\r
-\r
-    case VK_F1:   Key.ScanCode = SCAN_F1;   break;\r
-    case VK_F2:   Key.ScanCode = SCAN_F2;   break;\r
-    case VK_F3:   Key.ScanCode = SCAN_F3;   break;\r
-    case VK_F4:   Key.ScanCode = SCAN_F4;   break;\r
-    case VK_F5:   Key.ScanCode = SCAN_F5;   break;\r
-    case VK_F6:   Key.ScanCode = SCAN_F6;   break;\r
-    case VK_F7:   Key.ScanCode = SCAN_F7;   break;\r
-    case VK_F8:   Key.ScanCode = SCAN_F8;   break;\r
-    case VK_F9:   Key.ScanCode = SCAN_F9;   break;\r
-    case VK_F11:  Key.ScanCode = SCAN_F11;  break;\r
-    case VK_F12:  Key.ScanCode = SCAN_F12;  break;\r
+    if ((lParam & GOP_ALT_KEY_PRESSED) == GOP_ALT_KEY_PRESSED) {\r
+      //\r
+      // ALT is pressed with another key pressed\r
+      //\r
+      WinNtGopConvertParamToEfiKey (Private, &wParam, &Key);\r
+\r
+      if ((lParam & GOP_EXTENDED_KEY) == GOP_EXTENDED_KEY) {\r
+        Private->RightAlt = TRUE;\r
+      } else {\r
+        Private->LeftAlt = TRUE;\r
+      }\r
+\r
+      if (Private->RightAlt && Private->LeftAlt) {\r
+        Private->LeftAlt = FALSE;\r
+      }\r
+    }\r
+\r
+    if (Key.ScanCode != 0) {\r
+      Key.UnicodeChar = 0;\r
+      GopPrivateAddQ (Private, Key);\r
+    }\r
+\r
+    return 0;\r
+\r
+  case WM_SYSKEYUP:\r
+    if ((lParam & GOP_ALT_KEY_PRESSED) == GOP_ALT_KEY_PRESSED) {\r
+      //\r
+      // ALT is pressed with another key released\r
+      //\r
+      WinNtGopConvertParamToEfiKeyShiftState (Private, &wParam, FALSE);  \r
+      //\r
+      // Actually ALT key is still held down here.\r
+      // Change the ALT key state when another key is released\r
+      // by user because we did not find a better solution to\r
+      // get a released ALT key. \r
+      //\r
+      Private->RightAlt = FALSE;\r
+      Private->LeftAlt = FALSE;\r
     }\r
 \r
+    return 0;\r
+\r
+\r
+  case WM_KEYDOWN:\r
+    Key.ScanCode = 0;\r
+    WinNtGopConvertParamToEfiKey (Private, &wParam, &Key);\r
     if (Key.ScanCode != 0) {\r
       Key.UnicodeChar = 0;\r
       GopPrivateAddQ (Private, Key);\r
@@ -662,6 +761,10 @@ WinNtGopThreadWindowProc (
 \r
     return 0;\r
 \r
+  case WM_KEYUP:\r
+    WinNtGopConvertParamToEfiKeyShiftState (Private, &wParam, FALSE);  \r
+    return 0;\r
+\r
   case WM_CHAR:\r
     //\r
     // The ESC key also generate WM_CHAR.\r