XTLDR Rewrite #7
189
xtldr2/textui.c
189
xtldr2/textui.c
@ -960,3 +960,192 @@ BlDisplayInputDialog(IN PWCHAR Caption,
|
||||
BlSetConsoleAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY);
|
||||
BlClearConsoleScreen();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
XTCDECL
|
||||
VOID
|
||||
BlDisplayBootMenu()
|
||||
{
|
||||
XTBL_DIALOG_HANDLE Handle;
|
||||
PXTBL_BOOTMENU_ITEM MenuEntries = NULL;
|
||||
ULONG Index, NumberOfEntries, HighligtedEntryId;
|
||||
UINT_PTR EventIndex;
|
||||
EFI_EVENT Events[2];
|
||||
EFI_INPUT_KEY Key;
|
||||
EFI_EVENT TimerEvent;
|
||||
EFI_STATUS Status;
|
||||
LONG TimeOut;
|
||||
PWCHAR TimeOutString;
|
||||
|
||||
/* Initialize boot menu list */
|
||||
BlInitializeBootMenuList(MenuEntries, &NumberOfEntries, &HighligtedEntryId);
|
||||
|
||||
/* Get timeout from the configuration */
|
||||
TimeOutString = NULL; //BlGetConfigValue(L"TIMEOUT");
|
||||
TimeOut = -1;
|
||||
|
||||
/* Check if timeout is specified */
|
||||
if(TimeOutString != NULL)
|
||||
{
|
||||
/* Convert timeout string to number */
|
||||
TimeOut = 0;
|
||||
while(*TimeOutString >= '0' && *TimeOutString <= '9')
|
||||
{
|
||||
TimeOut *= 10;
|
||||
TimeOut += *TimeOutString - '0';
|
||||
TimeOutString++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Infinite boot menu loop */
|
||||
while(TRUE)
|
||||
{
|
||||
/* Draw boot menu */
|
||||
BlpDrawBootMenu(&Handle);
|
||||
|
||||
/* Check if there is anything to show in the boot menu */
|
||||
if(NumberOfEntries > 0) {
|
||||
/* Iterate through all menu entries */
|
||||
for(Index = 0; Index < NumberOfEntries; Index++)
|
||||
{
|
||||
/* Draw menu entry */
|
||||
BlpDrawBootMenuEntry(&Handle, MenuEntries[Index].EntryName, Index, Index == HighligtedEntryId);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No menu entries found, show error message */
|
||||
BlDisplayErrorDialog(L"XTLDR", L"No boot menu entries found in the configuration. Falling back to shell.");
|
||||
|
||||
/* Exit into XTLDR shell */
|
||||
return;
|
||||
}
|
||||
|
||||
/* Create a timer event for controlling the timeout of the boot menu */
|
||||
Status = EfiSystemTable->BootServices->CreateEvent(EFI_EVENT_TIMER, EFI_TPL_CALLBACK, NULL, NULL, &TimerEvent);
|
||||
if(Status == STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Setup new EFI timer */
|
||||
Status = EfiSystemTable->BootServices->SetTimer(TimerEvent, TimerPeriodic, 10000000);
|
||||
}
|
||||
|
||||
/* Check is EFI timer was successfully created */
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Timer creation failed, disable the timer */
|
||||
TimeOut = -1;
|
||||
}
|
||||
|
||||
/* Initialize EFI events */
|
||||
Events[0] = EfiSystemTable->ConIn->WaitForKey;
|
||||
Events[1] = TimerEvent;
|
||||
|
||||
/* Infinite boot menu event loop */
|
||||
while(TRUE)
|
||||
{
|
||||
/* Wait for EFI event */
|
||||
BlWaitForEfiEvent(2, Events, &EventIndex);
|
||||
|
||||
/* Check which event was received */
|
||||
if(EventIndex == 0)
|
||||
{
|
||||
/* Key pressed, check if timer is still active */
|
||||
if(TimeOut != -1)
|
||||
{
|
||||
/* Disable the timer */
|
||||
TimeOut = -1;
|
||||
|
||||
/* Cancel timer event */
|
||||
EfiSystemTable->BootServices->SetTimer(TimerEvent, TimerCancel, 0);
|
||||
|
||||
/* Remove the timer message */
|
||||
BlSetCursorPosition(4, Handle.PosY + Handle.Height + 4);
|
||||
BlConsolePrint(L" ", TimeOut);
|
||||
}
|
||||
|
||||
/* Read key stroke */
|
||||
BlReadKeyStroke(&Key);
|
||||
|
||||
if(Key.ScanCode == 0x03 || Key.UnicodeChar == 0x0D)
|
||||
{
|
||||
/* ENTER or RightArrow key pressed, boot the highlighted OS */
|
||||
BlDisplayInfoDialog(L"XTLDR", L"Booting highlighted OS ...");
|
||||
|
||||
/* Break from boot menu event loop to redraw whole boot menu */
|
||||
break;
|
||||
}
|
||||
else if(Key.ScanCode == 0x01)
|
||||
{
|
||||
/* UpArrow key pressed, go to previous entry if possible */
|
||||
if(HighligtedEntryId > 0)
|
||||
{
|
||||
/* Highlight previous entry */
|
||||
HighligtedEntryId--;
|
||||
BlpDrawBootMenuEntry(&Handle, MenuEntries[HighligtedEntryId + 1].EntryName, HighligtedEntryId + 1, FALSE);
|
||||
BlpDrawBootMenuEntry(&Handle, MenuEntries[HighligtedEntryId].EntryName, HighligtedEntryId, TRUE);
|
||||
}
|
||||
}
|
||||
else if(Key.ScanCode == 0x02)
|
||||
{
|
||||
/* DownArrow key pressed, go to next entry if possible */
|
||||
if(HighligtedEntryId < NumberOfEntries - 1)
|
||||
{
|
||||
/* Highlight next entry */
|
||||
HighligtedEntryId++;
|
||||
BlpDrawBootMenuEntry(&Handle, MenuEntries[HighligtedEntryId - 1].EntryName, HighligtedEntryId - 1, FALSE);
|
||||
BlpDrawBootMenuEntry(&Handle, MenuEntries[HighligtedEntryId].EntryName, HighligtedEntryId, TRUE);
|
||||
}
|
||||
}
|
||||
else if(Key.ScanCode == 0x0B)
|
||||
{
|
||||
/* F1 key pressed, show help */
|
||||
BlDisplayInfoDialog(L"XTLDR", L"XTLDR Boot Loader Help");
|
||||
|
||||
/* Break from boot menu event loop to redraw whole boot menu */
|
||||
break;
|
||||
}
|
||||
else if(Key.UnicodeChar == 0x65)
|
||||
{
|
||||
/* 'e' key pressed, edit the highlighted entry */
|
||||
|
||||
/* Break from boot menu event loop to redraw whole boot menu */
|
||||
break;
|
||||
}
|
||||
else if(Key.UnicodeChar == 0x73)
|
||||
{
|
||||
/* 's' key pressed, exit into XTLDR shell */
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Timer tick, check if time out expired */
|
||||
if(TimeOut > 0)
|
||||
{
|
||||
/* Update a message and decrease timeout value */
|
||||
BlSetCursorPosition(4, Handle.PosY + Handle.Height + 4);
|
||||
BlConsolePrint(L"The highlighted position will be booted automatically in %ld seconds. ", TimeOut);
|
||||
TimeOut--;
|
||||
}
|
||||
else if(TimeOut == 0)
|
||||
{
|
||||
/* Time out expired, update a message */
|
||||
BlSetCursorPosition(4, Handle.PosY + Handle.Height + 4);
|
||||
BlConsolePrint(L"Booting '%S' now... ",
|
||||
MenuEntries[HighligtedEntryId].EntryName);
|
||||
|
||||
/* Disable the timer just in case booting OS fails */
|
||||
TimeOut = -1;
|
||||
|
||||
/* Boot the highlighted (default) OS */
|
||||
BlDisplayInfoDialog(L"XTLDR", L"Booting highlighted OS ...");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,6 +9,10 @@
|
||||
#include <xtldr.h>
|
||||
|
||||
|
||||
XTCDECL
|
||||
VOID
|
||||
BlDisplayBootMenu();
|
||||
|
||||
/**
|
||||
* Initializes a list of operating systems for XTLDR boot menu.
|
||||
*
|
||||
@ -186,6 +190,12 @@ BlStartXtLoader(IN EFI_HANDLE ImageHandle,
|
||||
BlDebugPrint(L"ERROR: Failed to discover and enumerate block devices\n");
|
||||
}
|
||||
|
||||
for(;;)
|
||||
{
|
||||
/* Display boot menu */
|
||||
BlDisplayBootMenu();
|
||||
}
|
||||
|
||||
/* This point should be never reached, if this happen return error code */
|
||||
return STATUS_EFI_LOAD_ERROR;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user