Semi-functional code for displaying boot menu
This commit is contained in:
parent
edcce638be
commit
a7c345a9b2
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);
|
BlSetConsoleAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY);
|
||||||
BlClearConsoleScreen();
|
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>
|
#include <xtldr.h>
|
||||||
|
|
||||||
|
|
||||||
|
XTCDECL
|
||||||
|
VOID
|
||||||
|
BlDisplayBootMenu();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes a list of operating systems for XTLDR boot menu.
|
* 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");
|
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 */
|
/* This point should be never reached, if this happen return error code */
|
||||||
return STATUS_EFI_LOAD_ERROR;
|
return STATUS_EFI_LOAD_ERROR;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user