1 /* LIBGIMP - The GIMP Library
2 * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
5 * (C) 1999 Austin Donnelly <austin@gimp.org>
7 * This library is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 3 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library. If not, see
19 * <https://www.gnu.org/licenses/>.
28 #include "libgimpbase/gimpbase.h"
30 #include "gimpmodule.h"
32 #include "libgimp/libgimp-intl.h"
38 * @short_description: A #GTypeModule subclass which implements module
39 * loading using #GModule.
40 * @see_also: #GModule, #GTypeModule
42 * A #GTypeModule subclass which implements module loading using #GModule.
53 static void gimp_module_finalize (GObject
*object
);
55 static gboolean
gimp_module_load (GTypeModule
*module
);
56 static void gimp_module_unload (GTypeModule
*module
);
58 static gboolean
gimp_module_open (GimpModule
*module
);
59 static gboolean
gimp_module_close (GimpModule
*module
);
60 static void gimp_module_set_last_error (GimpModule
*module
,
61 const gchar
*error_str
);
64 G_DEFINE_TYPE (GimpModule
, gimp_module
, G_TYPE_TYPE_MODULE
)
66 #define parent_class gimp_module_parent_class
68 static guint module_signals
[LAST_SIGNAL
];
72 gimp_module_class_init (GimpModuleClass
*klass
)
74 GObjectClass
*object_class
= G_OBJECT_CLASS (klass
);
75 GTypeModuleClass
*module_class
= G_TYPE_MODULE_CLASS (klass
);
77 module_signals
[MODIFIED
] =
78 g_signal_new ("modified",
79 G_TYPE_FROM_CLASS (klass
),
81 G_STRUCT_OFFSET (GimpModuleClass
, modified
),
83 g_cclosure_marshal_VOID__VOID
,
86 object_class
->finalize
= gimp_module_finalize
;
88 module_class
->load
= gimp_module_load
;
89 module_class
->unload
= gimp_module_unload
;
91 klass
->modified
= NULL
;
95 gimp_module_init (GimpModule
*module
)
97 module
->filename
= NULL
;
98 module
->verbose
= FALSE
;
99 module
->state
= GIMP_MODULE_STATE_ERROR
;
100 module
->on_disk
= FALSE
;
101 module
->load_inhibit
= FALSE
;
103 module
->module
= NULL
;
105 module
->last_module_error
= NULL
;
107 module
->query_module
= NULL
;
108 module
->register_module
= NULL
;
112 gimp_module_finalize (GObject
*object
)
114 GimpModule
*module
= GIMP_MODULE (object
);
118 gimp_module_info_free (module
->info
);
122 if (module
->last_module_error
)
124 g_free (module
->last_module_error
);
125 module
->last_module_error
= NULL
;
128 if (module
->filename
)
130 g_free (module
->filename
);
131 module
->filename
= NULL
;
134 G_OBJECT_CLASS (parent_class
)->finalize (object
);
138 gimp_module_load (GTypeModule
*module
)
140 GimpModule
*gimp_module
= GIMP_MODULE (module
);
143 g_return_val_if_fail (gimp_module
->filename
!= NULL
, FALSE
);
144 g_return_val_if_fail (gimp_module
->module
== NULL
, FALSE
);
146 if (gimp_module
->verbose
)
147 g_print ("Loading module '%s'\n",
148 gimp_filename_to_utf8 (gimp_module
->filename
));
150 if (! gimp_module_open (gimp_module
))
153 if (! gimp_module_query_module (gimp_module
))
156 /* find the gimp_module_register symbol */
157 if (! g_module_symbol (gimp_module
->module
, "gimp_module_register", &func
))
159 gimp_module_set_last_error (gimp_module
,
160 "Missing gimp_module_register() symbol");
162 g_message (_("Module '%s' load error: %s"),
163 gimp_filename_to_utf8 (gimp_module
->filename
),
164 gimp_module
->last_module_error
);
166 gimp_module_close (gimp_module
);
168 gimp_module
->state
= GIMP_MODULE_STATE_ERROR
;
173 gimp_module
->register_module
= func
;
175 if (! gimp_module
->register_module (module
))
177 gimp_module_set_last_error (gimp_module
,
178 "gimp_module_register() returned FALSE");
180 g_message (_("Module '%s' load error: %s"),
181 gimp_filename_to_utf8 (gimp_module
->filename
),
182 gimp_module
->last_module_error
);
184 gimp_module_close (gimp_module
);
186 gimp_module
->state
= GIMP_MODULE_STATE_LOAD_FAILED
;
191 gimp_module
->state
= GIMP_MODULE_STATE_LOADED
;
197 gimp_module_unload (GTypeModule
*module
)
199 GimpModule
*gimp_module
= GIMP_MODULE (module
);
201 g_return_if_fail (gimp_module
->module
!= NULL
);
203 if (gimp_module
->verbose
)
204 g_print ("Unloading module '%s'\n",
205 gimp_filename_to_utf8 (gimp_module
->filename
));
207 gimp_module_close (gimp_module
);
211 /* public functions */
215 * @filename: The filename of a loadable module.
216 * @load_inhibit: Pass %TRUE to exclude this module from auto-loading.
217 * @verbose: Pass %TRUE to enable debugging output.
219 * Creates a new #GimpModule instance.
221 * Return value: The new #GimpModule object.
224 gimp_module_new (const gchar
*filename
,
225 gboolean load_inhibit
,
230 g_return_val_if_fail (filename
!= NULL
, NULL
);
232 module
= g_object_new (GIMP_TYPE_MODULE
, NULL
);
234 module
->filename
= g_strdup (filename
);
235 module
->load_inhibit
= load_inhibit
? TRUE
: FALSE
;
236 module
->verbose
= verbose
? TRUE
: FALSE
;
237 module
->on_disk
= TRUE
;
239 if (! module
->load_inhibit
)
241 if (gimp_module_load (G_TYPE_MODULE (module
)))
242 gimp_module_unload (G_TYPE_MODULE (module
));
247 g_print ("Skipping module '%s'\n",
248 gimp_filename_to_utf8 (filename
));
250 module
->state
= GIMP_MODULE_STATE_NOT_LOADED
;
257 * gimp_module_query_module:
258 * @module: A #GimpModule.
260 * Queries the module without actually registering any of the types it
261 * may implement. After successful query, the @info field of the
262 * #GimpModule struct will be available for further inspection.
264 * Return value: %TRUE on success.
267 gimp_module_query_module (GimpModule
*module
)
269 const GimpModuleInfo
*info
;
270 gboolean close_module
= FALSE
;
273 g_return_val_if_fail (GIMP_IS_MODULE (module
), FALSE
);
275 if (! module
->module
)
277 if (! gimp_module_open (module
))
283 /* find the gimp_module_query symbol */
284 if (! g_module_symbol (module
->module
, "gimp_module_query", &func
))
286 gimp_module_set_last_error (module
,
287 "Missing gimp_module_query() symbol");
289 g_message (_("Module '%s' load error: %s"),
290 gimp_filename_to_utf8 (module
->filename
),
291 module
->last_module_error
);
293 gimp_module_close (module
);
295 module
->state
= GIMP_MODULE_STATE_ERROR
;
299 module
->query_module
= func
;
303 gimp_module_info_free (module
->info
);
307 info
= module
->query_module (G_TYPE_MODULE (module
));
309 if (! info
|| info
->abi_version
!= GIMP_MODULE_ABI_VERSION
)
311 gimp_module_set_last_error (module
,
313 "module ABI version does not match" :
314 "gimp_module_query() returned NULL");
316 g_message (_("Module '%s' load error: %s"),
317 gimp_filename_to_utf8 (module
->filename
),
318 module
->last_module_error
);
320 gimp_module_close (module
);
322 module
->state
= GIMP_MODULE_STATE_ERROR
;
326 module
->info
= gimp_module_info_copy (info
);
329 return gimp_module_close (module
);
335 * gimp_module_modified:
336 * @module: A #GimpModule.
338 * Emits the "modified" signal. Call it whenever you have modified the module
339 * manually (which you shouldn't do).
342 gimp_module_modified (GimpModule
*module
)
344 g_return_if_fail (GIMP_IS_MODULE (module
));
346 g_signal_emit (module
, module_signals
[MODIFIED
], 0);
350 * gimp_module_set_load_inhibit:
351 * @module: A #GimpModule.
352 * @load_inhibit: Pass %TRUE to exclude this module from auto-loading.
354 * Sets the @load_inhibit property if the module. Emits "modified".
357 gimp_module_set_load_inhibit (GimpModule
*module
,
358 gboolean load_inhibit
)
360 g_return_if_fail (GIMP_IS_MODULE (module
));
362 if (load_inhibit
!= module
->load_inhibit
)
364 module
->load_inhibit
= load_inhibit
? TRUE
: FALSE
;
366 gimp_module_modified (module
);
371 * gimp_module_state_name:
372 * @state: A #GimpModuleState.
374 * Returns the translated textual representation of a #GimpModuleState.
375 * The returned string must not be freed.
377 * Return value: The @state's name.
380 gimp_module_state_name (GimpModuleState state
)
382 static const gchar
* const statenames
[] =
390 g_return_val_if_fail (state
>= GIMP_MODULE_STATE_ERROR
&&
391 state
<= GIMP_MODULE_STATE_NOT_LOADED
, NULL
);
393 return gettext (statenames
[state
]);
397 * gimp_module_error_quark:
399 * This function is never called directly. Use GIMP_MODULE_ERROR() instead.
401 * Return value: the #GQuark that defines the GIMP module error domain.
406 gimp_module_error_quark (void)
408 return g_quark_from_static_string ("gimp-module-error-quark");
412 /* private functions */
415 gimp_module_open (GimpModule
*module
)
417 module
->module
= g_module_open (module
->filename
, 0);
419 if (! module
->module
)
421 module
->state
= GIMP_MODULE_STATE_ERROR
;
422 gimp_module_set_last_error (module
, g_module_error ());
424 g_message (_("Module '%s' load error: %s"),
425 gimp_filename_to_utf8 (module
->filename
),
426 module
->last_module_error
);
435 gimp_module_close (GimpModule
*module
)
437 g_module_close (module
->module
); /* FIXME: error handling */
438 module
->module
= NULL
;
439 module
->query_module
= NULL
;
440 module
->register_module
= NULL
;
442 module
->state
= GIMP_MODULE_STATE_NOT_LOADED
;
448 gimp_module_set_last_error (GimpModule
*module
,
449 const gchar
*error_str
)
451 if (module
->last_module_error
)
452 g_free (module
->last_module_error
);
454 module
->last_module_error
= g_strdup (error_str
);
458 /* GimpModuleInfo functions */
461 * gimp_module_info_new:
462 * @abi_version: The #GIMP_MODULE_ABI_VERSION the module was compiled against.
463 * @purpose: The module's general purpose.
464 * @author: The module's author.
465 * @version: The module's version.
466 * @copyright: The module's copyright.
467 * @date: The module's release date.
469 * Creates a newly allocated #GimpModuleInfo struct.
471 * Return value: The new #GimpModuleInfo struct.
474 gimp_module_info_new (guint32 abi_version
,
475 const gchar
*purpose
,
477 const gchar
*version
,
478 const gchar
*copyright
,
481 GimpModuleInfo
*info
= g_slice_new0 (GimpModuleInfo
);
483 info
->abi_version
= abi_version
;
484 info
->purpose
= g_strdup (purpose
);
485 info
->author
= g_strdup (author
);
486 info
->version
= g_strdup (version
);
487 info
->copyright
= g_strdup (copyright
);
488 info
->date
= g_strdup (date
);
494 * gimp_module_info_copy:
495 * @info: The #GimpModuleInfo struct to copy.
497 * Copies a #GimpModuleInfo struct.
499 * Return value: The new copy.
502 gimp_module_info_copy (const GimpModuleInfo
*info
)
504 g_return_val_if_fail (info
!= NULL
, NULL
);
506 return gimp_module_info_new (info
->abi_version
,
515 * gimp_module_info_free:
516 * @info: The #GimpModuleInfo struct to free
518 * Frees the passed #GimpModuleInfo.
521 gimp_module_info_free (GimpModuleInfo
*info
)
523 g_return_if_fail (info
!= NULL
);
525 g_free (info
->purpose
);
526 g_free (info
->author
);
527 g_free (info
->version
);
528 g_free (info
->copyright
);
531 g_slice_free (GimpModuleInfo
, info
);