Move the module cache files below libdir

These files contain architecture-dependent paths, and thus placing
them into sysconfdir causes unnecessary hassle. Now the immodule cache
file is looked for in libdir/gtk-3.0/3.0.0/immodules.cache, and the
pixbuf loader cache is looked for in libdir/gtk-3.0/3.0.0/loaders.cache.
This commit is contained in:
Matthias Clasen
2010-05-17 21:30:46 -04:00
parent 8a487aca2c
commit 0b0f176ac4
9 changed files with 1480 additions and 1469 deletions

View File

@ -35,6 +35,12 @@ If called without arguments, it looks for modules in the
If called with arguments, it looks for the specified modules. The arguments If called with arguments, it looks for the specified modules. The arguments
may be absolute or relative paths. may be absolute or relative paths.
</para> </para>
<para>
Normally, the output of <command>gdk-pixbuf-queryloaders-3.0</command> is written
to <filename><replaceable>libdir</replaceable>gtk-3.0/3.0.0/loaders.cache</filename>, where <application>gdk-pixbuf</application> looks for it by default. If it is written to some other
location, the environment variable <link linkend="GDK_PIXBUF_MODULE_FILE"><envar>GDK_PIXBUF_MODULE_FILE</envar></link>
can be set to point <application>gdk-pixbuf</application> at the file.
</para>
</refsect1> </refsect1>
<refsect1><title>Environment</title> <refsect1><title>Environment</title>

View File

