Damjan Jovanovic : winemenubuilder: Associate file open applications with freedesktop.

Alexandre Julliard julliard at winehq.org
Thu Jun 4 07:59:35 CDT 2009


Module: wine
Branch: master
Commit: 7287023647dcf76f8bae71e5945b0ec45937744f
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=7287023647dcf76f8bae71e5945b0ec45937744f

Author: Damjan Jovanovic <damjan.jov at gmail.com>
Date:   Wed Jun  3 18:33:28 2009 +0200

winemenubuilder: Associate file open applications with freedesktop.

---

 programs/winemenubuilder/winemenubuilder.c |  119 ++++++++++++++++++++++++++-
 1 files changed, 114 insertions(+), 5 deletions(-)

diff --git a/programs/winemenubuilder/winemenubuilder.c b/programs/winemenubuilder/winemenubuilder.c
index 462456a..bd9c30d 100644
--- a/programs/winemenubuilder/winemenubuilder.c
+++ b/programs/winemenubuilder/winemenubuilder.c
@@ -1514,6 +1514,21 @@ static BOOL freedesktop_mime_type_for_extension(struct list *native_mime_types,
     return ret;
 }
 
+static WCHAR* reg_get_valW(HKEY key, LPCWSTR subkey, LPCWSTR name)
+{
+    DWORD size;
+    if (RegGetValueW(key, subkey, name, RRF_RT_REG_SZ, NULL, NULL, &size) == ERROR_SUCCESS)
+    {
+        WCHAR *ret = HeapAlloc(GetProcessHeap(), 0, size);
+        if (ret)
+        {
+            if (RegGetValueW(key, subkey, name, RRF_RT_REG_SZ, NULL, ret, &size) == ERROR_SUCCESS)
+                return ret;
+        }
+    }
+    return NULL;
+}
+
 static BOOL write_freedesktop_mime_type_entry(const char *packages_dir, const char *dot_extension,
                                               const char *mime_type, const char *comment)
 {
@@ -1563,6 +1578,35 @@ static BOOL is_extension_blacklisted(LPCWSTR extension)
     return FALSE;
 }
 
