]> code.delx.au - refind/commitdiff
"resolution" option now takes either x & y resolution or a UEFI mode
authorsrs5694 <srs5694@users.sourceforge.net>
Fri, 14 Dec 2012 19:29:26 +0000 (14:29 -0500)
committersrs5694 <srs5694@users.sourceforge.net>
Fri, 14 Dec 2012 19:29:26 +0000 (14:29 -0500)
number.

NEWS.txt
docs/refind/configfile.html
libeg/libegint.h
libeg/screen.c
refind.conf-sample
refind/config.c
refind/screen.c

index b7a7d88034ea90005f17c3f2f2ce15b8025f917b..2598bc99c10e31e4cf1811cc9ed16df5e7313f4b 100644 (file)
--- a/NEWS.txt
+++ b/NEWS.txt
@@ -3,6 +3,18 @@
 
 - Added identifying screen header to line editor.
 
+- Fixed bug that caused rEFInd's display to be mis-sized upon return
+  from a program that set the resolution itself.
+
+- Adjusted "resolution" refind.conf parameter so that it can accept EITHER
+  a resolution as width and height OR a single digit as a UEFI mode number
+  (which is system-specific). This is done because some systems present the
+  same mode twice in their mode lists, perhaps varying in refresh rate,
+  monitor output, or some other salient characteristics; specifying the
+  mode number enables selecting the higher-numbered mode, whereas using
+  horizontal and vertical resolution values selects the lowest-numbered
+  mode.
+
 - Added "textmode" refind.conf parameter to set the text mode used in
   text-only displays, and for the line editor and boot-time handoff
   display even in graphics mode.
index ab72f1beda8fecaa4a32f5651c584dbc12c3e091..682b962f0f7c0193d00e2d1f5b0163e48c347aea 100644 (file)
@@ -185,8 +185,8 @@ timeout 20
 </tr>
 <tr>
    <td><tt>resolution</tt></td>
-   <td>Two integer values</td>
-   <td>Sets the video resolution used by rEFInd; takes a width and a height as options. For instance, <tt>resolution 1024 768</tt> sets the resolution to 1024x768. If you set a resolution that doesn't work on a UEFI-based system, rEFInd displays a message along with a list of valid modes. On an system built around EFI 1.<i>x</i> (such as a Mac), setting an incorrect resolution fails silently; you'll get the system's default resolution. You'll also get the system's default resolution if you set either resolution value to <tt>0</tt> or if you pass anything but two numbers. (Note that passing a resolution with an <tt>x</tt>, as in <tt>1024x768</tt>, will be interpreted as <i>one</i> option and so will cause the default resolution to be used.) Also, be aware that it is possible to set a valid resolution for your video card that's invalid for your monitor. If you do this, your monitor will go blank until you've booted an OS that resets the video mode.</td>
+   <td>one or two integer values</td>
+   <td>Sets the video resolution used by rEFInd; takes <i>either</i> a width and a height <i>or</i> a single UEFI video mode number as options. For instance, <tt>resolution 1024 768</tt> sets the resolution to 1024x768. On UEFI systems, <tt>resolution 1</tt> sets video mode 1, the resolution of which varies from system to system. If you set a resolution that doesn't work on a UEFI-based system, rEFInd displays a message along with a list of valid modes. On an system built around EFI 1.<i>x</i> (such as a Mac), setting an incorrect resolution fails silently; you'll get the system's default resolution. You'll also get the system's default resolution if you set both resolution values to <tt>0</tt> or if you pass anything but two numbers. (Note that passing a resolution with an <tt>x</tt>, as in <tt>1024x768</tt>, will be interpreted as <i>one</i> option and so will cause the default resolution to be used.) Also, be aware that it is possible to set a valid resolution for your video card that's invalid for your monitor. If you do this, your monitor will go blank until you've booted an OS that resets the video mode.</td>
 </tr>
 <tr>
    <td><tt>use_graphics_for</tt></td>
