]> code.delx.au - refind/commitdiff
Refinements to PNG support.
authorsrs5694 <srs5694@users.sourceforge.net>
Tue, 15 Jan 2013 07:20:58 +0000 (02:20 -0500)
committersrs5694 <srs5694@users.sourceforge.net>
Tue, 15 Jan 2013 07:20:58 +0000 (02:20 -0500)
docs/refind/configfile.html
docs/refind/themes.html
refind.conf-sample
refind/icns.c
refind/lib.c
refind/lib.h
refind/main.c

index ae5bc7c8dc309718523dad1db96ae22d657dd240..077ad326773aea2f122c55213448e6cf5268a116 100644 (file)
@@ -132,11 +132,11 @@ href="mailto:rodsmith@rodsbooks.com">rodsmith@rodsbooks.com</a></p>
 
 <ul>
 
-<li>You can name an icon file after your boot loader, but with an extension of <tt>.icns</tt>. For instance, if you're using <tt class="variable">loader</tt><tt>.efi</tt>, you would name the icon file <tt class="variable">loader</tt><tt>.icns</tt>. (If you use the <tt>scan_all_linux_kernels</tt> option, you can give an icon for a Linux kernel without a <tt>.efi</tt> extension a name based on the kernel name but with a <tt>.icns</tt> extension&mdash;for instance, <tt>bzImage-3.6.9.icns</tt> will serve as the icon for the <tt>bzImage-3.6.9</tt> kernel.) These icon files should be 128x128 images in <a href="http://en.wikipedia.org/wiki/Apple_Icon_Image_format">Apple's ICNS format.</a> You can create such files easily in OS X or convert PNG files to ICNS format with <a href="http://icns.sourceforge.net/">libicns.</a></li>
+<li>You can name an icon file after your boot loader, but with an extension of <tt>.icns</tt> or <tt>.png</tt> for ICNS-format and PNG-format icons, respectively. For instance, if you're using <tt class="variable">loader</tt><tt>.efi</tt>, you would name the icon file <tt class="variable">loader</tt><tt>.icns</tt>. (If you use the <tt>scan_all_linux_kernels</tt> option, you can give an icon for a Linux kernel without a <tt>.efi</tt> extension a name based on the kernel name but with a <tt>.icns</tt> or <tt>.png</tt> extension&mdash;for instance, <tt>bzImage-3.6.9.png</tt> will serve as the icon for the <tt>bzImage-3.6.9</tt> kernel.) These icon files should be 128x128 images in <a href="http://en.wikipedia.org/wiki/Apple_Icon_Image_format">Apple's ICNS</a> or <a href="http://en.wikipedia.org/wiki/Portable_Network_Graphics">Portable Network Graphics (PNG)</a> format, depending on the filename extension.</li>
 
-<li>If you're booting OS X from its standard boot loader, or if you place a boot loader file for any OS in the root directory of a partition, you can create a file called <tt>.VolumeIcon.icns</tt> that holds an icon file. OS X uses this file for its volume icons, so rEFInd picks up these icons automatically, provided they include 128x128 bitmaps.</li>
+<li>If you're booting OS X from its standard boot loader, or if you place a boot loader file for any OS in the root directory of a partition, you can create a file called <tt>.VolumeIcon.icns</tt> or <tt>.VolumeIcon.png</tt> that holds an icon file. OS X uses the <tt>.VolumeIcon.icns</tt> file for its volume icons, so rEFInd picks up these icons automatically, provided they include 128x128 bitmaps.</li>
 
