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