gimppluginmanager.c 30.8 KB
Newer Older
Elliot Lee's avatar
Elliot Lee committed
1 2 3
/* The GIMP -- an image manipulation program
 * Copyright (C) 1995 Spencer Kimball and Peter Mattis
 *
4 5
 * plug-ins.c
 *
Elliot Lee's avatar
Elliot Lee committed
6 7 8 9 10 11 12 13 14 15 16 17
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Elliot Lee's avatar
Elliot Lee committed
19
 */
20

Elliot Lee's avatar
Elliot Lee committed
21
#include "config.h"
Tor Lillqvist's avatar
Tor Lillqvist committed
22

23
#include "string.h"
Manish Singh's avatar
Manish Singh committed
24

25
#include <glib-object.h>
Tor Lillqvist's avatar
Tor Lillqvist committed
26

27 28 29
#include "libgimpbase/gimpbase.h"
#include "libgimpbase/gimpprotocol.h"
#include "libgimpbase/gimpwire.h"
30
#include "libgimpconfig/gimpconfig.h"
31

Michael Natterer's avatar
Michael Natterer committed
32
#include "plug-in-types.h"
33

34 35
#include "config/gimpcoreconfig.h"

36
#include "core/gimp.h"
37
#include "core/gimpcontext.h"
38 39
#include "core/gimpdrawable.h"
#include "core/gimpimage.h"
40

Michael Natterer's avatar
Michael Natterer committed
41
#include "plug-in.h"
42 43 44
#include "plug-ins.h"
#include "plug-in-def.h"
#include "plug-in-params.h"
45
#include "plug-in-proc-def.h"
46
#include "plug-in-progress.h"
47
#include "plug-in-rc.h"
48
#include "plug-in-run.h"
Michael Natterer's avatar
Michael Natterer committed
49

50
#include "gimp-intl.h"
51

52

53
#define STD_PLUGINS_DOMAIN  GETTEXT_PACKAGE "-std-plug-ins"
54 55


56 57
typedef struct _PlugInLocaleDomain PlugInLocaleDomain;
typedef struct _PlugInHelpDomain   PlugInHelpDomain;
58

59
struct _PlugInLocaleDomain
60 61
{
  gchar *prog_name;
62 63
  gchar *domain_name;
  gchar *domain_path;
64
};
65

66
struct _PlugInHelpDomain
67 68
{
  gchar *prog_name;
69 70
  gchar *domain_name;
  gchar *domain_uri;
71 72 73
};


74 75 76 77 78 79 80 81 82
static void            plug_ins_init_file   (const GimpDatafileData *file_data,
                                             gpointer                data);
static void            plug_ins_add_to_db         (Gimp             *gimp,
                                                   GimpContext      *context);
static PlugInProcDef * plug_ins_proc_def_insert   (Gimp             *gimp,
                                                   PlugInProcDef    *proc_def);
static gint            plug_ins_file_proc_compare (gconstpointer     a,
                                                   gconstpointer     b,
                                                   gpointer          data);
83

84

85 86
/*  public functions  */

Elliot Lee's avatar
Elliot Lee committed
87
void
88
plug_ins_init (Gimp               *gimp,
89
               GimpContext        *context,
90
               GimpInitStatusFunc  status_callback)