-<li>You can place a boot loader in a directory with a name that matches one of rEFInd's standard icons, which take names of the form <tt>os_<tt class="variable">name</tt>.icns</tt>. To use this icon, you would place the boot loader in the directory called <tt class="variable">name</tt>.</li>
+<li>You can place a boot loader in a directory with a name that matches one of rEFInd's standard icons, which take names of the form <tt>os_<tt class="variable">name</tt>.icns</tt> or <tt>os_<tt class="variable">name</tt>.png</tt>. To use such an icon, you would place the boot loader in the directory called <tt class="variable">name</tt>.</li>
 
 <li>You can give the filesystem from which the boot loader is loaded a name that matches the OS name component of the icon filename. For instance, if you call your boot filesystem <tt>CentOS</tt>, it matches the <tt>os_centos.icns</tt> icon. This match is performed on a word-by-word basis within the name, with "words" being delimited by spaces, dashes (<tt>-</tt>), and underscores (<tt>_</tt>). Thus, a volume called <tt>Debian-boot</tt> will match <tt>os_debian.icns</tt> or <tt>os_boot.icns</tt>.</li>
 
@@ -146,7 +146,7 @@ href="mailto:rodsmith@rodsbooks.com">rodsmith@rodsbooks.com</a></p>
 
 <p>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.</p>
 
-<p>In addition to the main OS tag icon, you can set the <i>badge</i> icon for a volume by creating a file called <tt>.VolumeBadge.icns</tt> 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 <tt>icons</tt> subdirectory (<tt>vol_external.icns</tt>, <tt>vol_internal.icns</tt>, and <tt>vol_optical.icns</tt>) with a completely transparent badge. The <tt>transparent.icns</tt> file in the rEFInd <tt>icons</tt> directory may be used for this purpose.</p>
+<p>In addition to the main OS tag icon, you can set the <i>badge</i> icon for a volume by creating a file called <tt>.VolumeBadge.icns</tt> or <tt>.VolumeBadge.png</tt> 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 <tt>icons</tt> subdirectory (<tt>vol_external.icns</tt>, <tt>vol_internal.icns</tt>, and <tt>vol_optical.icns</tt>) with a completely transparent badge. The <tt>transparent.icns</tt> file in the rEFInd <tt>icons</tt> directory may be used for this purpose.</p>
 
 <a name="adjusting">
 <h2>Adjusting the Global Configuration</h2>
index ea14a303672a490caaca287158645794ab1ac291..9a259e2d968e475261bb63e7370bb67630921649 100644 (file)
@@ -96,19 +96,19 @@ href="mailto:rodsmith@rodsbooks.com">rodsmith@rodsbooks.com</a></p>
 
 <ul>
 
-<li>You can create new icons, place them in a subdirectory of rEFInd's main directory, and tell the program to use the new icons by setting the <tt>icons_dir</tt> token in <tt>refind.conf</tt>. This will affect the appearance of the OS tags, the utility tags, and so on. The names of these icons should match those in the <tt>icons</tt> subdirectory, and are fairly self-explanatory. If an icon is missing from the directory specified by <tt>icons_dir</tt>, rEFInd falls back to the icon from the standard <tt>icons</tt> subdirectory; thus, you can replace just a subset of the standard icons. Be aware that rEFInd expects its icons to be in Apple's <a href="http://en.wikipedia.org/wiki/Icns">icon image format (ICNS).</a> You can generate such files easily in various Apple programs, or by using the <a href="http://icns.sourceforge.net/">libicns</a> library (and in particular its <tt>png2icns</tt> program) in Linux.</li>
+<li>You can create new icons, place them in a subdirectory of rEFInd's main directory, and tell the program to use the new icons by setting the <tt>icons_dir</tt> token in <tt>refind.conf</tt>. This will affect the appearance of the OS tags, the utility tags, and so on. The names of these icons should match those in the <tt>icons</tt> subdirectory, and are fairly self-explanatory. OS tags should be 128x128 pixels, while tags for 2nd-row utilities should be 48x48 pixels. If an icon is missing from the directory specified by <tt>icons_dir</tt>, rEFInd falls back to the icon from the standard <tt>icons</tt> subdirectory; thus, you can replace just a subset of the standard icons. rEFInd can use icons in either Apple's <a href="http://en.wikipedia.org/wiki/Apple_Icon_Image">icon image (ICNS)</a> or <a href="http://en.wikipedia.org/wiki/Portable_Network_Graphics">Portable Network Graphics (PNG)</a> format. PNG files are easier to generate on most platforms. You can generate ICNS files in various Apple programs or by using the <a href="http://icns.sourceforge.net/">libicns</a> library (and in particular its <tt>png2icns</tt> program) in Linux.</li>
 
 <li>You can do as above, but place your new icons in the default <tt>icons</tt> subdirectory. This method is discouraged because using the <tt>install.sh</tt> script to upgrade rEFInd will replace your customized icons.</li>
 
