Add USB arrow key support
Since SBL shell added support for command line history. It is required to support it from USB keyboard console as well. This patch added USB keyboard arrow key handling to convert arrow key scan code into ANSI escape sequence so that Shell can recognize the arrow key from keyboard. Signed-off-by: Maurice Ma <maurice.ma@intel.com>
This commit is contained in:
parent
94a477902b
commit
d74c294506
|
@ -9,10 +9,13 @@
|
|||
#include <UsbKbLibInternal.h>
|
||||
#include <Library/TimeStampLib.h>
|
||||
|
||||
#define ARROW_KEY_MODIFIER 0x1000
|
||||
|
||||
CONST CHAR8 *mKeyboardKeyMap[] = {
|
||||
"abcdefghijklmnopqrstuvwxyz1234567890\r\x1b\b\t -=[]\\ ;'`,./",
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$%^&*()\r\x1b\b\t _+{}| :\"~<>?",
|
||||
"/*-+\r1234567890."
|
||||
"/*-+\r1234567890.",
|
||||
"CDBA"
|
||||
};
|
||||
|
||||
USB_KB_DEV mUsbKbDevice;
|
||||
|
@ -489,6 +492,44 @@ CheckQueue (
|
|||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Enqueue the key.
|
||||
|
||||
@param Queue The queue to be enqueued.
|
||||
@param Char The key data to be enqueued.
|
||||
|
||||
@retval EFI_NOT_READY The queue is full.
|
||||
@retval EFI_UNSUPPORTED The char is invalid.
|
||||
@retval EFI_SUCCESS Successfully enqueued the key data.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EnqueueChar (
|
||||
IN SIMPLE_QUEUE *Queue,
|
||||
IN CHAR16 Char
|
||||
)
|
||||
{
|
||||
CHAR16 Modifier;
|
||||
CHAR8 AnsiChar;
|
||||
EFI_STATUS Status;
|
||||
|
||||
Status = EFI_UNSUPPORTED;
|
||||
Modifier = Char & 0xFF00;
|
||||
AnsiChar = (CHAR8)Char;
|
||||
if (Modifier == 0) {
|
||||
if (AnsiChar > 0) {
|
||||
Status = Enqueue (Queue, AnsiChar);
|
||||
}
|
||||
} else if (Modifier == ARROW_KEY_MODIFIER) {
|
||||
// Convert arrow key to ANSI escape sequence
|
||||
Enqueue (Queue, '\x1b');
|
||||
Enqueue (Queue, '[');
|
||||
Status = Enqueue (Queue, AnsiChar);
|
||||
}
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Return queue length.
|
||||
|
||||
|
@ -522,7 +563,7 @@ GetQueueLength (
|
|||
@retval The ascii for the key code.
|
||||
|
||||
**/
|
||||
CHAR8
|
||||
CHAR16
|
||||
ConvertKeyToAscii (
|
||||
IN UINT8 Modifier,
|
||||
IN UINT8 Key
|
||||
|
@ -547,6 +588,11 @@ ConvertKeyToAscii (
|
|||
}
|
||||
}
|
||||
|
||||
if (Key >= 0x4F && Key <= 0x52) {
|
||||
// Arrow key
|
||||
return ARROW_KEY_MODIFIER | mKeyboardKeyMap[3][Key - 0x4F];
|
||||
}
|
||||
|
||||
if (Key == 0x53) {
|
||||
// Num Lock
|
||||
mUsbKbDevice.NumLockOn = mUsbKbDevice.NumLockOn ? FALSE : TRUE;
|
||||
|
@ -580,7 +626,7 @@ KeyboardPoll (
|
|||
EFI_STATUS Status;
|
||||
USB_KB_DEV *UsbKbDevice;
|
||||
UINT8 KeyBuf[8];
|
||||
CHAR8 Char;
|
||||
CHAR16 Char;
|
||||
UINTN DataSize;
|
||||
UINTN Index;
|
||||
UINTN Index2;
|
||||
|
@ -682,7 +728,7 @@ KeyboardPoll (
|
|||
if (KeyPress) {
|
||||
Char = ConvertKeyToAscii (CurKeyCodeBuffer[0], CurKeyCodeBuffer[Index]);
|
||||
if (Char > 0) {
|
||||
Enqueue (&UsbKbDevice->Queue, Char);
|
||||
EnqueueChar (&UsbKbDevice->Queue, Char);
|
||||
// Prepare new repeat key, and clear the original one.
|
||||
UsbKbDevice->RepeatCounter = 0;
|
||||
UsbKbDevice->RepeatChar = Char;
|
||||
|
@ -710,7 +756,7 @@ KeyboardPoll (
|
|||
if (UsbKbDevice->RepeatCounter < KEY_REPEAT_DELAY) {
|
||||
UsbKbDevice->RepeatCounter++;
|
||||
} else {
|
||||
Enqueue (&UsbKbDevice->Queue, UsbKbDevice->RepeatChar);
|
||||
EnqueueChar (&UsbKbDevice->Queue, UsbKbDevice->RepeatChar);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
|
||||
#define USB_KB_DEVICE_SIG SIGNATURE_32 ('U', 'S', 'K', 'B')
|
||||
|
||||
#define QUEUE_MAX_COUNT 32
|
||||
#define QUEUE_MAX_COUNT 64
|
||||
#define KEY_REPEAT_DELAY 10
|
||||
|
||||
#define USBKBD_VALID_KEYCODE(Key) ((UINT8) (Key) > 3)
|
||||
|
@ -51,8 +51,8 @@ typedef struct {
|
|||
BOOLEAN ScrollOn;
|
||||
SIMPLE_QUEUE Queue;
|
||||
UINT32 RepeatCounter;
|
||||
CHAR16 RepeatChar;
|
||||
UINT8 RepeatKey;
|
||||
CHAR8 RepeatChar;
|
||||
UINT8 LastKeyCodeArray[8];
|
||||
UINT32 TimeStampFreqKhz;
|
||||
UINT64 LastTransferTimeStamp;
|
||||
|
|
Loading…
Reference in New Issue