Revise key handling in boot phase
Add escape key handler as early as possible, and set timeout immediately upon displaying splash.
This commit is contained in:
committed by
Tim Crawford
parent
52d5d1b2c5
commit
976842130a
@ -1169,6 +1169,19 @@ InstallReadyToLock (
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static BOOLEAN ESCAPE_KEY_DETECTED = FALSE;
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
EscapeKeyNotify (
|
||||||
|
EFI_KEY_DATA *KeyData
|
||||||
|
)
|
||||||
|
{
|
||||||
|
DEBUG((DEBUG_INFO, "Detected escape key\n"));
|
||||||
|
ESCAPE_KEY_DETECTED = TRUE;
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
EFIAPI
|
EFIAPI
|
||||||
PlatformBdsPolicyBehavior (
|
PlatformBdsPolicyBehavior (
|
||||||
@ -1198,9 +1211,13 @@ Returns:
|
|||||||
--*/
|
--*/
|
||||||
{
|
{
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
UINT16 Timeout;
|
EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *SimpleTextInEx;
|
||||||
|
EFI_KEY_DATA EscapeKeyData;
|
||||||
|
EFI_HANDLE EscapeKeyHandle;
|
||||||
EFI_EVENT UserInputDurationTime;
|
EFI_EVENT UserInputDurationTime;
|
||||||
|
EFI_EVENT Events[2];
|
||||||
UINTN Index;
|
UINTN Index;
|
||||||
|
UINT16 Timeout;
|
||||||
EFI_INPUT_KEY Key;
|
EFI_INPUT_KEY Key;
|
||||||
EFI_BOOT_MODE BootMode;
|
EFI_BOOT_MODE BootMode;
|
||||||
|
|
||||||
@ -1238,6 +1255,30 @@ Returns:
|
|||||||
PlatformBdsNoConsoleAction ();
|
PlatformBdsNoConsoleAction ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Find simple text input extension protocol for console in
|
||||||
|
SimpleTextInEx = NULL;
|
||||||
|
Status = gBS->HandleProtocol(
|
||||||
|
gST->ConsoleInHandle,
|
||||||
|
&gEfiSimpleTextInputExProtocolGuid,
|
||||||
|
(VOID **) &SimpleTextInEx
|
||||||
|
);
|
||||||
|
|
||||||
|
// Register a handler for escape key
|
||||||
|
ESCAPE_KEY_DETECTED = FALSE;
|
||||||
|
if (SimpleTextInEx != NULL) {
|
||||||
|
EscapeKeyData.Key.ScanCode = SCAN_ESC;
|
||||||
|
EscapeKeyData.Key.UnicodeChar = 0;
|
||||||
|
EscapeKeyData.KeyState.KeyShiftState = 0;
|
||||||
|
EscapeKeyData.KeyState.KeyToggleState = 0;
|
||||||
|
Status = SimpleTextInEx->RegisterKeyNotify(
|
||||||
|
SimpleTextInEx,
|
||||||
|
&EscapeKeyData,
|
||||||
|
EscapeKeyNotify,
|
||||||
|
&EscapeKeyHandle
|
||||||
|
);
|
||||||
|
ASSERT (Status == EFI_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Perform some platform specific connect sequence
|
// Perform some platform specific connect sequence
|
||||||
//
|
//
|
||||||
@ -1252,7 +1293,7 @@ Returns:
|
|||||||
BdsLibConnectAll ();
|
BdsLibConnectAll ();
|
||||||
|
|
||||||
//
|
//
|
||||||
// Create a 1s duration event to ensure user has enough input time to enter Setup
|
// Create a 2s duration event to ensure user has enough input time to enter Setup
|
||||||
//
|
//
|
||||||
Status = gBS->CreateEvent (
|
Status = gBS->CreateEvent (
|
||||||
EVT_TIMER,
|
EVT_TIMER,
|
||||||
@ -1265,22 +1306,47 @@ Returns:
|
|||||||
Status = gBS->SetTimer (UserInputDurationTime, TimerRelative, 20000000);
|
Status = gBS->SetTimer (UserInputDurationTime, TimerRelative, 20000000);
|
||||||
ASSERT (Status == EFI_SUCCESS);
|
ASSERT (Status == EFI_SUCCESS);
|
||||||
|
|
||||||
//
|
// Connect all drivers, could be delayed
|
||||||
// To give the User a chance to enter Setup here, if user set TimeOut is 0.
|
BdsLibConnectAll ();
|
||||||
// BDS should still give user a chance to enter Setup
|
|
||||||
// Check whether the user input after the duration time has expired
|
|
||||||
//
|
|
||||||
gBS->WaitForEvent (1, &UserInputDurationTime, &Index);
|
|
||||||
gBS->CloseEvent (UserInputDurationTime);
|
|
||||||
Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
|
|
||||||
|
|
||||||
if (!EFI_ERROR (Status)) {
|
// The escape key could have been pressed already
|
||||||
//
|
if (!ESCAPE_KEY_DETECTED) {
|
||||||
// Enter Setup if user input
|
//
|
||||||
//
|
// To give the User a chance to enter Setup here, if user set TimeOut is 0.
|
||||||
Timeout = 0xffff;
|
// BDS should still give user a chance to enter Setup
|
||||||
|
// Check whether the user input after the duration time has expired
|
||||||
|
//
|
||||||
|
Events[0] = gST->ConIn->WaitForKey;
|
||||||
|
Events[1] = UserInputDurationTime;
|
||||||
|
gBS->WaitForEvent (2, Events, &Index);
|
||||||
|
}
|
||||||
|
gBS->CloseEvent (UserInputDurationTime);
|
||||||
|
|
||||||
|
if (SimpleTextInEx != NULL) {
|
||||||
|
// Remove escape key handler
|
||||||
|
Status = SimpleTextInEx->UnregisterKeyNotify(
|
||||||
|
SimpleTextInEx,
|
||||||
|
EscapeKeyHandle
|
||||||
|
);
|
||||||
|
ASSERT (Status == EFI_SUCCESS);
|
||||||
} else {
|
} else {
|
||||||
Timeout = 0;
|
Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
|
||||||
|
if (!EFI_ERROR (Status)) {
|
||||||
|
//
|
||||||
|
// Enter Setup if user input
|
||||||
|
//
|
||||||
|
ESCAPE_KEY_DETECTED = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ESCAPE_KEY_DETECTED) {
|
||||||
|
Timeout = 0xffff;
|
||||||
|
DEBUG((DEBUG_INFO, "Escape key detected, going to menu\n"));
|
||||||
|
|
||||||
|
// Clear pending keypresses if we are going to the menu
|
||||||
|
while (!EFI_ERROR (gST->ConIn->ReadKeyStroke (gST->ConIn, &Key))) {}
|
||||||
|
} else {
|
||||||
|
Timeout = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
BdsLibEnumerateAllBootOption (BootOptionList);
|
BdsLibEnumerateAllBootOption (BootOptionList);
|
||||||
@ -1315,10 +1381,15 @@ Returns:
|
|||||||
|
|
||||||
--*/
|
--*/
|
||||||
{
|
{
|
||||||
CHAR16 *TmpStr;
|
EFI_INPUT_KEY Key;
|
||||||
|
CHAR16 *TmpStr;
|
||||||
|
|
||||||
|
// Clear screen before showing success message
|
||||||
gST->ConOut->ClearScreen(gST->ConOut);
|
gST->ConOut->ClearScreen(gST->ConOut);
|
||||||
|
|
||||||
|
// Clear pending keypresses before showing success message
|
||||||
|
while (!EFI_ERROR (gST->ConIn->ReadKeyStroke (gST->ConIn, &Key))) {}
|
||||||
|
|
||||||
//
|
//
|
||||||
// If Boot returned with EFI_SUCCESS and there is not in the boot device
|
// If Boot returned with EFI_SUCCESS and there is not in the boot device
|
||||||
// select loop then we need to pop up a UI and wait for user input.
|
// select loop then we need to pop up a UI and wait for user input.
|
||||||
@ -1360,10 +1431,15 @@ Returns:
|
|||||||
|
|
||||||
--*/
|
--*/
|
||||||
{
|
{
|
||||||
CHAR16 *TmpStr;
|
EFI_INPUT_KEY Key;
|
||||||
|
CHAR16 *TmpStr;
|
||||||
|
|
||||||
|
// Clear screen before showing fail message
|
||||||
gST->ConOut->ClearScreen(gST->ConOut);
|
gST->ConOut->ClearScreen(gST->ConOut);
|
||||||
|
|
||||||
|
// Clear pending keypresses before showing fail message
|
||||||
|
while (!EFI_ERROR (gST->ConIn->ReadKeyStroke (gST->ConIn, &Key))) {}
|
||||||
|
|
||||||
//
|
//
|
||||||
// If Boot returned with failed status then we need to pop up a UI and wait
|
// If Boot returned with failed status then we need to pop up a UI and wait
|
||||||
// for user input.
|
// for user input.
|
||||||
|
Reference in New Issue
Block a user