-<li>You can customize the appearance of an individual boot loader by placing an ICNS file in its directory with the same name as the boot loader but with a <tt>.icns</tt> extension. For instance, if your boot loader program is <tt>elilo.efi</tt>, you can create a custom icon by naming it <tt>elilo.icns</tt>.</li>
+<li>You can customize the appearance of an individual boot loader by placing an ICNS or PNG file in its directory with the same name as the boot loader but with a <tt>.icns</tt> or <tt>.png</tt> extension. For instance, if your boot loader program is <tt>elilo.efi</tt>, you can create a custom icon by naming it <tt>elilo.png</tt>.</li>
 
-<li>You can provide an icon for boot loaders stored in the root directory of a filesystem by placing a file called <tt>.VolumeIcon.icns</tt> in that volume's root.</li>
+<li>You can provide an icon for boot loaders stored in the root directory of a filesystem by placing a file called <tt>.VolumeIcon.icns</tt> or <tt>.VolumeIcon.png</tt> in that volume's root.</li>
 
-<li>You can set a custom badge (the small icon that identifies the disk type) by creating a file called <tt>.VolumeBadge.icns</tt> in that volume's root. This setting applies to all the boot loaders found on this volume, even if they're in subdirectories.</li>
+<li>You can set a custom badge (the small icon that identifies the disk type) by creating a file called <tt>.VolumeBadge.icns</tt> or <tt>.VolumeBadge.png</tt> in that volume's root. This setting applies to all the boot loaders found on this volume, even if they're in subdirectories.</li>
 
-<li>You can adjust the selection background (used to highlight a selected icon) by creating new icons in Microsoft's <a href="http://en.wikipedia.org/wiki/BMP_file_format">BMP format</a>. You should create both 144x144 and 64x64 images and tell rEFInd about them by using the <tt>selection_big</tt> and <tt>selection_small</tt> tokens, respectively, in <tt>refind.conf</tt>.</li>
+<li>You can adjust the selection background (used to highlight a selected icon) by creating new icons in PNG or in Microsoft's <a href="http://en.wikipedia.org/wiki/BMP_file_format">BMP format</a>. You should create both 144x144 and 64x64 images and tell rEFInd about them by using the <tt>selection_big</tt> and <tt>selection_small</tt> tokens, respectively, in <tt>refind.conf</tt>. If you omit the large icon, rEFInd will stretch the small icon to fit the larger space; if you omit the small icon, rEFInd will use the default small icon. Because BMP doesn't support transparency (alpha channels), you must use the PNG format if you want your selection background to show the underlying image beneath it. (You can create the illusion of transparency on a solid background by matching the colors, though.)</li>
 
-<li>You can create a new background image and logo by placing a BMP file in rEFInd's main directory and passing its filename to rEFInd with the <tt>banner</tt> option in <tt>refind.conf</tt>. If the image is smaller than the screen, the color in the top-left corner of the image will be used for the rest of the display.</li>
+<li>You can create a new background image and logo by placing a PNG or BMP file in rEFInd's main directory and passing its filename to rEFInd with the <tt>banner</tt> option in <tt>refind.conf</tt>. If the image is smaller than the screen, the color in the top-left corner of the image will be used for the rest of the display.</li>
 
 </ul>
 
index 657e69d67e0f689bde0ee198c46bcaf69e0de7cb..5d0039918849b614a20eb905825fc1d2ddd5d461 100644 (file)
@@ -39,9 +39,10 @@ timeout 20
 # path is relative to the directory where refind.efi is located. The color
 # in the top left corner of the image is used as the background color
 # for the menu screens. Currently uncompressed BMP images with color
-# depths of 24, 8, 4 or 1 bits are supported.
+# depths of 24, 8, 4 or 1 bits are supported, as well as PNG images.
 #
 #banner hostname.bmp
+#banner mybanner.png
 
 # 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
@@ -50,7 +51,9 @@ timeout 20
 # the built-in default will be used for the small icons.
 #
 # Like the banner option above, these options take a filename of an
-# uncompressed BMP image file with a color depth of 24, 8, 4, or 1 bits.
+# uncompressed BMP image file with a color depth of 24, 8, 4, or 1 bits,
+# or a PNG image. The PNG format is required if you need transparency
+# support (to let you "see through" to a full-screen banner).
 #
 #selection_big   selection-big.bmp
 #selection_small selection-small.bmp
index 5cd9fcd9d10549783e20e3bc086f7cfa2ec9e9a5..0f55c8d207967ab7c4efdd3e5fbb2b07f846a3ae 100644 (file)
@@ -140,16 +140,22 @@ EG_IMAGE * LoadOSIcon(IN CHAR16 *OSIconName OPTIONAL, IN CHAR16 *FallbackIconNam
 } /* EG_IMAGE * LoadOSIcon() */
 
 
-//
-// Load an image from a .icns file
-//
-
-EG_IMAGE * LoadIcns(IN EFI_FILE_HANDLE BaseDir, IN CHAR16 *FileName, IN UINTN PixelSize)
-{
-    if (GlobalConfig.TextOnly)      // skip loading if it's not used anyway
-        return NULL;
-    return egLoadIcon(BaseDir, FileName, PixelSize);
-}
+// Load an image from a .icns or .png file. FileNames contains a comma-delimited
+// list of potential filanems; the function tries each in turn until it finds
+// a loadable icon. If no file has a valid icon, it returns NULL.
+EG_IMAGE * LoadIcns(IN EFI_FILE_HANDLE BaseDir, IN CHAR16 *FileNames, IN UINTN PixelSize) {
+   CHAR16   *FileName;
+   EG_IMAGE *Image = NULL;
+   UINTN    Index = 0;
+
+   if (GlobalConfig.TextOnly)      // skip loading if it's not used anyway
+      return NULL;
+
+   while (((FileName = FindCommaDelimited(FileNames, Index++)) != NULL) && (Image == NULL)) {
+      Image = egLoadIcon(BaseDir, FileName, PixelSize);
+   }
+   return Image;
+} // EG_IMAGE * LoadIcns()
 
 static EG_PIXEL BlackPixel  = { 0x00, 0x00, 0x00, 0 };
 //static EG_PIXEL YellowPixel = { 0x00, 0xff, 0xff, 0 };
index b4d93a8cc03de8ffd72a74f7f429a31758e7fa7d..db3a6dde04b1684b65d97506765b260226d0209d 100644 (file)
@@ -93,8 +93,8 @@ UINTN            VolumesCount = 0;
 #define SAMPLE_SIZE 69632 /* 68 KiB -- ReiserFS superblock begins at 64 KiB */
 
 // Default names for volume badges (mini-icon to define disk type) and icons
-#define VOLUME_BADGE_NAME L".VolumeBadge.icns"
-#define VOLUME_ICON_NAME L".VolumeIcon.icns"
+#define VOLUME_BADGE_NAMES L".VolumeBadge.icns,.VolumeBadge.png"
+#define VOLUME_ICON_NAMES L".VolumeIcon.icns,.VolumeIcon.png"
 
 // functions
 
@@ -849,11 +849,10 @@ VOID ScanVolume(REFIT_VOLUME *Volume)
     Volume->VolName = GetVolumeName(Volume);
 
     // get custom volume icon if present
-    if (FileExists(Volume->RootDir, VOLUME_BADGE_NAME))
-        Volume->VolBadgeImage = LoadIcns(Volume->RootDir, VOLUME_BADGE_NAME, 32);
-    if (FileExists(Volume->RootDir, VOLUME_ICON_NAME)) {
-       Volume->VolIconImage = LoadIcns(Volume->RootDir, VOLUME_ICON_NAME, 128);
-    }
+    if (!Volume->VolBadgeImage)
+       Volume->VolBadgeImage = LoadIcns(Volume->RootDir, VOLUME_BADGE_NAMES, 32);
+    if (!Volume->VolIconImage)
+       Volume->VolIconImage = LoadIcns(Volume->RootDir, VOLUME_ICON_NAMES, 128);
 } // ScanVolume()
 
 static VOID ScanExtendedPartition(REFIT_VOLUME *WholeDiskVolume, MBR_PARTITION_INFO *MbrEntry)
@@ -1320,20 +1319,37 @@ CHAR16 * Basename(IN CHAR16 *Path)
     return FileName;
 }
 
+// Remove the .efi extension from FileName -- for instance, if FileName is
+// "fred.efi", returns "fred". If the filename contains no .efi extension,
+// returns a copy of the original input.
+CHAR16 * StripEfiExtension(CHAR16 *FileName) {
+   UINTN  Length;
+   CHAR16 *Copy = NULL;
+
+   if ((FileName != NULL) && ((Copy = StrDuplicate(FileName)) != NULL)) {
+      Length = StrLen(Copy);
+      // Note: Do StriCmp() twice to work around Gigabyte Hybrid EFI case-sensitivity bug....
+      if ((Length >= 4) && ((StriCmp(&Copy[Length - 4], L".efi") == 0) || (StriCmp(&Copy[Length - 4], L".EFI") == 0))) {
+         Copy[Length - 4] = 0;
+      } // if
+   } // if
+   return Copy;
+} // CHAR16 * StripExtension()
+
 // Replaces a filename extension of ".efi" with the specified string
 // (Extension). If the input Path doesn't end in ".efi", Extension
 // is added to the existing filename.
-VOID ReplaceEfiExtension(IN OUT CHAR16 *Path, IN CHAR16 *Extension)
-{
-    UINTN PathLen;
-
-    PathLen = StrLen(Path);
-    // Note: Do StriCmp() twice to work around Gigabyte Hybrid EFI case-sensitivity bug....
-    if ((PathLen >= 4) && ((StriCmp(&Path[PathLen - 4], L".efi") == 0) || (StriCmp(&Path[PathLen - 4], L".EFI") == 0))) {
-       Path[PathLen - 4] = 0;
-    } // if
-    StrCat(Path, Extension);
-} // VOID ReplaceEfiExtension()
+// VOID ReplaceEfiExtension(IN OUT CHAR16 *Path, IN CHAR16 *Extension)
+// {
+//     UINTN PathLen;
+// 
+//     PathLen = StrLen(Path);
+//     // Note: Do StriCmp() twice to work around Gigabyte Hybrid EFI case-sensitivity bug....
+//     if ((PathLen >= 4) && ((StriCmp(&Path[PathLen - 4], L".efi") == 0) || (StriCmp(&Path[PathLen - 4], L".EFI") == 0))) {
+//        Path[PathLen - 4] = 0;
+//     } // if
+//     StrCat(Path, Extension);
+// } // VOID ReplaceEfiExtension()
 
 //
 // memory string search
