Damjan Jovanovic : winemenubuilder: Extract all icon sizes on freedesktop too.
Alexandre Julliard
julliard at winehq.org
Mon Jan 17 10:59:41 CST 2011
Module: wine
Branch: master
Commit: bf07eb926ed9fa3591d10cfa74711fc94c3e3ab5
URL: http://source.winehq.org/git/wine.git/?a=commit;h=bf07eb926ed9fa3591d10cfa74711fc94c3e3ab5
Author: Damjan Jovanovic <damjan.jov at gmail.com>
Date: Sat Jan 15 10:37:52 2011 +0200
winemenubuilder: Extract all icon sizes on freedesktop too.
---
programs/winemenubuilder/winemenubuilder.c | 113 ++++++++++++++++++++-------
1 files changed, 83 insertions(+), 30 deletions(-)
diff --git a/programs/winemenubuilder/winemenubuilder.c b/programs/winemenubuilder/winemenubuilder.c
index 56ff158..070a8c2 100644
--- a/programs/winemenubuilder/winemenubuilder.c
+++ b/programs/winemenubuilder/winemenubuilder.c
@@ -939,18 +939,34 @@ end:
return hr;
}
#else
+static void refresh_icon_cache(const char *iconsDir)
+{
+ /* The icon theme spec only requires the mtime on the "toplevel"
+ * directory (whatever that is) to be changed for a refresh,
+ * but on Gnome you have to create a file in that directory
+ * instead. Creating a file also works on KDE, XFCE and LXDE.
+ */
+ char *filename = heap_printf("%s/.wine-refresh-XXXXXX", iconsDir);
+ if (filename != NULL)
+ {
+ int fd = mkstemps(filename, 0);
+ if (fd >= 0)
+ {
+ close(fd);
+ unlink(filename);
+ }
+ HeapFree(GetProcessHeap(), 0, filename);
+ }
+}
+
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;
unsigned short crc;
char *p, *q;
HRESULT hr = S_OK;
@@ -959,19 +975,6 @@ static HRESULT platform_write_icon(IStream *icoStream, int exeIndex, LPCWSTR ico
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)
@@ -1000,31 +1003,81 @@ static HRESULT platform_write_icon(IStream *icoStream, int exeIndex, LPCWSTR ico
hr = E_OUTOFMEMORY;
goto end;
}
- iconsDir = heap_printf("%s/icons", xdg_data_dir);
+ iconsDir = heap_printf("%s/icons/hicolor", xdg_data_dir);
if (iconsDir == NULL)
{
hr = E_OUTOFMEMORY;
goto end;
}
- create_directories(iconsDir);
- pngPath = heap_printf("%s/%s.png", iconsDir, *nativeIdentifier);
- if (pngPath == NULL)
+
+ for (i = 0; i < numEntries; i++)
{
- hr = E_OUTOFMEMORY;
- goto end;
+ int bestIndex;
+ int maxBits = -1;
+ int j;
+ BOOLEAN duplicate = FALSE;
+ int w, h;
+ char *iconDir = NULL;
+ char *pngPath = NULL;
+
+ WINE_TRACE("[%d]: %d x %d @ %d\n", i, iconDirEntries[i].bWidth,
+ iconDirEntries[i].bHeight, iconDirEntries[i].wBitCount);
+
+ for (j = 0; j < i; j++)
+ {
+ if (iconDirEntries[j].bWidth == iconDirEntries[i].bWidth &&
+ iconDirEntries[j].bHeight == iconDirEntries[i].bHeight)
+ {
+ duplicate = TRUE;
+ break;
+ }
+ }
+ if (duplicate)
+ continue;
+ for (j = i; j < numEntries; j++)
+ {
+ if (iconDirEntries[j].bWidth == iconDirEntries[i].bWidth &&
+ iconDirEntries[j].bHeight == iconDirEntries[i].bHeight &&
+ iconDirEntries[j].wBitCount >= maxBits)
+ {
+ bestIndex = j;
+ maxBits = iconDirEntries[j].wBitCount;
+ }
+ }
+ WINE_TRACE("Selected: %d\n", bestIndex);
+
+ w = iconDirEntries[bestIndex].bWidth ? iconDirEntries[bestIndex].bWidth : 256;
+ h = iconDirEntries[bestIndex].bHeight ? iconDirEntries[bestIndex].bHeight : 256;
+ iconDir = heap_printf("%s/%dx%d/apps", iconsDir, w, h);
+ if (iconDir == NULL)
+ {
+ hr = E_OUTOFMEMORY;
+ goto endloop;
+ }
+ create_directories(iconDir);
+ pngPath = heap_printf("%s/%s.png", iconDir, *nativeIdentifier);
+ if (pngPath == NULL)
+ {
+ hr = E_OUTOFMEMORY;
+ goto endloop;
+ }
+ zero.QuadPart = 0;
+ hr = IStream_Seek(icoStream, zero, STREAM_SEEK_SET, NULL);
+ if (FAILED(hr))
+ goto endloop;
+ hr = convert_to_native_icon(icoStream, &bestIndex, 1, &CLSID_WICPngEncoder,
+ pngPath, icoPathW);
+
+ endloop:
+ HeapFree(GetProcessHeap(), 0, iconDir);
+ HeapFree(GetProcessHeap(), 0, pngPath);
}
- zero.QuadPart = 0;
- hr = IStream_Seek(icoStream, zero, STREAM_SEEK_SET, NULL);
- if (FAILED(hr))
- goto end;
- hr = convert_to_native_icon(icoStream, &bestIndex, 1, &CLSID_WICPngEncoder,
- pngPath, icoPathW);
+ refresh_icon_cache(iconsDir);
end:
HeapFree(GetProcessHeap(), 0, iconDirEntries);
HeapFree(GetProcessHeap(), 0, icoPathA);
HeapFree(GetProcessHeap(), 0, iconsDir);
- HeapFree(GetProcessHeap(), 0, pngPath);
return hr;
}
#endif /* defined(__APPLE__) */
More information about the wine-cvs
mailing list