app: s/sprintf/g_snprintf/ in xcf_save_image()
[gimp.git] / libgimpmodule / gimpmodule.c
blobc6aa566ff08ad433e22b028e3df27432852efe63
1 /* LIBGIMP - The GIMP Library
2 * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
4 * gimpmodule.c
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/>.
22 #include "config.h"
24 #include <string.h>
26 #include <gio/gio.h>
28 #include "libgimpbase/gimpbase.h"
30 #include "gimpmodule.h"
32 #include "libgimp/libgimp-intl.h"
35 /**
36 * SECTION: gimpmodule
37 * @title: GimpModule
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.
43 **/
46 enum
48 MODIFIED,
49 LAST_SIGNAL
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];
71 static void
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),
80 G_SIGNAL_RUN_FIRST,
81 G_STRUCT_OFFSET (GimpModuleClass, modified),
82 NULL, NULL,
83 g_cclosure_marshal_VOID__VOID,
84 G_TYPE_NONE, 0);
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;
94 static void
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;
104 module->info = NULL;
105 module->last_module_error = NULL;
107 module->query_module = NULL;
108 module->register_module = NULL;
111 static void
112 gimp_module_finalize (GObject *object)
114 GimpModule *module = GIMP_MODULE (object);
116 if (module->info)
118 gimp_module_info_free (module->info);
119 module->info = NULL;
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);
137 static gboolean
138 gimp_module_load (GTypeModule *module)
140 GimpModule *gimp_module = GIMP_MODULE (module);
141 gpointer func;
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))
151 return FALSE;
153 if (! gimp_module_query_module (gimp_module))
154 return FALSE;
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;
170 return FALSE;
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;
188 return FALSE;
191 gimp_module->state = GIMP_MODULE_STATE_LOADED;
193 return TRUE;
196 static void
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 */
214 * gimp_module_new:
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.
223 GimpModule *
224 gimp_module_new (const gchar *filename,
225 gboolean load_inhibit,
226 gboolean verbose)
228 GimpModule *module;
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));
244 else
246 if (verbose)
247 g_print ("Skipping module '%s'\n",
248 gimp_filename_to_utf8 (filename));
250 module->state = GIMP_MODULE_STATE_NOT_LOADED;
253 return module;
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.
266 gboolean
267 gimp_module_query_module (GimpModule *module)
269 const GimpModuleInfo *info;
270 gboolean close_module = FALSE;
271 gpointer func;
273 g_return_val_if_fail (GIMP_IS_MODULE (module), FALSE);
275 if (! module->module)
277 if (! gimp_module_open (module))
278 return FALSE;
280 close_module = TRUE;
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;
296 return FALSE;
299 module->query_module = func;
301 if (module->info)
303 gimp_module_info_free (module->info);
304 module->info = NULL;
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,
312 info ?
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;
323 return FALSE;
326 module->info = gimp_module_info_copy (info);
328 if (close_module)
329 return gimp_module_close (module);
331 return TRUE;
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).
341 void
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".
356 void
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.
379 const gchar *
380 gimp_module_state_name (GimpModuleState state)
382 static const gchar * const statenames[] =
384 N_("Module error"),
385 N_("Loaded"),
386 N_("Load failed"),
387 N_("Not loaded")
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.
403 * Since: 2.8
405 GQuark
406 gimp_module_error_quark (void)
408 return g_quark_from_static_string ("gimp-module-error-quark");
412 /* private functions */
414 static gboolean
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);
428 return FALSE;
431 return TRUE;
434 static gboolean
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;
444 return TRUE;
447 static void
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.
473 GimpModuleInfo *
474 gimp_module_info_new (guint32 abi_version,
475 const gchar *purpose,
476 const gchar *author,
477 const gchar *version,
478 const gchar *copyright,
479 const gchar *date)
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);
490 return info;
494 * gimp_module_info_copy:
495 * @info: The #GimpModuleInfo struct to copy.
497 * Copies a #GimpModuleInfo struct.
499 * Return value: The new copy.
501 GimpModuleInfo *
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,
507 info->purpose,
508 info->author,
509 info->version,
510 info->copyright,
511 info->date);
515 * gimp_module_info_free:
516 * @info: The #GimpModuleInfo struct to free
518 * Frees the passed #GimpModuleInfo.
520 void
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);
529 g_free (info->date);
531 g_slice_free (GimpModuleInfo, info);