From: Alex Ionescu Date: Tue, 27 Dec 2005 03:12:00 +0000 (+0000) Subject: - Added support for NTLDR style freeloader GUI. To enable, edit freeldr.ini and add: X-Git-Tag: backups/expat-rbuild@40467~771 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=901929a78711583e331863949bb1b20c7bb3d8b9 - Added support for NTLDR style freeloader GUI. To enable, edit freeldr.ini and add: ShowTime=No MinimalUI=Yes MenuBox=No CenterMenu=No TimeText=Seconds until highlighted choice will be started automatically: Also make sure the following are set: MenuTextColor=Gray MenuColor=Black TextColor=Gray SelectedTextColor=Black SelectedColor=Gray. - Also made the boot-up screen black, not blue, since that's the actual color it's been after NT4. If booting without NOGUIBOOT, this results in a much nicer transition to the boot screen (especially if using the NTLDR theme) - Some other minor changes done to simplify transitions while booting. Hoping for filip to finish his Bootvid patch to remove the last annoying gui->text->gui switch near the end :). svn path=/trunk/; revision=20366 --- diff --git a/reactos/boot/freeldr/freeldr/include/ui.h b/reactos/boot/freeldr/freeldr/include/ui.h index 307f06830f8..41d5991c088 100644 --- a/reactos/boot/freeldr/freeldr/include/ui.h +++ b/reactos/boot/freeldr/freeldr/include/ui.h @@ -46,6 +46,10 @@ extern CHAR UiTitleBoxTitleText[260]; // Title box's title text extern BOOL UserInterfaceUp; // Tells us if the user interface is displayed extern BOOL UiUseSpecialEffects; // Tells us if we should use fade effects +extern BOOL UiCenterMenu; +extern BOOL UiMenuBox; +extern BOOL UiMinimal; +extern CHAR UiTimeText[]; extern const CHAR UiMonthNames[12][15]; diff --git a/reactos/boot/freeldr/freeldr/include/ui/tui.h b/reactos/boot/freeldr/freeldr/include/ui/tui.h index cece7b89eff..9ae09b575c3 100644 --- a/reactos/boot/freeldr/freeldr/include/ui/tui.h +++ b/reactos/boot/freeldr/freeldr/include/ui/tui.h @@ -73,12 +73,12 @@ typedef struct } TUI_MENU_INFO, *PTUI_MENU_INFO; -VOID TuiCalcMenuBoxSize(PTUI_MENU_INFO MenuInfo); -VOID TuiDrawMenu(PTUI_MENU_INFO MenuInfo); -VOID TuiDrawMenuBox(PTUI_MENU_INFO MenuInfo); -VOID TuiDrawMenuItem(PTUI_MENU_INFO MenuInfo, ULONG MenuItemNumber); -ULONG TuiProcessMenuKeyboardEvent(PTUI_MENU_INFO MenuInfo, UiMenuKeyPressFilterCallback KeyPressFilter); -BOOL TuiDisplayMenu(PCSTR MenuItemList[], ULONG MenuItemCount, ULONG DefaultMenuItem, LONG MenuTimeOut, ULONG* SelectedMenuItem, BOOL CanEscape, UiMenuKeyPressFilterCallback KeyPressFilter); +VOID WINAPI TuiCalcMenuBoxSize(PTUI_MENU_INFO MenuInfo); +VOID WINAPI TuiDrawMenu(PTUI_MENU_INFO MenuInfo); +VOID WINAPI TuiDrawMenuBox(PTUI_MENU_INFO MenuInfo); +VOID WINAPI TuiDrawMenuItem(PTUI_MENU_INFO MenuInfo, ULONG MenuItemNumber); +ULONG WINAPI TuiProcessMenuKeyboardEvent(PTUI_MENU_INFO MenuInfo, UiMenuKeyPressFilterCallback KeyPressFilter); +BOOL WINAPI TuiDisplayMenu(PCSTR MenuItemList[], ULONG MenuItemCount, ULONG DefaultMenuItem, LONG MenuTimeOut, ULONG* SelectedMenuItem, BOOL CanEscape, UiMenuKeyPressFilterCallback KeyPressFilter); /* diff --git a/reactos/boot/freeldr/freeldr/reactos/reactos.c b/reactos/boot/freeldr/freeldr/reactos/reactos.c index 158d7218ed5..6e1871132db 100644 --- a/reactos/boot/freeldr/freeldr/reactos/reactos.c +++ b/reactos/boot/freeldr/freeldr/reactos/reactos.c @@ -587,6 +587,10 @@ LoadAndBootReactOS(PCSTR OperatingSystemName) return; } + UiDrawBackdrop(); + UiDrawStatusText("Detecting Hardware..."); + UiDrawProgressBarCenter(1, 100, szLoadingMsg); + /* * Setup multiboot information structure */ @@ -677,19 +681,15 @@ LoadAndBootReactOS(PCSTR OperatingSystemName) strcat(reactos_kernel_cmdline, value); } - - UiDrawBackdrop(); - UiDrawStatusText("Detecting Hardware..."); - /* * Detect hardware */ MachHwDetect(); + UiDrawProgressBarCenter(5, 100, szLoadingMsg); if (AcpiPresent) LoaderBlock.Flags |= MB_FLAGS_ACPI_TABLE; UiDrawStatusText("Loading..."); - UiDrawProgressBarCenter(0, 100, szLoadingMsg); /* * Try to open system drive diff --git a/reactos/boot/freeldr/freeldr/ui/tui.c b/reactos/boot/freeldr/freeldr/ui/tui.c index 7a99bf82789..73ae36af047 100644 --- a/reactos/boot/freeldr/freeldr/ui/tui.c +++ b/reactos/boot/freeldr/freeldr/ui/tui.c @@ -20,6 +20,8 @@ #include PVOID TextVideoBuffer = NULL; +extern BOOL UiDrawTime; +extern BOOL UiMinimal; /* * printf() - prints formatted text to stdout @@ -111,6 +113,25 @@ VOID TuiUnInitialize(VOID) VOID TuiDrawBackdrop(VOID) { + if (UiMinimal) + { + // + // Fill in a black background + // + TuiFillArea(0, + 0, + UiScreenWidth - 1, + UiScreenHeight - 1, + 0, + 0); + + // + // Update the screen buffer + // + VideoCopyOffScreenBufferToVRAM(); + return; + } + // // Fill in the background (excluding title box & status bar) // @@ -429,6 +450,11 @@ VOID TuiDrawStatusText(PCSTR StatusText) { ULONG i; + // + // Minimal UI doesn't have a status bar + // + if (UiMinimal) return; + TuiDrawText(0, UiScreenHeight-1, " ", ATTR(UiStatusBarFgColor, UiStatusBarBgColor)); TuiDrawText(1, UiScreenHeight-1, StatusText, ATTR(UiStatusBarFgColor, UiStatusBarBgColor)); @@ -449,6 +475,9 @@ VOID TuiUpdateDateTime(VOID) CHAR TempString[20]; BOOL PMHour = FALSE; + /* Don't draw the time if this has been disabled */ + if (!UiDrawTime) return; + MachRTCGetCurrentDateTime(&Year, &Month, &Day, &Hour, &Minute, &Second); if (Year < 1 || 9999 < Year || Month < 1 || 12 < Month || Day < 1 || 31 < Day || 23 < Hour || 59 < Minute || 59 < Second) @@ -663,10 +692,28 @@ VOID TuiDrawProgressBarCenter(ULONG Position, ULONG Range, PCHAR ProgressText) ULONG Width = 50; // Allow for 50 "bars" ULONG Height = 2; - Left = (UiScreenWidth - Width - 4) / 2; - Right = Left + Width + 3; - Top = (UiScreenHeight - Height - 2) / 2; - Top += 2; + // + // Is this the minimal UI? + // + if (UiMinimal) + { + // + // Use alternate settings + // + Width = 80; + Left = 0; + Right = Left + Width; + Top = UiScreenHeight - Height - 4; + Bottom = Top + Height + 1; + } + else + { + Left = (UiScreenWidth - Width - 4) / 2; + Right = Left + Width + 3; + Top = (UiScreenHeight - Height - 2) / 2; + Top += 2; + } + Bottom = Top + Height + 1; TuiDrawProgressBar(Left, Top, Right, Bottom, Position, Range, ProgressText); @@ -685,12 +732,26 @@ VOID TuiDrawProgressBar(ULONG Left, ULONG Top, ULONG Right, ULONG Bottom, ULONG Position = Range; } - // Draw the box - TuiDrawBox(Left, Top, Right, Bottom, VERT, HORZ, TRUE, TRUE, ATTR(UiMenuFgColor, UiMenuBgColor)); - - // Draw the "Loading..." text - //TuiDrawText(70/2, Top+1, "Loading...", ATTR(UiTextColor, UiMenuBgColor)); - TuiDrawCenteredText(Left + 2, Top + 2, Right - 2, Top + 2, ProgressText, ATTR(UiTextColor, UiMenuBgColor)); + // + // Minimal UI has no box, and only generic loading text + // + if (!UiMinimal) + { + // Draw the box + TuiDrawBox(Left, Top, Right, Bottom, VERT, HORZ, TRUE, TRUE, ATTR(UiMenuFgColor, UiMenuBgColor)); + + // + // Draw the "Loading..." text + // + TuiDrawCenteredText(Left + 2, Top + 2, Right - 2, Top + 2, ProgressText, ATTR(UiTextColor, UiMenuBgColor)); + } + else + { + // + // Draw the "Loading..." text + // + TuiDrawCenteredText(Left + 2, Top + 1, Right - 2, Top + 1, "ReactOS is loading files...", ATTR(7, 0)); + } // Draw the percent complete for (i=0; i<(Position*ProgressBarWidth)/Range; i++) @@ -698,14 +759,16 @@ VOID TuiDrawProgressBar(ULONG Left, ULONG Top, ULONG Right, ULONG Bottom, ULONG TuiDrawText(Left+2+i, Top+2, "\xDB", ATTR(UiTextColor, UiMenuBgColor)); } - // Draw the rest - for (; i - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: FreeLoader + * FILE: freeldr/ui/tuimenu.c + * PURPOSE: UI Menu Functions + * PROGRAMMERS: Alex Ionescu (alex@relsoft.net) + * Brian Palmer (brianp@sginet.com) */ +/* INCLUDES ******************************************************************/ + #include -BOOL TuiDisplayMenu(PCSTR MenuItemList[], ULONG MenuItemCount, ULONG DefaultMenuItem, LONG MenuTimeOut, ULONG* SelectedMenuItem, BOOL CanEscape, UiMenuKeyPressFilterCallback KeyPressFilter) +/* FUNCTIONS *****************************************************************/ + +BOOL +WINAPI +TuiDisplayMenu(PCSTR MenuItemList[], + ULONG MenuItemCount, + ULONG DefaultMenuItem, + LONG MenuTimeOut, + ULONG* SelectedMenuItem, + BOOL CanEscape, + UiMenuKeyPressFilterCallback KeyPressFilter) { - TUI_MENU_INFO MenuInformation; - ULONG LastClockSecond; - ULONG CurrentClockSecond; - ULONG KeyPress; - - // - // The first thing we need to check is the timeout - // If it's zero then don't bother with anything, - // just return the default item - // - if (MenuTimeOut == 0) - { - if (SelectedMenuItem != NULL) - { - *SelectedMenuItem = DefaultMenuItem; - } - - return TRUE; - } - - // - // Setup the MENU_INFO structure - // - MenuInformation.MenuItemList = MenuItemList; - MenuInformation.MenuItemCount = MenuItemCount; - MenuInformation.MenuTimeRemaining = MenuTimeOut; - MenuInformation.SelectedMenuItem = DefaultMenuItem; - - // - // Calculate the size of the menu box - // - TuiCalcMenuBoxSize(&MenuInformation); - - // - // Draw the menu - // - TuiDrawMenu(&MenuInformation); - - // - // Get the current second of time - // - MachRTCGetCurrentDateTime(NULL, NULL, NULL, NULL, NULL, &LastClockSecond); - - // - // Process keys - // - while (1) - { - // - // Process key presses - // - KeyPress = TuiProcessMenuKeyboardEvent(&MenuInformation, KeyPressFilter); - if (KeyPress == KEY_ENTER) - { - // - // If they pressed enter then exit this loop - // - break; - } - else if (CanEscape && KeyPress == KEY_ESC) - { - // - // They pressed escape, so just return FALSE - // - return FALSE; - } - - // - // Update the date & time - // - TuiUpdateDateTime(); - - VideoCopyOffScreenBufferToVRAM(); - - if (MenuInformation.MenuTimeRemaining > 0) - { - MachRTCGetCurrentDateTime(NULL, NULL, NULL, NULL, NULL, &CurrentClockSecond); - if (CurrentClockSecond != LastClockSecond) - { - // - // Update the time information - // - LastClockSecond = CurrentClockSecond; - MenuInformation.MenuTimeRemaining--; - - // - // Update the menu - // - TuiDrawMenuBox(&MenuInformation); - - VideoCopyOffScreenBufferToVRAM(); - } - } - else if (MenuInformation.MenuTimeRemaining == 0) - { - // - // A time out occurred, exit this loop and return default OS - // - break; - } - } - - // - // Update the selected menu item information - // - if (SelectedMenuItem != NULL) - { - *SelectedMenuItem = MenuInformation.SelectedMenuItem; - } - - return TRUE; + TUI_MENU_INFO MenuInformation; + ULONG LastClockSecond; + ULONG CurrentClockSecond; + ULONG KeyPress; + + // + // Check if there's no timeout + if (!MenuTimeOut) + { + // + // Return the default selected item + // + if (SelectedMenuItem) *SelectedMenuItem = DefaultMenuItem; + return TRUE; + } + + // + // Setup the MENU_INFO structure + // + MenuInformation.MenuItemList = MenuItemList; + MenuInformation.MenuItemCount = MenuItemCount; + MenuInformation.MenuTimeRemaining = MenuTimeOut; + MenuInformation.SelectedMenuItem = DefaultMenuItem; + + // + // Calculate the size of the menu box + // + TuiCalcMenuBoxSize(&MenuInformation); + + // + // Draw the menu + // + TuiDrawMenu(&MenuInformation); + + // + // Get the current second of time + // + MachRTCGetCurrentDateTime(NULL, NULL, NULL, NULL, NULL, &LastClockSecond); + + // + // Process keys + // + while (TRUE) + { + // + // Process key presses + // + KeyPress = TuiProcessMenuKeyboardEvent(&MenuInformation, + KeyPressFilter); + + // + // Check for ENTER or ESC + // + if (KeyPress == KEY_ENTER) break; + if (CanEscape && KeyPress == KEY_ESC) return FALSE; + + // + // Update the date & time + // + TuiUpdateDateTime(); + VideoCopyOffScreenBufferToVRAM(); + + // + // Check if there is a countdown + // + if (MenuInformation.MenuTimeRemaining) + { + // + // Get the updated time, seconds only + // + MachRTCGetCurrentDateTime(NULL, + NULL, + NULL, + NULL, + NULL, + &CurrentClockSecond); + + // + // Check if more then a second has now elapsed + // + if (CurrentClockSecond != LastClockSecond) + { + // + // Update the time information + // + LastClockSecond = CurrentClockSecond; + MenuInformation.MenuTimeRemaining--; + + // + // Update the menu + // + TuiDrawMenuBox(&MenuInformation); + VideoCopyOffScreenBufferToVRAM(); + } + } + else + { + // + // A time out occurred, exit this loop and return default OS + // + break; + } + } + + // + // Return the selected item + // + if (SelectedMenuItem) *SelectedMenuItem = MenuInformation.SelectedMenuItem; + return TRUE; } -VOID TuiCalcMenuBoxSize(PTUI_MENU_INFO MenuInfo) +VOID +WINAPI +TuiCalcMenuBoxSize(PTUI_MENU_INFO MenuInfo) { - ULONG Idx; - ULONG Width; - ULONG Height; - ULONG Length; - - // - // Height is the menu item count plus 2 (top border & bottom border) - // - Height = MenuInfo->MenuItemCount + 2; - Height -= 1; // Height is zero-based - - // - // Find the length of the longest string in the menu - // - Width = 0; - for(Idx=0; IdxMenuItemCount; Idx++) - { - Length = strlen(MenuInfo->MenuItemList[Idx]); - - if (Length > Width) - { - Width = Length; - } - } - - // - // Allow room for left & right borders, plus 8 spaces on each side - // - Width += 18; - - // - // Calculate the menu box area - // - MenuInfo->Left = (UiScreenWidth - Width) / 2; - MenuInfo->Right = (MenuInfo->Left) + Width; - MenuInfo->Top = (((UiScreenHeight - TUI_TITLE_BOX_CHAR_HEIGHT) - Height) / 2) + TUI_TITLE_BOX_CHAR_HEIGHT; - MenuInfo->Bottom = (MenuInfo->Top) + Height; + ULONG i; + ULONG Width = 0; + ULONG Height; + ULONG Length; + + // + // Height is the menu item count plus 2 (top border & bottom border) + // + Height = MenuInfo->MenuItemCount + 2; + Height -= 1; // Height is zero-based + + // + // Loop every item + // + for(i = 0; i < MenuInfo->MenuItemCount; i++) + { + // + // Get the string length and make it become the new width if necessary + // + Length = strlen(MenuInfo->MenuItemList[i]); + if (Length > Width) Width = Length; + } + + // + // Allow room for left & right borders, plus 8 spaces on each side + // + Width += 18; + + // + // Check if we're drawing a centered menu + // + if (UiCenterMenu) + { + // + // Calculate the menu box area for a centered menu + // + MenuInfo->Left = (UiScreenWidth - Width) / 2; + MenuInfo->Top = (((UiScreenHeight - TUI_TITLE_BOX_CHAR_HEIGHT) - + Height) / 2) + TUI_TITLE_BOX_CHAR_HEIGHT; + } + else + { + // + // Put the menu in the default left-corner position + // + MenuInfo->Left = -1; + MenuInfo->Top = 4; + } + + // + // The other margins are the same + // + MenuInfo->Right = (MenuInfo->Left) + Width; + MenuInfo->Bottom = (MenuInfo->Top) + Height; } -VOID TuiDrawMenu(PTUI_MENU_INFO MenuInfo) +VOID +WINAPI +TuiDrawMenu(PTUI_MENU_INFO MenuInfo) { - ULONG Idx; - - // - // Draw the backdrop - // - UiDrawBackdrop(); - - // - // Update the status bar - // - UiDrawStatusText("Use \x18\x19 to select, then press ENTER."); - - // - // Draw the menu box - // - TuiDrawMenuBox(MenuInfo); - - // - // Draw each line of the menu - // - for (Idx=0; IdxMenuItemCount; Idx++) - { - TuiDrawMenuItem(MenuInfo, Idx); - } - - VideoCopyOffScreenBufferToVRAM(); + ULONG i; + + // + // Draw the backdrop + // + UiDrawBackdrop(); + + // + // Check if this is the minimal (console) UI + // + if (UiMinimal) + { + // + // No GUI status bar text, just minimal text. first to tell the user to + // choose. + // + TuiDrawText(0, + MenuInfo->Top - 2, + "Please select the operating system to start:", + ATTR(UiMenuFgColor, UiMenuBgColor)); + + // + // Now tell him how to choose + // + TuiDrawText(0, + MenuInfo->Bottom + 1, + "Use the up and down arrow keys to move the highlight to " + "your choice.", + ATTR(UiMenuFgColor, UiMenuBgColor)); + TuiDrawText(0, + MenuInfo->Bottom + 2, + "Press ENTER to choose.", + ATTR(UiMenuFgColor, UiMenuBgColor)); + + // + // And offer F8 options + // + TuiDrawText(0, + UiScreenHeight - 4, + "For troubleshooting and advanced startup options for " + "ReactOS, press F8.", + ATTR(UiMenuFgColor, UiMenuBgColor)); + } + else + { + // + // Update the status bar + // + UiDrawStatusText("Use \x18\x19 to select, then press ENTER."); + } + + // + // Draw the menu box + // + TuiDrawMenuBox(MenuInfo); + + // + // Draw each line of the menu + // + for (i = 0; i < MenuInfo->MenuItemCount; i++) TuiDrawMenuItem(MenuInfo, i); + VideoCopyOffScreenBufferToVRAM(); } -VOID TuiDrawMenuBox(PTUI_MENU_INFO MenuInfo) +VOID +WINAPI +TuiDrawMenuBox(PTUI_MENU_INFO MenuInfo) { - CHAR MenuLineText[80]; - CHAR TempString[80]; - ULONG Idx; - - // - // Draw the menu box - // - UiDrawBox(MenuInfo->Left, - MenuInfo->Top, - MenuInfo->Right, - MenuInfo->Bottom, - D_VERT, - D_HORZ, - FALSE, // Filled - TRUE, // Shadow - ATTR(UiMenuFgColor, UiMenuBgColor)); - - // - // If there is a timeout draw the time remaining - // - if (MenuInfo->MenuTimeRemaining >= 0) - { - strcpy(MenuLineText, "[ Time Remaining: "); - _itoa(MenuInfo->MenuTimeRemaining, TempString, 10); - strcat(MenuLineText, TempString); - strcat(MenuLineText, " ]"); - - UiDrawText(MenuInfo->Right - strlen(MenuLineText) - 1, - MenuInfo->Bottom, - MenuLineText, - ATTR(UiMenuFgColor, UiMenuBgColor)); - } - - // - // Now draw the separators - // - for (Idx=0; IdxMenuItemCount; Idx++) - { - if (_stricmp(MenuInfo->MenuItemList[Idx], "SEPARATOR") == 0) - { - UiDrawText(MenuInfo->Left, MenuInfo->Top + Idx + 1, "\xC7", ATTR(UiMenuFgColor, UiMenuBgColor)); - UiDrawText(MenuInfo->Right, MenuInfo->Top + Idx + 1, "\xB6", ATTR(UiMenuFgColor, UiMenuBgColor)); - } - } + CHAR MenuLineText[80]; + CHAR TempString[80]; + ULONG i; + + // + // Draw the menu box if requested + // + if (UiMenuBox) + { + UiDrawBox(MenuInfo->Left, + MenuInfo->Top, + MenuInfo->Right, + MenuInfo->Bottom, + D_VERT, + D_HORZ, + FALSE, // Filled + TRUE, // Shadow + ATTR(UiMenuFgColor, UiMenuBgColor)); + } + + // + // If there is a timeout draw the time remaining + // + if (MenuInfo->MenuTimeRemaining >= 0) + { + // + // Copy the integral time text string, and remove the last 2 chars + // + strcpy(TempString, UiTimeText); + i = strlen(TempString); + TempString[i - 2] = 0; + + // + // Display the first part of the string and the remaining time + // + strcpy(MenuLineText, TempString); + _itoa(MenuInfo->MenuTimeRemaining, TempString, 10); + strcat(MenuLineText, TempString); + + // + // Add the last 2 chars + // + strcat(MenuLineText, &UiTimeText[i - 2]); + + // + // Check if this is a centered menu + // + if (UiCenterMenu) + { + // + // Display it in the center of the menu + // + UiDrawText(MenuInfo->Right - strlen(MenuLineText) - 1, + MenuInfo->Bottom, + MenuLineText, + ATTR(UiMenuFgColor, UiMenuBgColor)); + } + else + { + // + // Display under the menu directly + // + UiDrawText(0, + MenuInfo->Bottom + 3, + MenuLineText, + ATTR(UiMenuFgColor, UiMenuBgColor)); + } + } + + // + // Loop each item + // + for (i = 0; i < MenuInfo->MenuItemCount; i++) + { + // + // Check if it's a separator + // + if (!(_stricmp(MenuInfo->MenuItemList[i], "SEPARATOR"))) + { + // + // Draw the separator line + // + UiDrawText(MenuInfo->Left, + MenuInfo->Top + i + 1, + "\xC7", + ATTR(UiMenuFgColor, UiMenuBgColor)); + UiDrawText(MenuInfo->Right, + MenuInfo->Top + i + 1, + "\xB6", + ATTR(UiMenuFgColor, UiMenuBgColor)); + } + } } -VOID TuiDrawMenuItem(PTUI_MENU_INFO MenuInfo, ULONG MenuItemNumber) +VOID +WINAPI +TuiDrawMenuItem(PTUI_MENU_INFO MenuInfo, + ULONG MenuItemNumber) { - ULONG Idx; - CHAR MenuLineText[80]; - ULONG SpaceTotal; - ULONG SpaceLeft; - ULONG SpaceRight; - UCHAR Attribute; - - // - // We will want the string centered so calculate - // how many spaces will be to the left and right - // - SpaceTotal = (MenuInfo->Right - MenuInfo->Left - 2) - strlen(MenuInfo->MenuItemList[MenuItemNumber]); - SpaceLeft = (SpaceTotal / 2) + 1; - SpaceRight = (SpaceTotal - SpaceLeft) + 1; - - // - // Insert the spaces on the left - // - for (Idx=0; IdxMenuItemList[MenuItemNumber]); - - // - // Now append the spaces on the right - // - for (Idx=0; IdxMenuItemList[MenuItemNumber], "SEPARATOR") == 0) - { - memset(MenuLineText, 0, 80); - memset(MenuLineText, 0xC4, (MenuInfo->Right - MenuInfo->Left - 1)); - Attribute = ATTR(UiMenuFgColor, UiMenuBgColor); - } - else - { - Attribute = ATTR(UiTextColor, UiMenuBgColor); - } - - // - // If this is the selected menu item then draw it as selected - // otherwise just draw it using the normal colors - // - if (MenuItemNumber == MenuInfo->SelectedMenuItem) - { - UiDrawText(MenuInfo->Left + 1, - MenuInfo->Top + 1 + MenuItemNumber, - MenuLineText, - ATTR(UiSelectedTextColor, UiSelectedTextBgColor)); - } - else - { - UiDrawText(MenuInfo->Left + 1, - MenuInfo->Top + 1 + MenuItemNumber, - MenuLineText, - Attribute); - } + ULONG i; + CHAR MenuLineText[80]; + ULONG SpaceTotal; + ULONG SpaceLeft; + ULONG SpaceRight = 0; + UCHAR Attribute = ATTR(UiTextColor, UiMenuBgColor); + + // + // Check if using centered menu + // + if (UiCenterMenu) + { + // + // We will want the string centered so calculate + // how many spaces will be to the left and right + // + SpaceTotal = (MenuInfo->Right - MenuInfo->Left - 2) - + strlen(MenuInfo->MenuItemList[MenuItemNumber]); + SpaceLeft = (SpaceTotal / 2) + 1; + SpaceRight = (SpaceTotal - SpaceLeft) + 1; + + // + // Insert the spaces on the left + // + for (i = 0; i < SpaceLeft; i++) MenuLineText[i] = ' '; + MenuLineText[i] = '\0'; + } + else + { + // + // Simply left-align it + // + MenuLineText[0] = '\0'; + strcat(MenuLineText, " "); + } + + // + // Now append the text string + // + strcat(MenuLineText, MenuInfo->MenuItemList[MenuItemNumber]); + + // + // Check if using centered menu, and add spaces on the right if so + // + if (UiCenterMenu) for (i=0; i < SpaceRight; i++) strcat(MenuLineText, " "); + + // + // If it is a separator + // + if (!(_stricmp(MenuInfo->MenuItemList[MenuItemNumber], "SEPARATOR"))) + { + // + // Make it a separator line and use menu colors + // + memset(MenuLineText, 0, 80); + memset(MenuLineText, 0xC4, (MenuInfo->Right - MenuInfo->Left - 1)); + Attribute = ATTR(UiMenuFgColor, UiMenuBgColor); + } + else if (MenuItemNumber == MenuInfo->SelectedMenuItem) + { + // + // If this is the selected item, use the selected colors + // + Attribute = ATTR(UiSelectedTextColor, UiSelectedTextBgColor); + } + + // + // Draw the item + // + UiDrawText(MenuInfo->Left + 1, + MenuInfo->Top + 1 + MenuItemNumber, + MenuLineText, + Attribute); } -ULONG TuiProcessMenuKeyboardEvent(PTUI_MENU_INFO MenuInfo, UiMenuKeyPressFilterCallback KeyPressFilter) +ULONG +WINAPI +TuiProcessMenuKeyboardEvent(PTUI_MENU_INFO MenuInfo, + UiMenuKeyPressFilterCallback KeyPressFilter) { - ULONG KeyEvent = 0; - - // - // Check for a keypress - // - if (MachConsKbHit()) - { - // - // Cancel the timeout - // - if (MenuInfo->MenuTimeRemaining != -1) - { - MenuInfo->MenuTimeRemaining = -1; - TuiDrawMenuBox(MenuInfo); - } - - // - // Get the key - // - KeyEvent = MachConsGetCh(); - - // - // Is it extended? - // - if (KeyEvent == 0) - KeyEvent = MachConsGetCh(); // Yes - so get the extended key - - // - // Call the supplied key filter callback function to see - // if it is going to handle this keypress. - // - if (KeyPressFilter != NULL) - { - if (KeyPressFilter(KeyEvent)) - { - // It processed the key character - TuiDrawMenu(MenuInfo); - - return 0; - } - } - - // - // Process the key - // - switch (KeyEvent) - { - case KEY_UP: - - if (MenuInfo->SelectedMenuItem > 0) - { - MenuInfo->SelectedMenuItem--; - - // - // Update the menu - // - TuiDrawMenuItem(MenuInfo, MenuInfo->SelectedMenuItem + 1); // Deselect previous item - - // Skip past any separators - if (MenuInfo->SelectedMenuItem > 0 && _stricmp(MenuInfo->MenuItemList[MenuInfo->SelectedMenuItem], "SEPARATOR") == 0) - { - MenuInfo->SelectedMenuItem--; - } - - TuiDrawMenuItem(MenuInfo, MenuInfo->SelectedMenuItem); // Select new item - } - - break; - - case KEY_DOWN: - - if (MenuInfo->SelectedMenuItem < (MenuInfo->MenuItemCount - 1)) - { - MenuInfo->SelectedMenuItem++; - - // - // Update the menu - // - TuiDrawMenuItem(MenuInfo, MenuInfo->SelectedMenuItem - 1); // Deselect previous item - - // Skip past any separators - if (MenuInfo->SelectedMenuItem < (MenuInfo->MenuItemCount - 1) && _stricmp(MenuInfo->MenuItemList[MenuInfo->SelectedMenuItem], "SEPARATOR") == 0) - { - MenuInfo->SelectedMenuItem++; - } - - TuiDrawMenuItem(MenuInfo, MenuInfo->SelectedMenuItem); // Select new item - } - - break; - } - - VideoCopyOffScreenBufferToVRAM(); - } - - return KeyEvent; + ULONG KeyEvent = 0; + ULONG Selected, Count; + + // + // Check for a keypress + // + if (MachConsKbHit()) + { + // + // Check if the timeout is not already complete + // + if (MenuInfo->MenuTimeRemaining != -1) + { + // + // Cancel it and remove it + // + MenuInfo->MenuTimeRemaining = -1; + TuiDrawMenuBox(MenuInfo); // FIXME: Remove for minimal UI too + } + + // + // Get the key + // + KeyEvent = MachConsGetCh(); + + // + // Is it extended? Then get the extended key + // + if (!KeyEvent) KeyEvent = MachConsGetCh(); + + // + // Call the supplied key filter callback function to see + // if it is going to handle this keypress. + // + if ((KeyPressFilter) && (KeyPressFilter(KeyEvent))) + { + // + // It processed the key character, so redraw and exit + // + TuiDrawMenu(MenuInfo); + return 0; + } + + // + // Process the key + // + if ((KeyEvent == KEY_UP) || (KeyEvent == KEY_DOWN)) + { + // + // Get the current selected item and count + // + Selected = MenuInfo->SelectedMenuItem; + Count = MenuInfo->MenuItemCount - 1; + + // + // Check if this was a key up and there's a selected menu item + // + if ((KeyEvent == KEY_UP) && (Selected)) + { + // + // Update the menu (Deselect previous item) + // + MenuInfo->SelectedMenuItem--; + TuiDrawMenuItem(MenuInfo, Selected); + Selected--; + + // Skip past any separators + if ((Selected) && + !(_stricmp(MenuInfo->MenuItemList[Selected], "SEPARATOR"))) + { + MenuInfo->SelectedMenuItem--; + } + } + else if ((KeyEvent == KEY_DOWN) && (Selected < Count)) + { + // + // Update the menu (deselect previous item) + // + MenuInfo->SelectedMenuItem++; + TuiDrawMenuItem(MenuInfo, Selected); + Selected++; + + // Skip past any separators + if ((Selected < Count) && + !(_stricmp(MenuInfo->MenuItemList[Selected], "SEPARATOR"))) + { + MenuInfo->SelectedMenuItem++; + } + } + + // + // Select new item and update video buffer + // + TuiDrawMenuItem(MenuInfo, MenuInfo->SelectedMenuItem); + VideoCopyOffScreenBufferToVRAM(); + } + } + + // + // Return the pressed key + // + return KeyEvent; } diff --git a/reactos/boot/freeldr/freeldr/ui/ui.c b/reactos/boot/freeldr/freeldr/ui/ui.c index 93ccd69aca8..299f817bd0c 100644 --- a/reactos/boot/freeldr/freeldr/ui/ui.c +++ b/reactos/boot/freeldr/freeldr/ui/ui.c @@ -50,6 +50,11 @@ BOOL UserInterfaceUp = FALSE; // Tells us if the user interface is display VIDEODISPLAYMODE UiDisplayMode = VideoTextMode; // Tells us if we are in text or graphics mode BOOL UiUseSpecialEffects = FALSE; // Tells us if we should use fade effects +BOOL UiDrawTime = TRUE; // Tells us if we should draw the time +BOOL UiMinimal = FALSE; // Tells us if we should use a minimal console-like UI +BOOL UiCenterMenu = TRUE; // Tells us if we should use a centered or left-aligned menu +BOOL UiMenuBox = TRUE; // Tells us if we shuld draw a box around the menu +CHAR UiTimeText[260] = "[Time Remaining: ] "; const CHAR UiMonthNames[12][15] = { "January ", "February ", "March ", "April ", "May ", "June ", "July ", "August ", "September ", "October ", "November ", "December " }; @@ -87,6 +92,10 @@ BOOL UiInitialize(BOOLEAN ShowGui) { strcpy(UiTitleBoxTitleText, SettingText); } + if (IniReadSettingByName(SectionId, "TimeText", SettingText, 260)) + { + strcpy(UiTimeText, SettingText); + } if (IniReadSettingByName(SectionId, "StatusBarColor", SettingText, 260)) { UiStatusBarBgColor = UiTextToColor(SettingText); @@ -162,6 +171,50 @@ BOOL UiInitialize(BOOLEAN ShowGui) UiUseSpecialEffects = FALSE; } } + if (IniReadSettingByName(SectionId, "ShowTime", SettingText, 260)) + { + if (_stricmp(SettingText, "Yes") == 0 && strlen(SettingText) == 3) + { + UiDrawTime = TRUE; + } + else + { + UiDrawTime = FALSE; + } + } + if (IniReadSettingByName(SectionId, "MinimalUI", SettingText, 260)) + { + if (_stricmp(SettingText, "Yes") == 0 && strlen(SettingText) == 3) + { + UiMinimal = TRUE; + } + else + { + UiMinimal = FALSE; + } + } + if (IniReadSettingByName(SectionId, "MenuBox", SettingText, 260)) + { + if (_stricmp(SettingText, "Yes") == 0 && strlen(SettingText) == 3) + { + UiMenuBox = TRUE; + } + else + { + UiMenuBox = FALSE; + } + } + if (IniReadSettingByName(SectionId, "CenterMenu", SettingText, 260)) + { + if (_stricmp(SettingText, "Yes") == 0 && strlen(SettingText) == 3) + { + UiCenterMenu = TRUE; + } + else + { + UiCenterMenu = FALSE; + } + } } UiDisplayMode = MachVideoSetDisplayMode(DisplayModeText, TRUE); diff --git a/reactos/hal/halx86/generic/display.c b/reactos/hal/halx86/generic/display.c index 48e3f44938e..bf89c63e6c4 100644 --- a/reactos/hal/halx86/generic/display.c +++ b/reactos/hal/halx86/generic/display.c @@ -171,7 +171,7 @@ #define CHAR_ATTRIBUTE_BLACK 0x00 /* black on black */ -#define CHAR_ATTRIBUTE 0x17 /* grey on blue */ +#define CHAR_ATTRIBUTE 0x07 /* grey on black */ #define FONT_AMOUNT (8*8192) diff --git a/reactos/hal/halx86/generic/halinit.c b/reactos/hal/halx86/generic/halinit.c index dfebdd72719..12f440c2c57 100644 --- a/reactos/hal/halx86/generic/halinit.c +++ b/reactos/hal/halx86/generic/halinit.c @@ -53,8 +53,7 @@ HalInitSystem (ULONG BootPhase, else if (BootPhase == 2) { /* Go to blue screen */ - HalClearDisplay (0x17); /* grey on blue */ - + HalpZeroPageMapping = MmMapIoSpace((LARGE_INTEGER)0LL, PAGE_SIZE, MmNonCached); } diff --git a/reactos/ntoskrnl/ex/init.c b/reactos/ntoskrnl/ex/init.c index 18367b0f00d..2847aaf9b56 100644 --- a/reactos/ntoskrnl/ex/init.c +++ b/reactos/ntoskrnl/ex/init.c @@ -29,6 +29,7 @@ extern LIST_ENTRY KiProfileListHead; extern LIST_ENTRY KiProfileSourceListHead; extern KSPIN_LOCK KiProfileLock; BOOLEAN SetupMode = TRUE; +BOOLEAN NoGuiBoot = FALSE; VOID PspPostInitSystemProcess(VOID); @@ -497,7 +498,6 @@ ExpInitializeExecutive(VOID) UNICODE_STRING EventName; HANDLE InitDoneEventHandle; OBJECT_ATTRIBUTES ObjectAttributes; - BOOLEAN NoGuiBoot = FALSE; BOOLEAN BootLog = FALSE; ULONG MaxMem = 0; BOOLEAN ForceAcpiDisable = FALSE; @@ -532,7 +532,6 @@ ExpInitializeExecutive(VOID) /* Parse the Loaded Modules (by FreeLoader) and cache the ones we'll need */ ParseAndCacheLoadedModules(); - /* Initialize the Dispatcher, Clock and Bug Check Mechanisms. */ KeInit2(); @@ -631,7 +630,7 @@ ExpInitializeExecutive(VOID) HalInitSystem(2, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock); /* Display version number and copyright/warranty message */ - ExpDisplayNotice(); + if (NoGuiBoot) ExpDisplayNotice(); /* Call KD Providers at Phase 2 */ KdInitSystem(2, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock); @@ -727,7 +726,10 @@ ExpInitializeExecutive(VOID) KEBUGCHECKEX(SESSION5_INITIALIZATION_FAILED, Status, 0, 0, 0); } - /* Disable the Boot Logo */ + /* + * FIXME: FILIP! + * Disable the Boot Logo + */ if (!NoGuiBoot) InbvEnableBootDriver(FALSE); /* Signal the Event and close the handle */ diff --git a/reactos/ntoskrnl/io/driver.c b/reactos/ntoskrnl/io/driver.c index 3684ac83713..862d9825647 100644 --- a/reactos/ntoskrnl/io/driver.c +++ b/reactos/ntoskrnl/io/driver.c @@ -18,6 +18,7 @@ extern LOADER_PARAMETER_BLOCK KeLoaderBlock; extern ULONG KeTickCount; extern BOOLEAN SetupMode; +extern BOOLEAN NoGuiBoot; typedef struct _SERVICE_GROUP { @@ -372,7 +373,7 @@ IopDisplayLoadingMessage(PVOID ServiceName, BOOLEAN Unicode) { CHAR TextBuffer[256]; - if (SetupMode) return; + if (SetupMode || !NoGuiBoot) return; if (Unicode) { sprintf(TextBuffer, "Loading %S...\n", (PWCHAR)ServiceName);