winemenubuilder: Generate icons for the fd.o "Open with" menu.
This commit is contained in:
parent
c3adb72820
commit
b5416b0292
|
@ -1814,12 +1814,14 @@ static HKEY open_associations_reg_key(void)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL has_association_changed(LPCWSTR extensionW, LPCSTR mimeType, LPCWSTR progId, LPCSTR appName, LPCWSTR docName)
|
static BOOL has_association_changed(LPCWSTR extensionW, LPCSTR mimeType, LPCWSTR progId,
|
||||||
|
LPCSTR appName, LPCWSTR docName, LPCSTR openWithIcon)
|
||||||
{
|
{
|
||||||
static const WCHAR ProgIDW[] = {'P','r','o','g','I','D',0};
|
static const WCHAR ProgIDW[] = {'P','r','o','g','I','D',0};
|
||||||
static const WCHAR DocNameW[] = {'D','o','c','N','a','m','e',0};
|
static const WCHAR DocNameW[] = {'D','o','c','N','a','m','e',0};
|
||||||
static const WCHAR MimeTypeW[] = {'M','i','m','e','T','y','p','e',0};
|
static const WCHAR MimeTypeW[] = {'M','i','m','e','T','y','p','e',0};
|
||||||
static const WCHAR AppNameW[] = {'A','p','p','N','a','m','e',0};
|
static const WCHAR AppNameW[] = {'A','p','p','N','a','m','e',0};
|
||||||
|
static const WCHAR OpenWithIconW[] = {'O','p','e','n','W','i','t','h','I','c','o','n',0};
|
||||||
HKEY assocKey;
|
HKEY assocKey;
|
||||||
BOOL ret;
|
BOOL ret;
|
||||||
|
|
||||||
|
@ -1850,6 +1852,13 @@ static BOOL has_association_changed(LPCWSTR extensionW, LPCSTR mimeType, LPCWSTR
|
||||||
ret = TRUE;
|
ret = TRUE;
|
||||||
HeapFree(GetProcessHeap(), 0, value);
|
HeapFree(GetProcessHeap(), 0, value);
|
||||||
|
|
||||||
|
valueA = reg_get_val_utf8(assocKey, extensionW, OpenWithIconW);
|
||||||
|
if ((openWithIcon && !valueA) ||
|
||||||
|
(!openWithIcon && valueA) ||
|
||||||
|
(openWithIcon && valueA && lstrcmpA(valueA, openWithIcon)))
|
||||||
|
ret = TRUE;
|
||||||
|
HeapFree(GetProcessHeap(), 0, valueA);
|
||||||
|
|
||||||
RegCloseKey(assocKey);
|
RegCloseKey(assocKey);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1860,18 +1869,21 @@ static BOOL has_association_changed(LPCWSTR extensionW, LPCSTR mimeType, LPCWSTR
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void update_association(LPCWSTR extension, LPCSTR mimeType, LPCWSTR progId, LPCSTR appName, LPCWSTR docName, LPCSTR desktopFile)
|
static void update_association(LPCWSTR extension, LPCSTR mimeType, LPCWSTR progId,
|
||||||
|
LPCSTR appName, LPCWSTR docName, LPCSTR desktopFile, LPCSTR openWithIcon)
|
||||||
{
|
{
|
||||||
static const WCHAR ProgIDW[] = {'P','r','o','g','I','D',0};
|
static const WCHAR ProgIDW[] = {'P','r','o','g','I','D',0};
|
||||||
static const WCHAR DocNameW[] = {'D','o','c','N','a','m','e',0};
|
static const WCHAR DocNameW[] = {'D','o','c','N','a','m','e',0};
|
||||||
static const WCHAR MimeTypeW[] = {'M','i','m','e','T','y','p','e',0};
|
static const WCHAR MimeTypeW[] = {'M','i','m','e','T','y','p','e',0};
|
||||||
static const WCHAR AppNameW[] = {'A','p','p','N','a','m','e',0};
|
static const WCHAR AppNameW[] = {'A','p','p','N','a','m','e',0};
|
||||||
static const WCHAR DesktopFileW[] = {'D','e','s','k','t','o','p','F','i','l','e',0};
|
static const WCHAR DesktopFileW[] = {'D','e','s','k','t','o','p','F','i','l','e',0};
|
||||||
|
static const WCHAR OpenWithIconW[] = {'O','p','e','n','W','i','t','h','I','c','o','n',0};
|
||||||
HKEY assocKey = NULL;
|
HKEY assocKey = NULL;
|
||||||
HKEY subkey = NULL;
|
HKEY subkey = NULL;
|
||||||
WCHAR *mimeTypeW = NULL;
|
WCHAR *mimeTypeW = NULL;
|
||||||
WCHAR *appNameW = NULL;
|
WCHAR *appNameW = NULL;
|
||||||
WCHAR *desktopFileW = NULL;
|
WCHAR *desktopFileW = NULL;
|
||||||
|
WCHAR *openWithIconW = NULL;
|
||||||
|
|
||||||
assocKey = open_associations_reg_key();
|
assocKey = open_associations_reg_key();
|
||||||
if (assocKey == NULL)
|
if (assocKey == NULL)
|
||||||
|
@ -1907,12 +1919,26 @@ static void update_association(LPCWSTR extension, LPCSTR mimeType, LPCWSTR progI
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (openWithIcon)
|
||||||
|
{
|
||||||
|
openWithIconW = utf8_chars_to_wchars(openWithIcon);
|
||||||
|
if (openWithIconW == NULL)
|
||||||
|
{
|
||||||
|
WINE_ERR("out of memory\n");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
RegSetValueExW(subkey, MimeTypeW, 0, REG_SZ, (const BYTE*) mimeTypeW, (lstrlenW(mimeTypeW) + 1) * sizeof(WCHAR));
|
RegSetValueExW(subkey, MimeTypeW, 0, REG_SZ, (const BYTE*) mimeTypeW, (lstrlenW(mimeTypeW) + 1) * sizeof(WCHAR));
|
||||||
RegSetValueExW(subkey, ProgIDW, 0, REG_SZ, (const BYTE*) progId, (lstrlenW(progId) + 1) * sizeof(WCHAR));
|
RegSetValueExW(subkey, ProgIDW, 0, REG_SZ, (const BYTE*) progId, (lstrlenW(progId) + 1) * sizeof(WCHAR));
|
||||||
RegSetValueExW(subkey, AppNameW, 0, REG_SZ, (const BYTE*) appNameW, (lstrlenW(appNameW) + 1) * sizeof(WCHAR));
|
RegSetValueExW(subkey, AppNameW, 0, REG_SZ, (const BYTE*) appNameW, (lstrlenW(appNameW) + 1) * sizeof(WCHAR));
|
||||||
if (docName)
|
if (docName)
|
||||||
RegSetValueExW(subkey, DocNameW, 0, REG_SZ, (const BYTE*) docName, (lstrlenW(docName) + 1) * sizeof(WCHAR));
|
RegSetValueExW(subkey, DocNameW, 0, REG_SZ, (const BYTE*) docName, (lstrlenW(docName) + 1) * sizeof(WCHAR));
|
||||||
RegSetValueExW(subkey, DesktopFileW, 0, REG_SZ, (const BYTE*) desktopFileW, (lstrlenW(desktopFileW) + 1) * sizeof(WCHAR));
|
RegSetValueExW(subkey, DesktopFileW, 0, REG_SZ, (const BYTE*) desktopFileW, (lstrlenW(desktopFileW) + 1) * sizeof(WCHAR));
|
||||||
|
if (openWithIcon)
|
||||||
|
RegSetValueExW(subkey, OpenWithIconW, 0, REG_SZ, (const BYTE*) openWithIconW, (lstrlenW(openWithIconW) + 1) * sizeof(WCHAR));
|
||||||
|
else
|
||||||
|
RegDeleteValueW(subkey, OpenWithIconW);
|
||||||
|
|
||||||
done:
|
done:
|
||||||
RegCloseKey(assocKey);
|
RegCloseKey(assocKey);
|
||||||
|
@ -1920,6 +1946,7 @@ done:
|
||||||
HeapFree(GetProcessHeap(), 0, mimeTypeW);
|
HeapFree(GetProcessHeap(), 0, mimeTypeW);
|
||||||
HeapFree(GetProcessHeap(), 0, appNameW);
|
HeapFree(GetProcessHeap(), 0, appNameW);
|
||||||
HeapFree(GetProcessHeap(), 0, desktopFileW);
|
HeapFree(GetProcessHeap(), 0, desktopFileW);
|
||||||
|
HeapFree(GetProcessHeap(), 0, openWithIconW);
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL cleanup_associations(void)
|
static BOOL cleanup_associations(void)
|
||||||
|
@ -2052,14 +2079,14 @@ static const char* get_special_mime_type(LPCWSTR extension)
|
||||||
|
|
||||||
static BOOL write_freedesktop_association_entry(const char *desktopPath, const char *dot_extension,
|
static BOOL write_freedesktop_association_entry(const char *desktopPath, const char *dot_extension,
|
||||||
const char *friendlyAppName, const char *mimeType,
|
const char *friendlyAppName, const char *mimeType,
|
||||||
const char *progId)
|
const char *progId, const char *openWithIcon)
|
||||||
{
|
{
|
||||||
BOOL ret = FALSE;
|
BOOL ret = FALSE;
|
||||||
FILE *desktop;
|
FILE *desktop;
|
||||||
|
|
||||||
WINE_TRACE("writing association for file type %s, friendlyAppName=%s, MIME type %s, progID=%s, to file %s\n",
|
WINE_TRACE("writing association for file type %s, friendlyAppName=%s, MIME type %s, progID=%s, icon=%s to file %s\n",
|
||||||
wine_dbgstr_a(dot_extension), wine_dbgstr_a(friendlyAppName), wine_dbgstr_a(mimeType),
|
wine_dbgstr_a(dot_extension), wine_dbgstr_a(friendlyAppName), wine_dbgstr_a(mimeType),
|
||||||
wine_dbgstr_a(progId), wine_dbgstr_a(desktopPath));
|
wine_dbgstr_a(progId), wine_dbgstr_a(openWithIcon), wine_dbgstr_a(desktopPath));
|
||||||
|
|
||||||
desktop = fopen(desktopPath, "w");
|
desktop = fopen(desktopPath, "w");
|
||||||
if (desktop)
|
if (desktop)
|
||||||
|
@ -2071,6 +2098,8 @@ static BOOL write_freedesktop_association_entry(const char *desktopPath, const c
|
||||||
fprintf(desktop, "Exec=wine start /ProgIDOpen %s %%f\n", progId);
|
fprintf(desktop, "Exec=wine start /ProgIDOpen %s %%f\n", progId);
|
||||||
fprintf(desktop, "NoDisplay=true\n");
|
fprintf(desktop, "NoDisplay=true\n");
|
||||||
fprintf(desktop, "StartupNotify=true\n");
|
fprintf(desktop, "StartupNotify=true\n");
|
||||||
|
if (openWithIcon)
|
||||||
|
fprintf(desktop, "Icon=%s\n", openWithIcon);
|
||||||
ret = TRUE;
|
ret = TRUE;
|
||||||
fclose(desktop);
|
fclose(desktop);
|
||||||
}
|
}
|
||||||
|
@ -2116,6 +2145,8 @@ static BOOL generate_associations(const char *xdg_data_home, const char *package
|
||||||
{
|
{
|
||||||
char *extensionA = NULL;
|
char *extensionA = NULL;
|
||||||
WCHAR *commandW = NULL;
|
WCHAR *commandW = NULL;
|
||||||
|
WCHAR *executableW = NULL;
|
||||||
|
char *openWithIconA = NULL;
|
||||||
WCHAR *friendlyDocNameW = NULL;
|
WCHAR *friendlyDocNameW = NULL;
|
||||||
char *friendlyDocNameA = NULL;
|
char *friendlyDocNameA = NULL;
|
||||||
WCHAR *iconW = NULL;
|
WCHAR *iconW = NULL;
|
||||||
|
@ -2200,6 +2231,10 @@ static BOOL generate_associations(const char *xdg_data_home, const char *package
|
||||||
/* no command => no application is associated */
|
/* no command => no application is associated */
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
|
executableW = assoc_query(ASSOCSTR_EXECUTABLE, extensionW, openW);
|
||||||
|
if (executableW)
|
||||||
|
openWithIconA = extract_icon(executableW, 0, NULL, FALSE);
|
||||||
|
|
||||||
friendlyAppNameW = assoc_query(ASSOCSTR_FRIENDLYAPPNAME, extensionW, NULL);
|
friendlyAppNameW = assoc_query(ASSOCSTR_FRIENDLYAPPNAME, extensionW, NULL);
|
||||||
if (friendlyAppNameW)
|
if (friendlyAppNameW)
|
||||||
{
|
{
|
||||||
|
@ -2233,15 +2268,15 @@ static BOOL generate_associations(const char *xdg_data_home, const char *package
|
||||||
else
|
else
|
||||||
goto end; /* no progID => not a file type association */
|
goto end; /* no progID => not a file type association */
|
||||||
|
|
||||||
if (has_association_changed(extensionW, mimeTypeA, progIdW, friendlyAppNameA, friendlyDocNameW))
|
if (has_association_changed(extensionW, mimeTypeA, progIdW, friendlyAppNameA, friendlyDocNameW, openWithIconA))
|
||||||
{
|
{
|
||||||
char *desktopPath = heap_printf("%s/wine-extension-%s.desktop", applications_dir, &extensionA[1]);
|
char *desktopPath = heap_printf("%s/wine-extension-%s.desktop", applications_dir, &extensionA[1]);
|
||||||
if (desktopPath)
|
if (desktopPath)
|
||||||
{
|
{
|
||||||
if (write_freedesktop_association_entry(desktopPath, extensionA, friendlyAppNameA, mimeTypeA, progIdA))
|
if (write_freedesktop_association_entry(desktopPath, extensionA, friendlyAppNameA, mimeTypeA, progIdA, openWithIconA))
|
||||||
{
|
{
|
||||||
hasChanged = TRUE;
|
hasChanged = TRUE;
|
||||||
update_association(extensionW, mimeTypeA, progIdW, friendlyAppNameA, friendlyDocNameW, desktopPath);
|
update_association(extensionW, mimeTypeA, progIdW, friendlyAppNameA, friendlyDocNameW, desktopPath, openWithIconA);
|
||||||
}
|
}
|
||||||
HeapFree(GetProcessHeap(), 0, desktopPath);
|
HeapFree(GetProcessHeap(), 0, desktopPath);
|
||||||
}
|
}
|
||||||
|
@ -2250,6 +2285,8 @@ static BOOL generate_associations(const char *xdg_data_home, const char *package
|
||||||
end:
|
end:
|
||||||
HeapFree(GetProcessHeap(), 0, extensionA);
|
HeapFree(GetProcessHeap(), 0, extensionA);
|
||||||
HeapFree(GetProcessHeap(), 0, commandW);
|
HeapFree(GetProcessHeap(), 0, commandW);
|
||||||
|
HeapFree(GetProcessHeap(), 0, executableW);
|
||||||
|
HeapFree(GetProcessHeap(), 0, openWithIconA);
|
||||||
HeapFree(GetProcessHeap(), 0, friendlyDocNameW);
|
HeapFree(GetProcessHeap(), 0, friendlyDocNameW);
|
||||||
HeapFree(GetProcessHeap(), 0, friendlyDocNameA);
|
HeapFree(GetProcessHeap(), 0, friendlyDocNameA);
|
||||||
HeapFree(GetProcessHeap(), 0, iconW);
|
HeapFree(GetProcessHeap(), 0, iconW);
|
||||||
|
|
Loading…
Reference in New Issue