UsbKeyboardDevice->SimpleInputEx.SetState = USBKeyboardSetState;\r
UsbKeyboardDevice->SimpleInputEx.RegisterKeyNotify = USBKeyboardRegisterKeyNotify;\r
UsbKeyboardDevice->SimpleInputEx.UnregisterKeyNotify = USBKeyboardUnregisterKeyNotify;\r
- \r
+\r
InitializeListHead (&UsbKeyboardDevice->NotifyList);\r
- \r
+\r
Status = gBS->CreateEvent (\r
EVT_TIMER | EVT_NOTIFY_SIGNAL,\r
TPL_NOTIFY,\r
\r
DestroyQueue (&UsbKeyboardDevice->UsbKeyQueue);\r
DestroyQueue (&UsbKeyboardDevice->EfiKeyQueue);\r
- \r
+\r
FreePool (UsbKeyboardDevice);\r
\r
return Status;\r
\r
UsbKeyboardDevice = USB_KB_DEV_FROM_THIS (This);\r
\r
- Status = USBKeyboardReadKeyStrokeWorker (UsbKeyboardDevice, &KeyData);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\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 = USBKeyboardReadKeyStrokeWorker (UsbKeyboardDevice, &KeyData);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ //\r
+ // SimpleTextIn Protocol doesn't support partial keystroke;\r
+ //\r
+ if (KeyData.Key.ScanCode == CHAR_NULL && KeyData.Key.UnicodeChar == SCAN_NULL) {\r
+ continue;\r
+ }\r
+ CopyMem (Key, &KeyData.Key, sizeof (EFI_INPUT_KEY));\r
+ return EFI_SUCCESS;\r
}\r
-\r
- CopyMem (Key, &KeyData.Key, sizeof (EFI_INPUT_KEY));\r
-\r
- return EFI_SUCCESS;\r
}\r
\r
\r
)\r
{\r
USB_KB_DEV *UsbKeyboardDevice;\r
+ EFI_KEY_DATA KeyData;\r
+ EFI_TPL OldTpl;\r
\r
UsbKeyboardDevice = (USB_KB_DEV *) Context;\r
\r
- if (!IsQueueEmpty (&UsbKeyboardDevice->EfiKeyQueue)) {\r
+ //\r
+ // Enter critical section\r
+ // \r
+ OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\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 (!IsQueueEmpty (&UsbKeyboardDevice->EfiKeyQueue)) {\r
//\r
// If there is pending key, signal the event.\r
//\r
+ CopyMem (\r
+ &KeyData,\r
+ UsbKeyboardDevice->EfiKeyQueue.Buffer[UsbKeyboardDevice->EfiKeyQueue.Head],\r
+ sizeof (EFI_KEY_DATA)\r
+ );\r
+ if (KeyData.Key.ScanCode == SCAN_NULL && KeyData.Key.UnicodeChar == CHAR_NULL) {\r
+ Dequeue (&UsbKeyboardDevice->EfiKeyQueue, &KeyData, sizeof (EFI_KEY_DATA));\r
+ continue;\r
+ }\r
gBS->SignalEvent (Event);\r
+ break;\r
}\r
+ //\r
+ // Leave critical section and return\r
+ //\r
+ gBS->RestoreTPL (OldTpl);\r
}\r
\r
/**\r
EFI_KEY_DATA KeyData;\r
\r
UsbKeyboardDevice = (USB_KB_DEV *) Context;\r
- \r
+\r
//\r
// Fetch raw data from the USB keyboard buffer,\r
// and translate it into USB keycode.\r
RemoveEntryList (Link);\r
FreePool (NotifyNode);\r
}\r
- \r
+\r
return EFI_SUCCESS;\r
}\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
//\r
-// Simple Text Input Ex protocol functions \r
+// Simple Text Input Ex protocol functions\r
//\r
/**\r
Resets the input device hardware.\r
return EFI_DEVICE_ERROR;\r
}\r
\r
+ UsbKeyboardDevice->KeyState.KeyShiftState = EFI_SHIFT_STATE_VALID;\r
+ UsbKeyboardDevice->KeyState.KeyToggleState = EFI_TOGGLE_STATE_VALID;\r
+\r
return EFI_SUCCESS;\r
\r
}\r
UsbKeyboardDevice = TEXT_INPUT_EX_USB_KB_DEV_FROM_THIS (This);\r
\r
return USBKeyboardReadKeyStrokeWorker (UsbKeyboardDevice, KeyData);\r
- \r
+\r
}\r
\r
/**\r
\r
UsbKeyboardDevice = TEXT_INPUT_EX_USB_KB_DEV_FROM_THIS (This);\r
\r
- if ((*KeyToggleState & EFI_TOGGLE_STATE_VALID) != EFI_TOGGLE_STATE_VALID) {\r
+ if (((UsbKeyboardDevice->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
UsbKeyboardDevice->ScrollOn = FALSE;\r
UsbKeyboardDevice->NumLockOn = FALSE;\r
UsbKeyboardDevice->CapsOn = FALSE;\r
- \r
+ UsbKeyboardDevice->IsSupportPartialKey = FALSE;\r
+\r
if ((*KeyToggleState & EFI_SCROLL_LOCK_ACTIVE) == EFI_SCROLL_LOCK_ACTIVE) {\r
UsbKeyboardDevice->ScrollOn = TRUE;\r
}\r
if ((*KeyToggleState & EFI_CAPS_LOCK_ACTIVE) == EFI_CAPS_LOCK_ACTIVE) {\r
UsbKeyboardDevice->CapsOn = TRUE;\r
}\r
+ if ((*KeyToggleState & EFI_KEY_STATE_EXPOSED) == EFI_KEY_STATE_EXPOSED) {\r
+ UsbKeyboardDevice->IsSupportPartialKey = TRUE;\r
+ }\r
\r
SetKeyLED (UsbKeyboardDevice);\r
\r
+ UsbKeyboardDevice->KeyState.KeyToggleState = *KeyToggleState;\r
+\r
return EFI_SUCCESS;\r
- \r
+\r
}\r
\r
/**\r
KEYBOARD_CONSOLE_IN_EX_NOTIFY *NewNotify;\r
LIST_ENTRY *Link;\r
LIST_ENTRY *NotifyList;\r
- KEYBOARD_CONSOLE_IN_EX_NOTIFY *CurrentNotify; \r
+ KEYBOARD_CONSOLE_IN_EX_NOTIFY *CurrentNotify;\r
\r
if (KeyData == NULL || NotifyHandle == NULL || KeyNotificationFunction == NULL) {\r
return EFI_INVALID_PARAMETER;\r
// Return EFI_SUCCESS if the (KeyData, NotificationFunction) is already registered.\r
//\r
NotifyList = &UsbKeyboardDevice->NotifyList;\r
- \r
+\r
for (Link = GetFirstNode (NotifyList);\r
!IsNull (NotifyList, Link);\r
Link = GetNextNode (NotifyList, Link)) {\r
CurrentNotify = CR (\r
- Link, \r
- KEYBOARD_CONSOLE_IN_EX_NOTIFY, \r
- NotifyEntry, \r
+ Link,\r
+ KEYBOARD_CONSOLE_IN_EX_NOTIFY,\r
+ NotifyEntry,\r
USB_KB_CONSOLE_IN_EX_NOTIFY_SIGNATURE\r
);\r
- if (IsKeyRegistered (&CurrentNotify->KeyData, KeyData)) { \r
+ if (IsKeyRegistered (&CurrentNotify->KeyData, KeyData)) {\r
if (CurrentNotify->KeyNotificationFn == KeyNotificationFunction) {\r
- *NotifyHandle = CurrentNotify->NotifyHandle; \r
+ *NotifyHandle = CurrentNotify->NotifyHandle;\r
return EFI_SUCCESS;\r
}\r
}\r
}\r
- \r
+\r
//\r
// Allocate resource to save the notification function\r
- // \r
+ //\r
NewNotify = (KEYBOARD_CONSOLE_IN_EX_NOTIFY *) AllocateZeroPool (sizeof (KEYBOARD_CONSOLE_IN_EX_NOTIFY));\r
if (NewNotify == NULL) {\r
return EFI_OUT_OF_RESOURCES;\r
}\r
\r
- NewNotify->Signature = USB_KB_CONSOLE_IN_EX_NOTIFY_SIGNATURE; \r
+ NewNotify->Signature = USB_KB_CONSOLE_IN_EX_NOTIFY_SIGNATURE;\r
NewNotify->KeyNotificationFn = KeyNotificationFunction;\r
NewNotify->NotifyHandle = (EFI_HANDLE) NewNotify;\r
CopyMem (&NewNotify->KeyData, KeyData, sizeof (EFI_KEY_DATA));\r
InsertTailList (&UsbKeyboardDevice->NotifyList, &NewNotify->NotifyEntry);\r
\r
\r
- *NotifyHandle = NewNotify->NotifyHandle; \r
- \r
+ *NotifyHandle = NewNotify->NotifyHandle;\r
+\r
return EFI_SUCCESS;\r
- \r
+\r
}\r
\r
/**\r
\r
if (NotificationHandle == NULL) {\r
return EFI_INVALID_PARAMETER;\r
- } \r
+ }\r
\r
if (((KEYBOARD_CONSOLE_IN_EX_NOTIFY *) NotificationHandle)->Signature != USB_KB_CONSOLE_IN_EX_NOTIFY_SIGNATURE) {\r
return EFI_INVALID_PARAMETER;\r
- } \r
- \r
+ }\r
+\r
UsbKeyboardDevice = TEXT_INPUT_EX_USB_KB_DEV_FROM_THIS (This);\r
- \r
+\r
//\r
// Traverse notify list of USB keyboard and remove the entry of NotificationHandle.\r
//\r
!IsNull (NotifyList, Link);\r
Link = GetNextNode (NotifyList, Link)) {\r
CurrentNotify = CR (\r
- Link, \r
- KEYBOARD_CONSOLE_IN_EX_NOTIFY, \r
- NotifyEntry, \r
+ Link,\r
+ KEYBOARD_CONSOLE_IN_EX_NOTIFY,\r
+ NotifyEntry,\r
USB_KB_CONSOLE_IN_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
- FreePool (CurrentNotify); \r
+ FreePool (CurrentNotify);\r
return EFI_SUCCESS;\r
}\r
}\r
//\r
// Cannot find the matching entry in database.\r
//\r
- return EFI_INVALID_PARAMETER; \r
+ return EFI_INVALID_PARAMETER;\r
}\r
\r