From 8eff90f521cfbc56dfb421d6d8c0f2e58e26fb6d Mon Sep 17 00:00:00 2001 From: srs5694 Date: Thu, 20 Dec 2012 21:26:25 -0500 Subject: [PATCH] Fixes to obscure and subtle bugs in code that sets screen resolution. --- NEWS.txt | 2 ++ libeg/libeg.h | 2 +- libeg/screen.c | 79 ++++++++++++++++++++++++++++--------------------- refind/config.c | 2 ++ refind/main.c | 5 ++-- refind/screen.c | 43 +++++++++++++++++++-------- 6 files changed, 83 insertions(+), 50 deletions(-) diff --git a/NEWS.txt b/NEWS.txt index e249ef8..0412d80 100644 --- a/NEWS.txt +++ b/NEWS.txt @@ -1,6 +1,8 @@ 0.6.1 (12/??/2012): ------------------- +- Fixed some screen resolution-setting bugs. + - Added the "words" that make up a filesystem's label (delimited by spaces, dashes, or underscores) to the list of bases used to search for OS icons. For instance, if the filesystem's label is "Arch", rEFInd searches for diff --git a/libeg/libeg.h b/libeg/libeg.h index e993ee1..a354aa3 100644 --- a/libeg/libeg.h +++ b/libeg/libeg.h @@ -124,7 +124,7 @@ VOID egDrawImageArea(IN EG_IMAGE *Image, VOID egDisplayMessage(IN CHAR16 *Text, EG_PIXEL *BGColor); VOID egScreenShot(VOID); //UINT32 egGetGraphicsMode(VOID); -UINT32 egSetTextMode(UINT32 RequestedMode); +BOOLEAN egSetTextMode(UINT32 RequestedMode); #endif /* __LIBEG_LIBEG_H__ */ diff --git a/libeg/screen.c b/libeg/screen.c index e4f585a..84062db 100644 --- a/libeg/screen.c +++ b/libeg/screen.c @@ -73,24 +73,10 @@ static UINTN egScreenHeight = 600; // Screen handling // -VOID egInitScreen(VOID) -{ +static VOID egDetermineScreenSize(VOID) { EFI_STATUS Status = EFI_SUCCESS; UINT32 UGAWidth, UGAHeight, UGADepth, UGARefreshRate; - // get protocols - Status = LibLocateProtocol(&ConsoleControlProtocolGuid, (VOID **) &ConsoleControl); - if (EFI_ERROR(Status)) - ConsoleControl = NULL; - - Status = LibLocateProtocol(&UgaDrawProtocolGuid, (VOID **) &UgaDraw); - if (EFI_ERROR(Status)) - UgaDraw = NULL; - - Status = LibLocateProtocol(&GraphicsOutputProtocolGuid, (VOID **) &GraphicsOutput); - if (EFI_ERROR(Status)) - GraphicsOutput = NULL; - // get screen size egHasGraphics = FALSE; if (GraphicsOutput != NULL) { @@ -109,6 +95,26 @@ VOID egInitScreen(VOID) } } +VOID egInitScreen(VOID) +{ + EFI_STATUS Status = EFI_SUCCESS; + + // get protocols + Status = LibLocateProtocol(&ConsoleControlProtocolGuid, (VOID **) &ConsoleControl); + if (EFI_ERROR(Status)) + ConsoleControl = NULL; + + Status = LibLocateProtocol(&UgaDrawProtocolGuid, (VOID **) &UgaDraw); + if (EFI_ERROR(Status)) + UgaDraw = NULL; + + Status = LibLocateProtocol(&GraphicsOutputProtocolGuid, (VOID **) &GraphicsOutput); + if (EFI_ERROR(Status)) + GraphicsOutput = NULL; + + egDetermineScreenSize(); +} + // Sets the screen resolution to the specified value, if possible. If *ScreenHeight // is 0 and GOP mode is detected, assume that *ScreenWidth contains a GOP mode // number rather than a horizontal resolution. If the specified resolution is not @@ -128,11 +134,11 @@ BOOLEAN egSetScreenSize(IN OUT UINTN *ScreenWidth, IN OUT UINTN *ScreenHeight) { if (GraphicsOutput != NULL) { // GOP mode (UEFI) if (*ScreenHeight == 0) { // User specified a mode number (stored in *ScreenWidth); use it directly - if (*ScreenWidth == GraphicsOutput->Mode->Mode) { // user requested current mode; do nothing - ModeSet = TRUE; - *ScreenWidth = Info->HorizontalResolution; - *ScreenHeight = Info->VerticalResolution; - } else { +// if ((*ScreenWidth == GraphicsOutput->Mode->Mode)) { // user requested current mode; do nothing +// ModeSet = TRUE; +// *ScreenWidth = Info->HorizontalResolution; +// *ScreenHeight = Info->VerticalResolution; +// } else { ModeNum = (UINT32) *ScreenWidth; Status = refit_call4_wrapper(GraphicsOutput->QueryMode, GraphicsOutput, ModeNum, &Size, &Info); if (Status == EFI_SUCCESS) { @@ -143,15 +149,15 @@ BOOLEAN egSetScreenSize(IN OUT UINTN *ScreenWidth, IN OUT UINTN *ScreenHeight) { *ScreenHeight = Info->VerticalResolution; } // if set mode OK } // if queried mode OK - } // if/else +// } // if/else // User specified width & height; must find mode -- but only if change is required.... } else { Status = refit_call4_wrapper(GraphicsOutput->QueryMode, GraphicsOutput, GraphicsOutput->Mode->Mode, &Size, &Info); - if ((Status == EFI_SUCCESS) && (Info->HorizontalResolution == *ScreenWidth) && - (Info->VerticalResolution == *ScreenHeight)) { - ModeSet = TRUE; // user requested current mode; do nothing - } else { +// if ((Status == EFI_SUCCESS) && (Info->HorizontalResolution == *ScreenWidth) && +// (Info->VerticalResolution == *ScreenHeight) && !AlwaysSet) { +// ModeSet = TRUE; // user requested current mode; do nothing +// } else { // Do a loop through the modes to see if the specified one is available; // and if so, switch to it.... do { @@ -162,7 +168,7 @@ BOOLEAN egSetScreenSize(IN OUT UINTN *ScreenWidth, IN OUT UINTN *ScreenHeight) { ModeSet = (Status == EFI_SUCCESS); } // if } while ((++ModeNum < GraphicsOutput->Mode->MaxMode) && !ModeSet); - } // if/else +// } // if/else } // if/else if (ModeSet) { @@ -203,24 +209,28 @@ BOOLEAN egSetScreenSize(IN OUT UINTN *ScreenWidth, IN OUT UINTN *ScreenHeight) { VOID egGetScreenSize(OUT UINTN *ScreenWidth, OUT UINTN *ScreenHeight) { + egDetermineScreenSize(); + if (ScreenWidth != NULL) *ScreenWidth = egScreenWidth; if (ScreenHeight != NULL) *ScreenHeight = egScreenHeight; } -// Set a text mode -// Returns the mode that was actually set. -UINT32 egSetTextMode(UINT32 RequestedMode) { +// Set a text mode. +// Returns TRUE if the mode actually changed, FALSE otherwise. +// Note that a FALSE return value can mean either an error or no change +// necessary. +BOOLEAN egSetTextMode(UINT32 RequestedMode) { UINTN i = 0, Width, Height; - UINT32 UsedMode = ST->ConOut->Mode->Mode; EFI_STATUS Status; + BOOLEAN ChangedIt = FALSE; if (RequestedMode != ST->ConOut->Mode->Mode) { - SwitchToGraphics(); +// SwitchToGraphics(); Status = refit_call2_wrapper(ST->ConOut->SetMode, ST->ConOut, RequestedMode); if (Status == EFI_SUCCESS) { - UsedMode = RequestedMode; + ChangedIt = TRUE; } else { SwitchToText(FALSE); Print(L"Error setting text mode %d; available modes are:\n", RequestedMode); @@ -234,8 +244,8 @@ UINT32 egSetTextMode(UINT32 RequestedMode) { SwitchToGraphics(); } // if/else successful change } // if need to change mode - return UsedMode; -} // UINT32 egSetTextMode() + return ChangedIt; +} // BOOLEAN egSetTextMode() CHAR16 * egScreenDescription(VOID) { @@ -290,6 +300,7 @@ VOID egSetGraphicsModeEnabled(IN BOOLEAN Enable) EFI_CONSOLE_CONTROL_SCREEN_MODE CurrentMode; EFI_CONSOLE_CONTROL_SCREEN_MODE NewMode; + egSetTextMode(GlobalConfig.RequestedTextMode); if (ConsoleControl != NULL) { refit_call4_wrapper(ConsoleControl->GetMode, ConsoleControl, &CurrentMode, NULL, NULL); diff --git a/refind/config.c b/refind/config.c index b1e0929..441d2a4 100644 --- a/refind/config.c +++ b/refind/config.c @@ -353,6 +353,8 @@ VOID ReadConfig(CHAR16 *FileName) GlobalConfig.DontScanDirs = StrDuplicate(SelfDirPath); MyFreePool(GlobalConfig.DontScanFiles); GlobalConfig.DontScanFiles = StrDuplicate(DONT_SCAN_FILES); +// egGetScreenSize(&GlobalConfig.RequestedScreenWidth, &GlobalConfig.RequestedScreenHeight); +// GlobalConfig.RequestedTextMode = ST->ConOut->Mode->Mode; } if (!FileExists(SelfDir, FileName)) { diff --git a/refind/main.c b/refind/main.c index 22693f1..07260ed 100644 --- a/refind/main.c +++ b/refind/main.c @@ -127,7 +127,7 @@ static VOID AboutrEFInd(VOID) if (AboutMenu.EntryCount == 0) { AboutMenu.TitleImage = BuiltinIcon(BUILTIN_ICON_FUNC_ABOUT); - AddMenuInfoLine(&AboutMenu, L"rEFInd Version 0.6.0.4"); + AddMenuInfoLine(&AboutMenu, L"rEFInd Version 0.6.0.5"); AddMenuInfoLine(&AboutMenu, L""); AddMenuInfoLine(&AboutMenu, L"Copyright (c) 2006-2010 Christoph Pfisterer"); AddMenuInfoLine(&AboutMenu, L"Copyright (c) 2012 Roderick W. Smith"); @@ -1960,7 +1960,6 @@ efi_main (EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) // bootstrap InitializeLib(ImageHandle, SystemTable); - InitScreen(); Status = InitRefitLib(ImageHandle); if (EFI_ERROR(Status)) return Status; @@ -1971,6 +1970,8 @@ efi_main (EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) if (GlobalConfig.LegacyType == LEGACY_TYPE_MAC) CopyMem(GlobalConfig.ScanFor, "ihebocm ", NUM_SCAN_OPTIONS); ReadConfig(CONFIG_FILE_NAME); + + InitScreen(); WarnIfLegacyProblems(); MainMenu.TimeoutSeconds = GlobalConfig.Timeout; diff --git a/refind/screen.c b/refind/screen.c index 32711d6..2ac7ceb 100644 --- a/refind/screen.c +++ b/refind/screen.c @@ -116,18 +116,37 @@ VOID InitScreen(VOID) PrepareBlankLine(); - // show the banner (even when in graphics mode) - DrawScreenHeader(L"Initializing..."); + // show the banner if in text mode + if (GlobalConfig.TextOnly) + DrawScreenHeader(L"Initializing..."); } VOID SetupScreen(VOID) { - GlobalConfig.RequestedTextMode = egSetTextMode(GlobalConfig.RequestedTextMode); + UINTN NewWidth, NewHeight; - if ((GlobalConfig.RequestedScreenWidth > 0) && - (egSetScreenSize(&GlobalConfig.RequestedScreenWidth, &GlobalConfig.RequestedScreenHeight))) { - UGAWidth = GlobalConfig.RequestedScreenWidth; - UGAHeight = GlobalConfig.RequestedScreenHeight; + if ((GlobalConfig.RequestedScreenWidth > 0) && (GlobalConfig.RequestedScreenHeight > 0)) { + UGAWidth = (UGAWidth < GlobalConfig.RequestedScreenWidth) ? UGAWidth : GlobalConfig.RequestedScreenWidth; + UGAHeight = (UGAHeight < GlobalConfig.RequestedScreenHeight) ? UGAHeight : GlobalConfig.RequestedScreenHeight; + } + if (egSetTextMode(GlobalConfig.RequestedTextMode)) { + egGetScreenSize(&NewWidth, &NewHeight); + if ((NewWidth > UGAWidth) || (NewHeight > UGAHeight)) { + UGAWidth = NewWidth; + UGAHeight = NewHeight; + } + if (UGAWidth > GlobalConfig.RequestedScreenWidth) { + // Requested text mode forces us to use a bigger graphics mode + // TODO: Convert single mode # to width & height to check it + GlobalConfig.RequestedScreenWidth = UGAWidth; + GlobalConfig.RequestedScreenHeight = UGAHeight; + } // if + } + + if (GlobalConfig.RequestedScreenWidth > 0) { + if (!egSetScreenSize(&GlobalConfig.RequestedScreenWidth, &GlobalConfig.RequestedScreenHeight)) + Print(L"Error setting screen size!\n"); + egGetScreenSize(&UGAWidth, &UGAHeight); } // if user requested a particular screen resolution if (GlobalConfig.TextOnly) { @@ -141,7 +160,7 @@ VOID SetupScreen(VOID) SwitchToGraphics(); BltClearScreen(TRUE); } -} +} // VOID SetupScreen() VOID SwitchToText(IN BOOLEAN CursorEnabled) { @@ -197,12 +216,10 @@ VOID BeginExternalScreen(IN BOOLEAN UseGraphicsMode, IN CHAR16 *Title) SwitchToGraphics(); BltClearScreen(FALSE); } else { - egClearScreen(&DarkBackgroundPixel); - DrawScreenHeader(Title); - } // if/else - - if (!UseGraphicsMode) + egClearScreen(&DarkBackgroundPixel); + DrawScreenHeader(Title); SwitchToText(TRUE); + } // reset error flag haveError = FALSE; -- 2.39.2