]> code.delx.au - refind/commitdiff
Support for transparency of icons & main menu text over large
authorsrs5694 <srs5694@users.sourceforge.net>
Sun, 13 Jan 2013 04:40:37 +0000 (23:40 -0500)
committersrs5694 <srs5694@users.sourceforge.net>
Sun, 13 Jan 2013 04:40:37 +0000 (23:40 -0500)
(fullscreen) banner graphic.

NEWS.txt
docs/refind/installing.html
libeg/image.c
libeg/libeg.h
libeg/load_icns.c
libeg/screen.c
refind.conf-sample
refind/global.h
refind/main.c
refind/menu.c
refind/screen.c

index d14ebed0fcc9c7498a1599dca9333b7efed36f78..09f77c9798a4b3aa511d0aaaaa6b5709c6be878b 100644 (file)
--- a/NEWS.txt
+++ b/NEWS.txt
@@ -1,6 +1,8 @@
 0.6.5 (1/??/2013):
 ------------------
 
+- Added icon for ALT Linux.
+
 - Added "safemode" option to "hideui" token, to hide option to boot into
   safe mode for OS X ("-v -x" option to boot.efi).
 
index a38452c6fb24c8b3926e931bef29c4669ba1e4e2..65e5b7d243b7a32874cb3ebf94da042ea1c918fb 100644 (file)
@@ -142,7 +142,17 @@ href="mailto:rodsmith@rodsbooks.com">rodsmith@rodsbooks.com</a></p>
 
 <li class="tight"><a href="#addons">Installing Additional Components</a></li>
 
-<li class="tight"><a href="#sluggish">Fixing a Sluggish Macintosh Boot</a></li>
+<li class="tight"><a href="#sluggish">Fixing a Sluggish Macintosh Boot</a>
+
+   <ul>
+
+   <li class="tight"><a href="#moving">Moving rEFInd to an HFS+ Volume</a></li>
+
+   <li class="tight"><a href="#fallback">Using the Fallback Filename</a></li>
+
+   <li class="tight"><a href="#clearing">Clearing the NVRAM Entries</a></li>
+
+   </ul></li>
 
 <li class="tight"><a href="#uninstalling">Uninstalling rEFInd</a></li>
 
@@ -826,7 +836,27 @@ $ <b>ioreg -l -p IODeviceTree | grep firmware-abi</b>
 <h2>Fixing a Sluggish Macintosh Boot</h2>
 </a>
 
-<p>I've received a few reports of a sluggish boot process (a delay of about 30 seconds before starting rEFInd) on some Macs after installing rEFInd. I've been unable to replicate this problem myself, and its true cause remains mysterious to me. I have found <a href="http://ubuntuforums.org/showpost.php?p=12256273&postcount=200">a Web forum post</a> describing a possible fix. Be aware, though, that this procedure involves using the <tt>efibootmgr</tt> utility on Macs, which has been known to damage the firmware on some Macs. Other reports indicate that this problem has been fixed with 3.3.0 and later kernels. Thus, I present this information cautiously and with a strong "use at your own risk" warning. If you care to proceed, I recommend you update your Linux kernel to the latest possible version and then proceed as follows:</p>
+<p>I've received a few reports of a sluggish boot process (a delay of about 30 seconds before starting rEFInd) on some Macs after installing rEFInd. I've been unable to replicate this problem myself, and its true cause remains mysterious to me. I have found three possible solutions, though: <a href="#moving">moving rEFInd to an HFS+ volume,</a> <a href="#fallback">using the fallback filename,</a> and <a href="#clearing">clearing NVRAM entries.</a></p>
+
+<a name="moving">
+<h3>Moving rEFInd to an HFS+ Volume</h3>
+</a>
+
+<p>Most of the reports of sluggish Macintosh boots I've seen note that the user installed rEFInd to the ESP rather than to the OS X root partition. Some users have reported that re-installing rEFInd to the OS X root partition clears up the problem. This is obviously a straightforward solution to the problem, if it works. Note that rEFInd can launch boot loaders that are stored on any partition that the EFI can read no matter where it's installed; therefore, you'll still be able to launch boot loaders stored on the ESP (or elsewhere) if you install it in this way.</p>
+
+<p>The biggest drawback to this approach is that you won't be able to edit the rEFInd configuration file or move rEFInd-related binaries from an EFI shell if you install it in this way, since Apple's HFS+ driver for EFI is read-only. (The same is true of rEFInd's HFS+ driver, so it won't help you overcome this limitation.) You may also be limited in making changes to your rEFInd configuration from Linux or other OSes, too, since Linux's HFS+ drivers disable write support by default on volumes with an active journal. You can force write access by using the <tt>force</tt> option to <tt>mount</tt>; however, this procedure is noted as being risky in the Linux HFS+ documentation, so I don't recommend doing this on a regular basis. As a compromise, you might try creating a small non-journaled HFS+ volume that's dedicated to holding rEFInd. You could even mount it as the Linux <tt>/boot</tt> partition, in which case it would also hold the Linux kernel and related files. You'll need to install rEFInd manually if you try this.</p>
+
+<a name="fallback">
+<h3>Using the Fallback Filename</h3>
+</a>
+
+<p>I've received one report that installing rEFInd to the ESP using the fallback filename (<tt>EFI/BOOT/bootx64.efi</tt> on most systems, or <tt>EFI/BOOT/bootia32.efi</tt> on very old Macs) can work around the problem.</p>
+
+<a name="clearing">
+<h3>Clearing the NVRAM Entries</h3>
+</a>
+
+<p>The first is <a href="http://ubuntuforums.org/showpost.php?p=12256273&postcount=200">a Web forum post</a> that describes a possible fix. Be aware, though, that this procedure involves using the <tt>efibootmgr</tt> utility on Macs, which has been known to damage the firmware on some Macs. Other reports indicate that this problem has been fixed with 3.3.0 and later kernels. Thus, I present this information cautiously and with a strong "use at your own risk" warning. If you care to proceed, I recommend you update your Linux kernel to the latest possible version and then proceed as follows:</p>
 
 <ol>
 
index 39039dab73efc29592ab221ef36e342c68764729..cd25312bc22860947d1973bc97fd1f2422a84930 100644 (file)
@@ -94,6 +94,27 @@ EG_IMAGE * egCopyImage(IN EG_IMAGE *Image)
     return NewImage;
 }
 
+// Returns a smaller image composed of the specified crop area from the larger area.
+// If the specified area is larger than is in the original, returns NULL.
+EG_IMAGE * egCropImage(IN EG_IMAGE *Image, IN UINTN StartX, IN UINTN StartY, IN UINTN Width, IN UINTN Height) {
+   EG_IMAGE *NewImage = NULL;
+   UINTN x, y;
+
+   if (((StartX + Width) > Image->Width) || ((StartY + Height) > Image->Height))
+      return NULL;
+
+   NewImage = egCreateImage(Width, Height, Image->HasAlpha);
+   if (NewImage == NULL)
+      return NULL;
+
+   for (y = 0; y < Height; y++) {
+      for (x = 0; x < Width; x++) {
+         NewImage->PixelData[y * NewImage->Width + x] = Image->PixelData[(y + StartY) * Image->Width + x + StartX];
+      }
+   }
+   return NewImage;
+} // EG_IMAGE * egCropImage()
+
 VOID egFreeImage(IN EG_IMAGE *Image)
 {
     if (Image != NULL) {
@@ -442,7 +463,7 @@ VOID egRawCopy(IN OUT EG_PIXEL *CompBasePtr, IN EG_PIXEL *TopBasePtr,
 {
     UINTN       x, y;
     EG_PIXEL    *TopPtr, *CompPtr;
-    
+
     for (y = 0; y < Height; y++) {
         TopPtr = TopBasePtr;
         CompPtr = CompBasePtr;
@@ -464,7 +485,7 @@ VOID egRawCompose(IN OUT EG_PIXEL *CompBasePtr, IN EG_PIXEL *TopBasePtr,
     UINTN       Alpha;
     UINTN       RevAlpha;
     UINTN       Temp;
-    
+
     for (y = 0; y < Height; y++) {
         TopPtr = TopBasePtr;
         CompPtr = CompBasePtr;
@@ -499,17 +520,18 @@ VOID egComposeImage(IN OUT EG_IMAGE *CompImage, IN EG_IMAGE *TopImage, IN UINTN
 
     // compose
     if (CompWidth > 0) {
-        if (CompImage->HasAlpha) {
-            CompImage->HasAlpha = FALSE;
-            egSetPlane(PLPTR(CompImage, a), 0, CompImage->Width * CompImage->Height);
-        }
+//         if (CompImage->HasAlpha) {
+//             CompImage->HasAlpha = FALSE;
+//             egSetPlane(PLPTR(CompImage, a), 0, CompImage->Width * CompImage->Height);
+//         }
 
-        if (TopImage->HasAlpha)
+        if (TopImage->HasAlpha) {
             egRawCompose(CompImage->PixelData + PosY * CompImage->Width + PosX, TopImage->PixelData,
                          CompWidth, CompHeight, CompImage->Width, TopImage->Width);
-        else
+        } else {
             egRawCopy(CompImage->PixelData + PosY * CompImage->Width + PosX, TopImage->PixelData,
                       CompWidth, CompHeight, CompImage->Width, TopImage->Width);
+        }
     }
 }
 
index 15e561adf51ce0d570f0ed7c29d88e6a37190ce0..77516c614d0455b25830e35dbae09e9d69850cb6 100644 (file)
@@ -92,6 +92,7 @@ VOID egSetGraphicsModeEnabled(IN BOOLEAN Enable);
 EG_IMAGE * egCreateImage(IN UINTN Width, IN UINTN Height, IN BOOLEAN HasAlpha);
 EG_IMAGE * egCreateFilledImage(IN UINTN Width, IN UINTN Height, IN BOOLEAN HasAlpha, IN EG_PIXEL *Color);
 EG_IMAGE * egCopyImage(IN EG_IMAGE *Image);
+EG_IMAGE * egCropImage(IN EG_IMAGE *Image, IN UINTN StartX, IN UINTN StartY, IN UINTN Width, IN UINTN Height);
 VOID egFreeImage(IN EG_IMAGE *Image);
 
 EG_IMAGE * egLoadImage(IN EFI_FILE* BaseDir, IN CHAR16 *FileName, IN BOOLEAN WantAlpha);
@@ -123,6 +124,7 @@ VOID egDrawImageArea(IN EG_IMAGE *Image,
                      IN UINTN AreaWidth, IN UINTN AreaHeight,
                      IN UINTN ScreenPosX, IN UINTN ScreenPosY);
 VOID egDisplayMessage(IN CHAR16 *Text, EG_PIXEL *BGColor);
+EG_IMAGE * egCopyScreen(VOID);
 VOID egScreenShot(VOID);
 //UINT32 egGetGraphicsMode(VOID);
 BOOLEAN egSetTextMode(UINT32 RequestedMode);
index 5477f46a26c5a5ddb9b8bcef386844223df2b507..f357ac36d7d9a1ac66507cd288551d6dbbb01e13 100644 (file)
@@ -48,13 +48,13 @@ VOID egDecompressIcnsRLE(IN OUT UINT8 **CompData, IN OUT UINTN *CompLen, IN UINT
     UINTN pp_left;
     UINTN len, i;
     UINT8 value;
-    
+
     // setup variables
     cp = *CompData;
     cp_end = cp + *CompLen;
     pp = PixelData;
     pp_left = PixelCount;
-    
+
     // decode
     while (cp + 1 < cp_end && pp_left > 0) {
         len = *cp++;
@@ -78,11 +78,11 @@ VOID egDecompressIcnsRLE(IN OUT UINT8 **CompData, IN OUT UINTN *CompLen, IN UINT
         }
         pp_left -= len;
     }
-    
+
     if (pp_left > 0) {
         Print(L" egDecompressIcnsRLE: still need %d bytes of pixel data\n", pp_left);
     }
-    
+
     // record what's left of the compressed data stream
     *CompData = cp;
     *CompLen = (UINTN)(cp_end - cp);
@@ -221,6 +221,6 @@ EG_IMAGE * egDecodeICNS(IN UINT8 *FileData, IN UINTN FileDataLength, IN UINTN Ic
     // FUTURE: scale to originally requested size if we had to load another size
 
     return NewImage;
-}
+} // EG_IMAGE * egDecodeICNS()
 
 /* EOF */
index 44d5c3929345cac638284fdef2eee0001a4bb6d8..da934cf3c6736c154398e41b218f35e3737741b2 100644 (file)
@@ -355,6 +355,8 @@ VOID egClearScreen(IN EG_PIXEL *Color)
 
 VOID egDrawImage(IN EG_IMAGE *Image, IN UINTN ScreenPosX, IN UINTN ScreenPosY)
 {
+    EG_IMAGE *CompImage = NULL;
+
     // NOTE: Weird seemingly redundant tests because some placement code can "wrap around" and
     // send "negative" values, which of course become very large unsigned ints that can then
     // wrap around AGAIN if values are added to them.....
@@ -362,18 +364,33 @@ VOID egDrawImage(IN EG_IMAGE *Image, IN UINTN ScreenPosX, IN UINTN ScreenPosY)
         (ScreenPosX > egScreenWidth) || (ScreenPosY > egScreenHeight))
         return;
 
-    if (Image->HasAlpha) {
-        Image->HasAlpha = FALSE;
-        egSetPlane(PLPTR(Image, a), 0, Image->Width * Image->Height);
+//     if (Image->HasAlpha) {
+//         Image->HasAlpha = FALSE;
+//         egSetPlane(PLPTR(Image, a), 0, Image->Width * Image->Height);
+//     }
+
+    if ((GlobalConfig.ScreenBackground == NULL) || ((Image->Width == egScreenWidth) && (Image->Height == egScreenHeight))) {
+       CompImage = Image;
+    } else if (GlobalConfig.ScreenBackground == Image) {
+       CompImage = GlobalConfig.ScreenBackground;
+    } else {
+       CompImage = egCropImage(GlobalConfig.ScreenBackground, ScreenPosX, ScreenPosY, Image->Width, Image->Height);
+       if (CompImage == NULL) {
+          Print(L"Error! Can't compose image in egDrawImage()!\n");
+          return;
+       }
+       egComposeImage(CompImage, Image, 0, 0);
     }
 
     if (GraphicsOutput != NULL) {
-        refit_call10_wrapper(GraphicsOutput->Blt, GraphicsOutput, (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *)Image->PixelData,
-                             EfiBltBufferToVideo, 0, 0, ScreenPosX, ScreenPosY, Image->Width, Image->Height, 0);
+       refit_call10_wrapper(GraphicsOutput->Blt, GraphicsOutput, (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *)CompImage->PixelData,
+                            EfiBltBufferToVideo, 0, 0, ScreenPosX, ScreenPosY, CompImage->Width, CompImage->Height, 0);
     } else if (UgaDraw != NULL) {
-        refit_call10_wrapper(UgaDraw->Blt, UgaDraw, (EFI_UGA_PIXEL *)Image->PixelData, EfiUgaBltBufferToVideo,
-                     0, 0, ScreenPosX, ScreenPosY, Image->Width, Image->Height, 0);
+       refit_call10_wrapper(UgaDraw->Blt, UgaDraw, (EFI_UGA_PIXEL *)CompImage->PixelData, EfiUgaBltBufferToVideo,
+                            0, 0, ScreenPosX, ScreenPosY, CompImage->Width, CompImage->Height, 0);
     }
+    if ((CompImage != GlobalConfig.ScreenBackground) && (CompImage != Image))
+       egFreeImage(CompImage);
 } /* VOID egDrawImage() */
 
 VOID egDrawImageArea(IN EG_IMAGE *Image,
@@ -388,17 +405,18 @@ VOID egDrawImageArea(IN EG_IMAGE *Image,
     if (AreaWidth == 0)
         return;
 
-    if (Image->HasAlpha) {
-        Image->HasAlpha = FALSE;
-        egSetPlane(PLPTR(Image, a), 0, Image->Width * Image->Height);
-    }
+//     if (Image->HasAlpha) {
+//         Image->HasAlpha = FALSE;
+//         egSetPlane(PLPTR(Image, a), 0, Image->Width * Image->Height);
+//     }
 
     if (GraphicsOutput != NULL) {
-        refit_call10_wrapper(GraphicsOutput->Blt, GraphicsOutput, (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *)Image->PixelData, EfiBltBufferToVideo,
-                            AreaPosX, AreaPosY, ScreenPosX, ScreenPosY, AreaWidth, AreaHeight, Image->Width * 4);
+        refit_call10_wrapper(GraphicsOutput->Blt, GraphicsOutput, (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *)Image->PixelData,
+                             EfiBltBufferToVideo, AreaPosX, AreaPosY, ScreenPosX, ScreenPosY, AreaWidth, AreaHeight,
+                             Image->Width * 4);
     } else if (UgaDraw != NULL) {
         refit_call10_wrapper(UgaDraw->Blt, UgaDraw, (EFI_UGA_PIXEL *)Image->PixelData, EfiUgaBltBufferToVideo,
-                     AreaPosX, AreaPosY, ScreenPosX, ScreenPosY, AreaWidth, AreaHeight, Image->Width * 4);
+                             AreaPosX, AreaPosY, ScreenPosX, ScreenPosY, AreaWidth, AreaHeight, Image->Width * 4);
     }
 }
 
@@ -420,6 +438,31 @@ VOID egDisplayMessage(IN CHAR16 *Text, EG_PIXEL *BGColor) {
    } // if non-NULL inputs
 } // VOID egDisplayMessage()
 
+// Copy the current contents of the display into an EG_IMAGE....
+// Returns pointer if successful, NULL if not.
+EG_IMAGE * egCopyScreen(VOID) {
+   EG_IMAGE *Image = NULL;
+
+   if (!egHasGraphics)
+      return NULL;
+
+   // allocate a buffer for the whole screen
+   Image = egCreateImage(egScreenWidth, egScreenHeight, FALSE);
+   if (Image == NULL) {
+      return NULL;
+   }
+
+   // get full screen image
+   if (GraphicsOutput != NULL) {
+      refit_call10_wrapper(GraphicsOutput->Blt, GraphicsOutput, (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *)Image->PixelData,
+                           EfiBltVideoToBltBuffer, 0, 0, 0, 0, Image->Width, Image->Height, 0);
+   } else if (UgaDraw != NULL) {
+      refit_call10_wrapper(UgaDraw->Blt, UgaDraw, (EFI_UGA_PIXEL *)Image->PixelData, EfiUgaVideoToBltBuffer,
+                           0, 0, 0, 0, Image->Width, Image->Height, 0);
+   }
+   return Image;
+} // EG_IMAGE * egCopyScreen()
+
 //
 // Make a screenshot
 //
@@ -432,23 +475,10 @@ VOID egScreenShot(VOID)
     UINTN           FileDataLength;
     UINTN           Index;
 
-    if (!egHasGraphics)
-        return;
-
-    // allocate a buffer for the whole screen
-    Image = egCreateImage(egScreenWidth, egScreenHeight, FALSE);
+    Image = egCopyScreen();
     if (Image == NULL) {
-        Print(L"Error egCreateImage returned NULL\n");
-        goto bailout_wait;
-    }
-
-    // get full screen image
-    if (GraphicsOutput != NULL) {
-        refit_call10_wrapper(GraphicsOutput->Blt, GraphicsOutput, (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *)Image->PixelData, EfiBltVideoToBltBuffer,
-                            0, 0, 0, 0, Image->Width, Image->Height, 0);
-    } else if (UgaDraw != NULL) {
-        refit_call10_wrapper(UgaDraw->Blt, UgaDraw, (EFI_UGA_PIXEL *)Image->PixelData, EfiUgaVideoToBltBuffer,
-                     0, 0, 0, 0, Image->Width, Image->Height, 0);
+       Print(L"Error: Unable to take screen shot\n");
+       goto bailout_wait;
     }
 
     // encode as BMP
index 424b8c45ce0d40b0e9abae8ec2a415445c51bca1..657e69d67e0f689bde0ee198c46bcaf69e0de7cb 100644 (file)
@@ -14,6 +14,7 @@ timeout 20
 #  label       - boot option text label in the menu
 #  singleuser  - remove the submenu options to boot Mac OS X in single-user
 #                or verbose modes; affects ONLY MacOS X
+#  safemode    - remove the submenu option to boot Mac OS X in "safe mode"
 #  hwtest      - the submenu option to run Apple's hardware test
 #  arrows      - scroll arrows on the OS selection tag line
 #  hints       - brief command summary in the menu
index 9d6b667745b7a95e4477e6651817ae80f741fe15..4e381db2c13811d5661ecc7b291b65aa1c2eab3e 100644 (file)
@@ -223,6 +223,7 @@ typedef struct {
    UINTN       LegacyType;
    UINTN       ScanDelay;
    CHAR16      *BannerFileName;
+   EG_IMAGE    *ScreenBackground;
    CHAR16      *SelectionSmallFileName;
    CHAR16      *SelectionBigFileName;
    CHAR16      *DefaultSelection;
index 4006ac7dfde453783eea5105ae147618914fa64b..0024c3d8d9d5548265336a002c57d19a682d93d4 100644 (file)
@@ -107,7 +107,7 @@ static REFIT_MENU_SCREEN MainMenu       = { L"Main Menu", NULL, 0, NULL, 0, NULL
 static REFIT_MENU_SCREEN AboutMenu      = { L"About", NULL, 0, NULL, 0, NULL, 0, NULL, L"Press Enter to return to main menu", L"" };
 
 REFIT_CONFIG GlobalConfig = { FALSE, FALSE, 0, 0, DONT_CHANGE_TEXT_MODE, 20, 0, 0, GRAPHICS_FOR_OSX, LEGACY_TYPE_MAC, 0,
-                              NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                              NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                               {TAG_SHELL, TAG_APPLE_RECOVERY, TAG_MOK_TOOL, TAG_ABOUT, TAG_SHUTDOWN, TAG_REBOOT, 0, 0, 0, 0, 0 }};
 
 // Structure used to hold boot loader filenames and time stamps in
@@ -128,7 +128,7 @@ static VOID AboutrEFInd(VOID)
 
     if (AboutMenu.EntryCount == 0) {
         AboutMenu.TitleImage = BuiltinIcon(BUILTIN_ICON_FUNC_ABOUT);
-        AddMenuInfoLine(&AboutMenu, L"rEFInd Version 0.6.4.1");
+        AddMenuInfoLine(&AboutMenu, L"rEFInd Version 0.6.4.2");
         AddMenuInfoLine(&AboutMenu, L"");
         AddMenuInfoLine(&AboutMenu, L"Copyright (c) 2006-2010 Christoph Pfisterer");
         AddMenuInfoLine(&AboutMenu, L"Copyright (c) 2012 Roderick W. Smith");
index 5154892ddb5c7c8d7147681fe1d9d523b9147efd..e6f9d4ffa59c6d463c22906acd60a5d636496bad 100644 (file)
@@ -48,6 +48,7 @@
 #include "menu.h"
 #include "config.h"
 #include "libeg.h"
+#include "libegint.h"
 #include "../include/refit_call_wrapper.h"
 
 #include "../include/egemb_back_selected_small.h"
@@ -638,11 +639,25 @@ static VOID TextMenuStyle(IN REFIT_MENU_SCREEN *Screen, IN SCROLL_STATE *State,
 // graphical generic style
 //
 
+// Display an unselected icon on the screen, so that the background image shows
+// through the transparency areas. The BadgeImage may be NULL, in which case
+// it's not composited in.
+static VOID DrawImageWithTransparency(EG_IMAGE *Image, EG_IMAGE *BadgeImage, UINTN XPos, UINTN YPos, UINTN Width, UINTN Height) {
+   EG_IMAGE *Background;
 
-static VOID DrawMenuText(IN CHAR16 *Text, IN UINTN SelectedWidth, IN UINTN XPos, IN UINTN YPos)
+   Background = egCropImage(GlobalConfig.ScreenBackground, XPos, YPos, Width, Height);
+   if (Background != NULL) {
+      BltImageCompositeBadge(Background, Image, BadgeImage, XPos, YPos);
+      egFreeImage(Background);
+   }
+} // VOID DrawImageWithTransparency()
+
+
+// Display a submenu
+static VOID DrawSubmenuText(IN CHAR16 *Text, IN UINTN SelectedWidth, IN UINTN XPos, IN UINTN YPos)
 {
     if (TextBuffer == NULL)
-        TextBuffer = egCreateImage(LAYOUT_TEXT_WIDTH, TEXT_LINE_HEIGHT, FALSE);
+        TextBuffer = egCreateImage(LAYOUT_TEXT_WIDTH, TEXT_LINE_HEIGHT, TRUE);
 
     egFillImage(TextBuffer, &MenuBackgroundPixel);
     if (SelectedWidth > 0) {
@@ -653,7 +668,8 @@ static VOID DrawMenuText(IN CHAR16 *Text, IN UINTN SelectedWidth, IN UINTN XPos,
 
     // render the text
     egRenderText(Text, TextBuffer, TEXT_XMARGIN, TEXT_YMARGIN);
-    BltImage(TextBuffer, XPos, YPos);
+    DrawImageWithTransparency(TextBuffer, NULL, XPos, YPos, TextBuffer->Width, TextBuffer->Height);
+//    BltImage(TextBuffer, XPos, YPos);
 }
 
 // Displays sub-menus
@@ -695,14 +711,12 @@ static VOID GraphicsMenuStyle(IN REFIT_MENU_SCREEN *Screen, IN SCROLL_STATE *Sta
             // initial painting
             SwitchToGraphicsAndClear();
             egMeasureText(Screen->Title, &ItemWidth, NULL);
-            DrawMenuText(Screen->Title, 0, ((UGAWidth - ItemWidth) >> 1) - TEXT_XMARGIN, EntriesPosY - TEXT_LINE_HEIGHT * 2);
+            DrawSubmenuText(Screen->Title, 0, ((UGAWidth - ItemWidth) >> 1) - TEXT_XMARGIN, EntriesPosY - TEXT_LINE_HEIGHT * 2);
             if (Screen->TitleImage)
-                BltImageAlpha(Screen->TitleImage,
-                              EntriesPosX - (Screen->TitleImage->Width + TITLEICON_SPACING), EntriesPosY,
-                              &MenuBackgroundPixel);
+               BltImage(Screen->TitleImage, EntriesPosX - (Screen->TitleImage->Width + TITLEICON_SPACING), EntriesPosY);
             if (Screen->InfoLineCount > 0) {
                 for (i = 0; i < (INTN)Screen->InfoLineCount; i++) {
-                    DrawMenuText(Screen->InfoLines[i], 0, EntriesPosX, EntriesPosY);
+                    DrawSubmenuText(Screen->InfoLines[i], 0, EntriesPosX, EntriesPosY);
                     EntriesPosY += TEXT_LINE_HEIGHT;
                 }
                 EntriesPosY += TEXT_LINE_HEIGHT;  // also add a blank line
@@ -716,16 +730,16 @@ static VOID GraphicsMenuStyle(IN REFIT_MENU_SCREEN *Screen, IN SCROLL_STATE *Sta
 
         case MENU_FUNCTION_PAINT_ALL:
             for (i = 0; i <= State->MaxIndex; i++) {
-                DrawMenuText(Screen->Entries[i]->Title, (i == State->CurrentSelection) ? MenuWidth : 0,
+                DrawSubmenuText(Screen->Entries[i]->Title, (i == State->CurrentSelection) ? MenuWidth : 0,
                              EntriesPosX, EntriesPosY + i * TEXT_LINE_HEIGHT);
             }
             if (!(GlobalConfig.HideUIFlags & HIDEUI_FLAG_HINTS)) {
                if ((Screen->Hint1 != NULL) && (StrLen(Screen->Hint1) > 0)) {
-                  DrawMenuText(Screen->Hint1, 0, (UGAWidth - (StrLen(Screen->Hint1) * FONT_CELL_WIDTH)) / 2,
+                  DrawSubmenuText(Screen->Hint1, 0, (UGAWidth - (StrLen(Screen->Hint1) * FONT_CELL_WIDTH)) / 2,
                                UGAHeight - (FONT_CELL_HEIGHT * 3));
                }
                if ((Screen->Hint2 != NULL) && (StrLen(Screen->Hint2) > 0)) {
-                  DrawMenuText(Screen->Hint2, 0, (UGAWidth - (StrLen(Screen->Hint2) * FONT_CELL_WIDTH)) / 2,
+                  DrawSubmenuText(Screen->Hint2, 0, (UGAWidth - (StrLen(Screen->Hint2) * FONT_CELL_WIDTH)) / 2,
                                UGAHeight - (FONT_CELL_HEIGHT * 2));
                } // if
             } // if
@@ -733,14 +747,14 @@ static VOID GraphicsMenuStyle(IN REFIT_MENU_SCREEN *Screen, IN SCROLL_STATE *Sta
 
         case MENU_FUNCTION_PAINT_SELECTION:
             // redraw selection cursor
-            DrawMenuText(Screen->Entries[State->PreviousSelection]->Title, 0,
+            DrawSubmenuText(Screen->Entries[State->PreviousSelection]->Title, 0,
                          EntriesPosX, EntriesPosY + State->PreviousSelection * TEXT_LINE_HEIGHT);
-            DrawMenuText(Screen->Entries[State->CurrentSelection]->Title, MenuWidth,
+            DrawSubmenuText(Screen->Entries[State->CurrentSelection]->Title, MenuWidth,
                          EntriesPosX, EntriesPosY + State->CurrentSelection * TEXT_LINE_HEIGHT);
             break;
 
         case MENU_FUNCTION_PAINT_TIMEOUT:
-            DrawMenuText(ParamText, 0, EntriesPosX, TimeoutPosY);
+            DrawSubmenuText(ParamText, 0, EntriesPosX, TimeoutPosY);
             break;
 
     }
@@ -755,19 +769,21 @@ static VOID DrawMainMenuEntry(REFIT_MENU_ENTRY *Entry, BOOLEAN selected, UINTN X
     UINTN ImageNum;
 
     ImageNum = ((Entry->Row == 0) ? 0 : 2) + (selected ? 0 : 1);
-    if (SelectionImages != NULL)
-        BltImageCompositeBadge(SelectionImages[ImageNum],
-                               Entry->Image, Entry->BadgeImage, XPos, YPos);
-}
+    if (SelectionImages != NULL) {
+       if ((ImageNum == 1) || (ImageNum == 3)) { // Image not selected; copy background
+          DrawImageWithTransparency(Entry->Image, Entry->BadgeImage, XPos, YPos,
+                                 SelectionImages[ImageNum]->Width, SelectionImages[ImageNum]->Height);
+       } else {
+          BltImageCompositeBadge(SelectionImages[ImageNum], Entry->Image, Entry->BadgeImage, XPos, YPos);
+       } // if/else
+    } // if
+} // VOID DrawMainMenuEntry()
 
 static VOID DrawMainMenuText(IN CHAR16 *Text, IN UINTN XPos, IN UINTN YPos)
 {
     UINTN TextWidth, TextPosX;
 
-    if (TextBuffer == NULL)
-        TextBuffer = egCreateImage(LAYOUT_TEXT_WIDTH, TEXT_LINE_HEIGHT, FALSE);
-
-    egFillImage(TextBuffer, &MenuBackgroundPixel);
+    TextBuffer = egCropImage(GlobalConfig.ScreenBackground, XPos, YPos, LAYOUT_TEXT_WIDTH, TEXT_LINE_HEIGHT);
 
     // render the text
     egMeasureText(Text, &TextWidth, NULL);
@@ -776,8 +792,7 @@ static VOID DrawMainMenuText(IN CHAR16 *Text, IN UINTN XPos, IN UINTN YPos)
     else
        TextPosX = (TextBuffer->Width - TextWidth) / 2;
     egRenderText(Text, TextBuffer, TextPosX, 0);
-//    egRenderText(Text, TextBuffer, (TextBuffer->Width - TextWidth) >> 1, 0);
-    BltImage(TextBuffer, XPos, YPos);
+    DrawImageWithTransparency(TextBuffer, NULL, XPos, YPos, TextBuffer->Width, TextBuffer->Height);
 }
 
 static VOID PaintAll(IN REFIT_MENU_SCREEN *Screen, IN SCROLL_STATE *State, UINTN *itemPosX,
@@ -853,7 +868,7 @@ static VOID PaintIcon(IN EG_EMBEDDED_IMAGE *BuiltInIcon, IN CHAR16 *ExternalFile
    if (Icon != NULL) {
       if (Alignment == ALIGN_RIGHT)
          PosX -= Icon->Width;
-      BltImageAlpha(Icon, PosX, PosY - (Icon->Height / 2), &MenuBackgroundPixel);
+      DrawImageWithTransparency(Icon, NULL, PosX, PosY - (Icon->Height / 2), Icon->Width, Icon->Height);
    }
 } // static VOID PaintIcon()
 
index d6327555eeb756f4465b64820866d181ab4b8b90..cd2fc861dfe4303a616db1224798841f95284312 100644 (file)
@@ -435,7 +435,7 @@ VOID SwitchToGraphicsAndClear(VOID)
 
 VOID BltClearScreen(IN BOOLEAN ShowBanner)
 {
-    static EG_IMAGE *Banner = NULL;
+    static EG_IMAGE *Banner = NULL, *CroppedBanner;
     INTN BannerPosX, BannerPosY;
 
     if (ShowBanner && !(GlobalConfig.HideUIFlags & HIDEUI_FLAG_BANNER)) {
@@ -445,20 +445,26 @@ VOID BltClearScreen(IN BOOLEAN ShowBanner)
                 Banner = egPrepareEmbeddedImage(&egemb_refind_banner, FALSE);
             } else {
                 Banner = egLoadImage(SelfDir, GlobalConfig.BannerFileName, FALSE);
-                if ((Banner == NULL) || (Banner->Width > UGAWidth) || (Banner->Height > UGAHeight)) {
+                if (Banner && ((Banner->Width > UGAWidth) || (Banner->Height > UGAHeight))) {
+                   CroppedBanner = egCropImage(Banner, 0, 0, (Banner->Width > UGAWidth) ? UGAWidth : Banner->Width,
+                                               (Banner->Height > UGAHeight) ? UGAHeight : Banner->Height);
                    MyFreePool(Banner);
+                   Banner = CroppedBanner;
+                } // if image too big
+                if (Banner == NULL) {
                    Banner = egPrepareEmbeddedImage(&egemb_refind_banner, FALSE);
                 } // if unusable image
             }
             if (Banner != NULL)
-                MenuBackgroundPixel = Banner->PixelData[0];
+               MenuBackgroundPixel = Banner->PixelData[0];
         }
 
         // clear and draw banner
         egClearScreen(&MenuBackgroundPixel);
         if (Banner != NULL) {
             BannerPosX = (Banner->Width < UGAWidth) ? ((UGAWidth - Banner->Width) / 2) : 0;
-            BannerPosY = ComputeRow0PosX() - Banner->Height - LAYOUT_BANNER_YGAP;
+            BannerPosY = (ComputeRow0PosX() / 2) - Banner->Height;
+//            BannerPosY = ComputeRow0PosX() - Banner->Height - LAYOUT_BANNER_YGAP;
             if (BannerPosY < 0)
                BannerPosY = 0;
             BltImage(Banner, (UINTN) BannerPosX, (UINTN) BannerPosY);
@@ -470,6 +476,8 @@ VOID BltClearScreen(IN BOOLEAN ShowBanner)
     }
 
     GraphicsScreenDirty = FALSE;
+    egFreeImage(GlobalConfig.ScreenBackground);
+    GlobalConfig.ScreenBackground = egCopyScreen();
 }
 
 VOID BltImage(IN EG_IMAGE *Image, IN UINTN XPos, IN UINTN YPos)