CopyMem (Key, &Queue->Q[Queue->Front], sizeof (EFI_KEY_DATA));\r
Queue->Front = (Queue->Front + 1) % MAX_Q;\r
\r
+ if (Key->Key.ScanCode == SCAN_NULL && Key->Key.UnicodeChar == CHAR_NULL) {\r
+ if (!Private->IsPartialKeySupport) {\r
+ //\r
+ // If partial keystrok is not enabled, don't return the partial keystroke.\r
+ //\r
+ Private->WinNtThunk->LeaveCriticalSection (&Queue->Cs);\r
+ ZeroMem (Key, sizeof (EFI_KEY_DATA));\r
+ return EFI_NOT_READY;\r
+ }\r
+ }\r
Private->WinNtThunk->LeaveCriticalSection (&Queue->Cs);\r
return EFI_SUCCESS;\r
}\r
\r
Arguments:\r
\r
- RegsiteredData - A pointer to a buffer that is filled in with the keystroke \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
+ InputData - 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
TRUE - Key be pressed matches a registered key.\r
- FLASE - Match failed. \r
- \r
+ FLASE - Match failed.\r
+\r
--*/\r
{\r
ASSERT (RegsiteredData != NULL && InputData != NULL);\r
- \r
+\r
if ((RegsiteredData->Key.ScanCode != InputData->Key.ScanCode) ||\r
(RegsiteredData->Key.UnicodeChar != InputData->Key.UnicodeChar)) {\r
- return FALSE; \r
- } \r
- \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
+ return FALSE;\r
+ }\r
if (RegsiteredData->KeyState.KeyToggleState != 0 &&\r
RegsiteredData->KeyState.KeyToggleState != InputData->KeyState.KeyToggleState) {\r
- return FALSE; \r
- } \r
- \r
+ return FALSE;\r
+ }\r
+\r
return TRUE;\r
\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
+ 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
+--*/\r
+{\r
LIST_ENTRY *Link;\r
WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY *CurrentNotify;\r
- \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
+ 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
\r
VOID\r
}\r
if (Private->LeftShift) {\r
KeyData.KeyState.KeyShiftState |= EFI_LEFT_SHIFT_PRESSED;\r
- } \r
+ }\r
if (Private->RightShift) {\r
KeyData.KeyState.KeyShiftState |= EFI_RIGHT_SHIFT_PRESSED;\r
}\r
}\r
if (Private->SysReq) {\r
KeyData.KeyState.KeyShiftState |= EFI_SYS_REQ_PRESSED;\r
- } \r
+ }\r
if (Private->CapsLock) {\r
KeyData.KeyState.KeyToggleState |= EFI_CAPS_LOCK_ACTIVE;\r
}\r
if (Private->ScrollLock) {\r
KeyData.KeyState.KeyToggleState |= EFI_SCROLL_LOCK_ACTIVE;\r
}\r
- \r
+ if (Private->IsPartialKeySupport) {\r
+ KeyData.KeyState.KeyToggleState |= EFI_KEY_STATE_EXPOSED;\r
+ }\r
+\r
//\r
// Convert Ctrl+[1-26] to Ctrl+[A-Z]\r
//\r
- if ((Private->LeftCtrl || Private->RightCtrl) && \r
+ if ((Private->LeftCtrl || Private->RightCtrl) &&\r
(KeyData.Key.UnicodeChar >= 1) && (KeyData.Key.UnicodeChar <= 26)\r
) {\r
if ((Private->LeftShift || Private->RightShift) == Private->CapsLock) {\r
\r
EFI_SUCCESS - The status light is updated successfully.\r
\r
---*/ \r
-{ \r
+--*/\r
+{\r
//\r
- // BUGBUG:Only SendInput/keybd_event function can toggle \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
\r
Private->RightLogo = FALSE;\r
Private->Menu = FALSE;\r
Private->SysReq = FALSE;\r
- \r
+\r
Private->CapsLock = FALSE;\r
Private->NumLock = FALSE;\r
Private->ScrollLock = FALSE;\r
- \r
+ Private->IsPartialKeySupport = FALSE;\r
+\r
Private->KeyState.KeyShiftState = EFI_SHIFT_STATE_VALID;\r
Private->KeyState.KeyToggleState = EFI_TOGGLE_STATE_VALID;\r
\r
/*++\r
\r
Routine Description:\r
- Reads the next keystroke from the input device. The WaitForKey Event can \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
Private - The private structure of WinNt Gop device.\r
- KeyData - A pointer to a buffer that is filled in with the keystroke \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
+ EFI_DEVICE_ERROR - The keystroke information was not returned due to\r
hardware errors.\r
- EFI_INVALID_PARAMETER - KeyData is NULL. \r
+ EFI_INVALID_PARAMETER - KeyData is NULL.\r
\r
--*/\r
{\r
EFI_STATUS Status;\r
- EFI_TPL OldTpl; \r
+ EFI_TPL OldTpl;\r
\r
if (KeyData == NULL) {\r
return EFI_INVALID_PARAMETER;\r
Status = GopPrivateDeleteQ (Private, &Private->QueueForRead, KeyData);\r
if (!EFI_ERROR (Status)) {\r
//\r
- // Leave critical section and return\r
+ // If partial keystroke is not enabled, check whether it is value key. If not return\r
+ // EFI_NOT_READY.\r
//\r
- gBS->RestoreTPL (OldTpl);\r
- return EFI_SUCCESS;\r
+ if (!Private->IsPartialKeySupport) {\r
+ if (KeyData->Key.ScanCode == SCAN_NULL && KeyData->Key.UnicodeChar == CHAR_NULL) {\r
+ Status = EFI_NOT_READY;\r
+ }\r
+ }\r
}\r
}\r
\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
+ // Considering if the partial keystroke is enabled, there maybe a partial\r
+ // keystroke in the queue, so here skip the partial keystroke and get the\r
+ // next key from the queue\r
+ //\r
+ while (1) {\r
+ Status = GopPrivateReadKeyStrokeWorker (Private, &KeyData);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ if (KeyData.Key.ScanCode == SCAN_NULL && KeyData.Key.UnicodeChar == CHAR_NULL) {\r
+ continue;\r
+ }\r
+ CopyMem (Key, &KeyData.Key, sizeof (EFI_INPUT_KEY));\r
+ return EFI_SUCCESS;\r
+ } \r
}\r
\r
\r
GOP_PRIVATE_DATA *Private;\r
EFI_STATUS Status;\r
EFI_TPL OldTpl;\r
+ EFI_KEY_DATA KeyData;\r
\r
Private = (GOP_PRIVATE_DATA *) Context;\r
\r
// Enter critical section\r
//\r
OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
- \r
+\r
//\r
// Call hot key callback before telling caller there is a key available\r
//\r
WinNtGopSimpleTextInTimerHandler (NULL, Private);\r
-\r
- Status = GopPrivateCheckQ (&Private->QueueForRead);\r
- if (!EFI_ERROR (Status)) {\r
- //\r
- // If a there is a key in the queue signal our event.\r
- //\r
- gBS->SignalEvent (Event);\r
- } else {\r
- //\r
- // We need to sleep or NT will schedule this thread with such high\r
- // priority that WinProc thread will never run and we will not see\r
- // keyboard input. This Sleep makes the syste run 10x faster, so don't\r
- // remove it.\r
- //\r
- Private->WinNtThunk->Sleep (1);\r
+ \r
+ //\r
+ // WaitforKey doesn't suppor the partial key.\r
+ // Considering if the partial keystroke is enabled, there maybe a partial\r
+ // keystroke in the queue, so here skip the partial keystroke and get the\r
+ // next key from the queue\r
+ //\r
+ while (1) {\r
+ Status = GopPrivateCheckQ (&Private->QueueForRead);\r
+ if (!EFI_ERROR (Status)) {\r
+ //\r
+ // If a there is a key in the queue and it is not partial keystroke, signal event.\r
+ //\r
+ if (Private->QueueForRead.Q[Private->QueueForRead.Front].Key.ScanCode == SCAN_NULL &&\r
+ Private->QueueForRead.Q[Private->QueueForRead.Front].Key.UnicodeChar == CHAR_NULL) {\r
+ GopPrivateDeleteQ (Private,&Private->QueueForRead,&KeyData);\r
+ continue;\r
+ }\r
+ gBS->SignalEvent (Event);\r
+ } else {\r
+ //\r
+ // We need to sleep or NT will schedule this thread with such high\r
+ // priority that WinProc thread will never run and we will not see\r
+ // keyboard input. This Sleep makes the syste run 10x faster, so don't\r
+ // remove it.\r
+ //\r
+ Private->WinNtThunk->Sleep (1);\r
+ }\r
+ break;\r
}\r
\r
//\r
GOP_PRIVATE_DATA *Private;\r
\r
Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_EX_THIS (This);\r
- \r
+\r
return GopPrivateResetWorker (Private);\r
}\r
\r
/*++\r
\r
Routine Description:\r
- Reads the next keystroke from the input device. The WaitForKey Event can \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
+ 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
+ EFI_DEVICE_ERROR - The keystroke information was not returned due to\r
hardware errors.\r
- EFI_INVALID_PARAMETER - KeyData is NULL. \r
+ EFI_INVALID_PARAMETER - KeyData is NULL.\r
\r
--*/\r
{\r
}\r
\r
Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_EX_THIS (This);\r
- \r
+\r
return GopPrivateReadKeyStrokeWorker (Private, KeyData);\r
\r
}\r
\r
Arguments:\r
This - Protocol instance pointer.\r
- KeyToggleState - A pointer to the EFI_KEY_TOGGLE_STATE to set the \r
+ KeyToggleState - A pointer to the EFI_KEY_TOGGLE_STATE to set the\r
state for the input device.\r
- \r
- Returns: \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
+ 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
+ EFI_INVALID_PARAMETER - KeyToggleState is NULL.\r
\r
---*/ \r
+--*/\r
{\r
EFI_STATUS Status;\r
GOP_PRIVATE_DATA *Private;\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
+ return EFI_UNSUPPORTED;\r
}\r
\r
- Private->ScrollLock = FALSE;\r
- Private->NumLock = FALSE;\r
- Private->CapsLock = FALSE;\r
+ Private->ScrollLock = FALSE;\r
+ Private->NumLock = FALSE;\r
+ Private->CapsLock = FALSE;\r
+ Private->IsPartialKeySupport = FALSE;\r
\r
if ((*KeyToggleState & EFI_SCROLL_LOCK_ACTIVE) == EFI_SCROLL_LOCK_ACTIVE) {\r
Private->ScrollLock = TRUE;\r
- } \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
+ if ((*KeyToggleState & EFI_KEY_STATE_EXPOSED) == EFI_KEY_STATE_EXPOSED) {\r
+ Private->IsPartialKeySupport = TRUE;\r
+ }\r
\r
- Status = GopPrivateUpdateStatusLight (Private); \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
\r
EFI_STATUS\r
\r
Arguments:\r
This - Protocol instance pointer.\r
- KeyData - A pointer to a buffer that is filled in with the keystroke \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
+ 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
+ EFI_INVALID_PARAMETER - KeyData or NotifyHandle is NULL.\r
+\r
+--*/\r
{\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
+ WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY *NewNotify;\r
\r
if (KeyData == NULL || KeyNotificationFunction == NULL || NotifyHandle == NULL) {\r
return EFI_INVALID_PARAMETER;\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
+ 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 (GopPrivateIsKeyRegistered (&CurrentNotify->KeyData, KeyData)) {\r
if (CurrentNotify->KeyNotificationFn == KeyNotificationFunction) {\r
*NotifyHandle = CurrentNotify->NotifyHandle;\r
return EFI_SUCCESS;\r
}\r
}\r
- } \r
- \r
+ }\r
+\r
//\r
// Allocate resource to save the notification function\r
- // \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->Signature = WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY_SIGNATURE;\r
NewNotify->KeyNotificationFn = KeyNotificationFunction;\r
NewNotify->NotifyHandle = (EFI_HANDLE) NewNotify;\r
CopyMem (&NewNotify->KeyData, KeyData, sizeof (EFI_KEY_DATA));\r
InsertTailList (&Private->NotifyList, &NewNotify->NotifyEntry);\r
\r
- *NotifyHandle = NewNotify->NotifyHandle; \r
- \r
+ *NotifyHandle = NewNotify->NotifyHandle;\r
+\r
return EFI_SUCCESS;\r
- \r
+\r
}\r
\r
EFI_STATUS\r
Remove a registered notification function from a particular keystroke.\r
\r
Arguments:\r
- This - Protocol instance pointer. \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
- \r
---*/ \r
+\r
+--*/\r
{\r
GOP_PRIVATE_DATA *Private;\r
LIST_ENTRY *Link;\r
\r
if (NotificationHandle == NULL) {\r
return EFI_INVALID_PARAMETER;\r
- } \r
+ }\r
\r
if (((WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY *) NotificationHandle)->Signature != WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY_SIGNATURE) {\r
return EFI_INVALID_PARAMETER;\r
- } \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
+ Link,\r
+ WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY,\r
+ NotifyEntry,\r
WIN_NT_GOP_SIMPLE_TEXTIN_EX_NOTIFY_SIGNATURE\r
- ); \r
+ );\r
if (CurrentNotify->NotifyHandle == NotificationHandle) {\r
//\r
// Remove the notification function from NotifyList and free resources\r
//\r
- RemoveEntryList (&CurrentNotify->NotifyEntry); \r
+ RemoveEntryList (&CurrentNotify->NotifyEntry);\r
\r
- gBS->FreePool (CurrentNotify); \r
+ gBS->FreePool (CurrentNotify);\r
return EFI_SUCCESS;\r
}\r
}\r
&Private->SimpleTextIn.WaitForKey\r
);\r
\r
- \r
+\r
Private->SimpleTextInEx.Reset = WinNtGopSimpleTextInExResetEx;\r
Private->SimpleTextInEx.ReadKeyStrokeEx = WinNtGopSimpleTextInExReadKeyStrokeEx;\r
Private->SimpleTextInEx.SetState = WinNtGopSimpleTextInExSetState;\r
Private->SimpleTextInEx.UnregisterKeyNotify = WinNtGopSimpleTextInExUnregisterKeyNotify;\r
\r
Private->SimpleTextInEx.Reset (&Private->SimpleTextInEx, FALSE);\r
- \r
+\r
InitializeListHead (&Private->NotifyList);\r
\r
Status = gBS->CreateEvent (\r
&Private->TimerEvent\r
);\r
ASSERT_EFI_ERROR (Status);\r
- \r
+\r
Status = gBS->SetTimer (\r
Private->TimerEvent,\r
TimerPeriodic,\r
IN VOID *Context\r
);\r
\r
-VOID\r
+BOOLEAN\r
WinNtGopConvertParamToEfiKeyShiftState (\r
IN GOP_PRIVATE_DATA *Private,\r
IN WPARAM *wParam,\r
+ IN LPARAM *lParam,\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
+ // 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
+ //\r
+ case VK_SHIFT:\r
+ if ((*lParam & GOP_EXTENDED_KEY) == GOP_EXTENDED_KEY) {\r
+ Private->RightShift = Flag;\r
+ } else {\r
+ Private->LeftShift = Flag;\r
+ }\r
+ return TRUE;\r
+\r
+ case VK_LSHIFT:\r
+ Private->LeftShift = Flag;\r
+ return TRUE;\r
+\r
+ case VK_RSHIFT:\r
+ Private->RightShift = Flag;\r
+ return TRUE;\r
+\r
case VK_CONTROL:\r
- Private->LeftCtrl = Flag;\r
- break;\r
- case VK_LWIN: \r
+ if ((*lParam & GOP_EXTENDED_KEY) == GOP_EXTENDED_KEY) {\r
+ Private->RightCtrl= Flag;\r
+ } else {\r
+ Private->LeftCtrl = Flag;\r
+ }\r
+ return TRUE;\r
+\r
+ case VK_LCONTROL:\r
+ Private->LeftCtrl = Flag;\r
+ return TRUE;\r
+\r
+ case VK_RCONTROL:\r
+ Private->RightCtrl = Flag;\r
+ return TRUE;\r
+\r
+ case VK_LWIN:\r
Private->LeftLogo = Flag;\r
- break;\r
- case VK_RWIN: \r
+ return TRUE;\r
+\r
+ case VK_RWIN:\r
Private->RightLogo = Flag;\r
- break;\r
- case VK_APPS: \r
+ return TRUE;\r
+\r
+ case VK_APPS:\r
Private->Menu = Flag;\r
- break;\r
+ return TRUE;\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
+ case VK_PRINT:\r
Private->SysReq = Flag;\r
- break;\r
+ return TRUE;\r
+ //\r
+ // For Alt Keystroke.\r
+ //\r
+ case VK_MENU:\r
+ if ((*lParam & GOP_EXTENDED_KEY) == GOP_EXTENDED_KEY) {\r
+ Private->RightAlt = Flag;\r
+ } else {\r
+ Private->LeftAlt = Flag;\r
+ }\r
+ return TRUE;\r
+\r
+ default:\r
+ return FALSE;\r
}\r
}\r
\r
-VOID\r
+BOOLEAN\r
WinNtGopConvertParamToEfiKey (\r
IN GOP_PRIVATE_DATA *Private,\r
IN WPARAM *wParam,\r
+ IN LPARAM *lParam,\r
IN EFI_INPUT_KEY *Key\r
)\r
{\r
+ BOOLEAN Flag;\r
+ Flag = FALSE;\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
- case VK_PAUSE: Key->ScanCode = SCAN_PAUSE; break;\r
+ case VK_HOME: Key->ScanCode = SCAN_HOME; Flag = TRUE; break;\r
+ case VK_END: Key->ScanCode = SCAN_END; Flag = TRUE; break;\r
+ case VK_LEFT: Key->ScanCode = SCAN_LEFT; Flag = TRUE; break;\r
+ case VK_RIGHT: Key->ScanCode = SCAN_RIGHT; Flag = TRUE; break;\r
+ case VK_UP: Key->ScanCode = SCAN_UP; Flag = TRUE; break;\r
+ case VK_DOWN: Key->ScanCode = SCAN_DOWN; Flag = TRUE; break;\r
+ case VK_DELETE: Key->ScanCode = SCAN_DELETE; Flag = TRUE; break;\r
+ case VK_INSERT: Key->ScanCode = SCAN_INSERT; Flag = TRUE; break;\r
+ case VK_PRIOR: Key->ScanCode = SCAN_PAGE_UP; Flag = TRUE; break;\r
+ case VK_NEXT: Key->ScanCode = SCAN_PAGE_DOWN; Flag = TRUE; break;\r
+ case VK_ESCAPE: Key->ScanCode = SCAN_ESC; Flag = TRUE; break;\r
+\r
+ case VK_F1: Key->ScanCode = SCAN_F1; Flag = TRUE; break;\r
+ case VK_F2: Key->ScanCode = SCAN_F2; Flag = TRUE; break;\r
+ case VK_F3: Key->ScanCode = SCAN_F3; Flag = TRUE; break;\r
+ case VK_F4: Key->ScanCode = SCAN_F4; Flag = TRUE; break;\r
+ case VK_F5: Key->ScanCode = SCAN_F5; Flag = TRUE; break;\r
+ case VK_F6: Key->ScanCode = SCAN_F6; Flag = TRUE; break;\r
+ case VK_F7: Key->ScanCode = SCAN_F7; Flag = TRUE; break;\r
+ case VK_F8: Key->ScanCode = SCAN_F8; Flag = TRUE; break;\r
+ case VK_F9: Key->ScanCode = SCAN_F9; Flag = TRUE; break;\r
+ case VK_F11: Key->ScanCode = SCAN_F11; Flag = TRUE; break;\r
+ case VK_F12: Key->ScanCode = SCAN_F12; Flag = TRUE; break;\r
+\r
+ case VK_F13: Key->ScanCode = SCAN_F13; Flag = TRUE; break;\r
+ case VK_F14: Key->ScanCode = SCAN_F14; Flag = TRUE; break;\r
+ case VK_F15: Key->ScanCode = SCAN_F15; Flag = TRUE; break;\r
+ case VK_F16: Key->ScanCode = SCAN_F16; Flag = TRUE; break;\r
+ case VK_F17: Key->ScanCode = SCAN_F17; Flag = TRUE; break;\r
+ case VK_F18: Key->ScanCode = SCAN_F18; Flag = TRUE; break;\r
+ case VK_F19: Key->ScanCode = SCAN_F19; Flag = TRUE; break;\r
+ case VK_F20: Key->ScanCode = SCAN_F20; Flag = TRUE; break;\r
+ case VK_F21: Key->ScanCode = SCAN_F21; Flag = TRUE; break;\r
+ case VK_F22: Key->ScanCode = SCAN_F22; Flag = TRUE; break;\r
+ case VK_F23: Key->ScanCode = SCAN_F23; Flag = TRUE; break;\r
+ case VK_F24: Key->ScanCode = SCAN_F24; Flag = TRUE; break;\r
+ case VK_PAUSE: Key->ScanCode = SCAN_PAUSE; Flag = TRUE; break;\r
\r
//\r
// Set toggle state\r
- // \r
- case VK_NUMLOCK: \r
+ //\r
+ case VK_NUMLOCK:\r
Private->NumLock = (BOOLEAN)(!Private->NumLock);\r
+ Flag = TRUE;\r
break;\r
case VK_SCROLL:\r
Private->ScrollLock = (BOOLEAN)(!Private->ScrollLock);\r
- break; \r
+ Flag = TRUE;\r
+ break;\r
case VK_CAPITAL:\r
Private->CapsLock = (BOOLEAN)(!Private->CapsLock);\r
- break; \r
+ Flag = TRUE;\r
+ break;\r
}\r
\r
- WinNtGopConvertParamToEfiKeyShiftState (Private, wParam, TRUE); \r
+ return (WinNtGopConvertParamToEfiKeyShiftState (Private, wParam, lParam, TRUE)) == TRUE ? TRUE : Flag;\r
}\r
\r
\r
PAINTSTRUCT PaintStruct;\r
LPARAM Index;\r
EFI_INPUT_KEY Key;\r
+ BOOLEAN AltIsPress;\r
\r
//\r
// BugBug - if there are two instances of this DLL in memory (such as is\r
// This works since each Gop protocol has a unique Private data instance and\r
// a unique thread.\r
//\r
+ AltIsPress = FALSE;\r
Private = mWinNt->TlsGetValue (mTlsIndex);\r
ASSERT (NULL != Private);\r
\r
\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
+ // 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
+\r
+ Key.ScanCode = 0;\r
+ Key.UnicodeChar = CHAR_NULL;\r
switch (wParam) {\r
case VK_F10:\r
Key.ScanCode = SCAN_F10;\r
- Key.UnicodeChar = 0;\r
+ Key.UnicodeChar = CHAR_NULL;\r
GopPrivateAddKey (Private, Key);\r
return 0;\r
}\r
\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
+ //\r
+ // If ALT or ALT + modifier key is pressed.\r
+ //\r
+ if (WinNtGopConvertParamToEfiKey (Private, &wParam, &lParam, &Key)) {\r
+ if (Key.ScanCode != 0){\r
+ //\r
+ // If ALT is pressed with other ScanCode.\r
+ // Always revers the left Alt for simple.\r
+ //\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
GopPrivateAddKey (Private, Key);\r
+ //\r
+ // When Alt is released there is no windoes message, so \r
+ // clean it after using it.\r
+ //\r
+ Private->RightAlt = FALSE;\r
+ Private->LeftAlt = FALSE;\r
+ return 0;\r
}\r
+ AltIsPress = TRUE;\r
\r
- return 0;\r
+ case WM_CHAR: \r
+ //\r
+ // The ESC key also generate WM_CHAR.\r
+ //\r
+ if (wParam == 0x1B) {\r
+ return 0;\r
+ } \r
\r
- case WM_SYSKEYUP:\r
- if ((lParam & GOP_ALT_KEY_PRESSED) == GOP_ALT_KEY_PRESSED) {\r
+ if (AltIsPress == TRUE) {\r
//\r
- // ALT is pressed with another key released\r
+ // If AltIsPress is true that means the Alt key is pressed.\r
//\r
- WinNtGopConvertParamToEfiKeyShiftState (Private, &wParam, FALSE); \r
+ Private->LeftAlt = TRUE;\r
+ }\r
+ for (Index = 0; Index < (lParam & 0xffff); Index++) {\r
+ if (wParam != 0) {\r
+ Key.UnicodeChar = (CHAR16) wParam;\r
+ Key.ScanCode = SCAN_NULL; \r
+ GopPrivateAddKey (Private, Key); \r
+ }\r
+ }\r
+ if (AltIsPress == TRUE) {\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
+ // When Alt is released there is no windoes message, so \r
+ // clean it after using it.\r
//\r
+ Private->LeftAlt = FALSE;\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
- GopPrivateAddKey (Private, Key);\r
- }\r
-\r
- return 0;\r
-\r
- case WM_KEYUP:\r
- WinNtGopConvertParamToEfiKeyShiftState (Private, &wParam, FALSE); \r
+ case WM_SYSKEYUP:\r
+ //\r
+ // ALT is pressed with another key released\r
+ //\r
+ WinNtGopConvertParamToEfiKeyShiftState (Private, &wParam, &lParam, FALSE);\r
return 0;\r
\r
- case WM_CHAR:\r
+ case WM_KEYDOWN:\r
+ Key.ScanCode = SCAN_NULL;\r
//\r
- // The ESC key also generate WM_CHAR.\r
+ // A value key press will cause a WM_KEYDOWN first, then cause a WM_CHAR\r
+ // So if there is no modifier key updated, skip the WM_KEYDOWN even.\r
//\r
- if (wParam == 0x1B) {\r
- return 0;\r
- }\r
-\r
- for (Index = 0; Index < (lParam & 0xffff); Index++) {\r
- if (wParam != 0) {\r
- Key.UnicodeChar = (CHAR16) wParam;\r
- Key.ScanCode = 0;\r
- GopPrivateAddKey (Private, Key);\r
+ if (WinNtGopConvertParamToEfiKey (Private, &wParam, &lParam, &Key)) {\r
+ if (Key.ScanCode != SCAN_NULL) {\r
+ Key.UnicodeChar = CHAR_NULL;\r
}\r
+ //\r
+ // Support the partial keystroke, add all keydown event into the queue.\r
+ //\r
+ GopPrivateAddKey (Private, Key);\r
}\r
+ return 0;\r
\r
+ case WM_KEYUP:\r
+ WinNtGopConvertParamToEfiKeyShiftState (Private, &wParam, &lParam, FALSE);\r
return 0;\r
\r
case WM_CLOSE:\r