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