index 8c7f1e1a5825a902890c6ff71fe181109d0aa62a..400a65c5f41f9702b2f6178f2e6a27c3f7538a35 100644 (file)
@@ -52,7 +52,7 @@ typedef EG_IMAGE * (*EG_DECODE_FUNC)(IN UINT8 *FileData, IN UINTN FileDataLength
 
 /* functions */
 
-BOOLEAN egSetScreenSize(IN UINTN ScreenWidth, IN UINTN ScreenHeight);
+BOOLEAN egSetScreenSize(IN OUT UINTN *ScreenWidth, IN OUT UINTN *ScreenHeight);
 
 VOID egRestrictImageArea(IN EG_IMAGE *Image,
                          IN UINTN AreaPosX, IN UINTN AreaPosY,
index 3200ef92976685dffee41536ef596d05076f4881..d2d12db4fc4f20eedb075223e4d7310e48674bc8 100644 (file)
@@ -101,43 +101,59 @@ VOID egInitScreen(VOID)
     }
 }
 
-// Sets the screen resolution to the specified value, if possible.
-// If the specified value is not valid, displays a warning with the valid
-// modes on UEFI systems, or silently fails on EFI 1.x systems. Note that
-// this function attempts to set ANY screen resolution, even 0x0 or
-// ridiculously large values.
+// 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
+// valid, displays a warning with the valid modes on GOP (UEFI) systems, or silently
+// fails on UGA (EFI 1.x) systems. Note that this function attempts to set ANY screen
+// resolution, even 0x0 or ridiculously large values.
+// Upon success, returns actual screen resolution in *ScreenWidth and *ScreenHeight.
+// These values are unchanged upon failure.
 // Returns TRUE if successful, FALSE if not.
