2 Implementation for EFI_SIMPLE_TEXT_INPUT_PROTOCOL protocol.
4 (C) Copyright 2014 Hewlett-Packard Development Company, L.P.<BR>
5 Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
6 Copyright (C) 2016 Silicon Graphics, Inc. All rights reserved.<BR>
7 This program and the accompanying materials
8 are licensed and made available under the terms and conditions of the BSD License
9 which accompanies this distribution. The full text of the license may be found at
10 http://opensource.org/licenses/bsd-license.php
12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
21 Reads the next keystroke from the input device. The WaitForKey Event can
22 be used to test for existence of a keystroke via WaitForEvent () call.
24 @param TerminalDevice Terminal driver private structure
25 @param KeyData A pointer to a buffer that is filled in with the
26 keystroke state data for the key that was
29 @retval EFI_SUCCESS The keystroke information was returned.
30 @retval EFI_NOT_READY There was no keystroke data available.
31 @retval EFI_INVALID_PARAMETER KeyData is NULL.
36 IN TERMINAL_DEV
*TerminalDevice
,
37 OUT EFI_KEY_DATA
*KeyData
40 if (KeyData
== NULL
) {
41 return EFI_INVALID_PARAMETER
;
44 if (!EfiKeyFiFoRemoveOneKey (TerminalDevice
, &KeyData
->Key
)) {
48 KeyData
->KeyState
.KeyShiftState
= 0;
49 KeyData
->KeyState
.KeyToggleState
= 0;
57 Implements EFI_SIMPLE_TEXT_INPUT_PROTOCOL.Reset().
58 This driver only perform dependent serial device reset regardless of
59 the value of ExtendeVerification
61 @param This Indicates the calling context.
62 @param ExtendedVerification Skip by this driver.
64 @retval EFI_SUCCESS The reset operation succeeds.
65 @retval EFI_DEVICE_ERROR The dependent serial port reset fails.
71 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*This
,
72 IN BOOLEAN ExtendedVerification
76 TERMINAL_DEV
*TerminalDevice
;
78 TerminalDevice
= TERMINAL_CON_IN_DEV_FROM_THIS (This
);
81 // Report progress code here
83 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
85 (EFI_PERIPHERAL_REMOTE_CONSOLE
| EFI_P_PC_RESET
),
86 TerminalDevice
->DevicePath
89 Status
= TerminalDevice
->SerialIo
->Reset (TerminalDevice
->SerialIo
);
92 // Make all the internal buffer empty for keys
94 TerminalDevice
->RawFiFo
->Head
= TerminalDevice
->RawFiFo
->Tail
;
95 TerminalDevice
->UnicodeFiFo
->Head
= TerminalDevice
->UnicodeFiFo
->Tail
;
96 TerminalDevice
->EfiKeyFiFo
->Head
= TerminalDevice
->EfiKeyFiFo
->Tail
;
97 TerminalDevice
->EfiKeyFiFoForNotify
->Head
= TerminalDevice
->EfiKeyFiFoForNotify
->Tail
;
99 if (EFI_ERROR (Status
)) {
100 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
101 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
102 (EFI_PERIPHERAL_REMOTE_CONSOLE
| EFI_P_EC_CONTROLLER_ERROR
),
103 TerminalDevice
->DevicePath
111 Implements EFI_SIMPLE_TEXT_INPUT_PROTOCOL.ReadKeyStroke().
113 @param This Indicates the calling context.
114 @param Key A pointer to a buffer that is filled in with the
115 keystroke information for the key that was sent
118 @retval EFI_SUCCESS The keystroke information is returned successfully.
119 @retval EFI_NOT_READY There is no keystroke data available.
120 @retval EFI_DEVICE_ERROR The dependent serial device encounters error.
125 TerminalConInReadKeyStroke (
126 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*This
,
127 OUT EFI_INPUT_KEY
*Key
130 TERMINAL_DEV
*TerminalDevice
;
132 EFI_KEY_DATA KeyData
;
135 // get TERMINAL_DEV from "This" parameter.
137 TerminalDevice
= TERMINAL_CON_IN_DEV_FROM_THIS (This
);
139 Status
= ReadKeyStrokeWorker (TerminalDevice
, &KeyData
);
140 if (EFI_ERROR (Status
)) {
144 CopyMem (Key
, &KeyData
.Key
, sizeof (EFI_INPUT_KEY
));
151 Check if the key already has been registered.
153 If both RegsiteredData and InputData is NULL, then ASSERT().
155 @param RegsiteredData A pointer to a buffer that is filled in with the
156 keystroke state data for the key that was
158 @param InputData A pointer to a buffer that is filled in with the
159 keystroke state data for the key that was
162 @retval TRUE Key be pressed matches a registered key.
163 @retval FALSE Match failed.
168 IN EFI_KEY_DATA
*RegsiteredData
,
169 IN EFI_KEY_DATA
*InputData
172 ASSERT (RegsiteredData
!= NULL
&& InputData
!= NULL
);
174 if ((RegsiteredData
->Key
.ScanCode
!= InputData
->Key
.ScanCode
) ||
175 (RegsiteredData
->Key
.UnicodeChar
!= InputData
->Key
.UnicodeChar
)) {
185 Event notification function for EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL.WaitForKeyEx event
186 Signal the event if there is key available
188 @param Event Indicates the event that invoke this function.
189 @param Context Indicates the calling context.
194 TerminalConInWaitForKeyEx (
199 TerminalConInWaitForKey (Event
, Context
);
203 // Simple Text Input Ex protocol functions
207 Reset the input device and optionally run diagnostics
209 @param This Protocol instance pointer.
210 @param ExtendedVerification Driver may perform diagnostics on reset.
212 @retval EFI_SUCCESS The device was reset.
213 @retval EFI_DEVICE_ERROR The device is not functioning properly and could
219 TerminalConInResetEx (
220 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*This
,
221 IN BOOLEAN ExtendedVerification
225 TERMINAL_DEV
*TerminalDevice
;
227 TerminalDevice
= TERMINAL_CON_IN_EX_DEV_FROM_THIS (This
);
229 Status
= TerminalDevice
->SimpleInput
.Reset (&TerminalDevice
->SimpleInput
, ExtendedVerification
);
230 if (EFI_ERROR (Status
)) {
231 return EFI_DEVICE_ERROR
;
240 Reads the next keystroke from the input device. The WaitForKey Event can
241 be used to test for existence of a keystroke via WaitForEvent () call.
243 @param This Protocol instance pointer.
244 @param KeyData A pointer to a buffer that is filled in with the
245 keystroke state data for the key that was
248 @retval EFI_SUCCESS The keystroke information was returned.
249 @retval EFI_NOT_READY There was no keystroke data available.
250 @retval EFI_DEVICE_ERROR The keystroke information was not returned due
252 @retval EFI_INVALID_PARAMETER KeyData is NULL.
257 TerminalConInReadKeyStrokeEx (
258 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*This
,
259 OUT EFI_KEY_DATA
*KeyData
262 TERMINAL_DEV
*TerminalDevice
;
264 if (KeyData
== NULL
) {
265 return EFI_INVALID_PARAMETER
;
268 TerminalDevice
= TERMINAL_CON_IN_EX_DEV_FROM_THIS (This
);
270 return ReadKeyStrokeWorker (TerminalDevice
, KeyData
);
276 Set certain state for the input device.
278 @param This Protocol instance pointer.
279 @param KeyToggleState A pointer to the EFI_KEY_TOGGLE_STATE to set the
280 state for the input device.
282 @retval EFI_SUCCESS The device state was set successfully.
283 @retval EFI_DEVICE_ERROR The device is not functioning correctly and
284 could not have the setting adjusted.
285 @retval EFI_UNSUPPORTED The device does not have the ability to set its
287 @retval EFI_INVALID_PARAMETER KeyToggleState is NULL.
292 TerminalConInSetState (
293 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*This
,
294 IN EFI_KEY_TOGGLE_STATE
*KeyToggleState
297 if (KeyToggleState
== NULL
) {
298 return EFI_INVALID_PARAMETER
;
301 if ((*KeyToggleState
& EFI_TOGGLE_STATE_VALID
) != EFI_TOGGLE_STATE_VALID
) {
302 return EFI_UNSUPPORTED
;
310 Register a notification function for a particular keystroke for the input device.
312 @param This Protocol instance pointer.
313 @param KeyData A pointer to a buffer that is filled in with the
314 keystroke information data for the key that was
316 @param KeyNotificationFunction Points to the function to be called when the key
317 sequence is typed specified by KeyData.
318 @param NotifyHandle Points to the unique handle assigned to the
319 registered notification.
321 @retval EFI_SUCCESS The notification function was registered
323 @retval EFI_OUT_OF_RESOURCES Unable to allocate resources for necessary data
325 @retval EFI_INVALID_PARAMETER KeyData or NotifyHandle is NULL.
330 TerminalConInRegisterKeyNotify (
331 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*This
,
332 IN EFI_KEY_DATA
*KeyData
,
333 IN EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction
,
334 OUT VOID
**NotifyHandle
337 TERMINAL_DEV
*TerminalDevice
;
338 TERMINAL_CONSOLE_IN_EX_NOTIFY
*NewNotify
;
340 LIST_ENTRY
*NotifyList
;
341 TERMINAL_CONSOLE_IN_EX_NOTIFY
*CurrentNotify
;
343 if (KeyData
== NULL
|| NotifyHandle
== NULL
|| KeyNotificationFunction
== NULL
) {
344 return EFI_INVALID_PARAMETER
;
347 TerminalDevice
= TERMINAL_CON_IN_EX_DEV_FROM_THIS (This
);
350 // Return EFI_SUCCESS if the (KeyData, NotificationFunction) is already registered.
352 NotifyList
= &TerminalDevice
->NotifyList
;
353 for (Link
= GetFirstNode (NotifyList
); !IsNull (NotifyList
,Link
); Link
= GetNextNode (NotifyList
,Link
)) {
356 TERMINAL_CONSOLE_IN_EX_NOTIFY
,
358 TERMINAL_CONSOLE_IN_EX_NOTIFY_SIGNATURE
360 if (IsKeyRegistered (&CurrentNotify
->KeyData
, KeyData
)) {
361 if (CurrentNotify
->KeyNotificationFn
== KeyNotificationFunction
) {
362 *NotifyHandle
= CurrentNotify
;
369 // Allocate resource to save the notification function
371 NewNotify
= (TERMINAL_CONSOLE_IN_EX_NOTIFY
*) AllocateZeroPool (sizeof (TERMINAL_CONSOLE_IN_EX_NOTIFY
));
372 if (NewNotify
== NULL
) {
373 return EFI_OUT_OF_RESOURCES
;
376 NewNotify
->Signature
= TERMINAL_CONSOLE_IN_EX_NOTIFY_SIGNATURE
;
377 NewNotify
->KeyNotificationFn
= KeyNotificationFunction
;
378 CopyMem (&NewNotify
->KeyData
, KeyData
, sizeof (EFI_KEY_DATA
));
379 InsertTailList (&TerminalDevice
->NotifyList
, &NewNotify
->NotifyEntry
);
381 *NotifyHandle
= NewNotify
;
388 Remove a registered notification function from a particular keystroke.
390 @param This Protocol instance pointer.
391 @param NotificationHandle The handle of the notification function being
394 @retval EFI_SUCCESS The notification function was unregistered
396 @retval EFI_INVALID_PARAMETER The NotificationHandle is invalid.
401 TerminalConInUnregisterKeyNotify (
402 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*This
,
403 IN VOID
*NotificationHandle
406 TERMINAL_DEV
*TerminalDevice
;
408 TERMINAL_CONSOLE_IN_EX_NOTIFY
*CurrentNotify
;
409 LIST_ENTRY
*NotifyList
;
411 if (NotificationHandle
== NULL
) {
412 return EFI_INVALID_PARAMETER
;
415 TerminalDevice
= TERMINAL_CON_IN_EX_DEV_FROM_THIS (This
);
417 NotifyList
= &TerminalDevice
->NotifyList
;
418 for (Link
= GetFirstNode (NotifyList
); !IsNull (NotifyList
,Link
); Link
= GetNextNode (NotifyList
,Link
)) {
421 TERMINAL_CONSOLE_IN_EX_NOTIFY
,
423 TERMINAL_CONSOLE_IN_EX_NOTIFY_SIGNATURE
425 if (CurrentNotify
== NotificationHandle
) {
427 // Remove the notification function from NotifyList and free resources
429 RemoveEntryList (&CurrentNotify
->NotifyEntry
);
431 gBS
->FreePool (CurrentNotify
);
437 // Can not find the matching entry in database.
439 return EFI_INVALID_PARAMETER
;
443 Translate raw data into Unicode (according to different encode), and
444 translate Unicode into key information. (according to different standard).
446 @param TerminalDevice Terminal driver private structure.
450 TranslateRawDataToEfiKey (
451 IN TERMINAL_DEV
*TerminalDevice
454 switch (TerminalDevice
->TerminalType
) {
460 AnsiRawDataToUnicode (TerminalDevice
);
461 UnicodeToEfiKey (TerminalDevice
);
466 // Process all the raw data in the RawFIFO,
467 // put the processed key into UnicodeFIFO.
469 VTUTF8RawDataToUnicode (TerminalDevice
);
472 // Translate all the Unicode data in the UnicodeFIFO to Efi key,
473 // then put into EfiKeyFIFO.
475 UnicodeToEfiKey (TerminalDevice
);
482 Event notification function for EFI_SIMPLE_TEXT_INPUT_PROTOCOL.WaitForKey event
483 Signal the event if there is key available
485 @param Event Indicates the event that invoke this function.
486 @param Context Indicates the calling context.
491 TerminalConInWaitForKey (
497 // Someone is waiting on the keystroke event, if there's
498 // a key pending, signal the event
500 if (!IsEfiKeyFiFoEmpty ((TERMINAL_DEV
*) Context
)) {
502 gBS
->SignalEvent (Event
);
507 Timer handler to poll the key from serial.
509 @param Event Indicates the event that invoke this function.
510 @param Context Indicates the calling context.
514 TerminalConInTimerHandler (
520 TERMINAL_DEV
*TerminalDevice
;
523 EFI_SERIAL_IO_MODE
*Mode
;
524 EFI_SERIAL_IO_PROTOCOL
*SerialIo
;
525 UINTN SerialInTimeOut
;
527 TerminalDevice
= (TERMINAL_DEV
*) Context
;
529 SerialIo
= TerminalDevice
->SerialIo
;
530 if (SerialIo
== NULL
) {
534 // if current timeout value for serial device is not identical with
535 // the value saved in TERMINAL_DEV structure, then recalculate the
536 // timeout value again and set serial attribute according to this value.
538 Mode
= SerialIo
->Mode
;
539 if (Mode
->Timeout
!= TerminalDevice
->SerialInTimeOut
) {
542 if (Mode
->BaudRate
!= 0) {
544 // According to BAUD rate to calculate the timeout value.
546 SerialInTimeOut
= (1 + Mode
->DataBits
+ Mode
->StopBits
) * 2 * 1000000 / (UINTN
) Mode
->BaudRate
;
549 Status
= SerialIo
->SetAttributes (
552 Mode
->ReceiveFifoDepth
,
553 (UINT32
) SerialInTimeOut
,
554 (EFI_PARITY_TYPE
) (Mode
->Parity
),
555 (UINT8
) Mode
->DataBits
,
556 (EFI_STOP_BITS_TYPE
) (Mode
->StopBits
)
559 if (EFI_ERROR (Status
)) {
560 TerminalDevice
->SerialInTimeOut
= 0;
562 TerminalDevice
->SerialInTimeOut
= SerialInTimeOut
;
566 // Check whether serial buffer is empty.
567 // Skip the key transfer loop only if the SerialIo protocol instance
568 // successfully reports EFI_SERIAL_INPUT_BUFFER_EMPTY.
570 Status
= SerialIo
->GetControl (SerialIo
, &Control
);
571 if (EFI_ERROR (Status
) || ((Control
& EFI_SERIAL_INPUT_BUFFER_EMPTY
) == 0)) {
573 // Fetch all the keys in the serial buffer,
574 // and insert the byte stream into RawFIFO.
576 while (!IsRawFiFoFull (TerminalDevice
)) {
578 Status
= GetOneKeyFromSerial (TerminalDevice
->SerialIo
, &Input
);
580 if (EFI_ERROR (Status
)) {
581 if (Status
== EFI_DEVICE_ERROR
) {
582 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
583 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
584 (EFI_PERIPHERAL_REMOTE_CONSOLE
| EFI_P_EC_INPUT_ERROR
),
585 TerminalDevice
->DevicePath
591 RawFiFoInsertOneKey (TerminalDevice
, Input
);
596 // Translate all the raw data in RawFIFO into EFI Key,
597 // according to different terminal type supported.
599 TranslateRawDataToEfiKey (TerminalDevice
);
605 @param Event Indicates the event that invoke this function.
606 @param Context Indicates the calling context.
610 KeyNotifyProcessHandler (
616 TERMINAL_DEV
*TerminalDevice
;
618 EFI_KEY_DATA KeyData
;
620 LIST_ENTRY
*NotifyList
;
621 TERMINAL_CONSOLE_IN_EX_NOTIFY
*CurrentNotify
;
624 TerminalDevice
= (TERMINAL_DEV
*) Context
;
627 // Invoke notification functions.
629 NotifyList
= &TerminalDevice
->NotifyList
;
632 // Enter critical section
634 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
635 HasKey
= EfiKeyFiFoForNotifyRemoveOneKey (TerminalDevice
->EfiKeyFiFoForNotify
, &Key
);
636 CopyMem (&KeyData
.Key
, &Key
, sizeof (EFI_INPUT_KEY
));
637 KeyData
.KeyState
.KeyShiftState
= 0;
638 KeyData
.KeyState
.KeyToggleState
= 0;
640 // Leave critical section
642 gBS
->RestoreTPL (OldTpl
);
646 for (Link
= GetFirstNode (NotifyList
); !IsNull (NotifyList
, Link
); Link
= GetNextNode (NotifyList
, Link
)) {
647 CurrentNotify
= CR (Link
, TERMINAL_CONSOLE_IN_EX_NOTIFY
, NotifyEntry
, TERMINAL_CONSOLE_IN_EX_NOTIFY_SIGNATURE
);
648 if (IsKeyRegistered (&CurrentNotify
->KeyData
, &KeyData
)) {
649 CurrentNotify
->KeyNotificationFn (&KeyData
);
656 Get one key out of serial buffer.
658 @param SerialIo Serial I/O protocol attached to the serial device.
659 @param Output The fetched key.
661 @retval EFI_NOT_READY If serial buffer is empty.
662 @retval EFI_DEVICE_ERROR If reading serial buffer encounter error.
663 @retval EFI_SUCCESS If reading serial buffer successfully, put
664 the fetched key to the parameter output.
668 GetOneKeyFromSerial (
669 EFI_SERIAL_IO_PROTOCOL
*SerialIo
,
680 // Read one key from serial I/O device.
682 Status
= SerialIo
->Read (SerialIo
, &Size
, Output
);
684 if (EFI_ERROR (Status
)) {
686 if (Status
== EFI_TIMEOUT
) {
687 return EFI_NOT_READY
;
690 return EFI_DEVICE_ERROR
;
695 return EFI_NOT_READY
;
702 Insert one byte raw data into the Raw Data FIFO.
704 @param TerminalDevice Terminal driver private structure.
705 @param Input The key will be input.
707 @retval TRUE If insert successfully.
708 @retval FALSE If Raw Data buffer is full before key insertion,
713 RawFiFoInsertOneKey (
714 TERMINAL_DEV
*TerminalDevice
,
720 Tail
= TerminalDevice
->RawFiFo
->Tail
;
722 if (IsRawFiFoFull (TerminalDevice
)) {
729 TerminalDevice
->RawFiFo
->Data
[Tail
] = Input
;
731 TerminalDevice
->RawFiFo
->Tail
= (UINT8
) ((Tail
+ 1) % (RAW_FIFO_MAX_NUMBER
+ 1));
737 Remove one pre-fetched key out of the Raw Data FIFO.
739 @param TerminalDevice Terminal driver private structure.
740 @param Output The key will be removed.
742 @retval TRUE If insert successfully.
743 @retval FALSE If Raw Data FIFO buffer is empty before remove operation.
747 RawFiFoRemoveOneKey (
748 TERMINAL_DEV
*TerminalDevice
,
754 Head
= TerminalDevice
->RawFiFo
->Head
;
756 if (IsRawFiFoEmpty (TerminalDevice
)) {
764 *Output
= TerminalDevice
->RawFiFo
->Data
[Head
];
766 TerminalDevice
->RawFiFo
->Head
= (UINT8
) ((Head
+ 1) % (RAW_FIFO_MAX_NUMBER
+ 1));
772 Clarify whether Raw Data FIFO buffer is empty.
774 @param TerminalDevice Terminal driver private structure
776 @retval TRUE If Raw Data FIFO buffer is empty.
777 @retval FALSE If Raw Data FIFO buffer is not empty.
782 TERMINAL_DEV
*TerminalDevice
785 if (TerminalDevice
->RawFiFo
->Head
== TerminalDevice
->RawFiFo
->Tail
) {
793 Clarify whether Raw Data FIFO buffer is full.
795 @param TerminalDevice Terminal driver private structure
797 @retval TRUE If Raw Data FIFO buffer is full.
798 @retval FALSE If Raw Data FIFO buffer is not full.
803 TERMINAL_DEV
*TerminalDevice
809 Tail
= TerminalDevice
->RawFiFo
->Tail
;
810 Head
= TerminalDevice
->RawFiFo
->Head
;
812 if (((Tail
+ 1) % (RAW_FIFO_MAX_NUMBER
+ 1)) == Head
) {
821 Insert one pre-fetched key into the FIFO buffer.
823 @param EfiKeyFiFo Pointer to instance of EFI_KEY_FIFO.
824 @param Input The key will be input.
826 @retval TRUE If insert successfully.
827 @retval FALSE If FIFO buffer is full before key insertion,
832 EfiKeyFiFoForNotifyInsertOneKey (
833 EFI_KEY_FIFO
*EfiKeyFiFo
,
839 Tail
= EfiKeyFiFo
->Tail
;
841 if (IsEfiKeyFiFoForNotifyFull (EfiKeyFiFo
)) {
848 CopyMem (&EfiKeyFiFo
->Data
[Tail
], Input
, sizeof (EFI_INPUT_KEY
));
850 EfiKeyFiFo
->Tail
= (UINT8
) ((Tail
+ 1) % (FIFO_MAX_NUMBER
+ 1));
856 Remove one pre-fetched key out of the FIFO buffer.
858 @param EfiKeyFiFo Pointer to instance of EFI_KEY_FIFO.
859 @param Output The key will be removed.
861 @retval TRUE If remove successfully.
862 @retval FALSE If FIFO buffer is empty before remove operation.
866 EfiKeyFiFoForNotifyRemoveOneKey (
867 EFI_KEY_FIFO
*EfiKeyFiFo
,
868 EFI_INPUT_KEY
*Output
873 Head
= EfiKeyFiFo
->Head
;
874 ASSERT (Head
< FIFO_MAX_NUMBER
+ 1);
876 if (IsEfiKeyFiFoForNotifyEmpty (EfiKeyFiFo
)) {
880 Output
->ScanCode
= SCAN_NULL
;
881 Output
->UnicodeChar
= 0;
885 CopyMem (Output
, &EfiKeyFiFo
->Data
[Head
], sizeof (EFI_INPUT_KEY
));
887 EfiKeyFiFo
->Head
= (UINT8
) ((Head
+ 1) % (FIFO_MAX_NUMBER
+ 1));
893 Clarify whether FIFO buffer is empty.
895 @param EfiKeyFiFo Pointer to instance of EFI_KEY_FIFO.
897 @retval TRUE If FIFO buffer is empty.
898 @retval FALSE If FIFO buffer is not empty.
902 IsEfiKeyFiFoForNotifyEmpty (
903 EFI_KEY_FIFO
*EfiKeyFiFo
906 if (EfiKeyFiFo
->Head
== EfiKeyFiFo
->Tail
) {
914 Clarify whether FIFO buffer is full.
916 @param EfiKeyFiFo Pointer to instance of EFI_KEY_FIFO.
918 @retval TRUE If FIFO buffer is full.
919 @retval FALSE If FIFO buffer is not full.
923 IsEfiKeyFiFoForNotifyFull (
924 EFI_KEY_FIFO
*EfiKeyFiFo
930 Tail
= EfiKeyFiFo
->Tail
;
931 Head
= EfiKeyFiFo
->Head
;
933 if (((Tail
+ 1) % (FIFO_MAX_NUMBER
+ 1)) == Head
) {
941 Insert one pre-fetched key into the FIFO buffer.
943 @param TerminalDevice Terminal driver private structure.
944 @param Key The key will be input.
946 @retval TRUE If insert successfully.
947 @retval FALSE If FIFO buffer is full before key insertion,
952 EfiKeyFiFoInsertOneKey (
953 TERMINAL_DEV
*TerminalDevice
,
959 LIST_ENTRY
*NotifyList
;
960 TERMINAL_CONSOLE_IN_EX_NOTIFY
*CurrentNotify
;
961 EFI_KEY_DATA KeyData
;
963 Tail
= TerminalDevice
->EfiKeyFiFo
->Tail
;
965 CopyMem (&KeyData
.Key
, Key
, sizeof (EFI_INPUT_KEY
));
966 KeyData
.KeyState
.KeyShiftState
= 0;
967 KeyData
.KeyState
.KeyToggleState
= 0;
970 // Signal KeyNotify process event if this key pressed matches any key registered.
972 NotifyList
= &TerminalDevice
->NotifyList
;
973 for (Link
= GetFirstNode (NotifyList
); !IsNull (NotifyList
,Link
); Link
= GetNextNode (NotifyList
,Link
)) {
976 TERMINAL_CONSOLE_IN_EX_NOTIFY
,
978 TERMINAL_CONSOLE_IN_EX_NOTIFY_SIGNATURE
980 if (IsKeyRegistered (&CurrentNotify
->KeyData
, &KeyData
)) {
982 // The key notification function needs to run at TPL_CALLBACK
983 // while current TPL is TPL_NOTIFY. It will be invoked in
984 // KeyNotifyProcessHandler() which runs at TPL_CALLBACK.
986 EfiKeyFiFoForNotifyInsertOneKey (TerminalDevice
->EfiKeyFiFoForNotify
, Key
);
987 gBS
->SignalEvent (TerminalDevice
->KeyNotifyProcessEvent
);
990 if (IsEfiKeyFiFoFull (TerminalDevice
)) {
992 // Efi Key FIFO is full
997 CopyMem (&TerminalDevice
->EfiKeyFiFo
->Data
[Tail
], Key
, sizeof (EFI_INPUT_KEY
));
999 TerminalDevice
->EfiKeyFiFo
->Tail
= (UINT8
) ((Tail
+ 1) % (FIFO_MAX_NUMBER
+ 1));
1005 Remove one pre-fetched key out of the FIFO buffer.
1007 @param TerminalDevice Terminal driver private structure.
1008 @param Output The key will be removed.
1010 @retval TRUE If insert successfully.
1011 @retval FALSE If FIFO buffer is empty before remove operation.
1015 EfiKeyFiFoRemoveOneKey (
1016 TERMINAL_DEV
*TerminalDevice
,
1017 EFI_INPUT_KEY
*Output
1022 Head
= TerminalDevice
->EfiKeyFiFo
->Head
;
1023 ASSERT (Head
< FIFO_MAX_NUMBER
+ 1);
1025 if (IsEfiKeyFiFoEmpty (TerminalDevice
)) {
1029 Output
->ScanCode
= SCAN_NULL
;
1030 Output
->UnicodeChar
= 0;
1034 CopyMem (Output
, &TerminalDevice
->EfiKeyFiFo
->Data
[Head
], sizeof (EFI_INPUT_KEY
));
1036 TerminalDevice
->EfiKeyFiFo
->Head
= (UINT8
) ((Head
+ 1) % (FIFO_MAX_NUMBER
+ 1));
1042 Clarify whether FIFO buffer is empty.
1044 @param TerminalDevice Terminal driver private structure
1046 @retval TRUE If FIFO buffer is empty.
1047 @retval FALSE If FIFO buffer is not empty.
1052 TERMINAL_DEV
*TerminalDevice
1055 if (TerminalDevice
->EfiKeyFiFo
->Head
== TerminalDevice
->EfiKeyFiFo
->Tail
) {
1063 Clarify whether FIFO buffer is full.
1065 @param TerminalDevice Terminal driver private structure
1067 @retval TRUE If FIFO buffer is full.
1068 @retval FALSE If FIFO buffer is not full.
1073 TERMINAL_DEV
*TerminalDevice
1079 Tail
= TerminalDevice
->EfiKeyFiFo
->Tail
;
1080 Head
= TerminalDevice
->EfiKeyFiFo
->Head
;
1082 if (((Tail
+ 1) % (FIFO_MAX_NUMBER
+ 1)) == Head
) {
1091 Insert one pre-fetched key into the Unicode FIFO buffer.
1093 @param TerminalDevice Terminal driver private structure.
1094 @param Input The key will be input.
1096 @retval TRUE If insert successfully.
1097 @retval FALSE If Unicode FIFO buffer is full before key insertion,
1098 and the key is lost.
1102 UnicodeFiFoInsertOneKey (
1103 TERMINAL_DEV
*TerminalDevice
,
1109 Tail
= TerminalDevice
->UnicodeFiFo
->Tail
;
1110 ASSERT (Tail
< FIFO_MAX_NUMBER
+ 1);
1113 if (IsUnicodeFiFoFull (TerminalDevice
)) {
1115 // Unicode FIFO is full
1120 TerminalDevice
->UnicodeFiFo
->Data
[Tail
] = Input
;
1122 TerminalDevice
->UnicodeFiFo
->Tail
= (UINT8
) ((Tail
+ 1) % (FIFO_MAX_NUMBER
+ 1));
1128 Remove one pre-fetched key out of the Unicode FIFO buffer.
1129 The caller should guarantee that Unicode FIFO buffer is not empty
1130 by IsUnicodeFiFoEmpty ().
1132 @param TerminalDevice Terminal driver private structure.
1133 @param Output The key will be removed.
1137 UnicodeFiFoRemoveOneKey (
1138 TERMINAL_DEV
*TerminalDevice
,
1144 Head
= TerminalDevice
->UnicodeFiFo
->Head
;
1145 ASSERT (Head
< FIFO_MAX_NUMBER
+ 1);
1147 *Output
= TerminalDevice
->UnicodeFiFo
->Data
[Head
];
1149 TerminalDevice
->UnicodeFiFo
->Head
= (UINT8
) ((Head
+ 1) % (FIFO_MAX_NUMBER
+ 1));
1153 Clarify whether Unicode FIFO buffer is empty.
1155 @param TerminalDevice Terminal driver private structure
1157 @retval TRUE If Unicode FIFO buffer is empty.
1158 @retval FALSE If Unicode FIFO buffer is not empty.
1162 IsUnicodeFiFoEmpty (
1163 TERMINAL_DEV
*TerminalDevice
1166 if (TerminalDevice
->UnicodeFiFo
->Head
== TerminalDevice
->UnicodeFiFo
->Tail
) {
1174 Clarify whether Unicode FIFO buffer is full.
1176 @param TerminalDevice Terminal driver private structure
1178 @retval TRUE If Unicode FIFO buffer is full.
1179 @retval FALSE If Unicode FIFO buffer is not full.
1184 TERMINAL_DEV
*TerminalDevice
1190 Tail
= TerminalDevice
->UnicodeFiFo
->Tail
;
1191 Head
= TerminalDevice
->UnicodeFiFo
->Head
;
1193 if (((Tail
+ 1) % (FIFO_MAX_NUMBER
+ 1)) == Head
) {
1202 Count Unicode FIFO buffer.
1204 @param TerminalDevice Terminal driver private structure
1206 @return The count in bytes of Unicode FIFO.
1210 UnicodeFiFoGetKeyCount (
1211 TERMINAL_DEV
*TerminalDevice
1217 Tail
= TerminalDevice
->UnicodeFiFo
->Tail
;
1218 Head
= TerminalDevice
->UnicodeFiFo
->Head
;
1221 return (UINT8
) (Tail
- Head
);
1223 return (UINT8
) (Tail
+ FIFO_MAX_NUMBER
+ 1 - Head
);
1228 Update the Unicode characters from a terminal input device into EFI Keys FIFO.
1230 @param TerminalDevice The terminal device to use to translate raw input into EFI Keys
1234 UnicodeToEfiKeyFlushState (
1235 IN TERMINAL_DEV
*TerminalDevice
1241 InputState
= TerminalDevice
->InputState
;
1243 if (IsEfiKeyFiFoFull (TerminalDevice
)) {
1247 if ((InputState
& INPUT_STATE_ESC
) != 0) {
1248 Key
.ScanCode
= SCAN_ESC
;
1249 Key
.UnicodeChar
= 0;
1250 EfiKeyFiFoInsertOneKey (TerminalDevice
, &Key
);
1253 if ((InputState
& INPUT_STATE_CSI
) != 0) {
1254 Key
.ScanCode
= SCAN_NULL
;
1255 Key
.UnicodeChar
= CSI
;
1256 EfiKeyFiFoInsertOneKey (TerminalDevice
, &Key
);
1259 if ((InputState
& INPUT_STATE_LEFTOPENBRACKET
) != 0) {
1260 Key
.ScanCode
= SCAN_NULL
;
1261 Key
.UnicodeChar
= LEFTOPENBRACKET
;
1262 EfiKeyFiFoInsertOneKey (TerminalDevice
, &Key
);
1265 if ((InputState
& INPUT_STATE_O
) != 0) {
1266 Key
.ScanCode
= SCAN_NULL
;
1267 Key
.UnicodeChar
= 'O';
1268 EfiKeyFiFoInsertOneKey (TerminalDevice
, &Key
);
1271 if ((InputState
& INPUT_STATE_2
) != 0) {
1272 Key
.ScanCode
= SCAN_NULL
;
1273 Key
.UnicodeChar
= '2';
1274 EfiKeyFiFoInsertOneKey (TerminalDevice
, &Key
);
1278 // Cancel the timer.
1281 TerminalDevice
->TwoSecondTimeOut
,
1286 TerminalDevice
->InputState
= INPUT_STATE_DEFAULT
;
1291 Converts a stream of Unicode characters from a terminal input device into EFI Keys that
1292 can be read through the Simple Input Protocol.
1294 The table below shows the keyboard input mappings that this function supports.
1295 If the ESC sequence listed in one of the columns is presented, then it is translated
1296 into the corresponding EFI Scan Code. If a matching sequence is not found, then the raw
1297 key strokes are converted into EFI Keys.
1299 2 seconds are allowed for an ESC sequence to be completed. If the ESC sequence is not
1300 completed in 2 seconds, then the raw key strokes of the partial ESC sequence are
1301 converted into EFI Keys.
1302 There is one special input sequence that will force the system to reset.
1303 This is ESC R ESC r ESC R.
1305 Note: current implementation support terminal types include: PC ANSI, VT100+/VTUTF8, VT100.
1306 The table below is not same with UEFI Spec 2.3 Appendix B Table 201(not support ANSI X3.64 /
1307 DEC VT200-500 and extra support PC ANSI, VT100)since UEFI Table 201 is just an example.
1309 Symbols used in table below
1310 ===========================
1316 +=========+======+===========+==========+==========+
1317 | | EFI | UEFI 2.0 | | |
1318 | | Scan | | VT100+ | |
1319 | KEY | Code | PC ANSI | VTUTF8 | VT100 |
1320 +=========+======+===========+==========+==========+
1321 | NULL | 0x00 | | | |
1322 | UP | 0x01 | ESC [ A | ESC [ A | ESC [ A |
1323 | DOWN | 0x02 | ESC [ B | ESC [ B | ESC [ B |
1324 | RIGHT | 0x03 | ESC [ C | ESC [ C | ESC [ C |
1325 | LEFT | 0x04 | ESC [ D | ESC [ D | ESC [ D |
1326 | HOME | 0x05 | ESC [ H | ESC h | ESC [ H |
1327 | END | 0x06 | ESC [ F | ESC k | ESC [ K |
1328 | INSERT | 0x07 | ESC [ @ | ESC + | ESC [ @ |
1329 | | | ESC [ L | | ESC [ L |
1330 | DELETE | 0x08 | ESC [ X | ESC - | ESC [ P |
1331 | PG UP | 0x09 | ESC [ I | ESC ? | ESC [ V |
1333 | PG DOWN | 0x0A | ESC [ G | ESC / | ESC [ U |
1335 | F1 | 0x0B | ESC [ M | ESC 1 | ESC O P |
1336 | F2 | 0x0C | ESC [ N | ESC 2 | ESC O Q |
1337 | F3 | 0x0D | ESC [ O | ESC 3 | ESC O w |
1338 | F4 | 0x0E | ESC [ P | ESC 4 | ESC O x |
1339 | F5 | 0x0F | ESC [ Q | ESC 5 | ESC O t |
1340 | F6 | 0x10 | ESC [ R | ESC 6 | ESC O u |
1341 | F7 | 0x11 | ESC [ S | ESC 7 | ESC O q |
1342 | F8 | 0x12 | ESC [ T | ESC 8 | ESC O r |
1343 | F9 | 0x13 | ESC [ U | ESC 9 | ESC O p |
1344 | F10 | 0x14 | ESC [ V | ESC 0 | ESC O M |
1345 | Escape | 0x17 | ESC | ESC | ESC |
1346 | F11 | 0x15 | | ESC ! | |
1347 | F12 | 0x16 | | ESC @ | |
1348 +=========+======+===========+==========+==========+
1352 ESC R ESC r ESC R = Reset System
1354 @param TerminalDevice The terminal device to use to translate raw input into EFI Keys
1359 IN TERMINAL_DEV
*TerminalDevice
1363 EFI_STATUS TimerStatus
;
1366 BOOLEAN SetDefaultResetState
;
1368 TimerStatus
= gBS
->CheckEvent (TerminalDevice
->TwoSecondTimeOut
);
1370 if (!EFI_ERROR (TimerStatus
)) {
1371 UnicodeToEfiKeyFlushState (TerminalDevice
);
1372 TerminalDevice
->ResetState
= RESET_STATE_DEFAULT
;
1375 while (!IsUnicodeFiFoEmpty (TerminalDevice
) && !IsEfiKeyFiFoFull (TerminalDevice
)) {
1377 if (TerminalDevice
->InputState
!= INPUT_STATE_DEFAULT
) {
1379 // Check to see if the 2 seconds timer has expired
1381 TimerStatus
= gBS
->CheckEvent (TerminalDevice
->TwoSecondTimeOut
);
1382 if (!EFI_ERROR (TimerStatus
)) {
1383 UnicodeToEfiKeyFlushState (TerminalDevice
);
1384 TerminalDevice
->ResetState
= RESET_STATE_DEFAULT
;
1389 // Fetch one Unicode character from the Unicode FIFO
1391 UnicodeFiFoRemoveOneKey (TerminalDevice
, &UnicodeChar
);
1393 SetDefaultResetState
= TRUE
;
1395 switch (TerminalDevice
->InputState
) {
1396 case INPUT_STATE_DEFAULT
:
1400 case INPUT_STATE_ESC
:
1402 if (UnicodeChar
== LEFTOPENBRACKET
) {
1403 TerminalDevice
->InputState
|= INPUT_STATE_LEFTOPENBRACKET
;
1404 TerminalDevice
->ResetState
= RESET_STATE_DEFAULT
;
1408 if (UnicodeChar
== 'O' && (TerminalDevice
->TerminalType
== VT100TYPE
||
1409 TerminalDevice
->TerminalType
== TTYTERMTYPE
)) {
1410 TerminalDevice
->InputState
|= INPUT_STATE_O
;
1411 TerminalDevice
->ResetState
= RESET_STATE_DEFAULT
;
1415 Key
.ScanCode
= SCAN_NULL
;
1417 if (TerminalDevice
->TerminalType
== VT100PLUSTYPE
||
1418 TerminalDevice
->TerminalType
== VTUTF8TYPE
) {
1419 switch (UnicodeChar
) {
1421 Key
.ScanCode
= SCAN_F1
;
1424 Key
.ScanCode
= SCAN_F2
;
1427 Key
.ScanCode
= SCAN_F3
;
1430 Key
.ScanCode
= SCAN_F4
;
1433 Key
.ScanCode
= SCAN_F5
;
1436 Key
.ScanCode
= SCAN_F6
;
1439 Key
.ScanCode
= SCAN_F7
;
1442 Key
.ScanCode
= SCAN_F8
;
1445 Key
.ScanCode
= SCAN_F9
;
1448 Key
.ScanCode
= SCAN_F10
;
1451 Key
.ScanCode
= SCAN_F11
;
1454 Key
.ScanCode
= SCAN_F12
;
1457 Key
.ScanCode
= SCAN_HOME
;
1460 Key
.ScanCode
= SCAN_END
;
1463 Key
.ScanCode
= SCAN_INSERT
;
1466 Key
.ScanCode
= SCAN_DELETE
;
1469 Key
.ScanCode
= SCAN_PAGE_DOWN
;
1472 Key
.ScanCode
= SCAN_PAGE_UP
;
1479 switch (UnicodeChar
) {
1481 if (TerminalDevice
->ResetState
== RESET_STATE_DEFAULT
) {
1482 TerminalDevice
->ResetState
= RESET_STATE_ESC_R
;
1483 SetDefaultResetState
= FALSE
;
1484 } else if (TerminalDevice
->ResetState
== RESET_STATE_ESC_R_ESC_R
) {
1485 gRT
->ResetSystem (EfiResetWarm
, EFI_SUCCESS
, 0, NULL
);
1487 Key
.ScanCode
= SCAN_NULL
;
1490 if (TerminalDevice
->ResetState
== RESET_STATE_ESC_R
) {
1491 TerminalDevice
->ResetState
= RESET_STATE_ESC_R_ESC_R
;
1492 SetDefaultResetState
= FALSE
;
1494 Key
.ScanCode
= SCAN_NULL
;
1500 if (SetDefaultResetState
) {
1501 TerminalDevice
->ResetState
= RESET_STATE_DEFAULT
;
1504 if (Key
.ScanCode
!= SCAN_NULL
) {
1505 Key
.UnicodeChar
= 0;
1506 EfiKeyFiFoInsertOneKey (TerminalDevice
, &Key
);
1507 TerminalDevice
->InputState
= INPUT_STATE_DEFAULT
;
1508 UnicodeToEfiKeyFlushState (TerminalDevice
);
1512 UnicodeToEfiKeyFlushState (TerminalDevice
);
1516 case INPUT_STATE_ESC
| INPUT_STATE_O
:
1518 TerminalDevice
->ResetState
= RESET_STATE_DEFAULT
;
1520 Key
.ScanCode
= SCAN_NULL
;
1522 if (TerminalDevice
->TerminalType
== VT100TYPE
) {
1523 switch (UnicodeChar
) {
1525 Key
.ScanCode
= SCAN_F1
;
1528 Key
.ScanCode
= SCAN_F2
;
1531 Key
.ScanCode
= SCAN_F3
;
1534 Key
.ScanCode
= SCAN_F4
;
1537 Key
.ScanCode
= SCAN_F5
;
1540 Key
.ScanCode
= SCAN_F6
;
1543 Key
.ScanCode
= SCAN_F7
;
1546 Key
.ScanCode
= SCAN_F8
;
1549 Key
.ScanCode
= SCAN_F9
;
1552 Key
.ScanCode
= SCAN_F10
;
1557 } else if (TerminalDevice
->TerminalType
== TTYTERMTYPE
) {
1558 /* Also accept VT100 escape codes for F1-F4, HOME and END for TTY term */
1559 switch (UnicodeChar
) {
1561 Key
.ScanCode
= SCAN_F1
;
1564 Key
.ScanCode
= SCAN_F2
;
1567 Key
.ScanCode
= SCAN_F3
;
1570 Key
.ScanCode
= SCAN_F4
;
1573 Key
.ScanCode
= SCAN_HOME
;
1576 Key
.ScanCode
= SCAN_END
;
1581 if (Key
.ScanCode
!= SCAN_NULL
) {
1582 Key
.UnicodeChar
= 0;
1583 EfiKeyFiFoInsertOneKey (TerminalDevice
, &Key
);
1584 TerminalDevice
->InputState
= INPUT_STATE_DEFAULT
;
1585 UnicodeToEfiKeyFlushState (TerminalDevice
);
1589 UnicodeToEfiKeyFlushState (TerminalDevice
);
1593 case INPUT_STATE_ESC
| INPUT_STATE_LEFTOPENBRACKET
:
1595 TerminalDevice
->ResetState
= RESET_STATE_DEFAULT
;
1597 Key
.ScanCode
= SCAN_NULL
;
1599 if (TerminalDevice
->TerminalType
== PCANSITYPE
||
1600 TerminalDevice
->TerminalType
== VT100TYPE
||
1601 TerminalDevice
->TerminalType
== VT100PLUSTYPE
||
1602 TerminalDevice
->TerminalType
== VTUTF8TYPE
||
1603 TerminalDevice
->TerminalType
== TTYTERMTYPE
) {
1604 switch (UnicodeChar
) {
1606 Key
.ScanCode
= SCAN_UP
;
1609 Key
.ScanCode
= SCAN_DOWN
;
1612 Key
.ScanCode
= SCAN_RIGHT
;
1615 Key
.ScanCode
= SCAN_LEFT
;
1618 if (TerminalDevice
->TerminalType
== PCANSITYPE
||
1619 TerminalDevice
->TerminalType
== VT100TYPE
||
1620 TerminalDevice
->TerminalType
== TTYTERMTYPE
) {
1621 Key
.ScanCode
= SCAN_HOME
;
1625 if (TerminalDevice
->TerminalType
== PCANSITYPE
||
1626 TerminalDevice
->TerminalType
== TTYTERMTYPE
) {
1627 Key
.ScanCode
= SCAN_END
;
1631 if (TerminalDevice
->TerminalType
== VT100TYPE
) {
1632 Key
.ScanCode
= SCAN_END
;
1637 if (TerminalDevice
->TerminalType
== PCANSITYPE
||
1638 TerminalDevice
->TerminalType
== VT100TYPE
) {
1639 Key
.ScanCode
= SCAN_INSERT
;
1643 if (TerminalDevice
->TerminalType
== PCANSITYPE
) {
1644 Key
.ScanCode
= SCAN_DELETE
;
1648 if (TerminalDevice
->TerminalType
== VT100TYPE
) {
1649 Key
.ScanCode
= SCAN_DELETE
;
1650 } else if (TerminalDevice
->TerminalType
== PCANSITYPE
) {
1651 Key
.ScanCode
= SCAN_F4
;
1655 if (TerminalDevice
->TerminalType
== PCANSITYPE
) {
1656 Key
.ScanCode
= SCAN_PAGE_UP
;
1660 if (TerminalDevice
->TerminalType
== PCANSITYPE
) {
1661 Key
.ScanCode
= SCAN_F10
;
1665 if (TerminalDevice
->TerminalType
== VT100TYPE
) {
1666 Key
.ScanCode
= SCAN_PAGE_UP
;
1670 if (TerminalDevice
->TerminalType
== PCANSITYPE
) {
1671 Key
.ScanCode
= SCAN_PAGE_DOWN
;
1675 if (TerminalDevice
->TerminalType
== PCANSITYPE
) {
1676 Key
.ScanCode
= SCAN_F9
;
1680 if (TerminalDevice
->TerminalType
== VT100TYPE
) {
1681 Key
.ScanCode
= SCAN_PAGE_DOWN
;
1685 if (TerminalDevice
->TerminalType
== PCANSITYPE
) {
1686 Key
.ScanCode
= SCAN_F1
;
1690 if (TerminalDevice
->TerminalType
== PCANSITYPE
) {
1691 Key
.ScanCode
= SCAN_F2
;
1695 if (TerminalDevice
->TerminalType
== PCANSITYPE
) {
1696 Key
.ScanCode
= SCAN_F3
;
1700 if (TerminalDevice
->TerminalType
== PCANSITYPE
) {
1701 Key
.ScanCode
= SCAN_F5
;
1705 if (TerminalDevice
->TerminalType
== PCANSITYPE
) {
1706 Key
.ScanCode
= SCAN_F6
;
1710 if (TerminalDevice
->TerminalType
== PCANSITYPE
) {
1711 Key
.ScanCode
= SCAN_F7
;
1715 if (TerminalDevice
->TerminalType
== PCANSITYPE
) {
1716 Key
.ScanCode
= SCAN_F8
;
1725 * The VT220 escape codes that the TTY terminal accepts all have
1726 * numeric codes, and there are no ambiguous prefixes shared with
1727 * other terminal types.
1729 if (TerminalDevice
->TerminalType
== TTYTERMTYPE
&&
1730 Key
.ScanCode
== SCAN_NULL
&&
1731 UnicodeChar
>= '0' &&
1732 UnicodeChar
<= '9') {
1733 TerminalDevice
->TtyEscapeStr
[0] = UnicodeChar
;
1734 TerminalDevice
->TtyEscapeIndex
= 1;
1735 TerminalDevice
->InputState
|= INPUT_STATE_LEFTOPENBRACKET_2
;
1739 if (Key
.ScanCode
!= SCAN_NULL
) {
1740 Key
.UnicodeChar
= 0;
1741 EfiKeyFiFoInsertOneKey (TerminalDevice
, &Key
);
1742 TerminalDevice
->InputState
= INPUT_STATE_DEFAULT
;
1743 UnicodeToEfiKeyFlushState (TerminalDevice
);
1747 UnicodeToEfiKeyFlushState (TerminalDevice
);
1752 case INPUT_STATE_ESC
| INPUT_STATE_LEFTOPENBRACKET
| INPUT_STATE_LEFTOPENBRACKET_2
:
1754 * Here we handle the VT220 escape codes that we accept. This
1755 * state is only used by the TTY terminal type.
1757 Key
.ScanCode
= SCAN_NULL
;
1758 if (TerminalDevice
->TerminalType
== TTYTERMTYPE
) {
1760 if (UnicodeChar
== '~' && TerminalDevice
->TtyEscapeIndex
<= 2) {
1762 TerminalDevice
->TtyEscapeStr
[TerminalDevice
->TtyEscapeIndex
] = 0; /* Terminate string */
1763 EscCode
= (UINT16
) StrDecimalToUintn(TerminalDevice
->TtyEscapeStr
);
1766 Key
.ScanCode
= SCAN_INSERT
;
1769 Key
.ScanCode
= SCAN_DELETE
;
1772 Key
.ScanCode
= SCAN_PAGE_UP
;
1775 Key
.ScanCode
= SCAN_PAGE_DOWN
;
1782 Key
.ScanCode
= SCAN_F1
+ EscCode
- 11;
1789 Key
.ScanCode
= SCAN_F6
+ EscCode
- 17;
1793 Key
.ScanCode
= SCAN_F11
+ EscCode
- 23;
1798 } else if (TerminalDevice
->TtyEscapeIndex
== 1){
1799 /* 2 character escape code */
1800 TerminalDevice
->TtyEscapeStr
[TerminalDevice
->TtyEscapeIndex
++] = UnicodeChar
;
1804 DEBUG ((EFI_D_ERROR
, "Unexpected state in escape2\n"));
1807 TerminalDevice
->ResetState
= RESET_STATE_DEFAULT
;
1809 if (Key
.ScanCode
!= SCAN_NULL
) {
1810 Key
.UnicodeChar
= 0;
1811 EfiKeyFiFoInsertOneKey (TerminalDevice
, &Key
);
1812 TerminalDevice
->InputState
= INPUT_STATE_DEFAULT
;
1813 UnicodeToEfiKeyFlushState (TerminalDevice
);
1817 UnicodeToEfiKeyFlushState (TerminalDevice
);
1822 // Invalid state. This should never happen.
1826 UnicodeToEfiKeyFlushState (TerminalDevice
);
1831 if (UnicodeChar
== ESC
) {
1832 TerminalDevice
->InputState
= INPUT_STATE_ESC
;
1835 if (UnicodeChar
== CSI
) {
1836 TerminalDevice
->InputState
= INPUT_STATE_CSI
;
1839 if (TerminalDevice
->InputState
!= INPUT_STATE_DEFAULT
) {
1840 Status
= gBS
->SetTimer(
1841 TerminalDevice
->TwoSecondTimeOut
,
1845 ASSERT_EFI_ERROR (Status
);
1849 if (SetDefaultResetState
) {
1850 TerminalDevice
->ResetState
= RESET_STATE_DEFAULT
;
1853 if (UnicodeChar
== DEL
) {
1854 if (TerminalDevice
->TerminalType
== TTYTERMTYPE
) {
1855 Key
.ScanCode
= SCAN_NULL
;
1856 Key
.UnicodeChar
= CHAR_BACKSPACE
;
1859 Key
.ScanCode
= SCAN_DELETE
;
1860 Key
.UnicodeChar
= 0;
1863 Key
.ScanCode
= SCAN_NULL
;
1864 Key
.UnicodeChar
= UnicodeChar
;
1867 EfiKeyFiFoInsertOneKey (TerminalDevice
, &Key
);