Elliot Lee's avatar
Elliot Lee committed
91
{
92 93 94 95 96
  gchar   *filename;
  gchar   *basename;
  gchar   *path;
  GSList  *list;
  GList   *extensions = NULL;
97 98 99
  gint     n_plugins;
  gint     n_extensions;
  gint     nth;
100
  GError  *error = NULL;
Elliot Lee's avatar
Elliot Lee committed
101

102
  g_return_if_fail (GIMP_IS_GIMP (gimp));
103
  g_return_if_fail (GIMP_IS_CONTEXT (context));
104 105
  g_return_if_fail (status_callback != NULL);

106
  plug_in_init (gimp);
107

Elliot Lee's avatar
Elliot Lee committed
108
  /* search for binaries in the plug-in directory path */
109 110 111
  path = gimp_config_path_expand (gimp->config->plug_in_path, TRUE, NULL);

  gimp_datafiles_read_directories (path,
112
                                   G_FILE_TEST_IS_EXECUTABLE,
113 114
				   plug_ins_init_file,
                                   &gimp->plug_in_defs);
Elliot Lee's avatar
Elliot Lee committed
115

116 117
  g_free (path);

Elliot Lee's avatar
Elliot Lee committed
118
  /* read the pluginrc file for cached data */
119
  if (gimp->config->plug_in_rc_path)
120
    {
121 122 123
      filename = gimp_config_path_expand (gimp->config->plug_in_rc_path,
                                          TRUE, NULL);

124
      if (! g_path_is_absolute (filename))
125
        {
126
          gchar *str = g_build_filename (gimp_directory (), filename, NULL);
127

128
          g_free (filename);
129
          filename = str;
130
        }
131 132
    }
  else
133 134 135
    {
      filename = gimp_personal_rc_file ("pluginrc");
    }
136

Sven Neumann's avatar
Sven Neumann committed
137 138
  status_callback (_("Resource configuration"),
                   gimp_filename_to_utf8 (filename), -1);
139 140 141

  if (! plug_in_rc_parse (gimp, filename, &error))
    {
142 143 144
      if (error->code != GIMP_CONFIG_ERROR_OPEN_ENOENT)
        g_message (error->message);

145
      g_clear_error (&error);
146
    }
Elliot Lee's avatar
Elliot Lee committed
147

Sven Neumann's avatar
Sven Neumann committed
148 149
  /*  query any plug-ins that have changed since we last wrote out
   *  the pluginrc file
Elliot Lee's avatar
Elliot Lee committed
150
   */
Sven Neumann's avatar
Sven Neumann committed
151
  status_callback (_("Querying new Plug-ins"), "", 0);
152

153
  for (list = gimp->plug_in_defs, n_plugins = 0; list; list = list->next)
Elliot Lee's avatar
Elliot Lee committed
154
    {
155
      PlugInDef *plug_in_def = list->data;
Elliot Lee's avatar
Elliot Lee committed
156

157
      if (plug_in_def->needs_query)
158 159 160 161 162 163 164 165 166 167 168 169 170 171 172
        n_plugins++;
    }

  if (n_plugins)
    {
      gimp->write_pluginrc = TRUE;

      for (list = gimp->plug_in_defs, nth = 0; list; list = list->next, nth++)
        {
          PlugInDef *plug_in_def = list->data;

          if (! plug_in_def->needs_query)
            continue;

          basename = g_filename_display_basename (plug_in_def->prog);
Sven Neumann's avatar
Sven Neumann committed
173
          status_callback (NULL, basename, (gdouble) nth / (gdouble) n_plugins);
174
          g_free (basename);
175

Michael Natterer's avatar
Michael Natterer committed
176
	  if (gimp->be_verbose)
177
	    g_print (_("Querying plug-in: '%s'\n"),
178
		     gimp_filename_to_utf8 (plug_in_def->prog));
179

Michael Natterer's avatar
Michael Natterer committed
180
	  plug_in_call_query (gimp, context, plug_in_def);
Elliot Lee's avatar
Elliot Lee committed
181 182 183
	}
    }

Sven Neumann's avatar
Sven Neumann committed
184
  status_callback (NULL, NULL, 1.0);
185

186
  /* initialize the plug-ins */
Sven Neumann's avatar
Sven Neumann committed
187
  status_callback (_("Initializing Plug-ins"), "", 0);
188

189
  for (list = gimp->plug_in_defs, n_plugins = 0; list; list = list->next)
190
    {
191
      PlugInDef *plug_in_def = list->data;
192 193

      if (plug_in_def->has_init)
194 195 196 197 198 199 200 201 202 203 204 205 206
        n_plugins++;
    }

  if (n_plugins)
    {
      for (list = gimp->plug_in_defs, nth = 0; list; list = list->next, nth++)
        {
          PlugInDef *plug_in_def = list->data;

          if (! plug_in_def->has_init)
            continue;

          basename = g_filename_display_basename (plug_in_def->prog);
Sven Neumann's avatar
Sven Neumann committed
207
          status_callback (NULL, basename, (gdouble) nth / (gdouble) n_plugins);
208 209 210 211
          g_free (basename);

          if (gimp->be_verbose)
            g_print (_("Initializing plug-in: '%s'\n"),
212 213
                     gimp_filename_to_utf8 (plug_in_def->prog));

214 215
          plug_in_call_init (gimp, context, plug_in_def);
        }
216 217
    }

Sven Neumann's avatar
Sven Neumann committed
218
  status_callback (NULL, NULL, 1.0);
219

Elliot Lee's avatar
Elliot Lee committed
220
  /* insert the proc defs */
221
  for (list = gimp->plug_in_defs; list; list = list->next)
Elliot Lee's avatar
Elliot Lee committed
222
    {
223 224
      PlugInDef *plug_in_def = list->data;
      GSList    *list2;
Elliot Lee's avatar
Elliot Lee committed
225

226
      for (list2 = plug_in_def->proc_defs; list2; list2 = list2->next)
Elliot Lee's avatar
Elliot Lee committed
227
	{
228
	  PlugInProcDef *proc_def = list2->data;
229 230
          PlugInProcDef *overridden_proc_def;

231
 	  proc_def->mtime = plug_in_def->mtime;
232

233
	  overridden_proc_def = plug_ins_proc_def_insert (gimp, proc_def);
234 235 236

          if (overridden_proc_def)
            {
237
              GSList *list3;
238

239 240 241 242
              g_printerr ("removing duplicate PDB procedure \"%s\" "
                          "registered by '%s'\n",
                          overridden_proc_def->db_info.name,
                          gimp_filename_to_utf8 (overridden_proc_def->prog));
243

244
              /* search the plugin list to see if any plugins had references to
245 246
               * the overridden_proc_def.
               */
247
              for (list3 = gimp->plug_in_defs; list3; list3 = list3->next)
248
                {
249
                  PlugInDef *plug_in_def2 = list3->data;
250 251 252 253 254 255

                  plug_in_def2->proc_defs =
                    g_slist_remove (plug_in_def2->proc_defs,
                                    overridden_proc_def);
                }

256 257 258 259 260 261
              /* also remove it from the lists of load and save procs */
              gimp->load_procs = g_slist_remove (gimp->load_procs,
                                                 overridden_proc_def);
              gimp->save_procs = g_slist_remove (gimp->save_procs,
                                                 overridden_proc_def);

262 263
              plug_in_proc_def_free (overridden_proc_def);
            }
Elliot Lee's avatar
Elliot Lee committed
264 265 266 267
	}
    }

  /* write the pluginrc file if necessary */
268
  if (gimp->write_pluginrc)
Elliot Lee's avatar
Elliot Lee committed
269
    {
Michael Natterer's avatar
Michael Natterer committed
270
      if (gimp->be_verbose)
Sven Neumann's avatar
Sven Neumann committed
271
	g_print (_("Writing '%s'\n"), gimp_filename_to_utf8 (filename));
272

273 274 275
      if (! plug_in_rc_write (gimp->plug_in_defs, filename, &error))
        {
          g_message ("%s", error->message);
276
          g_clear_error (&error);
277 278
        }

279
      gimp->write_pluginrc = FALSE;
Elliot Lee's avatar
Elliot Lee committed
280 281
    }

Tor Lillqvist's avatar
Tor Lillqvist committed
282 283
  g_free (filename);

Elliot Lee's avatar
Elliot Lee committed
284
  /* add the plug-in procs to the procedure database */
Michael Natterer's avatar
Michael Natterer committed
285
  plug_ins_add_to_db (gimp, context);
Elliot Lee's avatar
Elliot Lee committed
286

287
  /* create help_path and locale_domain lists */
288
  for (list = gimp->plug_in_defs; list; list = list->next)
289
    {
290
      PlugInDef *plug_in_def = list->data;
291

292
      if (plug_in_def->locale_domain_name)
293 294 295 296
        plug_ins_locale_domain_add (gimp,
                                    plug_in_def->prog,
                                    plug_in_def->locale_domain_name,
                                    plug_in_def->locale_domain_path);
297

298
      if (plug_in_def->help_domain_name)
299 300 301 302
        plug_ins_help_domain_add (gimp,
                                  plug_in_def->prog,
                                  plug_in_def->help_domain_name,
                                  plug_in_def->help_domain_uri);
303 304
    }

305
  if (! gimp->no_interface)
306 307 308 309 310 311 312 313 314 315
    {
      gimp->load_procs = g_slist_sort_with_data (gimp->load_procs,
                                                 plug_ins_file_proc_compare,
                                                 gimp);
      gimp->save_procs = g_slist_sort_with_data (gimp->save_procs,
                                                 plug_ins_file_proc_compare,
                                                 gimp);

      gimp_menus_init (gimp, gimp->plug_in_defs, STD_PLUGINS_DOMAIN);
    }
Elliot Lee's avatar
Elliot Lee committed
316

317
  /* build list of automatically started extensions */
318
  for (list = gimp->plug_in_proc_defs, nth = 0; list; list = list->next, nth++)
Elliot Lee's avatar
Elliot Lee committed
319
    {
320
      PlugInProcDef *proc_def = list->data;
Elliot Lee's avatar
Elliot Lee committed
321

322 323 324
      if (proc_def->prog                                &&
	  proc_def->db_info.proc_type == GIMP_EXTENSION &&
	  proc_def->db_info.num_args  == 0)
Elliot Lee's avatar
Elliot Lee committed
325
	{
326 327 328 329 330 331 332 333 334 335
          extensions = g_list_prepend (extensions, proc_def);
        }
    }

  extensions   = g_list_reverse (extensions);
  n_extensions = g_list_length (extensions);

  /* run the available extensions */
  if (extensions)
    {
336 337
      GList *list;

Sven Neumann's avatar
Sven Neumann committed
338
      status_callback (_("Starting Extensions"), "", 0);
339

340
      for (list = extensions, nth = 0; list; list = g_list_next (list), nth++)
341
        {
342
          PlugInProcDef *proc_def = list->data;
343

Michael Natterer's avatar
Michael Natterer committed
344
	  if (gimp->be_verbose)
345
	    g_print (_("Starting extension: '%s'\n"), proc_def->db_info.name);
346

Sven Neumann's avatar
Sven Neumann committed
347 348
	  status_callback (NULL, proc_def->db_info.name,
                           (gdouble) nth / (gdouble) n_extensions);
349

350
	  plug_in_run (gimp, context, NULL, &proc_def->db_info,
Michael Natterer's avatar
Michael Natterer committed
351
                       NULL, 0, FALSE, TRUE, -1);
Elliot Lee's avatar
Elliot Lee committed
352
	}
353

Sven Neumann's avatar
Sven Neumann committed
354
      status_callback (NULL, NULL, 1.0);
355 356

      g_list_free (extensions);
Elliot Lee's avatar
Elliot Lee committed
357
    }
358

359
  /* free up stuff */
360 361
  for (list = gimp->plug_in_defs; list; list = list->next)
    plug_in_def_free (list->data, FALSE);
362

363 364
  g_slist_free (gimp->plug_in_defs);
  gimp->plug_in_defs = NULL;
Elliot Lee's avatar
Elliot Lee committed
365 366 367
}

