[2/10] winemenubuilder: Use a dispatch table to access XDG specific parts. (try 2)
Per Johansson
per at morth.org
Wed Mar 20 02:43:26 CDT 2013
Also adds a "none" option for dispatch to disable winemenubuilder.
build_desktop_link and build_menu_link was made to have identical
arguments, which is why lastEntry was moved.
---
programs/winemenubuilder/winemenubuilder.c | 384 ++++++++++++++++++-----------
programs/winemenubuilder/winemenubuilder.h | 59 +++++
2 files changed, 305 insertions(+), 138 deletions(-)
create mode 100644 programs/winemenubuilder/winemenubuilder.h
diff --git a/programs/winemenubuilder/winemenubuilder.c b/programs/winemenubuilder/winemenubuilder.c
index 1aabda0..5425854 100644
--- a/programs/winemenubuilder/winemenubuilder.c
+++ b/programs/winemenubuilder/winemenubuilder.c
@@ -7,6 +7,7 @@
* Copyright 2004 Dmitry Timoshkov
* Copyright 2005 Bill Medland
* Copyright 2008 Damjan Jovanovic
+ * Copyright 2011 - 2013 Per Johansson
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -97,6 +98,8 @@
#include "wine/list.h"
#include "wine/rbtree.h"
+#include "winemenubuilder.h"
+
WINE_DEFAULT_DEBUG_CHANNEL(menubuilder);
#define in_desktop_dir(csidl) ((csidl)==CSIDL_DESKTOPDIRECTORY || \
@@ -130,25 +133,6 @@ typedef struct
typedef struct
{
- BYTE bWidth;
- BYTE bHeight;
- BYTE bColorCount;
- BYTE bReserved;
- WORD wPlanes;
- WORD wBitCount;
- DWORD dwBytesInRes;
- DWORD dwImageOffset;
-} ICONDIRENTRY;
-
-typedef struct
-{
- WORD idReserved;
- WORD idType;
- WORD idCount;
-} ICONDIR;
-
-typedef struct
-{
WORD offset;
WORD length;
WORD flags;
@@ -175,6 +159,15 @@ typedef struct
int nIndex;
} ENUMRESSTRUCT;
+struct xdg_file_type_user_data
+{
+ char *mime_dir;
+ char *packages_dir;
+ char *applications_dir;
+
+ struct list *native_mime_types;
+};
+
struct xdg_mime_type
{
char *mimeType;
@@ -191,6 +184,8 @@ struct rb_string_entry
DEFINE_GUID(CLSID_WICIcnsEncoder, 0x312fb6f1,0xb767,0x409d,0x8a,0x6d,0x0f,0xc1,0x54,0xd4,0xf0,0x5c);
+const struct winemenubuilder_dispatch *wmb_dispatch;
+
static char *xdg_config_dir;
static char *xdg_data_dir;
static char *xdg_desktop_dir;
@@ -1126,7 +1121,7 @@ static inline int size_to_slot(int size)
#define CLASSIC_SLOT 3
-static HRESULT platform_write_icon(IStream *icoStream, int exeIndex, LPCWSTR icoPathW,
+static HRESULT osx_write_icon(IStream *icoStream, int exeIndex, LPCWSTR icoPathW,
const char *destFilename, char **nativeIdentifier)
{
ICONDIRENTRY *iconDirEntries = NULL;
@@ -1256,7 +1251,7 @@ static void refresh_icon_cache(const char *iconsDir)
}
}
-static HRESULT platform_write_icon(IStream *icoStream, int exeIndex, LPCWSTR icoPathW,
+static HRESULT xdg_write_icon(IStream *icoStream, int exeIndex, LPCWSTR icoPathW,
const char *destFilename, char **nativeIdentifier)
{
ICONDIRENTRY *iconDirEntries = NULL;
@@ -1370,7 +1365,7 @@ 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 = platform_write_icon(stream, index, icoPathW, destFilename, &nativeIdentifier);
+ hr = wmb_dispatch->write_icon(stream, index, icoPathW, destFilename, &nativeIdentifier);
if (FAILED(hr))
WINE_WARN("writing icon failed, error 0x%08X\n", hr);
@@ -2177,14 +2172,15 @@ static BOOL match_glob(struct list *native_mime_types, const char *extension,
return TRUE;
}
-static BOOL freedesktop_mime_type_for_extension(struct list *native_mime_types,
+static BOOL freedesktop_mime_type_for_extension(void *user,
const char *extensionA,
LPCWSTR extensionW,
char **mime_type)
{
+ struct xdg_file_type_user_data *ud = user;
WCHAR *lower_extensionW;
INT len;
- BOOL ret = match_glob(native_mime_types, extensionA, 0, mime_type);
+ BOOL ret = match_glob(ud->native_mime_types, extensionA, 0, mime_type);
if (ret == FALSE || *mime_type != NULL)
return ret;
len = strlenW(extensionW);
@@ -2197,7 +2193,7 @@ static BOOL freedesktop_mime_type_for_extension(struct list *native_mime_types,
lower_extensionA = wchars_to_utf8_chars(lower_extensionW);
if (lower_extensionA)
{
- ret = match_glob(native_mime_types, lower_extensionA, 1, mime_type);
+ ret = match_glob(ud->native_mime_types, lower_extensionA, 1, mime_type);
HeapFree(GetProcessHeap(), 0, lower_extensionA);
}
else
@@ -2368,7 +2364,7 @@ done:
HeapFree(GetProcessHeap(), 0, openWithIconW);
}
-static BOOL cleanup_associations(char *applications_dir)
+static BOOL cleanup_associations(void *user)
{
static const WCHAR openW[] = {'o','p','e','n',0};
HKEY assocKey;
@@ -2406,14 +2402,8 @@ static BOOL cleanup_associations(char *applications_dir)
char *extensionA = wchars_to_utf8_chars(strlwrW(extensionW));
if (extensionA)
{
- char *desktopFile = heap_printf("%s/wine-extension-%s.desktop", applications_dir, &extensionA[1]);
+ wmb_dispatch->remove_file_type_association(user, extensionA, extensionW);
- if (desktopFile)
- {
- WINE_TRACE("removing file type association for %s\n", wine_dbgstr_w(extensionW));
- remove(desktopFile);
- HeapFree(GetProcessHeap(), 0, desktopFile);
- }
HeapFree(GetProcessHeap(), 0, extensionA);
}
RegDeleteKeyW(assocKey, extensionW);
@@ -2438,16 +2428,17 @@ static BOOL cleanup_associations(char *applications_dir)
return hasChanged;
}
-static BOOL write_freedesktop_mime_type_entry(const char *packages_dir, const char *dot_extension,
+static BOOL write_freedesktop_mime_type_entry(void *user, const char *dot_extension,
const char *mime_type, const char *comment)
{
+ struct xdg_file_type_user_data *ud = user;
BOOL ret = FALSE;
char *filename;
WINE_TRACE("writing MIME type %s, extension=%s, comment=%s\n", wine_dbgstr_a(mime_type),
wine_dbgstr_a(dot_extension), wine_dbgstr_a(comment));
- filename = heap_printf("%s/x-wine-extension-%s.xml", packages_dir, &dot_extension[1]);
+ filename = heap_printf("%s/x-wine-extension-%s.xml", ud->packages_dir, &dot_extension[1]);
if (filename)
{
FILE *packageFile = fopen(filename, "w");
@@ -2503,12 +2494,21 @@ static const char* get_special_mime_type(LPCWSTR extension)
return NULL;
}
-static BOOL write_freedesktop_association_entry(const char *desktopPath, const char *dot_extension,
- const char *friendlyAppName, const char *mimeType,
- const char *progId, const char *openWithIcon)
+static BOOL write_freedesktop_association_entry(void *user, const char *dot_extension,
+ const char *friendlyAppName,
+ const char *friendlyDocNameA,
+ const char *mimeType, const char *progId,
+ const char *openWithIcon)
{
+ struct xdg_file_type_user_data *ud = user;
BOOL ret = FALSE;
FILE *desktop;
+ char *desktopPath = heap_printf("%s/wine-extension-%s.desktop", ud->applications_dir, &dot_extension[1]);
+
+ if (!desktopPath) {
+ WINE_ERR("out of memory\n");
+ return FALSE;
+ }
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),
@@ -2534,11 +2534,10 @@ static BOOL write_freedesktop_association_entry(const char *desktopPath, const c
return ret;
}
-static BOOL generate_associations(const char *xdg_data_home, const char *packages_dir, const char *applications_dir)
+static BOOL generate_associations(void *user)
{
static const WCHAR openW[] = {'o','p','e','n',0};
struct wine_rb_tree mimeProgidTree;
- struct list *nativeMimeTypes = NULL;
LSTATUS ret = 0;
int i;
BOOL hasChanged = FALSE;
@@ -2548,11 +2547,6 @@ static BOOL generate_associations(const char *xdg_data_home, const char *package
WINE_ERR("wine_rb_init failed\n");
return FALSE;
}
- if (!build_native_mime_types(xdg_data_home, &nativeMimeTypes))
- {
- WINE_ERR("could not build native MIME types\n");
- return FALSE;
- }
for (i = 0; ; i++)
{
@@ -2615,7 +2609,7 @@ static BOOL generate_associations(const char *xdg_data_home, const char *package
if (contentTypeW)
strlwrW(contentTypeW);
- if (!freedesktop_mime_type_for_extension(nativeMimeTypes, extensionA, extensionW, &mimeTypeA))
+ if (!wmb_dispatch->mime_type_for_extension(user, extensionA, extensionW, &mimeTypeA))
goto end;
if (mimeTypeA == NULL)
@@ -2649,7 +2643,7 @@ static BOOL generate_associations(const char *xdg_data_home, const char *package
}
}
- write_freedesktop_mime_type_entry(packages_dir, extensionA, mimeTypeA, friendlyDocNameA);
+ wmb_dispatch->write_mime_type_entry(user, extensionA, mimeTypeA, friendlyDocNameA);
hasChanged = TRUE;
}
else
@@ -2727,15 +2721,10 @@ static BOOL generate_associations(const char *xdg_data_home, const char *package
if (has_association_changed(extensionW, mimeTypeA, progIdW, friendlyAppNameA, openWithIconA))
{
- char *desktopPath = heap_printf("%s/wine-extension-%s.desktop", applications_dir, &extensionA[1]);
- if (desktopPath)
+ if (wmb_dispatch->write_association_entry(user, extensionA, friendlyAppNameA, friendlyDocNameA, mimeTypeA, progIdA, openWithIconA))
{
- if (write_freedesktop_association_entry(desktopPath, extensionA, friendlyAppNameA, mimeTypeA, progIdA, openWithIconA))
- {
- hasChanged = TRUE;
- update_association(extensionW, mimeTypeA, progIdW, friendlyAppNameA, openWithIconA);
- }
- HeapFree(GetProcessHeap(), 0, desktopPath);
+ hasChanged = TRUE;
+ update_association(extensionW, mimeTypeA, progIdW, friendlyAppNameA, openWithIconA);
}
}
@@ -2761,7 +2750,6 @@ static BOOL generate_associations(const char *xdg_data_home, const char *package
}
wine_rb_destroy(&mimeProgidTree, winemenubuilder_rb_destroy, NULL);
- free_native_mime_types(nativeMimeTypes);
return hasChanged;
}
@@ -2806,6 +2794,7 @@ static BOOL InvokeShellLinker( IShellLinkW *sl, LPCWSTR link, BOOL bWait )
HANDLE hsem = NULL;
char *unix_link = NULL;
char *start_path = NULL;
+ const char *lastEntry;
if ( !link )
{
@@ -2945,33 +2934,27 @@ static BOOL InvokeShellLinker( IShellLinkW *sl, LPCWSTR link, BOOL bWait )
goto cleanup;
}
+ lastEntry = strrchr(link_name, '/');
+ if (lastEntry == NULL)
+ lastEntry = link_name;
+ else
+ ++lastEntry;
+
if (in_desktop_dir(csidl))
{
- char *location;
- const char *lastEntry;
- lastEntry = strrchr(link_name, '/');
- if (lastEntry == NULL)
- lastEntry = link_name;
- else
- ++lastEntry;
- location = heap_printf("%s/%s.desktop", xdg_desktop_dir, lastEntry);
- if (location)
+ if (csidl == CSIDL_COMMON_DESKTOPDIRECTORY)
{
- if (csidl == CSIDL_COMMON_DESKTOPDIRECTORY)
+ char *link_arg = escape_unix_link_arg(unix_link);
+ if (link_arg)
{
- char *link_arg = escape_unix_link_arg(unix_link);
- if (link_arg)
- {
- r = !write_desktop_entry(unix_link, location, lastEntry,
+ r = wmb_dispatch->build_desktop_link(unix_link, link_name, lastEntry,
start_path, link_arg, description, work_dir, icon_name);
- HeapFree(GetProcessHeap(), 0, link_arg);
- }
+ HeapFree(GetProcessHeap(), 0, link_arg);
}
- else
- r = !write_desktop_entry(NULL, location, lastEntry, escaped_path, escaped_args, description, work_dir, icon_name);
- if (r == 0)
- chmod(location, 0755);
- HeapFree(GetProcessHeap(), 0, location);
+ }
+ else
+ {
+ r = wmb_dispatch->build_desktop_link(NULL, link_name, lastEntry, escaped_path, escaped_args, description, work_dir, icon_name);
}
}
else
@@ -2979,7 +2962,7 @@ static BOOL InvokeShellLinker( IShellLinkW *sl, LPCWSTR link, BOOL bWait )
char *link_arg = escape_unix_link_arg(unix_link);
if (link_arg)
{
- r = !write_menu_entry(unix_link, link_name, start_path, link_arg, description, work_dir, icon_name);
+ r = wmb_dispatch->build_menu_link(unix_link, link_name, lastEntry, start_path, link_arg, description, work_dir, icon_name);
HeapFree(GetProcessHeap(), 0, link_arg);
}
}
@@ -3020,6 +3003,7 @@ static BOOL InvokeShellLinkerForURL( IUniformResourceLocatorW *url, LPCWSTR link
PROPVARIANT pv[2];
char *start_path = NULL;
BOOL has_icon = FALSE;
+ char *lastEntry;
if ( !link )
{
@@ -3117,26 +3101,15 @@ static BOOL InvokeShellLinkerForURL( IUniformResourceLocatorW *url, LPCWSTR link
WINE_ERR("failed wait for semaphore\n");
goto cleanup;
}
+ lastEntry = strrchr(link_name, '/');
+ if (lastEntry == NULL)
+ lastEntry = link_name;
+ else
+ ++lastEntry;
if (in_desktop_dir(csidl))
- {
- char *location;
- const char *lastEntry;
- lastEntry = strrchr(link_name, '/');
- if (lastEntry == NULL)
- lastEntry = link_name;
- else
- ++lastEntry;
- location = heap_printf("%s/%s.desktop", xdg_desktop_dir, lastEntry);
- if (location)
- {
- r = !write_desktop_entry(NULL, location, lastEntry, start_path, escaped_urlPath, NULL, NULL, icon_name);
- if (r == 0)
- chmod(location, 0755);
- HeapFree(GetProcessHeap(), 0, location);
- }
- }
+ r = wmb_dispatch->build_desktop_link(NULL, link_name, lastEntry, start_path, escaped_urlPath, NULL, NULL, icon_name);
else
- r = !write_menu_entry(unix_link, link_name, start_path, escaped_urlPath, NULL, NULL, icon_name);
+ r = wmb_dispatch->build_menu_link(unix_link, link_name, lastEntry, start_path, escaped_urlPath, NULL, NULL, icon_name);
ret = (r == 0);
ReleaseSemaphore(hSem, 1, NULL);
@@ -3318,10 +3291,8 @@ static BOOL Process_URL( LPCWSTR urlname, BOOL bWait )
static void RefreshFileTypeAssociations(void)
{
HANDLE hSem = NULL;
- char *mime_dir = NULL;
- char *packages_dir = NULL;
- char *applications_dir = NULL;
BOOL hasChanged;
+ void *user;
hSem = CreateSemaphoreA( NULL, 1, 1, "winemenubuilder_semaphore");
if( WAIT_OBJECT_0 != MsgWaitForMultipleObjects( 1, &hSem, FALSE, INFINITE, QS_ALLINPUT ) )
@@ -3332,45 +3303,15 @@ static void RefreshFileTypeAssociations(void)
goto end;
}
- mime_dir = heap_printf("%s/mime", xdg_data_dir);
- if (mime_dir == NULL)
- {
- WINE_ERR("out of memory\n");
- goto end;
- }
- create_directories(mime_dir);
-
- packages_dir = heap_printf("%s/packages", mime_dir);
- if (packages_dir == NULL)
- {
- WINE_ERR("out of memory\n");
- goto end;
- }
- create_directories(packages_dir);
+ user = wmb_dispatch->refresh_file_type_associations_init();
- applications_dir = heap_printf("%s/applications", xdg_data_dir);
- if (applications_dir == NULL)
- {
- WINE_ERR("out of memory\n");
+ if (!user)
goto end;
- }
- create_directories(applications_dir);
-
- hasChanged = generate_associations(xdg_data_dir, packages_dir, applications_dir);
- hasChanged |= cleanup_associations(applications_dir);
- if (hasChanged)
- {
- const char *argv[3];
- argv[0] = "update-mime-database";
- argv[1] = mime_dir;
- argv[2] = NULL;
- spawnvp( _P_DETACH, argv[0], argv );
+ hasChanged = generate_associations(user);
+ hasChanged |= cleanup_associations(user);
- argv[0] = "update-desktop-database";
- argv[1] = applications_dir;
- spawnvp( _P_DETACH, argv[0], argv );
- }
+ wmb_dispatch->refresh_file_type_associations_cleanup(user, hasChanged);
end:
if (hSem)
@@ -3378,9 +3319,6 @@ end:
ReleaseSemaphore(hSem, 1, NULL);
CloseHandle(hSem);
}
- HeapFree(GetProcessHeap(), 0, mime_dir);
- HeapFree(GetProcessHeap(), 0, packages_dir);
- HeapFree(GetProcessHeap(), 0, applications_dir);
}
static void cleanup_menus(void)
@@ -3627,6 +3565,173 @@ static BOOL init_xdg(void)
return FALSE;
}
+static int xdg_build_desktop_link(const char *unix_link, const char *link, const char *link_name, const char *path,
+ const char *args, const char *descr, const char *workdir, char *icon)
+{
+ char *location;
+ int r = -1;
+
+ location = heap_printf("%s/%s.desktop", xdg_desktop_dir, link_name);
+ if (location)
+ {
+ r = !write_desktop_entry(unix_link, location, link_name,
+ path, args, descr, workdir, icon);
+ if (r == 0)
+ chmod(location, 0755);
+ }
+ return r;
+}
+
+static int xdg_build_menu_link(const char *unix_link, const char *link, const char *link_name, const char *path,
+ const char *args, const char *descr, const char *workdir, char *icon)
+{
+ return !write_menu_entry(unix_link, link, path, args, descr, workdir, icon);
+}
+
+static void *xdg_refresh_file_type_associations_init(void)
+{
+ struct xdg_file_type_user_data *ud = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ud));
+
+ if (ud == NULL)
+ {
+ WINE_ERR("out of memory\n");
+ return NULL;
+ }
+
+ ud->mime_dir = heap_printf("%s/mime", xdg_data_dir);
+ if (ud->mime_dir == NULL)
+ {
+ WINE_ERR("out of memory\n");
+ return NULL;
+ }
+ create_directories(ud->mime_dir);
+
+ ud->packages_dir = heap_printf("%s/packages", ud->mime_dir);
+ if (ud->packages_dir == NULL)
+ {
+ WINE_ERR("out of memory\n");
+ return NULL;
+ }
+ create_directories(ud->packages_dir);
+
+ ud->applications_dir = heap_printf("%s/applications", xdg_data_dir);
+ if (ud->applications_dir == NULL)
+ {
+ WINE_ERR("out of memory\n");
+ return NULL;
+ }
+ create_directories(ud->applications_dir);
+
+ if (!build_native_mime_types(xdg_data_dir, &ud->native_mime_types))
+ return NULL;
+
+ return ud;
+}
+
+static BOOL xdg_remove_file_type_association(void *user, const char *dot_extension, LPCWSTR extensionW)
+{
+ struct xdg_file_type_user_data *ud = user;
+ char *desktopPath = heap_printf("%s/wine-extension-%s.desktop", ud->applications_dir, &dot_extension[1]);
+
+ if (desktopPath)
+ {
+ WINE_TRACE("removing file type association for %s\n", wine_dbgstr_w(extensionW));
+ remove(desktopPath);
+ HeapFree(GetProcessHeap(), 0, desktopPath);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static void xdg_refresh_file_type_associations_cleanup(void *user, BOOL hasChanged)
+{
+ struct xdg_file_type_user_data *ud = user;
+
+ if (hasChanged)
+ {
+ const char *argv[3];
+
+ argv[0] = "update-mime-database";
+ argv[1] = ud->mime_dir;
+ argv[2] = NULL;
+ spawnvp( _P_DETACH, argv[0], argv );
+
+ argv[0] = "update-desktop-database";
+ argv[1] = ud->applications_dir;
+ spawnvp( _P_DETACH, argv[0], argv );
+ }
+
+ HeapFree(GetProcessHeap(), 0, ud->mime_dir);
+ HeapFree(GetProcessHeap(), 0, ud->packages_dir);
+ HeapFree(GetProcessHeap(), 0, ud->applications_dir);
+ HeapFree(GetProcessHeap(), 0, ud);
+}
+
+const struct winemenubuilder_dispatch xdg_dispatch =
+{
+ init_xdg,
+
+ xdg_build_desktop_link,
+ xdg_build_menu_link,
+
+#ifdef __APPLE__
+ osx_write_icon,
+#else
+ xdg_write_icon,
+#endif
+
+ xdg_refresh_file_type_associations_init,
+ freedesktop_mime_type_for_extension,
+ write_freedesktop_mime_type_entry,
+ write_freedesktop_association_entry,
+ xdg_remove_file_type_association,
+ xdg_refresh_file_type_associations_cleanup
+};
+
+static BOOL dispatch_init(void)
+{
+ const char *dispatch = NULL;
+ unsigned char buffer[256];
+ HKEY hkey;
+
+ if (RegOpenKeyExA(HKEY_CURRENT_USER, "Software\\Wine\\MenuBuilder", 0, KEY_READ, &hkey) == ERROR_SUCCESS)
+ {
+ DWORD type, count = sizeof(buffer);
+
+ buffer[0] = 0;
+
+ RegQueryValueExA(hkey, "Dispatch", 0, &type, buffer, &count);
+ if (buffer[0] && type == REG_SZ)
+ {
+ dispatch = (char*)buffer;
+ WINE_TRACE("Dispatch set to %s from registry\n", dispatch);
+ }
+ else
+ WINE_TRACE("No Dispatch key in registry or type != string\n");
+ }
+ else
+ WINE_TRACE("No MenuBuilder key in registry\n");
+
+ if (dispatch)
+ {
+ if (strcmp(dispatch, "none") == 0)
+ return FALSE;
+
+ if (strcmp(dispatch, "xdg") == 0)
+ {
+ wmb_dispatch = &xdg_dispatch;
+ return TRUE;
+ }
+
+ WINE_WARN("Unknown Wine MenuBuilder Dispatch \"%s\"\n", dispatch);
+ }
+
+ wmb_dispatch = &xdg_dispatch;
+ WINE_TRACE("Dispatch set to xdg by default\n");
+ return TRUE;
+}
+
/***********************************************************************
*
* wWinMain
@@ -3645,7 +3750,10 @@ int PASCAL wWinMain (HINSTANCE hInstance, HINSTANCE prev, LPWSTR cmdline, int sh
HRESULT hr;
int ret = 0;
- if (!init_xdg())
+ if (!dispatch_init())
+ return 0;
+
+ if (!wmb_dispatch->init())
return 1;
hr = CoInitialize(NULL);
diff --git a/programs/winemenubuilder/winemenubuilder.h b/programs/winemenubuilder/winemenubuilder.h
new file mode 100644
index 0000000..0bd3425
--- /dev/null
+++ b/programs/winemenubuilder/winemenubuilder.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2011 - 2013 Per Johansson
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+typedef struct
+{
+ BYTE bWidth;
+ BYTE bHeight;
+ BYTE bColorCount;
+ BYTE bReserved;
+ WORD wPlanes;
+ WORD wBitCount;
+ DWORD dwBytesInRes;
+ DWORD dwImageOffset;
+} ICONDIRENTRY;
+
+typedef struct
+{
+ WORD idReserved;
+ WORD idType;
+ WORD idCount;
+} ICONDIR;
+
+struct winemenubuilder_dispatch
+{
+ BOOL (*init)(void);
+
+ int (*build_desktop_link)(const char *unix_link, const char *link, const char *link_name, const char *path,
+ const char *args, const char *descr, const char *workdir, char *icon);
+ int (*build_menu_link)(const char *unix_link, const char *link, const char *link_name, const char *path,
+ const char *args, const char *descr, const char *workdir, char *icon);
+
+ HRESULT (*write_icon)(IStream *icoStream, int exeIndex, LPCWSTR icoPathW,
+ const char *destFilename, char **nativeIdentifier);
+
+
+ void *(*refresh_file_type_associations_init)(void);
+ BOOL (*mime_type_for_extension)(void *user, const char *extensionA, LPCWSTR extensionW, char **mime_type);
+ BOOL (*write_mime_type_entry)(void *user, const char *extensionA, const char *mimeTypeA, const char *friendlyDocNameA);
+ BOOL (*write_association_entry)(void *user, const char *extensionA, const char *friendlyAppNameA,
+ const char *friendlyDocNameA, const char *mimeTypeA, const char *progIdA,
+ const char *appIconA);
+ BOOL (*remove_file_type_association)(void *user, const char *extensionA, LPCWSTR extensionW);
+ void (*refresh_file_type_associations_cleanup)(void *user, BOOL hasChanged);
+};
--
1.8.0.2
More information about the wine-patches
mailing list