1
/* GIMP - The GNU Image Manipulation Program
2
* Copyright (C) 1995-2002 Spencer Kimball, Peter Mattis, and others
4
* gimppluginmanager-restore.c
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; either version 2 of the License, or
9
* (at your option) any later version.
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25
#include <glib-object.h>
27
#include "libgimpbase/gimpbase.h"
28
#include "libgimpconfig/gimpconfig.h"
30
#include "plug-in-types.h"
32
#include "config/gimpcoreconfig.h"
34
#include "core/gimp.h"
35
#include "core/gimpcontext.h"
37
#include "pdb/gimppdb.h"
39
#include "gimpinterpreterdb.h"
40
#include "gimpplugindef.h"
41
#include "gimppluginmanager.h"
42
#define __YES_I_NEED_GIMP_PLUG_IN_MANAGER_CALL__
43
#include "gimppluginmanager-call.h"
44
#include "gimppluginmanager-help-domain.h"
45
#include "gimppluginmanager-locale-domain.h"
46
#include "gimppluginmanager-restore.h"
47
#include "gimppluginprocedure.h"
48
#include "plug-in-rc.h"
50
#include "gimp-intl.h"
53
static void gimp_plug_in_manager_search (GimpPlugInManager *manager,
54
GimpInitStatusFunc status_callback);
55
static gchar * gimp_plug_in_manager_get_pluginrc (GimpPlugInManager *manager);
56
static void gimp_plug_in_manager_read_pluginrc (GimpPlugInManager *manager,
57
const gchar *pluginrc,
58
GimpInitStatusFunc status_callback);
59
static void gimp_plug_in_manager_query_new (GimpPlugInManager *manager,
61
GimpInitStatusFunc status_callback);
62
static void gimp_plug_in_manager_init_plug_ins (GimpPlugInManager *manager,
64
GimpInitStatusFunc status_callback);
65
static void gimp_plug_in_manager_run_extensions (GimpPlugInManager *manager,
67
GimpInitStatusFunc status_callback);
68
static void gimp_plug_in_manager_bind_text_domains (GimpPlugInManager *manager);
69
static void gimp_plug_in_manager_add_from_file (const GimpDatafileData *file_data,
71
static void gimp_plug_in_manager_add_from_rc (GimpPlugInManager *manager,
72
GimpPlugInDef *plug_in_def);
73
static void gimp_plug_in_manager_add_to_db (GimpPlugInManager *manager,
75
GimpPlugInProcedure *proc);
76
static gint gimp_plug_in_manager_file_proc_compare (gconstpointer a,
83
gimp_plug_in_manager_restore (GimpPlugInManager *manager,
85
GimpInitStatusFunc status_callback)
92
g_return_if_fail (GIMP_IS_PLUG_IN_MANAGER (manager));
93
g_return_if_fail (GIMP_IS_CONTEXT (context));
94
g_return_if_fail (status_callback != NULL);
98
/* search for binaries in the plug-in directory path */
99
gimp_plug_in_manager_search (manager, status_callback);
101
/* read the pluginrc file for cached data */
102
pluginrc = gimp_plug_in_manager_get_pluginrc (manager);
104
gimp_plug_in_manager_read_pluginrc (manager, pluginrc, status_callback);
106
/* query any plug-ins that changed since we last wrote out pluginrc */
107
gimp_plug_in_manager_query_new (manager, context, status_callback);
109
/* initialize the plug-ins */
110
gimp_plug_in_manager_init_plug_ins (manager, context, status_callback);
112
/* add the procedures to manager->plug_in_procedures */
113
for (list = manager->plug_in_defs; list; list = list->next)
115
GimpPlugInDef *plug_in_def = list->data;
118
for (list2 = plug_in_def->procedures; list2; list2 = list2->next)
120
gimp_plug_in_manager_add_procedure (manager, list2->data);
124
/* write the pluginrc file if necessary */
125
if (manager->write_pluginrc)
127
if (gimp->be_verbose)
128
g_print ("Writing '%s'\n", gimp_filename_to_utf8 (pluginrc));
130
if (! plug_in_rc_write (manager->plug_in_defs, pluginrc, &error))
132
gimp_message (gimp, NULL, GIMP_MESSAGE_ERROR, "%s", error->message);
133
g_clear_error (&error);
136
manager->write_pluginrc = FALSE;
141
/* create locale and help domain lists */
142
for (list = manager->plug_in_defs; list; list = list->next)
144
GimpPlugInDef *plug_in_def = list->data;
146
if (plug_in_def->locale_domain_name)
147
gimp_plug_in_manager_add_locale_domain (manager,
149
plug_in_def->locale_domain_name,
150
plug_in_def->locale_domain_path);
152
/* set the default plug-in locale domain */
153
gimp_plug_in_def_set_locale_domain (plug_in_def,
154
gimp_plug_in_manager_get_locale_domain (manager,
159
if (plug_in_def->help_domain_name)
160
gimp_plug_in_manager_add_help_domain (manager,
162
plug_in_def->help_domain_name,
163
plug_in_def->help_domain_uri);
166
/* we're done with the plug-in-defs */
167
g_slist_foreach (manager->plug_in_defs, (GFunc) g_object_unref, NULL);
168
g_slist_free (manager->plug_in_defs);
169
manager->plug_in_defs = NULL;
171
/* bind plug-in text domains */
172
gimp_plug_in_manager_bind_text_domains (manager);
174
/* add the plug-in procs to the procedure database */
175
for (list = manager->plug_in_procedures; list; list = list->next)
177
gimp_plug_in_manager_add_to_db (manager, context, list->data);
180
/* sort the load and save procedures */
181
manager->load_procs =
182
g_slist_sort_with_data (manager->load_procs,
183
gimp_plug_in_manager_file_proc_compare, manager);
184
manager->save_procs =
185
g_slist_sort_with_data (manager->save_procs,
186
gimp_plug_in_manager_file_proc_compare, manager);
188
gimp_plug_in_manager_run_extensions (manager, context, status_callback);
192
/* search for binaries in the plug-in directory path */
194
gimp_plug_in_manager_search (GimpPlugInManager *manager,
195
GimpInitStatusFunc status_callback)
198
const gchar *pathext = g_getenv ("PATHEXT");
200
/* If PATHEXT is set, we are likely on Windows and need to add
201
* the known file extensions.
207
exts = gimp_interpreter_db_get_extensions (manager->interpreter_db);
213
value = g_strconcat (pathext, G_SEARCHPATH_SEPARATOR_S, exts, NULL);
215
g_setenv ("PATHEXT", value, TRUE);
222
status_callback (_("Searching Plug-Ins"), "", 0.0);
224
path = gimp_config_path_expand (manager->gimp->config->plug_in_path,
227
gimp_datafiles_read_directories (path,
228
G_FILE_TEST_IS_EXECUTABLE,
229
gimp_plug_in_manager_add_from_file,
236
gimp_plug_in_manager_get_pluginrc (GimpPlugInManager *manager)
238
Gimp *gimp = manager->gimp;
241
if (gimp->config->plug_in_rc_path)
243
pluginrc = gimp_config_path_expand (gimp->config->plug_in_rc_path,
246
if (! g_path_is_absolute (pluginrc))
248
gchar *str = g_build_filename (gimp_directory (), pluginrc, NULL);
256
pluginrc = gimp_personal_rc_file ("pluginrc");
262
/* read the pluginrc file for cached data */
264
gimp_plug_in_manager_read_pluginrc (GimpPlugInManager *manager,
265
const gchar *pluginrc,
266
GimpInitStatusFunc status_callback)
269
GError *error = NULL;
271
status_callback (_("Resource configuration"),
272
gimp_filename_to_utf8 (pluginrc), 0.0);
274
if (manager->gimp->be_verbose)
275
g_print ("Parsing '%s'\n", gimp_filename_to_utf8 (pluginrc));
277
rc_defs = plug_in_rc_parse (manager->gimp, pluginrc, &error);
283
for (list = rc_defs; list; list = g_slist_next (list))
284
gimp_plug_in_manager_add_from_rc (manager, list->data); /* consumes list->data */
286
g_slist_free (rc_defs);
290
if (error->code != GIMP_CONFIG_ERROR_OPEN_ENOENT)
291
gimp_message (manager->gimp, NULL, GIMP_MESSAGE_ERROR,
292
"%s", error->message);
294
g_clear_error (&error);
298
/* query any plug-ins that changed since we last wrote out pluginrc */
300
gimp_plug_in_manager_query_new (GimpPlugInManager *manager,
301
GimpContext *context,
302
GimpInitStatusFunc status_callback)
307
status_callback (_("Querying new Plug-ins"), "", 0.0);
309
for (list = manager->plug_in_defs, n_plugins = 0; list; list = list->next)
311
GimpPlugInDef *plug_in_def = list->data;
313
if (plug_in_def->needs_query)
321
manager->write_pluginrc = TRUE;
323
for (list = manager->plug_in_defs, nth = 0; list; list = list->next)
325
GimpPlugInDef *plug_in_def = list->data;
327
if (plug_in_def->needs_query)
331
basename = g_filename_display_basename (plug_in_def->prog);
332
status_callback (NULL, basename,
333
(gdouble) nth++ / (gdouble) n_plugins);
336
if (manager->gimp->be_verbose)
337
g_print ("Querying plug-in: '%s'\n",
338
gimp_filename_to_utf8 (plug_in_def->prog));
340
gimp_plug_in_manager_call_query (manager, context, plug_in_def);
345
status_callback (NULL, "", 1.0);
348
/* initialize the plug-ins */
350
gimp_plug_in_manager_init_plug_ins (GimpPlugInManager *manager,
351
GimpContext *context,
352
GimpInitStatusFunc status_callback)
357
status_callback (_("Initializing Plug-ins"), "", 0.0);
359
for (list = manager->plug_in_defs, n_plugins = 0; list; list = list->next)
361
GimpPlugInDef *plug_in_def = list->data;
363
if (plug_in_def->has_init)
371
for (list = manager->plug_in_defs, nth = 0; list; list = list->next)
373
GimpPlugInDef *plug_in_def = list->data;
375
if (plug_in_def->has_init)
379
basename = g_filename_display_basename (plug_in_def->prog);
380
status_callback (NULL, basename,
381
(gdouble) nth++ / (gdouble) n_plugins);
384
if (manager->gimp->be_verbose)
385
g_print ("Initializing plug-in: '%s'\n",
386
gimp_filename_to_utf8 (plug_in_def->prog));
388
gimp_plug_in_manager_call_init (manager, context, plug_in_def);
393
status_callback (NULL, "", 1.0);
396
/* run automatically started extensions */
398
gimp_plug_in_manager_run_extensions (GimpPlugInManager *manager,
399
GimpContext *context,
400
GimpInitStatusFunc status_callback)
402
Gimp *gimp = manager->gimp;
404
GList *extensions = NULL;
407
/* build list of automatically started extensions */
408
for (list = manager->plug_in_procedures; list; list = list->next)
410
GimpPlugInProcedure *proc = list->data;
413
GIMP_PROCEDURE (proc)->proc_type == GIMP_EXTENSION &&
414
GIMP_PROCEDURE (proc)->num_args == 0)
416
extensions = g_list_prepend (extensions, proc);
420
extensions = g_list_reverse (extensions);
421
n_extensions = g_list_length (extensions);
423
/* run the available extensions */
429
status_callback (_("Starting Extensions"), "", 0.0);
431
for (list = extensions, nth = 0; list; list = g_list_next (list), nth++)
433
GimpPlugInProcedure *proc = list->data;
436
if (gimp->be_verbose)
437
g_print ("Starting extension: '%s'\n", GIMP_OBJECT (proc)->name);
439
status_callback (NULL, GIMP_OBJECT (proc)->name,
440
(gdouble) nth / (gdouble) n_extensions);
442
args = g_value_array_new (0);
444
gimp_procedure_execute_async (GIMP_PROCEDURE (proc),
445
gimp, context, NULL, args, NULL);
447
g_value_array_free (args);
450
g_list_free (extensions);
452
status_callback (NULL, "", 1.0);
457
gimp_plug_in_manager_bind_text_domains (GimpPlugInManager *manager)
459
gchar **locale_domains;
460
gchar **locale_paths;
464
n_domains = gimp_plug_in_manager_get_locale_domains (manager,
468
for (i = 0; i < n_domains; i++)
470
bindtextdomain (locale_domains[i], locale_paths[i]);
471
#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
472
bind_textdomain_codeset (locale_domains[i], "UTF-8");
476
g_strfreev (locale_domains);
477
g_strfreev (locale_paths);
481
gimp_plug_in_manager_add_from_file (const GimpDatafileData *file_data,
484
GimpPlugInManager *manager = data;
485
GimpPlugInDef *plug_in_def;
488
for (list = manager->plug_in_defs; list; list = list->next)
492
plug_in_def = list->data;
493
plug_in_name = g_path_get_basename (plug_in_def->prog);
495
if (g_ascii_strcasecmp (file_data->basename, plug_in_name) == 0)
497
g_printerr ("Skipping duplicate plug-in: '%s'\n",
498
gimp_filename_to_utf8 (file_data->filename));
500
g_free (plug_in_name);
505
g_free (plug_in_name);
508
plug_in_def = gimp_plug_in_def_new (file_data->filename);
510
gimp_plug_in_def_set_mtime (plug_in_def, file_data->mtime);
511
gimp_plug_in_def_set_needs_query (plug_in_def, TRUE);
513
manager->plug_in_defs = g_slist_prepend (manager->plug_in_defs, plug_in_def);
517
gimp_plug_in_manager_add_from_rc (GimpPlugInManager *manager,
518
GimpPlugInDef *plug_in_def)
523
g_return_if_fail (GIMP_IS_PLUG_IN_MANAGER (manager));
524
g_return_if_fail (plug_in_def != NULL);
525
g_return_if_fail (plug_in_def->prog != NULL);
527
if (! g_path_is_absolute (plug_in_def->prog))
529
g_warning ("plug_ins_def_add_from_rc: filename not absolute (skipping)");
530
g_object_unref (plug_in_def);
534
basename1 = g_path_get_basename (plug_in_def->prog);
536
/* If this is a file load or save plugin, make sure we have
537
* something for one of the extensions, prefixes, or magic number.
538
* Other bits of code rely on detecting file plugins by the
539
* presence of one of these things, but the raw plug-in needs to be
540
* able to register no extensions, prefixes or magics.
542
for (list = plug_in_def->procedures; list; list = list->next)
544
GimpPlugInProcedure *proc = list->data;
546
if (! proc->extensions &&
550
(g_str_has_prefix (proc->menu_paths->data, "<Load>") ||
551
g_str_has_prefix (proc->menu_paths->data, "<Save>")))
553
proc->extensions = g_strdup ("");
557
/* Check if the entry mentioned in pluginrc matches an executable
558
* found in the plug_in_path.
560
for (list = manager->plug_in_defs; list; list = list->next)
562
GimpPlugInDef *ondisk_plug_in_def = list->data;
565
basename2 = g_path_get_basename (ondisk_plug_in_def->prog);
567
if (! strcmp (basename1, basename2))
569
if (! g_ascii_strcasecmp (plug_in_def->prog,
570
ondisk_plug_in_def->prog) &&
571
(plug_in_def->mtime == ondisk_plug_in_def->mtime))
573
/* Use pluginrc entry, deleting ondisk entry */
574
list->data = plug_in_def;
575
g_object_unref (ondisk_plug_in_def);
579
/* Use ondisk entry, deleting pluginrc entry */
580
g_object_unref (plug_in_def);
594
manager->write_pluginrc = TRUE;
595
g_printerr ("Executable not found: '%s'\n",
596
gimp_filename_to_utf8 (plug_in_def->prog));
597
g_object_unref (plug_in_def);
602
gimp_plug_in_manager_add_to_db (GimpPlugInManager *manager,
603
GimpContext *context,
604
GimpPlugInProcedure *proc)
606
gimp_pdb_register_procedure (manager->gimp->pdb, GIMP_PROCEDURE (proc));
610
GValueArray *return_vals;
612
if (proc->image_types)
615
gimp_pdb_execute_procedure_by_name (manager->gimp->pdb,
617
"gimp-register-save-handler",
618
G_TYPE_STRING, GIMP_OBJECT (proc)->name,
619
G_TYPE_STRING, proc->extensions,
620
G_TYPE_STRING, proc->prefixes,
626
gimp_pdb_execute_procedure_by_name (manager->gimp->pdb,
628
"gimp-register-magic-load-handler",
629
G_TYPE_STRING, GIMP_OBJECT (proc)->name,
630
G_TYPE_STRING, proc->extensions,
631
G_TYPE_STRING, proc->prefixes,
632
G_TYPE_STRING, proc->magics,
636
g_value_array_free (return_vals);
641
gimp_plug_in_manager_file_proc_compare (gconstpointer a,
645
GimpPlugInProcedure *proc_a = GIMP_PLUG_IN_PROCEDURE (a);
646
GimpPlugInProcedure *proc_b = GIMP_PLUG_IN_PROCEDURE (b);
647
const gchar *label_a;
648
const gchar *label_b;
651
if (g_str_has_prefix (proc_a->prog, "gimp-xcf"))
654
if (g_str_has_prefix (proc_b->prog, "gimp-xcf"))
657
label_a = gimp_plug_in_procedure_get_label (proc_a);
658
label_b = gimp_plug_in_procedure_get_label (proc_b);
660
if (label_a && label_b)
661
retval = g_utf8_collate (label_a, label_b);