mirror of https://github.com/acidanthera/audk.git
Fix the terminal driver to call hotkey callback even no one is calling ReadKeyStroke
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@11562 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
66fe714632
commit
f0368006b0
|
@ -2,7 +2,7 @@
|
|||
Produces Simple Text Input Protocol, Simple Text Input Extended Protocol and
|
||||
Simple Text Output Protocol upon Serial IO Protocol.
|
||||
|
||||
Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
|
||||
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
|
||||
|
@ -75,6 +75,7 @@ TERMINAL_DEV mTerminalDevTemplate = {
|
|||
NULL, // EfiKeyFiFo
|
||||
|
||||
NULL, // ControllerNameTable
|
||||
NULL, // TimerEvent
|
||||
NULL, // TwoSecondTimeOut
|
||||
INPUT_STATE_DEFAULT,
|
||||
RESET_STATE_DEFAULT,
|
||||
|
@ -648,7 +649,7 @@ TerminalDriverBindingStart (
|
|||
EVT_NOTIFY_WAIT,
|
||||
TPL_NOTIFY,
|
||||
TerminalConInWaitForKeyEx,
|
||||
&TerminalDevice->SimpleInputEx,
|
||||
TerminalDevice,
|
||||
&TerminalDevice->SimpleInputEx.WaitForKeyEx
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
|
@ -659,7 +660,7 @@ TerminalDriverBindingStart (
|
|||
EVT_NOTIFY_WAIT,
|
||||
TPL_NOTIFY,
|
||||
TerminalConInWaitForKey,
|
||||
&TerminalDevice->SimpleInput,
|
||||
TerminalDevice,
|
||||
&TerminalDevice->SimpleInput.WaitForKey
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
|
@ -842,6 +843,22 @@ TerminalDriverBindingStart (
|
|||
goto ReportError;
|
||||
}
|
||||
|
||||
Status = gBS->CreateEvent (
|
||||
EVT_TIMER | EVT_NOTIFY_SIGNAL,
|
||||
TPL_NOTIFY,
|
||||
TerminalConInTimerHandler,
|
||||
TerminalDevice,
|
||||
&TerminalDevice->TimerEvent
|
||||
);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
Status = gBS->SetTimer (
|
||||
TerminalDevice->TimerEvent,
|
||||
TimerPeriodic,
|
||||
KEYBOARD_TIMER_INTERVAL
|
||||
);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
Status = gBS->CreateEvent (
|
||||
EVT_TIMER,
|
||||
TPL_CALLBACK,
|
||||
|
@ -849,6 +866,7 @@ TerminalDriverBindingStart (
|
|||
NULL,
|
||||
&TerminalDevice->TwoSecondTimeOut
|
||||
);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
Status = gBS->InstallProtocolInterface (
|
||||
&TerminalDevice->Handle,
|
||||
|
@ -1052,6 +1070,10 @@ Error:
|
|||
gBS->CloseEvent (TerminalDevice->TwoSecondTimeOut);
|
||||
}
|
||||
|
||||
if (TerminalDevice->TimerEvent != NULL) {
|
||||
gBS->CloseEvent (TerminalDevice->TimerEvent);
|
||||
}
|
||||
|
||||
if (TerminalDevice->SimpleInput.WaitForKey != NULL) {
|
||||
gBS->CloseEvent (TerminalDevice->SimpleInput.WaitForKey);
|
||||
}
|
||||
|
@ -1245,6 +1267,7 @@ TerminalDriverBindingStop (
|
|||
FreeUnicodeStringTable (TerminalDevice->ControllerNameTable);
|
||||
}
|
||||
|
||||
gBS->CloseEvent (TerminalDevice->TimerEvent);
|
||||
gBS->CloseEvent (TerminalDevice->TwoSecondTimeOut);
|
||||
gBS->CloseEvent (TerminalDevice->SimpleInput.WaitForKey);
|
||||
gBS->CloseEvent (TerminalDevice->SimpleInputEx.WaitForKeyEx);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/** @file
|
||||
Header file for Terminal driver.
|
||||
|
||||
Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
|
||||
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
|
||||
|
@ -61,6 +61,8 @@ typedef struct {
|
|||
EFI_INPUT_KEY Data[FIFO_MAX_NUMBER + 1];
|
||||
} EFI_KEY_FIFO;
|
||||
|
||||
#define KEYBOARD_TIMER_INTERVAL 200000 // 0.02s
|
||||
|
||||
#define TERMINAL_DEV_SIGNATURE SIGNATURE_32 ('t', 'm', 'n', 'l')
|
||||
|
||||
#define TERMINAL_CONSOLE_IN_EX_NOTIFY_SIGNATURE SIGNATURE_32 ('t', 'm', 'e', 'n')
|
||||
|
@ -86,6 +88,7 @@ typedef struct {
|
|||
UNICODE_FIFO *UnicodeFiFo;
|
||||
EFI_KEY_FIFO *EfiKeyFiFo;
|
||||
EFI_UNICODE_STRING_TABLE *ControllerNameTable;
|
||||
EFI_EVENT TimerEvent;
|
||||
EFI_EVENT TwoSecondTimeOut;
|
||||
UINT32 InputState;
|
||||
UINT32 ResetState;
|
||||
|
@ -954,7 +957,7 @@ IsRawFiFoFull (
|
|||
BOOLEAN
|
||||
EfiKeyFiFoInsertOneKey (
|
||||
TERMINAL_DEV *TerminalDevice,
|
||||
EFI_INPUT_KEY Key
|
||||
EFI_INPUT_KEY *Key
|
||||
);
|
||||
|
||||
/**
|
||||
|
@ -1348,4 +1351,16 @@ IsHotPlugDevice (
|
|||
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
|
||||
);
|
||||
|
||||
/**
|
||||
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
|
||||
);
|
||||
#endif
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/** @file
|
||||
Implementation for EFI_SIMPLE_TEXT_INPUT_PROTOCOL protocol.
|
||||
|
||||
Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
|
||||
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
|
||||
|
@ -26,8 +26,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|||
|
||||
@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.
|
||||
|
||||
**/
|
||||
|
@ -37,26 +35,10 @@ ReadKeyStrokeWorker (
|
|||
OUT EFI_KEY_DATA *KeyData
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
LIST_ENTRY *Link;
|
||||
LIST_ENTRY *NotifyList;
|
||||
TERMINAL_CONSOLE_IN_EX_NOTIFY *CurrentNotify;
|
||||
|
||||
if (KeyData == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
//
|
||||
// Initialize *Key to nonsense value.
|
||||
//
|
||||
KeyData->Key.ScanCode = SCAN_NULL;
|
||||
KeyData->Key.UnicodeChar = 0;
|
||||
|
||||
Status = TerminalConInCheckForKey (&TerminalDevice->SimpleInput);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return EFI_NOT_READY;
|
||||
}
|
||||
|
||||
if (!EfiKeyFiFoRemoveOneKey (TerminalDevice, &KeyData->Key)) {
|
||||
return EFI_NOT_READY;
|
||||
}
|
||||
|
@ -64,21 +46,6 @@ ReadKeyStrokeWorker (
|
|||
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);
|
||||
}
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
|
||||
|
@ -226,12 +193,7 @@ TerminalConInWaitForKeyEx (
|
|||
IN VOID *Context
|
||||
)
|
||||
{
|
||||
TERMINAL_DEV *TerminalDevice;
|
||||
|
||||
TerminalDevice = TERMINAL_CON_IN_EX_DEV_FROM_THIS (Context);
|
||||
|
||||
TerminalConInWaitForKey (Event, &TerminalDevice->SimpleInput);
|
||||
|
||||
TerminalConInWaitForKey (Event, Context);
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -532,43 +494,37 @@ TerminalConInWaitForKey (
|
|||
// Someone is waiting on the keystroke event, if there's
|
||||
// a key pending, signal the event
|
||||
//
|
||||
// Context is the pointer to EFI_SIMPLE_TEXT_INPUT_PROTOCOL
|
||||
//
|
||||
if (!EFI_ERROR (TerminalConInCheckForKey (Context))) {
|
||||
if (!IsEfiKeyFiFoEmpty ((TERMINAL_DEV *) Context)) {
|
||||
|
||||
gBS->SignalEvent (Event);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Check for a pending key in the Efi Key FIFO or Serial device buffer.
|
||||
|
||||
@param This Indicates the calling context.
|
||||
|
||||
@retval EFI_SUCCESS There is key pending.
|
||||
@retval EFI_NOT_READY There is no key pending.
|
||||
@retval EFI_DEVICE_ERROR If Serial IO is not attached to serial device.
|
||||
Timer handler to poll the key from serial.
|
||||
|
||||
@param Event Indicates the event that invoke this function.
|
||||
@param Context Indicates the calling context.
|
||||
**/
|
||||
EFI_STATUS
|
||||
TerminalConInCheckForKey (
|
||||
IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This
|
||||
VOID
|
||||
EFIAPI
|
||||
TerminalConInTimerHandler (
|
||||
IN EFI_EVENT Event,
|
||||
IN VOID *Context
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
TERMINAL_DEV *TerminalDevice;
|
||||
UINT32 Control;
|
||||
UINT8 Input;
|
||||
EFI_SERIAL_IO_MODE *Mode;
|
||||
EFI_SERIAL_IO_PROTOCOL *SerialIo;
|
||||
UINTN SerialInTimeOut;
|
||||
|
||||
TerminalDevice = TERMINAL_CON_IN_DEV_FROM_THIS (This);
|
||||
TerminalDevice = (TERMINAL_DEV *) Context;
|
||||
|
||||
SerialIo = TerminalDevice->SerialIo;
|
||||
if (SerialIo == NULL) {
|
||||
return EFI_DEVICE_ERROR;
|
||||
return ;
|
||||
}
|
||||
//
|
||||
// if current timeout value for serial device is not identical with
|
||||
|
@ -602,28 +558,7 @@ TerminalConInCheckForKey (
|
|||
TerminalDevice->SerialInTimeOut = SerialInTimeOut;
|
||||
}
|
||||
}
|
||||
//
|
||||
// Check whether serial buffer is empty.
|
||||
//
|
||||
Status = SerialIo->GetControl (SerialIo, &Control);
|
||||
|
||||
if ((Control & EFI_SERIAL_INPUT_BUFFER_EMPTY) != 0) {
|
||||
//
|
||||
// Translate all the raw data in RawFIFO into EFI Key,
|
||||
// according to different terminal type supported.
|
||||
//
|
||||
TranslateRawDataToEfiKey (TerminalDevice);
|
||||
|
||||
//
|
||||
// if there is pre-fetched Efi Key in EfiKeyFIFO buffer,
|
||||
// return directly.
|
||||
//
|
||||
if (!IsEfiKeyFiFoEmpty (TerminalDevice)) {
|
||||
return EFI_SUCCESS;
|
||||
} else {
|
||||
return EFI_NOT_READY;
|
||||
}
|
||||
}
|
||||
//
|
||||
// Fetch all the keys in the serial buffer,
|
||||
// and insert the byte stream into RawFIFO.
|
||||
|
@ -651,12 +586,6 @@ TerminalConInCheckForKey (
|
|||
// according to different terminal type supported.
|
||||
//
|
||||
TranslateRawDataToEfiKey (TerminalDevice);
|
||||
|
||||
if (IsEfiKeyFiFoEmpty (TerminalDevice)) {
|
||||
return EFI_NOT_READY;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -837,15 +766,37 @@ IsRawFiFoFull (
|
|||
**/
|
||||
BOOLEAN
|
||||
EfiKeyFiFoInsertOneKey (
|
||||
TERMINAL_DEV *TerminalDevice,
|
||||
EFI_INPUT_KEY Key
|
||||
TERMINAL_DEV *TerminalDevice,
|
||||
EFI_INPUT_KEY *Key
|
||||
)
|
||||
{
|
||||
UINT8 Tail;
|
||||
UINT8 Tail;
|
||||
LIST_ENTRY *Link;
|
||||
LIST_ENTRY *NotifyList;
|
||||
TERMINAL_CONSOLE_IN_EX_NOTIFY *CurrentNotify;
|
||||
EFI_KEY_DATA KeyData;
|
||||
|
||||
Tail = TerminalDevice->EfiKeyFiFo->Tail;
|
||||
ASSERT (Tail < FIFO_MAX_NUMBER + 1);
|
||||
|
||||
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
|
||||
|
@ -853,9 +804,9 @@ EfiKeyFiFoInsertOneKey (
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
TerminalDevice->EfiKeyFiFo->Data[Tail] = Key;
|
||||
CopyMem (&TerminalDevice->EfiKeyFiFo->Data[Tail], Key, sizeof (EFI_INPUT_KEY));
|
||||
|
||||
TerminalDevice->EfiKeyFiFo->Tail = (UINT8) ((Tail + 1) % (FIFO_MAX_NUMBER + 1));
|
||||
TerminalDevice->EfiKeyFiFo->Tail = (UINT8) ((Tail + 1) % (FIFO_MAX_NUMBER + 1));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -1113,31 +1064,31 @@ UnicodeToEfiKeyFlushState (
|
|||
if ((InputState & INPUT_STATE_ESC) != 0) {
|
||||
Key.ScanCode = SCAN_ESC;
|
||||
Key.UnicodeChar = 0;
|
||||
EfiKeyFiFoInsertOneKey (TerminalDevice, Key);
|
||||
EfiKeyFiFoInsertOneKey (TerminalDevice, &Key);
|
||||
}
|
||||
|
||||
if ((InputState & INPUT_STATE_CSI) != 0) {
|
||||
Key.ScanCode = SCAN_NULL;
|
||||
Key.UnicodeChar = CSI;
|
||||
EfiKeyFiFoInsertOneKey (TerminalDevice, Key);
|
||||
EfiKeyFiFoInsertOneKey (TerminalDevice, &Key);
|
||||
}
|
||||
|
||||
if ((InputState & INPUT_STATE_LEFTOPENBRACKET) != 0) {
|
||||
Key.ScanCode = SCAN_NULL;
|
||||
Key.UnicodeChar = LEFTOPENBRACKET;
|
||||
EfiKeyFiFoInsertOneKey (TerminalDevice, Key);
|
||||
EfiKeyFiFoInsertOneKey (TerminalDevice, &Key);
|
||||
}
|
||||
|
||||
if ((InputState & INPUT_STATE_O) != 0) {
|
||||
Key.ScanCode = SCAN_NULL;
|
||||
Key.UnicodeChar = 'O';
|
||||
EfiKeyFiFoInsertOneKey (TerminalDevice, Key);
|
||||
EfiKeyFiFoInsertOneKey (TerminalDevice, &Key);
|
||||
}
|
||||
|
||||
if ((InputState & INPUT_STATE_2) != 0) {
|
||||
Key.ScanCode = SCAN_NULL;
|
||||
Key.UnicodeChar = '2';
|
||||
EfiKeyFiFoInsertOneKey (TerminalDevice, Key);
|
||||
EfiKeyFiFoInsertOneKey (TerminalDevice, &Key);
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -1368,7 +1319,7 @@ UnicodeToEfiKey (
|
|||
|
||||
if (Key.ScanCode != SCAN_NULL) {
|
||||
Key.UnicodeChar = 0;
|
||||
EfiKeyFiFoInsertOneKey (TerminalDevice,Key);
|
||||
EfiKeyFiFoInsertOneKey (TerminalDevice, &Key);
|
||||
TerminalDevice->InputState = INPUT_STATE_DEFAULT;
|
||||
UnicodeToEfiKeyFlushState (TerminalDevice);
|
||||
continue;
|
||||
|
@ -1423,7 +1374,7 @@ UnicodeToEfiKey (
|
|||
|
||||
if (Key.ScanCode != SCAN_NULL) {
|
||||
Key.UnicodeChar = 0;
|
||||
EfiKeyFiFoInsertOneKey (TerminalDevice,Key);
|
||||
EfiKeyFiFoInsertOneKey (TerminalDevice, &Key);
|
||||
TerminalDevice->InputState = INPUT_STATE_DEFAULT;
|
||||
UnicodeToEfiKeyFlushState (TerminalDevice);
|
||||
continue;
|
||||
|
@ -1561,7 +1512,7 @@ UnicodeToEfiKey (
|
|||
|
||||
if (Key.ScanCode != SCAN_NULL) {
|
||||
Key.UnicodeChar = 0;
|
||||
EfiKeyFiFoInsertOneKey (TerminalDevice,Key);
|
||||
EfiKeyFiFoInsertOneKey (TerminalDevice, &Key);
|
||||
TerminalDevice->InputState = INPUT_STATE_DEFAULT;
|
||||
UnicodeToEfiKeyFlushState (TerminalDevice);
|
||||
continue;
|
||||
|
@ -1613,6 +1564,6 @@ UnicodeToEfiKey (
|
|||
Key.UnicodeChar = UnicodeChar;
|
||||
}
|
||||
|
||||
EfiKeyFiFoInsertOneKey (TerminalDevice,Key);
|
||||
EfiKeyFiFoInsertOneKey (TerminalDevice, &Key);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue