From: srs5694 Date: Sun, 13 Jan 2013 04:40:37 +0000 (-0500) Subject: Support for transparency of icons & main menu text over large X-Git-Url: https://code.delx.au/refind/commitdiff_plain/3de252726460bd9affa70c91dac72af0347620c6 Support for transparency of icons & main menu text over large (fullscreen) banner graphic. --- diff --git a/NEWS.txt b/NEWS.txt index d14ebed..09f77c9 100644 --- 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). diff --git a/docs/refind/installing.html b/docs/refind/installing.html index a38452c..65e5b7d 100644 --- a/docs/refind/installing.html +++ b/docs/refind/installing.html @@ -142,7 +142,17 @@ href="mailto:rodsmith@rodsbooks.com">rodsmith@rodsbooks.com

  • Installing Additional Components
  • -
  • Fixing a Sluggish Macintosh Boot
  • +
  • Fixing a Sluggish Macintosh Boot + +
  • Uninstalling rEFInd
  • @@ -826,7 +836,27 @@ $ ioreg -l -p IODeviceTree | grep firmware-abi

    Fixing a Sluggish Macintosh Boot

    -

    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 Web forum post describing a possible fix. Be aware, though, that this procedure involves using the efibootmgr 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:

    +

    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: moving rEFInd to an HFS+ volume, using the fallback filename, and clearing NVRAM entries.

    + + +

    Moving rEFInd to an HFS+ Volume

    +
    + +

    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.

    + +

    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 force option to mount; 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 /boot 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.

    + + +

    Using the Fallback Filename

    +
    + +

    I've received one report that installing rEFInd to the ESP using the fallback filename (EFI/BOOT/bootx64.efi on most systems, or EFI/BOOT/bootia32.efi on very old Macs) can work around the problem.

    + + +

    Clearing the NVRAM Entries

    +
    + +

    The first is a Web forum post that describes a possible fix. Be aware, though, that this procedure involves using the efibootmgr 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:

      diff --git a/libeg/image.c b/libeg/image.c index 39039da..cd25312 100644 --- a/libeg/image.c +++ b/libeg/image.c @@ -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); + } } } diff --git a/libeg/libeg.h b/libeg/libeg.h index 15e561a..77516c6 100644 --- a/libeg/libeg.h +++ b/libeg/libeg.h @@ -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); diff --git a/libeg/load_icns.c b/libeg/load_icns.c index 5477f46..f357ac3 100644 --- a/libeg/load_icns.c +++ b/libeg/load_icns.c @@ -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 */ diff --git a/libeg/screen.c b/libeg/screen.c index 44d5c39..da934cf 100644 --- a/libeg/screen.c +++ b/libeg/screen.c @@ -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 diff --git a/refind.conf-sample b/refind.conf-sample index 424b8c4..657e69d 100644 --- a/refind.conf-sample +++ b/refind.conf-sample @@ -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 diff --git a/refind/global.h b/refind/global.h index 9d6b667..4e381db 100644 --- a/refind/global.h +++ b/refind/global.h @@ -223,6 +223,7 @@ typedef struct { UINTN LegacyType; UINTN ScanDelay; CHAR16 *BannerFileName; + EG_IMAGE *ScreenBackground; CHAR16 *SelectionSmallFileName; CHAR16 *SelectionBigFileName; CHAR16 *DefaultSelection; diff --git a/refind/main.c b/refind/main.c index 4006ac7..0024c3d 100644 --- a/refind/main.c +++ b/refind/main.c @@ -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"); diff --git a/refind/menu.c b/refind/menu.c index 5154892..e6f9d4f 100644 --- a/refind/menu.c +++ b/refind/menu.c @@ -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() diff --git a/refind/screen.c b/refind/screen.c index d632755..cd2fc86 100644 --- a/refind/screen.c +++ b/refind/screen.c @@ -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)