void
368
plug_ins_exit (Gimp *gimp)
Elliot Lee's avatar
Elliot Lee committed
369
{
370
  GSList *list;
Elliot Lee's avatar
Elliot Lee committed
371

372
  plug_in_exit (gimp);
Sven Neumann's avatar
Sven Neumann committed
373

374 375 376 377 378 379 380 381 382 383 384 385 386
  for (list = gimp->plug_in_menu_branches; list; list = list->next)
    {
      PlugInMenuBranch *branch = list->data;

      g_free (branch->prog_name);
      g_free (branch->menu_path);
      g_free (branch->menu_label);
      g_free (branch);
    }

  g_slist_free (gimp->plug_in_menu_branches);
  gimp->plug_in_menu_branches = NULL;

387
  for (list = gimp->plug_in_locale_domains; list; list = list->next)
Elliot Lee's avatar
Elliot Lee committed
388
    {
389
      PlugInLocaleDomain *domain = list->data;
Elliot Lee's avatar
Elliot Lee committed
390

391 392 393 394
      g_free (domain->prog_name);
      g_free (domain->domain_name);
      g_free (domain->domain_path);
      g_free (domain);
Elliot Lee's avatar
Elliot Lee committed
395 396
    }

397 398
  g_slist_free (gimp->plug_in_locale_domains);
  gimp->plug_in_locale_domains = NULL;
Elliot Lee's avatar
Elliot Lee committed
399

400
  for (list = gimp->plug_in_help_domains; list; list = list->next)
401
    {
402
      PlugInHelpDomain *domain = list->data;
403

404 405 406 407
      g_free (domain->prog_name);
      g_free (domain->domain_name);
      g_free (domain->domain_uri);
      g_free (domain);
Elliot Lee's avatar
Elliot Lee committed
408 409
    }

410 411
  g_slist_free (gimp->plug_in_help_domains);
  gimp->plug_in_help_domains = NULL;
Elliot Lee's avatar
Elliot Lee committed
412 413 414
}

