/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: FreeLoader
- * FILE: freeldr/ui/tuimenu.c
+ * FILE: boot/freeldr/freeldr/ui/tuimenu.c
* PURPOSE: UI Menu Functions
* PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
* Brian Palmer (brianp@sginet.com)
/* FUNCTIONS *****************************************************************/
BOOLEAN
-TuiDisplayMenu(PCSTR MenuItemList[],
+TuiDisplayMenu(PCSTR MenuHeader,
+ PCSTR MenuFooter,
+ BOOLEAN ShowBootOptions,
+ PCSTR MenuItemList[],
ULONG MenuItemCount,
ULONG DefaultMenuItem,
LONG MenuTimeOut,
ULONG CurrentClockSecond;
ULONG KeyPress;
+ //
+ // Before taking any default action if there is no timeout,
+ // check whether the supplied key filter callback function
+ // may handle a specific user keypress. If it does, the
+ // timeout is cancelled.
+ //
+ if (!MenuTimeOut && KeyPressFilter && MachConsKbHit())
+ {
+ //
+ // Get the key
+ //
+ KeyPress = MachConsGetCh();
+
+ //
+ // Is it extended? Then get the extended key
+ //
+ if (!KeyPress) KeyPress = MachConsGetCh();
+
+ //
+ // Call the supplied key filter callback function to see
+ // if it is going to handle this keypress.
+ //
+ if (KeyPressFilter(KeyPress))
+ {
+ //
+ // It processed the key character, cancel the timeout
+ //
+ MenuTimeOut = -1;
+ }
+ }
+
//
// Check if there's no timeout
+ //
if (!MenuTimeOut)
{
//
//
// Setup the MENU_INFO structure
//
+ MenuInformation.MenuHeader = MenuHeader;
+ MenuInformation.MenuFooter = MenuFooter;
+ MenuInformation.ShowBootOptions = ShowBootOptions;
MenuInformation.MenuItemList = MenuItemList;
MenuInformation.MenuItemCount = MenuItemCount;
MenuInformation.MenuTimeRemaining = MenuTimeOut;
//
// Check if there is a countdown
//
- if (MenuInformation.MenuTimeRemaining)
+ if (MenuInformation.MenuTimeRemaining > 0)
{
//
// Get the updated time, seconds only
VideoCopyOffScreenBufferToVRAM();
}
}
- else
+ else if (MenuInformation.MenuTimeRemaining == 0)
{
//
// A time out occurred, exit this loop and return default OS
//
break;
}
+
+ MachHwIdle();
}
//
//
// Get the string length and make it become the new width if necessary
//
- Length = strlen(MenuInfo->MenuItemList[i]);
- if (Length > Width) Width = Length;
+ if (MenuInfo->MenuItemList[i])
+ {
+ Length = (ULONG)strlen(MenuInfo->MenuItemList[i]);
+ if (Length > Width) Width = Length;
+ }
}
//
//
// Update the status bar
//
- UiVtbl.DrawStatusText("Use \x18\x19 to select, then press ENTER.");
+ UiVtbl.DrawStatusText("Use \x18 and \x19 to select, then press ENTER.");
//
// Draw the menu box
//
// Draw each line of the menu
//
- for (i = 0; i < MenuInfo->MenuItemCount; i++) TuiDrawMenuItem(MenuInfo, i);
+ for (i = 0; i < MenuInfo->MenuItemCount; i++)
+ {
+ TuiDrawMenuItem(MenuInfo, i);
+ }
+
+ /* Display the boot options if needed */
+ if (MenuInfo->ShowBootOptions)
+ {
+ DisplayBootTimeOptions();
+ }
+
VideoCopyOffScreenBufferToVRAM();
}
NTAPI
TuiDrawMenuBox(PUI_MENU_INFO MenuInfo)
{
- CHAR MenuLineText[80];
- CHAR TempString[80];
+ CHAR MenuLineText[80], TempString[80];
ULONG i;
//
D_VERT,
D_HORZ,
FALSE, // Filled
- TRUE, // Shadow
+ TRUE, // Shadow
ATTR(UiMenuFgColor, UiMenuBgColor));
}
// Copy the integral time text string, and remove the last 2 chars
//
strcpy(TempString, UiTimeText);
- i = strlen(TempString);
+ i = (ULONG)strlen(TempString);
TempString[i - 2] = 0;
//
//
// Display it in the center of the menu
//
- UiDrawText(MenuInfo->Right - strlen(MenuLineText) - 1,
+ UiDrawText(MenuInfo->Right - (ULONG)strlen(MenuLineText) - 1,
MenuInfo->Bottom,
MenuLineText,
ATTR(UiMenuFgColor, UiMenuBgColor));
// Display under the menu directly
//
UiDrawText(0,
- MenuInfo->Bottom + 3,
+ MenuInfo->Bottom + 4,
MenuLineText,
ATTR(UiMenuFgColor, UiMenuBgColor));
}
//
if (UiCenterMenu)
{
- UiDrawText(MenuInfo->Right - strlen(MenuLineText) - 1,
+ UiDrawText(MenuInfo->Right - (ULONG)strlen(MenuLineText) - 1,
MenuInfo->Bottom,
MenuLineText,
ATTR(UiMenuFgColor, UiMenuBgColor));
else
{
UiDrawText(0,
- MenuInfo->Bottom + 3,
+ MenuInfo->Bottom + 4,
MenuLineText,
ATTR(UiMenuFgColor, UiMenuBgColor));
}
//
// Check if it's a separator
//
- if (!(_stricmp(MenuInfo->MenuItemList[i], "SEPARATOR")))
+ if (MenuInfo->MenuItemList[i] == NULL)
{
//
// Draw the separator line
// how many spaces will be to the left and right
//
SpaceTotal = (MenuInfo->Right - MenuInfo->Left - 2) -
- strlen(MenuInfo->MenuItemList[MenuItemNumber]);
+ (ULONG)(MenuInfo->MenuItemList[MenuItemNumber] ?
+ strlen(MenuInfo->MenuItemList[MenuItemNumber]) : 0);
SpaceLeft = (SpaceTotal / 2) + 1;
SpaceRight = (SpaceTotal - SpaceLeft) + 1;
//
// Now append the text string
//
- strcat(MenuLineText, MenuInfo->MenuItemList[MenuItemNumber]);
+ if (MenuInfo->MenuItemList[MenuItemNumber])
+ strcat(MenuLineText, MenuInfo->MenuItemList[MenuItemNumber]);
//
// Check if using centered menu, and add spaces on the right if so
//
// If it is a separator
//
- if (!(_stricmp(MenuInfo->MenuItemList[MenuItemNumber], "SEPARATOR")))
+ if (MenuInfo->MenuItemList[MenuItemNumber] == NULL)
{
//
// Make it a separator line and use menu colors
//
// Process the key
//
- if ((KeyEvent == KEY_UP) || (KeyEvent == KEY_DOWN))
+ if ((KeyEvent == KEY_UP ) || (KeyEvent == KEY_DOWN) ||
+ (KeyEvent == KEY_HOME) || (KeyEvent == KEY_END ))
{
//
// Get the current selected item and count
Count = MenuInfo->MenuItemCount - 1;
//
- // Check if this was a key up and there's a selected menu item
+ // Check the key and change the selected menu item
//
- if ((KeyEvent == KEY_UP) && (Selected))
+ if ((KeyEvent == KEY_UP) && (Selected > 0))
{
//
- // Update the menu (Deselect previous item)
+ // Deselect previous item and go up
//
MenuInfo->SelectedMenuItem--;
TuiDrawMenuItem(MenuInfo, Selected);
Selected--;
// Skip past any separators
- if ((Selected) &&
- !(_stricmp(MenuInfo->MenuItemList[Selected], "SEPARATOR")))
+ if ((Selected > 0) &&
+ (MenuInfo->MenuItemList[Selected] == NULL))
{
MenuInfo->SelectedMenuItem--;
}
}
+ else if ( ((KeyEvent == KEY_UP) && (Selected == 0)) ||
+ (KeyEvent == KEY_END) )
+ {
+ //
+ // Go to the end
+ //
+ MenuInfo->SelectedMenuItem = Count;
+ TuiDrawMenuItem(MenuInfo, Selected);
+ }
else if ((KeyEvent == KEY_DOWN) && (Selected < Count))
{
//
- // Update the menu (deselect previous item)
+ // Deselect previous item and go down
//
MenuInfo->SelectedMenuItem++;
TuiDrawMenuItem(MenuInfo, Selected);
// Skip past any separators
if ((Selected < Count) &&
- !(_stricmp(MenuInfo->MenuItemList[Selected], "SEPARATOR")))
+ (MenuInfo->MenuItemList[Selected] == NULL))
{
MenuInfo->SelectedMenuItem++;
}
}
+ else if ( ((KeyEvent == KEY_DOWN) && (Selected == Count)) ||
+ (KeyEvent == KEY_HOME) )
+ {
+ //
+ // Go to the beginning
+ //
+ MenuInfo->SelectedMenuItem = 0;
+ TuiDrawMenuItem(MenuInfo, Selected);
+ }
//
// Select new item and update video buffer