1 /* -*- mode: C; c-file-style: "linux" -*- */
5 * Copyright (C) 2002 The Free Software Foundation
7 * Author: Matthias Clasen <maclas@gmx.de>
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Library General Public
11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Library General Public License for more details.
19 * You should have received a copy of the GNU Library General Public
20 * License along with this library; if not, write to the
21 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22 * Boston, MA 02111-1307, USA.
28 #include <glib/gprintf.h>
37 #include "gdk-pixbuf/gdk-pixbuf.h"
38 #include "gdk-pixbuf/gdk-pixbuf-private.h"
39 #include "gdk-pixbuf/gdk-pixbuf-io.h"
44 #define SOEXT ("." G_MODULE_SUFFIX)
46 #define SOEXT_LEN (strlen (SOEXT))
53 print_escaped (const char *str
)
55 gchar
*tmp
= g_strescape (str
, "");
56 g_printf ("\"%s\" ", tmp
);
61 loader_sanity_check (const char *path
, GdkPixbufFormat
*info
, GdkPixbufModule
*vtable
)
63 const GdkPixbufModulePattern
*pattern
;
64 const char *error
= "";
66 for (pattern
= info
->signature
; pattern
->prefix
; pattern
++)
68 int prefix_len
= strlen (pattern
->prefix
);
71 error
= "empty pattern";
77 int mask_len
= strlen (pattern
->mask
);
78 if (mask_len
!= prefix_len
)
80 error
= "mask length mismatch";
84 if (strspn (pattern
->mask
, " !xzn*") < mask_len
)
86 error
= "bad char in mask";
93 if (!vtable
->load
&& !vtable
->begin_load
&& !vtable
->load_animation
)
95 error
= "no load method implemented";
100 if (vtable
->begin_load
&& (!vtable
->stop_load
|| !vtable
->load_increment
))
102 error
= "incremental loading support incomplete";
107 if ((info
->flags
& GDK_PIXBUF_FORMAT_WRITABLE
) && !(vtable
->save
|| vtable
->save_to_callback
))
109 error
= "loader claims to support saving but doesn't implement save";
116 g_fprintf (stderr
, "Loader sanity check failed for %s: %s\n",
123 write_loader_info (const char *path
, GdkPixbufFormat
*info
)
125 const GdkPixbufModulePattern
*pattern
;
129 g_printf("\"%s\"\n", path
);
130 g_printf ("\"%s\" %u \"%s\" \"%s\" \"%s\"\n",
131 info
->name
, info
->flags
,
132 info
->domain
? info
->domain
: GETTEXT_PACKAGE
, info
->description
, info
->license
);
133 for (mime
= info
->mime_types
; *mime
; mime
++) {
134 g_printf ("\"%s\" ", *mime
);
137 for (ext
= info
->extensions
; *ext
; ext
++) {
138 g_printf ("\"%s\" ", *ext
);
141 for (pattern
= info
->signature
; pattern
->prefix
; pattern
++) {
142 print_escaped (pattern
->prefix
);
143 print_escaped (pattern
->mask
? (const char *)pattern
->mask
: "");
144 g_printf ("%d\n", pattern
->relevance
);
150 query_module (const char *dir
, const char *file
)
154 void (*fill_info
) (GdkPixbufFormat
*info
);
155 void (*fill_vtable
) (GdkPixbufModule
*module
);
157 if (g_path_is_absolute (file
))
158 path
= g_strdup (file
);
160 path
= g_build_filename (dir
, file
, NULL
);
162 module
= g_module_open (path
, 0);
164 g_module_symbol (module
, "fill_info", (gpointer
*) &fill_info
) &&
165 g_module_symbol (module
, "fill_vtable", (gpointer
*) &fill_vtable
)) {
166 GdkPixbufFormat
*info
;
167 GdkPixbufModule
*vtable
;
170 /* Replace backslashes in path with forward slashes, so that
171 * it reads in without problems.
182 info
= g_new0 (GdkPixbufFormat
, 1);
183 vtable
= g_new0 (GdkPixbufModule
, 1);
185 vtable
->module
= module
;
188 (*fill_vtable
) (vtable
);
190 if (loader_sanity_check (path
, info
, vtable
))
191 write_loader_info (path
, info
);
198 g_fprintf (stderr
, "g_module_open() failed for %s: %s\n", path
,
201 g_fprintf (stderr
, "Cannot load loader %s\n", path
);
204 g_module_close (module
);
208 int main (int argc
, char **argv
)
215 gchar
*runtime_prefix
;
218 if (g_ascii_strncasecmp (PIXBUF_LIBDIR
, GTK_PREFIX
, strlen (GTK_PREFIX
)) == 0 &&
219 G_IS_DIR_SEPARATOR (PIXBUF_LIBDIR
[strlen (GTK_PREFIX
)])) {
220 /* GTK_PREFIX is a prefix of PIXBUF_LIBDIR, as it
221 * normally is. Replace that prefix in PIXBUF_LIBDIR
222 * with the installation directory on this machine.
223 * We assume this invokation of
224 * gdk-pixbuf-query-loaders is run from either a "bin"
225 * subdirectory of the installation directory, or in
226 * the installation directory itself.
228 if (G_WIN32_HAVE_WIDECHAR_API ()) {
230 GetModuleFileNameW (NULL
, fn
, G_N_ELEMENTS (fn
));
231 runtime_prefix
= g_utf16_to_utf8 (fn
, -1, NULL
, NULL
, NULL
);
235 GetModuleFileNameA (NULL
, fn
, G_N_ELEMENTS (fn
));
236 runtime_prefix
= g_locale_to_utf8 (fn
, -1, NULL
, NULL
, NULL
);
238 slash
= strrchr (runtime_prefix
, '\\');
240 slash
= strrchr (runtime_prefix
, '\\');
241 if (slash
!= NULL
&& g_ascii_strcasecmp (slash
+ 1, "bin") == 0) {
245 libdir
= g_strconcat (runtime_prefix
,
247 PIXBUF_LIBDIR
+ strlen (GTK_PREFIX
) + 1,
251 libdir
= PIXBUF_LIBDIR
;
255 #define PIXBUF_LIBDIR libdir
258 prgname
= g_get_prgname ();
259 g_printf ("# GdkPixbuf Image Loader Modules file\n"
260 "# Automatically generated file, do not edit\n"
261 "# Created by %s from gtk+-%s\n"
263 (prgname
? prgname
: "gdk-pixbuf-query-loaders"),
271 path
= g_getenv ("GDK_PIXBUF_MODULEDIR");
273 if (path
!= NULL
&& *path
!= '\0')
274 path
= g_locale_to_utf8 (path
, -1, NULL
, NULL
, NULL
);
276 if (path
== NULL
|| *path
== '\0')
277 path
= PIXBUF_LIBDIR
;
279 g_printf ("# LoaderDir = %s\n#\n", path
);
281 dir
= g_dir_open (path
, 0, NULL
);
285 while ((dent
= g_dir_read_name (dir
))) {
286 gint len
= strlen (dent
);
287 if (len
> SOEXT_LEN
&&
288 strcmp (dent
+ len
- SOEXT_LEN
, SOEXT
) == 0) {
289 query_module (path
, dent
);
295 g_printf ("# dynamic loading of modules not supported\n");
299 char *cwd
= g_get_current_dir ();
301 for (i
= 1; i
< argc
; i
++) {
302 char *infilename
= argv
[i
];
304 infilename
= g_locale_to_utf8 (infilename
,
305 -1, NULL
, NULL
, NULL
);
307 query_module (cwd
, infilename
);