-BOOLEAN egSetScreenSize(IN UINTN ScreenWidth, IN UINTN ScreenHeight) {
-   EFI_STATUS Status = EFI_SUCCESS;
-   EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info;
-   UINT32 ModeNum = 0;
-   UINTN Size;
-   BOOLEAN ModeSet = FALSE;
-   UINT32 UGAWidth, UGAHeight, UGADepth, UGARefreshRate;
+BOOLEAN egSetScreenSize(IN OUT UINTN *ScreenWidth, IN OUT UINTN *ScreenHeight) {
+   EFI_STATUS                            Status = EFI_SUCCESS;
+   EFI_GRAPHICS_OUTPUT_MODE_INFORMATION  *Info;
+   UINT32                                ModeNum = 0;
+   UINTN                                 Size;
+   BOOLEAN                               ModeSet = FALSE;
+   UINT32                                UGAWidth, UGAHeight, UGADepth, UGARefreshRate;
 
    if (GraphicsOutput != NULL) { // GOP mode (UEFI)
-      // Do a loop through the modes to see if the specified one is available;
-      // and if so, switch to it....
-      while ((Status == EFI_SUCCESS) && (!ModeSet)) {
+      if (*ScreenHeight == 0) { // User specified a mode number (stored in *ScreenWidth); use it directly
+         ModeNum = (UINT32) *ScreenWidth;
          Status = refit_call4_wrapper(GraphicsOutput->QueryMode, GraphicsOutput, ModeNum, &Size, &Info);
-         if ((Status == EFI_SUCCESS) && (Size >= sizeof(*Info)) &&
-             (Info->HorizontalResolution == ScreenWidth) && (Info->VerticalResolution == ScreenHeight)) {
+         if (Status == EFI_SUCCESS) {
             Status = refit_call2_wrapper(GraphicsOutput->SetMode, GraphicsOutput, ModeNum);
-            ModeSet = (Status == EFI_SUCCESS);
-         } // if
-         ModeNum++;
-      } // while()
+            if (Status == EFI_SUCCESS) {
+               ModeSet = TRUE;
+               *ScreenWidth = Info->HorizontalResolution;
+               *ScreenHeight = Info->VerticalResolution;
+            }
+         }
+      } else { // User specified width & height; must find mode
+         // Do a loop through the modes to see if the specified one is available;
+         // and if so, switch to it....
+         while ((Status == EFI_SUCCESS) && (!ModeSet)) {
+            Status = refit_call4_wrapper(GraphicsOutput->QueryMode, GraphicsOutput, ModeNum, &Size, &Info);
+            if ((Status == EFI_SUCCESS) && (Size >= sizeof(*Info)) &&
+                (Info->HorizontalResolution == *ScreenWidth) && (Info->VerticalResolution == *ScreenHeight)) {
+               Status = refit_call2_wrapper(GraphicsOutput->SetMode, GraphicsOutput, ModeNum);
+               ModeSet = (Status == EFI_SUCCESS);
+            } // if
+            ModeNum++;
+         } // while()
+      } // if/else
 
       if (ModeSet) {
-         egScreenWidth = ScreenWidth;
-         egScreenHeight = ScreenHeight;
+         egScreenWidth = *ScreenWidth;
+         egScreenHeight = *ScreenHeight;
       } else {// If unsuccessful, display an error message for the user....
          SwitchToText(FALSE);
-         Print(L"Error setting graphics mode %d x %d; using default mode!\nAvailable modes are:\n", ScreenWidth, ScreenHeight);
+         Print(L"Error setting graphics mode %d x %d; using default mode!\nAvailable modes are:\n", *ScreenWidth, *ScreenHeight);
          ModeNum = 0;
          do {
             Status = refit_call4_wrapper(GraphicsOutput->QueryMode, GraphicsOutput, ModeNum, &Size, &Info);
-            if (Status == EFI_SUCCESS) {
+            if ((Status == EFI_SUCCESS) && (Info != NULL)) {
                Print(L"Mode %d: %d x %d\n", ModeNum, Info->HorizontalResolution, Info->VerticalResolution);
             } // else
          } while ((ModeNum++ < 10) || (Status == EFI_SUCCESS));
@@ -156,10 +172,10 @@ BOOLEAN egSetScreenSize(IN UINTN ScreenWidth, IN UINTN ScreenHeight) {
       // Try to use current color depth & refresh rate for new mode. Maybe not the best choice
       // in all cases, but I don't know how to probe for alternatives....
       Status = refit_call5_wrapper(UgaDraw->GetMode, UgaDraw, &UGAWidth, &UGAHeight, &UGADepth, &UGARefreshRate);
-      Status = refit_call5_wrapper(UgaDraw->SetMode, UgaDraw, ScreenWidth, ScreenHeight, UGADepth, UGARefreshRate);
+      Status = refit_call5_wrapper(UgaDraw->SetMode, UgaDraw, *ScreenWidth, *ScreenHeight, UGADepth, UGARefreshRate);
       if (Status == EFI_SUCCESS) {
-         egScreenWidth = ScreenWidth;
-         egScreenHeight = ScreenHeight;
+         egScreenWidth = *ScreenWidth;
+         egScreenHeight = *ScreenHeight;
          ModeSet = TRUE;
       } else {
          // TODO: Find a list of supported modes and display it.
@@ -192,7 +208,7 @@ UINT32 egSetTextMode(UINT32 RequestedMode) {
          UsedMode = RequestedMode;
       } else {
          SwitchToText(FALSE);
-         Print(L"Error setting text mode %d; available modes are:\n", ST->ConOut->Mode->Mode);
+         Print(L"Error setting text mode %d; available modes are:\n", RequestedMode);
          do {
             Status = refit_call4_wrapper(ST->ConOut->QueryMode, ST->ConOut, i, &Width, &Height);
             if (Status == EFI_SUCCESS)
index 4ae887fbce31f52307171808c6d4b83ec38f6988..c15d905b54a263e799fa0da1f0ae2fd6823ea323 100644 (file)
@@ -71,17 +71,20 @@ timeout 20
 #
 #textmode 2
 
-# Set the screen's video resolution. Pass this option two values,
-# corresponding to the X and Y resolutions. Note that not all resolutions
-# are supported. On UEFI systems, passing an incorrect value results in a
-# message being shown on the screen to that effect, along with a list of
-# supported modes. On EFI 1.x systems (e.g., Macintoshes), setting an
-# incorrect mode silently fails. On both types of systems, setting an
-# incorrect resolution results in the default resolution being used.
-# A resolution of 1024x768 usually works, but higher values often don't.
+# Set the screen's video resolution. Pass this option either:
+#  * two values, corresponding to the X and Y resolutions
+#  * one value, corresponding to a GOP (UEFI) video mode
+# Note that not all resolutions are supported. On UEFI systems, passing
+# an incorrect value results in a message being shown on the screen to
+# that effect, along with a list of supported modes. On EFI 1.x systems
+# (e.g., Macintoshes), setting an incorrect mode silently fails. On both
+# types of systems, setting an incorrect resolution results in the default
+# resolution being used. A resolution of 1024x768 usually works, but higher
+# values often don't.
 # Default is "0 0" (use the system default resolution, usually 800x600).
 #
 #resolution 1024 768
+#resolution 3
 
 # Launch specified OSes in graphics mode. By default, rEFInd switches
 # to text mode and displays basic pre-launch information when launching
index 9149b9b7bb08a49d432c7ff434d4609f56f47b35..416461df8a0e36b0b58d6805cd1214d9b59687be 100644 (file)
@@ -463,9 +463,12 @@ VOID ReadConfig(CHAR16 *FileName)
         } else if (StriCmp(TokenList[0], L"textmode") == 0) {
            HandleInt(TokenList, TokenCount, &(GlobalConfig.RequestedTextMode));
 
-        } else if ((StriCmp(TokenList[0], L"resolution") == 0) && (TokenCount == 3)) {
+        } else if ((StriCmp(TokenList[0], L"resolution") == 0) && ((TokenCount == 2) || (TokenCount == 3))) {
            GlobalConfig.RequestedScreenWidth = Atoi(TokenList[1]);
-           GlobalConfig.RequestedScreenHeight = Atoi(TokenList[2]);
+           if (TokenCount == 3)
+              GlobalConfig.RequestedScreenHeight = Atoi(TokenList[2]);
+           else
+              GlobalConfig.RequestedScreenHeight = 0;
 
         } else if (StriCmp(TokenList[0], L"use_graphics_for") == 0) {
            GlobalConfig.GraphicsFor = 0;
index 6aa04bedc86d0a3418445cfb8e98866c9633e969..dc1f21d987bb421ba6d3b115d79cb2945c20778c 100644 (file)
@@ -115,8 +115,8 @@ VOID SetupScreen(VOID)
 {
     GlobalConfig.RequestedTextMode = egSetTextMode(GlobalConfig.RequestedTextMode);
 
-    if ((GlobalConfig.RequestedScreenWidth > 0) && (GlobalConfig.RequestedScreenHeight > 0) &&
-        egSetScreenSize(GlobalConfig.RequestedScreenWidth, GlobalConfig.RequestedScreenHeight)) {
+    if ((GlobalConfig.RequestedScreenWidth > 0) &&
+        (egSetScreenSize(&GlobalConfig.RequestedScreenWidth, &GlobalConfig.RequestedScreenHeight))) {
           UGAWidth = GlobalConfig.RequestedScreenWidth;
           UGAHeight = GlobalConfig.RequestedScreenHeight;
     } // if user requested a particular screen resolution
@@ -206,6 +206,9 @@ VOID BeginExternalScreen(IN BOOLEAN UseGraphicsMode, IN CHAR16 *Title)
 
 VOID FinishExternalScreen(VOID)
 {
+    // Reset the screen resolution, in case external program changed it....
+    SetupScreen();
+
     // make sure we clean up later
     GraphicsScreenDirty = TRUE;