@ -16,12 +16,12 @@ a #GdkPixbufModuleFillVtableFunc function named
<para> <para>
In order to make format-checking work before actually loading the modules In order to make format-checking work before actually loading the modules
(which may require dlopening image libraries), modules export their (which may require dlopening image libraries), modules export their
signatures (and other information) via the <function>fill_info</function> signatures (and other information) via the <function>fill_info</function>
function. An external utility, <command>gdk-pixbuf-query-loaders</command>, function. An external utility, <command>gdk-pixbuf-query-loaders-3.0</command>,
uses this to create a text file containing a list of all available loaders and uses this to create a text file containing a list of all available loaders and
their signatures. This file is then read at runtime by &gdk-pixbuf; to obtain their signatures. This file is then read at runtime by &gdk-pixbuf; to obtain
the list of available loaders and their signatures. the list of available loaders and their signatures.
</para> </para>
<para> <para>
@ -30,21 +30,21 @@ Modules may only implement a subset of the functionality available via
<function>fill_vtable</function> function will simply not set the corresponding <function>fill_vtable</function> function will simply not set the corresponding
function pointers of the #GdkPixbufModule structure. If a module supports function pointers of the #GdkPixbufModule structure. If a module supports
incremental loading (i.e. provides #begin_load, #stop_load and incremental loading (i.e. provides #begin_load, #stop_load and
#load_increment), it doesn't have to implement #load, since &gdk-pixbuf; can #load_increment), it doesn't have to implement #load, since &gdk-pixbuf; can
supply a generic #load implementation wrapping the incremental loading. supply a generic #load implementation wrapping the incremental loading.
</para> </para>
<para> <para>
Installing a module is a two-step process: Installing a module is a two-step process:
<itemizedlist> <itemizedlist>
<listitem><para>copy the module file(s) to the loader directory (normally <listitem><para>copy the module file(s) to the loader directory (normally
<filename><replaceable>libdir</replaceable>/gtk-2.0/<replaceable>version</replaceable>/loaders</filename>, <filename><replaceable>libdir</replaceable>/gtk-3.0/<replaceable>version</replaceable>/loaders</filename>,
unless overridden by the environment variable unless overridden by the environment variable
<envar>GDK_PIXBUF_MODULEDIR</envar>) <envar>GDK_PIXBUF_MODULEDIR</envar>)
</para></listitem> </para></listitem>
<listitem><para>call <command>gdk-pixbuf-query-loaders</command> to update the <listitem><para>call <command>gdk-pixbuf-query-loaders-3.0</command> to update the
module file (normally module file (normally
<filename><replaceable>sysconfdir</replaceable>/gtk-2.0/gdk-pixbuf.loaders</filename>, <filename><replaceable>libdir</replaceable>/gtk-3.0/<replaceable>version</replaceable>/loaders.cache</filename>,
unless overridden by the environment variable unless overridden by the environment variable
<envar>GDK_PIXBUF_MODULE_FILE</envar>) <envar>GDK_PIXBUF_MODULE_FILE</envar>)
</para></listitem> </para></listitem>
@ -52,11 +52,11 @@ unless overridden by the environment variable
</para> </para>
<para> <para>
The &gdk-pixbuf; interfaces needed for implementing modules are contained in The &gdk-pixbuf; interfaces needed for implementing modules are contained in
<filename>gdk-pixbuf-io.h</filename> (and <filename>gdk-pixbuf-io.h</filename> (and
<filename>gdk-pixbuf-animation.h</filename> if the module supports animations). <filename>gdk-pixbuf-animation.h</filename> if the module supports animations).
They are not covered by the same stability guarantees as the regular They are not covered by the same stability guarantees as the regular
&gdk-pixbuf; API. To underline this fact, they are protected by &gdk-pixbuf; API. To underline this fact, they are protected by
<literal>#ifdef GDK_PIXBUF_ENABLE_BACKEND</literal>. <literal>#ifdef GDK_PIXBUF_ENABLE_BACKEND</literal>.
</para> </para>
@ -188,7 +188,7 @@ use the <function>gdk_pixbuf_format_*</function> functions.
image format. image format.
@flags: a combination of #GdkPixbufFormatFlags. @flags: a combination of #GdkPixbufFormatFlags.
@disabled: a boolean determining whether the loader is disabled. @disabled: a boolean determining whether the loader is disabled.
@license: a string containing license information, typically set to @license: a string containing license information, typically set to
shorthands like "GPL", "LGPL", etc. shorthands like "GPL", "LGPL", etc.
@Since: 2.2 @Since: 2.2
@ -208,21 +208,21 @@ operations.
<!-- ##### STRUCT GdkPixbufModulePattern ##### --> <!-- ##### STRUCT GdkPixbufModulePattern ##### -->
<para> <para>
The signature of a module is a set of prefixes. Prefixes are encoded as The signature of a module is a set of prefixes. Prefixes are encoded as
pairs of ordinary strings, where the second string, called the mask, if pairs of ordinary strings, where the second string, called the mask, if
not %NULL, must be of the same length as the first one and may contain not %NULL, must be of the same length as the first one and may contain
' ', '!', 'x', 'z', and 'n' to indicate bytes that must be matched, ' ', '!', 'x', 'z', and 'n' to indicate bytes that must be matched,
not matched, "don't-care"-bytes, zeros and non-zeros. not matched, "don't-care"-bytes, zeros and non-zeros.
Each prefix has an associated integer that describes the relevance of Each prefix has an associated integer that describes the relevance of
the prefix, with 0 meaning a mismatch and 100 a "perfect match". the prefix, with 0 meaning a mismatch and 100 a "perfect match".
</para> </para>
<para> <para>
Starting with &gdk-pixbuf; 2.8, the first byte of the mask may be '*', Starting with &gdk-pixbuf; 2.8, the first byte of the mask may be '*',
indicating an unanchored pattern that matches not only at the beginning, indicating an unanchored pattern that matches not only at the beginning,
but also in the middle. Versions prior to 2.8 will interpret the '*' but also in the middle. Versions prior to 2.8 will interpret the '*'
like an 'x'. like an 'x'.
</para> </para>
<para> <para>
The signature of a module is stored as an array of The signature of a module is stored as an array of
#GdkPixbufModulePattern<!-- -->s. The array is terminated by a pattern #GdkPixbufModulePattern<!-- -->s. The array is terminated by a pattern
where the @prefix is %NULL. where the @prefix is %NULL.
</para> </para>
@ -234,7 +234,7 @@ GdkPixbufModulePattern *signature[] = {
{ NULL, NULL, 0 } { NULL, NULL, 0 }
}; };
</programlisting> </programlisting>
The example matches e.g. "auud\0" with relevance 100, and "blau" with The example matches e.g. "auud\0" with relevance 100, and "blau" with
relevance 90.</informalexample> relevance 90.</informalexample>
@prefix: the prefix for this pattern @prefix: the prefix for this pattern
@ -245,8 +245,8 @@ relevance 90.</informalexample>
<!-- ##### USER_FUNCTION GdkPixbufModuleFillVtableFunc ##### --> <!-- ##### USER_FUNCTION GdkPixbufModuleFillVtableFunc ##### -->
<para> <para>
Defines the type of the function used to set the vtable of a Defines the type of the function used to set the vtable of a
#GdkPixbufModule when it is loaded. #GdkPixbufModule when it is loaded.
</para> </para>
@module: a #GdkPixbufModule. @module: a #GdkPixbufModule.
@ -255,7 +255,7 @@ Defines the type of the function used to set the vtable of a
<!-- ##### USER_FUNCTION GdkPixbufModuleFillInfoFunc ##### --> <!-- ##### USER_FUNCTION GdkPixbufModuleFillInfoFunc ##### -->
<para> <para>
Defines the type of the function used to fill a Defines the type of the function used to fill a
#GdkPixbufFormat structure with information about a module. #GdkPixbufFormat structure with information about a module.
</para> </para>
@ -265,19 +265,19 @@ Defines the type of the function used to fill a
<!-- ##### USER_FUNCTION GdkPixbufModuleSizeFunc ##### --> <!-- ##### USER_FUNCTION GdkPixbufModuleSizeFunc ##### -->
<para> <para>
Defines the type of the function that gets called once the size Defines the type of the function that gets called once the size
of the loaded image is known. of the loaded image is known.
</para> </para>
<para> <para>
The function is expected to set @width and @height to the desired The function is expected to set @width and @height to the desired
size to which the image should be scaled. If a module has no efficient size to which the image should be scaled. If a module has no efficient
way to achieve the desired scaling during the loading of the image, it may way to achieve the desired scaling during the loading of the image, it may
either ignore the size request, or only approximate it -- &gdk-pixbuf; will either ignore the size request, or only approximate it -- &gdk-pixbuf; will
then perform the required scaling on the completely loaded image. then perform the required scaling on the completely loaded image.
</para> </para>
<para> <para>
If the function sets @width or @height to zero, the module should interpret If the function sets @width or @height to zero, the module should interpret
this as a hint that it will be closed soon and shouldn't allocate further this as a hint that it will be closed soon and shouldn't allocate further
resources. This convention is used to implement gdk_pixbuf_get_file_info() resources. This convention is used to implement gdk_pixbuf_get_file_info()
efficiently. efficiently.
</para> </para>
@ -290,11 +290,11 @@ efficiently.
<!-- ##### USER_FUNCTION GdkPixbufModulePreparedFunc ##### --> <!-- ##### USER_FUNCTION GdkPixbufModulePreparedFunc ##### -->
<para> <para>
Defines the type of the function that gets called once the initial Defines the type of the function that gets called once the initial
setup of @pixbuf is done. setup of @pixbuf is done.
</para> </para>
<para> <para>
#GdkPixbufLoader uses a function of this type to emit the #GdkPixbufLoader uses a function of this type to emit the
"<link linkend="GdkPixbufLoader-area-prepared">area_prepared</link>" "<link linkend="GdkPixbufLoader-area-prepared">area_prepared</link>"
signal. signal.
</para> </para>
@ -311,7 +311,7 @@ Defines the type of the function that gets called every time a region
of @pixbuf is updated. of @pixbuf is updated.
</para> </para>
<para> <para>
#GdkPixbufLoader uses a function of this type to emit the #GdkPixbufLoader uses a function of this type to emit the
"<link linkend="GdkPixbufLoader-area-updated">area_updated</link>" "<link linkend="GdkPixbufLoader-area-updated">area_updated</link>"
signal. signal.
</para> </para>
@ -327,14 +327,14 @@ signal.
<!-- ##### STRUCT GdkPixbufModule ##### --> <!-- ##### STRUCT GdkPixbufModule ##### -->
<para> <para>
A #GdkPixbufModule contains the necessary functions to load and save A #GdkPixbufModule contains the necessary functions to load and save
images in a certain file format. images in a certain file format.
</para> </para>
<para> <para>
A #GdkPixbufModule can be loaded dynamically from a #GModule. A #GdkPixbufModule can be loaded dynamically from a #GModule.
Each loadable module must contain a #GdkPixbufModuleFillVtableFunc function Each loadable module must contain a #GdkPixbufModuleFillVtableFunc function
named <function>fill_vtable</function>, which will get called when the module named <function>fill_vtable</function>, which will get called when the module
is loaded and must set the function pointers of the #GdkPixbufModule. is loaded and must set the function pointers of the #GdkPixbufModule.
</para> </para>
@module_name: the name of the module, usually the same as the @module_name: the name of the module, usually the same as the
@ -353,8 +353,8 @@ is loaded and must set the function pointers of the #GdkPixbufModule.
<!-- ##### STRUCT GdkPixbufAnimationClass ##### --> <!-- ##### STRUCT GdkPixbufAnimationClass ##### -->
<para> <para>
Modules supporting animations must derive a type from Modules supporting animations must derive a type from
#GdkPixbufAnimation, providing suitable implementations of the #GdkPixbufAnimation, providing suitable implementations of the
virtual functions. virtual functions.
</para> </para>
@ -366,17 +366,17 @@ virtual functions.
<!-- ##### STRUCT GdkPixbufAnimationIterClass ##### --> <!-- ##### STRUCT GdkPixbufAnimationIterClass ##### -->
<para> <para>
Modules supporting animations must derive a type from Modules supporting animations must derive a type from
#GdkPixbufAnimationIter, providing suitable implementations of the #GdkPixbufAnimationIter, providing suitable implementations of the
virtual functions. virtual functions.
</para> </para>
@parent_class: the parent class @parent_class: the parent class
@get_delay_time: returns the time in milliseconds that the current frame @get_delay_time: returns the time in milliseconds that the current frame
should be shown. should be shown.
@get_pixbuf: returns the current frame. @get_pixbuf: returns the current frame.
@on_currently_loading_frame: returns whether the current frame of @iter is @on_currently_loading_frame: returns whether the current frame of @iter is
being loaded. being loaded.
@advance: advances the iterator to @current_time, possibly changing the @advance: advances the iterator to @current_time, possibly changing the
current frame. current frame.

View File

@ -34,6 +34,12 @@ module path.
If called with arguments, it looks for the specified modules. The arguments If called with arguments, it looks for the specified modules. The arguments
may be absolute or relative paths. may be absolute or relative paths.
</para> </para>
<para>
Normally, the output of <command>gtk-query-immodules-3.0</command> is written
to <filename><replaceable>libdir</replaceable>gtk-3.0/3.0.0/immodules.cache</filename>, where GTK+ looks for it by default. If it is written to some other
location, the environment variable <link linkend="GTK_IM_MODULE_FILE"><envar>GTK_IM_MODULE_FILE</envar></link>
can be set to point GTK+ at the file.
</para>
</refsect1> </refsect1>
<refsect1><title>Environment</title> <refsect1><title>Environment</title>

View File

@ -262,9 +262,8 @@ additional environment variables.
Specifies the file listing the IM modules to load. This environment Specifies the file listing the IM modules to load. This environment
variable overrides the <literal>im_module_file</literal> specified in variable overrides the <literal>im_module_file</literal> specified in
the RC files, which in turn overrides the default value the RC files, which in turn overrides the default value
<filename><replaceable>sysconfdir</replaceable>/gtk-3.0/gtk.immodules</filename> <filename><replaceable>libdir</replaceable>/gtk-3.0/3.0.0/immodules.cache</filename>
(<replaceable>sysconfdir</replaceable> is the sysconfdir specified when GTK+ was configured, (<replaceable>libdir</replaceable> has the same meaning here as explained for <envar>GTK_PATH</envar>).
usually <filename>/usr/local/etc</filename>.)
</para> </para>
</formalpara> </formalpara>

View File

@ -509,7 +509,7 @@ INCLUDES = \
-I$(top_srcdir) -I$(top_builddir) \ -I$(top_srcdir) -I$(top_builddir) \
-I$(top_srcdir)/gdk-pixbuf \ -I$(top_srcdir)/gdk-pixbuf \
-I$(top_builddir)/gdk-pixbuf \ -I$(top_builddir)/gdk-pixbuf \
-DGTK_SYSCONFDIR=\"$(sysconfdir)\" \ -DGTK_LIBDIR=\"$(libdir)\" \
-DGTK_VERSION=\"$(GTK_VERSION)\" \ -DGTK_VERSION=\"$(GTK_VERSION)\" \
-DGTK_BINARY_VERSION=\"$(GTK_BINARY_VERSION)\" \ -DGTK_BINARY_VERSION=\"$(GTK_BINARY_VERSION)\" \
-DGTK_PREFIX=\"$(prefix)\" \ -DGTK_PREFIX=\"$(prefix)\" \

File diff suppressed because it is too large Load Diff

View File

@ -3,7 +3,7 @@
* queryloaders.c: * queryloaders.c:
* *
* Copyright (C) 2002 The Free Software Foundation * Copyright (C) 2002 The Free Software Foundation
* *
* Author: Matthias Clasen <maclas@gmx.de> * Author: Matthias Clasen <maclas@gmx.de>
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
@ -13,7 +13,7 @@
* *
* This library is distributed in the hope that it will be useful, * This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details. * Library General Public License for more details.
* *
* You should have received a copy of the GNU Library General Public * You should have received a copy of the GNU Library General Public
@ -52,276 +52,276 @@
static void static void
print_escaped (const char *str) print_escaped (const char *str)
{ {
gchar *tmp = g_strescape (str, ""); gchar *tmp = g_strescape (str, "");
g_printf ("\"%s\" ", tmp); g_printf ("\"%s\" ", tmp);
g_free (tmp); g_free (tmp);
} }
static int static int
loader_sanity_check (const char *path, GdkPixbufFormat *info, GdkPixbufModule *vtable) loader_sanity_check (const char *path, GdkPixbufFormat *info, GdkPixbufModule *vtable)
{ {
const GdkPixbufModulePattern *pattern; const GdkPixbufModulePattern *pattern;
const char *error = ""; const char *error = "";
for (pattern = info->signature; pattern->prefix; pattern++) for (pattern = info->signature; pattern->prefix; pattern++)
{ {
int prefix_len = strlen (pattern->prefix); int prefix_len = strlen (pattern->prefix);
if (prefix_len == 0) if (prefix_len == 0)
{ {
error = "empty pattern"; error = "empty pattern";
goto error; goto error;
} }
if (pattern->mask) if (pattern->mask)
{ {
int mask_len = strlen (pattern->mask); int mask_len = strlen (pattern->mask);
if (mask_len != prefix_len) if (mask_len != prefix_len)
{ {
error = "mask length mismatch"; error = "mask length mismatch";
goto error; goto error;
} }
if (strspn (pattern->mask, " !xzn*") < mask_len) if (strspn (pattern->mask, " !xzn*") < mask_len)
{ {
error = "bad char in mask"; error = "bad char in mask";
goto error; goto error;
} }
} }
} }
if (!vtable->load && !vtable->begin_load && !vtable->load_animation) if (!vtable->load && !vtable->begin_load && !vtable->load_animation)
{ {
error = "no load method implemented"; error = "no load method implemented";
goto error; goto error;
} }
if (vtable->begin_load && (!vtable->stop_load || !vtable->load_increment)) if (vtable->begin_load && (!vtable->stop_load || !vtable->load_increment))
{ {
error = "incremental loading support incomplete"; error = "incremental loading support incomplete";
goto error; goto error;
} }
if ((info->flags & GDK_PIXBUF_FORMAT_WRITABLE) && !(vtable->save || vtable->save_to_callback)) if ((info->flags & GDK_PIXBUF_FORMAT_WRITABLE) && !(vtable->save || vtable->save_to_callback))
{ {
error = "loader claims to support saving but doesn't implement save"; error = "loader claims to support saving but doesn't implement save";
goto error; goto error;
} }
return 1; return 1;
error: error:
g_fprintf (stderr, "Loader sanity check failed for %s: %s\n", g_fprintf (stderr, "Loader sanity check failed for %s: %s\n",
path, error); path, error);
return 0; return 0;
} }
static void static void
write_loader_info (const char *path, GdkPixbufFormat *info) write_loader_info (const char *path, GdkPixbufFormat *info)
{ {
const GdkPixbufModulePattern *pattern; const GdkPixbufModulePattern *pattern;
char **mime; char **mime;
char **ext; char **ext;
g_printf("\"%s\"\n", path); g_printf("\"%s\"\n", path);
g_printf ("\"%s\" %u \"%s\" \"%s\" \"%s\"\n", g_printf ("\"%s\" %u \"%s\" \"%s\" \"%s\"\n",
info->name, info->name,
info->flags, info->flags,
info->domain ? info->domain : GETTEXT_PACKAGE, info->domain ? info->domain : GETTEXT_PACKAGE,
info->description, info->description,
info->license ? info->license : ""); info->license ? info->license : "");
for (mime = info->mime_types; *mime; mime++) { for (mime = info->mime_types; *mime; mime++) {
g_printf ("\"%s\" ", *mime); g_printf ("\"%s\" ", *mime);
} }
g_printf ("\"\"\n"); g_printf ("\"\"\n");
for (ext = info->extensions; *ext; ext++) { for (ext = info->extensions; *ext; ext++) {
g_printf ("\"%s\" ", *ext); g_printf ("\"%s\" ", *ext);
} }
g_printf ("\"\"\n"); g_printf ("\"\"\n");
for (pattern = info->signature; pattern->prefix; pattern++) { for (pattern = info->signature; pattern->prefix; pattern++) {
print_escaped (pattern->prefix); print_escaped (pattern->prefix);
print_escaped (pattern->mask ? (const char *)pattern->mask : ""); print_escaped (pattern->mask ? (const char *)pattern->mask : "");
g_printf ("%d\n", pattern->relevance); g_printf ("%d\n", pattern->relevance);
} }
g_printf ("\n"); g_printf ("\n");
} }
static void static void
query_module (const char *dir, const char *file) query_module (const char *dir, const char *file)
{ {
char *path; char *path;
GModule *module; GModule *module;
void (*fill_info) (GdkPixbufFormat *info); void (*fill_info) (GdkPixbufFormat *info);
void (*fill_vtable) (GdkPixbufModule *module); void (*fill_vtable) (GdkPixbufModule *module);
gpointer fill_info_ptr; gpointer fill_info_ptr;
gpointer fill_vtable_ptr; gpointer fill_vtable_ptr;
if (g_path_is_absolute (file)) if (g_path_is_absolute (file))
path = g_strdup (file); path = g_strdup (file);
else else
path = g_build_filename (dir, file, NULL); path = g_build_filename (dir, file, NULL);
module = g_module_open (path, 0); module = g_module_open (path, 0);
if (module && if (module &&
g_module_symbol (module, "fill_info", &fill_info_ptr) && g_module_symbol (module, "fill_info", &fill_info_ptr) &&
g_module_symbol (module, "fill_vtable", &fill_vtable_ptr)) { g_module_symbol (module, "fill_vtable", &fill_vtable_ptr)) {
GdkPixbufFormat *info; GdkPixbufFormat *info;
GdkPixbufModule *vtable; GdkPixbufModule *vtable;
#ifdef G_OS_WIN32 #ifdef G_OS_WIN32
/* Replace backslashes in path with forward slashes, so that /* Replace backslashes in path with forward slashes, so that
* it reads in without problems. * it reads in without problems.
*/ */
{ {
char *p = path; char *p = path;
while (*p) { while (*p) {
if (*p == '\\') if (*p == '\\')
*p = '/'; *p = '/';
p++; p++;
} }
} }
#endif #endif
info = g_new0 (GdkPixbufFormat, 1); info = g_new0 (GdkPixbufFormat, 1);
vtable = g_new0 (GdkPixbufModule, 1); vtable = g_new0 (GdkPixbufModule, 1);
vtable->module = module; vtable->module = module;
fill_info = fill_info_ptr; fill_info = fill_info_ptr;
fill_vtable = fill_vtable_ptr; fill_vtable = fill_vtable_ptr;
(*fill_info) (info); (*fill_info) (info);
(*fill_vtable) (vtable); (*fill_vtable) (vtable);
if (loader_sanity_check (path, info, vtable)) if (loader_sanity_check (path, info, vtable))
write_loader_info (path, info); write_loader_info (path, info);
g_free (info); g_free (info);
g_free (vtable); g_free (vtable);
} }
else { else {
if (module == NULL) if (module == NULL)
g_fprintf (stderr, "g_module_open() failed for %s: %s\n", path, g_fprintf (stderr, "g_module_open() failed for %s: %s\n", path,
g_module_error()); g_module_error());
else else
g_fprintf (stderr, "Cannot load loader %s\n", path); g_fprintf (stderr, "Cannot load loader %s\n", path);
} }
if (module) if (module)
g_module_close (module); g_module_close (module);
g_free (path); g_free (path);
} }
int main (int argc, char **argv) int main (int argc, char **argv)
{ {
gint i; gint i;
gchar *prgname; gchar *prgname;
#ifdef G_OS_WIN32 #ifdef G_OS_WIN32
gchar *libdir; gchar *libdir;
gchar *runtime_prefix; gchar *runtime_prefix;
gchar *slash; gchar *slash;
if (g_ascii_strncasecmp (PIXBUF_LIBDIR, GTK_PREFIX, strlen (GTK_PREFIX)) == 0 && if (g_ascii_strncasecmp (PIXBUF_LIBDIR, GTK_PREFIX, strlen (GTK_PREFIX)) == 0 &&
G_IS_DIR_SEPARATOR (PIXBUF_LIBDIR[strlen (GTK_PREFIX)])) { G_IS_DIR_SEPARATOR (PIXBUF_LIBDIR[strlen (GTK_PREFIX)])) {
/* GTK_PREFIX is a prefix of PIXBUF_LIBDIR, as it /* GTK_PREFIX is a prefix of PIXBUF_LIBDIR, as it
* normally is. Replace that prefix in PIXBUF_LIBDIR * normally is. Replace that prefix in PIXBUF_LIBDIR
* with the installation directory on this machine. * with the installation directory on this machine.
* We assume this invokation of * We assume this invokation of
* gdk-pixbuf-query-loaders is run from either a "bin" * gdk-pixbuf-query-loaders is run from either a "bin"
* subdirectory of the installation directory, or in * subdirectory of the installation directory, or in
* the installation directory itself. * the installation directory itself.
*/ */
wchar_t fn[1000]; wchar_t fn[1000];
GetModuleFileNameW (NULL, fn, G_N_ELEMENTS (fn)); GetModuleFileNameW (NULL, fn, G_N_ELEMENTS (fn));
runtime_prefix = g_utf16_to_utf8 (fn, -1, NULL, NULL, NULL); runtime_prefix = g_utf16_to_utf8 (fn, -1, NULL, NULL, NULL);
slash = strrchr (runtime_prefix, '\\'); slash = strrchr (runtime_prefix, '\\');
*slash = '\0'; *slash = '\0';
slash = strrchr (runtime_prefix, '\\'); slash = strrchr (runtime_prefix, '\\');
/* If running from some weird location, or from the /* If running from some weird location, or from the
* build directory (either in the .libs folder where * build directory (either in the .libs folder where
* libtool places the real executable when using a * libtool places the real executable when using a
* wrapper, or directly from the gdk-pixbuf folder), * wrapper, or directly from the gdk-pixbuf folder),
* use the compile-time libdir. * use the compile-time libdir.
*/ */
if (slash == NULL || if (slash == NULL ||
g_ascii_strcasecmp (slash + 1, ".libs") == 0 || g_ascii_strcasecmp (slash + 1, ".libs") == 0 ||
g_ascii_strcasecmp (slash + 1, "gdk-pixbuf") == 0) { g_ascii_strcasecmp (slash + 1, "gdk-pixbuf") == 0) {
libdir = PIXBUF_LIBDIR; libdir = PIXBUF_LIBDIR;
} }
else { else {
if (slash != NULL && g_ascii_strcasecmp (slash + 1, "bin") == 0) { if (slash != NULL && g_ascii_strcasecmp (slash + 1, "bin") == 0) {
*slash = '\0'; *slash = '\0';
} }
libdir = g_strconcat (runtime_prefix, libdir = g_strconcat (runtime_prefix,
"/", "/",
PIXBUF_LIBDIR + strlen (GTK_PREFIX) + 1, PIXBUF_LIBDIR + strlen (GTK_PREFIX) + 1,
NULL); NULL);
} }
} }
else { else {
libdir = PIXBUF_LIBDIR; libdir = PIXBUF_LIBDIR;
} }
#undef PIXBUF_LIBDIR #undef PIXBUF_LIBDIR
#define PIXBUF_LIBDIR libdir #define PIXBUF_LIBDIR libdir
#endif #endif
prgname = g_get_prgname (); prgname = g_get_prgname ();
g_printf ("# GdkPixbuf Image Loader Modules file\n" g_printf ("# GdkPixbuf Image Loader Modules file\n"
"# Automatically generated file, do not edit\n" "# Automatically generated file, do not edit\n"
"# Created by %s from gtk+-%s\n" "# Created by %s from gtk+-%s\n"
"#\n", "#\n",
(prgname ? prgname : "gdk-pixbuf-query-loaders-3.0"), (prgname ? prgname : "gdk-pixbuf-query-loaders-3.0"),
GDK_PIXBUF_VERSION); GDK_PIXBUF_VERSION);
if (argc == 1) { if (argc == 1) {
#ifdef USE_GMODULE #ifdef USE_GMODULE
const char *path; const char *path;
GDir *dir; GDir *dir;
path = g_getenv ("GDK_PIXBUF_MODULEDIR"); path = g_getenv ("GDK_PIXBUF_MODULEDIR");
#ifdef G_OS_WIN32 #ifdef G_OS_WIN32
if (path != NULL && *path != '\0') if (path != NULL && *path != '\0')
path = g_locale_to_utf8 (path, -1, NULL, NULL, NULL); path = g_locale_to_utf8 (path, -1, NULL, NULL, NULL);
#endif #endif
if (path == NULL || *path == '\0') if (path == NULL || *path == '\0')
path = PIXBUF_LIBDIR; path = PIXBUF_LIBDIR;
g_printf ("# LoaderDir = %s\n#\n", path); g_printf ("# LoaderDir = %s\n#\n", path);
dir = g_dir_open (path, 0, NULL); dir = g_dir_open (path, 0, NULL);
if (dir) { if (dir) {
const char *dent; const char *dent;
while ((dent = g_dir_read_name (dir))) { while ((dent = g_dir_read_name (dir))) {
gint len = strlen (dent); gint len = strlen (dent);
if (len > SOEXT_LEN && if (len > SOEXT_LEN &&
strcmp (dent + len - SOEXT_LEN, SOEXT) == 0) { strcmp (dent + len - SOEXT_LEN, SOEXT) == 0) {
query_module (path, dent); query_module (path, dent);
} }
} }
g_dir_close (dir); g_dir_close (dir);
} }
#else #else
g_printf ("# dynamic loading of modules not supported\n"); g_printf ("# dynamic loading of modules not supported\n");
#endif #endif
} }
else { else {
char *cwd = g_get_current_dir (); char *cwd = g_get_current_dir ();
for (i = 1; i < argc; i++) { for (i = 1; i < argc; i++) {
char *infilename = argv[i]; char *infilename = argv[i];
#ifdef G_OS_WIN32 #ifdef G_OS_WIN32
infilename = g_locale_to_utf8 (infilename, infilename = g_locale_to_utf8 (infilename,
-1, NULL, NULL, NULL); -1, NULL, NULL, NULL);
#endif #endif
query_module (cwd, infilename); query_module (cwd, infilename);
} }
g_free (cwd); g_free (cwd);
} }
return 0; return 0;
} }

