📄 keyboard.c
字号:
UsbKeyboardDevice->LastKeyCodeArray[i] = CurKeyCodeBuffer[i];
}
//
// pre-process KeyboardBuffer, pop out the ctrl,alt,del key in sequence
// and judge whether it will invoke reset event.
//
SavedTail = UsbKeyboardDevice->KeyboardBuffer.bTail;
i = UsbKeyboardDevice->KeyboardBuffer.bHead;
while(i != SavedTail) {
RemoveKeyCode(&(UsbKeyboardDevice->KeyboardBuffer),&UsbKey);
switch(UsbKey.KeyCode) {
case 0xe0:
case 0xe4:
if(UsbKey.Down) {
UsbKeyboardDevice->CtrlOn = 1;
} else {
UsbKeyboardDevice->CtrlOn = 0;
}
break;
case 0xe2:
case 0xe6:
if(UsbKey.Down) {
UsbKeyboardDevice->AltOn = 1;
} else {
UsbKeyboardDevice->AltOn = 0;
}
break;
case 0x4c: // Del Key Code
case 0x63:
if(UsbKey.Down) {
if(UsbKeyboardDevice->CtrlOn && UsbKeyboardDevice->AltOn) {
gRT->ResetSystem(EfiResetWarm, EFI_SUCCESS, 0, NULL);
}
}
break;
default:
break;
}
//
// insert the key back to the buffer.
// so the key sequence will not be destroyed.
//
InsertKeyCode(&(UsbKeyboardDevice->KeyboardBuffer),
UsbKey.KeyCode,
UsbKey.Down
);
i = UsbKeyboardDevice->KeyboardBuffer.bHead;
}
//
// If have new key pressed, update the RepeatKey value, and set the
// timer to repeate delay timer
//
if(NewRepeatKey != 0) {
//
// sets trigger time to "Repeat Delay Time",
// to trigger the repeat timer when the key is hold long
// enough time.
//
gBS->SetTimer(UsbKeyboardDevice->RepeatTimer,
TimerRelative,
USBKBD_REPEAT_DELAY
);
UsbKeyboardDevice->RepeatKey = NewRepeatKey;
}
return EFI_SUCCESS;
}
EFI_STATUS
USBParseKey(
IN OUT USB_KB_DEV *UsbKeyboardDevice,
OUT UINT8 *KeyChar
)
/*++
Routine Description:
Retrieves a key character after parsing the raw data in keyboard buffer.
Arguments:
UsbKeyboardDevice: The USB_KB_DEV instance.
KeyChar: Points to the Key character after key parsing.
Returns:
--*/
{
USB_KEY UsbKey;
*KeyChar = 0;
while (!IsUSBKeyboardBufferEmpty(UsbKeyboardDevice->KeyboardBuffer)) {
//
// pops one raw data off.
//
RemoveKeyCode(&(UsbKeyboardDevice->KeyboardBuffer),&UsbKey);
if (!UsbKey.Down) {
switch(UsbKey.KeyCode) {
case 0xe0: // fall through
case 0xe4:
UsbKeyboardDevice->CtrlOn = 0;
break;
case 0xe1: // fall through
case 0xe5:
UsbKeyboardDevice->ShiftOn = 0;
break;
case 0xe2: // fall through
case 0xe6:
UsbKeyboardDevice->AltOn = 0;
break;
default:
break;
}
continue;
}
//
// Analyzes key pressing situation
//
switch (UsbKey.KeyCode) {
case 0xe0: // fall through
case 0xe4:
UsbKeyboardDevice->CtrlOn = 1;
continue;
break;
case 0xe1: // fall through
case 0xe5:
UsbKeyboardDevice->ShiftOn = 1;
continue;
break;
case 0xe2: // fall through
case 0xe6:
UsbKeyboardDevice->AltOn = 1;
continue;
break;
case 0xe3: // fall through
case 0xe7:
continue;
break;
case 0x53:
UsbKeyboardDevice->NumLockOn ^= 1;
SetKeyLED(UsbKeyboardDevice);
continue;
break;
case 0x39:
UsbKeyboardDevice->CapsOn ^= 1;
SetKeyLED(UsbKeyboardDevice);
continue;
break;
//
// F11,F12,PrintScreen,ScrollLock,Pause,Application,Power
// keys are not valid EFI key
//
case 0x44: // fall through
case 0x45: // fall through
case 0x46: // fall through
case 0x47: // fall through
case 0x48: // fall through
case 0x65: // fall through
case 0x66:
continue;
break;
default:
break;
}
//
// When encountered Del Key...
//
if (UsbKey.KeyCode == 0x4c || UsbKey.KeyCode == 0x63) {
if(UsbKeyboardDevice->CtrlOn && UsbKeyboardDevice->AltOn) {
gRT->ResetSystem(EfiResetWarm, EFI_SUCCESS, 0, NULL);
}
}
*KeyChar = UsbKey.KeyCode;
return EFI_SUCCESS;
}
return EFI_NOT_READY;
}
EFI_STATUS
USBKeyCodeToEFIScanCode(
IN USB_KB_DEV *UsbKeyboardDevice,
IN UINT8 KeyChar,
OUT EFI_INPUT_KEY *Key
)
/*++
Routine Description:
Converts USB Keyboard code to EFI Scan Code.
Arguments:
UsbKeyboardDevice: The USB_KB_DEV instance.
KeyChar: Indicates the key code that will be interpreted.
Key: A pointer to a buffer that is filled in with
the keystroke information for the key that
was pressed.
Returns:
--*/
{
UINT8 Index;
if (!USBKBD_VALID_KEYCODE(KeyChar)) {
return EFI_NOT_READY;
}
//
// valid USB Key Code starts from 4
//
Index = (UINT8)(KeyChar - 4);
if (Index >= USB_KEYCODE_MAX_MAKE){
return EFI_NOT_READY;
}
Key->ScanCode = KeyConvertionTable[Index][0];
if (UsbKeyboardDevice->ShiftOn) {
Key->UnicodeChar = KeyConvertionTable[Index][2];
} else {
Key->UnicodeChar = KeyConvertionTable[Index][1];
}
if (UsbKeyboardDevice->CapsOn) {
if (Key->UnicodeChar >= 'a' && Key->UnicodeChar <= 'z') {
Key->UnicodeChar = KeyConvertionTable[Index][2];
} else if (Key->UnicodeChar >= 'A' && Key->UnicodeChar <= 'Z') {
Key->UnicodeChar = KeyConvertionTable[Index][1];
}
}
if (KeyChar >= 0x59 && KeyChar <=0x63 && Key->ScanCode != SCAN_NULL) {
if (UsbKeyboardDevice->NumLockOn && !UsbKeyboardDevice->ShiftOn) {
Key->ScanCode = SCAN_NULL;
} else {
Key->UnicodeChar = 0x00;
}
}
if(Key->UnicodeChar == 0 && Key->ScanCode == SCAN_NULL) {
return EFI_NOT_READY;
}
return EFI_SUCCESS;
}
EFI_STATUS
InitUSBKeyBuffer(
IN OUT USB_KB_BUFFER *KeyboardBuffer
)
/*++
Routine Description:
Resets USB Keyboard Buffer.
Arguments:
KeyboardBuffer: Points to the USB Keyboard Buffer.
Returns:
--*/
{
EfiZeroMem(KeyboardBuffer,sizeof(USB_KB_BUFFER));
KeyboardBuffer->bHead = KeyboardBuffer->bTail;
return EFI_SUCCESS;
}
BOOLEAN
IsUSBKeyboardBufferEmpty(
IN USB_KB_BUFFER KeyboardBuffer
)
/*++
Routine Description:
Check whether USB Keyboard buffer is empty.
Arguments:
KeyboardBuffer: USB Keyboard Buffer.
Returns:
--*/
{
//
// meet FIFO empty condition
//
return (BOOLEAN)(KeyboardBuffer.bHead == KeyboardBuffer.bTail);
}
BOOLEAN
IsUSBKeyboardBufferFull(
IN USB_KB_BUFFER KeyboardBuffer
)
/*++
Routine Description:
Check whether USB Keyboard buffer is full.
Arguments:
KeyboardBuffer: USB Keyboard Buffer.
Returns:
--*/
{
return (BOOLEAN)(((KeyboardBuffer.bTail + 1) % (MAX_KEY_ALLOWED + 1)) ==
KeyboardBuffer.bHead);
}
EFI_STATUS
InsertKeyCode(
IN OUT USB_KB_BUFFER *KeyboardBuffer,
IN UINT8 Key,
IN UINT8 Down
)
/*++
Routine Description:
Inserts a key code into keyboard buffer.
Arguments:
KeyboardBuffer: Points to the USB Keyboard Buffer.
Returns:
--*/
{
USB_KEY UsbKey;
//
// if keyboard buffer is full, throw the
// first key out of the keyboard buffer.
//
if (IsUSBKeyboardBufferFull (*KeyboardBuffer)) {
RemoveKeyCode(KeyboardBuffer,&UsbKey);
}
KeyboardBuffer->buffer[KeyboardBuffer->bTail].KeyCode = Key;
KeyboardBuffer->buffer[KeyboardBuffer->bTail].Down = Down;
//
// adjust the tail pointer of the FIFO keyboard buffer.
//
KeyboardBuffer->bTail = (UINT8)((KeyboardBuffer->bTail + 1)
% (MAX_KEY_ALLOWED + 1)) ;
return EFI_SUCCESS;
}
EFI_STATUS
RemoveKeyCode(
IN OUT USB_KB_BUFFER *KeyboardBuffer,
OUT USB_KEY *UsbKey
)
/*++
Routine Description:
Pops a key code off from keyboard buffer.
Arguments:
KeyboardBuffer: Points to the USB Keyboard Buffer.
UsbKey: Points to the buffer that contains a usb key code.
Returns:
--*/
{
if (IsUSBKeyboardBufferEmpty (*KeyboardBuffer)) {
return EFI_DEVICE_ERROR;
}
UsbKey->KeyCode = KeyboardBuffer->buffer[KeyboardBuffer->bHead].KeyCode;
UsbKey->Down = KeyboardBuffer->buffer[KeyboardBuffer->bHead].Down;
//
// adjust the head pointer of the FIFO keyboard buffer.
//
KeyboardBuffer->bHead = (UINT8)((KeyboardBuffer->bHead + 1) %
(MAX_KEY_ALLOWED + 1)) ;
return EFI_SUCCESS;
}
EFI_STATUS
SetKeyLED(
IN USB_KB_DEV *UsbKeyboardDevice
)
/*++
Routine Description:
Sets USB Keyboard LED state.
Arguments:
UsbKeyboardDevice: The USB_KB_DEV instance.
Returns:
--*/
{
LED_MAP Led;
UINT8 ReportId;
//
// Set each field in Led map.
//
Led.NumLock = (UINT8)UsbKeyboardDevice->NumLockOn;
Led.CapsLock = (UINT8)UsbKeyboardDevice->CapsOn;
Led.Resrvd = 0;
ReportId = 0;
//
// call Set Report Request to lighten the LED.
//
UsbSetReportRequest (
UsbKeyboardDevice->UsbIo,
UsbKeyboardDevice->InterfaceDescriptor.InterfaceNumber,
ReportId,
HID_OUTPUT_REPORT,
1,
(CHAR8 *)&Led
);
return EFI_SUCCESS;
}
VOID
USBKeyboardRepeatHandler(
IN EFI_EVENT Event,
IN VOID *Context
)
/*++
Routine Description:
Timer handler for Repeat Key timer.
Arguments:
Event: The Repeat Key event.
Context: Points to the USB_KB_DEV instance.
Returns:
--*/
{
USB_KB_DEV *UsbKeyboardDevice;
UsbKeyboardDevice = (USB_KB_DEV*)Context;
//
// Do nothing when there is no repeat key.
//
if(UsbKeyboardDevice->RepeatKey != 0) {
//
// Inserts one Repeat key into keyboard buffer,
//
InsertKeyCode(
&(UsbKeyboardDevice->KeyboardBuffer),
UsbKeyboardDevice->RepeatKey,
1
);
//
// set repeate rate for repeat key generation.
//
gBS->SetTimer(UsbKeyboardDevice->RepeatTimer,
TimerRelative,
USBKBD_REPEAT_RATE
) ;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -