Ken Thomases : winemenubuilder: On Mac OS X, keep multiple icon sizes.
Alexandre Julliard
julliard at winehq.org
Thu Jan 6 12:33:51 CST 2011
Module: wine
Branch: master
Commit: 53ba89c9673faead03a938166be7e05f98b4ef36
URL: http://source.winehq.org/git/wine.git/?a=commit;h=53ba89c9673faead03a938166be7e05f98b4ef36
Author: Ken Thomases <ken at codeweavers.com>
Date: Wed Jan 5 04:57:18 2011 -0600
winemenubuilder: On Mac OS X, keep multiple icon sizes.
ICNS files can store multiple sizes, like ICOs.
---
programs/winemenubuilder/winemenubuilder.c | 120 +++++++++++++++++++++-------
1 files changed, 91 insertions(+), 29 deletions(-)
diff --git a/programs/winemenubuilder/winemenubuilder.c b/programs/winemenubuilder/winemenubuilder.c
index d88dac1..dfb2441 100644
--- a/programs/winemenubuilder/winemenubuilder.c
+++ b/programs/winemenubuilder/winemenubuilder.c
@@ -815,10 +815,35 @@ static HRESULT open_icon(LPCWSTR filename, int index, BOOL bWait, IStream **ppSt
}
#ifdef __APPLE__
-static HRESULT platform_write_icon(IStream *icoStream, int exeIndex,
- int bestIndex, LPCWSTR icoPathW,
+#define ICNS_SLOTS 6
+
+static inline int size_to_slot(int size)
+{
+ switch (size)
+ {
+ case 16: return 0;
+ case 32: return 1;
+ case 48: return 2;
+ case 128: return 3;
+ case 256: return 4;
+ case 512: return 5;
+ }
+
+ return -1;
+}
+
+static HRESULT platform_write_icon(IStream *icoStream, int exeIndex, LPCWSTR icoPathW,
const char *destFilename, char **nativeIdentifier)
{
+ ICONDIRENTRY *iconDirEntries = NULL;
+ int numEntries;
+ struct {
+ int index;
+ int maxPixels;
+ int maxBits;
+ } best[ICNS_SLOTS];
+ int indexes[ICNS_SLOTS];
+ int i;
GUID guid;
WCHAR *guidStrW = NULL;
char *guidStrA = NULL;
@@ -826,6 +851,42 @@ static HRESULT platform_write_icon(IStream *icoStream, int exeIndex,
LARGE_INTEGER zero;
HRESULT hr;
+ hr = read_ico_direntries(icoStream, &iconDirEntries, &numEntries);
+ if (FAILED(hr))
+ goto end;
+ for (i = 0; i < ICNS_SLOTS; i++)
+ {
+ best[i].index = -1;
+ best[i].maxPixels = 0;
+ best[i].maxBits = 0;
+ }
+ for (i = 0; i < numEntries; i++)
+ {
+ int slot;
+
+ WINE_TRACE("[%d]: %d x %d @ %d\n", i, iconDirEntries[i].bWidth,
+ iconDirEntries[i].bHeight, iconDirEntries[i].wBitCount);
+ slot = size_to_slot(iconDirEntries[i].bWidth);
+ if (slot < 0)
+ continue;
+ if (iconDirEntries[i].wBitCount >= best[slot].maxBits &&
+ (iconDirEntries[i].bHeight * iconDirEntries[i].bWidth) >= best[slot].maxPixels)
+ {
+ best[slot].index = i;
+ best[slot].maxPixels = iconDirEntries[i].bHeight * iconDirEntries[i].bWidth;
+ best[slot].maxBits = iconDirEntries[i].wBitCount;
+ }
+ }
+ numEntries = 0;
+ for (i = 0; i < ICNS_SLOTS; i++)
+ {
+ if (best[i].index >= 0)
+ {
+ indexes[numEntries] = best[i].index;
+ numEntries++;
+ }
+ }
+
hr = CoCreateGuid(&guid);
if (FAILED(hr))
{
@@ -859,7 +920,7 @@ static HRESULT platform_write_icon(IStream *icoStream, int exeIndex,
WINE_WARN("seeking icon stream failed, error 0x%08X\n", hr);
goto end;
}
- hr = convert_to_native_icon(icoStream, &bestIndex, 1, &CLSID_WICIcnsEncoder,
+ hr = convert_to_native_icon(icoStream, indexes, numEntries, &CLSID_WICIcnsEncoder,
icnsPath, icoPathW);
if (FAILED(hr))
{
@@ -869,6 +930,7 @@ static HRESULT platform_write_icon(IStream *icoStream, int exeIndex,
}
end:
+ HeapFree(GetProcessHeap(), 0, iconDirEntries);
CoTaskMemFree(guidStrW);
HeapFree(GetProcessHeap(), 0, guidStrA);
if (SUCCEEDED(hr))
@@ -878,10 +940,15 @@ end:
return hr;
}
#else
-static HRESULT platform_write_icon(IStream *icoStream, int exeIndex,
- int bestIndex, LPCWSTR icoPathW,
+static HRESULT platform_write_icon(IStream *icoStream, int exeIndex, LPCWSTR icoPathW,
const char *destFilename, char **nativeIdentifier)
{
+ ICONDIRENTRY *iconDirEntries = NULL;
+ int numEntries;
+ int bestIndex = -1;
+ int maxPixels = 0;
+ int maxBits = 0;
+ int i;
char *icoPathA = NULL;
char *iconsDir = NULL;
char *pngPath = NULL;
@@ -890,6 +957,23 @@ static HRESULT platform_write_icon(IStream *icoStream, int exeIndex,
HRESULT hr = S_OK;
LARGE_INTEGER zero;
+ hr = read_ico_direntries(icoStream, &iconDirEntries, &numEntries);
+ if (FAILED(hr))
+ goto end;
+ for (i = 0; i < numEntries; i++)
+ {
+ WINE_TRACE("[%d]: %d x %d @ %d\n", i, iconDirEntries[i].bWidth,
+ iconDirEntries[i].bHeight, iconDirEntries[i].wBitCount);
+ if (iconDirEntries[i].wBitCount >= maxBits &&
+ (iconDirEntries[i].bHeight * iconDirEntries[i].bWidth) >= maxPixels)
+ {
+ bestIndex = i;
+ maxPixels = iconDirEntries[i].bHeight * iconDirEntries[i].bWidth;
+ maxBits = iconDirEntries[i].wBitCount;
+ }
+ }
+ WINE_TRACE("Selected: %d\n", bestIndex);
+
icoPathA = wchars_to_utf8_chars(icoPathW);
if (icoPathA == NULL)
{
@@ -938,6 +1022,7 @@ static HRESULT platform_write_icon(IStream *icoStream, int exeIndex,
pngPath, icoPathW);
end:
+ HeapFree(GetProcessHeap(), 0, iconDirEntries);
HeapFree(GetProcessHeap(), 0, icoPathA);
HeapFree(GetProcessHeap(), 0, iconsDir);
HeapFree(GetProcessHeap(), 0, pngPath);
@@ -951,12 +1036,6 @@ static char *extract_icon(LPCWSTR icoPathW, int index, const char *destFilename,
IStream *stream = NULL;
HRESULT hr;
char *nativeIdentifier = NULL;
- ICONDIRENTRY *iconDirEntries = NULL;
- int numEntries;
- int bestIndex = -1;
- int maxPixels = 0;
- int maxBits = 0;
- int i;
WINE_TRACE("path=[%s] index=%d destFilename=[%s]\n", wine_dbgstr_w(icoPathW), index, wine_dbgstr_a(destFilename));
@@ -966,30 +1045,13 @@ static char *extract_icon(LPCWSTR icoPathW, int index, const char *destFilename,
WINE_WARN("opening icon %s index %d failed, hr=0x%08X\n", wine_dbgstr_w(icoPathW), index, hr);
goto end;
}
- hr = read_ico_direntries(stream, &iconDirEntries, &numEntries);
- if (FAILED(hr))
- goto end;
- for (i = 0; i < numEntries; i++)
- {
- WINE_TRACE("[%d]: %d x %d @ %d\n", i, iconDirEntries[i].bWidth,
- iconDirEntries[i].bHeight, iconDirEntries[i].wBitCount);
- if (iconDirEntries[i].wBitCount >= maxBits &&
- (iconDirEntries[i].bHeight * iconDirEntries[i].bWidth) >= maxPixels)
- {
- bestIndex = i;
- maxPixels = iconDirEntries[i].bHeight * iconDirEntries[i].bWidth;
- maxBits = iconDirEntries[i].wBitCount;
- }
- }
- WINE_TRACE("Selected: %d\n", bestIndex);
- hr = platform_write_icon(stream, index, bestIndex, icoPathW, destFilename, &nativeIdentifier);
+ hr = platform_write_icon(stream, index, icoPathW, destFilename, &nativeIdentifier);
if (FAILED(hr))
WINE_WARN("writing icon failed, error 0x%08X\n", hr);
end:
if (stream)
IStream_Release(stream);
- HeapFree(GetProcessHeap(), 0, iconDirEntries);
if (FAILED(hr))
{
HeapFree(GetProcessHeap(), 0, nativeIdentifier);
More information about the wine-cvs
mailing list