void
415 416
plug_ins_add_internal (Gimp          *gimp,
                       PlugInProcDef *proc_def)
Elliot Lee's avatar
Elliot Lee committed
417
{
418
  g_return_if_fail (GIMP_IS_GIMP (gimp));
419 420
  g_return_if_fail (proc_def != NULL);

421 422
  gimp->plug_in_proc_defs = g_slist_prepend (gimp->plug_in_proc_defs,
                                             proc_def);
Elliot Lee's avatar
Elliot Lee committed
423 424
}

425
PlugInProcDef *
426 427 428 429 430
plug_ins_file_register_magic (Gimp        *gimp,
                              const gchar *name,
                              const gchar *extensions,
                              const gchar *prefixes,
                              const gchar *magics)
Elliot Lee's avatar
Elliot Lee committed
431
{
432 433
  PlugInProcDef *proc_def;
  GSList        *list;
Elliot Lee's avatar
Elliot Lee committed
434

435
  g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
Sven Neumann's avatar
Sven Neumann committed
436 437
  g_return_val_if_fail (name != NULL, NULL);

438
  if (gimp->current_plug_in && gimp->current_plug_in->plug_in_def)
439
    list = gimp->current_plug_in->plug_in_def->proc_defs;
Elliot Lee's avatar
Elliot Lee committed
440
  else
441
    list = gimp->plug_in_proc_defs;
Elliot Lee's avatar
Elliot Lee committed
442

443 444 445
  proc_def = plug_in_proc_def_find (list, name);

  if (proc_def)
Elliot Lee's avatar
Elliot Lee committed
446
    {
447
      proc_def->file_proc = TRUE;
Elliot Lee's avatar
Elliot Lee committed
448

449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477
      if (proc_def->extensions != extensions)
        {
          if (proc_def->extensions)
            g_free (proc_def->extensions);
          proc_def->extensions = g_strdup (extensions);
        }

      proc_def->extensions_list =
        plug_ins_extensions_parse (proc_def->extensions);

      if (proc_def->prefixes != prefixes)
        {
          if (proc_def->prefixes)
            g_free (proc_def->prefixes);
          proc_def->prefixes = g_strdup (prefixes);
        }

      proc_def->prefixes_list =
        plug_ins_extensions_parse (proc_def->prefixes);

      if (proc_def->magics != magics)
        {
          if (proc_def->magics)
            g_free (proc_def->magics);
          proc_def->magics = g_strdup (magics);
        }

      proc_def->magics_list =
        plug_ins_extensions_parse (proc_def->magics);
Elliot Lee's avatar
Elliot Lee committed
478 479
    }

480
  return proc_def;
Elliot Lee's avatar
Elliot Lee committed
481 482
}

