diff options
Diffstat (limited to 'MdeModulePkg')
-rw-r--r-- | MdeModulePkg/Universal/Console/TerminalDxe/Ansi.c | 158 | ||||
-rw-r--r-- | MdeModulePkg/Universal/Console/TerminalDxe/TerminalConIn.c | 3144 | ||||
-rw-r--r-- | MdeModulePkg/Universal/Console/TerminalDxe/Vtutf8.c | 656 |
3 files changed, 1980 insertions, 1978 deletions
diff --git a/MdeModulePkg/Universal/Console/TerminalDxe/Ansi.c b/MdeModulePkg/Universal/Console/TerminalDxe/Ansi.c index 4f84cc0..15147c1 100644 --- a/MdeModulePkg/Universal/Console/TerminalDxe/Ansi.c +++ b/MdeModulePkg/Universal/Console/TerminalDxe/Ansi.c @@ -1,79 +1,79 @@ -/** @file - Implementation of translation upon PC ANSI. - -Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.<BR> -This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - - -#include "Terminal.h" - -/** - Translate all raw data in the Raw FIFO into unicode, and insert - them into Unicode FIFO. - - @param TerminalDevice The terminal device. - -**/ -VOID -AnsiRawDataToUnicode ( - IN TERMINAL_DEV *TerminalDevice - ) -{ - UINT8 RawData; - - // - // pop the raw data out from the raw fifo, - // and translate it into unicode, then push - // the unicode into unicode fifo, until the raw fifo is empty. - // - while (!IsRawFiFoEmpty (TerminalDevice) && !IsUnicodeFiFoFull(TerminalDevice) ) { - - RawFiFoRemoveOneKey (TerminalDevice, &RawData); - - UnicodeFiFoInsertOneKey (TerminalDevice, (UINT16) RawData); - } -} - -/** - Check if input string is valid Ascii string, valid EFI control characters - or valid text graphics. - - @param TerminalDevice The terminal device. - @param WString The input string. - - @retval EFI_UNSUPPORTED If not all input characters are valid. - @retval EFI_SUCCESS If all input characters are valid. - -**/ -EFI_STATUS -AnsiTestString ( - IN TERMINAL_DEV *TerminalDevice, - IN CHAR16 *WString - ) -{ - CHAR8 GraphicChar; - - // - // support three kind of character: - // valid ascii, valid efi control char, valid text graphics. - // - for (; *WString != CHAR_NULL; WString++) { - - if ( !(TerminalIsValidAscii (*WString) || - TerminalIsValidEfiCntlChar (*WString) || - TerminalIsValidTextGraphics (*WString, &GraphicChar, NULL) )) { - - return EFI_UNSUPPORTED; - } - } - - return EFI_SUCCESS; -} +/** @file
+ Implementation of translation upon PC ANSI.
+
+Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+
+#include "Terminal.h"
+
+/**
+ Translate all raw data in the Raw FIFO into unicode, and insert
+ them into Unicode FIFO.
+
+ @param TerminalDevice The terminal device.
+
+**/
+VOID
+AnsiRawDataToUnicode (
+ IN TERMINAL_DEV *TerminalDevice
+ )
+{
+ UINT8 RawData;
+
+ //
+ // pop the raw data out from the raw fifo,
+ // and translate it into unicode, then push
+ // the unicode into unicode fifo, until the raw fifo is empty.
+ //
+ while (!IsRawFiFoEmpty (TerminalDevice) && !IsUnicodeFiFoFull (TerminalDevice)) {
+
+ RawFiFoRemoveOneKey (TerminalDevice, &RawData);
+
+ UnicodeFiFoInsertOneKey (TerminalDevice, (UINT16) RawData);
+ }
+}
+
+/**
+ Check if input string is valid Ascii string, valid EFI control characters
+ or valid text graphics.
+
+ @param TerminalDevice The terminal device.
+ @param WString The input string.
+
+ @retval EFI_UNSUPPORTED If not all input characters are valid.
+ @retval EFI_SUCCESS If all input characters are valid.
+
+**/
+EFI_STATUS
+AnsiTestString (
+ IN TERMINAL_DEV *TerminalDevice,
+ IN CHAR16 *WString
+ )
+{
+ CHAR8 GraphicChar;
+
+ //
+ // support three kind of character:
+ // valid ascii, valid efi control char, valid text graphics.
+ //
+ for (; *WString != CHAR_NULL; WString++) {
+
+ if ( !(TerminalIsValidAscii (*WString) ||
+ TerminalIsValidEfiCntlChar (*WString) ||
+ TerminalIsValidTextGraphics (*WString, &GraphicChar, NULL) )) {
+
+ return EFI_UNSUPPORTED;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
diff --git a/MdeModulePkg/Universal/Console/TerminalDxe/TerminalConIn.c b/MdeModulePkg/Universal/Console/TerminalDxe/TerminalConIn.c index 662cd56..47881a9 100644 --- a/MdeModulePkg/Universal/Console/TerminalDxe/TerminalConIn.c +++ b/MdeModulePkg/Universal/Console/TerminalDxe/TerminalConIn.c @@ -1,1571 +1,1573 @@ -/** @file - Implementation for EFI_SIMPLE_TEXT_INPUT_PROTOCOL protocol. - -Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR> -This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "Terminal.h" - - -/** - Reads the next keystroke from the input device. The WaitForKey Event can - be used to test for existence of a keystroke via WaitForEvent () call. - - @param TerminalDevice Terminal driver private structure - @param KeyData A pointer to a buffer that is filled in with the - keystroke state data for the key that was - pressed. - - @retval EFI_SUCCESS The keystroke information was returned. - @retval EFI_NOT_READY There was no keystroke data available. - @retval EFI_INVALID_PARAMETER KeyData is NULL. - -**/ -EFI_STATUS -ReadKeyStrokeWorker ( - IN TERMINAL_DEV *TerminalDevice, - OUT EFI_KEY_DATA *KeyData - ) -{ - if (KeyData == NULL) { - return EFI_INVALID_PARAMETER; - } - - if (!EfiKeyFiFoRemoveOneKey (TerminalDevice, &KeyData->Key)) { - return EFI_NOT_READY; - } - - KeyData->KeyState.KeyShiftState = 0; - KeyData->KeyState.KeyToggleState = 0; - - - return EFI_SUCCESS; - -} - -/** - Implements EFI_SIMPLE_TEXT_INPUT_PROTOCOL.Reset(). - This driver only perform dependent serial device reset regardless of - the value of ExtendeVerification - - @param This Indicates the calling context. - @param ExtendedVerification Skip by this driver. - - @retval EFI_SUCCESS The reset operation succeeds. - @retval EFI_DEVICE_ERROR The dependent serial port reset fails. - -**/ -EFI_STATUS -EFIAPI -TerminalConInReset ( - IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This, - IN BOOLEAN ExtendedVerification - ) -{ - EFI_STATUS Status; - TERMINAL_DEV *TerminalDevice; - - TerminalDevice = TERMINAL_CON_IN_DEV_FROM_THIS (This); - - // - // Report progress code here - // - REPORT_STATUS_CODE_WITH_DEVICE_PATH ( - EFI_PROGRESS_CODE, - (EFI_PERIPHERAL_REMOTE_CONSOLE | EFI_P_PC_RESET), - TerminalDevice->DevicePath - ); - - Status = TerminalDevice->SerialIo->Reset (TerminalDevice->SerialIo); - - // - // Make all the internal buffer empty for keys - // - TerminalDevice->RawFiFo->Head = TerminalDevice->RawFiFo->Tail; - TerminalDevice->UnicodeFiFo->Head = TerminalDevice->UnicodeFiFo->Tail; - TerminalDevice->EfiKeyFiFo->Head = TerminalDevice->EfiKeyFiFo->Tail; - - if (EFI_ERROR (Status)) { - REPORT_STATUS_CODE_WITH_DEVICE_PATH ( - EFI_ERROR_CODE | EFI_ERROR_MINOR, - (EFI_PERIPHERAL_REMOTE_CONSOLE | EFI_P_EC_CONTROLLER_ERROR), - TerminalDevice->DevicePath - ); - } - - return Status; -} - -/** - Implements EFI_SIMPLE_TEXT_INPUT_PROTOCOL.ReadKeyStroke(). - - @param This Indicates the calling context. - @param Key A pointer to a buffer that is filled in with the - keystroke information for the key that was sent - from terminal. - - @retval EFI_SUCCESS The keystroke information is returned successfully. - @retval EFI_NOT_READY There is no keystroke data available. - @retval EFI_DEVICE_ERROR The dependent serial device encounters error. - -**/ -EFI_STATUS -EFIAPI -TerminalConInReadKeyStroke ( - IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This, - OUT EFI_INPUT_KEY *Key - ) -{ - TERMINAL_DEV *TerminalDevice; - EFI_STATUS Status; - EFI_KEY_DATA KeyData; - - // - // get TERMINAL_DEV from "This" parameter. - // - TerminalDevice = TERMINAL_CON_IN_DEV_FROM_THIS (This); - - Status = ReadKeyStrokeWorker (TerminalDevice, &KeyData); - if (EFI_ERROR (Status)) { - return Status; - } - - CopyMem (Key, &KeyData.Key, sizeof (EFI_INPUT_KEY)); - - return EFI_SUCCESS; - -} - -/** - Check if the key already has been registered. - - If both RegsiteredData and InputData is NULL, then ASSERT(). - - @param RegsiteredData A pointer to a buffer that is filled in with the - keystroke state data for the key that was - registered. - @param InputData A pointer to a buffer that is filled in with the - keystroke state data for the key that was - pressed. - - @retval TRUE Key be pressed matches a registered key. - @retval FLASE Match failed. - -**/ -BOOLEAN -IsKeyRegistered ( - IN EFI_KEY_DATA *RegsiteredData, - IN EFI_KEY_DATA *InputData - ) -{ - ASSERT (RegsiteredData != NULL && InputData != NULL); - - if ((RegsiteredData->Key.ScanCode != InputData->Key.ScanCode) || - (RegsiteredData->Key.UnicodeChar != InputData->Key.UnicodeChar)) { - return FALSE; - } - - return TRUE; -} - - - -/** - Event notification function for EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL.WaitForKeyEx event - Signal the event if there is key available - - @param Event Indicates the event that invoke this function. - @param Context Indicates the calling context. - -**/ -VOID -EFIAPI -TerminalConInWaitForKeyEx ( - IN EFI_EVENT Event, - IN VOID *Context - ) -{ - TerminalConInWaitForKey (Event, Context); -} - -// -// Simple Text Input Ex protocol functions -// - -/** - Reset the input device and optionally run diagnostics - - @param This Protocol instance pointer. - @param ExtendedVerification Driver may perform diagnostics on reset. - - @retval EFI_SUCCESS The device was reset. - @retval EFI_DEVICE_ERROR The device is not functioning properly and could - not be reset. - -**/ -EFI_STATUS -EFIAPI -TerminalConInResetEx ( - IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, - IN BOOLEAN ExtendedVerification - ) -{ - EFI_STATUS Status; - TERMINAL_DEV *TerminalDevice; - - TerminalDevice = TERMINAL_CON_IN_EX_DEV_FROM_THIS (This); - - Status = TerminalDevice->SimpleInput.Reset (&TerminalDevice->SimpleInput, ExtendedVerification); - if (EFI_ERROR (Status)) { - return EFI_DEVICE_ERROR; - } - - return EFI_SUCCESS; - -} - - -/** - Reads the next keystroke from the input device. The WaitForKey Event can - be used to test for existence of a keystroke via WaitForEvent () call. - - @param This Protocol instance pointer. - @param KeyData A pointer to a buffer that is filled in with the - keystroke state data for the key that was - pressed. - - @retval EFI_SUCCESS The keystroke information was returned. - @retval EFI_NOT_READY There was no keystroke data available. - @retval EFI_DEVICE_ERROR The keystroke information was not returned due - to hardware errors. - @retval EFI_INVALID_PARAMETER KeyData is NULL. - -**/ -EFI_STATUS -EFIAPI -TerminalConInReadKeyStrokeEx ( - IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, - OUT EFI_KEY_DATA *KeyData - ) -{ - TERMINAL_DEV *TerminalDevice; - - if (KeyData == NULL) { - return EFI_INVALID_PARAMETER; - } - - TerminalDevice = TERMINAL_CON_IN_EX_DEV_FROM_THIS (This); - - return ReadKeyStrokeWorker (TerminalDevice, KeyData); - -} - - -/** - Set certain state for the input device. - - @param This Protocol instance pointer. - @param KeyToggleState A pointer to the EFI_KEY_TOGGLE_STATE to set the - state for the input device. - - @retval EFI_SUCCESS The device state was set successfully. - @retval EFI_DEVICE_ERROR The device is not functioning correctly and - could not have the setting adjusted. - @retval EFI_UNSUPPORTED The device does not have the ability to set its - state. - @retval EFI_INVALID_PARAMETER KeyToggleState is NULL. - -**/ -EFI_STATUS -EFIAPI -TerminalConInSetState ( - IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, - IN EFI_KEY_TOGGLE_STATE *KeyToggleState - ) -{ - if (KeyToggleState == NULL) { - return EFI_INVALID_PARAMETER; - } - - return EFI_SUCCESS; -} - - -/** - Register a notification function for a particular keystroke for the input device. - - @param This Protocol instance pointer. - @param KeyData A pointer to a buffer that is filled in with the - keystroke information data for the key that was - pressed. - @param KeyNotificationFunction Points to the function to be called when the key - sequence is typed specified by KeyData. - @param NotifyHandle Points to the unique handle assigned to the - registered notification. - - @retval EFI_SUCCESS The notification function was registered - successfully. - @retval EFI_OUT_OF_RESOURCES Unable to allocate resources for necessary data - structures. - @retval EFI_INVALID_PARAMETER KeyData or NotifyHandle is NULL. - -**/ -EFI_STATUS -EFIAPI -TerminalConInRegisterKeyNotify ( - IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, - IN EFI_KEY_DATA *KeyData, - IN EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction, - OUT EFI_HANDLE *NotifyHandle - ) -{ - TERMINAL_DEV *TerminalDevice; - TERMINAL_CONSOLE_IN_EX_NOTIFY *NewNotify; - LIST_ENTRY *Link; - LIST_ENTRY *NotifyList; - TERMINAL_CONSOLE_IN_EX_NOTIFY *CurrentNotify; - - if (KeyData == NULL || NotifyHandle == NULL || KeyNotificationFunction == NULL) { - return EFI_INVALID_PARAMETER; - } - - TerminalDevice = TERMINAL_CON_IN_EX_DEV_FROM_THIS (This); - - // - // Return EFI_SUCCESS if the (KeyData, NotificationFunction) is already registered. - // - NotifyList = &TerminalDevice->NotifyList; - for (Link = GetFirstNode (NotifyList); !IsNull (NotifyList,Link); Link = GetNextNode (NotifyList,Link)) { - CurrentNotify = CR ( - Link, - TERMINAL_CONSOLE_IN_EX_NOTIFY, - NotifyEntry, - TERMINAL_CONSOLE_IN_EX_NOTIFY_SIGNATURE - ); - if (IsKeyRegistered (&CurrentNotify->KeyData, KeyData)) { - if (CurrentNotify->KeyNotificationFn == KeyNotificationFunction) { - *NotifyHandle = CurrentNotify->NotifyHandle; - return EFI_SUCCESS; - } - } - } - - // - // Allocate resource to save the notification function - // - NewNotify = (TERMINAL_CONSOLE_IN_EX_NOTIFY *) AllocateZeroPool (sizeof (TERMINAL_CONSOLE_IN_EX_NOTIFY)); - if (NewNotify == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - NewNotify->Signature = TERMINAL_CONSOLE_IN_EX_NOTIFY_SIGNATURE; - NewNotify->KeyNotificationFn = KeyNotificationFunction; - NewNotify->NotifyHandle = (EFI_HANDLE) NewNotify; - CopyMem (&NewNotify->KeyData, KeyData, sizeof (KeyData)); - InsertTailList (&TerminalDevice->NotifyList, &NewNotify->NotifyEntry); - - *NotifyHandle = NewNotify->NotifyHandle; - - return EFI_SUCCESS; -} - - -/** - Remove a registered notification function from a particular keystroke. - - @param This Protocol instance pointer. - @param NotificationHandle The handle of the notification function being - unregistered. - - @retval EFI_SUCCESS The notification function was unregistered - successfully. - @retval EFI_INVALID_PARAMETER The NotificationHandle is invalid. - -**/ -EFI_STATUS -EFIAPI -TerminalConInUnregisterKeyNotify ( - IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, - IN EFI_HANDLE NotificationHandle - ) -{ - TERMINAL_DEV *TerminalDevice; - LIST_ENTRY *Link; - TERMINAL_CONSOLE_IN_EX_NOTIFY *CurrentNotify; - LIST_ENTRY *NotifyList; - - if (NotificationHandle == NULL) { - return EFI_INVALID_PARAMETER; - } - - if (((TERMINAL_CONSOLE_IN_EX_NOTIFY *) NotificationHandle)->Signature != TERMINAL_CONSOLE_IN_EX_NOTIFY_SIGNATURE) { - return EFI_INVALID_PARAMETER; - } - - TerminalDevice = TERMINAL_CON_IN_EX_DEV_FROM_THIS (This); - - NotifyList = &TerminalDevice->NotifyList; - for (Link = GetFirstNode (NotifyList); !IsNull (NotifyList,Link); Link = GetNextNode (NotifyList,Link)) { - CurrentNotify = CR ( - Link, - TERMINAL_CONSOLE_IN_EX_NOTIFY, - NotifyEntry, - TERMINAL_CONSOLE_IN_EX_NOTIFY_SIGNATURE - ); - if (CurrentNotify->NotifyHandle == NotificationHandle) { - // - // Remove the notification function from NotifyList and free resources - // - RemoveEntryList (&CurrentNotify->NotifyEntry); - - gBS->FreePool (CurrentNotify); - return EFI_SUCCESS; - } - } - - // - // Can not find the matching entry in database. - // - return EFI_INVALID_PARAMETER; -} - -/** - Translate raw data into Unicode (according to different encode), and - translate Unicode into key information. (according to different standard). - - @param TerminalDevice Terminal driver private structure. - -**/ -VOID -TranslateRawDataToEfiKey ( - IN TERMINAL_DEV *TerminalDevice - ) -{ - switch (TerminalDevice->TerminalType) { - - case PCANSITYPE: - case VT100TYPE: - case VT100PLUSTYPE: - AnsiRawDataToUnicode (TerminalDevice); - UnicodeToEfiKey (TerminalDevice); - break; - - case VTUTF8TYPE: - // - // Process all the raw data in the RawFIFO, - // put the processed key into UnicodeFIFO. - // - VTUTF8RawDataToUnicode (TerminalDevice); - - // - // Translate all the Unicode data in the UnicodeFIFO to Efi key, - // then put into EfiKeyFIFO. - // - UnicodeToEfiKey (TerminalDevice); - - break; - } -} - -/** - Event notification function for EFI_SIMPLE_TEXT_INPUT_PROTOCOL.WaitForKey event - Signal the event if there is key available - - @param Event Indicates the event that invoke this function. - @param Context Indicates the calling context. - -**/ -VOID -EFIAPI -TerminalConInWaitForKey ( - IN EFI_EVENT Event, - IN VOID *Context - ) -{ - // - // Someone is waiting on the keystroke event, if there's - // a key pending, signal the event - // - if (!IsEfiKeyFiFoEmpty ((TERMINAL_DEV *) Context)) { - - gBS->SignalEvent (Event); - } -} - -/** - Timer handler to poll the key from serial. - - @param Event Indicates the event that invoke this function. - @param Context Indicates the calling context. -**/ -VOID -EFIAPI -TerminalConInTimerHandler ( - IN EFI_EVENT Event, - IN VOID *Context - ) -{ - EFI_STATUS Status; - TERMINAL_DEV *TerminalDevice; - UINT8 Input; - EFI_SERIAL_IO_MODE *Mode; - EFI_SERIAL_IO_PROTOCOL *SerialIo; - UINTN SerialInTimeOut; - - TerminalDevice = (TERMINAL_DEV *) Context; - - SerialIo = TerminalDevice->SerialIo; - if (SerialIo == NULL) { - return ; - } - // - // if current timeout value for serial device is not identical with - // the value saved in TERMINAL_DEV structure, then recalculate the - // timeout value again and set serial attribute according to this value. - // - Mode = SerialIo->Mode; - if (Mode->Timeout != TerminalDevice->SerialInTimeOut) { - - SerialInTimeOut = 0; - if (Mode->BaudRate != 0) { - // - // According to BAUD rate to calculate the timeout value. - // - SerialInTimeOut = (1 + Mode->DataBits + Mode->StopBits) * 2 * 1000000 / (UINTN) Mode->BaudRate; - } - - Status = SerialIo->SetAttributes ( - SerialIo, - Mode->BaudRate, - Mode->ReceiveFifoDepth, - (UINT32) SerialInTimeOut, - (EFI_PARITY_TYPE) (Mode->Parity), - (UINT8) Mode->DataBits, - (EFI_STOP_BITS_TYPE) (Mode->StopBits) - ); - - if (EFI_ERROR (Status)) { - TerminalDevice->SerialInTimeOut = 0; - } else { - TerminalDevice->SerialInTimeOut = SerialInTimeOut; - } - } - - // - // Fetch all the keys in the serial buffer, - // and insert the byte stream into RawFIFO. - // - while( !IsRawFiFoFull(TerminalDevice) ) { - - Status = GetOneKeyFromSerial (TerminalDevice->SerialIo, &Input); - - if (EFI_ERROR (Status)) { - if (Status == EFI_DEVICE_ERROR) { - REPORT_STATUS_CODE_WITH_DEVICE_PATH ( - EFI_ERROR_CODE | EFI_ERROR_MINOR, - (EFI_PERIPHERAL_REMOTE_CONSOLE | EFI_P_EC_INPUT_ERROR), - TerminalDevice->DevicePath - ); - } - break; - } - - RawFiFoInsertOneKey (TerminalDevice, Input); - } - - // - // Translate all the raw data in RawFIFO into EFI Key, - // according to different terminal type supported. - // - TranslateRawDataToEfiKey (TerminalDevice); -} - -/** - Get one key out of serial buffer. - - @param SerialIo Serial I/O protocol attached to the serial device. - @param Output The fetched key. - - @retval EFI_NOT_READY If serial buffer is empty. - @retval EFI_DEVICE_ERROR If reading serial buffer encounter error. - @retval EFI_SUCCESS If reading serial buffer successfully, put - the fetched key to the parameter output. - -**/ -EFI_STATUS -GetOneKeyFromSerial ( - EFI_SERIAL_IO_PROTOCOL *SerialIo, - UINT8 *Output - ) -{ - EFI_STATUS Status; - UINTN Size; - - Size = 1; - *Output = 0; - - // - // Read one key from serial I/O device. - // - Status = SerialIo->Read (SerialIo, &Size, Output); - - if (EFI_ERROR (Status)) { - - if (Status == EFI_TIMEOUT) { - return EFI_NOT_READY; - } - - return EFI_DEVICE_ERROR; - - } - - if (*Output == 0) { - return EFI_NOT_READY; - } - - return EFI_SUCCESS; -} - -/** - Insert one byte raw data into the Raw Data FIFO. - - @param TerminalDevice Terminal driver private structure. - @param Input The key will be input. - - @retval TRUE If insert successfully. - @retval FLASE If Raw Data buffer is full before key insertion, - and the key is lost. - -**/ -BOOLEAN -RawFiFoInsertOneKey ( - TERMINAL_DEV *TerminalDevice, - UINT8 Input - ) -{ - UINT8 Tail; - - Tail = TerminalDevice->RawFiFo->Tail; - - if (IsRawFiFoFull (TerminalDevice)) { - // - // Raw FIFO is full - // - return FALSE; - } - - TerminalDevice->RawFiFo->Data[Tail] = Input; - - TerminalDevice->RawFiFo->Tail = (UINT8) ((Tail + 1) % (RAW_FIFO_MAX_NUMBER + 1)); - - return TRUE; -} - -/** - Remove one pre-fetched key out of the Raw Data FIFO. - - @param TerminalDevice Terminal driver private structure. - @param Output The key will be removed. - - @retval TRUE If insert successfully. - @retval FLASE If Raw Data FIFO buffer is empty before remove operation. - -**/ -BOOLEAN -RawFiFoRemoveOneKey ( - TERMINAL_DEV *TerminalDevice, - UINT8 *Output - ) -{ - UINT8 Head; - - Head = TerminalDevice->RawFiFo->Head; - - if (IsRawFiFoEmpty (TerminalDevice)) { - // - // FIFO is empty - // - *Output = 0; - return FALSE; - } - - *Output = TerminalDevice->RawFiFo->Data[Head]; - - TerminalDevice->RawFiFo->Head = (UINT8) ((Head + 1) % (RAW_FIFO_MAX_NUMBER + 1)); - - return TRUE; -} - -/** - Clarify whether Raw Data FIFO buffer is empty. - - @param TerminalDevice Terminal driver private structure - - @retval TRUE If Raw Data FIFO buffer is empty. - @retval FLASE If Raw Data FIFO buffer is not empty. - -**/ -BOOLEAN -IsRawFiFoEmpty ( - TERMINAL_DEV *TerminalDevice - ) -{ - if (TerminalDevice->RawFiFo->Head == TerminalDevice->RawFiFo->Tail) { - return TRUE; - } else { - return FALSE; - } -} - -/** - Clarify whether Raw Data FIFO buffer is full. - - @param TerminalDevice Terminal driver private structure - - @retval TRUE If Raw Data FIFO buffer is full. - @retval FLASE If Raw Data FIFO buffer is not full. - -**/ -BOOLEAN -IsRawFiFoFull ( - TERMINAL_DEV *TerminalDevice - ) -{ - UINT8 Tail; - UINT8 Head; - - Tail = TerminalDevice->RawFiFo->Tail; - Head = TerminalDevice->RawFiFo->Head; - - if (((Tail + 1) % (RAW_FIFO_MAX_NUMBER + 1)) == Head) { - - return TRUE; - } - - return FALSE; -} - -/** - Insert one pre-fetched key into the FIFO buffer. - - @param TerminalDevice Terminal driver private structure. - @param Key The key will be input. - - @retval TRUE If insert successfully. - @retval FLASE If FIFO buffer is full before key insertion, - and the key is lost. - -**/ -BOOLEAN -EfiKeyFiFoInsertOneKey ( - TERMINAL_DEV *TerminalDevice, - EFI_INPUT_KEY *Key - ) -{ - UINT8 Tail; - LIST_ENTRY *Link; - LIST_ENTRY *NotifyList; - TERMINAL_CONSOLE_IN_EX_NOTIFY *CurrentNotify; - EFI_KEY_DATA KeyData; - - Tail = TerminalDevice->EfiKeyFiFo->Tail; - - CopyMem (&KeyData.Key, Key, sizeof (EFI_INPUT_KEY)); - KeyData.KeyState.KeyShiftState = 0; - KeyData.KeyState.KeyToggleState = 0; - - // - // Invoke notification functions if exist - // - NotifyList = &TerminalDevice->NotifyList; - for (Link = GetFirstNode (NotifyList); !IsNull (NotifyList,Link); Link = GetNextNode (NotifyList,Link)) { - CurrentNotify = CR ( - Link, - TERMINAL_CONSOLE_IN_EX_NOTIFY, - NotifyEntry, - TERMINAL_CONSOLE_IN_EX_NOTIFY_SIGNATURE - ); - if (IsKeyRegistered (&CurrentNotify->KeyData, &KeyData)) { - CurrentNotify->KeyNotificationFn (&KeyData); - } - } - if (IsEfiKeyFiFoFull (TerminalDevice)) { - // - // Efi Key FIFO is full - // - return FALSE; - } - - CopyMem (&TerminalDevice->EfiKeyFiFo->Data[Tail], Key, sizeof (EFI_INPUT_KEY)); - - TerminalDevice->EfiKeyFiFo->Tail = (UINT8) ((Tail + 1) % (FIFO_MAX_NUMBER + 1)); - - return TRUE; -} - -/** - Remove one pre-fetched key out of the FIFO buffer. - - @param TerminalDevice Terminal driver private structure. - @param Output The key will be removed. - - @retval TRUE If insert successfully. - @retval FLASE If FIFO buffer is empty before remove operation. - -**/ -BOOLEAN -EfiKeyFiFoRemoveOneKey ( - TERMINAL_DEV *TerminalDevice, - EFI_INPUT_KEY *Output - ) -{ - UINT8 Head; - - Head = TerminalDevice->EfiKeyFiFo->Head; - ASSERT (Head < FIFO_MAX_NUMBER + 1); - - if (IsEfiKeyFiFoEmpty (TerminalDevice)) { - // - // FIFO is empty - // - Output->ScanCode = SCAN_NULL; - Output->UnicodeChar = 0; - return FALSE; - } - - *Output = TerminalDevice->EfiKeyFiFo->Data[Head]; - - TerminalDevice->EfiKeyFiFo->Head = (UINT8) ((Head + 1) % (FIFO_MAX_NUMBER + 1)); - - return TRUE; -} - -/** - Clarify whether FIFO buffer is empty. - - @param TerminalDevice Terminal driver private structure - - @retval TRUE If FIFO buffer is empty. - @retval FLASE If FIFO buffer is not empty. - -**/ -BOOLEAN -IsEfiKeyFiFoEmpty ( - TERMINAL_DEV *TerminalDevice - ) -{ - if (TerminalDevice->EfiKeyFiFo->Head == TerminalDevice->EfiKeyFiFo->Tail) { - return TRUE; - } else { - return FALSE; - } -} - -/** - Clarify whether FIFO buffer is full. - - @param TerminalDevice Terminal driver private structure - - @retval TRUE If FIFO buffer is full. - @retval FLASE If FIFO buffer is not full. - -**/ -BOOLEAN -IsEfiKeyFiFoFull ( - TERMINAL_DEV *TerminalDevice - ) -{ - UINT8 Tail; - UINT8 Head; - - Tail = TerminalDevice->EfiKeyFiFo->Tail; - Head = TerminalDevice->EfiKeyFiFo->Head; - - if (((Tail + 1) % (FIFO_MAX_NUMBER + 1)) == Head) { - - return TRUE; - } - - return FALSE; -} - -/** - Insert one pre-fetched key into the Unicode FIFO buffer. - - @param TerminalDevice Terminal driver private structure. - @param Input The key will be input. - - @retval TRUE If insert successfully. - @retval FLASE If Unicode FIFO buffer is full before key insertion, - and the key is lost. - -**/ -BOOLEAN -UnicodeFiFoInsertOneKey ( - TERMINAL_DEV *TerminalDevice, - UINT16 Input - ) -{ - UINT8 Tail; - - Tail = TerminalDevice->UnicodeFiFo->Tail; - ASSERT (Tail < FIFO_MAX_NUMBER + 1); - - - if (IsUnicodeFiFoFull (TerminalDevice)) { - // - // Unicode FIFO is full - // - return FALSE; - } - - TerminalDevice->UnicodeFiFo->Data[Tail] = Input; - - TerminalDevice->UnicodeFiFo->Tail = (UINT8) ((Tail + 1) % (FIFO_MAX_NUMBER + 1)); - - return TRUE; -} - -/** - Remove one pre-fetched key out of the Unicode FIFO buffer. - - @param TerminalDevice Terminal driver private structure. - @param Output The key will be removed. - - @retval TRUE If insert successfully. - @retval FLASE If Unicode FIFO buffer is empty before remove operation. - -**/ -BOOLEAN -UnicodeFiFoRemoveOneKey ( - TERMINAL_DEV *TerminalDevice, - UINT16 *Output - ) -{ - UINT8 Head; - - Head = TerminalDevice->UnicodeFiFo->Head; - ASSERT (Head < FIFO_MAX_NUMBER + 1); - - if (IsUnicodeFiFoEmpty (TerminalDevice)) { - // - // FIFO is empty - // - Output = NULL; - return FALSE; - } - - *Output = TerminalDevice->UnicodeFiFo->Data[Head]; - - TerminalDevice->UnicodeFiFo->Head = (UINT8) ((Head + 1) % (FIFO_MAX_NUMBER + 1)); - - return TRUE; -} - -/** - Clarify whether Unicode FIFO buffer is empty. - - @param TerminalDevice Terminal driver private structure - - @retval TRUE If Unicode FIFO buffer is empty. - @retval FLASE If Unicode FIFO buffer is not empty. - -**/ -BOOLEAN -IsUnicodeFiFoEmpty ( - TERMINAL_DEV *TerminalDevice - ) -{ - if (TerminalDevice->UnicodeFiFo->Head == TerminalDevice->UnicodeFiFo->Tail) { - return TRUE; - } else { - return FALSE; - } -} - -/** - Clarify whether Unicode FIFO buffer is full. - - @param TerminalDevice Terminal driver private structure - - @retval TRUE If Unicode FIFO buffer is full. - @retval FLASE If Unicode FIFO buffer is not full. - -**/ -BOOLEAN -IsUnicodeFiFoFull ( - TERMINAL_DEV *TerminalDevice - ) -{ - UINT8 Tail; - UINT8 Head; - - Tail = TerminalDevice->UnicodeFiFo->Tail; - Head = TerminalDevice->UnicodeFiFo->Head; - - if (((Tail + 1) % (FIFO_MAX_NUMBER + 1)) == Head) { - - return TRUE; - } - - return FALSE; -} - -/** - Count Unicode FIFO buffer. - - @param TerminalDevice Terminal driver private structure - - @return The count in bytes of Unicode FIFO. - -**/ -UINT8 -UnicodeFiFoGetKeyCount ( - TERMINAL_DEV *TerminalDevice - ) -{ - UINT8 Tail; - UINT8 Head; - - Tail = TerminalDevice->UnicodeFiFo->Tail; - Head = TerminalDevice->UnicodeFiFo->Head; - - if (Tail >= Head) { - return (UINT8) (Tail - Head); - } else { - return (UINT8) (Tail + FIFO_MAX_NUMBER + 1 - Head); - } -} - -/** - Update the Unicode characters from a terminal input device into EFI Keys FIFO. - - @param TerminalDevice The terminal device to use to translate raw input into EFI Keys - -**/ -VOID -UnicodeToEfiKeyFlushState ( - IN TERMINAL_DEV *TerminalDevice - ) -{ - EFI_INPUT_KEY Key; - UINT32 InputState; - - InputState = TerminalDevice->InputState; - - if( IsEfiKeyFiFoFull(TerminalDevice) ) return; - - if ((InputState & INPUT_STATE_ESC) != 0) { - Key.ScanCode = SCAN_ESC; - Key.UnicodeChar = 0; - EfiKeyFiFoInsertOneKey (TerminalDevice, &Key); - } - - if ((InputState & INPUT_STATE_CSI) != 0) { - Key.ScanCode = SCAN_NULL; - Key.UnicodeChar = CSI; - EfiKeyFiFoInsertOneKey (TerminalDevice, &Key); - } - - if ((InputState & INPUT_STATE_LEFTOPENBRACKET) != 0) { - Key.ScanCode = SCAN_NULL; - Key.UnicodeChar = LEFTOPENBRACKET; - EfiKeyFiFoInsertOneKey (TerminalDevice, &Key); - } - - if ((InputState & INPUT_STATE_O) != 0) { - Key.ScanCode = SCAN_NULL; - Key.UnicodeChar = 'O'; - EfiKeyFiFoInsertOneKey (TerminalDevice, &Key); - } - - if ((InputState & INPUT_STATE_2) != 0) { - Key.ScanCode = SCAN_NULL; - Key.UnicodeChar = '2'; - EfiKeyFiFoInsertOneKey (TerminalDevice, &Key); - } - - // - // Cancel the timer. - // - gBS->SetTimer ( - TerminalDevice->TwoSecondTimeOut, - TimerCancel, - 0 - ); - - TerminalDevice->InputState = INPUT_STATE_DEFAULT; -} - - -/** - Converts a stream of Unicode characters from a terminal input device into EFI Keys that - can be read through the Simple Input Protocol. - - The table below shows the keyboard input mappings that this function supports. - If the ESC sequence listed in one of the columns is presented, then it is translated - into the corresponding EFI Scan Code. If a matching sequence is not found, then the raw - key strokes are converted into EFI Keys. - - 2 seconds are allowed for an ESC sequence to be completed. If the ESC sequence is not - completed in 2 seconds, then the raw key strokes of the partial ESC sequence are - converted into EFI Keys. - There is one special input sequence that will force the system to reset. - This is ESC R ESC r ESC R. - - Note: current implementation support terminal types include: PC ANSI, VT100+/VTUTF8, VT100. - The table below is not same with UEFI Spec 2.3 Appendix B Table 201(not support ANSI X3.64 / - DEC VT200-500 and extra support PC ANSI, VT100)since UEFI Table 201 is just an example. - - Symbols used in table below - =========================== - ESC = 0x1B - CSI = 0x9B - DEL = 0x7f - ^ = CTRL - - +=========+======+===========+==========+==========+ - | | EFI | UEFI 2.0 | | | - | | Scan | | VT100+ | | - | KEY | Code | PC ANSI | VTUTF8 | VT100 | - +=========+======+===========+==========+==========+ - | NULL | 0x00 | | | | - | UP | 0x01 | ESC [ A | ESC [ A | ESC [ A | - | DOWN | 0x02 | ESC [ B | ESC [ B | ESC [ B | - | RIGHT | 0x03 | ESC [ C | ESC [ C | ESC [ C | - | LEFT | 0x04 | ESC [ D | ESC [ D | ESC [ D | - | HOME | 0x05 | ESC [ H | ESC h | ESC [ H | - | END | 0x06 | ESC [ F | ESC k | ESC [ K | - | INSERT | 0x07 | ESC [ @ | ESC + | ESC [ @ | - | | | ESC [ L | | ESC [ L | - | DELETE | 0x08 | ESC [ X | ESC - | ESC [ P | - | PG UP | 0x09 | ESC [ I | ESC ? | ESC [ V | - | | | | | ESC [ ? | - | PG DOWN | 0x0A | ESC [ G | ESC / | ESC [ U | - | | | | | ESC [ / | - | F1 | 0x0B | ESC [ M | ESC 1 | ESC O P | - | F2 | 0x0C | ESC [ N | ESC 2 | ESC O Q | - | F3 | 0x0D | ESC [ O | ESC 3 | ESC O w | - | F4 | 0x0E | ESC [ P | ESC 4 | ESC O x | - | F5 | 0x0F | ESC [ Q | ESC 5 | ESC O t | - | F6 | 0x10 | ESC [ R | ESC 6 | ESC O u | - | F7 | 0x11 | ESC [ S | ESC 7 | ESC O q | - | F8 | 0x12 | ESC [ T | ESC 8 | ESC O r | - | F9 | 0x13 | ESC [ U | ESC 9 | ESC O p | - | F10 | 0x14 | ESC [ V | ESC 0 | ESC O M | - | Escape | 0x17 | ESC | ESC | ESC | - | F11 | 0x15 | | ESC ! | | - | F12 | 0x16 | | ESC @ | | - +=========+======+===========+==========+==========+ - - Special Mappings - ================ - ESC R ESC r ESC R = Reset System - - @param TerminalDevice The terminal device to use to translate raw input into EFI Keys - -**/ -VOID -UnicodeToEfiKey ( - IN TERMINAL_DEV *TerminalDevice - ) -{ - EFI_STATUS Status; - EFI_STATUS TimerStatus; - UINT16 UnicodeChar; - EFI_INPUT_KEY Key; - BOOLEAN SetDefaultResetState; - - TimerStatus = gBS->CheckEvent (TerminalDevice->TwoSecondTimeOut); - - if (!EFI_ERROR (TimerStatus)) { - UnicodeToEfiKeyFlushState (TerminalDevice); - TerminalDevice->ResetState = RESET_STATE_DEFAULT; - } - - while (!IsUnicodeFiFoEmpty(TerminalDevice) && !IsEfiKeyFiFoFull(TerminalDevice) ) { - - if (TerminalDevice->InputState != INPUT_STATE_DEFAULT) { - // - // Check to see if the 2 seconds timer has expired - // - TimerStatus = gBS->CheckEvent (TerminalDevice->TwoSecondTimeOut); - if (!EFI_ERROR (TimerStatus)) { - UnicodeToEfiKeyFlushState (TerminalDevice); - TerminalDevice->ResetState = RESET_STATE_DEFAULT; - } - } - - // - // Fetch one Unicode character from the Unicode FIFO - // - UnicodeFiFoRemoveOneKey (TerminalDevice, &UnicodeChar); - - SetDefaultResetState = TRUE; - - switch (TerminalDevice->InputState) { - case INPUT_STATE_DEFAULT: - - break; - - case INPUT_STATE_ESC: - - if (UnicodeChar == LEFTOPENBRACKET) { - TerminalDevice->InputState |= INPUT_STATE_LEFTOPENBRACKET; - TerminalDevice->ResetState = RESET_STATE_DEFAULT; - continue; - } - - if (UnicodeChar == 'O' && TerminalDevice->TerminalType == VT100TYPE) { - TerminalDevice->InputState |= INPUT_STATE_O; - TerminalDevice->ResetState = RESET_STATE_DEFAULT; - continue; - } - - Key.ScanCode = SCAN_NULL; - - if (TerminalDevice->TerminalType == VT100PLUSTYPE || - TerminalDevice->TerminalType == VTUTF8TYPE) { - switch (UnicodeChar) { - case '1': - Key.ScanCode = SCAN_F1; - break; - case '2': - Key.ScanCode = SCAN_F2; - break; - case '3': - Key.ScanCode = SCAN_F3; - break; - case '4': - Key.ScanCode = SCAN_F4; - break; - case '5': - Key.ScanCode = SCAN_F5; - break; - case '6': - Key.ScanCode = SCAN_F6; - break; - case '7': - Key.ScanCode = SCAN_F7; - break; - case '8': - Key.ScanCode = SCAN_F8; - break; - case '9': - Key.ScanCode = SCAN_F9; - break; - case '0': - Key.ScanCode = SCAN_F10; - break; - case '!': - Key.ScanCode = SCAN_F11; - break; - case '@': - Key.ScanCode = SCAN_F12; - break; - case 'h': - Key.ScanCode = SCAN_HOME; - break; - case 'k': - Key.ScanCode = SCAN_END; - break; - case '+': - Key.ScanCode = SCAN_INSERT; - break; - case '-': - Key.ScanCode = SCAN_DELETE; - break; - case '/': - Key.ScanCode = SCAN_PAGE_DOWN; - break; - case '?': - Key.ScanCode = SCAN_PAGE_UP; - break; - default : - break; - } - } - - switch (UnicodeChar) { - case 'R': - if (TerminalDevice->ResetState == RESET_STATE_DEFAULT) { - TerminalDevice->ResetState = RESET_STATE_ESC_R; - SetDefaultResetState = FALSE; - } else if (TerminalDevice->ResetState == RESET_STATE_ESC_R_ESC_R) { - gRT->ResetSystem (EfiResetWarm, EFI_SUCCESS, 0, NULL); - } - Key.ScanCode = SCAN_NULL; - break; - case 'r': - if (TerminalDevice->ResetState == RESET_STATE_ESC_R) { - TerminalDevice->ResetState = RESET_STATE_ESC_R_ESC_R; - SetDefaultResetState = FALSE; - } - Key.ScanCode = SCAN_NULL; - break; - default : - break; - } - - if (SetDefaultResetState) { - TerminalDevice->ResetState = RESET_STATE_DEFAULT; - } - - if (Key.ScanCode != SCAN_NULL) { - Key.UnicodeChar = 0; - EfiKeyFiFoInsertOneKey (TerminalDevice, &Key); - TerminalDevice->InputState = INPUT_STATE_DEFAULT; - UnicodeToEfiKeyFlushState (TerminalDevice); - continue; - } - - UnicodeToEfiKeyFlushState (TerminalDevice); - - break; - - case INPUT_STATE_ESC | INPUT_STATE_O: - - TerminalDevice->ResetState = RESET_STATE_DEFAULT; - - Key.ScanCode = SCAN_NULL; - - if (TerminalDevice->TerminalType == VT100TYPE) { - switch (UnicodeChar) { - case 'P': - Key.ScanCode = SCAN_F1; - break; - case 'Q': - Key.ScanCode = SCAN_F2; - break; - case 'w': - Key.ScanCode = SCAN_F3; - break; - case 'x': - Key.ScanCode = SCAN_F4; - break; - case 't': - Key.ScanCode = SCAN_F5; - break; - case 'u': - Key.ScanCode = SCAN_F6; - break; - case 'q': - Key.ScanCode = SCAN_F7; - break; - case 'r': - Key.ScanCode = SCAN_F8; - break; - case 'p': - Key.ScanCode = SCAN_F9; - break; - case 'M': - Key.ScanCode = SCAN_F10; - break; - default : - break; - } - } - - if (Key.ScanCode != SCAN_NULL) { - Key.UnicodeChar = 0; - EfiKeyFiFoInsertOneKey (TerminalDevice, &Key); - TerminalDevice->InputState = INPUT_STATE_DEFAULT; - UnicodeToEfiKeyFlushState (TerminalDevice); - continue; - } - - UnicodeToEfiKeyFlushState (TerminalDevice); - - break; - - case INPUT_STATE_ESC | INPUT_STATE_LEFTOPENBRACKET: - - TerminalDevice->ResetState = RESET_STATE_DEFAULT; - - Key.ScanCode = SCAN_NULL; - - if (TerminalDevice->TerminalType == PCANSITYPE || - TerminalDevice->TerminalType == VT100TYPE || - TerminalDevice->TerminalType == VT100PLUSTYPE || - TerminalDevice->TerminalType == VTUTF8TYPE) { - switch (UnicodeChar) { - case 'A': - Key.ScanCode = SCAN_UP; - break; - case 'B': - Key.ScanCode = SCAN_DOWN; - break; - case 'C': - Key.ScanCode = SCAN_RIGHT; - break; - case 'D': - Key.ScanCode = SCAN_LEFT; - break; - case 'H': - if (TerminalDevice->TerminalType == PCANSITYPE || - TerminalDevice->TerminalType == VT100TYPE) { - Key.ScanCode = SCAN_HOME; - } - break; - case 'F': - if (TerminalDevice->TerminalType == PCANSITYPE) { - Key.ScanCode = SCAN_END; - } - break; - case 'K': - if (TerminalDevice->TerminalType == VT100TYPE) { - Key.ScanCode = SCAN_END; - } - break; - case 'L': - case '@': - if (TerminalDevice->TerminalType == PCANSITYPE || - TerminalDevice->TerminalType == VT100TYPE) { - Key.ScanCode = SCAN_INSERT; - } - break; - case 'X': - if (TerminalDevice->TerminalType == PCANSITYPE) { - Key.ScanCode = SCAN_DELETE; - } - break; - case 'P': - if (TerminalDevice->TerminalType == VT100TYPE) { - Key.ScanCode = SCAN_DELETE; - } else if (TerminalDevice->TerminalType == PCANSITYPE) { - Key.ScanCode = SCAN_F4; - } - break; - case 'I': - if (TerminalDevice->TerminalType == PCANSITYPE) { - Key.ScanCode = SCAN_PAGE_UP; - } - break; - case 'V': - if (TerminalDevice->TerminalType == PCANSITYPE) { - Key.ScanCode = SCAN_F10; - } - case '?': - if (TerminalDevice->TerminalType == VT100TYPE) { - Key.ScanCode = SCAN_PAGE_UP; - } - break; - case 'G': - if (TerminalDevice->TerminalType == PCANSITYPE) { - Key.ScanCode = SCAN_PAGE_DOWN; - } - break; - case 'U': - if (TerminalDevice->TerminalType == PCANSITYPE) { - Key.ScanCode = SCAN_F9; - } - case '/': - if (TerminalDevice->TerminalType == VT100TYPE) { - Key.ScanCode = SCAN_PAGE_DOWN; - } - break; - case 'M': - if (TerminalDevice->TerminalType == PCANSITYPE) { - Key.ScanCode = SCAN_F1; - } - break; - case 'N': - if (TerminalDevice->TerminalType == PCANSITYPE) { - Key.ScanCode = SCAN_F2; - } - break; - case 'O': - if (TerminalDevice->TerminalType == PCANSITYPE) { - Key.ScanCode = SCAN_F3; - } - break; - case 'Q': - if (TerminalDevice->TerminalType == PCANSITYPE) { - Key.ScanCode = SCAN_F5; - } - break; - case 'R': - if (TerminalDevice->TerminalType == PCANSITYPE) { - Key.ScanCode = SCAN_F6; - } - break; - case 'S': - if (TerminalDevice->TerminalType == PCANSITYPE) { - Key.ScanCode = SCAN_F7; - } - break; - case 'T': - if (TerminalDevice->TerminalType == PCANSITYPE) { - Key.ScanCode = SCAN_F8; - } - break; - default : - break; - } - } - - if (Key.ScanCode != SCAN_NULL) { - Key.UnicodeChar = 0; - EfiKeyFiFoInsertOneKey (TerminalDevice, &Key); - TerminalDevice->InputState = INPUT_STATE_DEFAULT; - UnicodeToEfiKeyFlushState (TerminalDevice); - continue; - } - - UnicodeToEfiKeyFlushState (TerminalDevice); - - break; - - - default: - // - // Invalid state. This should never happen. - // - ASSERT (FALSE); - - UnicodeToEfiKeyFlushState (TerminalDevice); - - break; - } - - if (UnicodeChar == ESC) { - TerminalDevice->InputState = INPUT_STATE_ESC; - } - - if (UnicodeChar == CSI) { - TerminalDevice->InputState = INPUT_STATE_CSI; - } - - if (TerminalDevice->InputState != INPUT_STATE_DEFAULT) { - Status = gBS->SetTimer( - TerminalDevice->TwoSecondTimeOut, - TimerRelative, - (UINT64)20000000 - ); - ASSERT_EFI_ERROR (Status); - continue; - } - - if (SetDefaultResetState) { - TerminalDevice->ResetState = RESET_STATE_DEFAULT; - } - - if (UnicodeChar == DEL) { - Key.ScanCode = SCAN_DELETE; - Key.UnicodeChar = 0; - } else { - Key.ScanCode = SCAN_NULL; - Key.UnicodeChar = UnicodeChar; - } - - EfiKeyFiFoInsertOneKey (TerminalDevice, &Key); - } -} +/** @file
+ Implementation for EFI_SIMPLE_TEXT_INPUT_PROTOCOL protocol.
+
+Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "Terminal.h"
+
+
+/**
+ Reads the next keystroke from the input device. The WaitForKey Event can
+ be used to test for existence of a keystroke via WaitForEvent () call.
+
+ @param TerminalDevice Terminal driver private structure
+ @param KeyData A pointer to a buffer that is filled in with the
+ keystroke state data for the key that was
+ pressed.
+
+ @retval EFI_SUCCESS The keystroke information was returned.
+ @retval EFI_NOT_READY There was no keystroke data available.
+ @retval EFI_INVALID_PARAMETER KeyData is NULL.
+
+**/
+EFI_STATUS
+ReadKeyStrokeWorker (
+ IN TERMINAL_DEV *TerminalDevice,
+ OUT EFI_KEY_DATA *KeyData
+ )
+{
+ if (KeyData == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (!EfiKeyFiFoRemoveOneKey (TerminalDevice, &KeyData->Key)) {
+ return EFI_NOT_READY;
+ }
+
+ KeyData->KeyState.KeyShiftState = 0;
+ KeyData->KeyState.KeyToggleState = 0;
+
+
+ return EFI_SUCCESS;
+
+}
+
+/**
+ Implements EFI_SIMPLE_TEXT_INPUT_PROTOCOL.Reset().
+ This driver only perform dependent serial device reset regardless of
+ the value of ExtendeVerification
+
+ @param This Indicates the calling context.
+ @param ExtendedVerification Skip by this driver.
+
+ @retval EFI_SUCCESS The reset operation succeeds.
+ @retval EFI_DEVICE_ERROR The dependent serial port reset fails.
+
+**/
+EFI_STATUS
+EFIAPI
+TerminalConInReset (
+ IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
+ IN BOOLEAN ExtendedVerification
+ )
+{
+ EFI_STATUS Status;
+ TERMINAL_DEV *TerminalDevice;
+
+ TerminalDevice = TERMINAL_CON_IN_DEV_FROM_THIS (This);
+
+ //
+ // Report progress code here
+ //
+ REPORT_STATUS_CODE_WITH_DEVICE_PATH (
+ EFI_PROGRESS_CODE,
+ (EFI_PERIPHERAL_REMOTE_CONSOLE | EFI_P_PC_RESET),
+ TerminalDevice->DevicePath
+ );
+
+ Status = TerminalDevice->SerialIo->Reset (TerminalDevice->SerialIo);
+
+ //
+ // Make all the internal buffer empty for keys
+ //
+ TerminalDevice->RawFiFo->Head = TerminalDevice->RawFiFo->Tail;
+ TerminalDevice->UnicodeFiFo->Head = TerminalDevice->UnicodeFiFo->Tail;
+ TerminalDevice->EfiKeyFiFo->Head = TerminalDevice->EfiKeyFiFo->Tail;
+
+ if (EFI_ERROR (Status)) {
+ REPORT_STATUS_CODE_WITH_DEVICE_PATH (
+ EFI_ERROR_CODE | EFI_ERROR_MINOR,
+ (EFI_PERIPHERAL_REMOTE_CONSOLE | EFI_P_EC_CONTROLLER_ERROR),
+ TerminalDevice->DevicePath
+ );
+ }
+
+ return Status;
+}
+
+/**
+ Implements EFI_SIMPLE_TEXT_INPUT_PROTOCOL.ReadKeyStroke().
+
+ @param This Indicates the calling context.
+ @param Key A pointer to a buffer that is filled in with the
+ keystroke information for the key that was sent
+ from terminal.
+
+ @retval EFI_SUCCESS The keystroke information is returned successfully.
+ @retval EFI_NOT_READY There is no keystroke data available.
+ @retval EFI_DEVICE_ERROR The dependent serial device encounters error.
+
+**/
+EFI_STATUS
+EFIAPI
+TerminalConInReadKeyStroke (
+ IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
+ OUT EFI_INPUT_KEY *Key
+ )
+{
+ TERMINAL_DEV *TerminalDevice;
+ EFI_STATUS Status;
+ EFI_KEY_DATA KeyData;
+
+ //
+ // get TERMINAL_DEV from "This" parameter.
+ //
+ TerminalDevice = TERMINAL_CON_IN_DEV_FROM_THIS (This);
+
+ Status = ReadKeyStrokeWorker (TerminalDevice, &KeyData);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ CopyMem (Key, &KeyData.Key, sizeof (EFI_INPUT_KEY));
+
+ return EFI_SUCCESS;
+
+}
+
+/**
+ Check if the key already has been registered.
+
+ If both RegsiteredData and InputData is NULL, then ASSERT().
+
+ @param RegsiteredData A pointer to a buffer that is filled in with the
+ keystroke state data for the key that was
+ registered.
+ @param InputData A pointer to a buffer that is filled in with the
+ keystroke state data for the key that was
+ pressed.
+
+ @retval TRUE Key be pressed matches a registered key.
+ @retval FLASE Match failed.
+
+**/
+BOOLEAN
+IsKeyRegistered (
+ IN EFI_KEY_DATA *RegsiteredData,
+ IN EFI_KEY_DATA *InputData
+ )
+{
+ ASSERT (RegsiteredData != NULL && InputData != NULL);
+
+ if ((RegsiteredData->Key.ScanCode != InputData->Key.ScanCode) ||
+ (RegsiteredData->Key.UnicodeChar != InputData->Key.UnicodeChar)) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+
+/**
+ Event notification function for EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL.WaitForKeyEx event
+ Signal the event if there is key available
+
+ @param Event Indicates the event that invoke this function.
+ @param Context Indicates the calling context.
+
+**/
+VOID
+EFIAPI
+TerminalConInWaitForKeyEx (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ TerminalConInWaitForKey (Event, Context);
+}
+
+//
+// Simple Text Input Ex protocol functions
+//
+
+/**
+ Reset the input device and optionally run diagnostics
+
+ @param This Protocol instance pointer.
+ @param ExtendedVerification Driver may perform diagnostics on reset.
+
+ @retval EFI_SUCCESS The device was reset.
+ @retval EFI_DEVICE_ERROR The device is not functioning properly and could
+ not be reset.
+
+**/
+EFI_STATUS
+EFIAPI
+TerminalConInResetEx (
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ IN BOOLEAN ExtendedVerification
+ )
+{
+ EFI_STATUS Status;
+ TERMINAL_DEV *TerminalDevice;
+
+ TerminalDevice = TERMINAL_CON_IN_EX_DEV_FROM_THIS (This);
+
+ Status = TerminalDevice->SimpleInput.Reset (&TerminalDevice->SimpleInput, ExtendedVerification);
+ if (EFI_ERROR (Status)) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ return EFI_SUCCESS;
+
+}
+
+
+/**
+ Reads the next keystroke from the input device. The WaitForKey Event can
+ be used to test for existence of a keystroke via WaitForEvent () call.
+
+ @param This Protocol instance pointer.
+ @param KeyData A pointer to a buffer that is filled in with the
+ keystroke state data for the key that was
+ pressed.
+
+ @retval EFI_SUCCESS The keystroke information was returned.
+ @retval EFI_NOT_READY There was no keystroke data available.
+ @retval EFI_DEVICE_ERROR The keystroke information was not returned due
+ to hardware errors.
+ @retval EFI_INVALID_PARAMETER KeyData is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+TerminalConInReadKeyStrokeEx (
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ OUT EFI_KEY_DATA *KeyData
+ )
+{
+ TERMINAL_DEV *TerminalDevice;
+
+ if (KeyData == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ TerminalDevice = TERMINAL_CON_IN_EX_DEV_FROM_THIS (This);
+
+ return ReadKeyStrokeWorker (TerminalDevice, KeyData);
+
+}
+
+
+/**
+ Set certain state for the input device.
+
+ @param This Protocol instance pointer.
+ @param KeyToggleState A pointer to the EFI_KEY_TOGGLE_STATE to set the
+ state for the input device.
+
+ @retval EFI_SUCCESS The device state was set successfully.
+ @retval EFI_DEVICE_ERROR The device is not functioning correctly and
+ could not have the setting adjusted.
+ @retval EFI_UNSUPPORTED The device does not have the ability to set its
+ state.
+ @retval EFI_INVALID_PARAMETER KeyToggleState is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+TerminalConInSetState (
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ IN EFI_KEY_TOGGLE_STATE *KeyToggleState
+ )
+{
+ if (KeyToggleState == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Register a notification function for a particular keystroke for the input device.
+
+ @param This Protocol instance pointer.
+ @param KeyData A pointer to a buffer that is filled in with the
+ keystroke information data for the key that was
+ pressed.
+ @param KeyNotificationFunction Points to the function to be called when the key
+ sequence is typed specified by KeyData.
+ @param NotifyHandle Points to the unique handle assigned to the
+ registered notification.
+
+ @retval EFI_SUCCESS The notification function was registered
+ successfully.
+ @retval EFI_OUT_OF_RESOURCES Unable to allocate resources for necessary data
+ structures.
+ @retval EFI_INVALID_PARAMETER KeyData or NotifyHandle is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+TerminalConInRegisterKeyNotify (
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ IN EFI_KEY_DATA *KeyData,
+ IN EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction,
+ OUT EFI_HANDLE *NotifyHandle
+ )
+{
+ TERMINAL_DEV *TerminalDevice;
+ TERMINAL_CONSOLE_IN_EX_NOTIFY *NewNotify;
+ LIST_ENTRY *Link;
+ LIST_ENTRY *NotifyList;
+ TERMINAL_CONSOLE_IN_EX_NOTIFY *CurrentNotify;
+
+ if (KeyData == NULL || NotifyHandle == NULL || KeyNotificationFunction == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ TerminalDevice = TERMINAL_CON_IN_EX_DEV_FROM_THIS (This);
+
+ //
+ // Return EFI_SUCCESS if the (KeyData, NotificationFunction) is already registered.
+ //
+ NotifyList = &TerminalDevice->NotifyList;
+ for (Link = GetFirstNode (NotifyList); !IsNull (NotifyList,Link); Link = GetNextNode (NotifyList,Link)) {
+ CurrentNotify = CR (
+ Link,
+ TERMINAL_CONSOLE_IN_EX_NOTIFY,
+ NotifyEntry,
+ TERMINAL_CONSOLE_IN_EX_NOTIFY_SIGNATURE
+ );
+ if (IsKeyRegistered (&CurrentNotify->KeyData, KeyData)) {
+ if (CurrentNotify->KeyNotificationFn == KeyNotificationFunction) {
+ *NotifyHandle = CurrentNotify->NotifyHandle;
+ return EFI_SUCCESS;
+ }
+ }
+ }
+
+ //
+ // Allocate resource to save the notification function
+ //
+ NewNotify = (TERMINAL_CONSOLE_IN_EX_NOTIFY *) AllocateZeroPool (sizeof (TERMINAL_CONSOLE_IN_EX_NOTIFY));
+ if (NewNotify == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ NewNotify->Signature = TERMINAL_CONSOLE_IN_EX_NOTIFY_SIGNATURE;
+ NewNotify->KeyNotificationFn = KeyNotificationFunction;
+ NewNotify->NotifyHandle = (EFI_HANDLE) NewNotify;
+ CopyMem (&NewNotify->KeyData, KeyData, sizeof (KeyData));
+ InsertTailList (&TerminalDevice->NotifyList, &NewNotify->NotifyEntry);
+
+ *NotifyHandle = NewNotify->NotifyHandle;
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Remove a registered notification function from a particular keystroke.
+
+ @param This Protocol instance pointer.
+ @param NotificationHandle The handle of the notification function being
+ unregistered.
+
+ @retval EFI_SUCCESS The notification function was unregistered
+ successfully.
+ @retval EFI_INVALID_PARAMETER The NotificationHandle is invalid.
+
+**/
+EFI_STATUS
+EFIAPI
+TerminalConInUnregisterKeyNotify (
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ IN EFI_HANDLE NotificationHandle
+ )
+{
+ TERMINAL_DEV *TerminalDevice;
+ LIST_ENTRY *Link;
+ TERMINAL_CONSOLE_IN_EX_NOTIFY *CurrentNotify;
+ LIST_ENTRY *NotifyList;
+
+ if (NotificationHandle == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (((TERMINAL_CONSOLE_IN_EX_NOTIFY *) NotificationHandle)->Signature != TERMINAL_CONSOLE_IN_EX_NOTIFY_SIGNATURE) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ TerminalDevice = TERMINAL_CON_IN_EX_DEV_FROM_THIS (This);
+
+ NotifyList = &TerminalDevice->NotifyList;
+ for (Link = GetFirstNode (NotifyList); !IsNull (NotifyList,Link); Link = GetNextNode (NotifyList,Link)) {
+ CurrentNotify = CR (
+ Link,
+ TERMINAL_CONSOLE_IN_EX_NOTIFY,
+ NotifyEntry,
+ TERMINAL_CONSOLE_IN_EX_NOTIFY_SIGNATURE
+ );
+ if (CurrentNotify->NotifyHandle == NotificationHandle) {
+ //
+ // Remove the notification function from NotifyList and free resources
+ //
+ RemoveEntryList (&CurrentNotify->NotifyEntry);
+
+ gBS->FreePool (CurrentNotify);
+ return EFI_SUCCESS;
+ }
+ }
+
+ //
+ // Can not find the matching entry in database.
+ //
+ return EFI_INVALID_PARAMETER;
+}
+
+/**
+ Translate raw data into Unicode (according to different encode), and
+ translate Unicode into key information. (according to different standard).
+
+ @param TerminalDevice Terminal driver private structure.
+
+**/
+VOID
+TranslateRawDataToEfiKey (
+ IN TERMINAL_DEV *TerminalDevice
+ )
+{
+ switch (TerminalDevice->TerminalType) {
+
+ case PCANSITYPE:
+ case VT100TYPE:
+ case VT100PLUSTYPE:
+ AnsiRawDataToUnicode (TerminalDevice);
+ UnicodeToEfiKey (TerminalDevice);
+ break;
+
+ case VTUTF8TYPE:
+ //
+ // Process all the raw data in the RawFIFO,
+ // put the processed key into UnicodeFIFO.
+ //
+ VTUTF8RawDataToUnicode (TerminalDevice);
+
+ //
+ // Translate all the Unicode data in the UnicodeFIFO to Efi key,
+ // then put into EfiKeyFIFO.
+ //
+ UnicodeToEfiKey (TerminalDevice);
+
+ break;
+ }
+}
+
+/**
+ Event notification function for EFI_SIMPLE_TEXT_INPUT_PROTOCOL.WaitForKey event
+ Signal the event if there is key available
+
+ @param Event Indicates the event that invoke this function.
+ @param Context Indicates the calling context.
+
+**/
+VOID
+EFIAPI
+TerminalConInWaitForKey (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ //
+ // Someone is waiting on the keystroke event, if there's
+ // a key pending, signal the event
+ //
+ if (!IsEfiKeyFiFoEmpty ((TERMINAL_DEV *) Context)) {
+
+ gBS->SignalEvent (Event);
+ }
+}
+
+/**
+ Timer handler to poll the key from serial.
+
+ @param Event Indicates the event that invoke this function.
+ @param Context Indicates the calling context.
+**/
+VOID
+EFIAPI
+TerminalConInTimerHandler (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ EFI_STATUS Status;
+ TERMINAL_DEV *TerminalDevice;
+ UINT8 Input;
+ EFI_SERIAL_IO_MODE *Mode;
+ EFI_SERIAL_IO_PROTOCOL *SerialIo;
+ UINTN SerialInTimeOut;
+
+ TerminalDevice = (TERMINAL_DEV *) Context;
+
+ SerialIo = TerminalDevice->SerialIo;
+ if (SerialIo == NULL) {
+ return ;
+ }
+ //
+ // if current timeout value for serial device is not identical with
+ // the value saved in TERMINAL_DEV structure, then recalculate the
+ // timeout value again and set serial attribute according to this value.
+ //
+ Mode = SerialIo->Mode;
+ if (Mode->Timeout != TerminalDevice->SerialInTimeOut) {
+
+ SerialInTimeOut = 0;
+ if (Mode->BaudRate != 0) {
+ //
+ // According to BAUD rate to calculate the timeout value.
+ //
+ SerialInTimeOut = (1 + Mode->DataBits + Mode->StopBits) * 2 * 1000000 / (UINTN) Mode->BaudRate;
+ }
+
+ Status = SerialIo->SetAttributes (
+ SerialIo,
+ Mode->BaudRate,
+ Mode->ReceiveFifoDepth,
+ (UINT32) SerialInTimeOut,
+ (EFI_PARITY_TYPE) (Mode->Parity),
+ (UINT8) Mode->DataBits,
+ (EFI_STOP_BITS_TYPE) (Mode->StopBits)
+ );
+
+ if (EFI_ERROR (Status)) {
+ TerminalDevice->SerialInTimeOut = 0;
+ } else {
+ TerminalDevice->SerialInTimeOut = SerialInTimeOut;
+ }
+ }
+
+ //
+ // Fetch all the keys in the serial buffer,
+ // and insert the byte stream into RawFIFO.
+ //
+ while (!IsRawFiFoFull (TerminalDevice)) {
+
+ Status = GetOneKeyFromSerial (TerminalDevice->SerialIo, &Input);
+
+ if (EFI_ERROR (Status)) {
+ if (Status == EFI_DEVICE_ERROR) {
+ REPORT_STATUS_CODE_WITH_DEVICE_PATH (
+ EFI_ERROR_CODE | EFI_ERROR_MINOR,
+ (EFI_PERIPHERAL_REMOTE_CONSOLE | EFI_P_EC_INPUT_ERROR),
+ TerminalDevice->DevicePath
+ );
+ }
+ break;
+ }
+
+ RawFiFoInsertOneKey (TerminalDevice, Input);
+ }
+
+ //
+ // Translate all the raw data in RawFIFO into EFI Key,
+ // according to different terminal type supported.
+ //
+ TranslateRawDataToEfiKey (TerminalDevice);
+}
+
+/**
+ Get one key out of serial buffer.
+
+ @param SerialIo Serial I/O protocol attached to the serial device.
+ @param Output The fetched key.
+
+ @retval EFI_NOT_READY If serial buffer is empty.
+ @retval EFI_DEVICE_ERROR If reading serial buffer encounter error.
+ @retval EFI_SUCCESS If reading serial buffer successfully, put
+ the fetched key to the parameter output.
+
+**/
+EFI_STATUS
+GetOneKeyFromSerial (
+ EFI_SERIAL_IO_PROTOCOL *SerialIo,
+ UINT8 *Output
+ )
+{
+ EFI_STATUS Status;
+ UINTN Size;
+
+ Size = 1;
+ *Output = 0;
+
+ //
+ // Read one key from serial I/O device.
+ //
+ Status = SerialIo->Read (SerialIo, &Size, Output);
+
+ if (EFI_ERROR (Status)) {
+
+ if (Status == EFI_TIMEOUT) {
+ return EFI_NOT_READY;
+ }
+
+ return EFI_DEVICE_ERROR;
+
+ }
+
+ if (*Output == 0) {
+ return EFI_NOT_READY;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Insert one byte raw data into the Raw Data FIFO.
+
+ @param TerminalDevice Terminal driver private structure.
+ @param Input The key will be input.
+
+ @retval TRUE If insert successfully.
+ @retval FLASE If Raw Data buffer is full before key insertion,
+ and the key is lost.
+
+**/
+BOOLEAN
+RawFiFoInsertOneKey (
+ TERMINAL_DEV *TerminalDevice,
+ UINT8 Input
+ )
+{
+ UINT8 Tail;
+
+ Tail = TerminalDevice->RawFiFo->Tail;
+
+ if (IsRawFiFoFull (TerminalDevice)) {
+ //
+ // Raw FIFO is full
+ //
+ return FALSE;
+ }
+
+ TerminalDevice->RawFiFo->Data[Tail] = Input;
+
+ TerminalDevice->RawFiFo->Tail = (UINT8) ((Tail + 1) % (RAW_FIFO_MAX_NUMBER + 1));
+
+ return TRUE;
+}
+
+/**
+ Remove one pre-fetched key out of the Raw Data FIFO.
+
+ @param TerminalDevice Terminal driver private structure.
+ @param Output The key will be removed.
+
+ @retval TRUE If insert successfully.
+ @retval FLASE If Raw Data FIFO buffer is empty before remove operation.
+
+**/
+BOOLEAN
+RawFiFoRemoveOneKey (
+ TERMINAL_DEV *TerminalDevice,
+ UINT8 *Output
+ )
+{
+ UINT8 Head;
+
+ Head = TerminalDevice->RawFiFo->Head;
+
+ if (IsRawFiFoEmpty (TerminalDevice)) {
+ //
+ // FIFO is empty
+ //
+ *Output = 0;
+ return FALSE;
+ }
+
+ *Output = TerminalDevice->RawFiFo->Data[Head];
+
+ TerminalDevice->RawFiFo->Head = (UINT8) ((Head + 1) % (RAW_FIFO_MAX_NUMBER + 1));
+
+ return TRUE;
+}
+
+/**
+ Clarify whether Raw Data FIFO buffer is empty.
+
+ @param TerminalDevice Terminal driver private structure
+
+ @retval TRUE If Raw Data FIFO buffer is empty.
+ @retval FLASE If Raw Data FIFO buffer is not empty.
+
+**/
+BOOLEAN
+IsRawFiFoEmpty (
+ TERMINAL_DEV *TerminalDevice
+ )
+{
+ if (TerminalDevice->RawFiFo->Head == TerminalDevice->RawFiFo->Tail) {
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
+
+/**
+ Clarify whether Raw Data FIFO buffer is full.
+
+ @param TerminalDevice Terminal driver private structure
+
+ @retval TRUE If Raw Data FIFO buffer is full.
+ @retval FLASE If Raw Data FIFO buffer is not full.
+
+**/
+BOOLEAN
+IsRawFiFoFull (
+ TERMINAL_DEV *TerminalDevice
+ )
+{
+ UINT8 Tail;
+ UINT8 Head;
+
+ Tail = TerminalDevice->RawFiFo->Tail;
+ Head = TerminalDevice->RawFiFo->Head;
+
+ if (((Tail + 1) % (RAW_FIFO_MAX_NUMBER + 1)) == Head) {
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/**
+ Insert one pre-fetched key into the FIFO buffer.
+
+ @param TerminalDevice Terminal driver private structure.
+ @param Key The key will be input.
+
+ @retval TRUE If insert successfully.
+ @retval FLASE If FIFO buffer is full before key insertion,
+ and the key is lost.
+
+**/
+BOOLEAN
+EfiKeyFiFoInsertOneKey (
+ TERMINAL_DEV *TerminalDevice,
+ EFI_INPUT_KEY *Key
+ )
+{
+ UINT8 Tail;
+ LIST_ENTRY *Link;
+ LIST_ENTRY *NotifyList;
+ TERMINAL_CONSOLE_IN_EX_NOTIFY *CurrentNotify;
+ EFI_KEY_DATA KeyData;
+
+ Tail = TerminalDevice->EfiKeyFiFo->Tail;
+
+ CopyMem (&KeyData.Key, Key, sizeof (EFI_INPUT_KEY));
+ KeyData.KeyState.KeyShiftState = 0;
+ KeyData.KeyState.KeyToggleState = 0;
+
+ //
+ // Invoke notification functions if exist
+ //
+ NotifyList = &TerminalDevice->NotifyList;
+ for (Link = GetFirstNode (NotifyList); !IsNull (NotifyList,Link); Link = GetNextNode (NotifyList,Link)) {
+ CurrentNotify = CR (
+ Link,
+ TERMINAL_CONSOLE_IN_EX_NOTIFY,
+ NotifyEntry,
+ TERMINAL_CONSOLE_IN_EX_NOTIFY_SIGNATURE
+ );
+ if (IsKeyRegistered (&CurrentNotify->KeyData, &KeyData)) {
+ CurrentNotify->KeyNotificationFn (&KeyData);
+ }
+ }
+ if (IsEfiKeyFiFoFull (TerminalDevice)) {
+ //
+ // Efi Key FIFO is full
+ //
+ return FALSE;
+ }
+
+ CopyMem (&TerminalDevice->EfiKeyFiFo->Data[Tail], Key, sizeof (EFI_INPUT_KEY));
+
+ TerminalDevice->EfiKeyFiFo->Tail = (UINT8) ((Tail + 1) % (FIFO_MAX_NUMBER + 1));
+
+ return TRUE;
+}
+
+/**
+ Remove one pre-fetched key out of the FIFO buffer.
+
+ @param TerminalDevice Terminal driver private structure.
+ @param Output The key will be removed.
+
+ @retval TRUE If insert successfully.
+ @retval FLASE If FIFO buffer is empty before remove operation.
+
+**/
+BOOLEAN
+EfiKeyFiFoRemoveOneKey (
+ TERMINAL_DEV *TerminalDevice,
+ EFI_INPUT_KEY *Output
+ )
+{
+ UINT8 Head;
+
+ Head = TerminalDevice->EfiKeyFiFo->Head;
+ ASSERT (Head < FIFO_MAX_NUMBER + 1);
+
+ if (IsEfiKeyFiFoEmpty (TerminalDevice)) {
+ //
+ // FIFO is empty
+ //
+ Output->ScanCode = SCAN_NULL;
+ Output->UnicodeChar = 0;
+ return FALSE;
+ }
+
+ *Output = TerminalDevice->EfiKeyFiFo->Data[Head];
+
+ TerminalDevice->EfiKeyFiFo->Head = (UINT8) ((Head + 1) % (FIFO_MAX_NUMBER + 1));
+
+ return TRUE;
+}
+
+/**
+ Clarify whether FIFO buffer is empty.
+
+ @param TerminalDevice Terminal driver private structure
+
+ @retval TRUE If FIFO buffer is empty.
+ @retval FLASE If FIFO buffer is not empty.
+
+**/
+BOOLEAN
+IsEfiKeyFiFoEmpty (
+ TERMINAL_DEV *TerminalDevice
+ )
+{
+ if (TerminalDevice->EfiKeyFiFo->Head == TerminalDevice->EfiKeyFiFo->Tail) {
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
+
+/**
+ Clarify whether FIFO buffer is full.
+
+ @param TerminalDevice Terminal driver private structure
+
+ @retval TRUE If FIFO buffer is full.
+ @retval FLASE If FIFO buffer is not full.
+
+**/
+BOOLEAN
+IsEfiKeyFiFoFull (
+ TERMINAL_DEV *TerminalDevice
+ )
+{
+ UINT8 Tail;
+ UINT8 Head;
+
+ Tail = TerminalDevice->EfiKeyFiFo->Tail;
+ Head = TerminalDevice->EfiKeyFiFo->Head;
+
+ if (((Tail + 1) % (FIFO_MAX_NUMBER + 1)) == Head) {
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/**
+ Insert one pre-fetched key into the Unicode FIFO buffer.
+
+ @param TerminalDevice Terminal driver private structure.
+ @param Input The key will be input.
+
+ @retval TRUE If insert successfully.
+ @retval FLASE If Unicode FIFO buffer is full before key insertion,
+ and the key is lost.
+
+**/
+BOOLEAN
+UnicodeFiFoInsertOneKey (
+ TERMINAL_DEV *TerminalDevice,
+ UINT16 Input
+ )
+{
+ UINT8 Tail;
+
+ Tail = TerminalDevice->UnicodeFiFo->Tail;
+ ASSERT (Tail < FIFO_MAX_NUMBER + 1);
+
+
+ if (IsUnicodeFiFoFull (TerminalDevice)) {
+ //
+ // Unicode FIFO is full
+ //
+ return FALSE;
+ }
+
+ TerminalDevice->UnicodeFiFo->Data[Tail] = Input;
+
+ TerminalDevice->UnicodeFiFo->Tail = (UINT8) ((Tail + 1) % (FIFO_MAX_NUMBER + 1));
+
+ return TRUE;
+}
+
+/**
+ Remove one pre-fetched key out of the Unicode FIFO buffer.
+
+ @param TerminalDevice Terminal driver private structure.
+ @param Output The key will be removed.
+
+ @retval TRUE If insert successfully.
+ @retval FLASE If Unicode FIFO buffer is empty before remove operation.
+
+**/
+BOOLEAN
+UnicodeFiFoRemoveOneKey (
+ TERMINAL_DEV *TerminalDevice,
+ UINT16 *Output
+ )
+{
+ UINT8 Head;
+
+ Head = TerminalDevice->UnicodeFiFo->Head;
+ ASSERT (Head < FIFO_MAX_NUMBER + 1);
+
+ if (IsUnicodeFiFoEmpty (TerminalDevice)) {
+ //
+ // FIFO is empty
+ //
+ Output = NULL;
+ return FALSE;
+ }
+
+ *Output = TerminalDevice->UnicodeFiFo->Data[Head];
+
+ TerminalDevice->UnicodeFiFo->Head = (UINT8) ((Head + 1) % (FIFO_MAX_NUMBER + 1));
+
+ return TRUE;
+}
+
+/**
+ Clarify whether Unicode FIFO buffer is empty.
+
+ @param TerminalDevice Terminal driver private structure
+
+ @retval TRUE If Unicode FIFO buffer is empty.
+ @retval FLASE If Unicode FIFO buffer is not empty.
+
+**/
+BOOLEAN
+IsUnicodeFiFoEmpty (
+ TERMINAL_DEV *TerminalDevice
+ )
+{
+ if (TerminalDevice->UnicodeFiFo->Head == TerminalDevice->UnicodeFiFo->Tail) {
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
+
+/**
+ Clarify whether Unicode FIFO buffer is full.
+
+ @param TerminalDevice Terminal driver private structure
+
+ @retval TRUE If Unicode FIFO buffer is full.
+ @retval FLASE If Unicode FIFO buffer is not full.
+
+**/
+BOOLEAN
+IsUnicodeFiFoFull (
+ TERMINAL_DEV *TerminalDevice
+ )
+{
+ UINT8 Tail;
+ UINT8 Head;
+
+ Tail = TerminalDevice->UnicodeFiFo->Tail;
+ Head = TerminalDevice->UnicodeFiFo->Head;
+
+ if (((Tail + 1) % (FIFO_MAX_NUMBER + 1)) == Head) {
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/**
+ Count Unicode FIFO buffer.
+
+ @param TerminalDevice Terminal driver private structure
+
+ @return The count in bytes of Unicode FIFO.
+
+**/
+UINT8
+UnicodeFiFoGetKeyCount (
+ TERMINAL_DEV *TerminalDevice
+ )
+{
+ UINT8 Tail;
+ UINT8 Head;
+
+ Tail = TerminalDevice->UnicodeFiFo->Tail;
+ Head = TerminalDevice->UnicodeFiFo->Head;
+
+ if (Tail >= Head) {
+ return (UINT8) (Tail - Head);
+ } else {
+ return (UINT8) (Tail + FIFO_MAX_NUMBER + 1 - Head);
+ }
+}
+
+/**
+ Update the Unicode characters from a terminal input device into EFI Keys FIFO.
+
+ @param TerminalDevice The terminal device to use to translate raw input into EFI Keys
+
+**/
+VOID
+UnicodeToEfiKeyFlushState (
+ IN TERMINAL_DEV *TerminalDevice
+ )
+{
+ EFI_INPUT_KEY Key;
+ UINT32 InputState;
+
+ InputState = TerminalDevice->InputState;
+
+ if (IsEfiKeyFiFoFull (TerminalDevice)) {
+ return;
+ }
+
+ if ((InputState & INPUT_STATE_ESC) != 0) {
+ Key.ScanCode = SCAN_ESC;
+ Key.UnicodeChar = 0;
+ EfiKeyFiFoInsertOneKey (TerminalDevice, &Key);
+ }
+
+ if ((InputState & INPUT_STATE_CSI) != 0) {
+ Key.ScanCode = SCAN_NULL;
+ Key.UnicodeChar = CSI;
+ EfiKeyFiFoInsertOneKey (TerminalDevice, &Key);
+ }
+
+ if ((InputState & INPUT_STATE_LEFTOPENBRACKET) != 0) {
+ Key.ScanCode = SCAN_NULL;
+ Key.UnicodeChar = LEFTOPENBRACKET;
+ EfiKeyFiFoInsertOneKey (TerminalDevice, &Key);
+ }
+
+ if ((InputState & INPUT_STATE_O) != 0) {
+ Key.ScanCode = SCAN_NULL;
+ Key.UnicodeChar = 'O';
+ EfiKeyFiFoInsertOneKey (TerminalDevice, &Key);
+ }
+
+ if ((InputState & INPUT_STATE_2) != 0) {
+ Key.ScanCode = SCAN_NULL;
+ Key.UnicodeChar = '2';
+ EfiKeyFiFoInsertOneKey (TerminalDevice, &Key);
+ }
+
+ //
+ // Cancel the timer.
+ //
+ gBS->SetTimer (
+ TerminalDevice->TwoSecondTimeOut,
+ TimerCancel,
+ 0
+ );
+
+ TerminalDevice->InputState = INPUT_STATE_DEFAULT;
+}
+
+
+/**
+ Converts a stream of Unicode characters from a terminal input device into EFI Keys that
+ can be read through the Simple Input Protocol.
+
+ The table below shows the keyboard input mappings that this function supports.
+ If the ESC sequence listed in one of the columns is presented, then it is translated
+ into the corresponding EFI Scan Code. If a matching sequence is not found, then the raw
+ key strokes are converted into EFI Keys.
+
+ 2 seconds are allowed for an ESC sequence to be completed. If the ESC sequence is not
+ completed in 2 seconds, then the raw key strokes of the partial ESC sequence are
+ converted into EFI Keys.
+ There is one special input sequence that will force the system to reset.
+ This is ESC R ESC r ESC R.
+
+ Note: current implementation support terminal types include: PC ANSI, VT100+/VTUTF8, VT100.
+ The table below is not same with UEFI Spec 2.3 Appendix B Table 201(not support ANSI X3.64 /
+ DEC VT200-500 and extra support PC ANSI, VT100)since UEFI Table 201 is just an example.
+
+ Symbols used in table below
+ ===========================
+ ESC = 0x1B
+ CSI = 0x9B
+ DEL = 0x7f
+ ^ = CTRL
+
+ +=========+======+===========+==========+==========+
+ | | EFI | UEFI 2.0 | | |
+ | | Scan | | VT100+ | |
+ | KEY | Code | PC ANSI | VTUTF8 | VT100 |
+ +=========+======+===========+==========+==========+
+ | NULL | 0x00 | | | |
+ | UP | 0x01 | ESC [ A | ESC [ A | ESC [ A |
+ | DOWN | 0x02 | ESC [ B | ESC [ B | ESC [ B |
+ | RIGHT | 0x03 | ESC [ C | ESC [ C | ESC [ C |
+ | LEFT | 0x04 | ESC [ D | ESC [ D | ESC [ D |
+ | HOME | 0x05 | ESC [ H | ESC h | ESC [ H |
+ | END | 0x06 | ESC [ F | ESC k | ESC [ K |
+ | INSERT | 0x07 | ESC [ @ | ESC + | ESC [ @ |
+ | | | ESC [ L | | ESC [ L |
+ | DELETE | 0x08 | ESC [ X | ESC - | ESC [ P |
+ | PG UP | 0x09 | ESC [ I | ESC ? | ESC [ V |
+ | | | | | ESC [ ? |
+ | PG DOWN | 0x0A | ESC [ G | ESC / | ESC [ U |
+ | | | | | ESC [ / |
+ | F1 | 0x0B | ESC [ M | ESC 1 | ESC O P |
+ | F2 | 0x0C | ESC [ N | ESC 2 | ESC O Q |
+ | F3 | 0x0D | ESC [ O | ESC 3 | ESC O w |
+ | F4 | 0x0E | ESC [ P | ESC 4 | ESC O x |
+ | F5 | 0x0F | ESC [ Q | ESC 5 | ESC O t |
+ | F6 | 0x10 | ESC [ R | ESC 6 | ESC O u |
+ | F7 | 0x11 | ESC [ S | ESC 7 | ESC O q |
+ | F8 | 0x12 | ESC [ T | ESC 8 | ESC O r |
+ | F9 | 0x13 | ESC [ U | ESC 9 | ESC O p |
+ | F10 | 0x14 | ESC [ V | ESC 0 | ESC O M |
+ | Escape | 0x17 | ESC | ESC | ESC |
+ | F11 | 0x15 | | ESC ! | |
+ | F12 | 0x16 | | ESC @ | |
+ +=========+======+===========+==========+==========+
+
+ Special Mappings
+ ================
+ ESC R ESC r ESC R = Reset System
+
+ @param TerminalDevice The terminal device to use to translate raw input into EFI Keys
+
+**/
+VOID
+UnicodeToEfiKey (
+ IN TERMINAL_DEV *TerminalDevice
+ )
+{
+ EFI_STATUS Status;
+ EFI_STATUS TimerStatus;
+ UINT16 UnicodeChar;
+ EFI_INPUT_KEY Key;
+ BOOLEAN SetDefaultResetState;
+
+ TimerStatus = gBS->CheckEvent (TerminalDevice->TwoSecondTimeOut);
+
+ if (!EFI_ERROR (TimerStatus)) {
+ UnicodeToEfiKeyFlushState (TerminalDevice);
+ TerminalDevice->ResetState = RESET_STATE_DEFAULT;
+ }
+
+ while (!IsUnicodeFiFoEmpty (TerminalDevice) && !IsEfiKeyFiFoFull (TerminalDevice)) {
+
+ if (TerminalDevice->InputState != INPUT_STATE_DEFAULT) {
+ //
+ // Check to see if the 2 seconds timer has expired
+ //
+ TimerStatus = gBS->CheckEvent (TerminalDevice->TwoSecondTimeOut);
+ if (!EFI_ERROR (TimerStatus)) {
+ UnicodeToEfiKeyFlushState (TerminalDevice);
+ TerminalDevice->ResetState = RESET_STATE_DEFAULT;
+ }
+ }
+
+ //
+ // Fetch one Unicode character from the Unicode FIFO
+ //
+ UnicodeFiFoRemoveOneKey (TerminalDevice, &UnicodeChar);
+
+ SetDefaultResetState = TRUE;
+
+ switch (TerminalDevice->InputState) {
+ case INPUT_STATE_DEFAULT:
+
+ break;
+
+ case INPUT_STATE_ESC:
+
+ if (UnicodeChar == LEFTOPENBRACKET) {
+ TerminalDevice->InputState |= INPUT_STATE_LEFTOPENBRACKET;
+ TerminalDevice->ResetState = RESET_STATE_DEFAULT;
+ continue;
+ }
+
+ if (UnicodeChar == 'O' && TerminalDevice->TerminalType == VT100TYPE) {
+ TerminalDevice->InputState |= INPUT_STATE_O;
+ TerminalDevice->ResetState = RESET_STATE_DEFAULT;
+ continue;
+ }
+
+ Key.ScanCode = SCAN_NULL;
+
+ if (TerminalDevice->TerminalType == VT100PLUSTYPE ||
+ TerminalDevice->TerminalType == VTUTF8TYPE) {
+ switch (UnicodeChar) {
+ case '1':
+ Key.ScanCode = SCAN_F1;
+ break;
+ case '2':
+ Key.ScanCode = SCAN_F2;
+ break;
+ case '3':
+ Key.ScanCode = SCAN_F3;
+ break;
+ case '4':
+ Key.ScanCode = SCAN_F4;
+ break;
+ case '5':
+ Key.ScanCode = SCAN_F5;
+ break;
+ case '6':
+ Key.ScanCode = SCAN_F6;
+ break;
+ case '7':
+ Key.ScanCode = SCAN_F7;
+ break;
+ case '8':
+ Key.ScanCode = SCAN_F8;
+ break;
+ case '9':
+ Key.ScanCode = SCAN_F9;
+ break;
+ case '0':
+ Key.ScanCode = SCAN_F10;
+ break;
+ case '!':
+ Key.ScanCode = SCAN_F11;
+ break;
+ case '@':
+ Key.ScanCode = SCAN_F12;
+ break;
+ case 'h':
+ Key.ScanCode = SCAN_HOME;
+ break;
+ case 'k':
+ Key.ScanCode = SCAN_END;
+ break;
+ case '+':
+ Key.ScanCode = SCAN_INSERT;
+ break;
+ case '-':
+ Key.ScanCode = SCAN_DELETE;
+ break;
+ case '/':
+ Key.ScanCode = SCAN_PAGE_DOWN;
+ break;
+ case '?':
+ Key.ScanCode = SCAN_PAGE_UP;
+ break;
+ default :
+ break;
+ }
+ }
+
+ switch (UnicodeChar) {
+ case 'R':
+ if (TerminalDevice->ResetState == RESET_STATE_DEFAULT) {
+ TerminalDevice->ResetState = RESET_STATE_ESC_R;
+ SetDefaultResetState = FALSE;
+ } else if (TerminalDevice->ResetState == RESET_STATE_ESC_R_ESC_R) {
+ gRT->ResetSystem (EfiResetWarm, EFI_SUCCESS, 0, NULL);
+ }
+ Key.ScanCode = SCAN_NULL;
+ break;
+ case 'r':
+ if (TerminalDevice->ResetState == RESET_STATE_ESC_R) {
+ TerminalDevice->ResetState = RESET_STATE_ESC_R_ESC_R;
+ SetDefaultResetState = FALSE;
+ }
+ Key.ScanCode = SCAN_NULL;
+ break;
+ default :
+ break;
+ }
+
+ if (SetDefaultResetState) {
+ TerminalDevice->ResetState = RESET_STATE_DEFAULT;
+ }
+
+ if (Key.ScanCode != SCAN_NULL) {
+ Key.UnicodeChar = 0;
+ EfiKeyFiFoInsertOneKey (TerminalDevice, &Key);
+ TerminalDevice->InputState = INPUT_STATE_DEFAULT;
+ UnicodeToEfiKeyFlushState (TerminalDevice);
+ continue;
+ }
+
+ UnicodeToEfiKeyFlushState (TerminalDevice);
+
+ break;
+
+ case INPUT_STATE_ESC | INPUT_STATE_O:
+
+ TerminalDevice->ResetState = RESET_STATE_DEFAULT;
+
+ Key.ScanCode = SCAN_NULL;
+
+ if (TerminalDevice->TerminalType == VT100TYPE) {
+ switch (UnicodeChar) {
+ case 'P':
+ Key.ScanCode = SCAN_F1;
+ break;
+ case 'Q':
+ Key.ScanCode = SCAN_F2;
+ break;
+ case 'w':
+ Key.ScanCode = SCAN_F3;
+ break;
+ case 'x':
+ Key.ScanCode = SCAN_F4;
+ break;
+ case 't':
+ Key.ScanCode = SCAN_F5;
+ break;
+ case 'u':
+ Key.ScanCode = SCAN_F6;
+ break;
+ case 'q':
+ Key.ScanCode = SCAN_F7;
+ break;
+ case 'r':
+ Key.ScanCode = SCAN_F8;
+ break;
+ case 'p':
+ Key.ScanCode = SCAN_F9;
+ break;
+ case 'M':
+ Key.ScanCode = SCAN_F10;
+ break;
+ default :
+ break;
+ }
+ }
+
+ if (Key.ScanCode != SCAN_NULL) {
+ Key.UnicodeChar = 0;
+ EfiKeyFiFoInsertOneKey (TerminalDevice, &Key);
+ TerminalDevice->InputState = INPUT_STATE_DEFAULT;
+ UnicodeToEfiKeyFlushState (TerminalDevice);
+ continue;
+ }
+
+ UnicodeToEfiKeyFlushState (TerminalDevice);
+
+ break;
+
+ case INPUT_STATE_ESC | INPUT_STATE_LEFTOPENBRACKET:
+
+ TerminalDevice->ResetState = RESET_STATE_DEFAULT;
+
+ Key.ScanCode = SCAN_NULL;
+
+ if (TerminalDevice->TerminalType == PCANSITYPE ||
+ TerminalDevice->TerminalType == VT100TYPE ||
+ TerminalDevice->TerminalType == VT100PLUSTYPE ||
+ TerminalDevice->TerminalType == VTUTF8TYPE) {
+ switch (UnicodeChar) {
+ case 'A':
+ Key.ScanCode = SCAN_UP;
+ break;
+ case 'B':
+ Key.ScanCode = SCAN_DOWN;
+ break;
+ case 'C':
+ Key.ScanCode = SCAN_RIGHT;
+ break;
+ case 'D':
+ Key.ScanCode = SCAN_LEFT;
+ break;
+ case 'H':
+ if (TerminalDevice->TerminalType == PCANSITYPE ||
+ TerminalDevice->TerminalType == VT100TYPE) {
+ Key.ScanCode = SCAN_HOME;
+ }
+ break;
+ case 'F':
+ if (TerminalDevice->TerminalType == PCANSITYPE) {
+ Key.ScanCode = SCAN_END;
+ }
+ break;
+ case 'K':
+ if (TerminalDevice->TerminalType == VT100TYPE) {
+ Key.ScanCode = SCAN_END;
+ }
+ break;
+ case 'L':
+ case '@':
+ if (TerminalDevice->TerminalType == PCANSITYPE ||
+ TerminalDevice->TerminalType == VT100TYPE) {
+ Key.ScanCode = SCAN_INSERT;
+ }
+ break;
+ case 'X':
+ if (TerminalDevice->TerminalType == PCANSITYPE) {
+ Key.ScanCode = SCAN_DELETE;
+ }
+ break;
+ case 'P':
+ if (TerminalDevice->TerminalType == VT100TYPE) {
+ Key.ScanCode = SCAN_DELETE;
+ } else if (TerminalDevice->TerminalType == PCANSITYPE) {
+ Key.ScanCode = SCAN_F4;
+ }
+ break;
+ case 'I':
+ if (TerminalDevice->TerminalType == PCANSITYPE) {
+ Key.ScanCode = SCAN_PAGE_UP;
+ }
+ break;
+ case 'V':
+ if (TerminalDevice->TerminalType == PCANSITYPE) {
+ Key.ScanCode = SCAN_F10;
+ }
+ case '?':
+ if (TerminalDevice->TerminalType == VT100TYPE) {
+ Key.ScanCode = SCAN_PAGE_UP;
+ }
+ break;
+ case 'G':
+ if (TerminalDevice->TerminalType == PCANSITYPE) {
+ Key.ScanCode = SCAN_PAGE_DOWN;
+ }
+ break;
+ case 'U':
+ if (TerminalDevice->TerminalType == PCANSITYPE) {
+ Key.ScanCode = SCAN_F9;
+ }
+ case '/':
+ if (TerminalDevice->TerminalType == VT100TYPE) {
+ Key.ScanCode = SCAN_PAGE_DOWN;
+ }
+ break;
+ case 'M':
+ if (TerminalDevice->TerminalType == PCANSITYPE) {
+ Key.ScanCode = SCAN_F1;
+ }
+ break;
+ case 'N':
+ if (TerminalDevice->TerminalType == PCANSITYPE) {
+ Key.ScanCode = SCAN_F2;
+ }
+ break;
+ case 'O':
+ if (TerminalDevice->TerminalType == PCANSITYPE) {
+ Key.ScanCode = SCAN_F3;
+ }
+ break;
+ case 'Q':
+ if (TerminalDevice->TerminalType == PCANSITYPE) {
+ Key.ScanCode = SCAN_F5;
+ }
+ break;
+ case 'R':
+ if (TerminalDevice->TerminalType == PCANSITYPE) {
+ Key.ScanCode = SCAN_F6;
+ }
+ break;
+ case 'S':
+ if (TerminalDevice->TerminalType == PCANSITYPE) {
+ Key.ScanCode = SCAN_F7;
+ }
+ break;
+ case 'T':
+ if (TerminalDevice->TerminalType == PCANSITYPE) {
+ Key.ScanCode = SCAN_F8;
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+ if (Key.ScanCode != SCAN_NULL) {
+ Key.UnicodeChar = 0;
+ EfiKeyFiFoInsertOneKey (TerminalDevice, &Key);
+ TerminalDevice->InputState = INPUT_STATE_DEFAULT;
+ UnicodeToEfiKeyFlushState (TerminalDevice);
+ continue;
+ }
+
+ UnicodeToEfiKeyFlushState (TerminalDevice);
+
+ break;
+
+
+ default:
+ //
+ // Invalid state. This should never happen.
+ //
+ ASSERT (FALSE);
+
+ UnicodeToEfiKeyFlushState (TerminalDevice);
+
+ break;
+ }
+
+ if (UnicodeChar == ESC) {
+ TerminalDevice->InputState = INPUT_STATE_ESC;
+ }
+
+ if (UnicodeChar == CSI) {
+ TerminalDevice->InputState = INPUT_STATE_CSI;
+ }
+
+ if (TerminalDevice->InputState != INPUT_STATE_DEFAULT) {
+ Status = gBS->SetTimer(
+ TerminalDevice->TwoSecondTimeOut,
+ TimerRelative,
+ (UINT64)20000000
+ );
+ ASSERT_EFI_ERROR (Status);
+ continue;
+ }
+
+ if (SetDefaultResetState) {
+ TerminalDevice->ResetState = RESET_STATE_DEFAULT;
+ }
+
+ if (UnicodeChar == DEL) {
+ Key.ScanCode = SCAN_DELETE;
+ Key.UnicodeChar = 0;
+ } else {
+ Key.ScanCode = SCAN_NULL;
+ Key.UnicodeChar = UnicodeChar;
+ }
+
+ EfiKeyFiFoInsertOneKey (TerminalDevice, &Key);
+ }
+}
diff --git a/MdeModulePkg/Universal/Console/TerminalDxe/Vtutf8.c b/MdeModulePkg/Universal/Console/TerminalDxe/Vtutf8.c index 1ad2f9c..586e8ab 100644 --- a/MdeModulePkg/Universal/Console/TerminalDxe/Vtutf8.c +++ b/MdeModulePkg/Universal/Console/TerminalDxe/Vtutf8.c @@ -1,328 +1,328 @@ -/** @file - Implementation of translation upon VT-UTF8. - -Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR> -This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "Terminal.h" - -/** - Translate all VT-UTF8 characters in the Raw FIFI into unicode characters, - and insert them into Unicode FIFO. - - @param TerminalDevice The terminal device. - -**/ -VOID -VTUTF8RawDataToUnicode ( - IN TERMINAL_DEV *TerminalDevice - ) -{ - UTF8_CHAR Utf8Char; - UINT8 ValidBytes; - UINT16 UnicodeChar; - - ValidBytes = 0; - // - // pop the raw data out from the raw fifo, - // and translate it into unicode, then push - // the unicode into unicode fifo, until the raw fifo is empty. - // - while (!IsRawFiFoEmpty (TerminalDevice) && !IsUnicodeFiFoFull(TerminalDevice) ) { - - GetOneValidUtf8Char (TerminalDevice, &Utf8Char, &ValidBytes); - - if (ValidBytes < 1 || ValidBytes > 3) { - continue; - } - - Utf8ToUnicode (Utf8Char, ValidBytes, (CHAR16 *) &UnicodeChar); - - UnicodeFiFoInsertOneKey (TerminalDevice, UnicodeChar); - } -} - -/** - Get one valid VT-UTF8 characters set from Raw Data FIFO. - - @param Utf8Device The terminal device. - @param Utf8Char Returned valid VT-UTF8 characters set. - @param ValidBytes The count of returned VT-VTF8 characters. - If ValidBytes is zero, no valid VT-UTF8 returned. - -**/ -VOID -GetOneValidUtf8Char ( - IN TERMINAL_DEV *Utf8Device, - OUT UTF8_CHAR *Utf8Char, - OUT UINT8 *ValidBytes - ) -{ - UINT8 Temp; - UINT8 Index; - BOOLEAN FetchFlag; - - Temp = 0; - Index = 0; - FetchFlag = TRUE; - - // - // if no valid Utf8 char is found in the RawFiFo, - // then *ValidBytes will be zero. - // - *ValidBytes = 0; - - while (!IsRawFiFoEmpty (Utf8Device)) { - - RawFiFoRemoveOneKey (Utf8Device, &Temp); - - switch (*ValidBytes) { - - case 0: - if ((Temp & 0x80) == 0) { - // - // one-byte utf8 char - // - *ValidBytes = 1; - - Utf8Char->Utf8_1 = Temp; - - FetchFlag = FALSE; - - } else if ((Temp & 0xe0) == 0xc0) { - // - // two-byte utf8 char - // - *ValidBytes = 2; - - Utf8Char->Utf8_2[1] = Temp; - - } else if ((Temp & 0xf0) == 0xe0) { - // - // three-byte utf8 char - // - *ValidBytes = 3; - - Utf8Char->Utf8_3[2] = Temp; - - Index++; - - } else { - // - // reset *ValidBytes to zero, let valid utf8 char search restart - // - *ValidBytes = 0; - } - - break; - - case 2: - // - // two-byte utf8 char go on - // - if ((Temp & 0xc0) == 0x80) { - - Utf8Char->Utf8_2[0] = Temp; - - FetchFlag = FALSE; - - } else { - - *ValidBytes = 0; - } - break; - - case 3: - // - // three-byte utf8 char go on - // - if ((Temp & 0xc0) == 0x80) { - if (Index == 1) { - Utf8Char->Utf8_3[1] = Temp; - Index++; - } else { - Utf8Char->Utf8_3[0] = Temp; - FetchFlag = FALSE; - } - } else { - // - // reset *ValidBytes and Index to zero, let valid utf8 char search restart - // - *ValidBytes = 0; - Index = 0; - } - break; - - default: - break; - } - - if (!FetchFlag) { - break; - } - } - - return ; -} - -/** - Translate VT-UTF8 characters into one Unicode character. - - UTF8 Encoding Table - Bits per Character | Unicode Character Range | Unicode Binary Encoding | UTF8 Binary Encoding - 0-7 | 0x0000 - 0x007F | 00000000 0xxxxxxx | 0xxxxxxx - 8-11 | 0x0080 - 0x07FF | 00000xxx xxxxxxxx | 110xxxxx 10xxxxxx - 12-16 | 0x0800 - 0xFFFF | xxxxxxxx xxxxxxxx | 1110xxxx 10xxxxxx 10xxxxxx - - - @param Utf8Char VT-UTF8 character set needs translating. - @param ValidBytes The count of valid VT-UTF8 characters. - @param UnicodeChar Returned unicode character. - -**/ -VOID -Utf8ToUnicode ( - IN UTF8_CHAR Utf8Char, - IN UINT8 ValidBytes, - OUT CHAR16 *UnicodeChar - ) -{ - UINT8 UnicodeByte0; - UINT8 UnicodeByte1; - UINT8 Byte0; - UINT8 Byte1; - UINT8 Byte2; - - *UnicodeChar = 0; - - // - // translate utf8 code to unicode, in terminal standard, - // up to 3 bytes utf8 code is supported. - // - switch (ValidBytes) { - case 1: - // - // one-byte utf8 code - // - *UnicodeChar = (UINT16) Utf8Char.Utf8_1; - break; - - case 2: - // - // two-byte utf8 code - // - Byte0 = Utf8Char.Utf8_2[0]; - Byte1 = Utf8Char.Utf8_2[1]; - - UnicodeByte0 = (UINT8) ((Byte1 << 6) | (Byte0 & 0x3f)); - UnicodeByte1 = (UINT8) ((Byte1 >> 2) & 0x07); - *UnicodeChar = (UINT16) (UnicodeByte0 | (UnicodeByte1 << 8)); - break; - - case 3: - // - // three-byte utf8 code - // - Byte0 = Utf8Char.Utf8_3[0]; - Byte1 = Utf8Char.Utf8_3[1]; - Byte2 = Utf8Char.Utf8_3[2]; - - UnicodeByte0 = (UINT8) ((Byte1 << 6) | (Byte0 & 0x3f)); - UnicodeByte1 = (UINT8) ((Byte2 << 4) | ((Byte1 >> 2) & 0x0f)); - *UnicodeChar = (UINT16) (UnicodeByte0 | (UnicodeByte1 << 8)); - - default: - break; - } - - return ; -} - -/** - Translate one Unicode character into VT-UTF8 characters. - - UTF8 Encoding Table - Bits per Character | Unicode Character Range | Unicode Binary Encoding | UTF8 Binary Encoding - 0-7 | 0x0000 - 0x007F | 00000000 0xxxxxxx | 0xxxxxxx - 8-11 | 0x0080 - 0x07FF | 00000xxx xxxxxxxx | 110xxxxx 10xxxxxx - 12-16 | 0x0800 - 0xFFFF | xxxxxxxx xxxxxxxx | 1110xxxx 10xxxxxx 10xxxxxx - - - @param Unicode Unicode character need translating. - @param Utf8Char Return VT-UTF8 character set. - @param ValidBytes The count of valid VT-UTF8 characters. If - ValidBytes is zero, no valid VT-UTF8 returned. - -**/ -VOID -UnicodeToUtf8 ( - IN CHAR16 Unicode, - OUT UTF8_CHAR *Utf8Char, - OUT UINT8 *ValidBytes - ) -{ - UINT8 UnicodeByte0; - UINT8 UnicodeByte1; - // - // translate unicode to utf8 code - // - UnicodeByte0 = (UINT8) Unicode; - UnicodeByte1 = (UINT8) (Unicode >> 8); - - if (Unicode < 0x0080) { - - Utf8Char->Utf8_1 = (UINT8) (UnicodeByte0 & 0x7f); - *ValidBytes = 1; - - } else if (Unicode < 0x0800) { - // - // byte sequence: high -> low - // Utf8_2[0], Utf8_2[1] - // - Utf8Char->Utf8_2[1] = (UINT8) ((UnicodeByte0 & 0x3f) + 0x80); - Utf8Char->Utf8_2[0] = (UINT8) ((((UnicodeByte1 << 2) + (UnicodeByte0 >> 6)) & 0x1f) + 0xc0); - - *ValidBytes = 2; - - } else { - // - // byte sequence: high -> low - // Utf8_3[0], Utf8_3[1], Utf8_3[2] - // - Utf8Char->Utf8_3[2] = (UINT8) ((UnicodeByte0 & 0x3f) + 0x80); - Utf8Char->Utf8_3[1] = (UINT8) ((((UnicodeByte1 << 2) + (UnicodeByte0 >> 6)) & 0x3f) + 0x80); - Utf8Char->Utf8_3[0] = (UINT8) (((UnicodeByte1 >> 4) & 0x0f) + 0xe0); - - *ValidBytes = 3; - } -} - - -/** - Check if input string is valid VT-UTF8 string. - - @param TerminalDevice The terminal device. - @param WString The input string. - - @retval EFI_SUCCESS If all input characters are valid. - -**/ -EFI_STATUS -VTUTF8TestString ( - IN TERMINAL_DEV *TerminalDevice, - IN CHAR16 *WString - ) -{ - // - // to utf8, all kind of characters are supported. - // - return EFI_SUCCESS; -} +/** @file
+ Implementation of translation upon VT-UTF8.
+
+Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "Terminal.h"
+
+/**
+ Translate all VT-UTF8 characters in the Raw FIFI into unicode characters,
+ and insert them into Unicode FIFO.
+
+ @param TerminalDevice The terminal device.
+
+**/
+VOID
+VTUTF8RawDataToUnicode (
+ IN TERMINAL_DEV *TerminalDevice
+ )
+{
+ UTF8_CHAR Utf8Char;
+ UINT8 ValidBytes;
+ UINT16 UnicodeChar;
+
+ ValidBytes = 0;
+ //
+ // pop the raw data out from the raw fifo,
+ // and translate it into unicode, then push
+ // the unicode into unicode fifo, until the raw fifo is empty.
+ //
+ while (!IsRawFiFoEmpty (TerminalDevice) && !IsUnicodeFiFoFull (TerminalDevice)) {
+
+ GetOneValidUtf8Char (TerminalDevice, &Utf8Char, &ValidBytes);
+
+ if (ValidBytes < 1 || ValidBytes > 3) {
+ continue;
+ }
+
+ Utf8ToUnicode (Utf8Char, ValidBytes, (CHAR16 *) &UnicodeChar);
+
+ UnicodeFiFoInsertOneKey (TerminalDevice, UnicodeChar);
+ }
+}
+
+/**
+ Get one valid VT-UTF8 characters set from Raw Data FIFO.
+
+ @param Utf8Device The terminal device.
+ @param Utf8Char Returned valid VT-UTF8 characters set.
+ @param ValidBytes The count of returned VT-VTF8 characters.
+ If ValidBytes is zero, no valid VT-UTF8 returned.
+
+**/
+VOID
+GetOneValidUtf8Char (
+ IN TERMINAL_DEV *Utf8Device,
+ OUT UTF8_CHAR *Utf8Char,
+ OUT UINT8 *ValidBytes
+ )
+{
+ UINT8 Temp;
+ UINT8 Index;
+ BOOLEAN FetchFlag;
+
+ Temp = 0;
+ Index = 0;
+ FetchFlag = TRUE;
+
+ //
+ // if no valid Utf8 char is found in the RawFiFo,
+ // then *ValidBytes will be zero.
+ //
+ *ValidBytes = 0;
+
+ while (!IsRawFiFoEmpty (Utf8Device)) {
+
+ RawFiFoRemoveOneKey (Utf8Device, &Temp);
+
+ switch (*ValidBytes) {
+
+ case 0:
+ if ((Temp & 0x80) == 0) {
+ //
+ // one-byte utf8 char
+ //
+ *ValidBytes = 1;
+
+ Utf8Char->Utf8_1 = Temp;
+
+ FetchFlag = FALSE;
+
+ } else if ((Temp & 0xe0) == 0xc0) {
+ //
+ // two-byte utf8 char
+ //
+ *ValidBytes = 2;
+
+ Utf8Char->Utf8_2[1] = Temp;
+
+ } else if ((Temp & 0xf0) == 0xe0) {
+ //
+ // three-byte utf8 char
+ //
+ *ValidBytes = 3;
+
+ Utf8Char->Utf8_3[2] = Temp;
+
+ Index++;
+
+ } else {
+ //
+ // reset *ValidBytes to zero, let valid utf8 char search restart
+ //
+ *ValidBytes = 0;
+ }
+
+ break;
+
+ case 2:
+ //
+ // two-byte utf8 char go on
+ //
+ if ((Temp & 0xc0) == 0x80) {
+
+ Utf8Char->Utf8_2[0] = Temp;
+
+ FetchFlag = FALSE;
+
+ } else {
+
+ *ValidBytes = 0;
+ }
+ break;
+
+ case 3:
+ //
+ // three-byte utf8 char go on
+ //
+ if ((Temp & 0xc0) == 0x80) {
+ if (Index == 1) {
+ Utf8Char->Utf8_3[1] = Temp;
+ Index++;
+ } else {
+ Utf8Char->Utf8_3[0] = Temp;
+ FetchFlag = FALSE;
+ }
+ } else {
+ //
+ // reset *ValidBytes and Index to zero, let valid utf8 char search restart
+ //
+ *ValidBytes = 0;
+ Index = 0;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ if (!FetchFlag) {
+ break;
+ }
+ }
+
+ return ;
+}
+
+/**
+ Translate VT-UTF8 characters into one Unicode character.
+
+ UTF8 Encoding Table
+ Bits per Character | Unicode Character Range | Unicode Binary Encoding | UTF8 Binary Encoding
+ 0-7 | 0x0000 - 0x007F | 00000000 0xxxxxxx | 0xxxxxxx
+ 8-11 | 0x0080 - 0x07FF | 00000xxx xxxxxxxx | 110xxxxx 10xxxxxx
+ 12-16 | 0x0800 - 0xFFFF | xxxxxxxx xxxxxxxx | 1110xxxx 10xxxxxx 10xxxxxx
+
+
+ @param Utf8Char VT-UTF8 character set needs translating.
+ @param ValidBytes The count of valid VT-UTF8 characters.
+ @param UnicodeChar Returned unicode character.
+
+**/
+VOID
+Utf8ToUnicode (
+ IN UTF8_CHAR Utf8Char,
+ IN UINT8 ValidBytes,
+ OUT CHAR16 *UnicodeChar
+ )
+{
+ UINT8 UnicodeByte0;
+ UINT8 UnicodeByte1;
+ UINT8 Byte0;
+ UINT8 Byte1;
+ UINT8 Byte2;
+
+ *UnicodeChar = 0;
+
+ //
+ // translate utf8 code to unicode, in terminal standard,
+ // up to 3 bytes utf8 code is supported.
+ //
+ switch (ValidBytes) {
+ case 1:
+ //
+ // one-byte utf8 code
+ //
+ *UnicodeChar = (UINT16) Utf8Char.Utf8_1;
+ break;
+
+ case 2:
+ //
+ // two-byte utf8 code
+ //
+ Byte0 = Utf8Char.Utf8_2[0];
+ Byte1 = Utf8Char.Utf8_2[1];
+
+ UnicodeByte0 = (UINT8) ((Byte1 << 6) | (Byte0 & 0x3f));
+ UnicodeByte1 = (UINT8) ((Byte1 >> 2) & 0x07);
+ *UnicodeChar = (UINT16) (UnicodeByte0 | (UnicodeByte1 << 8));
+ break;
+
+ case 3:
+ //
+ // three-byte utf8 code
+ //
+ Byte0 = Utf8Char.Utf8_3[0];
+ Byte1 = Utf8Char.Utf8_3[1];
+ Byte2 = Utf8Char.Utf8_3[2];
+
+ UnicodeByte0 = (UINT8) ((Byte1 << 6) | (Byte0 & 0x3f));
+ UnicodeByte1 = (UINT8) ((Byte2 << 4) | ((Byte1 >> 2) & 0x0f));
+ *UnicodeChar = (UINT16) (UnicodeByte0 | (UnicodeByte1 << 8));
+
+ default:
+ break;
+ }
+
+ return ;
+}
+
+/**
+ Translate one Unicode character into VT-UTF8 characters.
+
+ UTF8 Encoding Table
+ Bits per Character | Unicode Character Range | Unicode Binary Encoding | UTF8 Binary Encoding
+ 0-7 | 0x0000 - 0x007F | 00000000 0xxxxxxx | 0xxxxxxx
+ 8-11 | 0x0080 - 0x07FF | 00000xxx xxxxxxxx | 110xxxxx 10xxxxxx
+ 12-16 | 0x0800 - 0xFFFF | xxxxxxxx xxxxxxxx | 1110xxxx 10xxxxxx 10xxxxxx
+
+
+ @param Unicode Unicode character need translating.
+ @param Utf8Char Return VT-UTF8 character set.
+ @param ValidBytes The count of valid VT-UTF8 characters. If
+ ValidBytes is zero, no valid VT-UTF8 returned.
+
+**/
+VOID
+UnicodeToUtf8 (
+ IN CHAR16 Unicode,
+ OUT UTF8_CHAR *Utf8Char,
+ OUT UINT8 *ValidBytes
+ )
+{
+ UINT8 UnicodeByte0;
+ UINT8 UnicodeByte1;
+ //
+ // translate unicode to utf8 code
+ //
+ UnicodeByte0 = (UINT8) Unicode;
+ UnicodeByte1 = (UINT8) (Unicode >> 8);
+
+ if (Unicode < 0x0080) {
+
+ Utf8Char->Utf8_1 = (UINT8) (UnicodeByte0 & 0x7f);
+ *ValidBytes = 1;
+
+ } else if (Unicode < 0x0800) {
+ //
+ // byte sequence: high -> low
+ // Utf8_2[0], Utf8_2[1]
+ //
+ Utf8Char->Utf8_2[1] = (UINT8) ((UnicodeByte0 & 0x3f) + 0x80);
+ Utf8Char->Utf8_2[0] = (UINT8) ((((UnicodeByte1 << 2) + (UnicodeByte0 >> 6)) & 0x1f) + 0xc0);
+
+ *ValidBytes = 2;
+
+ } else {
+ //
+ // byte sequence: high -> low
+ // Utf8_3[0], Utf8_3[1], Utf8_3[2]
+ //
+ Utf8Char->Utf8_3[2] = (UINT8) ((UnicodeByte0 & 0x3f) + 0x80);
+ Utf8Char->Utf8_3[1] = (UINT8) ((((UnicodeByte1 << 2) + (UnicodeByte0 >> 6)) & 0x3f) + 0x80);
+ Utf8Char->Utf8_3[0] = (UINT8) (((UnicodeByte1 >> 4) & 0x0f) + 0xe0);
+
+ *ValidBytes = 3;
+ }
+}
+
+
+/**
+ Check if input string is valid VT-UTF8 string.
+
+ @param TerminalDevice The terminal device.
+ @param WString The input string.
+
+ @retval EFI_SUCCESS If all input characters are valid.
+
+**/
+EFI_STATUS
+VTUTF8TestString (
+ IN TERMINAL_DEV *TerminalDevice,
+ IN CHAR16 *WString
+ )
+{
+ //
+ // to utf8, all kind of characters are supported.
+ //
+ return EFI_SUCCESS;
+}
|