user-specified icon directory.
+0.6.7 (?/??/2013):
+------------------
+
+- Fixed broken mixing of PNG and ICNS icons when using a user-specified
+ icons directory -- previously, an ICNS file in the default directory
+ would override a PNG file in the user-specified directory.
+
0.6.6 (1/26/2013):
------------------
// Basic file operations
//
-EFI_STATUS egLoadFile(IN EFI_FILE* BaseDir, IN CHAR16 *FileName,
- OUT UINT8 **FileData, OUT UINTN *FileDataLength)
+EFI_STATUS egLoadFile(IN EFI_FILE* BaseDir, IN CHAR16 *FileName, OUT UINT8 **FileData, OUT UINTN *FileDataLength)
{
EFI_STATUS Status;
EFI_FILE_HANDLE FileHandle;
// Loading images from files and embedded data
//
-// static CHAR16 * egFindExtension(IN CHAR16 *FileName)
-// {
-// UINTN i;
-//
-// for (i = StrLen(FileName); i >= 0; i--) {
-// if (FileName[i] == '.')
-// return FileName + i + 1;
-// if (FileName[i] == '/' || FileName[i] == '\\')
-// break;
-// }
-// return FileName + StrLen(FileName);
-// }
-
// Decode the specified image data. The IconSize parameter is relevant only
// for ICNS, for which it selects which ICNS sub-image is decoded.
// Returns a pointer to the resulting EG_IMAGE or NULL if decoding failed.
}
// Load an icon from (BaseDir)/Path, extracting the icon of size IconSize x IconSize.
-// If the initial attempt is unsuccessful, try again, replacing the directory
-// component of Path with DEFAULT_ICONS_DIR.
-// Note: The assumption is that BaseDir points to rEFInd's home directory and Path
-// includes one subdirectory level. If this changes in future revisions, it may be
-// necessary to alter the code that tries again with DEFAULT_ICONS_DIR.
// Returns a pointer to the image data, or NULL if the icon could not be loaded.
EG_IMAGE * egLoadIcon(IN EFI_FILE* BaseDir, IN CHAR16 *Path, IN UINTN IconSize)
{
EFI_STATUS Status;
UINT8 *FileData;
UINTN FileDataLength;
- CHAR16 *FileName, FileName2[256];
EG_IMAGE *NewImage;
if (BaseDir == NULL || Path == NULL)
// load file
Status = egLoadFile(BaseDir, Path, &FileData, &FileDataLength);
- if (EFI_ERROR(Status)) {
- FileName = Basename(Path); // Note: FileName is a pointer within Path; DON'T FREE IT!
- SPrint(FileName2, 255, L"%s\\%s", DEFAULT_ICONS_DIR, FileName);
- Status = egLoadFile(BaseDir, FileName2, &FileData, &FileDataLength);
- if (EFI_ERROR(Status))
- return NULL;
- }
+ if (EFI_ERROR(Status))
+ return NULL;
// decode it
NewImage = egDecodeAny(FileData, FileDataLength, IconSize, TRUE);
return NewImage;
} // EG_IMAGE *egLoadIcon()
+// Returns an icon with any extension in ICON_EXTENSIONS from either the directory
+// specified by GlobalConfig.IconsDir or DEFAULT_ICONS_DIR. The input BaseName
+// should be the icon name without an extension. For instance, if BaseName is
+// os_linux, GlobalConfig.IconsDir is myicons, DEFAULT_ICONS_DIR is icons, and
+// ICON_EXTENSIONS is "icns,png", this function will return myicons/os_linux.icns,
+// myicons/os_linux.png, icons/os_linux.icns, or icons/os_linux.png, in that
+// order of preference. Returns NULL if no such icon can be found. All file
+// references are relative to SelfDir.
+EG_IMAGE * egFindIcon(IN CHAR16 *BaseName, IN UINTN IconSize) {
+ CHAR16 *LoadDir, *Extension;
+ CHAR16 FileName[256];
+ UINTN i;
+ EG_IMAGE *Image = NULL;
+
+ if (GlobalConfig.IconsDir != NULL)
+ LoadDir = GlobalConfig.IconsDir;
+ else
+ LoadDir = StrDuplicate(DEFAULT_ICONS_DIR);
+
+ while ((LoadDir != NULL) && (Image == NULL)) {
+ i = 0;
+ while (((Extension = FindCommaDelimited(ICON_EXTENSIONS, i++)) != NULL) && (Image == NULL)) {
+ SPrint(FileName, 255, L"%s\\%s.%s", LoadDir, BaseName, Extension);
+ Image = egLoadIcon(SelfDir, FileName, IconSize);
+ MyFreePool(Extension);
+ } // while()
+ if (LoadDir == GlobalConfig.IconsDir) {
+ LoadDir = StrDuplicate(DEFAULT_ICONS_DIR);
+ } else {
+ MyFreePool(LoadDir);
+ LoadDir = NULL;
+ } // if/else
+ } // while()
+ return Image;
+} // EG_IMAGE * egFindIcon()
+
EG_IMAGE * egPrepareEmbeddedImage(IN EG_EMBEDDED_IMAGE *EmbeddedImage, IN BOOLEAN WantAlpha)
{
EG_IMAGE *NewImage;
#define EG_EICOMPMODE_RLE (1)
#define EG_EICOMPMODE_EFICOMPRESS (2)
+#define ICON_EXTENSIONS L"icns,png"
+
typedef struct {
UINTN Width;
UINTN Height;
EG_IMAGE * egLoadImage(IN EFI_FILE* BaseDir, IN CHAR16 *FileName, IN BOOLEAN WantAlpha);
EG_IMAGE * egLoadIcon(IN EFI_FILE* BaseDir, IN CHAR16 *FileName, IN UINTN IconSize);
+EG_IMAGE * egFindIcon(IN CHAR16 *BaseName, IN UINTN IconSize);
EG_IMAGE * egPrepareEmbeddedImage(IN EG_EMBEDDED_IMAGE *EmbeddedImage, IN BOOLEAN WantAlpha);
EG_IMAGE * egEnsureImageSize(IN EG_IMAGE *Image, IN UINTN Width, IN UINTN Height, IN EG_PIXEL *Color);
Summary: EFI boot manager software
Name: refind
-Version: 0.6.6
+Version: 0.6.6.1
Release: 1%{?dist}
Summary: EFI boot manager software
License: GPLv3
} else if ((StriCmp(TokenList[0], L"icon") == 0) && (TokenCount > 1)) {
MyFreePool(Entry->me.Image);
- Entry->me.Image = LoadIcns(CurrentVolume->RootDir, TokenList[1], 128);
+// Entry->me.Image = LoadIcns(CurrentVolume->RootDir, TokenList[1], 128);
+ Entry->me.Image = egLoadIcon(CurrentVolume->RootDir, TokenList[1], 128);
if (Entry->me.Image == NULL) {
Entry->me.Image = DummyImage(128);
}
} BUILTIN_ICON;
BUILTIN_ICON BuiltinIconTable[BUILTIN_ICON_COUNT] = {
- { NULL, L"func_about.icns", 48 },
- { NULL, L"func_reset.icns", 48 },
- { NULL, L"func_shutdown.icns", 48 },
- { NULL, L"func_exit.icns", 48 },
- { NULL, L"tool_shell.icns", 48 },
- { NULL, L"tool_part.icns", 48 },
- { NULL, L"tool_rescue.icns", 48 },
- { NULL, L"tool_apple_rescue.icns", 48 },
- { NULL, L"tool_mok_tool.icns", 48 },
- { NULL, L"vol_internal.icns", 32 },
- { NULL, L"vol_external.icns", 32 },
- { NULL, L"vol_optical.icns", 32 },
+ { NULL, L"func_about", 48 },
+ { NULL, L"func_reset", 48 },
+ { NULL, L"func_shutdown", 48 },
+ { NULL, L"func_exit", 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_mok_tool", 48 },
+ { NULL, L"vol_internal", 32 },
+ { NULL, L"vol_external", 32 },
+ { NULL, L"vol_optical", 32 },
};
EG_IMAGE * BuiltinIcon(IN UINTN Id)
{
- CHAR16 FileName[256];
-
if (Id >= BUILTIN_ICON_COUNT)
return NULL;
if (BuiltinIconTable[Id].Image == NULL) {
- SPrint(FileName, 255, L"%s\\%s", GlobalConfig.IconsDir ? GlobalConfig.IconsDir : DEFAULT_ICONS_DIR,
- BuiltinIconTable[Id].FileName);
- BuiltinIconTable[Id].Image = LoadIcnsFallback(SelfDir, FileName, BuiltinIconTable[Id].PixelSize);
+ BuiltinIconTable[Id].Image = egFindIcon(BuiltinIconTable[Id].FileName, BuiltinIconTable[Id].PixelSize);
+ if (BuiltinIconTable[Id].Image == NULL)
+ BuiltinIconTable[Id].Image = DummyImage(BuiltinIconTable[Id].PixelSize);
} // if
return BuiltinIconTable[Id].Image;
}
-// Construct filename for all valid icon extensions and try to load it.
-// Returns image data or NULL if it can't be found.
-static EG_IMAGE * LoadIconAnyFormat(IN CHAR16 *IconsDir, IN CHAR16 *BaseName, IN CHAR16 *OsName) {
- CHAR16 FileName[256];
- CHAR16 *Extension;
- EG_IMAGE *Image = NULL;
- UINTN Index = 0;
-
- while (((Extension = FindCommaDelimited(ICON_EXTENSIONS, Index++)) != NULL) && (Image == NULL)) {
- SPrint(FileName, 255, L"%s\\%s_%s.%s", IconsDir, BaseName, OsName, Extension);
-
- // try to load it
- Image = egLoadIcon(SelfDir, FileName, 128);
- MyFreePool(Extension);
- } // while()
- return Image;
-} // EG_IMAGE * LoadIconAnyFormat()
-
//
// Load an icon for an operating system
//
// Load an OS icon from among the comma-delimited list provided in OSIconName.
// Searches for icons with extensions in the ICON_EXTENSIONS list (via
-// LoadIconAnyFormat()).
+// egFindIcon()).
// Returns image data. On failure, returns an ugly "dummy" icon.
EG_IMAGE * LoadOSIcon(IN CHAR16 *OSIconName OPTIONAL, IN CHAR16 *FallbackIconName, BOOLEAN BootLogo)
{
EG_IMAGE *Image = NULL;
- CHAR16 *CutoutName;
+ CHAR16 *CutoutName, BaseName[256];
UINTN Index = 0;
if (GlobalConfig.TextOnly) // skip loading if it's not used anyway
return NULL;
- // try the names from OSIconName
+ // First, try to find an icon from the OSIconName list....
while (((CutoutName = FindCommaDelimited(OSIconName, Index++)) != NULL) && (Image == NULL)) {
- Image = LoadIconAnyFormat(GlobalConfig.IconsDir ? GlobalConfig.IconsDir : DEFAULT_ICONS_DIR,
- BootLogo ? L"boot" : L"os", CutoutName);
- MyFreePool(CutoutName);
- } // while()
+ SPrint(BaseName, 255, L"%s_%s", BootLogo ? L"boot" : L"os", CutoutName);
+ Image = egFindIcon(BaseName, 128);
+ }
- // try the fallback name
- if (Image == NULL)
- Image = LoadIconAnyFormat(GlobalConfig.IconsDir ? GlobalConfig.IconsDir : DEFAULT_ICONS_DIR,
- BootLogo ? L"boot" : L"os", FallbackIconName);
+ // 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);
+ }
- // try the fallback name with os_ instead of boot_
- if (BootLogo && (Image == NULL))
- Image = LoadIconAnyFormat(GlobalConfig.IconsDir ? GlobalConfig.IconsDir : DEFAULT_ICONS_DIR, L"os", FallbackIconName);
+ // 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);
+ }
+
+ // If all of these fail, return the dummy image....
+ if (Image == NULL)
+ Image = DummyImage(128);
- if (Image != NULL)
- return Image;
- else
- return DummyImage(128);
+ return Image;
} /* EG_IMAGE * LoadOSIcon() */
return Image;
}
-
-EG_IMAGE * LoadIcnsFallback(IN EFI_FILE_HANDLE BaseDir, IN CHAR16 *FileName, IN UINTN PixelSize)
-{
- EG_IMAGE *Image;
- if (GlobalConfig.TextOnly) // skip loading if it's not used anyway
- return NULL;
-
- Image = LoadIcns(BaseDir, FileName, PixelSize);
- if (Image == NULL) {
- Image = DummyImage(PixelSize);
- }
- return Image;
-}
// icns loader module
//
-#define ICON_EXTENSIONS L"icns,png"
-
EG_IMAGE * LoadOSIcon(IN CHAR16 *OSIconName OPTIONAL, IN CHAR16 *FallbackIconName, BOOLEAN BootLogo);
EG_IMAGE * LoadIcns(IN EFI_FILE_HANDLE BaseDir, IN CHAR16 *FileName, IN UINTN PixelSize);
-EG_IMAGE * LoadIcnsFallback(IN EFI_FILE_HANDLE BaseDir, IN CHAR16 *FileName, IN UINTN PixelSize);
EG_IMAGE * DummyImage(IN UINTN PixelSize);
EG_IMAGE * BuiltinIcon(IN UINTN Id);
while (KeepGoing && (OnePattern = FindCommaDelimited(FilePattern, i++)) != NULL) {
if (MetaiMatch(DirIter->LastFileInfo->FileName, OnePattern))
KeepGoing = FALSE;
+// Print(L"%s did%s match %s\n", DirIter->LastFileInfo->FileName, KeepGoing ? L" not" : L"", OnePattern);
} // while
// else continue loop
} else
break;
- } while (KeepGoing);
+ } while (KeepGoing && FilePattern);
*DirEntry = DirIter->LastFileInfo;
return TRUE;
#define FALLBACK_BASENAME L"boot.efi" /* Not really correct */
#endif
-#define MOK_NAMES L"\\EFI\\tools\\MokManager.efi,\\EFI\\redhat\\MokManager.efi,\\EFI\\ubuntu\\MokManager.efi,\\EFI\\suse\\MokManager"
+#define MOK_NAMES L"\\EFI\\tools\\MokManager.efi,\\EFI\\fedora\\MokManager.efi,\\EFI\\redhat\\MokManager.efi,\\EFI\\ubuntu\\MokManager.efi,\\EFI\\suse\\MokManager"
// Filename patterns that identify EFI boot loaders. Note that a single case (either L"*.efi" or
// L"*.EFI") is fine for most systems; but Gigabyte's buggy Hybrid EFI does a case-sensitive
if (AboutMenu.EntryCount == 0) {
AboutMenu.TitleImage = BuiltinIcon(BUILTIN_ICON_FUNC_ABOUT);
- AddMenuInfoLine(&AboutMenu, L"rEFInd Version 0.6.6");
+ AddMenuInfoLine(&AboutMenu, L"rEFInd Version 0.6.6.4");
AddMenuInfoLine(&AboutMenu, L"");
AddMenuInfoLine(&AboutMenu, L"Copyright (c) 2006-2010 Christoph Pfisterer");
AddMenuInfoLine(&AboutMenu, L"Copyright (c) 2012 Roderick W. Smith");
// code and shortcut letter. For Linux EFI stub loaders, also sets kernel options
// that will (with luck) work fairly automatically.
VOID SetLoaderDefaults(LOADER_ENTRY *Entry, CHAR16 *LoaderPath, REFIT_VOLUME *Volume) {
- CHAR16 *FileName, *PathOnly, *IconNames = NULL, *NoExtension, *OSIconName = NULL, *Temp, *SubString;
+ CHAR16 *FileName, *PathOnly, *NoExtension, *OSIconName = NULL, *Temp, *SubString;
CHAR16 ShortcutLetter = 0;
UINTN i = 0, Length;
// locate a custom icon for the loader
// Anything found here takes precedence over the "hints" in the OSIconName variable
- while ((Temp = FindCommaDelimited(ICON_EXTENSIONS, i++)) != NULL) {
- MergeStrings(&IconNames, NoExtension, L',');
- MergeStrings(&IconNames, Temp, L'.');
- MyFreePool(Temp);
- }
if (!Entry->me.Image)
- Entry->me.Image = LoadIcns(Volume->RootDir, IconNames, 128);
+ Entry->me.Image = egFindIcon(NoExtension, 128);
if (!Entry->me.Image)
Entry->me.Image = Volume->VolIconImage;
- MyFreePool(IconNames);
// Begin creating icon "hints" by using last part of directory path leading
// to the loader
struct LOADER_LIST *LoaderList = NULL, *NewLoader;
BOOLEAN FoundFallbackDuplicate = FALSE;
+// Print(L"Entering ScanLoaderDir(), scanning '%s' for pattern '%s'\n", Path, Pattern);
if ((!SelfDirPath || !Path || ((StriCmp(Path, SelfDirPath) == 0) && (Volume->DeviceHandle != SelfVolume->DeviceHandle)) ||
(StriCmp(Path, SelfDirPath) != 0)) &&
(ShouldScan(Volume, Path))) {
CheckError(Status, FileName);
} // if (Status != EFI_NOT_FOUND)
} // if not scanning our own directory
+// PauseForKey();
return FoundFallbackDuplicate;
} /* static VOID ScanLoaderDir() */
UINTN i, Length, VolNum;
BOOLEAN ScanFallbackLoader = TRUE;
+// Print(L"Entering ScanEfiFiles(), GlobalConfig.ScanAllLinux = %s\n", GlobalConfig.ScanAllLinux ? L"TRUE" : L"FALSE");
MatchPatterns = StrDuplicate(LOADER_MATCH_PATTERNS);
if (GlobalConfig.ScanAllLinux)
MergeStrings(&MatchPatterns, LINUX_MATCH_PATTERNS, L',');
+// Print(L"MatchPatterns = '%s'\n", MatchPatterns);
if ((Volume->RootDir != NULL) && (Volume->VolName != NULL)) {
// check for Mac OS X boot loader
}
} // static VOID MoveSelection(VOID)
-// Display an icon at the specified location. Uses the image specified by
+// Display a 48x48 icon at the specified location. Uses the image specified by
// ExternalFilename if it's available, or BuiltInImage if it's not. The
// Y position is specified as the center value, and so is adjusted by half
// the icon's height. The X position is set along the icon's left
static VOID PaintIcon(IN EG_EMBEDDED_IMAGE *BuiltInIcon, IN CHAR16 *ExternalFilename, UINTN PosX, UINTN PosY, UINTN Alignment) {
EG_IMAGE *Icon = NULL;
- if (FileExists(SelfDir, ExternalFilename))
- Icon = egLoadIcon(SelfDir, ExternalFilename, 48);
+ Icon = egFindIcon(ExternalFilename, 48);
if (Icon == NULL)
Icon = egPrepareEmbeddedImage(BuiltInIcon, TRUE);
if (Icon != NULL) {
PosX -= Icon->Width;
egDrawImageWithTransparency(Icon, NULL, PosX, PosY - (Icon->Height / 2), Icon->Width, Icon->Height);
}
-} // static VOID PaintIcon()
+} // static VOID ()
inline UINTN ComputeRow0PosY(VOID) {
return ((UGAHeight / 2) - ROW0_TILESIZE / 2);
// Display (or erase) the arrow icons to the left and right of an icon's row,
// as appropriate.
static VOID PaintArrows(SCROLL_STATE *State, UINTN PosX, UINTN PosY, UINTN row0Loaders) {
- CHAR16 FileName[256];
EG_IMAGE *TempImage;
UINTN Width, Height, RightX, AdjPosY;
// of the surrounding row; PaintIcon() adjusts this back up by half the
// icon's height to properly center it.
if ((State->FirstVisible > 0) && (!(GlobalConfig.HideUIFlags & HIDEUI_FLAG_ARROWS))) {
- SPrint(FileName, 255, L"%s\\arrow_left.icns", GlobalConfig.IconsDir ? GlobalConfig.IconsDir : DEFAULT_ICONS_DIR);
- PaintIcon(&egemb_arrow_left, FileName, PosX, PosY, ALIGN_RIGHT);
+ PaintIcon(&egemb_arrow_left, L"arrow_left", PosX, PosY, ALIGN_RIGHT);
} else {
TempImage = egCropImage(GlobalConfig.ScreenBackground, PosX - Width, AdjPosY, Width, Height);
BltImage(TempImage, PosX - Width, AdjPosY);
} // if/else
if ((State->LastVisible < (row0Loaders - 1)) && (!(GlobalConfig.HideUIFlags & HIDEUI_FLAG_ARROWS))) {
- SPrint(FileName, 255, L"%s\\arrow_right.icns", GlobalConfig.IconsDir ? GlobalConfig.IconsDir : DEFAULT_ICONS_DIR);
- PaintIcon(&egemb_arrow_right, FileName, RightX, PosY, ALIGN_LEFT);
+ PaintIcon(&egemb_arrow_right, L"arrow_right", RightX, PosY, ALIGN_LEFT);
} else {
TempImage = egCropImage(GlobalConfig.ScreenBackground, RightX, AdjPosY, Width, Height);
BltImage(TempImage, RightX, AdjPosY);