/**@file\r
- Implementation for EFI_SIMPLE_TEXT_INPUT_PROTOCOL protocol.\r
- \r
+ Implementation for EFI_SIMPLE_TEXT_INPUT_PROTOCOL protocol.\r
+ \r
Copyright (c) 2006 - 2007 Intel Corporation. <BR>\r
All rights reserved. This program and the accompanying materials \r
are licensed and made available under the terms and conditions of the BSD License \r
#include "Terminal.h"\r
\r
\r
+STATIC\r
+EFI_STATUS\r
+ReadKeyStrokeWorker (\r
+ IN TERMINAL_DEV *TerminalDevice,\r
+ OUT EFI_KEY_DATA *KeyData\r
+ )\r
+/*++\r
+\r
+ Routine Description:\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
+ TerminalDevice - Terminal driver private structure\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
+ hardware errors.\r
+ EFI_INVALID_PARAMETER - KeyData is NULL. \r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ LIST_ENTRY *Link;\r
+ TERMINAL_CONSOLE_IN_EX_NOTIFY *CurrentNotify;\r
+\r
+ if (KeyData == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ } \r
+\r
+ //\r
+ // Initialize *Key to nonsense value.\r
+ //\r
+ KeyData->Key.ScanCode = SCAN_NULL;\r
+ KeyData->Key.UnicodeChar = 0;\r
+\r
+ Status = TerminalConInCheckForKey (&TerminalDevice->SimpleInput);\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_NOT_READY;\r
+ }\r
+\r
+ if (!EfiKeyFiFoRemoveOneKey (TerminalDevice, &KeyData->Key)) {\r
+ return EFI_NOT_READY;\r
+ }\r
+\r
+ KeyData->KeyState.KeyShiftState = 0;\r
+ KeyData->KeyState.KeyToggleState = 0;\r
+\r
+ //\r
+ // Invoke notification functions if exist\r
+ //\r
+ for (Link = TerminalDevice->NotifyList.ForwardLink; Link != &TerminalDevice->NotifyList; Link = Link->ForwardLink) {\r
+ CurrentNotify = CR (\r
+ Link, \r
+ TERMINAL_CONSOLE_IN_EX_NOTIFY, \r
+ NotifyEntry, \r
+ TERMINAL_CONSOLE_IN_EX_NOTIFY_SIGNATURE\r
+ );\r
+ if (IsKeyRegistered (&CurrentNotify->KeyData, KeyData)) { \r
+ CurrentNotify->KeyNotificationFn (KeyData);\r
+ }\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+\r
+}\r
+\r
+\r
EFI_STATUS\r
EFIAPI\r
TerminalConInReset (\r
{\r
TERMINAL_DEV *TerminalDevice;\r
EFI_STATUS Status;\r
+ EFI_KEY_DATA KeyData;\r
\r
- //\r
- // Initialize *Key to nonsense value.\r
- //\r
- Key->ScanCode = SCAN_NULL;\r
- Key->UnicodeChar = 0;\r
//\r
// get TERMINAL_DEV from "This" parameter.\r
//\r
TerminalDevice = TERMINAL_CON_IN_DEV_FROM_THIS (This);\r
\r
- Status = TerminalConInCheckForKey (This);\r
+ Status = ReadKeyStrokeWorker (TerminalDevice, &KeyData);\r
if (EFI_ERROR (Status)) {\r
- return EFI_NOT_READY;\r
+ return Status;\r
+ }\r
+\r
+ CopyMem (Key, &KeyData.Key, sizeof (EFI_INPUT_KEY));\r
+\r
+ return EFI_SUCCESS;\r
+\r
+}\r
+\r
+\r
+BOOLEAN\r
+IsKeyRegistered (\r
+ IN EFI_KEY_DATA *RegsiteredData,\r
+ IN EFI_KEY_DATA *InputData\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+Arguments:\r
+\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
+ 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
+--*/\r
+{\r
+ ASSERT (RegsiteredData != NULL && InputData != NULL);\r
+ \r
+ if ((RegsiteredData->Key.ScanCode != InputData->Key.ScanCode) ||\r
+ (RegsiteredData->Key.UnicodeChar != InputData->Key.UnicodeChar)) {\r
+ return FALSE; \r
+ } \r
+ \r
+ return TRUE;\r
+}\r
+\r
+\r
+VOID\r
+EFIAPI\r
+TerminalConInWaitForKeyEx (\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
+ )\r
+/*++\r
+ Routine Description:\r
+ \r
+ Event notification function for EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL.WaitForKeyEx event\r
+ Signal the event if there is key available \r
+ \r
+ Arguments:\r
+ \r
+ Event - Indicates the event that invoke this function.\r
+ \r
+ Context - Indicates the calling context.\r
+ \r
+ Returns:\r
+ \r
+ N/A\r
+ \r
+--*/\r
+{\r
+ TERMINAL_DEV *TerminalDevice;\r
+ \r
+ TerminalDevice = TERMINAL_CON_IN_EX_DEV_FROM_THIS (Context);\r
+\r
+ TerminalConInWaitForKey (Event, &TerminalDevice->SimpleInput);\r
+\r
+}\r
+\r
+//\r
+// Simple Text Input Ex protocol functions\r
+//\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+TerminalConInResetEx (\r
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,\r
+ IN BOOLEAN ExtendedVerification\r
+ )\r
+/*++\r
+\r
+ Routine Description:\r
+ Reset the input device and optionaly run diagnostics\r
+\r
+ Arguments:\r
+ This - Protocol instance pointer.\r
+ ExtendedVerification - Driver may perform diagnostics on reset.\r
+\r
+ Returns:\r
+ EFI_SUCCESS - The device was reset.\r
+ EFI_DEVICE_ERROR - The device is not functioning properly and could \r
+ not be reset.\r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ TERMINAL_DEV *TerminalDevice;\r
+\r
+ TerminalDevice = TERMINAL_CON_IN_EX_DEV_FROM_THIS (This);\r
+\r
+ Status = TerminalDevice->SimpleInput.Reset (&TerminalDevice->SimpleInput, ExtendedVerification);\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_DEVICE_ERROR;\r
}\r
\r
- EfiKeyFiFoRemoveOneKey (TerminalDevice, Key);\r
+ return EFI_SUCCESS;\r
+ \r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+TerminalConInReadKeyStrokeEx (\r
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,\r
+ OUT EFI_KEY_DATA *KeyData\r
+ )\r
+/*++\r
+\r
+ Routine Description:\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
+ 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
+ hardware errors.\r
+ EFI_INVALID_PARAMETER - KeyData is NULL. \r
+\r
+--*/\r
+{\r
+ TERMINAL_DEV *TerminalDevice;\r
+\r
+ if (KeyData == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ } \r
+\r
+ TerminalDevice = TERMINAL_CON_IN_EX_DEV_FROM_THIS (This);\r
+\r
+ return ReadKeyStrokeWorker (TerminalDevice, KeyData);\r
+\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+TerminalConInSetState (\r
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,\r
+ IN EFI_KEY_TOGGLE_STATE *KeyToggleState\r
+ )\r
+/*++\r
+\r
+ Routine Description:\r
+ Set certain state for the input device.\r
+\r
+ Arguments:\r
+ This - Protocol instance pointer.\r
+ KeyToggleState - A pointer to the EFI_KEY_TOGGLE_STATE to set the \r
+ state for the input device.\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
+ 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
+\r
+--*/ \r
+{\r
+ if (KeyToggleState == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
\r
return EFI_SUCCESS;\r
+}\r
\r
+EFI_STATUS\r
+EFIAPI\r
+TerminalConInRegisterKeyNotify (\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
+ )\r
+/*++\r
+\r
+ Routine Description:\r
+ Register a notification function for a particular keystroke for the input device.\r
+\r
+ Arguments:\r
+ This - Protocol instance pointer.\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
+\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
+{\r
+ EFI_STATUS Status;\r
+ TERMINAL_DEV *TerminalDevice;\r
+ TERMINAL_CONSOLE_IN_EX_NOTIFY *NewNotify;\r
+ LIST_ENTRY *Link;\r
+ TERMINAL_CONSOLE_IN_EX_NOTIFY *CurrentNotify; \r
+\r
+ if (KeyData == NULL || NotifyHandle == NULL || KeyNotificationFunction == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ TerminalDevice = TERMINAL_CON_IN_EX_DEV_FROM_THIS (This);\r
+\r
+ //\r
+ // Return EFI_SUCCESS if the (KeyData, NotificationFunction) is already registered.\r
+ //\r
+ for (Link = TerminalDevice->NotifyList.ForwardLink; Link != &TerminalDevice->NotifyList; Link = Link->ForwardLink) {\r
+ CurrentNotify = CR (\r
+ Link, \r
+ TERMINAL_CONSOLE_IN_EX_NOTIFY, \r
+ NotifyEntry, \r
+ TERMINAL_CONSOLE_IN_EX_NOTIFY_SIGNATURE\r
+ );\r
+ if (IsKeyRegistered (&CurrentNotify->KeyData, KeyData)) { \r
+ if (CurrentNotify->KeyNotificationFn == KeyNotificationFunction) {\r
+ *NotifyHandle = CurrentNotify->NotifyHandle; \r
+ return EFI_SUCCESS;\r
+ }\r
+ }\r
+ }\r
+\r
+ //\r
+ // Allocate resource to save the notification function\r
+ // \r
+ NewNotify = (TERMINAL_CONSOLE_IN_EX_NOTIFY *) AllocateZeroPool (sizeof (TERMINAL_CONSOLE_IN_EX_NOTIFY));\r
+ if (NewNotify == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ } \r
+\r
+ NewNotify->Signature = TERMINAL_CONSOLE_IN_EX_NOTIFY_SIGNATURE; \r
+ NewNotify->KeyNotificationFn = KeyNotificationFunction;\r
+ CopyMem (&NewNotify->KeyData, KeyData, sizeof (KeyData));\r
+ InsertTailList (&TerminalDevice->NotifyList, &NewNotify->NotifyEntry);\r
+ //\r
+ // Use gSimpleTextInExNotifyGuid to get a valid EFI_HANDLE\r
+ // \r
+ Status = gBS->InstallMultipleProtocolInterfaces (\r
+ &NewNotify->NotifyHandle,\r
+ &gSimpleTextInExNotifyGuid,\r
+ NULL,\r
+ NULL\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+ *NotifyHandle = NewNotify->NotifyHandle; \r
+\r
+ return EFI_SUCCESS;\r
}\r
\r
+EFI_STATUS\r
+EFIAPI\r
+TerminalConInUnregisterKeyNotify (\r
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,\r
+ IN EFI_HANDLE NotificationHandle\r
+ )\r
+/*++\r
+\r
+ Routine Description:\r
+ Remove a registered notification function from a particular keystroke.\r
+\r
+ Arguments:\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
+ EFI_NOT_FOUND - Can not find the matching entry in database. \r
+ \r
+--*/ \r
+{\r
+ EFI_STATUS Status;\r
+ TERMINAL_DEV *TerminalDevice;\r
+ LIST_ENTRY *Link;\r
+ TERMINAL_CONSOLE_IN_EX_NOTIFY *CurrentNotify;\r
+\r
+ if (NotificationHandle == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ } \r
+ \r
+ Status = gBS->OpenProtocol (\r
+ NotificationHandle,\r
+ &gSimpleTextInExNotifyGuid,\r
+ NULL,\r
+ NULL,\r
+ NULL,\r
+ EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ TerminalDevice = TERMINAL_CON_IN_EX_DEV_FROM_THIS (This);\r
+\r
+ for (Link = TerminalDevice->NotifyList.ForwardLink; Link != &TerminalDevice->NotifyList; Link = Link->ForwardLink) {\r
+ CurrentNotify = CR (\r
+ Link, \r
+ TERMINAL_CONSOLE_IN_EX_NOTIFY, \r
+ NotifyEntry, \r
+ TERMINAL_CONSOLE_IN_EX_NOTIFY_SIGNATURE\r
+ );\r
+ if (CurrentNotify->NotifyHandle == NotificationHandle) {\r
+ //\r
+ // Remove the notification function from NotifyList and free resources\r
+ //\r
+ RemoveEntryList (&CurrentNotify->NotifyEntry); \r
+ Status = gBS->UninstallMultipleProtocolInterfaces (\r
+ CurrentNotify->NotifyHandle,\r
+ &gSimpleTextInExNotifyGuid,\r
+ NULL,\r
+ NULL\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+ gBS->FreePool (CurrentNotify); \r
+ return EFI_SUCCESS;\r
+ }\r
+ }\r
+ \r
+ return EFI_NOT_FOUND; \r
+}\r
+\r
+\r
VOID\r
TranslateRawDataToEfiKey (\r
IN TERMINAL_DEV *TerminalDevice\r
| F9 | 0x13 | ESC [ U | ESC 9 | ESC O p |\r
| F10 | 0x14 | ESC [ V | ESC 0 | ESC O M |\r
| Escape | 0x17 | ESC | ESC | ESC |\r
-+=========+======+===========+==========+=========+\r
+| F11 | 0x15 | | ESC ! | |\r
+| F12 | 0x16 | | ESC @ | |\r
++=========+======+===========+==========+==========+\r
\r
Special Mappings\r
================\r
case '0': \r
Key.ScanCode = SCAN_F10; \r
break;\r
+ case '!':\r
+ Key.ScanCode = SCAN_F11;\r
+ break;\r
+ case '@':\r
+ Key.ScanCode = SCAN_F12;\r
+ break; \r
case 'h': \r
Key.ScanCode = SCAN_HOME; \r
break;\r
if (UnicodeChar == ESC) {\r
TerminalDevice->InputState = INPUT_STATE_ESC;\r
}\r
+\r
+ if (UnicodeChar == CSI) {\r
+ TerminalDevice->InputState = INPUT_STATE_CSI;\r
+ }\r
\r
if (TerminalDevice->InputState != INPUT_STATE_DEFAULT) {\r
Status = gBS->SetTimer(\r