/** @file\r
Implementation for EFI_SIMPLE_TEXT_INPUT_PROTOCOL protocol.\r
\r
-Copyright (c) 2006 - 2008, 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
+(C) Copyright 2014 Hewlett-Packard Development Company, L.P.<BR>\r
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
+Copyright (C) 2016 Silicon Graphics, Inc. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\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
OUT EFI_KEY_DATA *KeyData\r
)\r
{\r
- EFI_STATUS Status;\r
- LIST_ENTRY *Link;\r
- LIST_ENTRY *NotifyList;\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
- 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
+ if (!EfiKeyFiFoRemoveOneKey (TerminalDevice, &KeyData->Key)) {\r
+ return EFI_NOT_READY;\r
}\r
\r
return EFI_SUCCESS;\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
TerminalDevice->RawFiFo->Head = TerminalDevice->RawFiFo->Tail;\r
TerminalDevice->UnicodeFiFo->Head = TerminalDevice->UnicodeFiFo->Tail;\r
TerminalDevice->EfiKeyFiFo->Head = TerminalDevice->EfiKeyFiFo->Tail;\r
+ TerminalDevice->EfiKeyFiFoForNotify->Head = TerminalDevice->EfiKeyFiFoForNotify->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
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
IN VOID *Context\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
+ TerminalConInWaitForKey (Event, Context);\r
}\r
\r
//\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
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 KeyData A pointer to a buffer that is filled in with\r
+ the keystroke information for the key that was\r
+ pressed. If KeyData.Key, KeyData.KeyState.KeyToggleState\r
+ and KeyData.KeyState.KeyShiftState are 0, then any incomplete\r
+ 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\r
registered notification.\r
\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
TERMINAL_DEV *TerminalDevice;\r
TERMINAL_CONSOLE_IN_EX_NOTIFY *NewNotify;\r
LIST_ENTRY *Link;\r
);\r
if (IsKeyRegistered (&CurrentNotify->KeyData, KeyData)) {\r
if (CurrentNotify->KeyNotificationFn == KeyNotificationFunction) {\r
- *NotifyHandle = CurrentNotify->NotifyHandle;\r
+ *NotifyHandle = CurrentNotify;\r
return EFI_SUCCESS;\r
}\r
}\r
\r
NewNotify->Signature = TERMINAL_CONSOLE_IN_EX_NOTIFY_SIGNATURE;\r
NewNotify->KeyNotificationFn = KeyNotificationFunction;\r
- CopyMem (&NewNotify->KeyData, KeyData, sizeof (KeyData));\r
+ CopyMem (&NewNotify->KeyData, KeyData, sizeof (EFI_KEY_DATA));\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
+ *NotifyHandle = NewNotify;\r
\r
return EFI_SUCCESS;\r
}\r
@retval EFI_SUCCESS The notification function was unregistered\r
successfully.\r
@retval EFI_INVALID_PARAMETER The NotificationHandle is invalid.\r
- @retval EFI_NOT_FOUND Can not find the matching entry in database.\r
\r
**/\r
EFI_STATUS\r
EFIAPI\r
TerminalConInUnregisterKeyNotify (\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
TERMINAL_DEV *TerminalDevice;\r
LIST_ENTRY *Link;\r
TERMINAL_CONSOLE_IN_EX_NOTIFY *CurrentNotify;\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
NotifyList = &TerminalDevice->NotifyList;\r
NotifyEntry,\r
TERMINAL_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
RemoveEntryList (&CurrentNotify->NotifyEntry);\r
- Status = gBS->UninstallMultipleProtocolInterfaces (\r
- CurrentNotify->NotifyHandle,\r
- &gSimpleTextInExNotifyGuid,\r
- NULL,\r
- NULL\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
+\r
gBS->FreePool (CurrentNotify);\r
return EFI_SUCCESS;\r
}\r
}\r
\r
- return EFI_NOT_FOUND;\r
+ //\r
+ // Can not find the matching entry in database.\r
+ //\r
+ return EFI_INVALID_PARAMETER;\r
}\r
\r
/**\r
{\r
switch (TerminalDevice->TerminalType) {\r
\r
- case PCANSITYPE:\r
- case VT100TYPE:\r
- case VT100PLUSTYPE:\r
+ case TerminalTypePcAnsi:\r
+ case TerminalTypeVt100:\r
+ case TerminalTypeVt100Plus:\r
+ case TerminalTypeTtyTerm:\r
AnsiRawDataToUnicode (TerminalDevice);\r
UnicodeToEfiKey (TerminalDevice);\r
break;\r
\r
- case VTUTF8TYPE:\r
+ case TerminalTypeVtUtf8:\r
//\r
// Process all the raw data in the RawFIFO,\r
// put the processed key into UnicodeFIFO.\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
-\r
/**\r
- Check for a pending key in the Efi Key FIFO or Serial device buffer.\r
-\r
- @param This Indicates the calling context.\r
-\r
- @retval EFI_SUCCESS There is key pending.\r
- @retval EFI_NOT_READY There is no key pending.\r
- @retval EFI_DEVICE_ERROR If Serial IO is not attached to serial device.\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
-EFI_STATUS\r
-TerminalConInCheckForKey (\r
- IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This\r
+VOID\r
+EFIAPI\r
+TerminalConInTimerHandler (\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
)\r
{\r
EFI_STATUS Status;\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
}\r
//\r
- // Check whether serial buffer is empty.\r
+ // Check whether serial buffer is empty.\r
+ // Skip the key transfer loop only if the SerialIo protocol instance\r
+ // successfully reports EFI_SERIAL_INPUT_BUFFER_EMPTY.\r
//\r
Status = SerialIo->GetControl (SerialIo, &Control);\r
-\r
- if ((Control & EFI_SERIAL_INPUT_BUFFER_EMPTY) != 0) {\r
+ if (EFI_ERROR (Status) || ((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
-\r
- Status = GetOneKeyFromSerial (TerminalDevice->SerialIo, &Input);\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
+ Process key notify.\r
\r
- return EFI_SUCCESS;\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
+ BOOLEAN HasKey;\r
+ TERMINAL_DEV *TerminalDevice;\r
+ EFI_INPUT_KEY Key;\r
+ EFI_KEY_DATA KeyData;\r
+ LIST_ENTRY *Link;\r
+ LIST_ENTRY *NotifyList;\r
+ TERMINAL_CONSOLE_IN_EX_NOTIFY *CurrentNotify;\r
+ EFI_TPL OldTpl;\r
+\r
+ TerminalDevice = (TERMINAL_DEV *) Context;\r
+\r
+ //\r
+ // Invoke notification functions.\r
+ //\r
+ NotifyList = &TerminalDevice->NotifyList;\r
+ while (TRUE) {\r
+ //\r
+ // Enter critical section\r
+ //\r
+ OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
+ HasKey = EfiKeyFiFoForNotifyRemoveOneKey (TerminalDevice->EfiKeyFiFoForNotify, &Key);\r
+ CopyMem (&KeyData.Key, &Key, sizeof (EFI_INPUT_KEY));\r
+ KeyData.KeyState.KeyShiftState = 0;\r
+ KeyData.KeyState.KeyToggleState = 0;\r
+ //\r
+ // Leave critical section\r
+ //\r
+ gBS->RestoreTPL (OldTpl);\r
+ if (!HasKey) {\r
+ break;\r
+ }\r
+ for (Link = GetFirstNode (NotifyList); !IsNull (NotifyList, Link); Link = GetNextNode (NotifyList, Link)) {\r
+ CurrentNotify = CR (Link, TERMINAL_CONSOLE_IN_EX_NOTIFY, NotifyEntry, TERMINAL_CONSOLE_IN_EX_NOTIFY_SIGNATURE);\r
+ if (IsKeyRegistered (&CurrentNotify->KeyData, &KeyData)) {\r
+ CurrentNotify->KeyNotificationFn (&KeyData);\r
+ }\r
+ }\r
+ }\r
}\r
\r
/**\r
@param Input The key will be input.\r
\r
@retval TRUE If insert successfully.\r
- @retval FLASE If Raw Data buffer is full before key insertion,\r
+ @retval FALSE If Raw Data buffer is full before key insertion,\r
and the key is lost.\r
\r
**/\r
@param Output The key will be removed.\r
\r
@retval TRUE If insert successfully.\r
- @retval FLASE If Raw Data FIFO buffer is empty before remove operation.\r
+ @retval FALSE If Raw Data FIFO buffer is empty before remove operation.\r
\r
**/\r
BOOLEAN\r
@param TerminalDevice Terminal driver private structure\r
\r
@retval TRUE If Raw Data FIFO buffer is empty.\r
- @retval FLASE If Raw Data FIFO buffer is not empty.\r
+ @retval FALSE If Raw Data FIFO buffer is not empty.\r
\r
**/\r
BOOLEAN\r
@param TerminalDevice Terminal driver private structure\r
\r
@retval TRUE If Raw Data FIFO buffer is full.\r
- @retval FLASE If Raw Data FIFO buffer is not full.\r
+ @retval FALSE If Raw Data FIFO buffer is not full.\r
\r
**/\r
BOOLEAN\r
return FALSE;\r
}\r
\r
+/**\r
+ Insert one pre-fetched key into the FIFO buffer.\r
+\r
+ @param EfiKeyFiFo Pointer to instance of EFI_KEY_FIFO.\r
+ @param Input 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
+EfiKeyFiFoForNotifyInsertOneKey (\r
+ EFI_KEY_FIFO *EfiKeyFiFo,\r
+ EFI_INPUT_KEY *Input\r
+ )\r
+{\r
+ UINT8 Tail;\r
+\r
+ Tail = EfiKeyFiFo->Tail;\r
+\r
+ if (IsEfiKeyFiFoForNotifyFull (EfiKeyFiFo)) {\r
+ //\r
+ // FIFO is full\r
+ //\r
+ return FALSE;\r
+ }\r
+\r
+ CopyMem (&EfiKeyFiFo->Data[Tail], Input, sizeof (EFI_INPUT_KEY));\r
+\r
+ 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 EfiKeyFiFo Pointer to instance of EFI_KEY_FIFO.\r
+ @param Output The key will be removed.\r
+\r
+ @retval TRUE If remove successfully.\r
+ @retval FALSE If FIFO buffer is empty before remove operation.\r
+\r
+**/\r
+BOOLEAN\r
+EfiKeyFiFoForNotifyRemoveOneKey (\r
+ EFI_KEY_FIFO *EfiKeyFiFo,\r
+ EFI_INPUT_KEY *Output\r
+ )\r
+{\r
+ UINT8 Head;\r
+\r
+ Head = EfiKeyFiFo->Head;\r
+ ASSERT (Head < FIFO_MAX_NUMBER + 1);\r
+\r
+ if (IsEfiKeyFiFoForNotifyEmpty (EfiKeyFiFo)) {\r
+ //\r
+ // FIFO is empty\r
+ //\r
+ Output->ScanCode = SCAN_NULL;\r
+ Output->UnicodeChar = 0;\r
+ return FALSE;\r
+ }\r
+\r
+ CopyMem (Output, &EfiKeyFiFo->Data[Head], sizeof (EFI_INPUT_KEY));\r
+\r
+ 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 EfiKeyFiFo Pointer to instance of EFI_KEY_FIFO.\r
+\r
+ @retval TRUE If FIFO buffer is empty.\r
+ @retval FALSE If FIFO buffer is not empty.\r
+\r
+**/\r
+BOOLEAN\r
+IsEfiKeyFiFoForNotifyEmpty (\r
+ EFI_KEY_FIFO *EfiKeyFiFo\r
+ )\r
+{\r
+ if (EfiKeyFiFo->Head == EfiKeyFiFo->Tail) {\r
+ return TRUE;\r
+ } else {\r
+ return FALSE;\r
+ }\r
+}\r
+\r
+/**\r
+ Clarify whether FIFO buffer is full.\r
+\r
+ @param EfiKeyFiFo Pointer to instance of EFI_KEY_FIFO.\r
+\r
+ @retval TRUE If FIFO buffer is full.\r
+ @retval FALSE If FIFO buffer is not full.\r
+\r
+**/\r
+BOOLEAN\r
+IsEfiKeyFiFoForNotifyFull (\r
+ EFI_KEY_FIFO *EfiKeyFiFo\r
+ )\r
+{\r
+ UINT8 Tail;\r
+ UINT8 Head;\r
+\r
+ Tail = EfiKeyFiFo->Tail;\r
+ Head = EfiKeyFiFo->Head;\r
+\r
+ if (((Tail + 1) % (FIFO_MAX_NUMBER + 1)) == Head) {\r
+ return TRUE;\r
+ }\r
+\r
+ return FALSE;\r
+}\r
+\r
/**\r
Insert one pre-fetched key into the FIFO buffer.\r
\r
@param Key The key will be input.\r
\r
@retval TRUE If insert successfully.\r
- @retval FLASE If FIFO buffer is full before key insertion,\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
- 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
- ASSERT (Tail < FIFO_MAX_NUMBER + 1);\r
\r
+ CopyMem (&KeyData.Key, Key, sizeof (EFI_INPUT_KEY));\r
+ KeyData.KeyState.KeyShiftState = 0;\r
+ KeyData.KeyState.KeyToggleState = 0;\r
+\r
+ //\r
+ // Signal KeyNotify process event if this key pressed matches any key 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
+ //\r
+ // The key notification function needs to run at TPL_CALLBACK\r
+ // while current TPL is TPL_NOTIFY. It will be invoked in\r
+ // KeyNotifyProcessHandler() which runs at TPL_CALLBACK.\r
+ //\r
+ EfiKeyFiFoForNotifyInsertOneKey (TerminalDevice->EfiKeyFiFoForNotify, Key);\r
+ gBS->SignalEvent (TerminalDevice->KeyNotifyProcessEvent);\r
+ break;\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
@param Output The key will be removed.\r
\r
@retval TRUE If insert successfully.\r
- @retval FLASE If FIFO buffer is empty before remove operation.\r
+ @retval FALSE If FIFO buffer is empty before remove operation.\r
\r
**/\r
BOOLEAN\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
\r
@param TerminalDevice Terminal driver private structure\r
\r
@retval TRUE If FIFO buffer is empty.\r
- @retval FLASE If FIFO buffer is not empty.\r
+ @retval FALSE If FIFO buffer is not empty.\r
\r
**/\r
BOOLEAN\r
@param TerminalDevice Terminal driver private structure\r
\r
@retval TRUE If FIFO buffer is full.\r
- @retval FLASE If FIFO buffer is not full.\r
+ @retval FALSE If FIFO buffer is not full.\r
\r
**/\r
BOOLEAN\r
@param Input The key will be input.\r
\r
@retval TRUE If insert successfully.\r
- @retval FLASE If Unicode FIFO buffer is full before key insertion,\r
+ @retval FALSE If Unicode FIFO buffer is full before key insertion,\r
and the key is lost.\r
\r
**/\r
\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
- @retval TRUE If insert successfully.\r
- @retval FLASE If Unicode FIFO buffer is empty before remove operation.\r
-\r
**/\r
-BOOLEAN\r
+VOID\r
UnicodeFiFoRemoveOneKey (\r
TERMINAL_DEV *TerminalDevice,\r
UINT16 *Output\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
-\r
*Output = TerminalDevice->UnicodeFiFo->Data[Head];\r
\r
TerminalDevice->UnicodeFiFo->Head = (UINT8) ((Head + 1) % (FIFO_MAX_NUMBER + 1));\r
-\r
- return TRUE;\r
}\r
\r
/**\r
@param TerminalDevice Terminal driver private structure\r
\r
@retval TRUE If Unicode FIFO buffer is empty.\r
- @retval FLASE If Unicode FIFO buffer is not empty.\r
+ @retval FALSE If Unicode FIFO buffer is not empty.\r
\r
**/\r
BOOLEAN\r
@param TerminalDevice Terminal driver private structure\r
\r
@retval TRUE If Unicode FIFO buffer is full.\r
- @retval FLASE If Unicode FIFO buffer is not full.\r
+ @retval FALSE If Unicode FIFO buffer is not full.\r
\r
**/\r
BOOLEAN\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
- )\r
-{\r
- UINT8 Tail;\r
- UINT8 Head;\r
-\r
- Tail = TerminalDevice->UnicodeFiFo->Tail;\r
- Head = TerminalDevice->UnicodeFiFo->Head;\r
-\r
- if (Tail >= Head) {\r
- return (UINT8) (Tail - Head);\r
- } else {\r
- return (UINT8) (Tail + FIFO_MAX_NUMBER + 1 - Head);\r
- }\r
-}\r
\r
/**\r
Update the Unicode characters from a terminal input device into EFI Keys FIFO.\r
\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 ((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 ((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 ((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 ((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
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
TerminalDevice->ResetState = RESET_STATE_DEFAULT;\r
}\r
\r
- while (!IsUnicodeFiFoEmpty(TerminalDevice)) {\r
+ while (!IsUnicodeFiFoEmpty (TerminalDevice) && !IsEfiKeyFiFoFull (TerminalDevice)) {\r
\r
if (TerminalDevice->InputState != INPUT_STATE_DEFAULT) {\r
//\r
continue;\r
}\r
\r
- if (UnicodeChar == 'O' && TerminalDevice->TerminalType == VT100TYPE) {\r
+ if (UnicodeChar == 'O' && (TerminalDevice->TerminalType == TerminalTypeVt100 ||\r
+ TerminalDevice->TerminalType == TerminalTypeTtyTerm)) {\r
TerminalDevice->InputState |= INPUT_STATE_O;\r
TerminalDevice->ResetState = RESET_STATE_DEFAULT;\r
continue;\r
\r
Key.ScanCode = SCAN_NULL;\r
\r
- if (TerminalDevice->TerminalType == VT100PLUSTYPE ||\r
- TerminalDevice->TerminalType == VTUTF8TYPE) {\r
+ if (TerminalDevice->TerminalType == TerminalTypeVt100Plus ||\r
+ TerminalDevice->TerminalType == TerminalTypeVtUtf8) {\r
switch (UnicodeChar) {\r
case '1':\r
Key.ScanCode = SCAN_F1;\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
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
\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
Key.ScanCode = SCAN_NULL;\r
\r
- if (TerminalDevice->TerminalType == VT100TYPE) {\r
+ if (TerminalDevice->TerminalType == TerminalTypeVt100) {\r
switch (UnicodeChar) {\r
case 'P':\r
Key.ScanCode = SCAN_F1;\r
default :\r
break;\r
}\r
+ } else if (TerminalDevice->TerminalType == TerminalTypeTtyTerm) {\r
+ /* Also accept VT100 escape codes for F1-F4, HOME and END 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
+ case 'H':\r
+ Key.ScanCode = SCAN_HOME;\r
+ break;\r
+ case 'F':\r
+ Key.ScanCode = SCAN_END;\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
\r
Key.ScanCode = SCAN_NULL;\r
\r
- if (TerminalDevice->TerminalType == PCANSITYPE ||\r
- TerminalDevice->TerminalType == VT100TYPE ||\r
- TerminalDevice->TerminalType == VT100PLUSTYPE ||\r
- TerminalDevice->TerminalType == VTUTF8TYPE) {\r
+ if (TerminalDevice->TerminalType == TerminalTypePcAnsi ||\r
+ TerminalDevice->TerminalType == TerminalTypeVt100 ||\r
+ TerminalDevice->TerminalType == TerminalTypeVt100Plus ||\r
+ TerminalDevice->TerminalType == TerminalTypeVtUtf8 ||\r
+ TerminalDevice->TerminalType == TerminalTypeTtyTerm) {\r
switch (UnicodeChar) {\r
case 'A':\r
Key.ScanCode = SCAN_UP;\r
Key.ScanCode = SCAN_LEFT;\r
break;\r
case 'H':\r
- if (TerminalDevice->TerminalType == PCANSITYPE ||\r
- TerminalDevice->TerminalType == VT100TYPE) {\r
+ if (TerminalDevice->TerminalType == TerminalTypePcAnsi ||\r
+ TerminalDevice->TerminalType == TerminalTypeVt100 ||\r
+ TerminalDevice->TerminalType == TerminalTypeTtyTerm) {\r
Key.ScanCode = SCAN_HOME;\r
}\r
break;\r
case 'F':\r
- if (TerminalDevice->TerminalType == PCANSITYPE) {\r
+ if (TerminalDevice->TerminalType == TerminalTypePcAnsi ||\r
+ TerminalDevice->TerminalType == TerminalTypeTtyTerm) {\r
Key.ScanCode = SCAN_END;\r
}\r
break;\r
case 'K':\r
- if (TerminalDevice->TerminalType == VT100TYPE) {\r
+ if (TerminalDevice->TerminalType == TerminalTypeVt100) {\r
Key.ScanCode = SCAN_END;\r
}\r
break;\r
case 'L':\r
case '@':\r
- if (TerminalDevice->TerminalType == PCANSITYPE ||\r
- TerminalDevice->TerminalType == VT100TYPE) {\r
+ if (TerminalDevice->TerminalType == TerminalTypePcAnsi ||\r
+ TerminalDevice->TerminalType == TerminalTypeVt100) {\r
Key.ScanCode = SCAN_INSERT;\r
}\r
break;\r
case 'X':\r
- if (TerminalDevice->TerminalType == PCANSITYPE) {\r
+ if (TerminalDevice->TerminalType == TerminalTypePcAnsi) {\r
Key.ScanCode = SCAN_DELETE;\r
}\r
break;\r
case 'P':\r
- if (TerminalDevice->TerminalType == VT100TYPE) {\r
+ if (TerminalDevice->TerminalType == TerminalTypeVt100) {\r
Key.ScanCode = SCAN_DELETE;\r
- } else if (TerminalDevice->TerminalType == PCANSITYPE) {\r
+ } else if (TerminalDevice->TerminalType == TerminalTypePcAnsi) {\r
Key.ScanCode = SCAN_F4;\r
}\r
break;\r
case 'I':\r
- if (TerminalDevice->TerminalType == PCANSITYPE) {\r
+ if (TerminalDevice->TerminalType == TerminalTypePcAnsi) {\r
Key.ScanCode = SCAN_PAGE_UP;\r
}\r
break;\r
case 'V':\r
- if (TerminalDevice->TerminalType == PCANSITYPE) {\r
+ if (TerminalDevice->TerminalType == TerminalTypePcAnsi) {\r
Key.ScanCode = SCAN_F10;\r
}\r
+ break;\r
case '?':\r
- if (TerminalDevice->TerminalType == VT100TYPE) {\r
+ if (TerminalDevice->TerminalType == TerminalTypeVt100) {\r
Key.ScanCode = SCAN_PAGE_UP;\r
}\r
break;\r
case 'G':\r
- if (TerminalDevice->TerminalType == PCANSITYPE) {\r
+ if (TerminalDevice->TerminalType == TerminalTypePcAnsi) {\r
Key.ScanCode = SCAN_PAGE_DOWN;\r
}\r
break;\r
case 'U':\r
- if (TerminalDevice->TerminalType == PCANSITYPE) {\r
+ if (TerminalDevice->TerminalType == TerminalTypePcAnsi) {\r
Key.ScanCode = SCAN_F9;\r
}\r
+ break;\r
case '/':\r
- if (TerminalDevice->TerminalType == VT100TYPE) {\r
+ if (TerminalDevice->TerminalType == TerminalTypeVt100) {\r
Key.ScanCode = SCAN_PAGE_DOWN;\r
}\r
break;\r
case 'M':\r
- if (TerminalDevice->TerminalType == PCANSITYPE) {\r
+ if (TerminalDevice->TerminalType == TerminalTypePcAnsi) {\r
Key.ScanCode = SCAN_F1;\r
}\r
break;\r
case 'N':\r
- if (TerminalDevice->TerminalType == PCANSITYPE) {\r
+ if (TerminalDevice->TerminalType == TerminalTypePcAnsi) {\r
Key.ScanCode = SCAN_F2;\r
}\r
break;\r
case 'O':\r
- if (TerminalDevice->TerminalType == PCANSITYPE) {\r
+ if (TerminalDevice->TerminalType == TerminalTypePcAnsi) {\r
Key.ScanCode = SCAN_F3;\r
}\r
break;\r
case 'Q':\r
- if (TerminalDevice->TerminalType == PCANSITYPE) {\r
+ if (TerminalDevice->TerminalType == TerminalTypePcAnsi) {\r
Key.ScanCode = SCAN_F5;\r
}\r
break;\r
case 'R':\r
- if (TerminalDevice->TerminalType == PCANSITYPE) {\r
+ if (TerminalDevice->TerminalType == TerminalTypePcAnsi) {\r
Key.ScanCode = SCAN_F6;\r
}\r
break;\r
case 'S':\r
- if (TerminalDevice->TerminalType == PCANSITYPE) {\r
+ if (TerminalDevice->TerminalType == TerminalTypePcAnsi) {\r
Key.ScanCode = SCAN_F7;\r
}\r
break;\r
case 'T':\r
- if (TerminalDevice->TerminalType == PCANSITYPE) {\r
+ if (TerminalDevice->TerminalType == TerminalTypePcAnsi) {\r
Key.ScanCode = SCAN_F8;\r
}\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 == TerminalTypeTtyTerm &&\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
break;\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 == TerminalTypeTtyTerm) {\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 2:\r
+ Key.ScanCode = SCAN_INSERT;\r
+ break;\r
+ case 3:\r
+ Key.ScanCode = SCAN_DELETE;\r
+ break;\r
+ case 5:\r
+ Key.ScanCode = SCAN_PAGE_UP;\r
+ break;\r
+ case 6:\r
+ Key.ScanCode = SCAN_PAGE_DOWN;\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
}\r
\r
if (UnicodeChar == DEL) {\r
- Key.ScanCode = SCAN_DELETE;\r
- Key.UnicodeChar = 0;\r
+ if (TerminalDevice->TerminalType == TerminalTypeTtyTerm) {\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