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/>.
25 #include "libgimpbase/gimpbase.h"
26 #include "libgimpconfig/gimpconfig.h"
28 #include "gimpmoduletypes.h"
30 #include "gimpmodule.h"
31 #include "gimpmoduledb.h"
35 * SECTION: gimpmoduledb
36 * @title: GimpModuleDB
37 * @short_description: Keeps a list of #GimpModule's found in a given
40 * Keeps a list of #GimpModule's found in a given searchpath.
55 struct _GimpModuleDBPrivate
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
,
70 static void gimp_module_db_load_module (GimpModuleDB
*db
,
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
,
78 static void gimp_module_db_module_on_disk_func (gpointer data
,
80 static void gimp_module_db_module_remove_func (gpointer data
,
83 static void gimp_module_db_module_modified (GimpModule
*module
,
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 };
95 gimp_module_db_class_init (GimpModuleDBClass
*klass
)
97 GObjectClass
*object_class
= G_OBJECT_CLASS (klass
);
101 G_TYPE_FROM_CLASS (klass
),
103 G_STRUCT_OFFSET (GimpModuleDBClass
, add
),
105 g_cclosure_marshal_VOID__OBJECT
,
110 g_signal_new ("remove",
111 G_TYPE_FROM_CLASS (klass
),
113 G_STRUCT_OFFSET (GimpModuleDBClass
, remove
),
115 g_cclosure_marshal_VOID__OBJECT
,
119 db_signals
[MODULE_MODIFIED
] =
120 g_signal_new ("module-modified",
121 G_TYPE_FROM_CLASS (klass
),
123 G_STRUCT_OFFSET (GimpModuleDBClass
, module_modified
),
125 g_cclosure_marshal_VOID__OBJECT
,
129 object_class
->finalize
= gimp_module_db_finalize
;
132 klass
->remove
= NULL
;
134 g_type_class_add_private (klass
, sizeof (GimpModuleDBPrivate
));
138 gimp_module_db_init (GimpModuleDB
*db
)
140 db
->priv
= G_TYPE_INSTANCE_GET_PRIVATE (db
,
142 GimpModuleDBPrivate
);
144 db
->priv
->modules
= NULL
;
145 db
->priv
->load_inhibit
= NULL
;
146 db
->priv
->verbose
= FALSE
;
150 gimp_module_db_finalize (GObject
*object
)
152 GimpModuleDBPrivate
*priv
= GET_PRIVATE (object
);
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
,
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.
184 gimp_module_db_new (gboolean verbose
)
188 db
= g_object_new (GIMP_TYPE_MODULE_DB
, NULL
);
190 db
->priv
->verbose
= verbose
? TRUE
: FALSE
;
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
202 * Return value: a #GList of #GimpModule instances.
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.
224 gimp_module_db_set_verbose (GimpModuleDB
*db
,
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.
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
;
251 is_in_inhibit_list (const gchar
*filename
,
252 const gchar
*inhibit_list
)
259 if (! inhibit_list
|| ! strlen (inhibit_list
))
262 p
= strstr (inhibit_list
, filename
);
266 /* we have a substring, but check for colons either side */
268 while (start
!= inhibit_list
&& *start
!= G_SEARCHPATH_SEPARATOR
)
271 if (*start
== G_SEARCHPATH_SEPARATOR
)
274 end
= strchr (p
, G_SEARCHPATH_SEPARATOR
);
276 end
= inhibit_list
+ strlen (inhibit_list
);
278 pathlen
= strlen (filename
);
280 if ((end
- start
) == pathlen
)
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()).
296 gimp_module_db_set_load_inhibit (GimpModuleDB
*db
,
297 const gchar
*load_inhibit
)
299 GimpModuleDBPrivate
*priv
;
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
,
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.
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
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 ())
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
);
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.
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
,
407 g_list_foreach (kill_list
,
408 gimp_module_db_module_remove_func
,
410 g_list_free (kill_list
);
412 /* walk filesystem and add new things we find */
413 gimp_module_db_load (db
, module_path
);
417 gimp_module_db_load_directory (GimpModuleDB
*db
,
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
,
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
);
455 gimp_module_db_load_module (GimpModuleDB
*db
,
458 GimpModuleDBPrivate
*priv
= GET_PRIVATE (db
);
461 gboolean load_inhibit
;
463 if (! gimp_file_has_extension (file
, "." G_MODULE_SUFFIX
))
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
))
475 load_inhibit
= is_in_inhibit_list (path
, priv
->load_inhibit
);
477 module
= gimp_module_new (path
,
483 g_signal_connect (module
, "modified",
484 G_CALLBACK (gimp_module_db_module_modified
),
487 priv
->modules
= g_list_append (priv
->modules
, module
);
489 g_signal_emit (db
, db_signals
[ADD
], 0, module
);
493 gimp_module_db_module_find_by_path (GimpModuleDB
*db
,
494 const char *fullpath
)
496 GimpModuleDBPrivate
*priv
= GET_PRIVATE (db
);
499 for (list
= priv
->modules
; list
; list
= g_list_next (list
))
501 GimpModule
*module
= list
->data
;
503 if (! strcmp (module
->filename
, fullpath
))
511 gimp_module_db_module_dump_func (gpointer 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",
522 module
->last_module_error
? module
->last_module_error
: "NONE",
523 module
->query_module
,
524 module
->register_module
);
528 g_print (" purpose: %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");
542 gimp_module_db_module_on_disk_func (gpointer 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
556 if (! module
->on_disk
&& ! module
->module
)
558 *kill_list
= g_list_append (*kill_list
, module
);
562 if (module
&& module
->on_disk
!= old_on_disk
)
563 gimp_module_modified (module
);
567 gimp_module_db_module_remove_func (gpointer 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
,
578 priv
->modules
= g_list_remove (priv
->modules
, module
);
580 g_signal_emit (db
, db_signals
[REMOVE
], 0, module
);
584 gimp_module_db_module_modified (GimpModule
*module
,
587 g_signal_emit (db
, db_signals
[MODULE_MODIFIED
], 0, module
);