diff options
-rw-r--r-- | gdk-pixbuf/gdk-pixbuf-io.c | 43 | ||||
-rw-r--r-- | gdk-pixbuf/queryloaders.c | 79 |
2 files changed, 82 insertions, 40 deletions
diff --git a/gdk-pixbuf/gdk-pixbuf-io.c b/gdk-pixbuf/gdk-pixbuf-io.c index 021b4c702..75fa26ae4 100644 --- a/gdk-pixbuf/gdk-pixbuf-io.c +++ b/gdk-pixbuf/gdk-pixbuf-io.c @@ -347,34 +347,24 @@ get_libdir (void) #undef GDK_PIXBUF_LIBDIR #define GDK_PIXBUF_LIBDIR get_libdir() -static void -correct_prefix (gchar **path) +#endif /* GDK_PIXBUF_RELOCATABLE */ + +/* In case we have a relative module path in the loaders cache + * prepend the toplevel dir */ +static gchar * +build_module_path (const gchar *path) { - if (strncmp (*path, GDK_PIXBUF_PREFIX "/", strlen (GDK_PIXBUF_PREFIX "/")) == 0 || - strncmp (*path, GDK_PIXBUF_PREFIX "\\", strlen (GDK_PIXBUF_PREFIX "\\")) == 0) - { - gchar *tem = NULL; - if (g_str_has_suffix (*path, ".libs")) - { - /* We are being run from inside the build tree, and shouldn't mess about. */ - return; +#ifdef GDK_PIXBUF_RELOCATABLE + if (g_path_is_absolute (path)) { + return g_strdup (path); + } else { + return g_build_filename (gdk_pixbuf_get_toplevel (), path, NULL); } - - /* This is an entry put there by gdk-pixbuf-query-loaders on the - * packager's system. On Windows a prebuilt gdk-pixbuf package can be - * installed in a random location. The loaders.cache file - * distributed in such a package contains paths from the package - * builder's machine. Replace the build-time prefix with the - * installation prefix on this machine. - */ - tem = *path; - *path = g_strconcat (gdk_pixbuf_get_toplevel (), tem + strlen (GDK_PIXBUF_PREFIX), NULL); - g_free (tem); - } +#else + return g_strdup (path); +#endif } -#endif /* GDK_PIXBUF_RELOCATABLE */ - static gchar * gdk_pixbuf_get_module_file (void) { @@ -512,9 +502,6 @@ gdk_pixbuf_io_init (void) /* Blank line marking the end of a module */ if (module && *p != '#') { -#ifdef GDK_PIXBUF_RELOCATABLE - correct_prefix (&module->module_path); -#endif file_formats = g_slist_prepend (file_formats, module); module = NULL; } @@ -536,7 +523,7 @@ gdk_pixbuf_io_init (void) filename, line_buf); have_error = TRUE; } - module->module_path = g_strdup (tmp_buf->str); + module->module_path = build_module_path (tmp_buf->str); } else if (!module->module_name) { module->info = g_new0 (GdkPixbufFormat, 1); diff --git a/gdk-pixbuf/queryloaders.c b/gdk-pixbuf/queryloaders.c index 2b025b88c..7728caf4b 100644 --- a/gdk-pixbuf/queryloaders.c +++ b/gdk-pixbuf/queryloaders.c @@ -116,14 +116,80 @@ loader_sanity_check (const char *path, GdkPixbufFormat *info, GdkPixbufModule *v return 0; } +#ifdef GDK_PIXBUF_RELOCATABLE + +/* Based on gdk_pixbuf_get_toplevel () */ +static gchar * +get_toplevel (void) +{ + static gchar *toplevel = NULL; + + if (toplevel == NULL) { +#if defined (G_OS_WIN32) + toplevel = g_win32_get_package_installation_directory_of_module (NULL); +#elif defined(OS_DARWIN) + char pathbuf[PATH_MAX + 1]; + uint32_t bufsize = sizeof (pathbuf); + gchar *bin_dir; + + _NSGetExecutablePath (pathbuf, &bufsize); + bin_dir = g_dirname (pathbuf); + toplevel = g_build_path (G_DIR_SEPARATOR_S, bin_dir, "..", NULL); + g_free (bin_dir); +#elif defined (OS_LINUX) || defined (__MINGW32__) + gchar *exe_path, *bin_dir; + + exe_path = g_file_read_link ("/proc/self/exe", NULL); + bin_dir = g_dirname (exe_path); + toplevel = g_build_path (G_DIR_SEPARATOR_S, bin_dir, "..", NULL); + g_free (exe_path); + g_free (bin_dir); +#else +#error "Relocations not supported for this platform" +#endif + } + return toplevel; +} + +/* Returns the relative path or NULL; transfer full */ +static gchar * +get_relative_path (const gchar *parent, const gchar *descendant) +{ + GFile *parent_file, *descendant_file; + char *relative_path; + + parent_file = g_file_new_for_path (parent); + descendant_file = g_file_new_for_path (descendant); + relative_path = g_file_get_relative_path (parent_file, descendant_file); + g_object_unref (parent_file); + g_object_unref (descendant_file); + + return relative_path; +} + +#endif /* GDK_PIXBUF_RELOCATABLE */ + static void write_loader_info (GString *contents, const char *path, GdkPixbufFormat *info) { const GdkPixbufModulePattern *pattern; char **mime; char **ext; + gchar *module_path = NULL, *escaped_path; + +#ifdef GDK_PIXBUF_RELOCATABLE + module_path = get_relative_path (get_toplevel (), path); +#endif + + if (module_path == NULL) { + module_path = g_strdup (path); + } + + escaped_path = g_strescape (module_path, ""); + g_string_append_printf (contents, "\"%s\"\n", escaped_path); + g_free (module_path); + g_free (escaped_path); - g_string_append_printf (contents, "\"%s\"\n", path); g_string_append_printf (contents, "\"%s\" %u \"%s\" \"%s\" \"%s\"\n", info->name, info->flags, @@ -213,17 +279,6 @@ query_module (GString *contents, const char *dir, const char *file) #ifdef G_OS_WIN32 static char * -get_toplevel (void) -{ - static char *toplevel = NULL; - - if (toplevel == NULL) - toplevel = g_win32_get_package_installation_directory_of_module (NULL); - - return toplevel; -} - -static char * get_libdir (void) { static char *libdir = NULL; |