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
SCAN_F10, // EFI_FUNCTION_KEY_TEN_MODIFIER\r
SCAN_F11, // EFI_FUNCTION_KEY_ELEVEN_MODIFIER\r
SCAN_F12, // EFI_FUNCTION_KEY_TWELVE_MODIFIER\r
+ //\r
+ // For Partial Keystroke support\r
+ //\r
SCAN_NULL, // EFI_PRINT_MODIFIER\r
SCAN_NULL, // EFI_SYS_REQUEST_MODIFIER\r
SCAN_NULL, // EFI_SCROLL_LOCK_MODIFIER\r
- SCAN_PAUSE // EFI_PAUSE_MODIFIER\r
+ SCAN_PAUSE, // EFI_PAUSE_MODIFIER\r
+ SCAN_NULL, // EFI_BREAK_MODIFIER\r
+ SCAN_NULL, // EFI_LEFT_LOGO_MODIFIER\r
+ SCAN_NULL, // EFI_RIGHT_LOGO_MODIFER\r
+ SCAN_NULL, // EFI_MENU_MODIFER\r
};\r
\r
/**\r
LIST_ENTRY *Link;\r
LIST_ENTRY *NsKeyList;\r
USB_NS_KEY *UsbNsKey;\r
- \r
+\r
NsKeyList = &UsbKeyboardDevice->NsKeyList;\r
Link = GetFirstNode (NsKeyList);\r
while (!IsNull (NsKeyList, Link)) {\r
//\r
InstallDefaultKeyboardLayout (UsbKeyboardDevice);\r
}\r
- \r
+\r
return EFI_SUCCESS;\r
}\r
\r
// Assumed the first config is the correct one and this is not always the case\r
//\r
Status = UsbGetConfiguration (\r
- UsbKeyboardDevice->UsbIo, \r
- &ConfigValue, \r
+ UsbKeyboardDevice->UsbIo,\r
+ &ConfigValue,\r
&TransferResult\r
);\r
if (EFI_ERROR (Status)) {\r
ConfigValue = 0x01;\r
}\r
- \r
+\r
//\r
// Uses default configuration to configure the USB Keyboard device.\r
//\r
UsbKeyboardDevice->NumLockOn = FALSE;\r
UsbKeyboardDevice->CapsOn = FALSE;\r
UsbKeyboardDevice->ScrollOn = FALSE;\r
- \r
+\r
UsbKeyboardDevice->LeftCtrlOn = FALSE;\r
UsbKeyboardDevice->LeftAltOn = FALSE;\r
UsbKeyboardDevice->LeftShiftOn = FALSE;\r
\r
//\r
// Delete & Submit this interrupt again\r
- // Handler of DelayedRecoveryEvent triggered by timer will re-submit the interrupt. \r
+ // Handler of DelayedRecoveryEvent triggered by timer will re-submit the interrupt.\r
//\r
UsbIo->UsbAsyncInterruptTransfer (\r
UsbIo,\r
case EFI_LEFT_CONTROL_MODIFIER:\r
UsbKeyboardDevice->LeftCtrlOn = TRUE;\r
UsbKeyboardDevice->CtrlOn = TRUE;\r
- continue;\r
break;\r
case EFI_RIGHT_CONTROL_MODIFIER:\r
UsbKeyboardDevice->RightCtrlOn = TRUE;\r
UsbKeyboardDevice->CtrlOn = TRUE;\r
- continue;\r
break;\r
\r
//\r
case EFI_LEFT_SHIFT_MODIFIER:\r
UsbKeyboardDevice->LeftShiftOn = TRUE;\r
UsbKeyboardDevice->ShiftOn = TRUE;\r
- continue;\r
break;\r
case EFI_RIGHT_SHIFT_MODIFIER:\r
UsbKeyboardDevice->RightShiftOn = TRUE;\r
UsbKeyboardDevice->ShiftOn = TRUE;\r
- continue;\r
break;\r
\r
//\r
case EFI_LEFT_ALT_MODIFIER:\r
UsbKeyboardDevice->LeftAltOn = TRUE;\r
UsbKeyboardDevice->AltOn = TRUE;\r
- continue;\r
break;\r
case EFI_RIGHT_ALT_MODIFIER:\r
UsbKeyboardDevice->RightAltOn = TRUE;\r
UsbKeyboardDevice->AltOn = TRUE;\r
- continue;\r
break;\r
\r
//\r
case EFI_PRINT_MODIFIER:\r
case EFI_SYS_REQUEST_MODIFIER:\r
UsbKeyboardDevice->SysReqOn = TRUE;\r
- continue;\r
break;\r
\r
//\r
//\r
UsbKeyboardDevice->NumLockOn = (BOOLEAN) (!(UsbKeyboardDevice->NumLockOn));\r
SetKeyLED (UsbKeyboardDevice);\r
- continue;\r
break;\r
\r
case EFI_CAPS_LOCK_MODIFIER:\r
//\r
UsbKeyboardDevice->CapsOn = (BOOLEAN) (!(UsbKeyboardDevice->CapsOn));\r
SetKeyLED (UsbKeyboardDevice);\r
- continue;\r
break;\r
\r
case EFI_SCROLL_LOCK_MODIFIER:\r
//\r
UsbKeyboardDevice->ScrollOn = (BOOLEAN) (!(UsbKeyboardDevice->ScrollOn));\r
SetKeyLED (UsbKeyboardDevice);\r
- continue;\r
break;\r
\r
default:\r
EFI_KEY_DESCRIPTOR *KeyDescriptor;\r
LIST_ENTRY *Link;\r
LIST_ENTRY *NotifyList;\r
- KEYBOARD_CONSOLE_IN_EX_NOTIFY *CurrentNotify; \r
+ KEYBOARD_CONSOLE_IN_EX_NOTIFY *CurrentNotify;\r
\r
//\r
- // KeyCode must in the range of 0x4 to 0x65\r
+ // KeyCode must in the range of [0x4, 0x65] or [0xe0, 0xe7].\r
//\r
- if (!USBKBD_VALID_KEYCODE (KeyCode)) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- if ((KeyCode - 4) >= NUMBER_OF_VALID_NON_MODIFIER_USB_KEYCODE) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
KeyDescriptor = GetKeyDescriptor (UsbKeyboardDevice, KeyCode);\r
ASSERT (KeyDescriptor != NULL);\r
\r
if ((UsbKeyboardDevice->NumLockOn) && (!(UsbKeyboardDevice->ShiftOn))) {\r
KeyData->Key.ScanCode = SCAN_NULL;\r
} else {\r
- KeyData->Key.UnicodeChar = 0x00;\r
+ KeyData->Key.UnicodeChar = CHAR_NULL;\r
}\r
}\r
\r
//\r
if (KeyData->Key.UnicodeChar == 0x1B && KeyData->Key.ScanCode == SCAN_NULL) {\r
KeyData->Key.ScanCode = SCAN_ESC;\r
- KeyData->Key.UnicodeChar = 0x00;\r
+ KeyData->Key.UnicodeChar = CHAR_NULL;\r
}\r
\r
//\r
// Not valid for key without both unicode key code and EFI Scan Code.\r
//\r
if (KeyData->Key.UnicodeChar == 0 && KeyData->Key.ScanCode == SCAN_NULL) {\r
+ if (!UsbKeyboardDevice->IsSupportPartialKey) {\r
return EFI_NOT_READY;\r
+ }\r
}\r
\r
//\r
if (UsbKeyboardDevice->CapsOn) {\r
KeyData->KeyState.KeyToggleState |= EFI_CAPS_LOCK_ACTIVE;\r
}\r
-\r
+ if (UsbKeyboardDevice->IsSupportPartialKey) {\r
+ KeyData->KeyState.KeyToggleState |= EFI_KEY_STATE_EXPOSED;\r
+ }\r
//\r
// Invoke notification functions if the key is registered.\r
//\r
NotifyList = &UsbKeyboardDevice->NotifyList;\r
for (Link = GetFirstNode (NotifyList); !IsNull (NotifyList, Link); Link = GetNextNode (NotifyList, Link)) {\r
CurrentNotify = CR (Link, KEYBOARD_CONSOLE_IN_EX_NOTIFY, NotifyEntry, USB_KB_CONSOLE_IN_EX_NOTIFY_SIGNATURE);\r
- if (IsKeyRegistered (&CurrentNotify->KeyData, KeyData)) { \r
+ if (IsKeyRegistered (&CurrentNotify->KeyData, KeyData)) {\r
CurrentNotify->KeyNotificationFn (KeyData);\r
}\r
}\r