483 484 485 486 487
PlugInProcDef *
plug_ins_file_register_mime (Gimp        *gimp,
                             const gchar *name,
                             const gchar *mime_type)
{
488 489
  PlugInProcDef *proc_def;
  GSList        *list;
490 491 492 493 494

  g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
  g_return_val_if_fail (name != NULL, NULL);
  g_return_val_if_fail (mime_type != NULL, NULL);

495
  if (gimp->current_plug_in && gimp->current_plug_in->plug_in_def)
496 497 498 499
    list = gimp->current_plug_in->plug_in_def->proc_defs;
  else
    list = gimp->plug_in_proc_defs;

500
  proc_def = plug_in_proc_def_find (list, name);
501

502 503 504 505 506
  if (proc_def)
    {
      if (proc_def->mime_type)
        g_free (proc_def->mime_type);
      proc_def->mime_type = g_strdup (mime_type);
507 508
    }

509
  return proc_def;
510 511
}

512 513 514 515 516
PlugInProcDef *
plug_ins_file_register_thumb_loader (Gimp        *gimp,
                                     const gchar *load_proc,
                                     const gchar *thumb_proc)
{
517 518
  PlugInProcDef *proc_def;
  GSList        *list;
519 520 521 522 523 524 525 526 527 528

  g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
  g_return_val_if_fail (load_proc, NULL);
  g_return_val_if_fail (thumb_proc, NULL);

  if (gimp->current_plug_in && gimp->current_plug_in->plug_in_def)
    list = gimp->current_plug_in->plug_in_def->proc_defs;
  else
    list = gimp->plug_in_proc_defs;

529
  proc_def = plug_in_proc_def_find (list, load_proc);
530

531 532 533 534
  if (proc_def)
    {
      if (proc_def->thumb_loader)
        g_free (proc_def->thumb_loader);
Sven Neumann's avatar
Sven Neumann committed
535

536
      proc_def->thumb_loader = g_strdup (thumb_proc);
537 538
    }

539
  return proc_def;
540 541
}