index 369d3a8d6459931b8ac1082793735286da016733..49786ca956983441f4763689348d92cd6d12cce4 100644 (file)
@@ -101,7 +101,8 @@ BOOLEAN DirIterNext(IN OUT REFIT_DIR_ITER *DirIter, IN UINTN FilterMode, IN CHAR
 EFI_STATUS DirIterClose(IN OUT REFIT_DIR_ITER *DirIter);
 
 CHAR16 * Basename(IN CHAR16 *Path);
-VOID ReplaceEfiExtension(IN OUT CHAR16 *Path, IN CHAR16 *Extension);
+CHAR16 * StripEfiExtension(CHAR16 *FileName);
+//VOID ReplaceEfiExtension(IN OUT CHAR16 *Path, IN CHAR16 *Extension);
 
 INTN FindMem(IN VOID *Buffer, IN UINTN BufferLength, IN VOID *SearchString, IN UINTN SearchStringLength);
 VOID ReinitVolumes(VOID);
index 6459939d9c47e3dbefe88b7d0f0cef43805f72f8..e10bab3a326c586383065eb63d9c41ede2ead236 100644 (file)
@@ -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.4");
+        AddMenuInfoLine(&AboutMenu, L"rEFInd Version 0.6.4.5");
         AddMenuInfoLine(&AboutMenu, L"");
         AddMenuInfoLine(&AboutMenu, L"Copyright (c) 2006-2010 Christoph Pfisterer");
         AddMenuInfoLine(&AboutMenu, L"Copyright (c) 2012 Roderick W. Smith");
@@ -711,23 +711,25 @@ static CHAR16 * GetMainLinuxOptions(IN CHAR16 * LoaderPath, IN REFIT_VOLUME *Vol
 // 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      IconFileName[256];
-   CHAR16      *FileName, *PathOnly, *OSIconName = NULL, *Temp, *SubString;
+   CHAR16      *FileName, *PathOnly, *IconNames = NULL, *NoExtension, *OSIconName = NULL, *Temp, *SubString;
    CHAR16      ShortcutLetter = 0;
-   UINTN       i, Length;
+   UINTN       i = 0, Length;
 
    FileName = Basename(LoaderPath);
    PathOnly = FindPath(LoaderPath);
+   NoExtension = StripEfiExtension(FileName);
 
    // locate a custom icon for the loader
    // Anything found here takes precedence over the "hints" in the OSIconName variable
-   StrCpy(IconFileName, LoaderPath);
-   ReplaceEfiExtension(IconFileName, L".icns");
-   if (FileExists(Volume->RootDir, IconFileName)) {
-      Entry->me.Image = LoadIcns(Volume->RootDir, IconFileName, 128);
-   } else if ((StrLen(PathOnly) == 0) && (Volume->VolIconImage != NULL)) {
+   while ((Temp = FindCommaDelimited(ICON_EXTENSIONS, i++)) != NULL) {
+      MergeStrings(&IconNames, NoExtension, L',');
+      MergeStrings(&IconNames, Temp, L'.');
+      MyFreePool(Temp);
+   }
+   Entry->me.Image = LoadIcns(Volume->RootDir, IconNames, 128);
+   if (!Entry->me.Image)
       Entry->me.Image = Volume->VolIconImage;
-   } // icon matched to loader or volume
+   MyFreePool(IconNames);
 
    // Begin creating icon "hints" by using last part of directory path leading
    // to the loader
@@ -953,6 +955,7 @@ static VOID ScanLoaderDir(IN REFIT_VOLUME *Volume, IN CHAR16 *Path, IN CHAR16 *P
           Extension = FindExtension(DirEntry->FileName);
           if (DirEntry->FileName[0] == '.' ||
               StriCmp(Extension, L".icns") == 0 ||
+              StriCmp(Extension, L".png") == 0 ||
               StriSubCmp(L"shell", DirEntry->FileName) ||
               IsIn(DirEntry->FileName, GlobalConfig.DontScanFiles))
                 continue;   // skip this