Routines implements SIMPLE_TEXT_IN protocol's interfaces based on 8042 interfaces\r
provided by Ps2KbdCtrller.c.\r
\r
-Copyright (c) 2006 - 2011, 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
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
EFI_KEY_DATA KeyData;\r
\r
ConsoleIn = KEYBOARD_CONSOLE_IN_DEV_FROM_THIS (This);\r
- \r
+\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
if (KeyData.Key.ScanCode == SCAN_NULL && KeyData.Key.UnicodeChar == CHAR_NULL) {\r
continue;\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
+ }\r
+ }\r
+\r
CopyMem (Key, &KeyData.Key, sizeof (EFI_INPUT_KEY));\r
return EFI_SUCCESS;\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\r
+ are 0, then any incomplete keystroke will trigger a notification of\r
+ 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
IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,\r
IN EFI_KEY_DATA *KeyData,\r
IN EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction,\r
- OUT EFI_HANDLE *NotifyHandle\r
+ OUT VOID **NotifyHandle\r
)\r
{\r
EFI_STATUS Status;\r
);\r
if (IsKeyRegistered (&CurrentNotify->KeyData, KeyData)) {\r
if (CurrentNotify->KeyNotificationFn == KeyNotificationFunction) {\r
- *NotifyHandle = CurrentNotify->NotifyHandle;\r
+ *NotifyHandle = CurrentNotify;\r
Status = EFI_SUCCESS;\r
goto Exit;\r
}\r
\r
NewNotify->Signature = KEYBOARD_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 (&ConsoleInDev->NotifyList, &NewNotify->NotifyEntry);\r
\r
- *NotifyHandle = NewNotify->NotifyHandle;\r
+ *NotifyHandle = NewNotify;\r
Status = EFI_SUCCESS;\r
\r
Exit:\r
EFIAPI\r
KeyboardUnregisterKeyNotify (\r
IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,\r
- IN EFI_HANDLE NotificationHandle\r
+ IN VOID *NotificationHandle\r
)\r
{\r
EFI_STATUS Status;\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
- if (((KEYBOARD_CONSOLE_IN_EX_NOTIFY *) NotificationHandle)->Signature != KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
ConsoleInDev = TEXT_INPUT_EX_KEYBOARD_CONSOLE_IN_DEV_FROM_THIS (This);\r
\r
//\r
NotifyEntry,\r
KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE\r
);\r
- if (CurrentNotify->NotifyHandle == NotificationHandle) {\r
+ if (CurrentNotify == NotificationHandle) {\r
//\r
// Remove the notification function from NotifyList and free resources\r
//\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
+ 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
+\r