Elliot Lee's avatar
Elliot Lee committed
542
void
543 544
plug_ins_def_add_from_rc (Gimp      *gimp,
                          PlugInDef *plug_in_def)
Elliot Lee's avatar
Elliot Lee committed
545
{
546
  GSList *list;
547
  gchar  *basename1;
548

549
  g_return_if_fail (GIMP_IS_GIMP (gimp));
550 551 552 553 554 555 556 557 558
  g_return_if_fail (plug_in_def != NULL);
  g_return_if_fail (plug_in_def->prog != NULL);

  if (! g_path_is_absolute (plug_in_def->prog))
    {
      g_warning ("plug_ins_def_add_from_rc: filename not absolute (skipping)");
      plug_in_def_free (plug_in_def, TRUE);
      return;
    }
Elliot Lee's avatar
Elliot Lee committed
559

560
  basename1 = g_path_get_basename (plug_in_def->prog);
Elliot Lee's avatar
Elliot Lee committed
561

562 563 564 565 566 567 568
  /*  If this is a file load or save plugin, make sure we have
   *  something for one of the extensions, prefixes, or magic number.
   *  Other bits of code rely on detecting file plugins by the presence
   *  of one of these things, but Nick Lamb's alien/unknown format
   *  loader needs to be able to register no extensions, prefixes or
   *  magics. -- austin 13/Feb/99
   */
569
  for (list = plug_in_def->proc_defs; list; list = list->next)
570
    {
571
      PlugInProcDef *proc_def = list->data;
572

573 574 575
      if (! proc_def->extensions &&
          ! proc_def->prefixes   &&
          ! proc_def->magics     &&
576 577 578
	  proc_def->menu_paths   &&
	  (! strncmp (proc_def->menu_paths->data, "<Load>", 6) ||
	   ! strncmp (proc_def->menu_paths->data, "<Save>", 6)))
579
	{
580
	  proc_def->extensions = g_strdup ("");
581 582
	}
    }
583

584 585 586
  /*  Check if the entry mentioned in pluginrc matches an executable
   *  found in the plug_in_path.
   */
587
  for (list = gimp->plug_in_defs; list; list = list->next)
Elliot Lee's avatar
Elliot Lee committed
588
    {
589
      PlugInDef *ondisk_plug_in_def = list->data;
590
      gchar     *basename2;
Elliot Lee's avatar
Elliot Lee committed
591

592 593 594
      basename2 = g_path_get_basename (ondisk_plug_in_def->prog);

      if (! strcmp (basename1, basename2))
Elliot Lee's avatar
Elliot Lee committed
595
	{
596 597 598
	  if (! g_ascii_strcasecmp (plug_in_def->prog,
                                    ondisk_plug_in_def->prog) &&
	      (plug_in_def->mtime == ondisk_plug_in_def->mtime))
Elliot Lee's avatar
Elliot Lee committed
599
	    {
600
	      /* Use pluginrc entry, deleting ondisk entry */
601
	      list->data = plug_in_def;
602
	      plug_in_def_free (ondisk_plug_in_def, TRUE);
Elliot Lee's avatar
Elliot Lee committed
603 604 605
	    }
	  else
	    {
606 607
              /* Use ondisk entry, deleting pluginrc entry */
	      plug_in_def_free (plug_in_def, TRUE);
Elliot Lee's avatar
Elliot Lee committed
608
	    }
609 610

	  g_free (basename2);
611
	  g_free (basename1);
612

Elliot Lee's avatar
Elliot Lee committed
613 614
	  return;
	}
615 616

      g_free (basename2);
Elliot Lee's avatar
Elliot Lee committed
617 618
    }

619 620
  g_free (basename1);

621
  gimp->write_pluginrc = TRUE;
622 623
  g_printerr ("executable not found: '%s'\n",
              gimp_filename_to_utf8 (plug_in_def->prog));
624
  plug_in_def_free (plug_in_def, FALSE);
Elliot Lee's avatar
Elliot Lee committed
625 626
}

