-/**@file\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
-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
+/** @file\r
+ Implementation for EFI_SIMPLE_TEXT_INPUT_PROTOCOL protocol.\r
+\r
+(C) Copyright 2014 Hewlett-Packard Development Company, L.P.<BR>\r
+Copyright (c) 2006 - 2014, 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
\r
**/\r
\r
#include "Terminal.h"\r
\r
\r
+/**\r
+ Reads the next keystroke from the input device. The WaitForKey Event can\r
+ be used to test for existence of a keystroke via WaitForEvent () call.\r
+\r
+ @param TerminalDevice Terminal driver private structure\r
+ @param KeyData A pointer to a buffer that is filled in with the\r
+ keystroke state data for the key that was\r
+ pressed.\r
+\r
+ @retval EFI_SUCCESS The keystroke information was returned.\r
+ @retval EFI_NOT_READY There was no keystroke data available.\r
+ @retval EFI_INVALID_PARAMETER KeyData is NULL.\r
+\r
+**/\r
+EFI_STATUS\r
+ReadKeyStrokeWorker (\r
+ IN TERMINAL_DEV *TerminalDevice,\r
+ OUT EFI_KEY_DATA *KeyData\r
+ )\r
+{\r
+ if (KeyData == NULL) {\r
+ return EFI_INVALID_PARAMETER;\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
+ return EFI_SUCCESS;\r
+\r
+}\r
+\r
+/**\r
+ Implements EFI_SIMPLE_TEXT_INPUT_PROTOCOL.Reset().\r
+ This driver only perform dependent serial device reset regardless of\r
+ the value of ExtendeVerification\r
+\r
+ @param This Indicates the calling context.\r
+ @param ExtendedVerification Skip by this driver.\r
+\r
+ @retval EFI_SUCCESS The reset operation succeeds.\r
+ @retval EFI_DEVICE_ERROR The dependent serial port reset fails.\r
+\r
+**/\r
EFI_STATUS\r
EFIAPI\r
TerminalConInReset (\r
IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,\r
IN BOOLEAN ExtendedVerification\r
)\r
-/*++\r
- Routine Description:\r
- \r
- Implements EFI_SIMPLE_TEXT_INPUT_PROTOCOL.Reset().\r
- This driver only perform dependent serial device reset regardless of \r
- the value of ExtendeVerification\r
- \r
- Arguments:\r
- \r
- This - Indicates the calling context.\r
- \r
- ExtendedVerification - Skip by this driver.\r
- \r
- Returns:\r
- \r
- EFI_SUCCESS\r
- The reset operation succeeds. \r
- \r
- EFI_DEVICE_ERROR\r
- The dependent serial port reset fails.\r
- \r
---*/\r
{\r
EFI_STATUS Status;\r
TERMINAL_DEV *TerminalDevice;\r
//\r
REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
EFI_PROGRESS_CODE,\r
- PcdGet32 (PcdStatusCodeValueRemoteConsoleReset),\r
+ (EFI_PERIPHERAL_REMOTE_CONSOLE | EFI_P_PC_RESET),\r
TerminalDevice->DevicePath\r
);\r
\r
Status = TerminalDevice->SerialIo->Reset (TerminalDevice->SerialIo);\r
\r
//\r
- // clear all the internal buffer for keys\r
+ // Make all the internal buffer empty for keys\r
//\r
- InitializeRawFiFo (TerminalDevice);\r
- InitializeUnicodeFiFo (TerminalDevice);\r
- InitializeEfiKeyFiFo (TerminalDevice);\r
+ TerminalDevice->RawFiFo->Head = TerminalDevice->RawFiFo->Tail;\r
+ TerminalDevice->UnicodeFiFo->Head = TerminalDevice->UnicodeFiFo->Tail;\r
+ TerminalDevice->EfiKeyFiFo->Head = TerminalDevice->EfiKeyFiFo->Tail;\r
\r
if (EFI_ERROR (Status)) {\r
REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
- PcdGet32 (PcdStatusCodeValueRemoteConsoleError),\r
+ (EFI_PERIPHERAL_REMOTE_CONSOLE | EFI_P_EC_CONTROLLER_ERROR),\r
TerminalDevice->DevicePath\r
);\r
}\r
return Status;\r
}\r
\r
+/**\r
+ Implements EFI_SIMPLE_TEXT_INPUT_PROTOCOL.ReadKeyStroke().\r
+\r
+ @param This Indicates the calling context.\r
+ @param Key A pointer to a buffer that is filled in with the\r
+ keystroke information for the key that was sent\r
+ from terminal.\r
+\r
+ @retval EFI_SUCCESS The keystroke information is returned successfully.\r
+ @retval EFI_NOT_READY There is no keystroke data available.\r
+ @retval EFI_DEVICE_ERROR The dependent serial device encounters error.\r
+\r
+**/\r
EFI_STATUS\r
EFIAPI\r
TerminalConInReadKeyStroke (\r
IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,\r
OUT EFI_INPUT_KEY *Key\r
)\r
-/*++\r
- Routine Description:\r
- \r
- Implements EFI_SIMPLE_TEXT_INPUT_PROTOCOL.ReadKeyStroke().\r
- \r
- Arguments:\r
- \r
- This - Indicates the calling context.\r
- \r
- Key - A pointer to a buffer that is filled in with the keystroke\r
- information for the key that was sent from terminal. \r
- \r
- Returns:\r
- \r
- EFI_SUCCESS\r
- The keystroke information is returned successfully.\r
- \r
- EFI_NOT_READY\r
- There is no keystroke data available.\r
- \r
- EFI_DEVICE_ERROR\r
- The dependent serial device encounters error.\r
- \r
---*/\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
- EfiKeyFiFoRemoveOneKey (TerminalDevice, Key);\r
+ CopyMem (Key, &KeyData.Key, sizeof (EFI_INPUT_KEY));\r
\r
return EFI_SUCCESS;\r
\r
}\r
\r
+/**\r
+ Check if the key already has been registered.\r
+\r
+ If both RegsiteredData and InputData is NULL, then ASSERT().\r
+\r
+ @param RegsiteredData A pointer to a buffer that is filled in with the\r
+ keystroke state data for the key that was\r
+ registered.\r
+ @param InputData A pointer to a buffer that is filled in with the\r
+ keystroke state data for the key that was\r
+ pressed.\r
+\r
+ @retval TRUE Key be pressed matches a registered key.\r
+ @retval FALSE Match failed.\r
+\r
+**/\r
+BOOLEAN\r
+IsKeyRegistered (\r
+ IN EFI_KEY_DATA *RegsiteredData,\r
+ IN EFI_KEY_DATA *InputData\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
+\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
+ @param Event Indicates the event that invoke this function.\r
+ @param Context Indicates the calling context.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+TerminalConInWaitForKeyEx (\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
+ )\r
+{\r
+ TerminalConInWaitForKey (Event, Context);\r
+}\r
+\r
+//\r
+// Simple Text Input Ex protocol functions\r
+//\r
+\r
+/**\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
+ @retval EFI_SUCCESS The device was reset.\r
+ @retval EFI_DEVICE_ERROR The device is not functioning properly and could\r
+ not be reset.\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
+ 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
+ return EFI_SUCCESS;\r
+\r
+}\r
+\r
+\r
+/**\r
+ Reads the next keystroke from the input device. The WaitForKey Event can\r
+ be used to test for existence of a keystroke via WaitForEvent () call.\r
+\r
+ @param This Protocol instance pointer.\r
+ @param KeyData A pointer to a buffer that is filled in with the\r
+ keystroke state data for the key that was\r
+ pressed.\r
+\r
+ @retval EFI_SUCCESS The keystroke information was returned.\r
+ @retval EFI_NOT_READY There was no keystroke data available.\r
+ @retval EFI_DEVICE_ERROR The keystroke information was not returned due\r
+ to hardware errors.\r
+ @retval EFI_INVALID_PARAMETER KeyData is NULL.\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
+ 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
+\r
+/**\r
+ Set certain state for the input device.\r
+\r
+ @param This Protocol instance pointer.\r
+ @param KeyToggleState A pointer to the EFI_KEY_TOGGLE_STATE to set the\r
+ state for the input device.\r
+\r
+ @retval EFI_SUCCESS The device state was set successfully.\r
+ @retval EFI_DEVICE_ERROR The device is not functioning correctly and\r
+ could not have the setting adjusted.\r
+ @retval EFI_UNSUPPORTED The device does not have the ability to set its\r
+ state.\r
+ @retval EFI_INVALID_PARAMETER KeyToggleState is NULL.\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
+ if (KeyToggleState == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ if ((*KeyToggleState & EFI_TOGGLE_STATE_VALID) != EFI_TOGGLE_STATE_VALID) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+ Register a notification function for a particular keystroke for the input device.\r
+\r
+ @param This Protocol instance pointer.\r
+ @param KeyData A pointer to a buffer that is filled in with the\r
+ keystroke information data for the key that was\r
+ pressed.\r
+ @param KeyNotificationFunction Points to the function to be called when the key\r
+ sequence is typed specified by KeyData.\r
+ @param NotifyHandle Points to the unique handle assigned to the\r
+ registered notification.\r
+\r
+ @retval EFI_SUCCESS The notification function was registered\r
+ successfully.\r
+ @retval EFI_OUT_OF_RESOURCES Unable to allocate resources for necessary data\r
+ structures.\r
+ @retval EFI_INVALID_PARAMETER KeyData or NotifyHandle is NULL.\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 VOID **NotifyHandle\r
+ )\r
+{\r
+ TERMINAL_DEV *TerminalDevice;\r
+ TERMINAL_CONSOLE_IN_EX_NOTIFY *NewNotify;\r
+ LIST_ENTRY *Link;\r
+ LIST_ENTRY *NotifyList;\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
+ NotifyList = &TerminalDevice->NotifyList;\r
+ for (Link = GetFirstNode (NotifyList); !IsNull (NotifyList,Link); Link = GetNextNode (NotifyList,Link)) {\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;\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 (EFI_KEY_DATA));\r
+ InsertTailList (&TerminalDevice->NotifyList, &NewNotify->NotifyEntry);\r
+\r
+ *NotifyHandle = NewNotify;\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+ Remove a registered notification function from a particular keystroke.\r
+\r
+ @param This Protocol instance pointer.\r
+ @param NotificationHandle The handle of the notification function being\r
+ unregistered.\r
+\r
+ @retval EFI_SUCCESS The notification function was unregistered\r
+ successfully.\r
+ @retval EFI_INVALID_PARAMETER The NotificationHandle is invalid.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+TerminalConInUnregisterKeyNotify (\r
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,\r
+ IN VOID *NotificationHandle\r
+ )\r
+{\r
+ TERMINAL_DEV *TerminalDevice;\r
+ LIST_ENTRY *Link;\r
+ TERMINAL_CONSOLE_IN_EX_NOTIFY *CurrentNotify;\r
+ LIST_ENTRY *NotifyList;\r
+\r
+ if (NotificationHandle == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ TerminalDevice = TERMINAL_CON_IN_EX_DEV_FROM_THIS (This);\r
+\r
+ NotifyList = &TerminalDevice->NotifyList;\r
+ for (Link = GetFirstNode (NotifyList); !IsNull (NotifyList,Link); Link = GetNextNode (NotifyList,Link)) {\r
+ CurrentNotify = CR (\r
+ Link,\r
+ TERMINAL_CONSOLE_IN_EX_NOTIFY,\r
+ NotifyEntry,\r
+ TERMINAL_CONSOLE_IN_EX_NOTIFY_SIGNATURE\r
+ );\r
+ if (CurrentNotify == NotificationHandle) {\r
+ //\r
+ // Remove the notification function from NotifyList and free resources\r
+ //\r
+ RemoveEntryList (&CurrentNotify->NotifyEntry);\r
+\r
+ gBS->FreePool (CurrentNotify);\r
+ return EFI_SUCCESS;\r
+ }\r
+ }\r
+\r
+ //\r
+ // Can not find the matching entry in database.\r
+ //\r
+ return EFI_INVALID_PARAMETER;\r
+}\r
+\r
+/**\r
+ Translate raw data into Unicode (according to different encode), and\r
+ translate Unicode into key information. (according to different standard).\r
+\r
+ @param TerminalDevice Terminal driver private structure.\r
+\r
+**/\r
VOID\r
TranslateRawDataToEfiKey (\r
IN TERMINAL_DEV *TerminalDevice\r
)\r
-/*++\r
- Step1: Turn raw data into Unicode (according to different encode).\r
- Step2: Translate Unicode into key information. \r
- (according to different terminal standard).\r
---*/\r
{\r
switch (TerminalDevice->TerminalType) {\r
\r
- case PcAnsiType:\r
- case VT100Type:\r
- case VT100PlusType:\r
+ case PCANSITYPE:\r
+ case VT100TYPE:\r
+ case VT100PLUSTYPE:\r
+ case TTYTERMTYPE:\r
AnsiRawDataToUnicode (TerminalDevice);\r
UnicodeToEfiKey (TerminalDevice);\r
break;\r
\r
- case VTUTF8Type:\r
+ case VTUTF8TYPE:\r
//\r
// Process all the raw data in the RawFIFO,\r
// put the processed key into UnicodeFIFO.\r
}\r
}\r
\r
+/**\r
+ Event notification function for EFI_SIMPLE_TEXT_INPUT_PROTOCOL.WaitForKey event\r
+ Signal the event if there is key available\r
+\r
+ @param Event Indicates the event that invoke this function.\r
+ @param Context Indicates the calling context.\r
+\r
+**/\r
VOID\r
EFIAPI\r
TerminalConInWaitForKey (\r
IN EFI_EVENT Event,\r
IN VOID *Context\r
)\r
-/*++\r
- Routine Description:\r
- \r
- Event notification function for EFI_SIMPLE_TEXT_INPUT_PROTOCOL.WaitForKey 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
//\r
// Someone is waiting on the keystroke event, if there's\r
// a key pending, signal the event\r
//\r
- // Context is the pointer to EFI_SIMPLE_TEXT_INPUT_PROTOCOL\r
- //\r
- if (!EFI_ERROR (TerminalConInCheckForKey (Context))) {\r
+ if (!IsEfiKeyFiFoEmpty ((TERMINAL_DEV *) Context)) {\r
\r
gBS->SignalEvent (Event);\r
}\r
}\r
\r
-EFI_STATUS\r
-TerminalConInCheckForKey (\r
- IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This\r
+/**\r
+ Timer handler to poll the key from serial.\r
+\r
+ @param Event Indicates the event that invoke this function.\r
+ @param Context Indicates the calling context.\r
+**/\r
+VOID\r
+EFIAPI\r
+TerminalConInTimerHandler (\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
)\r
-/*++\r
- Routine Description:\r
- \r
- Check for a pending key in the Efi Key FIFO or Serial device buffer.\r
- \r
- Arguments:\r
- \r
- This - Indicates the calling context.\r
- \r
- Returns:\r
- \r
- EFI_SUCCESS\r
- There is key pending. \r
- \r
- EFI_NOT_READY\r
- There is no key pending.\r
- \r
- EFI_DEVICE_ERROR\r
- \r
---*/\r
{\r
EFI_STATUS Status;\r
TERMINAL_DEV *TerminalDevice;\r
EFI_SERIAL_IO_PROTOCOL *SerialIo;\r
UINTN SerialInTimeOut;\r
\r
- TerminalDevice = TERMINAL_CON_IN_DEV_FROM_THIS (This);\r
+ TerminalDevice = (TERMINAL_DEV *) Context;\r
\r
SerialIo = TerminalDevice->SerialIo;\r
if (SerialIo == NULL) {\r
- return EFI_DEVICE_ERROR;\r
+ return ;\r
}\r
//\r
// if current timeout value for serial device is not identical with\r
\r
SerialInTimeOut = 0;\r
if (Mode->BaudRate != 0) {\r
+ //\r
+ // According to BAUD rate to calculate the timeout value.\r
+ //\r
SerialInTimeOut = (1 + Mode->DataBits + Mode->StopBits) * 2 * 1000000 / (UINTN) Mode->BaudRate;\r
}\r
\r
}\r
}\r
//\r
- // check whether serial buffer is empty\r
+ // Check whether serial buffer is empty.\r
//\r
Status = SerialIo->GetControl (SerialIo, &Control);\r
\r
- if (Control & EFI_SERIAL_INPUT_BUFFER_EMPTY) {\r
+ if ((Control & EFI_SERIAL_INPUT_BUFFER_EMPTY) == 0) {\r
//\r
- // Translate all the raw data in RawFIFO into EFI Key,\r
- // according to different terminal type supported.\r
+ // Fetch all the keys in the serial buffer,\r
+ // and insert the byte stream into RawFIFO.\r
//\r
- TranslateRawDataToEfiKey (TerminalDevice);\r
+ while (!IsRawFiFoFull (TerminalDevice)) {\r
\r
- //\r
- // if there is pre-fetched Efi Key in EfiKeyFIFO buffer,\r
- // return directly.\r
- //\r
- if (!IsEfiKeyFiFoEmpty (TerminalDevice)) {\r
- return EFI_SUCCESS;\r
- } else {\r
- return EFI_NOT_READY;\r
- }\r
- }\r
- //\r
- // Fetch all the keys in the serial buffer,\r
- // and insert the byte stream into RawFIFO.\r
- //\r
- do {\r
+ Status = GetOneKeyFromSerial (TerminalDevice->SerialIo, &Input);\r
\r
- Status = GetOneKeyFromSerial (TerminalDevice->SerialIo, &Input);\r
-\r
- if (EFI_ERROR (Status)) {\r
- if (Status == EFI_DEVICE_ERROR) {\r
- REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
- EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
- PcdGet32 (PcdStatusCodeValueRemoteConsoleInputError),\r
- TerminalDevice->DevicePath\r
- );\r
+ if (EFI_ERROR (Status)) {\r
+ if (Status == EFI_DEVICE_ERROR) {\r
+ REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
+ EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
+ (EFI_PERIPHERAL_REMOTE_CONSOLE | EFI_P_EC_INPUT_ERROR),\r
+ TerminalDevice->DevicePath\r
+ );\r
+ }\r
+ break;\r
}\r
- break;\r
- }\r
\r
- RawFiFoInsertOneKey (TerminalDevice, Input);\r
- } while (TRUE);\r
+ RawFiFoInsertOneKey (TerminalDevice, Input);\r
+ }\r
+ }\r
\r
//\r
// Translate all the raw data in RawFIFO into EFI Key,\r
// according to different terminal type supported.\r
//\r
TranslateRawDataToEfiKey (TerminalDevice);\r
+}\r
\r
- if (IsEfiKeyFiFoEmpty (TerminalDevice)) {\r
- return EFI_NOT_READY;\r
- }\r
+/**\r
+ Get one key out of serial buffer.\r
\r
- return EFI_SUCCESS;\r
-}\r
+ @param SerialIo Serial I/O protocol attached to the serial device.\r
+ @param Output The fetched key.\r
\r
+ @retval EFI_NOT_READY If serial buffer is empty.\r
+ @retval EFI_DEVICE_ERROR If reading serial buffer encounter error.\r
+ @retval EFI_SUCCESS If reading serial buffer successfully, put\r
+ the fetched key to the parameter output.\r
+\r
+**/\r
EFI_STATUS\r
GetOneKeyFromSerial (\r
EFI_SERIAL_IO_PROTOCOL *SerialIo,\r
- UINT8 *Input\r
+ UINT8 *Output\r
)\r
-/*++\r
- Get one key out of serial buffer.\r
- If serial buffer is empty, return EFI_NOT_READY;\r
- if reading serial buffer encounter error, returns EFI_DEVICE_ERROR;\r
- if reading serial buffer successfully, put the fetched key to \r
- the parameter "Input", and return EFI_SUCCESS.\r
---*/\r
{\r
EFI_STATUS Status;\r
UINTN Size;\r
\r
Size = 1;\r
- *Input = 0;\r
+ *Output = 0;\r
\r
- Status = SerialIo->Read (SerialIo, &Size, Input);\r
+ //\r
+ // Read one key from serial I/O device.\r
+ //\r
+ Status = SerialIo->Read (SerialIo, &Size, Output);\r
\r
if (EFI_ERROR (Status)) {\r
\r
\r
}\r
\r
- if (*Input == 0) {\r
+ if (*Output == 0) {\r
return EFI_NOT_READY;\r
}\r
\r
return EFI_SUCCESS;\r
}\r
\r
+/**\r
+ Insert one byte raw data into the Raw Data FIFO.\r
+\r
+ @param TerminalDevice Terminal driver private structure.\r
+ @param Input The key will be input.\r
+\r
+ @retval TRUE If insert successfully.\r
+ @retval FALSE If Raw Data buffer is full before key insertion,\r
+ and the key is lost.\r
+\r
+**/\r
BOOLEAN\r
RawFiFoInsertOneKey (\r
TERMINAL_DEV *TerminalDevice,\r
UINT8 Input\r
)\r
-/*++\r
- Insert one byte raw data into the Raw Data FIFO.\r
- If FIFO is FULL before data insertion,\r
- return FALSE, and the key is lost.\r
---*/\r
{\r
UINT8 Tail;\r
\r
- Tail = TerminalDevice->RawFiFo.Tail;\r
+ Tail = TerminalDevice->RawFiFo->Tail;\r
\r
if (IsRawFiFoFull (TerminalDevice)) {\r
//\r
return FALSE;\r
}\r
\r
- TerminalDevice->RawFiFo.Data[Tail] = Input;\r
+ TerminalDevice->RawFiFo->Data[Tail] = Input;\r
\r
- TerminalDevice->RawFiFo.Tail = (UINT8) ((Tail + 1) % (RAW_FIFO_MAX_NUMBER + 1));\r
+ TerminalDevice->RawFiFo->Tail = (UINT8) ((Tail + 1) % (RAW_FIFO_MAX_NUMBER + 1));\r
\r
return TRUE;\r
}\r
\r
+/**\r
+ Remove one pre-fetched key out of the Raw Data FIFO.\r
+\r
+ @param TerminalDevice Terminal driver private structure.\r
+ @param Output The key will be removed.\r
+\r
+ @retval TRUE If insert successfully.\r
+ @retval FALSE If Raw Data FIFO buffer is empty before remove operation.\r
+\r
+**/\r
BOOLEAN\r
RawFiFoRemoveOneKey (\r
TERMINAL_DEV *TerminalDevice,\r
UINT8 *Output\r
)\r
-/*++\r
- Remove one byte raw data out of the Raw Data FIFO.\r
- If FIFO buffer is empty before remove operation,\r
- return FALSE.\r
---*/\r
{\r
UINT8 Head;\r
\r
- Head = TerminalDevice->RawFiFo.Head;\r
+ Head = TerminalDevice->RawFiFo->Head;\r
\r
if (IsRawFiFoEmpty (TerminalDevice)) {\r
//\r
return FALSE;\r
}\r
\r
- *Output = TerminalDevice->RawFiFo.Data[Head];\r
+ *Output = TerminalDevice->RawFiFo->Data[Head];\r
\r
- TerminalDevice->RawFiFo.Head = (UINT8) ((Head + 1) % (RAW_FIFO_MAX_NUMBER + 1));\r
+ TerminalDevice->RawFiFo->Head = (UINT8) ((Head + 1) % (RAW_FIFO_MAX_NUMBER + 1));\r
\r
return TRUE;\r
}\r
\r
+/**\r
+ Clarify whether Raw Data FIFO buffer is empty.\r
+\r
+ @param TerminalDevice Terminal driver private structure\r
+\r
+ @retval TRUE If Raw Data FIFO buffer is empty.\r
+ @retval FALSE If Raw Data FIFO buffer is not empty.\r
+\r
+**/\r
BOOLEAN\r
IsRawFiFoEmpty (\r
TERMINAL_DEV *TerminalDevice\r
)\r
-/*++\r
- Clarify whether FIFO buffer is empty.\r
---*/\r
{\r
- if (TerminalDevice->RawFiFo.Head == TerminalDevice->RawFiFo.Tail) {\r
+ if (TerminalDevice->RawFiFo->Head == TerminalDevice->RawFiFo->Tail) {\r
return TRUE;\r
} else {\r
return FALSE;\r
}\r
}\r
\r
+/**\r
+ Clarify whether Raw Data FIFO buffer is full.\r
+\r
+ @param TerminalDevice Terminal driver private structure\r
+\r
+ @retval TRUE If Raw Data FIFO buffer is full.\r
+ @retval FALSE If Raw Data FIFO buffer is not full.\r
+\r
+**/\r
BOOLEAN\r
IsRawFiFoFull (\r
TERMINAL_DEV *TerminalDevice\r
)\r
-/*++\r
- Clarify whether FIFO buffer is full.\r
---*/\r
{\r
UINT8 Tail;\r
UINT8 Head;\r
\r
- Tail = TerminalDevice->RawFiFo.Tail;\r
- Head = TerminalDevice->RawFiFo.Head;\r
+ Tail = TerminalDevice->RawFiFo->Tail;\r
+ Head = TerminalDevice->RawFiFo->Head;\r
\r
if (((Tail + 1) % (RAW_FIFO_MAX_NUMBER + 1)) == Head) {\r
\r
return FALSE;\r
}\r
\r
+/**\r
+ Insert one pre-fetched key into the FIFO buffer.\r
+\r
+ @param TerminalDevice Terminal driver private structure.\r
+ @param Key The key will be input.\r
+\r
+ @retval TRUE If insert successfully.\r
+ @retval FALSE If FIFO buffer is full before key insertion,\r
+ and the key is lost.\r
+\r
+**/\r
BOOLEAN\r
EfiKeyFiFoInsertOneKey (\r
- TERMINAL_DEV *TerminalDevice,\r
- EFI_INPUT_KEY Key\r
+ TERMINAL_DEV *TerminalDevice,\r
+ EFI_INPUT_KEY *Key\r
)\r
-/*++\r
- Insert one pre-fetched key into the FIFO buffer.\r
- If FIFO buffer is FULL before key insertion,\r
- return FALSE, and the key is lost.\r
---*/\r
{\r
- UINT8 Tail;\r
+ UINT8 Tail;\r
+ LIST_ENTRY *Link;\r
+ LIST_ENTRY *NotifyList;\r
+ TERMINAL_CONSOLE_IN_EX_NOTIFY *CurrentNotify;\r
+ EFI_KEY_DATA KeyData;\r
+\r
+ Tail = TerminalDevice->EfiKeyFiFo->Tail;\r
\r
- Tail = TerminalDevice->EfiKeyFiFo.Tail;\r
+ CopyMem (&KeyData.Key, Key, sizeof (EFI_INPUT_KEY));\r
+ KeyData.KeyState.KeyShiftState = 0;\r
+ KeyData.KeyState.KeyToggleState = 0;\r
\r
+ //\r
+ // Invoke notification functions if exist\r
+ //\r
+ NotifyList = &TerminalDevice->NotifyList;\r
+ for (Link = GetFirstNode (NotifyList); !IsNull (NotifyList,Link); Link = GetNextNode (NotifyList,Link)) {\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
if (IsEfiKeyFiFoFull (TerminalDevice)) {\r
//\r
// Efi Key FIFO is full\r
return FALSE;\r
}\r
\r
- TerminalDevice->EfiKeyFiFo.Data[Tail] = Key;\r
+ CopyMem (&TerminalDevice->EfiKeyFiFo->Data[Tail], Key, sizeof (EFI_INPUT_KEY));\r
\r
- TerminalDevice->EfiKeyFiFo.Tail = (UINT8) ((Tail + 1) % (FIFO_MAX_NUMBER + 1));\r
+ TerminalDevice->EfiKeyFiFo->Tail = (UINT8) ((Tail + 1) % (FIFO_MAX_NUMBER + 1));\r
\r
return TRUE;\r
}\r
\r
+/**\r
+ Remove one pre-fetched key out of the FIFO buffer.\r
+\r
+ @param TerminalDevice Terminal driver private structure.\r
+ @param Output The key will be removed.\r
+\r
+ @retval TRUE If insert successfully.\r
+ @retval FALSE If FIFO buffer is empty before remove operation.\r
+\r
+**/\r
BOOLEAN\r
EfiKeyFiFoRemoveOneKey (\r
TERMINAL_DEV *TerminalDevice,\r
EFI_INPUT_KEY *Output\r
)\r
-/*++\r
- Remove one pre-fetched key out of the FIFO buffer.\r
- If FIFO buffer is empty before remove operation,\r
- return FALSE.\r
---*/\r
{\r
UINT8 Head;\r
\r
- Head = TerminalDevice->EfiKeyFiFo.Head;\r
+ Head = TerminalDevice->EfiKeyFiFo->Head;\r
+ ASSERT (Head < FIFO_MAX_NUMBER + 1);\r
\r
if (IsEfiKeyFiFoEmpty (TerminalDevice)) {\r
//\r
return FALSE;\r
}\r
\r
- *Output = TerminalDevice->EfiKeyFiFo.Data[Head];\r
+ CopyMem (Output, &TerminalDevice->EfiKeyFiFo->Data[Head], sizeof (EFI_INPUT_KEY));\r
\r
- TerminalDevice->EfiKeyFiFo.Head = (UINT8) ((Head + 1) % (FIFO_MAX_NUMBER + 1));\r
+ TerminalDevice->EfiKeyFiFo->Head = (UINT8) ((Head + 1) % (FIFO_MAX_NUMBER + 1));\r
\r
return TRUE;\r
}\r
\r
+/**\r
+ Clarify whether FIFO buffer is empty.\r
+\r
+ @param TerminalDevice Terminal driver private structure\r
+\r
+ @retval TRUE If FIFO buffer is empty.\r
+ @retval FALSE If FIFO buffer is not empty.\r
+\r
+**/\r
BOOLEAN\r
IsEfiKeyFiFoEmpty (\r
TERMINAL_DEV *TerminalDevice\r
)\r
-/*++\r
- Clarify whether FIFO buffer is empty.\r
---*/\r
{\r
- if (TerminalDevice->EfiKeyFiFo.Head == TerminalDevice->EfiKeyFiFo.Tail) {\r
+ if (TerminalDevice->EfiKeyFiFo->Head == TerminalDevice->EfiKeyFiFo->Tail) {\r
return TRUE;\r
} else {\r
return FALSE;\r
}\r
}\r
\r
+/**\r
+ Clarify whether FIFO buffer is full.\r
+\r
+ @param TerminalDevice Terminal driver private structure\r
+\r
+ @retval TRUE If FIFO buffer is full.\r
+ @retval FALSE If FIFO buffer is not full.\r
+\r
+**/\r
BOOLEAN\r
IsEfiKeyFiFoFull (\r
TERMINAL_DEV *TerminalDevice\r
)\r
-/*++\r
- Clarify whether FIFO buffer is full.\r
---*/\r
{\r
UINT8 Tail;\r
UINT8 Head;\r
\r
- Tail = TerminalDevice->EfiKeyFiFo.Tail;\r
- Head = TerminalDevice->EfiKeyFiFo.Head;\r
+ Tail = TerminalDevice->EfiKeyFiFo->Tail;\r
+ Head = TerminalDevice->EfiKeyFiFo->Head;\r
\r
if (((Tail + 1) % (FIFO_MAX_NUMBER + 1)) == Head) {\r
\r
return FALSE;\r
}\r
\r
+/**\r
+ Insert one pre-fetched key into the Unicode FIFO buffer.\r
+\r
+ @param TerminalDevice Terminal driver private structure.\r
+ @param Input The key will be input.\r
+\r
+ @retval TRUE If insert successfully.\r
+ @retval FALSE If Unicode FIFO buffer is full before key insertion,\r
+ and the key is lost.\r
+\r
+**/\r
BOOLEAN\r
UnicodeFiFoInsertOneKey (\r
TERMINAL_DEV *TerminalDevice,\r
UINT16 Input\r
)\r
-/*++\r
- Insert one pre-fetched key into the FIFO buffer.\r
- If FIFO buffer is FULL before key insertion,\r
- return FALSE, and the key is lost.\r
---*/\r
{\r
UINT8 Tail;\r
\r
- Tail = TerminalDevice->UnicodeFiFo.Tail;\r
+ Tail = TerminalDevice->UnicodeFiFo->Tail;\r
+ ASSERT (Tail < FIFO_MAX_NUMBER + 1);\r
+\r
\r
if (IsUnicodeFiFoFull (TerminalDevice)) {\r
//\r
return FALSE;\r
}\r
\r
- TerminalDevice->UnicodeFiFo.Data[Tail] = Input;\r
+ TerminalDevice->UnicodeFiFo->Data[Tail] = Input;\r
\r
- TerminalDevice->UnicodeFiFo.Tail = (UINT8) ((Tail + 1) % (FIFO_MAX_NUMBER + 1));\r
+ TerminalDevice->UnicodeFiFo->Tail = (UINT8) ((Tail + 1) % (FIFO_MAX_NUMBER + 1));\r
\r
return TRUE;\r
}\r
\r
-BOOLEAN\r
+/**\r
+ Remove one pre-fetched key out of the Unicode FIFO buffer.\r
+ The caller should guarantee that Unicode FIFO buffer is not empty \r
+ by IsUnicodeFiFoEmpty ().\r
+\r
+ @param TerminalDevice Terminal driver private structure.\r
+ @param Output The key will be removed.\r
+\r
+**/\r
+VOID\r
UnicodeFiFoRemoveOneKey (\r
TERMINAL_DEV *TerminalDevice,\r
UINT16 *Output\r
)\r
-/*++\r
- Remove one pre-fetched key out of the FIFO buffer.\r
- If FIFO buffer is empty before remove operation,\r
- return FALSE.\r
---*/\r
{\r
UINT8 Head;\r
\r
- Head = TerminalDevice->UnicodeFiFo.Head;\r
+ Head = TerminalDevice->UnicodeFiFo->Head;\r
+ ASSERT (Head < FIFO_MAX_NUMBER + 1);\r
\r
- if (IsUnicodeFiFoEmpty (TerminalDevice)) {\r
- //\r
- // FIFO is empty\r
- //\r
- Output = NULL;\r
- return FALSE;\r
- }\r
+ *Output = TerminalDevice->UnicodeFiFo->Data[Head];\r
+\r
+ TerminalDevice->UnicodeFiFo->Head = (UINT8) ((Head + 1) % (FIFO_MAX_NUMBER + 1));\r
+}\r
\r
- *Output = TerminalDevice->UnicodeFiFo.Data[Head];\r
+/**\r
+ Clarify whether Unicode FIFO buffer is empty.\r
\r
- TerminalDevice->UnicodeFiFo.Head = (UINT8) ((Head + 1) % (FIFO_MAX_NUMBER + 1));\r
+ @param TerminalDevice Terminal driver private structure\r
\r
- return TRUE;\r
-}\r
+ @retval TRUE If Unicode FIFO buffer is empty.\r
+ @retval FALSE If Unicode FIFO buffer is not empty.\r
\r
+**/\r
BOOLEAN\r
IsUnicodeFiFoEmpty (\r
TERMINAL_DEV *TerminalDevice\r
)\r
-/*++\r
- Clarify whether FIFO buffer is empty.\r
---*/\r
{\r
- if (TerminalDevice->UnicodeFiFo.Head == TerminalDevice->UnicodeFiFo.Tail) {\r
+ if (TerminalDevice->UnicodeFiFo->Head == TerminalDevice->UnicodeFiFo->Tail) {\r
return TRUE;\r
} else {\r
return FALSE;\r
}\r
}\r
\r
+/**\r
+ Clarify whether Unicode FIFO buffer is full.\r
+\r
+ @param TerminalDevice Terminal driver private structure\r
+\r
+ @retval TRUE If Unicode FIFO buffer is full.\r
+ @retval FALSE If Unicode FIFO buffer is not full.\r
+\r
+**/\r
BOOLEAN\r
IsUnicodeFiFoFull (\r
TERMINAL_DEV *TerminalDevice\r
)\r
-/*++\r
- Clarify whether FIFO buffer is full.\r
---*/\r
{\r
UINT8 Tail;\r
UINT8 Head;\r
\r
- Tail = TerminalDevice->UnicodeFiFo.Tail;\r
- Head = TerminalDevice->UnicodeFiFo.Head;\r
+ Tail = TerminalDevice->UnicodeFiFo->Tail;\r
+ Head = TerminalDevice->UnicodeFiFo->Head;\r
\r
if (((Tail + 1) % (FIFO_MAX_NUMBER + 1)) == Head) {\r
\r
return FALSE;\r
}\r
\r
+/**\r
+ Count Unicode FIFO buffer.\r
+\r
+ @param TerminalDevice Terminal driver private structure\r
+\r
+ @return The count in bytes of Unicode FIFO.\r
+\r
+**/\r
UINT8\r
UnicodeFiFoGetKeyCount (\r
TERMINAL_DEV *TerminalDevice\r
UINT8 Tail;\r
UINT8 Head;\r
\r
- Tail = TerminalDevice->UnicodeFiFo.Tail;\r
- Head = TerminalDevice->UnicodeFiFo.Head;\r
+ Tail = TerminalDevice->UnicodeFiFo->Tail;\r
+ Head = TerminalDevice->UnicodeFiFo->Head;\r
\r
if (Tail >= Head) {\r
return (UINT8) (Tail - Head);\r
}\r
}\r
\r
-STATIC\r
+/**\r
+ Update the Unicode characters from a terminal input device into EFI Keys FIFO.\r
+\r
+ @param TerminalDevice The terminal device to use to translate raw input into EFI Keys\r
+\r
+**/\r
VOID\r
UnicodeToEfiKeyFlushState (\r
IN TERMINAL_DEV *TerminalDevice\r
)\r
{\r
EFI_INPUT_KEY Key;\r
+ UINT32 InputState;\r
\r
- if (TerminalDevice->InputState & INPUT_STATE_ESC) {\r
+ InputState = TerminalDevice->InputState;\r
+\r
+ if (IsEfiKeyFiFoFull (TerminalDevice)) {\r
+ return;\r
+ }\r
+\r
+ if ((InputState & INPUT_STATE_ESC) != 0) {\r
Key.ScanCode = SCAN_ESC;\r
Key.UnicodeChar = 0;\r
- EfiKeyFiFoInsertOneKey (TerminalDevice, Key);\r
+ EfiKeyFiFoInsertOneKey (TerminalDevice, &Key);\r
}\r
\r
- if (TerminalDevice->InputState & INPUT_STATE_CSI) {\r
+ if ((InputState & INPUT_STATE_CSI) != 0) {\r
Key.ScanCode = SCAN_NULL;\r
Key.UnicodeChar = CSI;\r
- EfiKeyFiFoInsertOneKey (TerminalDevice, Key);\r
+ EfiKeyFiFoInsertOneKey (TerminalDevice, &Key);\r
}\r
\r
- if (TerminalDevice->InputState & INPUT_STATE_LEFTOPENBRACKET) {\r
+ if ((InputState & INPUT_STATE_LEFTOPENBRACKET) != 0) {\r
Key.ScanCode = SCAN_NULL;\r
Key.UnicodeChar = LEFTOPENBRACKET;\r
- EfiKeyFiFoInsertOneKey (TerminalDevice, Key);\r
+ EfiKeyFiFoInsertOneKey (TerminalDevice, &Key);\r
}\r
\r
- if (TerminalDevice->InputState & INPUT_STATE_O) {\r
+ if ((InputState & INPUT_STATE_O) != 0) {\r
Key.ScanCode = SCAN_NULL;\r
Key.UnicodeChar = 'O';\r
- EfiKeyFiFoInsertOneKey (TerminalDevice, Key);\r
+ EfiKeyFiFoInsertOneKey (TerminalDevice, &Key);\r
}\r
\r
- if (TerminalDevice->InputState & INPUT_STATE_2) {\r
+ if ((InputState & INPUT_STATE_2) != 0) {\r
Key.ScanCode = SCAN_NULL;\r
Key.UnicodeChar = '2';\r
- EfiKeyFiFoInsertOneKey (TerminalDevice, Key);\r
+ EfiKeyFiFoInsertOneKey (TerminalDevice, &Key);\r
}\r
\r
+ //\r
+ // Cancel the timer.\r
+ //\r
gBS->SetTimer (\r
TerminalDevice->TwoSecondTimeOut,\r
TimerCancel,\r
TerminalDevice->InputState = INPUT_STATE_DEFAULT;\r
}\r
\r
+\r
+/**\r
+ Converts a stream of Unicode characters from a terminal input device into EFI Keys that\r
+ can be read through the Simple Input Protocol.\r
+\r
+ The table below shows the keyboard input mappings that this function supports.\r
+ If the ESC sequence listed in one of the columns is presented, then it is translated\r
+ into the corresponding EFI Scan Code. If a matching sequence is not found, then the raw\r
+ key strokes are converted into EFI Keys.\r
+\r
+ 2 seconds are allowed for an ESC sequence to be completed. If the ESC sequence is not\r
+ completed in 2 seconds, then the raw key strokes of the partial ESC sequence are\r
+ converted into EFI Keys.\r
+ There is one special input sequence that will force the system to reset.\r
+ This is ESC R ESC r ESC R.\r
+\r
+ Note: current implementation support terminal types include: PC ANSI, VT100+/VTUTF8, VT100. \r
+ The table below is not same with UEFI Spec 2.3 Appendix B Table 201(not support ANSI X3.64 /\r
+ DEC VT200-500 and extra support PC ANSI, VT100)since UEFI Table 201 is just an example.\r
+ \r
+ Symbols used in table below\r
+ ===========================\r
+ ESC = 0x1B\r
+ CSI = 0x9B\r
+ DEL = 0x7f\r
+ ^ = CTRL\r
+\r
+ +=========+======+===========+==========+==========+\r
+ | | EFI | UEFI 2.0 | | |\r
+ | | Scan | | VT100+ | |\r
+ | KEY | Code | PC ANSI | VTUTF8 | VT100 |\r
+ +=========+======+===========+==========+==========+\r
+ | NULL | 0x00 | | | |\r
+ | UP | 0x01 | ESC [ A | ESC [ A | ESC [ A |\r
+ | DOWN | 0x02 | ESC [ B | ESC [ B | ESC [ B |\r
+ | RIGHT | 0x03 | ESC [ C | ESC [ C | ESC [ C |\r
+ | LEFT | 0x04 | ESC [ D | ESC [ D | ESC [ D |\r
+ | HOME | 0x05 | ESC [ H | ESC h | ESC [ H |\r
+ | END | 0x06 | ESC [ F | ESC k | ESC [ K |\r
+ | INSERT | 0x07 | ESC [ @ | ESC + | ESC [ @ |\r
+ | | | ESC [ L | | ESC [ L |\r
+ | DELETE | 0x08 | ESC [ X | ESC - | ESC [ P |\r
+ | PG UP | 0x09 | ESC [ I | ESC ? | ESC [ V |\r
+ | | | | | ESC [ ? |\r
+ | PG DOWN | 0x0A | ESC [ G | ESC / | ESC [ U |\r
+ | | | | | ESC [ / |\r
+ | F1 | 0x0B | ESC [ M | ESC 1 | ESC O P |\r
+ | F2 | 0x0C | ESC [ N | ESC 2 | ESC O Q |\r
+ | F3 | 0x0D | ESC [ O | ESC 3 | ESC O w |\r
+ | F4 | 0x0E | ESC [ P | ESC 4 | ESC O x |\r
+ | F5 | 0x0F | ESC [ Q | ESC 5 | ESC O t |\r
+ | F6 | 0x10 | ESC [ R | ESC 6 | ESC O u |\r
+ | F7 | 0x11 | ESC [ S | ESC 7 | ESC O q |\r
+ | F8 | 0x12 | ESC [ T | ESC 8 | ESC O r |\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
+ | F11 | 0x15 | | ESC ! | |\r
+ | F12 | 0x16 | | ESC @ | |\r
+ +=========+======+===========+==========+==========+\r
+\r
+ Special Mappings\r
+ ================\r
+ ESC R ESC r ESC R = Reset System\r
+\r
+ @param TerminalDevice The terminal device to use to translate raw input into EFI Keys\r
+\r
+**/\r
VOID\r
UnicodeToEfiKey (\r
IN TERMINAL_DEV *TerminalDevice\r
)\r
-/*++\r
- Routine Description:\r
- \r
- Converts a stream of Unicode characters from a terminal input device into EFI Keys that\r
- can be read through the Simple Input Protocol. The table below shows the keyboard\r
- input mappings that this function supports. If the ESC sequence listed in one of the \r
- columns is presented, then it is translated into the coorespoding EFI Scan Code. If a\r
- matching sequence is not found, then the raw key strokes are converted into EFI Keys.\r
- \r
- 2 seconds are allowed for an ESC sequence to be completed. If the ESC sequence is not \r
- completed in 2 seconds, then the raw key strokes of the partial ESC sequence are \r
- converted into EFI Keys.\r
- \r
- There is one special input sequence that will force the system to reset. \r
- This is ESC R ESC r ESC R.\r
- \r
- Arguments:\r
-\r
- TerminaDevice : The terminal device to use to translate raw input into EFI Keys\r
- \r
- Returns:\r
-\r
- None\r
-\r
-Symbols used in table below\r
-===========================\r
- ESC = 0x1B \r
- CSI = 0x9B \r
- DEL = 0x7f \r
- ^ = CTRL\r
-\r
-+=========+======+===========+==========+==========+\r
-| | EFI | EFI 1.10 | | |\r
-| | Scan | | VT100+ | |\r
-| KEY | Code | PC ANSI | VTUTF8 | VT100 |\r
-+=========+======+===========+==========+==========+\r
-| NULL | 0x00 | | | |\r
-| UP | 0x01 | ESC [ A | ESC [ A | ESC [ A |\r
-| DOWN | 0x02 | ESC [ B | ESC [ B | ESC [ B |\r
-| RIGHT | 0x03 | ESC [ C | ESC [ C | ESC [ C | \r
-| LEFT | 0x04 | ESC [ D | ESC [ D | ESC [ D |\r
-| HOME | 0x05 | ESC [ H | ESC h | ESC [ H |\r
-| END | 0x06 | ESC [ F | ESC k | ESC [ K |\r
-| INSERT | 0x07 | ESC [ @ | ESC + | ESC [ @ |\r
-| | | ESC [ L | | ESC [ L |\r
-| DELETE | 0x08 | ESC [ X | ESC - | ESC [ P |\r
-| PG UP | 0x09 | ESC [ I | ESC ? | ESC [ V |\r
-| | | | | ESC [ ? |\r
-| PG DOWN | 0x0A | ESC [ G | ESC / | ESC [ U |\r
-| | | | | ESC [ / |\r
-| F1 | 0x0B | ESC [ M | ESC 1 | ESC O P |\r
-| F2 | 0x0C | ESC [ N | ESC 2 | ESC O Q |\r
-| F3 | 0x0D | ESC [ O | ESC 3 | ESC O w |\r
-| F4 | 0x0E | ESC [ P | ESC 4 | ESC O x |\r
-| F5 | 0x0F | ESC [ Q | ESC 5 | ESC O t |\r
-| F6 | 0x10 | ESC [ R | ESC 6 | ESC O u |\r
-| F7 | 0x11 | ESC [ S | ESC 7 | ESC O q |\r
-| F8 | 0x12 | ESC [ T | ESC 8 | ESC O r |\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
-\r
-Special Mappings\r
-================\r
-ESC R ESC r ESC R = Reset System\r
-\r
---*/\r
{\r
EFI_STATUS Status;\r
EFI_STATUS TimerStatus;\r
UINT16 UnicodeChar;\r
EFI_INPUT_KEY Key;\r
BOOLEAN SetDefaultResetState;\r
- \r
+\r
TimerStatus = gBS->CheckEvent (TerminalDevice->TwoSecondTimeOut);\r
\r
if (!EFI_ERROR (TimerStatus)) {\r
TerminalDevice->ResetState = RESET_STATE_DEFAULT;\r
}\r
\r
- while (!IsUnicodeFiFoEmpty(TerminalDevice)) {\r
- \r
+ while (!IsUnicodeFiFoEmpty (TerminalDevice) && !IsEfiKeyFiFoFull (TerminalDevice)) {\r
+\r
if (TerminalDevice->InputState != INPUT_STATE_DEFAULT) {\r
//\r
- // Check to see if the 2 second timer has expired\r
+ // Check to see if the 2 seconds timer has expired\r
//\r
TimerStatus = gBS->CheckEvent (TerminalDevice->TwoSecondTimeOut);\r
if (!EFI_ERROR (TimerStatus)) {\r
//\r
// Fetch one Unicode character from the Unicode FIFO\r
//\r
- UnicodeFiFoRemoveOneKey (TerminalDevice,&UnicodeChar);\r
+ UnicodeFiFoRemoveOneKey (TerminalDevice, &UnicodeChar);\r
\r
SetDefaultResetState = TRUE;\r
\r
continue;\r
}\r
\r
- if (UnicodeChar == 'O' && TerminalDevice->TerminalType == VT100Type) {\r
+ if (UnicodeChar == 'O' && (TerminalDevice->TerminalType == VT100TYPE ||\r
+ TerminalDevice->TerminalType == TTYTERMTYPE)) {\r
TerminalDevice->InputState |= INPUT_STATE_O;\r
TerminalDevice->ResetState = RESET_STATE_DEFAULT;\r
continue;\r
}\r
\r
Key.ScanCode = SCAN_NULL;\r
- \r
- if (TerminalDevice->TerminalType == VT100PlusType || \r
- TerminalDevice->TerminalType == VTUTF8Type) {\r
+\r
+ if (TerminalDevice->TerminalType == VT100PLUSTYPE ||\r
+ TerminalDevice->TerminalType == VTUTF8TYPE) {\r
switch (UnicodeChar) {\r
- case '1': \r
- Key.ScanCode = SCAN_F1; \r
+ case '1':\r
+ Key.ScanCode = SCAN_F1;\r
+ break;\r
+ case '2':\r
+ Key.ScanCode = SCAN_F2;\r
+ break;\r
+ case '3':\r
+ Key.ScanCode = SCAN_F3;\r
break;\r
- case '2': \r
- Key.ScanCode = SCAN_F2; \r
+ case '4':\r
+ Key.ScanCode = SCAN_F4;\r
break;\r
- case '3': \r
- Key.ScanCode = SCAN_F3; \r
+ case '5':\r
+ Key.ScanCode = SCAN_F5;\r
break;\r
- case '4': \r
- Key.ScanCode = SCAN_F4; \r
+ case '6':\r
+ Key.ScanCode = SCAN_F6;\r
break;\r
- case '5': \r
- Key.ScanCode = SCAN_F5; \r
+ case '7':\r
+ Key.ScanCode = SCAN_F7;\r
break;\r
- case '6': \r
- Key.ScanCode = SCAN_F6; \r
+ case '8':\r
+ Key.ScanCode = SCAN_F8;\r
break;\r
- case '7': \r
- Key.ScanCode = SCAN_F7; \r
+ case '9':\r
+ Key.ScanCode = SCAN_F9;\r
break;\r
- case '8': \r
- Key.ScanCode = SCAN_F8; \r
+ case '0':\r
+ Key.ScanCode = SCAN_F10;\r
break;\r
- case '9': \r
- Key.ScanCode = SCAN_F9; \r
+ case '!':\r
+ Key.ScanCode = SCAN_F11;\r
break;\r
- case '0': \r
- Key.ScanCode = SCAN_F10; \r
+ case '@':\r
+ Key.ScanCode = SCAN_F12;\r
break;\r
- case 'h': \r
- Key.ScanCode = SCAN_HOME; \r
+ case 'h':\r
+ Key.ScanCode = SCAN_HOME;\r
break;\r
- case 'k': \r
- Key.ScanCode = SCAN_END; \r
+ case 'k':\r
+ Key.ScanCode = SCAN_END;\r
break;\r
- case '+': \r
- Key.ScanCode = SCAN_INSERT; \r
+ case '+':\r
+ Key.ScanCode = SCAN_INSERT;\r
break;\r
- case '-': \r
- Key.ScanCode = SCAN_DELETE; \r
+ case '-':\r
+ Key.ScanCode = SCAN_DELETE;\r
break;\r
- case '/': \r
- Key.ScanCode = SCAN_PAGE_DOWN; \r
+ case '/':\r
+ Key.ScanCode = SCAN_PAGE_DOWN;\r
break;\r
- case '?': \r
- Key.ScanCode = SCAN_PAGE_UP; \r
- break; \r
- default : \r
+ case '?':\r
+ Key.ScanCode = SCAN_PAGE_UP;\r
+ break;\r
+ default :\r
break;\r
}\r
}\r
- \r
+\r
switch (UnicodeChar) {\r
- case 'R': \r
+ case 'R':\r
if (TerminalDevice->ResetState == RESET_STATE_DEFAULT) {\r
TerminalDevice->ResetState = RESET_STATE_ESC_R;\r
SetDefaultResetState = FALSE;\r
- } else if (TerminalDevice->ResetState == RESET_STATE_ESC_R_ESC_r) {\r
+ } else if (TerminalDevice->ResetState == RESET_STATE_ESC_R_ESC_R) {\r
gRT->ResetSystem (EfiResetWarm, EFI_SUCCESS, 0, NULL);\r
}\r
Key.ScanCode = SCAN_NULL;\r
break;\r
- case 'r': \r
+ case 'r':\r
if (TerminalDevice->ResetState == RESET_STATE_ESC_R) {\r
- TerminalDevice->ResetState = RESET_STATE_ESC_R_ESC_r;\r
+ TerminalDevice->ResetState = RESET_STATE_ESC_R_ESC_R;\r
SetDefaultResetState = FALSE;\r
}\r
Key.ScanCode = SCAN_NULL;\r
break;\r
- default : \r
+ default :\r
break;\r
}\r
\r
\r
if (Key.ScanCode != SCAN_NULL) {\r
Key.UnicodeChar = 0;\r
- EfiKeyFiFoInsertOneKey (TerminalDevice,Key);\r
+ EfiKeyFiFoInsertOneKey (TerminalDevice, &Key);\r
TerminalDevice->InputState = INPUT_STATE_DEFAULT;\r
UnicodeToEfiKeyFlushState (TerminalDevice);\r
continue;\r
TerminalDevice->ResetState = RESET_STATE_DEFAULT;\r
\r
Key.ScanCode = SCAN_NULL;\r
- \r
- if (TerminalDevice->TerminalType == VT100Type) {\r
+\r
+ if (TerminalDevice->TerminalType == VT100TYPE) {\r
switch (UnicodeChar) {\r
- case 'P': \r
- Key.ScanCode = SCAN_F1; \r
+ case 'P':\r
+ Key.ScanCode = SCAN_F1;\r
break;\r
- case 'Q': \r
- Key.ScanCode = SCAN_F2; \r
+ case 'Q':\r
+ Key.ScanCode = SCAN_F2;\r
break;\r
- case 'w': \r
- Key.ScanCode = SCAN_F3; \r
+ case 'w':\r
+ Key.ScanCode = SCAN_F3;\r
break;\r
- case 'x': \r
- Key.ScanCode = SCAN_F4; \r
+ case 'x':\r
+ Key.ScanCode = SCAN_F4;\r
break;\r
- case 't': \r
- Key.ScanCode = SCAN_F5; \r
+ case 't':\r
+ Key.ScanCode = SCAN_F5;\r
break;\r
- case 'u': \r
- Key.ScanCode = SCAN_F6; \r
+ case 'u':\r
+ Key.ScanCode = SCAN_F6;\r
break;\r
- case 'q': \r
- Key.ScanCode = SCAN_F7; \r
+ case 'q':\r
+ Key.ScanCode = SCAN_F7;\r
break;\r
- case 'r': \r
- Key.ScanCode = SCAN_F8; \r
+ case 'r':\r
+ Key.ScanCode = SCAN_F8;\r
break;\r
- case 'p': \r
- Key.ScanCode = SCAN_F9; \r
+ case 'p':\r
+ Key.ScanCode = SCAN_F9;\r
break;\r
- case 'M': \r
- Key.ScanCode = SCAN_F10; \r
+ case 'M':\r
+ Key.ScanCode = SCAN_F10;\r
break;\r
- default : \r
+ default :\r
+ break;\r
+ }\r
+ } else if (TerminalDevice->TerminalType == TTYTERMTYPE) {\r
+ /* Also accept VT100 escape codes for F1-F4 for TTY term */\r
+ switch (UnicodeChar) {\r
+ case 'P':\r
+ Key.ScanCode = SCAN_F1;\r
+ break;\r
+ case 'Q':\r
+ Key.ScanCode = SCAN_F2;\r
+ break;\r
+ case 'R':\r
+ Key.ScanCode = SCAN_F3;\r
+ break;\r
+ case 'S':\r
+ Key.ScanCode = SCAN_F4;\r
break;\r
}\r
}\r
\r
if (Key.ScanCode != SCAN_NULL) {\r
Key.UnicodeChar = 0;\r
- EfiKeyFiFoInsertOneKey (TerminalDevice,Key);\r
+ EfiKeyFiFoInsertOneKey (TerminalDevice, &Key);\r
TerminalDevice->InputState = INPUT_STATE_DEFAULT;\r
UnicodeToEfiKeyFlushState (TerminalDevice);\r
continue;\r
break;\r
\r
case INPUT_STATE_ESC | INPUT_STATE_LEFTOPENBRACKET:\r
- \r
+\r
TerminalDevice->ResetState = RESET_STATE_DEFAULT;\r
- \r
+\r
Key.ScanCode = SCAN_NULL;\r
- \r
- if (TerminalDevice->TerminalType == PcAnsiType ||\r
- TerminalDevice->TerminalType == VT100Type ||\r
- TerminalDevice->TerminalType == VT100PlusType || \r
- TerminalDevice->TerminalType == VTUTF8Type) {\r
+\r
+ if (TerminalDevice->TerminalType == PCANSITYPE ||\r
+ TerminalDevice->TerminalType == VT100TYPE ||\r
+ TerminalDevice->TerminalType == VT100PLUSTYPE ||\r
+ TerminalDevice->TerminalType == VTUTF8TYPE ||\r
+ TerminalDevice->TerminalType == TTYTERMTYPE) {\r
switch (UnicodeChar) {\r
- case 'A': \r
- Key.ScanCode = SCAN_UP; \r
+ case 'A':\r
+ Key.ScanCode = SCAN_UP;\r
break;\r
- case 'B': \r
- Key.ScanCode = SCAN_DOWN; \r
+ case 'B':\r
+ Key.ScanCode = SCAN_DOWN;\r
break;\r
- case 'C': \r
- Key.ScanCode = SCAN_RIGHT; \r
+ case 'C':\r
+ Key.ScanCode = SCAN_RIGHT;\r
break;\r
- case 'D': \r
- Key.ScanCode = SCAN_LEFT; \r
+ case 'D':\r
+ Key.ScanCode = SCAN_LEFT;\r
break;\r
- case 'H': \r
- if (TerminalDevice->TerminalType == PcAnsiType ||\r
- TerminalDevice->TerminalType == VT100Type) {\r
- Key.ScanCode = SCAN_HOME; \r
+ case 'H':\r
+ if (TerminalDevice->TerminalType == PCANSITYPE ||\r
+ TerminalDevice->TerminalType == VT100TYPE) {\r
+ Key.ScanCode = SCAN_HOME;\r
}\r
break;\r
- case 'F': \r
- if (TerminalDevice->TerminalType == PcAnsiType) {\r
+ case 'F':\r
+ if (TerminalDevice->TerminalType == PCANSITYPE) {\r
Key.ScanCode = SCAN_END;\r
}\r
break;\r
- case 'K': \r
- if (TerminalDevice->TerminalType == VT100Type) {\r
- Key.ScanCode = SCAN_END; \r
+ case 'K':\r
+ if (TerminalDevice->TerminalType == VT100TYPE) {\r
+ Key.ScanCode = SCAN_END;\r
}\r
break;\r
- case 'L': \r
- case '@': \r
- if (TerminalDevice->TerminalType == PcAnsiType ||\r
- TerminalDevice->TerminalType == VT100Type) {\r
- Key.ScanCode = SCAN_INSERT; \r
+ case 'L':\r
+ case '@':\r
+ if (TerminalDevice->TerminalType == PCANSITYPE ||\r
+ TerminalDevice->TerminalType == VT100TYPE) {\r
+ Key.ScanCode = SCAN_INSERT;\r
}\r
break;\r
- case 'X': \r
- if (TerminalDevice->TerminalType == PcAnsiType) {\r
+ case 'X':\r
+ if (TerminalDevice->TerminalType == PCANSITYPE) {\r
Key.ScanCode = SCAN_DELETE;\r
}\r
break;\r
- case 'P': \r
- if (TerminalDevice->TerminalType == VT100Type) {\r
- Key.ScanCode = SCAN_DELETE; \r
- } else if (TerminalDevice->TerminalType == PcAnsiType) {\r
+ case 'P':\r
+ if (TerminalDevice->TerminalType == VT100TYPE) {\r
+ Key.ScanCode = SCAN_DELETE;\r
+ } else if (TerminalDevice->TerminalType == PCANSITYPE) {\r
Key.ScanCode = SCAN_F4;\r
}\r
break;\r
- case 'I': \r
- if (TerminalDevice->TerminalType == PcAnsiType) {\r
+ case 'I':\r
+ if (TerminalDevice->TerminalType == PCANSITYPE) {\r
Key.ScanCode = SCAN_PAGE_UP;\r
}\r
- break; \r
- case 'V': \r
- if (TerminalDevice->TerminalType == PcAnsiType) {\r
+ break;\r
+ case 'V':\r
+ if (TerminalDevice->TerminalType == PCANSITYPE) {\r
Key.ScanCode = SCAN_F10;\r
- } \r
- case '?': \r
- if (TerminalDevice->TerminalType == VT100Type) {\r
- Key.ScanCode = SCAN_PAGE_UP; \r
}\r
break;\r
- case 'G': \r
- if (TerminalDevice->TerminalType == PcAnsiType) {\r
+ case '?':\r
+ if (TerminalDevice->TerminalType == VT100TYPE) {\r
+ Key.ScanCode = SCAN_PAGE_UP;\r
+ }\r
+ break;\r
+ case 'G':\r
+ if (TerminalDevice->TerminalType == PCANSITYPE) {\r
Key.ScanCode = SCAN_PAGE_DOWN;\r
}\r
- break; \r
- case 'U': \r
- if (TerminalDevice->TerminalType == PcAnsiType) {\r
+ break;\r
+ case 'U':\r
+ if (TerminalDevice->TerminalType == PCANSITYPE) {\r
Key.ScanCode = SCAN_F9;\r
}\r
- case '/': \r
- if (TerminalDevice->TerminalType == VT100Type) {\r
- Key.ScanCode = SCAN_PAGE_DOWN; \r
+ break;\r
+ case '/':\r
+ if (TerminalDevice->TerminalType == VT100TYPE) {\r
+ Key.ScanCode = SCAN_PAGE_DOWN;\r
}\r
break;\r
- case 'M': \r
- if (TerminalDevice->TerminalType == PcAnsiType) {\r
+ case 'M':\r
+ if (TerminalDevice->TerminalType == PCANSITYPE) {\r
Key.ScanCode = SCAN_F1;\r
}\r
- break; \r
- case 'N': \r
- if (TerminalDevice->TerminalType == PcAnsiType) {\r
+ break;\r
+ case 'N':\r
+ if (TerminalDevice->TerminalType == PCANSITYPE) {\r
Key.ScanCode = SCAN_F2;\r
}\r
- break; \r
- case 'O': \r
- if (TerminalDevice->TerminalType == PcAnsiType) {\r
+ break;\r
+ case 'O':\r
+ if (TerminalDevice->TerminalType == PCANSITYPE) {\r
Key.ScanCode = SCAN_F3;\r
}\r
- break; \r
- case 'Q': \r
- if (TerminalDevice->TerminalType == PcAnsiType) {\r
+ break;\r
+ case 'Q':\r
+ if (TerminalDevice->TerminalType == PCANSITYPE) {\r
Key.ScanCode = SCAN_F5;\r
}\r
- break; \r
- case 'R': \r
- if (TerminalDevice->TerminalType == PcAnsiType) {\r
+ break;\r
+ case 'R':\r
+ if (TerminalDevice->TerminalType == PCANSITYPE) {\r
Key.ScanCode = SCAN_F6;\r
}\r
- break; \r
- case 'S': \r
- if (TerminalDevice->TerminalType == PcAnsiType) {\r
+ break;\r
+ case 'S':\r
+ if (TerminalDevice->TerminalType == PCANSITYPE) {\r
Key.ScanCode = SCAN_F7;\r
}\r
- break; \r
- case 'T': \r
- if (TerminalDevice->TerminalType == PcAnsiType) {\r
+ break;\r
+ case 'T':\r
+ if (TerminalDevice->TerminalType == PCANSITYPE) {\r
Key.ScanCode = SCAN_F8;\r
}\r
- break; \r
- default : \r
+ break;\r
+ default :\r
break;\r
}\r
}\r
\r
+ /*\r
+ * The VT220 escape codes that the TTY terminal accepts all have\r
+ * numeric codes, and there are no ambiguous prefixes shared with\r
+ * other terminal types.\r
+ */\r
+ if (TerminalDevice->TerminalType == TTYTERMTYPE &&\r
+ Key.ScanCode == SCAN_NULL &&\r
+ UnicodeChar >= '0' &&\r
+ UnicodeChar <= '9') {\r
+ TerminalDevice->TtyEscapeStr[0] = UnicodeChar;\r
+ TerminalDevice->TtyEscapeIndex = 1;\r
+ TerminalDevice->InputState |= INPUT_STATE_LEFTOPENBRACKET_2;\r
+ continue;\r
+ }\r
+\r
if (Key.ScanCode != SCAN_NULL) {\r
Key.UnicodeChar = 0;\r
- EfiKeyFiFoInsertOneKey (TerminalDevice,Key);\r
+ EfiKeyFiFoInsertOneKey (TerminalDevice, &Key);\r
TerminalDevice->InputState = INPUT_STATE_DEFAULT;\r
UnicodeToEfiKeyFlushState (TerminalDevice);\r
continue;\r
\r
break;\r
\r
- \r
+\r
+ case INPUT_STATE_ESC | INPUT_STATE_LEFTOPENBRACKET | INPUT_STATE_LEFTOPENBRACKET_2:\r
+ /*\r
+ * Here we handle the VT220 escape codes that we accept. This\r
+ * state is only used by the TTY terminal type.\r
+ */\r
+ Key.ScanCode = SCAN_NULL;\r
+ if (TerminalDevice->TerminalType == TTYTERMTYPE) {\r
+\r
+ if (UnicodeChar == '~' && TerminalDevice->TtyEscapeIndex <= 2) {\r
+ UINT16 EscCode;\r
+ TerminalDevice->TtyEscapeStr[TerminalDevice->TtyEscapeIndex] = 0; /* Terminate string */\r
+ EscCode = (UINT16) StrDecimalToUintn(TerminalDevice->TtyEscapeStr);\r
+ switch (EscCode) {\r
+ case 3:\r
+ Key.ScanCode = SCAN_DELETE;\r
+ break;\r
+ case 11:\r
+ case 12:\r
+ case 13:\r
+ case 14:\r
+ case 15:\r
+ Key.ScanCode = SCAN_F1 + EscCode - 11;\r
+ break;\r
+ case 17:\r
+ case 18:\r
+ case 19:\r
+ case 20:\r
+ case 21:\r
+ Key.ScanCode = SCAN_F6 + EscCode - 17;\r
+ break;\r
+ case 23:\r
+ case 24:\r
+ Key.ScanCode = SCAN_F11 + EscCode - 23;\r
+ break;\r
+ default:\r
+ break;\r
+ }\r
+ } else if (TerminalDevice->TtyEscapeIndex == 1){\r
+ /* 2 character escape code */\r
+ TerminalDevice->TtyEscapeStr[TerminalDevice->TtyEscapeIndex++] = UnicodeChar;\r
+ continue;\r
+ }\r
+ else {\r
+ DEBUG ((EFI_D_ERROR, "Unexpected state in escape2\n"));\r
+ }\r
+ }\r
+ TerminalDevice->ResetState = RESET_STATE_DEFAULT;\r
+\r
+ if (Key.ScanCode != SCAN_NULL) {\r
+ Key.UnicodeChar = 0;\r
+ EfiKeyFiFoInsertOneKey (TerminalDevice, &Key);\r
+ TerminalDevice->InputState = INPUT_STATE_DEFAULT;\r
+ UnicodeToEfiKeyFlushState (TerminalDevice);\r
+ continue;\r
+ }\r
+\r
+ UnicodeToEfiKeyFlushState (TerminalDevice);\r
+ break;\r
+\r
default:\r
//\r
// Invalid state. This should never happen.\r
if (UnicodeChar == ESC) {\r
TerminalDevice->InputState = INPUT_STATE_ESC;\r
}\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
TerminalDevice->TwoSecondTimeOut,\r
}\r
\r
if (UnicodeChar == DEL) {\r
- Key.ScanCode = SCAN_DELETE;\r
- Key.UnicodeChar = 0;\r
+ if (TerminalDevice->TerminalType == TTYTERMTYPE) {\r
+ Key.ScanCode = SCAN_NULL;\r
+ Key.UnicodeChar = CHAR_BACKSPACE;\r
+ }\r
+ else {\r
+ Key.ScanCode = SCAN_DELETE;\r
+ Key.UnicodeChar = 0;\r
+ }\r
} else {\r
Key.ScanCode = SCAN_NULL;\r
Key.UnicodeChar = UnicodeChar;\r
}\r
\r
- EfiKeyFiFoInsertOneKey (TerminalDevice,Key);\r
+ EfiKeyFiFoInsertOneKey (TerminalDevice, &Key);\r
}\r
}\r