+static BOOL write_freedesktop_association_entry(const char *desktopPath, const char *dot_extension,
+                                                const char *friendlyAppName, const char *mimeType,
+                                                const char *progId)
+{
+    BOOL ret = FALSE;
+    FILE *desktop;
+
+    WINE_TRACE("writing association for file type %s, friendlyAppName=%s, MIME type %s, progID=%s, to file %s\n",
+               wine_dbgstr_a(dot_extension), wine_dbgstr_a(friendlyAppName), wine_dbgstr_a(mimeType),
+               wine_dbgstr_a(progId), wine_dbgstr_a(desktopPath));
+
+    desktop = fopen(desktopPath, "w");
+    if (desktop)
+    {
+        fprintf(desktop, "[Desktop Entry]\n");
+        fprintf(desktop, "Type=Application\n");
+        fprintf(desktop, "Name=%s\n", friendlyAppName);
+        fprintf(desktop, "MimeType=%s\n", mimeType);
+        fprintf(desktop, "Exec=wine start /ProgIDOpen %s %%f\n", progId);
+        fprintf(desktop, "NoDisplay=true\n");
+        fprintf(desktop, "StartupNotify=true\n");
+        ret = TRUE;
+        fclose(desktop);
+    }
+    else
+        WINE_ERR("error writing association file %s\n", wine_dbgstr_a(desktopPath));
+    return ret;
+}
+
 static BOOL generate_associations(const char *xdg_data_home, const char *packages_dir, const char *applications_dir)
 {
     struct list *nativeMimeTypes = NULL;
@@ -1603,6 +1647,10 @@ static BOOL generate_associations(const char *xdg_data_home, const char *package
             char *friendlyDocNameA = NULL;
             WCHAR *contentTypeW = NULL;
             char *mimeTypeA = NULL;
+            WCHAR *friendlyAppNameW = NULL;
+            char *friendlyAppNameA = NULL;
+            WCHAR *progIdW = NULL;
+            char *progIdA = NULL;
 
             extensionA = wchars_to_utf8_chars(extensionW);
             if (extensionA == NULL)
@@ -1611,11 +1659,6 @@ static BOOL generate_associations(const char *xdg_data_home, const char *package
                 goto end;
             }
 
-            commandW = assoc_query(ASSOCSTR_COMMAND, extensionW, NULL);
-            if (commandW == NULL)
-                /* no command -> unusable extension */
-                goto end;
-
             friendlyDocNameW = assoc_query(ASSOCSTR_FRIENDLYDOCNAME, extensionW, NULL);
             if (friendlyDocNameW)
             {
@@ -1651,6 +1694,56 @@ static BOOL generate_associations(const char *xdg_data_home, const char *package
                 }
             }
 
+            commandW = assoc_query(ASSOCSTR_COMMAND, extensionW, NULL);
+            if (commandW == NULL)
+                /* no command => no application is associated */
+                goto end;
+
+            friendlyAppNameW = assoc_query(ASSOCSTR_FRIENDLYAPPNAME, extensionW, NULL);
+            if (friendlyAppNameW)
+            {
+                friendlyAppNameA = wchars_to_utf8_chars(friendlyAppNameW);
+                if (friendlyAppNameA == NULL)
+                {
+                    WINE_ERR("out of memory\n");
+                    goto end;
+                }
+            }
+            else
+            {
+                friendlyAppNameA = heap_printf("A Wine application");
+                if (friendlyAppNameA == NULL)
+                {
+                    WINE_ERR("out of memory\n");
+                    goto end;
+                }
+            }
+
+            progIdW = reg_get_valW(HKEY_CLASSES_ROOT, extensionW, NULL);
+            if (progIdW)
+            {
+                progIdA = wchars_to_utf8_chars(progIdW);
+                if (progIdA == NULL)
+                {
+                    WINE_ERR("out of memory\n");
+                    goto end;
+                }
+            }
+            else
+                goto end; /* no progID => not a file type association */
+
+            {
+                char *desktopPath = heap_printf("%s/wine-extension-%s.desktop", applications_dir, &extensionA[1]);
+                if (desktopPath)
+                {
+                    if (write_freedesktop_association_entry(desktopPath, extensionA, friendlyAppNameA, mimeTypeA, progIdA))
+                    {
+                        hasChanged = TRUE;
+                    }
+                    HeapFree(GetProcessHeap(), 0, desktopPath);
+                }
+            }
+
         end:
             HeapFree(GetProcessHeap(), 0, extensionA);
             HeapFree(GetProcessHeap(), 0, commandW);
@@ -1658,6 +1751,10 @@ static BOOL generate_associations(const char *xdg_data_home, const char *package
             HeapFree(GetProcessHeap(), 0, friendlyDocNameA);
             HeapFree(GetProcessHeap(), 0, contentTypeW);
             HeapFree(GetProcessHeap(), 0, mimeTypeA);
+            HeapFree(GetProcessHeap(), 0, friendlyAppNameW);
+            HeapFree(GetProcessHeap(), 0, friendlyAppNameA);
+            HeapFree(GetProcessHeap(), 0, progIdW);
+            HeapFree(GetProcessHeap(), 0, progIdA);
         }
         HeapFree(GetProcessHeap(), 0, extensionW);
         if (ret != ERROR_SUCCESS)
@@ -2148,6 +2245,18 @@ static void RefreshFileTypeAssociations(void)
             WINE_ERR("out of memory\n");
             goto end;
         }
+
+        command = heap_printf("update-desktop-database %s/applications", xdg_data_dir);
+        if (command)
+        {
+            system(command);
+            HeapFree(GetProcessHeap(), 0, command);
+        }
+        else
+        {
+            WINE_ERR("out of memory\n");
+            goto end;
+        }
     }
 
 end:




More information about the wine-cvs mailing list