627 628
void
plug_ins_temp_proc_def_add (Gimp          *gimp,
629
                            PlugInProcDef *proc_def)
Elliot Lee's avatar
Elliot Lee committed
630
{
631 632
  g_return_if_fail (GIMP_IS_GIMP (gimp));
  g_return_if_fail (proc_def != NULL);
Sven Neumann's avatar
Sven Neumann committed
633

634
  if (! gimp->no_interface)
Elliot Lee's avatar
Elliot Lee committed
635
    {
636
      if (proc_def->menu_label || proc_def->menu_paths)
637
        gimp_menus_create_item (gimp, proc_def, NULL);
Elliot Lee's avatar
Elliot Lee committed
638 639
    }

640 641
  /*  Register the procedural database entry  */
  procedural_db_register (gimp, &proc_def->db_info);
Elliot Lee's avatar
Elliot Lee committed
642

643
  /*  Add the definition to the global list  */
644
  gimp->plug_in_proc_defs = g_slist_prepend (gimp->plug_in_proc_defs, proc_def);
645 646 647 648 649 650 651 652 653 654 655
}

void
plug_ins_temp_proc_def_remove (Gimp          *gimp,
                               PlugInProcDef *proc_def)
{
  g_return_if_fail (GIMP_IS_GIMP (gimp));
  g_return_if_fail (proc_def != NULL);

  if (! gimp->no_interface)
    {
656
      if (proc_def->menu_label || proc_def->menu_paths)
657
        gimp_menus_delete_item (gimp, proc_def);
Elliot Lee's avatar
Elliot Lee committed
658 659
    }

660 661 662 663
  /*  Unregister the procedural database entry  */
  procedural_db_unregister (gimp, proc_def->db_info.name);

  /*  Remove the definition from the global list  */
664
  gimp->plug_in_proc_defs = g_slist_remove (gimp->plug_in_proc_defs, proc_def);
665 666 667

  /*  Destroy the definition  */
  plug_in_proc_def_free (proc_def);
Elliot Lee's avatar
Elliot Lee committed
668 669
}

670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726
void
plug_ins_menu_branch_add (Gimp        *gimp,
                          const gchar *prog_name,
                          const gchar *menu_path,
                          const gchar *menu_label)
{
  PlugInMenuBranch *branch;

  g_return_if_fail (GIMP_IS_GIMP (gimp));
  g_return_if_fail (prog_name != NULL);
  g_return_if_fail (menu_path != NULL);
  g_return_if_fail (menu_label != NULL);

  branch = g_new (PlugInMenuBranch, 1);

  branch->prog_name  = g_strdup (prog_name);
  branch->menu_path  = g_strdup (menu_path);
  branch->menu_label = g_strdup (menu_label);

  gimp->plug_in_menu_branches = g_slist_append (gimp->plug_in_menu_branches,
                                                branch);

#ifdef VERBOSE
  g_print ("added menu branch \"%s\" at path \"%s\"\n",
           branch->menu_label, branch->menu_path);
#endif
}

void
plug_ins_locale_domain_add (Gimp        *gimp,
                            const gchar *prog_name,
                            const gchar *domain_name,
                            const gchar *domain_path)
{
  PlugInLocaleDomain *domain;

  g_return_if_fail (GIMP_IS_GIMP (gimp));
  g_return_if_fail (prog_name != NULL);
  g_return_if_fail (domain_name != NULL);

  domain = g_new (PlugInLocaleDomain, 1);

  domain->prog_name   = g_strdup (prog_name);
  domain->domain_name = g_strdup (domain_name);
  domain->domain_path = g_strdup (domain_path);

  gimp->plug_in_locale_domains = g_slist_prepend (gimp->plug_in_locale_domains,
                                                  domain);

#ifdef VERBOSE
  g_print ("added locale domain \"%s\" for path \"%s\"\n",
           domain->domain_name ? domain->domain_name : "(null)",
           domain->domain_path ?
           gimp_filename_to_utf8 (domain->domain_path) : "(null)");
#endif
}

727
const gchar *
728 729
plug_ins_locale_domain (Gimp         *gimp,
                        const gchar  *prog_name,
730
                        const gchar **domain_path)