View File

@ -450,9 +450,9 @@ gtk_rc_get_im_module_file (void)
if (!result) if (!result)
{ {
if (im_module_file) if (im_module_file)
result = g_strdup (im_module_file); result = g_strdup (im_module_file);
else else
result = g_build_filename (GTK_SYSCONFDIR, "gtk-3.0", "gtk.immodules", NULL); result = gtk_rc_make_default_dir ("immodules.cache");
} }
return result; return result;

View File

@ -1,7 +1,7 @@
/* GTK+ /* GTK+
* querymodules.c: * querymodules.c:
* *
* Copyright (C) 2000 Red Hat Software * Copyright (C) 2000-2010 Red Hat Software
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public * modify it under the terms of the GNU Library General Public
@ -10,7 +10,7 @@
* *
* This library is distributed in the hope that it will be useful, * This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details. * Library General Public License for more details.
* *
* You should have received a copy of the GNU Library General Public * You should have received a copy of the GNU Library General Public
@ -49,28 +49,28 @@ escape_string (const char *str)
while (TRUE) while (TRUE)
{ {
char c = *str++; char c = *str++;
switch (c) switch (c)
{ {
case '\0': case '\0':
goto done; goto done;
case '\n': case '\n':
g_string_append (result, "\\n"); g_string_append (result, "\\n");
break; break;
case '\"': case '\"':
g_string_append (result, "\\\""); g_string_append (result, "\\\"");
break; break;
#ifdef G_OS_WIN32 #ifdef G_OS_WIN32
/* Replace backslashes in path with forward slashes, so that /* Replace backslashes in path with forward slashes, so that
* it reads in without problems. * it reads in without problems.
*/ */
case '\\': case '\\':
g_string_append (result, "/"); g_string_append (result, "/");
break; break;
#endif #endif
default: default:
g_string_append_c (result, c); g_string_append_c (result, c);
} }
} }
done: done:
@ -89,7 +89,7 @@ static gboolean
query_module (const char *dir, const char *name) query_module (const char *dir, const char *name)
{ {
void (*list) (const GtkIMContextInfo ***contexts, void (*list) (const GtkIMContextInfo ***contexts,
guint *n_contexts); guint *n_contexts);
void (*init) (GTypeModule *type_module); void (*init) (GTypeModule *type_module);
void (*exit) (void); void (*exit) (void);
GtkIMContext *(*create) (const gchar *context_id); GtkIMContext *(*create) (const gchar *context_id);
@ -107,7 +107,7 @@ query_module (const char *dir, const char *name)
path = g_strdup (name); path = g_strdup (name);
else else
path = g_build_filename (dir, name, NULL); path = g_build_filename (dir, name, NULL);
module = g_module_open (path, 0); module = g_module_open (path, 0);
if (!module) if (!module)
@ -115,7 +115,7 @@ query_module (const char *dir, const char *name)
g_fprintf (stderr, "Cannot load module %s: %s\n", path, g_module_error()); g_fprintf (stderr, "Cannot load module %s: %s\n", path, g_module_error());
error = TRUE; error = TRUE;
} }
if (module && if (module &&
g_module_symbol (module, "im_module_list", &list_ptr) && g_module_symbol (module, "im_module_list", &list_ptr) &&
g_module_symbol (module, "im_module_init", &init_ptr) && g_module_symbol (module, "im_module_init", &init_ptr) &&
@ -137,20 +137,20 @@ query_module (const char *dir, const char *name)
(*list) (&contexts, &n_contexts); (*list) (&contexts, &n_contexts);
for (i=0; i<n_contexts; i++) for (i=0; i<n_contexts; i++)
{ {
print_escaped (contexts[i]->context_id); print_escaped (contexts[i]->context_id);
print_escaped (contexts[i]->context_name); print_escaped (contexts[i]->context_name);
print_escaped (contexts[i]->domain); print_escaped (contexts[i]->domain);
print_escaped (contexts[i]->domain_dirname); print_escaped (contexts[i]->domain_dirname);
print_escaped (contexts[i]->default_locales); print_escaped (contexts[i]->default_locales);
fputs ("\n", stdout); fputs ("\n", stdout);
} }
fputs ("\n", stdout); fputs ("\n", stdout);
} }
else else
{ {
g_fprintf (stderr, "%s does not export GTK+ IM module API: %s\n", path, g_fprintf (stderr, "%s does not export GTK+ IM module API: %s\n", path,
g_module_error ()); g_module_error ());
error = TRUE; error = TRUE;
} }
@ -159,7 +159,7 @@ query_module (const char *dir, const char *name)
g_module_close (module); g_module_close (module);
return error; return error;
} }
int main (int argc, char **argv) int main (int argc, char **argv)
{ {
@ -169,14 +169,14 @@ int main (int argc, char **argv)
gboolean error = FALSE; gboolean error = FALSE;
g_printf ("# GTK+ Input Method Modules file\n" g_printf ("# GTK+ Input Method Modules file\n"
"# Automatically generated file, do not edit\n" "# Automatically generated file, do not edit\n"
"# Created by %s from gtk+-%d.%d.%d\n" "# Created by %s from gtk+-%d.%d.%d\n"
"#\n", "#\n",
argv[0], argv[0],
GTK_MAJOR_VERSION, GTK_MINOR_VERSION, GTK_MICRO_VERSION); GTK_MAJOR_VERSION, GTK_MINOR_VERSION, GTK_MICRO_VERSION);
if (argc == 1) /* No arguments given */ if (argc == 1) /* No arguments given */
{ {
char **dirs; char **dirs;
int i; int i;
@ -189,22 +189,22 @@ int main (int argc, char **argv)
dirs = pango_split_file_list (path); dirs = pango_split_file_list (path);
dirs_done = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, NULL); dirs_done = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, NULL);
for (i=0; dirs[i]; i++) for (i = 0; dirs[i]; i++)
if (!g_hash_table_lookup (dirs_done, dirs[i])) if (!g_hash_table_lookup (dirs_done, dirs[i]))
{ {
GDir *dir = g_dir_open (dirs[i], 0, NULL); GDir *dir = g_dir_open (dirs[i], 0, NULL);
if (dir) if (dir)
{ {
const char *dent; const char *dent;
while ((dent = g_dir_read_name (dir))) while ((dent = g_dir_read_name (dir)))
{ {
if (g_str_has_suffix (dent, SOEXT)) if (g_str_has_suffix (dent, SOEXT))
error |= query_module (dirs[i], dent); error |= query_module (dirs[i], dent);
} }
g_dir_close (dir); g_dir_close (dir);
} }
g_hash_table_insert (dirs_done, dirs[i], GUINT_TO_POINTER (TRUE)); g_hash_table_insert (dirs_done, dirs[i], GUINT_TO_POINTER (TRUE));
} }
@ -214,12 +214,12 @@ int main (int argc, char **argv)
else else
{ {
cwd = g_get_current_dir (); cwd = g_get_current_dir ();
for (i=1; i<argc; i++) for (i = 1; i < argc; i++)
error |= query_module (cwd, argv[i]); error |= query_module (cwd, argv[i]);
g_free (cwd); g_free (cwd);
} }
return error ? 1 : 0; return error ? 1 : 0;
} }