From 8b5b878155046a6da1956a2855f39f364abc0338 Mon Sep 17 00:00:00 2001 From: srs5694 Date: Sat, 8 Mar 2014 21:37:10 -0500 Subject: [PATCH] New small_icon_size and big_icon_size tokens for refind.conf. --- docs/refind/configfile.html | 33 +++++++++++-- libeg/image.c | 70 ++++++++++++++-------------- libeg/load_icns.c | 6 --- refind.conf-sample | 11 +++++ refind/config.c | 18 ++++++-- refind/global.h | 10 ++++ refind/icns.c | 44 +++++++++--------- refind/icns.h | 2 +- refind/lib.c | 4 +- refind/main.c | 9 ++-- refind/menu.c | 92 +++++++++++++++---------------------- refind/screen.c | 2 +- 12 files changed, 167 insertions(+), 134 deletions(-) diff --git a/docs/refind/configfile.html b/docs/refind/configfile.html index 1a041ca..8c63fd3 100644 --- a/docs/refind/configfile.html +++ b/docs/refind/configfile.html @@ -142,6 +142,8 @@ href="mailto:rodsmith@rodsbooks.com">rodsmith@rodsbooks.com

  • Hiding and Displaying EFI Boot Loaders
  • +
  • Setting OS Icons
  • +
  • Adjusting the Global Configuration
  • Creating OS Stanzas
  • @@ -166,13 +168,17 @@ href="mailto:rodsmith@rodsbooks.com">rodsmith@rodsbooks.com

    Another way to hide a boot loader is to move it into rEFInd's own directory. In order to keep rEFInd from showing up in its own menu, it ignores boot loaders in its own directory. This obviously includes the rEFInd binary file itself, but also anything else you might store there.

    -

    In addition to hiding boot loaders, you can adjust their icons. You can do this in any of five ways for auto-detected boot loaders:

    + +

    Setting OS Icons

    +
    + +

    In addition to hiding boot loaders, you can adjust their icons. You can do this in any of six ways for auto-detected boot loaders:

    As a special case, rEFInd assigns icons to the Windows and OS X boot loaders based on their conventional locations, so they get suitable icons even if they don't follow these rules.

    -

    In addition to the main OS tag icon, you can set the badge icon for a volume by creating a file called .VolumeBadge.icns or .VolumeBadge.png in the root directory of a partition. This icon file must include a 32x32 bitmap. If present, it replaces the disk-type icons that are overlaid on the main OS icon. If you use this feature, the badge is applied to all the boot loaders read from the disk, not just those stored in the root directory or the Apple boot loader location. You could use this feature to set a custom badge for different specific disks or to help differentiate multiple OS X installations on one computer. If you don't want any badges, you can replace the three badge icons in the rEFInd icons subdirectory (vol_external.icns, vol_internal.icns, and vol_optical.icns) with a completely transparent badge. The transparent.icns file in the rEFInd icons directory may be used for this purpose.

    +

    In addition to the main OS tag icon, you can set the badge icon for a volume by creating a file called .VolumeBadge.icns or .VolumeBadge.png in the root directory of a partition. If present, it replaces the disk-type icons that are overlaid on the main OS icon. If you use this feature, the badge is applied to all the boot loaders read from the disk, not just those stored in the root directory or the Apple boot loader location. You could use this feature to set a custom badge for different specific disks or to help differentiate multiple OS X installations on one computer. If you don't want any badges, you can replace the three badge icons in the rEFInd icons subdirectory (vol_external.icns, vol_internal.icns, and vol_optical.icns) with a completely transparent badge. The transparent.icns file in the rEFInd icons directory may be used for this purpose.

    + +

    The default icon sizes are 128x128 pixels for OS icons, 48x48 pixels for the second-row tools, and 32x32 pixels for badges. You can change the sizes of the big OS icons and the small tool icons with the big_icon_size and small_icon_size tokens in refind.conf, as noted in Table 1. The size of the disk-type badges is 1/4 the size of OS icons.

    Adjusting the Global Configuration

    @@ -233,6 +243,21 @@ timeout 20 filename Specifies a custom banner file to replace the rEFInd banner image. The file should be a BMP or PNG image with a color depth of 24, 8, 4, or 1 bits. The file path is relative to the directory where the rEFInd binary is stored. + + banner_scale + noscale or fillscreen + Tells rEFInd whether to display banner images pixel-for-pixel (noscale) or to scale banner images to fill the screen (fillscreen). The former is the default. + + + big_icon_size + numeric value (at least 32) + Sets the size of big icons (those used for OSes on the first row). All icons are square, so only one value is specified. If icon files don't contain images of the specified size, the available images are scaled to this size. The disk-type badge size is set indirectly by this token; badges are 1/4 the size of big icons. The default value is 128. + + + small_icon_size + numeric value (at least 32) + Sets the size of small icons (those used for tools on the second row). All icons are square, so only one value is specified. If icon files don't contain images of the specified size, the available images are scaled to this size. The default value is 128. + selection_big filename diff --git a/libeg/image.c b/libeg/image.c index 530589a..da3ccc6 100644 --- a/libeg/image.c +++ b/libeg/image.c @@ -69,7 +69,7 @@ EG_IMAGE * egCreateImage(IN UINTN Width, IN UINTN Height, IN BOOLEAN HasAlpha) return NULL; NewImage->PixelData = (EG_PIXEL *) AllocatePool(Width * Height * sizeof(EG_PIXEL)); if (NewImage->PixelData == NULL) { - FreePool(NewImage); + egFreeImage(NewImage); return NULL; } @@ -129,7 +129,7 @@ EG_IMAGE * egCropImage(IN EG_IMAGE *Image, IN UINTN StartX, IN UINTN StartY, IN // code presented at http://tech-algorithm.com/articles/bilinear-image-scaling/. // Resize an image; returns pointer to resized image if successful, NULL otherwise. // Calling function is responsible for freeing allocated memory. -EG_IMAGE * egScaleImage(EG_IMAGE *Image, UINTN NewWidth, UINTN NewHeight) { +EG_IMAGE * egScaleImage(IN EG_IMAGE *Image, IN UINTN NewWidth, IN UINTN NewHeight) { EG_IMAGE *NewImage = NULL; EG_PIXEL a, b, c, d; UINTN x, y, Index ; @@ -147,20 +147,20 @@ EG_IMAGE * egScaleImage(EG_IMAGE *Image, UINTN NewWidth, UINTN NewHeight) { if (NewImage == NULL) return NULL; - x_ratio = ((float)(Image->Width-1))/NewWidth ; - y_ratio = ((float)(Image->Height-1))/NewHeight ; + x_ratio = ((float)(Image->Width - 1)) / NewWidth; + y_ratio = ((float)(Image->Height - 1)) / NewHeight; for (i = 0; i < NewHeight; i++) { for (j = 0; j < NewWidth; j++) { - x = (UINTN)(x_ratio * j) ; - y = (UINTN)(y_ratio * i) ; - x_diff = (x_ratio * j) - x ; - y_diff = (y_ratio * i) - y ; - Index = ((y * Image->Width) + x) ; - a = Image->PixelData[Index] ; - b = Image->PixelData[Index + 1] ; - c = Image->PixelData[Index + Image->Width] ; - d = Image->PixelData[Index + Image->Width + 1] ; + x = (UINTN)(x_ratio * j); + y = (UINTN)(y_ratio * i); + x_diff = (x_ratio * j) - x; + y_diff = (y_ratio * i) - y; + Index = ((y * Image->Width) + x); + a = Image->PixelData[Index]; + b = Image->PixelData[Index + 1]; + c = Image->PixelData[Index + Image->Width]; + d = Image->PixelData[Index + Image->Width + 1]; // blue element // Yb = Ab(1-Image->Width)(1-Image->Height) + Bb(Image->Width)(1-Image->Height) + Cb(Image->Height)(1-Image->Width) + Db(wh) @@ -321,7 +321,7 @@ EG_IMAGE * egLoadImage(IN EFI_FILE* BaseDir, IN CHAR16 *FileName, IN BOOLEAN Wan return NULL; // decode it - NewImage = egDecodeAny(FileData, FileDataLength, 128, WantAlpha); + NewImage = egDecodeAny(FileData, FileDataLength, 128 /* arbitrary value */, WantAlpha); FreePool(FileData); return NewImage; @@ -351,7 +351,7 @@ EG_IMAGE * egLoadIcon(IN EFI_FILE* BaseDir, IN CHAR16 *Path, IN UINTN IconSize) NewImage = egScaleImage(Image, IconSize, IconSize); if (!NewImage) Print(L"Warning: Unable to scale icon of the wrong size from '%s'\n", Path); - MyFreePool(Image); + egFreeImage(Image); Image = NewImage; } @@ -617,26 +617,26 @@ VOID egComposeImage(IN OUT EG_IMAGE *CompImage, IN EG_IMAGE *TopImage, IN UINTN } } /* VOID egComposeImage() */ -EG_IMAGE * egEnsureImageSize(IN EG_IMAGE *Image, IN UINTN Width, IN UINTN Height, IN EG_PIXEL *Color) -{ - EG_IMAGE *NewImage; - - if (Image == NULL) - return NULL; - if (Image->Width == Width && Image->Height == Height) - return Image; - - NewImage = egCreateFilledImage(Width, Height, Image->HasAlpha, Color); - if (NewImage == NULL) { - egFreeImage(Image); - return NULL; - } - Image->HasAlpha = FALSE; - egComposeImage(NewImage, Image, 0, 0); - egFreeImage(Image); - - return NewImage; -} +// EG_IMAGE * egEnsureImageSize(IN EG_IMAGE *Image, IN UINTN Width, IN UINTN Height, IN EG_PIXEL *Color) +// { +// EG_IMAGE *NewImage; +// +// if (Image == NULL) +// return NULL; +// if (Image->Width == Width && Image->Height == Height) +// return Image; +// +// NewImage = egCreateFilledImage(Width, Height, Image->HasAlpha, Color); +// if (NewImage == NULL) { +// egFreeImage(Image); +// return NULL; +// } +// Image->HasAlpha = FALSE; +// egComposeImage(NewImage, Image, 0, 0); +// egFreeImage(Image); +// +// return NewImage; +// } // // misc internal functions diff --git a/libeg/load_icns.c b/libeg/load_icns.c index ce9e7ab..41fca77 100644 --- a/libeg/load_icns.c +++ b/libeg/load_icns.c @@ -174,12 +174,6 @@ EG_IMAGE * egDecodeICNS(IN UINT8 *FileData, IN UINTN FileDataLength, IN UINTN Ic } } while ((DataPtr == NULL) && (SizeToTry++ < MAX_ICNS_SIZES)); - /* FUTURE: try to load a different size and scale it later - if (DataPtr == NULL && IconSize == 32) { - IconSize = 128; - continue; - } - */ break; } diff --git a/refind.conf-sample b/refind.conf-sample index 9d84357..ebca00f 100644 --- a/refind.conf-sample +++ b/refind.conf-sample @@ -59,6 +59,17 @@ timeout 20 # #banner_scale fillscreen +# Icon sizes. All icons are square, so just one value is specified. The +# big icons are used for OS selectors in the first row and the small +# icons are used for tools on the second row. Drive-type badges are 1/4 +# the size of the big icons. Legal values are 32 and above. If the icon +# files do not hold icons of the proper size, the icons are scaled to +# the specified size. The default values are 48 and 128 for small and +# big icons, respectively. +# +#small_icon_size 96 +#big_icon_size 256 + # Custom images for the selection background. There is a big one (144 x 144) # for the OS icons, and a small one (64 x 64) for the function icons in the # second row. If only a small image is given, that one is also used for diff --git a/refind/config.c b/refind/config.c index fd7f677..d3b0601 100644 --- a/refind/config.c +++ b/refind/config.c @@ -561,12 +561,24 @@ VOID ReadConfig(CHAR16 *FileName) } else if ((StriCmp(TokenList[0], L"banner_scale") == 0) && (TokenCount == 2)) { if (StriCmp(TokenList[1], L"noscale") == 0) { GlobalConfig.BannerScale = BANNER_NOSCALE; - } else if (StriCmp(TokenList[1], L"fillscreen") == 0) { + } else if ((StriCmp(TokenList[1], L"fillscreen") == 0) || (StriCmp(TokenList[1], L"fullscreen") == 0)) { GlobalConfig.BannerScale = BANNER_FILLSCREEN; } else { Print(L" unknown banner_type flag: '%s'\n", TokenList[1]); } // if/else + } else if ((StriCmp(TokenList[0], L"small_icon_size") == 0) && (TokenCount == 2)) { + HandleInt(TokenList, TokenCount, &i); + if (i >= 32) + GlobalConfig.IconSizes[ICON_SIZE_SMALL] = i; + + } else if ((StriCmp(TokenList[0], L"big_icon_size") == 0) && (TokenCount == 2)) { + HandleInt(TokenList, TokenCount, &i); + if (i >= 32) { + GlobalConfig.IconSizes[ICON_SIZE_BIG] = i; + GlobalConfig.IconSizes[ICON_SIZE_BADGE] = i / 4; + } + } else if (StriCmp(TokenList[0], L"selection_small") == 0) { HandleString(TokenList, TokenCount, &(GlobalConfig.SelectionSmallFileName)); @@ -792,9 +804,9 @@ static LOADER_ENTRY * AddStanzaEntries(REFIT_FILE *File, REFIT_VOLUME *Volume, C } else if ((StriCmp(TokenList[0], L"icon") == 0) && (TokenCount > 1)) { MyFreePool(Entry->me.Image); - Entry->me.Image = egLoadIcon(CurrentVolume->RootDir, TokenList[1], 128); + Entry->me.Image = egLoadIcon(CurrentVolume->RootDir, TokenList[1], GlobalConfig.IconSizes[ICON_SIZE_BIG]); if (Entry->me.Image == NULL) { - Entry->me.Image = DummyImage(128); + Entry->me.Image = DummyImage(GlobalConfig.IconSizes[ICON_SIZE_BIG]); } } else if ((StriCmp(TokenList[0], L"initrd") == 0) && (TokenCount > 1)) { diff --git a/refind/global.h b/refind/global.h index 6641d8b..947ba34 100644 --- a/refind/global.h +++ b/refind/global.h @@ -128,6 +128,15 @@ #define BANNER_NOSCALE 0 #define BANNER_FILLSCREEN 1 +// Sizes of the default icons; badges are 1/4 the big icon size +#define DEFAULT_SMALL_ICON_SIZE 48 +#define DEFAULT_BIG_ICON_SIZE 128 + +// Codes for types of icon sizes; used for indexing into GlobalConfig.IconSizes[] +#define ICON_SIZE_BADGE 0 +#define ICON_SIZE_SMALL 1 +#define ICON_SIZE_BIG 2 + // Names of binaries that can manage MOKs.... #define MOK_NAMES L"MokManager.efi,HashTool.efi,HashTool-signed.efi" // Directories to search for these MOK-managing programs. Note that SelfDir is @@ -243,6 +252,7 @@ typedef struct { UINTN LegacyType; UINTN ScanDelay; UINTN ScreensaverTime; + UINTN IconSizes[3]; UINTN BannerScale; CHAR16 *BannerFileName; EG_IMAGE *ScreenBackground; diff --git a/refind/icns.c b/refind/icns.c index 45c5049..53a94ef 100644 --- a/refind/icns.c +++ b/refind/icns.c @@ -47,25 +47,25 @@ typedef struct { EG_IMAGE *Image; CHAR16 *FileName; - UINTN PixelSize; + UINTN IconSize; } BUILTIN_ICON; BUILTIN_ICON BuiltinIconTable[BUILTIN_ICON_COUNT] = { - { NULL, L"func_about", 48 }, - { NULL, L"func_reset", 48 }, - { NULL, L"func_shutdown", 48 }, - { NULL, L"func_exit", 48 }, - { NULL, L"func_firmware", 48 }, - { NULL, L"tool_shell", 48 }, - { NULL, L"tool_part", 48 }, - { NULL, L"tool_rescue", 48 }, - { NULL, L"tool_apple_rescue", 48 }, - { NULL, L"tool_windows_rescue", 48 }, - { NULL, L"tool_mok_tool", 48 }, - { NULL, L"tool_memtest", 48 }, - { NULL, L"vol_internal", 32 }, - { NULL, L"vol_external", 32 }, - { NULL, L"vol_optical", 32 }, + { NULL, L"func_about", ICON_SIZE_SMALL }, + { NULL, L"func_reset", ICON_SIZE_SMALL }, + { NULL, L"func_shutdown", ICON_SIZE_SMALL }, + { NULL, L"func_exit", ICON_SIZE_SMALL }, + { NULL, L"func_firmware", ICON_SIZE_SMALL }, + { NULL, L"tool_shell", ICON_SIZE_SMALL }, + { NULL, L"tool_part", ICON_SIZE_SMALL }, + { NULL, L"tool_rescue", ICON_SIZE_SMALL }, + { NULL, L"tool_apple_rescue", ICON_SIZE_SMALL }, + { NULL, L"tool_windows_rescue", ICON_SIZE_SMALL }, + { NULL, L"tool_mok_tool", ICON_SIZE_SMALL }, + { NULL, L"tool_memtest", ICON_SIZE_SMALL }, + { NULL, L"vol_internal", ICON_SIZE_BADGE }, + { NULL, L"vol_external", ICON_SIZE_BADGE }, + { NULL, L"vol_optical", ICON_SIZE_BADGE }, }; EG_IMAGE * BuiltinIcon(IN UINTN Id) @@ -74,9 +74,9 @@ EG_IMAGE * BuiltinIcon(IN UINTN Id) return NULL; if (BuiltinIconTable[Id].Image == NULL) { - BuiltinIconTable[Id].Image = egFindIcon(BuiltinIconTable[Id].FileName, BuiltinIconTable[Id].PixelSize); + BuiltinIconTable[Id].Image = egFindIcon(BuiltinIconTable[Id].FileName, GlobalConfig.IconSizes[BuiltinIconTable[Id].IconSize]); if (BuiltinIconTable[Id].Image == NULL) - BuiltinIconTable[Id].Image = DummyImage(BuiltinIconTable[Id].PixelSize); + BuiltinIconTable[Id].Image = DummyImage(GlobalConfig.IconSizes[BuiltinIconTable[Id].IconSize]); } // if return BuiltinIconTable[Id].Image; @@ -102,24 +102,24 @@ EG_IMAGE * LoadOSIcon(IN CHAR16 *OSIconName OPTIONAL, IN CHAR16 *FallbackIconNam // First, try to find an icon from the OSIconName list.... while (((CutoutName = FindCommaDelimited(OSIconName, Index++)) != NULL) && (Image == NULL)) { SPrint(BaseName, 255, L"%s_%s", BootLogo ? L"boot" : L"os", CutoutName); - Image = egFindIcon(BaseName, 128); + Image = egFindIcon(BaseName, GlobalConfig.IconSizes[ICON_SIZE_BIG]); } // If that fails, try again using the FallbackIconName.... if (Image == NULL) { SPrint(BaseName, 255, L"%s_%s", BootLogo ? L"boot" : L"os", FallbackIconName); - Image = egFindIcon(BaseName, 128); + Image = egFindIcon(BaseName, GlobalConfig.IconSizes[ICON_SIZE_BIG]); } // If that fails and if BootLogo was set, try again using the "os_" start of the name.... if (BootLogo && (Image == NULL)) { SPrint(BaseName, 255, L"os_%s", FallbackIconName); - Image = egFindIcon(BaseName, 128); + Image = egFindIcon(BaseName, GlobalConfig.IconSizes[ICON_SIZE_BIG]); } // If all of these fail, return the dummy image.... if (Image == NULL) - Image = DummyImage(128); + Image = DummyImage(GlobalConfig.IconSizes[ICON_SIZE_BIG]); return Image; } /* EG_IMAGE * LoadOSIcon() */ diff --git a/refind/icns.h b/refind/icns.h index 229594f..25b545e 100644 --- a/refind/icns.h +++ b/refind/icns.h @@ -34,7 +34,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* - * Modifications copyright (c) 2012 Roderick W. Smith + * Modifications copyright (c) 2012-2014 Roderick W. Smith * * Modifications distributed under the terms of the GNU General Public * License (GPL) version 3 (GPLv3), a copy of which must be distributed diff --git a/refind/lib.c b/refind/lib.c index a3a8cfe..0de0cc4 100644 --- a/refind/lib.c +++ b/refind/lib.c @@ -662,7 +662,7 @@ static VOID ScanVolumeBootcode(REFIT_VOLUME *Volume, BOOLEAN *Bootable) VOID SetVolumeBadgeIcon(REFIT_VOLUME *Volume) { if (Volume->VolBadgeImage == NULL) { - Volume->VolBadgeImage = egLoadIconAnyType(Volume->RootDir, L"", L".VolumeBadge", 128); + Volume->VolBadgeImage = egLoadIconAnyType(Volume->RootDir, L"", L".VolumeBadge", GlobalConfig.IconSizes[ICON_SIZE_BADGE]); } if (Volume->VolBadgeImage == NULL) { @@ -889,7 +889,7 @@ VOID ScanVolume(REFIT_VOLUME *Volume) // get custom volume icons if present if (!Volume->VolIconImage) - Volume->VolIconImage = egLoadIconAnyType(Volume->RootDir, L"", L".VolumeIcon", 128); + Volume->VolIconImage = egLoadIconAnyType(Volume->RootDir, L"", L".VolumeIcon", GlobalConfig.IconSizes[ICON_SIZE_BIG]); } // ScanVolume() static VOID ScanExtendedPartition(REFIT_VOLUME *WholeDiskVolume, MBR_PARTITION_INFO *MbrEntry) diff --git a/refind/main.c b/refind/main.c index 3581067..027afc2 100644 --- a/refind/main.c +++ b/refind/main.c @@ -132,7 +132,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, 0, DONT_CHANGE_TEXT_MODE, 20, 0, 0, GRAPHICS_FOR_OSX, LEGACY_TYPE_MAC, 0, 0, - BANNER_NOSCALE, + { DEFAULT_BIG_ICON_SIZE / 4, DEFAULT_SMALL_ICON_SIZE, DEFAULT_BIG_ICON_SIZE }, BANNER_NOSCALE, NULL, NULL, CONFIG_FILE_NAME, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, { TAG_SHELL, TAG_MEMTEST, TAG_APPLE_RECOVERY, TAG_WINDOWS_RECOVERY, TAG_MOK_TOOL, TAG_ABOUT, TAG_SHUTDOWN, TAG_REBOOT, TAG_FIRMWARE, 0, 0, 0, 0, 0, 0 } @@ -156,7 +156,7 @@ static VOID AboutrEFInd(VOID) { if (AboutMenu.EntryCount == 0) { AboutMenu.TitleImage = BuiltinIcon(BUILTIN_ICON_FUNC_ABOUT); - AddMenuInfoLine(&AboutMenu, L"rEFInd Version 0.7.7"); + AddMenuInfoLine(&AboutMenu, L"rEFInd Version 0.7.7.2"); AddMenuInfoLine(&AboutMenu, L""); AddMenuInfoLine(&AboutMenu, L"Copyright (c) 2006-2010 Christoph Pfisterer"); AddMenuInfoLine(&AboutMenu, L"Copyright (c) 2012-2013 Roderick W. Smith"); @@ -898,7 +898,7 @@ VOID SetLoaderDefaults(LOADER_ENTRY *Entry, CHAR16 *LoaderPath, REFIT_VOLUME *Vo // locate a custom icon for the loader // Anything found here takes precedence over the "hints" in the OSIconName variable if (!Entry->me.Image) - Entry->me.Image = egLoadIconAnyType(Volume->RootDir, PathOnly, NoExtension, 128); + Entry->me.Image = egLoadIconAnyType(Volume->RootDir, PathOnly, NoExtension, GlobalConfig.IconSizes[ICON_SIZE_BIG]); if (!Entry->me.Image) Entry->me.Image = egCopyImage(Volume->VolIconImage); @@ -2423,8 +2423,7 @@ static VOID SetConfigFilename(EFI_HANDLE ImageHandle) { EFI_STATUS Status; INTN Where; - Status = uefi_call_wrapper(BS->HandleProtocol, 3, ImageHandle, - &LoadedImageProtocol, (VOID **) &Info); + Status = refit_call3_wrapper(BS->HandleProtocol, ImageHandle, &LoadedImageProtocol, (VOID **) &Info); if ((Status == EFI_SUCCESS) && (Info->LoadOptionsSize > 0)) { Options = (CHAR16 *) Info->LoadOptions; Where = FindSubString(L" -c ", Options); diff --git a/refind/menu.c b/refind/menu.c index eb49b92..4c0d359 100644 --- a/refind/menu.c +++ b/refind/menu.c @@ -52,6 +52,7 @@ #include "../include/refit_call_wrapper.h" #include "../include/egemb_back_selected_small.h" +#include "../include/egemb_back_selected_big.h" #include "../include/egemb_arrow_left.h" #include "../include/egemb_arrow_right.h" @@ -68,15 +69,12 @@ typedef VOID (*MENU_STYLE_FUNC)(IN REFIT_MENU_SCREEN *Screen, IN SCROLL_STATE *S static CHAR16 ArrowUp[2] = { ARROW_UP, 0 }; static CHAR16 ArrowDown[2] = { ARROW_DOWN, 0 }; +static UINTN TileSizes[2] = { 144, 64 }; // Text and icon spacing constants.... #define TEXT_YMARGIN (2) -//#define TEXT_XMARGIN (8) -//#define TEXT_LINE_HEIGHT (FONT_CELL_HEIGHT + TEXT_YMARGIN * 2) #define TITLEICON_SPACING (16) -#define ROW0_TILESIZE (144) -#define ROW1_TILESIZE (64) #define TILE_XSPACING (8) #define TILE_YSPACING (16) @@ -93,8 +91,8 @@ static EG_PIXEL SelectionBackgroundPixel = { 0xff, 0xff, 0xff, 0 }; static VOID InitSelection(VOID) { - UINTN x, y, src_x, src_y; - EG_PIXEL *DestPtr, *SrcPtr; + EG_IMAGE *TempSmallImage = NULL, *TempBigImage = NULL; + BOOLEAN LoadedSmallImage = FALSE; if (!AllowGraphicsMode) return; @@ -103,51 +101,32 @@ static VOID InitSelection(VOID) // load small selection image if (GlobalConfig.SelectionSmallFileName != NULL) { - SelectionImages[1] = egLoadImage(SelfDir, GlobalConfig.SelectionSmallFileName, TRUE); + TempSmallImage = egLoadImage(SelfDir, GlobalConfig.SelectionSmallFileName, TRUE); } - if (SelectionImages[1] == NULL) - SelectionImages[1] = egPrepareEmbeddedImage(&egemb_back_selected_small, TRUE); - SelectionImages[1] = egEnsureImageSize(SelectionImages[1], ROW1_TILESIZE, ROW1_TILESIZE, &MenuBackgroundPixel); - if (SelectionImages[1] == NULL) - return; + if (TempSmallImage == NULL) + TempSmallImage = egPrepareEmbeddedImage(&egemb_back_selected_small, TRUE); + else + LoadedSmallImage = TRUE; + SelectionImages[1] = egScaleImage(TempSmallImage, TileSizes[1], TileSizes[1]); // load big selection image if (GlobalConfig.SelectionBigFileName != NULL) { - SelectionImages[0] = egLoadImage(SelfDir, GlobalConfig.SelectionBigFileName, TRUE); - SelectionImages[0] = egEnsureImageSize(SelectionImages[0], ROW0_TILESIZE, ROW0_TILESIZE, &MenuBackgroundPixel); + TempBigImage = egLoadImage(SelfDir, GlobalConfig.SelectionBigFileName, TRUE); } - if (SelectionImages[0] == NULL) { - // calculate big selection image from small one - - SelectionImages[0] = egCreateImage(ROW0_TILESIZE, ROW0_TILESIZE, TRUE); - if (SelectionImages[0] == NULL) { - egFreeImage(SelectionImages[1]); - SelectionImages[1] = NULL; - return; - } - - DestPtr = SelectionImages[0]->PixelData; - SrcPtr = SelectionImages[1]->PixelData; - for (y = 0; y < ROW0_TILESIZE; y++) { - if (y < (ROW1_TILESIZE >> 1)) - src_y = y; - else if (y < (ROW0_TILESIZE - (ROW1_TILESIZE >> 1))) - src_y = (ROW1_TILESIZE >> 1); - else - src_y = y - (ROW0_TILESIZE - ROW1_TILESIZE); - - for (x = 0; x < ROW0_TILESIZE; x++) { - if (x < (ROW1_TILESIZE >> 1)) - src_x = x; - else if (x < (ROW0_TILESIZE - (ROW1_TILESIZE >> 1))) - src_x = (ROW1_TILESIZE >> 1); - else - src_x = x - (ROW0_TILESIZE - ROW1_TILESIZE); - - *DestPtr++ = SrcPtr[src_y * ROW1_TILESIZE + src_x]; - } + if (TempBigImage == NULL) { + if (LoadedSmallImage) { + // calculate big selection image from small one + TempBigImage = egCopyImage(TempSmallImage); + } else { + TempBigImage = egPrepareEmbeddedImage(&egemb_back_selected_big, TRUE); } } + SelectionImages[0] = egScaleImage(TempBigImage, TileSizes[0], TileSizes[0]); + + if (TempSmallImage) + egFreeImage(TempSmallImage); + if (TempBigImage) + egFreeImage(TempBigImage); } // VOID InitSelection() // @@ -160,7 +139,7 @@ static VOID InitScroll(OUT SCROLL_STATE *State, IN UINTN ItemCount, IN UINTN Vis State->MaxIndex = (INTN)ItemCount - 1; State->FirstVisible = 0; if (AllowGraphicsMode) { - State->MaxVisible = UGAWidth / (ROW0_TILESIZE + TILE_XSPACING) - 1; + State->MaxVisible = UGAWidth / (TileSizes[0] + TILE_XSPACING) - 1; } else State->MaxVisible = ConHeight - 4; if ((VisibleSpace > 0) && (VisibleSpace < State->MaxVisible)) @@ -1011,7 +990,7 @@ static VOID PaintSelection(IN REFIT_MENU_SCREEN *Screen, IN SCROLL_STATE *State, static VOID PaintIcon(IN EG_EMBEDDED_IMAGE *BuiltInIcon, IN CHAR16 *ExternalFilename, UINTN PosX, UINTN PosY, UINTN Alignment) { EG_IMAGE *Icon = NULL; - Icon = egFindIcon(ExternalFilename, 48); + Icon = egFindIcon(ExternalFilename, GlobalConfig.IconSizes[ICON_SIZE_SMALL]); if (Icon == NULL) Icon = egPrepareEmbeddedImage(BuiltInIcon, TRUE); if (Icon != NULL) { @@ -1022,7 +1001,7 @@ static VOID PaintIcon(IN EG_EMBEDDED_IMAGE *BuiltInIcon, IN CHAR16 *ExternalFile } // static VOID () inline UINTN ComputeRow0PosY(VOID) { - return ((UGAHeight / 2) - ROW0_TILESIZE / 2); + return ((UGAHeight / 2) - TileSizes[0] / 2); } // UINTN ComputeRow0PosY() // Display (or erase) the arrow icons to the left and right of an icon's row, @@ -1034,7 +1013,7 @@ static VOID PaintArrows(SCROLL_STATE *State, UINTN PosX, UINTN PosY, UINTN row0L // NOTE: Assume that left and right arrows are of the same size.... Width = egemb_arrow_left.Width; Height = egemb_arrow_left.Height; - RightX = (UGAWidth + (ROW0_TILESIZE + TILE_XSPACING) * State->MaxVisible) / 2 + TILE_XSPACING; + RightX = (UGAWidth + (TileSizes[0] + TILE_XSPACING) * State->MaxVisible) / 2 + TILE_XSPACING; AdjPosY = PosY - (Height / 2); // For PaintIcon() calls, the starting Y position is moved to the midpoint @@ -1085,12 +1064,12 @@ VOID MainMenuStyle(IN REFIT_MENU_SCREEN *Screen, IN SCROLL_STATE *State, IN UINT row0Count++; } } - row0PosX = (UGAWidth + TILE_XSPACING - (ROW0_TILESIZE + TILE_XSPACING) * row0Count) >> 1; + row0PosX = (UGAWidth + TILE_XSPACING - (TileSizes[0] + TILE_XSPACING) * row0Count) >> 1; row0PosY = ComputeRow0PosY(); - row1PosX = (UGAWidth + TILE_XSPACING - (ROW1_TILESIZE + TILE_XSPACING) * row1Count) >> 1; - row1PosY = row0PosY + ROW0_TILESIZE + TILE_YSPACING; + row1PosX = (UGAWidth + TILE_XSPACING - (TileSizes[1] + TILE_XSPACING) * row1Count) >> 1; + row1PosY = row0PosY + TileSizes[0] + TILE_YSPACING; if (row1Count > 0) - textPosY = row1PosY + ROW1_TILESIZE + TILE_YSPACING; + textPosY = row1PosY + TileSizes[1] + TILE_YSPACING; else textPosY = row1PosY; @@ -1100,10 +1079,10 @@ VOID MainMenuStyle(IN REFIT_MENU_SCREEN *Screen, IN SCROLL_STATE *State, IN UINT for (i = 0; i <= State->MaxIndex; i++) { if (Screen->Entries[i]->Row == 0) { itemPosX[i] = row0PosXRunning; - row0PosXRunning += ROW0_TILESIZE + TILE_XSPACING; + row0PosXRunning += TileSizes[0] + TILE_XSPACING; } else { itemPosX[i] = row1PosXRunning; - row1PosXRunning += ROW1_TILESIZE + TILE_XSPACING; + row1PosXRunning += TileSizes[1] + TILE_XSPACING; } } // initial painting @@ -1120,7 +1099,7 @@ VOID MainMenuStyle(IN REFIT_MENU_SCREEN *Screen, IN SCROLL_STATE *State, IN UINT // For PaintArrows(), the starting Y position is moved to the midpoint // of the surrounding row; PaintIcon() adjusts this back up by half the // icon's height to properly center it. - PaintArrows(State, row0PosX - TILE_XSPACING, row0PosY + (ROW0_TILESIZE / 2), row0Loaders); + PaintArrows(State, row0PosX - TILE_XSPACING, row0PosY + (TileSizes[0] / 2), row0Loaders); break; case MENU_FUNCTION_PAINT_SELECTION: @@ -1188,6 +1167,9 @@ UINTN RunMainMenu(IN REFIT_MENU_SCREEN *Screen, IN CHAR16* DefaultSelection, OUT INTN DefaultEntryIndex = -1; INTN DefaultSubmenuIndex = -1; + TileSizes[0] = (GlobalConfig.IconSizes[ICON_SIZE_BIG] * 9) / 8; + TileSizes[1] = (GlobalConfig.IconSizes[ICON_SIZE_SMALL] * 4) / 3; + if (DefaultSelection != NULL) { // Find a menu entry that includes *DefaultSelection as a substring DefaultEntryIndex = FindMenuShortcutEntry(Screen, DefaultSelection); diff --git a/refind/screen.c b/refind/screen.c index 49c7a94..655057f 100644 --- a/refind/screen.c +++ b/refind/screen.c @@ -34,7 +34,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* - * Modifications copyright (c) 2012 Roderick W. Smith + * Modifications copyright (c) 2012-2014 Roderick W. Smith * * Modifications distributed under the terms of the GNU General Public * License (GPL) version 3 (GPLv3), a copy of which must be distributed -- 2.39.2