summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdk-pixbuf/gdk-pixbuf-io.c43
-rw-r--r--gdk-pixbuf/queryloaders.c79
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;