app: s/sprintf/g_snprintf/ in xcf_save_image()
[gimp.git] / libgimpmodule / gimpmoduledb.c
blob66025d7ce43ec0b59b19517c5e6d5b36233bfa4c
1 /* LIBGIMP - The GIMP Library
2 * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
4 * This library is free software: you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 3 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library. If not, see
16 * <https://www.gnu.org/licenses/>.
19 #include "config.h"
21 #include <string.h>
23 #include <gio/gio.h>
25 #include "libgimpbase/gimpbase.h"
26 #include "libgimpconfig/gimpconfig.h"
28 #include "gimpmoduletypes.h"
30 #include "gimpmodule.h"
31 #include "gimpmoduledb.h"
34 /**
35 * SECTION: gimpmoduledb
36 * @title: GimpModuleDB
37 * @short_description: Keeps a list of #GimpModule's found in a given
38 * searchpath.
40 * Keeps a list of #GimpModule's found in a given searchpath.
41 **/
44 enum
46 ADD,
47 REMOVE,
48 MODULE_MODIFIED,
49 LAST_SIGNAL
52 #define DUMP_DB FALSE
55 struct _GimpModuleDBPrivate
57 GList *modules;
59 gchar *load_inhibit;
60 gboolean verbose;
63 #define GET_PRIVATE(obj) (((GimpModuleDB *) (obj))->priv)
66 static void gimp_module_db_finalize (GObject *object);
68 static void gimp_module_db_load_directory (GimpModuleDB *db,
69 GFile *directory);
70 static void gimp_module_db_load_module (GimpModuleDB *db,
71 GFile *file);
73 static GimpModule * gimp_module_db_module_find_by_path (GimpModuleDB *db,
74 const char *fullpath);
76 static void gimp_module_db_module_dump_func (gpointer data,
77 gpointer user_data);
78 static void gimp_module_db_module_on_disk_func (gpointer data,
79 gpointer user_data);
80 static void gimp_module_db_module_remove_func (gpointer data,
81 gpointer user_data);
83 static void gimp_module_db_module_modified (GimpModule *module,
84 GimpModuleDB *db);
87 G_DEFINE_TYPE (GimpModuleDB, gimp_module_db, G_TYPE_OBJECT)
89 #define parent_class gimp_module_db_parent_class
91 static guint db_signals[LAST_SIGNAL] = { 0 };
94 static void
95 gimp_module_db_class_init (GimpModuleDBClass *klass)
97 GObjectClass *object_class = G_OBJECT_CLASS (klass);
99 db_signals[ADD] =
100 g_signal_new ("add",
101 G_TYPE_FROM_CLASS (klass),
102 G_SIGNAL_RUN_FIRST,
103 G_STRUCT_OFFSET (GimpModuleDBClass, add),
104 NULL, NULL,
105 g_cclosure_marshal_VOID__OBJECT,
106 G_TYPE_NONE, 1,
107 GIMP_TYPE_MODULE);
109 db_signals[REMOVE] =
110 g_signal_new ("remove",
111 G_TYPE_FROM_CLASS (klass),
112 G_SIGNAL_RUN_FIRST,
113 G_STRUCT_OFFSET (GimpModuleDBClass, remove),
114 NULL, NULL,
115 g_cclosure_marshal_VOID__OBJECT,
116 G_TYPE_NONE, 1,
117 GIMP_TYPE_MODULE);
119 db_signals[MODULE_MODIFIED] =
120 g_signal_new ("module-modified",
121 G_TYPE_FROM_CLASS (klass),
122 G_SIGNAL_RUN_FIRST,
123 G_STRUCT_OFFSET (GimpModuleDBClass, module_modified),
124 NULL, NULL,
125 g_cclosure_marshal_VOID__OBJECT,
126 G_TYPE_NONE, 1,
127 GIMP_TYPE_MODULE);
129 object_class->finalize = gimp_module_db_finalize;
131 klass->add = NULL;
132 klass->remove = NULL;
134 g_type_class_add_private (klass, sizeof (GimpModuleDBPrivate));
137 static void
138 gimp_module_db_init (GimpModuleDB *db)
140 db->priv = G_TYPE_INSTANCE_GET_PRIVATE (db,
141 GIMP_TYPE_MODULE_DB,
142 GimpModuleDBPrivate);
144 db->priv->modules = NULL;
145 db->priv->load_inhibit = NULL;
146 db->priv->verbose = FALSE;
149 static void
150 gimp_module_db_finalize (GObject *object)
152 GimpModuleDBPrivate *priv = GET_PRIVATE (object);
154 if (priv->modules)
156 GList *list;
158 for (list = priv->modules; list; list = g_list_next (list))
160 g_signal_handlers_disconnect_by_func (list->data,
161 gimp_module_db_module_modified,
162 object);
165 g_list_free (priv->modules);
166 priv->modules = NULL;
169 g_clear_pointer (&priv->load_inhibit, g_free);
171 G_OBJECT_CLASS (parent_class)->finalize (object);
175 * gimp_module_db_new:
176 * @verbose: Pass %TRUE to enable debugging output.
178 * Creates a new #GimpModuleDB instance. The @verbose parameter will be
179 * passed to the created #GimpModule instances using gimp_module_new().
181 * Return value: The new #GimpModuleDB instance.
183 GimpModuleDB *
184 gimp_module_db_new (gboolean verbose)
186 GimpModuleDB *db;
188 db = g_object_new (GIMP_TYPE_MODULE_DB, NULL);
190 db->priv->verbose = verbose ? TRUE : FALSE;
192 return db;
196 * gimp_module_db_get_modules:
197 * @db: A #GimpModuleDB.
199 * Returns a #GList of the modules kept by @db. The list must not be
200 * modified or freed.
202 * Return value: a #GList of #GimpModule instances.
204 * Since: 3.0
206 GList *
207 gimp_module_db_get_modules (GimpModuleDB *db)
209 g_return_val_if_fail (GIMP_IS_MODULE_DB (db), NULL);
211 return GET_PRIVATE (db)->modules;
215 * gimp_module_db_set_verbose:
216 * @db: A #GimpModuleDB.
217 * @verbose: the new 'verbose' setting
219 * Sets the 'verbose' setting of @db.
221 * Since: 3.0
223 void
224 gimp_module_db_set_verbose (GimpModuleDB *db,
225 gboolean verbose)
227 g_return_if_fail (GIMP_IS_MODULE_DB (db));
229 GET_PRIVATE (db)->verbose = verbose ? TRUE : FALSE;
233 * gimp_module_db_get_verbose:
234 * @db: A #GimpModuleDB.
236 * Returns the 'verbose' setting of @db.
238 * Return value: the 'verbose' setting.
240 * Since: 3.0
242 gboolean
243 gimp_module_db_get_verbose (GimpModuleDB *db)
245 g_return_val_if_fail (GIMP_IS_MODULE_DB (db), FALSE);
247 return GET_PRIVATE (db)->verbose;
250 static gboolean
251 is_in_inhibit_list (const gchar *filename,
252 const gchar *inhibit_list)
254 gchar *p;
255 gint pathlen;
256 const gchar *start;
257 const gchar *end;
259 if (! inhibit_list || ! strlen (inhibit_list))
260 return FALSE;
262 p = strstr (inhibit_list, filename);
263 if (!p)
264 return FALSE;
266 /* we have a substring, but check for colons either side */
267 start = p;
268 while (start != inhibit_list && *start != G_SEARCHPATH_SEPARATOR)
269 start--;
271 if (*start == G_SEARCHPATH_SEPARATOR)
272 start++;
274 end = strchr (p, G_SEARCHPATH_SEPARATOR);
275 if (! end)
276 end = inhibit_list + strlen (inhibit_list);
278 pathlen = strlen (filename);
280 if ((end - start) == pathlen)
281 return TRUE;
283 return FALSE;
287 * gimp_module_db_set_load_inhibit:
288 * @db: A #GimpModuleDB.
289 * @load_inhibit: A #G_SEARCHPATH_SEPARATOR delimited list of module
290 * filenames to exclude from auto-loading.
292 * Sets the @load_inhibit flag for all #GimpModule's which are kept
293 * by @db (using gimp_module_set_load_inhibit()).
295 void
296 gimp_module_db_set_load_inhibit (GimpModuleDB *db,
297 const gchar *load_inhibit)
299 GimpModuleDBPrivate *priv;
300 GList *list;
302 g_return_if_fail (GIMP_IS_MODULE_DB (db));
304 priv = GET_PRIVATE (db);
306 if (priv->load_inhibit)
307 g_free (priv->load_inhibit);
309 priv->load_inhibit = g_strdup (load_inhibit);
311 for (list = priv->modules; list; list = g_list_next (list))
313 GimpModule *module = list->data;
315 gimp_module_set_load_inhibit (module,
316 is_in_inhibit_list (module->filename,
317 load_inhibit));
322 * gimp_module_db_get_load_inhibit:
323 * @db: A #GimpModuleDB.
325 * Return the #G_SEARCHPATH_SEPARATOR delimited list of module filenames
326 * which are excluded from auto-loading.
328 * Return value: the @db's @load_inhibit string.
330 const gchar *
331 gimp_module_db_get_load_inhibit (GimpModuleDB *db)
333 g_return_val_if_fail (GIMP_IS_MODULE_DB (db), NULL);
335 return GET_PRIVATE (db)->load_inhibit;
339 * gimp_module_db_load:
340 * @db: A #GimpModuleDB.
341 * @module_path: A #G_SEARCHPATH_SEPARATOR delimited list of directories
342 * to load modules from.
344 * Scans the directories contained in @module_path and creates a
345 * #GimpModule instance for every loadable module contained in the
346 * directories.
348 void
349 gimp_module_db_load (GimpModuleDB *db,
350 const gchar *module_path)
352 GimpModuleDBPrivate *priv;
354 g_return_if_fail (GIMP_IS_MODULE_DB (db));
355 g_return_if_fail (module_path != NULL);
357 priv = GET_PRIVATE (db);
359 if (g_module_supported ())
361 GList *path;
362 GList *list;
364 path = gimp_config_path_expand_to_files (module_path, NULL);
366 for (list = path; list; list = g_list_next (list))
368 gimp_module_db_load_directory (db, list->data);
371 g_list_free_full (path, (GDestroyNotify) g_object_unref);
374 if (DUMP_DB)
375 g_list_foreach (priv->modules, gimp_module_db_module_dump_func, NULL);
379 * gimp_module_db_refresh:
380 * @db: A #GimpModuleDB.
381 * @module_path: A #G_SEARCHPATH_SEPARATOR delimited list of directories
382 * to load modules from.
384 * Does the same as gimp_module_db_load(), plus removes all #GimpModule
385 * instances whose modules have been deleted from disk.
387 * Note that the #GimpModule's will just be removed from the internal
388 * list and not freed as this is not possible with #GTypeModule
389 * instances which actually implement types.
391 void
392 gimp_module_db_refresh (GimpModuleDB *db,
393 const gchar *module_path)
395 GimpModuleDBPrivate *priv;
396 GList *kill_list = NULL;
398 g_return_if_fail (GIMP_IS_MODULE_DB (db));
399 g_return_if_fail (module_path != NULL);
401 priv = GET_PRIVATE (db);
403 /* remove modules we don't have on disk anymore */
404 g_list_foreach (priv->modules,
405 gimp_module_db_module_on_disk_func,
406 &kill_list);
407 g_list_foreach (kill_list,
408 gimp_module_db_module_remove_func,
409 db);
410 g_list_free (kill_list);
412 /* walk filesystem and add new things we find */
413 gimp_module_db_load (db, module_path);
416 static void
417 gimp_module_db_load_directory (GimpModuleDB *db,
418 GFile *directory)
420 GFileEnumerator *enumerator;
422 enumerator = g_file_enumerate_children (directory,
423 G_FILE_ATTRIBUTE_STANDARD_NAME ","
424 G_FILE_ATTRIBUTE_STANDARD_IS_HIDDEN ","
425 G_FILE_ATTRIBUTE_STANDARD_TYPE,
426 G_FILE_QUERY_INFO_NONE,
427 NULL, NULL);
429 if (enumerator)
431 GFileInfo *info;
433 while ((info = g_file_enumerator_next_file (enumerator, NULL, NULL)))
435 GFileType file_type = g_file_info_get_file_type (info);
437 if (file_type == G_FILE_TYPE_REGULAR &&
438 ! g_file_info_get_is_hidden (info))
440 GFile *child = g_file_enumerator_get_child (enumerator, info);
442 gimp_module_db_load_module (db, child);
444 g_object_unref (child);
447 g_object_unref (info);
450 g_object_unref (enumerator);
454 static void
455 gimp_module_db_load_module (GimpModuleDB *db,
456 GFile *file)
458 GimpModuleDBPrivate *priv = GET_PRIVATE (db);
459 GimpModule *module;
460 gchar *path;
461 gboolean load_inhibit;
463 if (! gimp_file_has_extension (file, "." G_MODULE_SUFFIX))
464 return;
466 path = g_file_get_path (file);
468 /* don't load if we already know about it */
469 if (gimp_module_db_module_find_by_path (db, path))
471 g_free (path);
472 return;
475 load_inhibit = is_in_inhibit_list (path, priv->load_inhibit);
477 module = gimp_module_new (path,
478 load_inhibit,
479 priv->verbose);
481 g_free (path);
483 g_signal_connect (module, "modified",
484 G_CALLBACK (gimp_module_db_module_modified),
485 db);
487 priv->modules = g_list_append (priv->modules, module);
489 g_signal_emit (db, db_signals[ADD], 0, module);
492 static GimpModule *
493 gimp_module_db_module_find_by_path (GimpModuleDB *db,
494 const char *fullpath)
496 GimpModuleDBPrivate *priv = GET_PRIVATE (db);
497 GList *list;
499 for (list = priv->modules; list; list = g_list_next (list))
501 GimpModule *module = list->data;
503 if (! strcmp (module->filename, fullpath))
504 return module;
507 return NULL;
510 static void
511 gimp_module_db_module_dump_func (gpointer data,
512 gpointer user_data)
514 GimpModule *module = data;
516 g_print ("\n%s: %s\n",
517 gimp_filename_to_utf8 (module->filename),
518 gimp_module_state_name (module->state));
520 g_print (" module: %p lasterr: %s query: %p register: %p\n",
521 module->module,
522 module->last_module_error ? module->last_module_error : "NONE",
523 module->query_module,
524 module->register_module);
526 if (module->info)
528 g_print (" purpose: %s\n"
529 " author: %s\n"
530 " version: %s\n"
531 " copyright: %s\n"
532 " date: %s\n",
533 module->info->purpose ? module->info->purpose : "NONE",
534 module->info->author ? module->info->author : "NONE",
535 module->info->version ? module->info->version : "NONE",
536 module->info->copyright ? module->info->copyright : "NONE",
537 module->info->date ? module->info->date : "NONE");
541 static void
542 gimp_module_db_module_on_disk_func (gpointer data,
543 gpointer user_data)
545 GimpModule *module = data;
546 GList **kill_list = user_data;
547 gboolean old_on_disk;
549 old_on_disk = module->on_disk;
551 module->on_disk = g_file_test (module->filename, G_FILE_TEST_IS_REGULAR);
553 /* if it's not on the disk, and it isn't in memory, mark it to be
554 * removed later.
556 if (! module->on_disk && ! module->module)
558 *kill_list = g_list_append (*kill_list, module);
559 module = NULL;
562 if (module && module->on_disk != old_on_disk)
563 gimp_module_modified (module);
566 static void
567 gimp_module_db_module_remove_func (gpointer data,
568 gpointer user_data)
570 GimpModule *module = data;
571 GimpModuleDB *db = user_data;
572 GimpModuleDBPrivate *priv = GET_PRIVATE (db);
574 g_signal_handlers_disconnect_by_func (module,
575 gimp_module_db_module_modified,
576 db);
578 priv->modules = g_list_remove (priv->modules, module);
580 g_signal_emit (db, db_signals[REMOVE], 0, module);
583 static void
584 gimp_module_db_module_modified (GimpModule *module,
585 GimpModuleDB *db)
587 g_signal_emit (db, db_signals[MODULE_MODIFIED], 0, module);