731
{
732
  GSList *list;
733

734
  g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
735

736 737
  if (domain_path)
    *domain_path = gimp_locale_directory ();
738

739 740 741 742
  /*  A NULL prog_name is GIMP itself, return the default domain  */
  if (! prog_name)
    return NULL;

743
  for (list = gimp->plug_in_locale_domains; list; list = list->next)
744
    {
745
      PlugInLocaleDomain *domain = list->data;
746

747 748
      if (domain && domain->prog_name &&
          ! strcmp (domain->prog_name, prog_name))
749
        {
750 751
          if (domain_path && domain->domain_path)
            *domain_path = domain->domain_path;
752

753
          return domain->domain_name;
754 755 756 757 758 759
        }
    }

  return STD_PLUGINS_DOMAIN;
}

760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787
void
plug_ins_help_domain_add (Gimp        *gimp,
                          const gchar *prog_name,
                          const gchar *domain_name,
                          const gchar *domain_uri)
{
  PlugInHelpDomain *domain;

  g_return_if_fail (GIMP_IS_GIMP (gimp));
  g_return_if_fail (prog_name != NULL);
  g_return_if_fail (domain_name != NULL);

  domain = g_new (PlugInHelpDomain, 1);

  domain->prog_name   = g_strdup (prog_name);
  domain->domain_name = g_strdup (domain_name);
  domain->domain_uri  = g_strdup (domain_uri);

  gimp->plug_in_help_domains = g_slist_prepend (gimp->plug_in_help_domains,
                                                domain);

#ifdef VERBOSE
  g_print ("added help domain \"%s\" for base uri \"%s\"\n",
           domain->domain_name ? domain->domain_name : "(null)",
           domain->domain_uri  ? domain->domain_uri  : "(null)");
#endif
}

788
const gchar *
789 790 791
plug_ins_help_domain (Gimp         *gimp,
                      const gchar  *prog_name,
                      const gchar **domain_uri)
792
{
793
  GSList *list;
794

795
  g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
796

797 798 799
  if (domain_uri)
    *domain_uri = NULL;

800 801 802 803
  /*  A NULL prog_name is GIMP itself, return the default domain  */
  if (! prog_name)
    return NULL;

804
  for (list = gimp->plug_in_help_domains; list; list = list->next)
805
    {
806
      PlugInHelpDomain *domain = list->data;
807

808 809
      if (domain && domain->prog_name &&
          ! strcmp (domain->prog_name, prog_name))
810
        {
811 812
          if (domain_uri && domain->domain_uri)
            *domain_uri = domain->domain_uri;
813

814
          return domain->domain_name;
815
        }
816 817 818 819 820
    }

  return NULL;
}

821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838
gint
plug_ins_help_domains (Gimp    *gimp,
                       gchar ***help_domains,
                       gchar ***help_uris)
{
  GSList *list;
  gint    n_domains;
  gint    i;

  g_return_val_if_fail (GIMP_IS_GIMP (gimp), 0);
  g_return_val_if_fail (help_domains != NULL, 0);
  g_return_val_if_fail (help_uris != NULL, 0);

  n_domains = g_slist_length (gimp->plug_in_help_domains);

  *help_domains = g_new0 (gchar *, n_domains);
  *help_uris    = g_new0 (gchar *, n_domains);

839
  for (list = gimp->plug_in_help_domains, i = 0; list; list = list->next, i++)
840
    {
841
      PlugInHelpDomain *domain = list->data;
842

843 844
      (*help_domains)[i] = g_strdup (domain->domain_name);
      (*help_uris)[i]    = g_strdup (domain->domain_uri);
845 846 847 848 849
    }

  return n_domains;
}

850 851 852 853 854 855 856 857 858
PlugInProcDef *
plug_ins_proc_def_find (Gimp       *gimp,
                        ProcRecord *proc_rec)
{
  GSList *list;

  g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
  g_return_val_if_fail (proc_rec != NULL, NULL);

859
  for (list = gimp->plug_in_proc_defs; list; list = list->next)
860
    {
Sven Neumann's avatar
Sven Neumann committed
861
      PlugInProcDef *proc_def = list->data;
862 863 864 865 866 867 868 869

      if (proc_rec == &proc_def->db_info)
        return proc_def;
    }

  return NULL;
}

870 871 872
GSList *
plug_ins_extensions_parse (gchar *extensions)
{
873
  GSList *list = NULL;
874 875 876 877

  /* EXTENSIONS can be NULL.  Avoid calling strtok if it is.  */
  if (extensions)
    {
878 879 880
      gchar *extension;
      gchar *next_token;

881
      extensions = g_strdup