Damjan Jovanovic : winemenubuilder: Build freedesktop MIME type list for later use.
Alexandre Julliard
julliard at winehq.org
Tue Apr 21 11:45:47 CDT 2009
Module: wine
Branch: master
Commit: 0b4499cdcde2614d2bd2a9e0a9dd8ac718367bc5
URL: http://source.winehq.org/git/wine.git/?a=commit;h=0b4499cdcde2614d2bd2a9e0a9dd8ac718367bc5
Author: Damjan Jovanovic <damjan.jov at gmail.com>
Date: Sat Apr 11 10:10:59 2009 +0200
winemenubuilder: Build freedesktop MIME type list for later use.
---
programs/winemenubuilder/winemenubuilder.c | 169 ++++++++++++++++++++++++++++
1 files changed, 169 insertions(+), 0 deletions(-)
diff --git a/programs/winemenubuilder/winemenubuilder.c b/programs/winemenubuilder/winemenubuilder.c
index 9dafc16..58e84c6 100644
--- a/programs/winemenubuilder/winemenubuilder.c
+++ b/programs/winemenubuilder/winemenubuilder.c
@@ -78,6 +78,7 @@
#include "wine/unicode.h"
#include "wine/debug.h"
#include "wine/library.h"
+#include "wine/list.h"
#include "wine.xpm"
#ifdef HAVE_PNG_H
@@ -144,6 +145,13 @@ typedef struct
int nIndex;
} ENUMRESSTRUCT;
+struct xdg_mime_type
+{
+ char *mimeType;
+ char *glob;
+ struct list entry;
+};
+
static char *xdg_config_dir;
static char *xdg_data_dir;
static char *xdg_desktop_dir;
@@ -1243,6 +1251,165 @@ static HRESULT get_cmdline( IShellLinkW *sl, LPWSTR szPath, DWORD pathSize,
return hr;
}
+static BOOL next_line(FILE *file, char **line, int *size)
+{
+ int pos = 0;
+ char *cr;
+ if (*line == NULL)
+ {
+ *size = 4096;
+ *line = HeapAlloc(GetProcessHeap(), 0, *size);
+ }
+ while (*line != NULL)
+ {
+ if (fgets(&(*line)[pos], *size - pos, file) == NULL)
+ {
+ HeapFree(GetProcessHeap(), 0, *line);
+ *line = NULL;
+ if (feof(file))
+ return TRUE;
+ return FALSE;
+ }
+ pos = strlen(*line);
+ cr = strchr(*line, '\n');
+ if (cr == NULL)
+ {
+ char *line2;
+ (*size) *= 2;
+ line2 = HeapReAlloc(GetProcessHeap(), 0, *line, *size);
+ if (line2)
+ *line = line2;
+ else
+ {
+ HeapFree(GetProcessHeap(), 0, *line);
+ *line = NULL;
+ }
+ }
+ else
+ {
+ *cr = 0;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+static BOOL add_mimes(const char *xdg_data_dir, struct list *mime_types)
+{
+ char *globs_filename = NULL;
+ BOOL ret = TRUE;
+ globs_filename = heap_printf("%s/mime/globs", xdg_data_dir);
+ if (globs_filename)
+ {
+ FILE *globs_file = fopen(globs_filename, "r");
+ if (globs_file) /* doesn't have to exist */
+ {
+ char *line = NULL;
+ int size = 0;
+ while (ret && (ret = next_line(globs_file, &line, &size)) && line)
+ {
+ char *pos;
+ struct xdg_mime_type *mime_type_entry = NULL;
+ if (line[0] != '#' && (pos = strchr(line, ':')))
+ {
+ mime_type_entry = HeapAlloc(GetProcessHeap(), 0, sizeof(struct xdg_mime_type));
+ if (mime_type_entry)
+ {
+ *pos = 0;
+ mime_type_entry->mimeType = line;
+ mime_type_entry->glob = pos + 1;
+ list_add_tail(mime_types, &mime_type_entry->entry);
+ }
+ else
+ ret = FALSE;
+ }
+ }
+ HeapFree(GetProcessHeap(), 0, line);
+ fclose(globs_file);
+ }
+ HeapFree(GetProcessHeap(), 0, globs_filename);
+ }
+ else
+ ret = FALSE;
+ return ret;
+}
+
+static void free_native_mime_types(struct list *native_mime_types)
+{
+ struct xdg_mime_type *mime_type_entry, *mime_type_entry2;
+
+ LIST_FOR_EACH_ENTRY_SAFE(mime_type_entry, mime_type_entry2, native_mime_types, struct xdg_mime_type, entry)
+ {
+ list_remove(&mime_type_entry->entry);
+ HeapFree(GetProcessHeap(), 0, mime_type_entry->mimeType);
+ HeapFree(GetProcessHeap(), 0, mime_type_entry);
+ }
+ HeapFree(GetProcessHeap(), 0, native_mime_types);
+}
+
+static BOOL build_native_mime_types(const char *xdg_data_home, struct list **mime_types)
+{
+ char *xdg_data_dirs;
+ BOOL ret;
+
+ *mime_types = NULL;
+
+ xdg_data_dirs = getenv("XDG_DATA_DIRS");
+ if (xdg_data_dirs == NULL)
+ xdg_data_dirs = heap_printf("/usr/local/share/:/usr/share/");
+ else
+ xdg_data_dirs = heap_printf("%s", xdg_data_dirs);
+
+ if (xdg_data_dirs)
+ {
+ *mime_types = HeapAlloc(GetProcessHeap(), 0, sizeof(struct list));
+ if (*mime_types)
+ {
+ const char *begin;
+ char *end;
+
+ list_init(*mime_types);
+ ret = add_mimes(xdg_data_home, *mime_types);
+ if (ret)
+ {
+ for (begin = xdg_data_dirs; (end = strchr(begin, ':')); begin = end + 1)
+ {
+ *end = '\0';
+ ret = add_mimes(begin, *mime_types);
+ *end = ':';
+ if (!ret)
+ break;
+ }
+ if (ret)
+ ret = add_mimes(begin, *mime_types);
+ }
+ }
+ else
+ ret = FALSE;
+ HeapFree(GetProcessHeap(), 0, xdg_data_dirs);
+ }
+ else
+ ret = FALSE;
+ if (!ret && *mime_types)
+ {
+ free_native_mime_types(*mime_types);
+ *mime_types = NULL;
+ }
+ return ret;
+}
+
+static BOOL generate_associations(const char *xdg_data_home, const char *packages_dir, const char *applications_dir)
+{
+ struct list *nativeMimeTypes = NULL;
+
+ if (!build_native_mime_types(xdg_data_home, &nativeMimeTypes))
+ {
+ WINE_ERR("could not build native MIME types\n");
+ return FALSE;
+ }
+ return TRUE;
+}
+
static BOOL InvokeShellLinker( IShellLinkW *sl, LPCWSTR link, BOOL bWait )
{
static const WCHAR startW[] = {'\\','c','o','m','m','a','n','d',
@@ -1708,6 +1875,8 @@ static void RefreshFileTypeAssociations(void)
}
create_directories(applications_dir);
+ generate_associations(xdg_data_dir, packages_dir, applications_dir);
+
end:
if (hSem)
{
More information about the wine-cvs
mailing list