Routines implements SIMPLE_TEXT_IN protocol's interfaces based on 8042 interfaces\r
provided by Ps2KbdCtrller.c.\r
\r
-Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
-\r
#include "Ps2Keyboard.h"\r
\r
/**\r
**/\r
BOOLEAN\r
IsEfikeyBufEmpty (\r
- IN EFI_KEY_QUEUE *Queue\r
+ IN EFI_KEY_QUEUE *Queue\r
)\r
{\r
- return (BOOLEAN) (Queue->Head == Queue->Tail);\r
+ return (BOOLEAN)(Queue->Head == Queue->Tail);\r
}\r
\r
/**\r
**/\r
EFI_STATUS\r
PopEfikeyBufHead (\r
- IN EFI_KEY_QUEUE *Queue,\r
- OUT EFI_KEY_DATA *KeyData OPTIONAL\r
+ IN EFI_KEY_QUEUE *Queue,\r
+ OUT EFI_KEY_DATA *KeyData OPTIONAL\r
)\r
{\r
if (IsEfikeyBufEmpty (Queue)) {\r
return EFI_NOT_READY;\r
}\r
+\r
//\r
// Retrieve and remove the values\r
//\r
if (KeyData != NULL) {\r
CopyMem (KeyData, &Queue->Buffer[Queue->Head], sizeof (EFI_KEY_DATA));\r
}\r
+\r
Queue->Head = (Queue->Head + 1) % KEYBOARD_EFI_KEY_MAX_COUNT;\r
return EFI_SUCCESS;\r
}\r
**/\r
VOID\r
PushEfikeyBufTail (\r
- IN EFI_KEY_QUEUE *Queue,\r
- IN EFI_KEY_DATA *KeyData\r
+ IN EFI_KEY_QUEUE *Queue,\r
+ IN EFI_KEY_DATA *KeyData\r
)\r
{\r
if ((Queue->Tail + 1) % KEYBOARD_EFI_KEY_MAX_COUNT == Queue->Head) {\r
//\r
PopEfikeyBufHead (Queue, NULL);\r
}\r
+\r
CopyMem (&Queue->Buffer[Queue->Tail], KeyData, sizeof (EFI_KEY_DATA));\r
Queue->Tail = (Queue->Tail + 1) % KEYBOARD_EFI_KEY_MAX_COUNT;\r
}\r
\r
/**\r
- Judge whether is a registed key\r
+ Judge whether is a registered key\r
\r
@param RegsiteredData A pointer to a buffer that is filled in with the keystroke\r
state data for the key that was registered.\r
state data for the key that was pressed.\r
\r
@retval TRUE Key be pressed matches a registered key.\r
- @retval FLASE Match failed.\r
+ @retval FALSE Match failed.\r
\r
**/\r
BOOLEAN\r
ASSERT (RegsiteredData != NULL && InputData != NULL);\r
\r
if ((RegsiteredData->Key.ScanCode != InputData->Key.ScanCode) ||\r
- (RegsiteredData->Key.UnicodeChar != InputData->Key.UnicodeChar)) {\r
+ (RegsiteredData->Key.UnicodeChar != InputData->Key.UnicodeChar))\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
+ if ((RegsiteredData->KeyState.KeyShiftState != 0) &&\r
+ (RegsiteredData->KeyState.KeyShiftState != InputData->KeyState.KeyShiftState))\r
+ {\r
return FALSE;\r
}\r
- if (RegsiteredData->KeyState.KeyToggleState != 0 &&\r
- RegsiteredData->KeyState.KeyToggleState != InputData->KeyState.KeyToggleState) {\r
+\r
+ if ((RegsiteredData->KeyState.KeyToggleState != 0) &&\r
+ (RegsiteredData->KeyState.KeyToggleState != InputData->KeyState.KeyToggleState))\r
+ {\r
return FALSE;\r
}\r
\r
return TRUE;\r
-\r
}\r
\r
/**\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
+ be used to test for existence of a keystroke via WaitForEvent () call.\r
\r
@param ConsoleInDev Ps2 Keyboard private structure\r
@param KeyData A pointer to a buffer that is filled in with the keystroke\r
\r
\r
@retval EFI_SUCCESS The keystroke information was returned.\r
- @retval EFI_NOT_READY There was no keystroke data availiable.\r
+ @retval EFI_NOT_READY There was no keystroke data available.\r
@retval EFI_DEVICE_ERROR The keystroke information was not returned due to\r
hardware errors.\r
@retval EFI_INVALID_PARAMETER KeyData is NULL.\r
**/\r
EFI_STATUS\r
KeyboardReadKeyStrokeWorker (\r
- IN KEYBOARD_CONSOLE_IN_DEV *ConsoleInDev,\r
- OUT EFI_KEY_DATA *KeyData\r
+ IN KEYBOARD_CONSOLE_IN_DEV *ConsoleInDev,\r
+ OUT EFI_KEY_DATA *KeyData\r
)\r
\r
{\r
- EFI_STATUS Status;\r
- EFI_TPL OldTpl;\r
+ EFI_STATUS Status;\r
+ EFI_TPL OldTpl;\r
\r
if (KeyData == NULL) {\r
return EFI_INVALID_PARAMETER;\r
Status = EFI_DEVICE_ERROR;\r
} else {\r
Status = PopEfikeyBufHead (&ConsoleInDev->EfiKeyQueue, KeyData);\r
+ if (Status == EFI_NOT_READY) {\r
+ ZeroMem (&KeyData->Key, sizeof (KeyData->Key));\r
+ InitializeKeyState (ConsoleInDev, &KeyData->KeyState);\r
+ }\r
}\r
\r
gBS->RestoreTPL (OldTpl);\r
IN BOOLEAN ExtendedVerification\r
)\r
{\r
- EFI_STATUS Status;\r
- KEYBOARD_CONSOLE_IN_DEV *ConsoleIn;\r
- EFI_TPL OldTpl;\r
+ EFI_STATUS Status;\r
+ KEYBOARD_CONSOLE_IN_DEV *ConsoleIn;\r
+ EFI_TPL OldTpl;\r
\r
ConsoleIn = KEYBOARD_CONSOLE_IN_DEV_FROM_THIS (This);\r
if (ConsoleIn->KeyboardErr) {\r
ConsoleIn->DevicePath\r
);\r
}\r
+\r
//\r
// Report the status If keyboard is locked\r
//\r
OUT EFI_INPUT_KEY *Key\r
)\r
{\r
- EFI_STATUS Status;\r
- KEYBOARD_CONSOLE_IN_DEV *ConsoleIn;\r
- EFI_KEY_DATA KeyData;\r
+ EFI_STATUS Status;\r
+ KEYBOARD_CONSOLE_IN_DEV *ConsoleIn;\r
+ EFI_KEY_DATA KeyData;\r
\r
ConsoleIn = KEYBOARD_CONSOLE_IN_DEV_FROM_THIS (This);\r
\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
+\r
//\r
// If it is partial keystroke, skip it.\r
//\r
- if (KeyData.Key.ScanCode == SCAN_NULL && KeyData.Key.UnicodeChar == CHAR_NULL) {\r
+ if ((KeyData.Key.ScanCode == SCAN_NULL) && (KeyData.Key.UnicodeChar == CHAR_NULL)) {\r
continue;\r
}\r
+\r
//\r
// Translate the CTRL-Alpha characters to their corresponding control value\r
// (ctrl-a = 0x0001 through ctrl-Z = 0x001A)\r
//\r
if ((KeyData.KeyState.KeyShiftState & (EFI_LEFT_CONTROL_PRESSED | EFI_RIGHT_CONTROL_PRESSED)) != 0) {\r
- if (KeyData.Key.UnicodeChar >= L'a' && KeyData.Key.UnicodeChar <= L'z') {\r
- KeyData.Key.UnicodeChar = (CHAR16) (KeyData.Key.UnicodeChar - L'a' + 1);\r
- } else if (KeyData.Key.UnicodeChar >= L'A' && KeyData.Key.UnicodeChar <= L'Z') {\r
- KeyData.Key.UnicodeChar = (CHAR16) (KeyData.Key.UnicodeChar - L'A' + 1);\r
+ if ((KeyData.Key.UnicodeChar >= L'a') && (KeyData.Key.UnicodeChar <= L'z')) {\r
+ KeyData.Key.UnicodeChar = (CHAR16)(KeyData.Key.UnicodeChar - L'a' + 1);\r
+ } else if ((KeyData.Key.UnicodeChar >= L'A') && (KeyData.Key.UnicodeChar <= L'Z')) {\r
+ KeyData.Key.UnicodeChar = (CHAR16)(KeyData.Key.UnicodeChar - L'A' + 1);\r
}\r
}\r
\r
Signal the event if there is key available\r
\r
@param Event the event object\r
- @param Context waitting context\r
+ @param Context waiting context\r
\r
**/\r
VOID\r
EFIAPI\r
KeyboardWaitForKey (\r
- IN EFI_EVENT Event,\r
- IN VOID *Context\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
)\r
{\r
- EFI_TPL OldTpl;\r
- KEYBOARD_CONSOLE_IN_DEV *ConsoleIn;\r
- EFI_KEY_DATA KeyData;\r
+ EFI_TPL OldTpl;\r
+ KEYBOARD_CONSOLE_IN_DEV *ConsoleIn;\r
+ EFI_KEY_DATA KeyData;\r
\r
- ConsoleIn = (KEYBOARD_CONSOLE_IN_DEV *) Context;\r
+ ConsoleIn = (KEYBOARD_CONSOLE_IN_DEV *)Context;\r
\r
//\r
// Enter critical section\r
\r
if (!ConsoleIn->KeyboardErr) {\r
//\r
- // WaitforKey doesn't suppor the partial key.\r
+ // WaitforKey doesn't support 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
&(ConsoleIn->EfiKeyQueue.Buffer[ConsoleIn->EfiKeyQueue.Head]),\r
sizeof (EFI_KEY_DATA)\r
);\r
- if (KeyData.Key.ScanCode == SCAN_NULL && KeyData.Key.UnicodeChar == CHAR_NULL) {\r
+ if ((KeyData.Key.ScanCode == SCAN_NULL) && (KeyData.Key.UnicodeChar == CHAR_NULL)) {\r
PopEfikeyBufHead (&ConsoleIn->EfiKeyQueue, &KeyData);\r
continue;\r
}\r
+\r
//\r
// if there is pending value key, signal the event.\r
//\r
break;\r
}\r
}\r
+\r
//\r
// Leave critical section and return\r
//\r
VOID\r
EFIAPI\r
KeyboardWaitForKeyEx (\r
- IN EFI_EVENT Event,\r
- IN VOID *Context\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
)\r
\r
{\r
}\r
\r
/**\r
- Reset the input device and optionaly run diagnostics\r
+ Reset the input device and optionally run diagnostics\r
\r
@param This Protocol instance pointer.\r
@param ExtendedVerification Driver may perform diagnostics on reset.\r
)\r
\r
{\r
- KEYBOARD_CONSOLE_IN_DEV *ConsoleInDev;\r
+ KEYBOARD_CONSOLE_IN_DEV *ConsoleInDev;\r
\r
ConsoleInDev = TEXT_INPUT_EX_KEYBOARD_CONSOLE_IN_DEV_FROM_THIS (This);\r
\r
\r
/**\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
+ be used to test for existence of a keystroke via WaitForEvent () call.\r
\r
\r
@param This Protocol instance pointer.\r
state data for the key that was pressed.\r
\r
@retval EFI_SUCCESS The keystroke information was returned.\r
- @retval EFI_NOT_READY There was no keystroke data availiable.\r
+ @retval EFI_NOT_READY There was no keystroke data available.\r
@retval EFI_DEVICE_ERROR The keystroke information was not returned due to\r
hardware errors.\r
@retval EFI_INVALID_PARAMETER KeyData is NULL.\r
EFI_STATUS\r
EFIAPI\r
KeyboardReadKeyStrokeEx (\r
- IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,\r
- OUT EFI_KEY_DATA *KeyData\r
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,\r
+ OUT EFI_KEY_DATA *KeyData\r
)\r
\r
{\r
- KEYBOARD_CONSOLE_IN_DEV *ConsoleInDev;\r
+ KEYBOARD_CONSOLE_IN_DEV *ConsoleInDev;\r
\r
if (KeyData == NULL) {\r
return EFI_INVALID_PARAMETER;\r
)\r
\r
{\r
- EFI_STATUS Status;\r
- KEYBOARD_CONSOLE_IN_DEV *ConsoleInDev;\r
- EFI_TPL OldTpl;\r
+ EFI_STATUS Status;\r
+ KEYBOARD_CONSOLE_IN_DEV *ConsoleInDev;\r
+ EFI_TPL OldTpl;\r
\r
if (KeyToggleState == NULL) {\r
return EFI_INVALID_PARAMETER;\r
if ((*KeyToggleState & EFI_SCROLL_LOCK_ACTIVE) == EFI_SCROLL_LOCK_ACTIVE) {\r
ConsoleInDev->ScrollLock = TRUE;\r
}\r
+\r
if ((*KeyToggleState & EFI_NUM_LOCK_ACTIVE) == EFI_NUM_LOCK_ACTIVE) {\r
ConsoleInDev->NumLock = TRUE;\r
}\r
+\r
if ((*KeyToggleState & EFI_CAPS_LOCK_ACTIVE) == EFI_CAPS_LOCK_ACTIVE) {\r
ConsoleInDev->CapsLock = TRUE;\r
}\r
+\r
if ((*KeyToggleState & EFI_KEY_STATE_EXPOSED) == EFI_KEY_STATE_EXPOSED) {\r
ConsoleInDev->IsSupportPartialKey = TRUE;\r
}\r
gBS->RestoreTPL (OldTpl);\r
\r
return Status;\r
-\r
}\r
\r
/**\r
\r
@param This Protocol instance pointer.\r
@param KeyData A pointer to a buffer that is filled in with the keystroke\r
- information data for the key that was pressed.\r
+ information data for the key that was pressed. If KeyData.Key,\r
+ KeyData.KeyState.KeyToggleState and KeyData.KeyState.KeyShiftState are 0,\r
+ then any incomplete keystroke will trigger a notification of the KeyNotificationFunction.\r
@param KeyNotificationFunction Points to the function to be called when the key\r
- sequence is typed specified by KeyData.\r
+ sequence is typed specified by KeyData. This notification function\r
+ should be called at <=TPL_CALLBACK.\r
@param NotifyHandle Points to the unique handle assigned to the registered notification.\r
\r
@retval EFI_SUCCESS The notification function was registered successfully.\r
- @retval EFI_OUT_OF_RESOURCES Unable to allocate resources for necesssary data structures.\r
+ @retval EFI_OUT_OF_RESOURCES Unable to allocate resources for necessary data structures.\r
@retval EFI_INVALID_PARAMETER KeyData or NotifyHandle or KeyNotificationFunction is NULL.\r
\r
**/\r
OUT VOID **NotifyHandle\r
)\r
{\r
- EFI_STATUS Status;\r
- KEYBOARD_CONSOLE_IN_DEV *ConsoleInDev;\r
- EFI_TPL OldTpl;\r
- LIST_ENTRY *Link;\r
- KEYBOARD_CONSOLE_IN_EX_NOTIFY *CurrentNotify;\r
- KEYBOARD_CONSOLE_IN_EX_NOTIFY *NewNotify;\r
-\r
- if (KeyData == NULL || NotifyHandle == NULL || KeyNotificationFunction == NULL) {\r
+ EFI_STATUS Status;\r
+ KEYBOARD_CONSOLE_IN_DEV *ConsoleInDev;\r
+ EFI_TPL OldTpl;\r
+ LIST_ENTRY *Link;\r
+ KEYBOARD_CONSOLE_IN_EX_NOTIFY *CurrentNotify;\r
+ KEYBOARD_CONSOLE_IN_EX_NOTIFY *NewNotify;\r
+\r
+ if ((KeyData == NULL) || (NotifyHandle == NULL) || (KeyNotificationFunction == NULL)) {\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
if (IsKeyRegistered (&CurrentNotify->KeyData, KeyData)) {\r
if (CurrentNotify->KeyNotificationFn == KeyNotificationFunction) {\r
*NotifyHandle = CurrentNotify;\r
- Status = EFI_SUCCESS;\r
+ Status = EFI_SUCCESS;\r
goto Exit;\r
}\r
}\r
//\r
// Allocate resource to save the notification function\r
//\r
- NewNotify = (KEYBOARD_CONSOLE_IN_EX_NOTIFY *) AllocateZeroPool (sizeof (KEYBOARD_CONSOLE_IN_EX_NOTIFY));\r
+ NewNotify = (KEYBOARD_CONSOLE_IN_EX_NOTIFY *)AllocateZeroPool (sizeof (KEYBOARD_CONSOLE_IN_EX_NOTIFY));\r
if (NewNotify == NULL) {\r
Status = EFI_OUT_OF_RESOURCES;\r
goto Exit;\r
CopyMem (&NewNotify->KeyData, KeyData, sizeof (EFI_KEY_DATA));\r
InsertTailList (&ConsoleInDev->NotifyList, &NewNotify->NotifyEntry);\r
\r
- *NotifyHandle = NewNotify;\r
- Status = EFI_SUCCESS;\r
+ *NotifyHandle = NewNotify;\r
+ Status = EFI_SUCCESS;\r
\r
Exit:\r
//\r
//\r
gBS->RestoreTPL (OldTpl);\r
return Status;\r
-\r
}\r
\r
/**\r
IN VOID *NotificationHandle\r
)\r
{\r
- EFI_STATUS Status;\r
- KEYBOARD_CONSOLE_IN_DEV *ConsoleInDev;\r
- EFI_TPL OldTpl;\r
- LIST_ENTRY *Link;\r
- KEYBOARD_CONSOLE_IN_EX_NOTIFY *CurrentNotify;\r
+ EFI_STATUS Status;\r
+ KEYBOARD_CONSOLE_IN_DEV *ConsoleInDev;\r
+ EFI_TPL OldTpl;\r
+ LIST_ENTRY *Link;\r
+ KEYBOARD_CONSOLE_IN_EX_NOTIFY *CurrentNotify;\r
\r
if (NotificationHandle == NULL) {\r
return EFI_INVALID_PARAMETER;\r
return Status;\r
}\r
\r
+/**\r
+ Process key notify.\r
+\r
+ @param Event Indicates the event that invoke this function.\r
+ @param Context Indicates the calling context.\r
+**/\r
+VOID\r
+EFIAPI\r
+KeyNotifyProcessHandler (\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ KEYBOARD_CONSOLE_IN_DEV *ConsoleIn;\r
+ EFI_KEY_DATA KeyData;\r
+ LIST_ENTRY *Link;\r
+ LIST_ENTRY *NotifyList;\r
+ KEYBOARD_CONSOLE_IN_EX_NOTIFY *CurrentNotify;\r
+ EFI_TPL OldTpl;\r
+\r
+ ConsoleIn = (KEYBOARD_CONSOLE_IN_DEV *)Context;\r
+\r
+ //\r
+ // Invoke notification functions.\r
+ //\r
+ NotifyList = &ConsoleIn->NotifyList;\r
+ while (TRUE) {\r
+ //\r
+ // Enter critical section\r
+ //\r
+ OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
+ Status = PopEfikeyBufHead (&ConsoleIn->EfiKeyQueueForNotify, &KeyData);\r
+ //\r
+ // Leave critical section\r
+ //\r
+ gBS->RestoreTPL (OldTpl);\r
+ if (EFI_ERROR (Status)) {\r
+ break;\r
+ }\r
+\r
+ for (Link = GetFirstNode (NotifyList); !IsNull (NotifyList, Link); Link = GetNextNode (NotifyList, Link)) {\r
+ CurrentNotify = CR (Link, KEYBOARD_CONSOLE_IN_EX_NOTIFY, NotifyEntry, KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE);\r
+ if (IsKeyRegistered (&CurrentNotify->KeyData, &KeyData)) {\r
+ CurrentNotify->KeyNotificationFn (&KeyData);\r
+ }\r
+ }\r
+ }\r
+}\r