home *** CD-ROM | disk | FTP | other *** search
- /* The GIMP -- an image manipulation program
- * Copyright (C) 1995 Spencer Kimball and Peter Mattis
- *
- * 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
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
- #include "config.h"
-
- #ifdef HAVE_SYS_PARAM_H
- #include <sys/param.h>
- #endif
-
- #include <glib.h>
-
- #include <errno.h>
- #include <signal.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #ifdef HAVE_SYS_WAIT_H
- #include <sys/wait.h>
- #endif
- #ifdef HAVE_SYS_TIME_H
- #include <sys/time.h>
- #endif
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <time.h>
- #ifdef HAVE_UNISTD_H
- #include <unistd.h>
- #endif
-
- #if defined(G_OS_WIN32) || defined(G_WITH_CYGWIN)
- #define STRICT
- #include <windows.h>
- #include <process.h>
-
- #ifdef G_OS_WIN32
- #include <fcntl.h>
- #include <io.h>
- #endif
-
- #ifdef G_WITH_CYGWIN
- #define O_TEXT 0x0100 /* text file */
- #define _O_TEXT 0x0100 /* text file */
- #define O_BINARY 0x0200 /* binary file */
- #define _O_BINARY 0x0200 /* binary file */
- #endif
-
- #endif
-
- #ifdef __EMX__
- #include <fcntl.h>
- #include <process.h>
- #define _O_BINARY O_BINARY
- #define _P_NOWAIT P_NOWAIT
- #define xspawnv spawnv
- #endif
-
- #ifdef HAVE_IPC_H
- #include <sys/ipc.h>
- #endif
-
- #ifdef HAVE_SHM_H
- #include <sys/shm.h>
- #endif
-
- #include "apptypes.h"
-
- #include "app_procs.h"
- #include "appenv.h"
- #include "brush_select.h" /* Need for closing dialogs */
- #include "drawable.h"
- #include "datafiles.h"
- #include "errors.h"
- #include "gdisplay.h"
- #include "general.h"
- #include "gimage.h"
- #include "gimprc.h"
- #include "gradient_select.h"
- #include "menus.h"
- #include "pattern_select.h" /* Needed for closing pattern dialogs */
- #include "plug_in.h"
-
- #include "tile.h" /* ick. */
-
- #include "libgimp/gimpenv.h"
- #include "libgimp/gimpprotocol.h"
- #include "libgimp/gimpwire.h"
- #include "libgimp/gimpparasite.h"
-
- #include "libgimp/gimpintl.h"
-
-
- typedef struct _PlugInBlocked PlugInBlocked;
-
- struct _PlugInBlocked
- {
- PlugIn *plug_in;
- gchar *proc_name;
- };
-
-
- typedef struct _PlugInMenuEntry PlugInMenuEntry;
-
- struct _PlugInMenuEntry
- {
- PlugInProcDef *proc_def;
- gchar *domain;
- gchar *help_path;
- };
-
-
- typedef struct _PlugInHelpPathDef PlugInHelpPathDef;
-
- struct _PlugInHelpPathDef
- {
- gchar *prog_name;
- gchar *help_path;
- };
-
-
- static gboolean plug_in_write (GIOChannel *channel,
- guint8 *buf,
- gulong count);
- static gboolean plug_in_flush (GIOChannel *channel);
- static void plug_in_push (PlugIn *plug_in);
- static void plug_in_pop (void);
- static gboolean plug_in_recv_message (GIOChannel *channel,
- GIOCondition cond,
- gpointer data);
- static void plug_in_handle_message (WireMessage *msg);
- static void plug_in_handle_quit (void);
- static void plug_in_handle_tile_req (GPTileReq *tile_req);
- static void plug_in_handle_proc_run (GPProcRun *proc_run);
- static void plug_in_handle_proc_return (GPProcReturn *proc_return);
- static void plug_in_handle_proc_install (GPProcInstall *proc_install);
- static void plug_in_handle_proc_uninstall (GPProcUninstall *proc_uninstall);
- static void plug_in_write_rc (gchar *filename);
- static void plug_in_init_file (gchar *filename);
- static void plug_in_query (PlugInDef *plug_in_def);
- static void plug_in_add_to_db (void);
- static void plug_in_make_menu (void);
- static gint plug_in_make_menu_entry (gpointer foo,
- PlugInMenuEntry *menu_entry,
- gpointer bar);
- static void plug_in_callback (GtkWidget *widget,
- gpointer client_data);
- static void plug_in_proc_def_insert (PlugInProcDef *proc_def,
- void (* superceed_fn) (void *));
- static void plug_in_proc_def_dead (void *freed_proc_def);
- static void plug_in_proc_def_remove (PlugInProcDef *proc_def);
- static void plug_in_proc_def_destroy (PlugInProcDef *proc_def,
- gboolean data_only);
-
- static Argument * plug_in_temp_run (ProcRecord *proc_rec,
- Argument *args,
- gint argc);
- static Argument * plug_in_params_to_args (GPParam *params,
- gint nparams,
- gboolean full_copy);
- static GPParam * plug_in_args_to_params (Argument *args,
- gint nargs,
- gboolean full_copy);
- static void plug_in_params_destroy (GPParam *params,
- gint nparams,
- gboolean full_destroy);
- static void plug_in_args_destroy (Argument *args,
- gint nargs,
- gboolean full_destroy);
- static void plug_in_init_shm (void);
-
-
- PlugIn *current_plug_in = NULL;
- GSList *proc_defs = NULL;
-
- static GSList *plug_in_defs = NULL;
- static GSList *gimprc_proc_defs = NULL;
- static GSList *open_plug_ins = NULL;
- static GSList *blocked_plug_ins = NULL;
-
- static GSList *help_path_defs = NULL;
-
- static GSList *plug_in_stack = NULL;
- static GIOChannel *current_readchannel = NULL;
- static GIOChannel *current_writechannel = NULL;
- static gint current_write_buffer_index = 0;
- static gchar *current_write_buffer = NULL;
- static Argument *current_return_vals = NULL;
- static gint current_return_nvals = 0;
-
- static ProcRecord *last_plug_in = NULL;
-
- static gint shm_ID = -1;
- static guchar *shm_addr = NULL;
-
- #if defined(G_OS_WIN32) || defined(G_WITH_CYGWIN)
- static HANDLE shm_handle;
- #endif
-
- static gboolean write_pluginrc = FALSE;
-
- static gchar *std_plugins_domain = "gimp-std-plugins";
-
-
- static void
- plug_in_init_shm (void)
- {
- /* allocate a piece of shared memory for use in transporting tiles
- * to plug-ins. if we can't allocate a piece of shared memory then
- * we'll fall back on sending the data over the pipe.
- */
-
- #ifdef HAVE_SHM_H
- shm_ID = shmget (IPC_PRIVATE, TILE_WIDTH * TILE_HEIGHT * 4, IPC_CREAT | 0777);
-
- if (shm_ID == -1)
- g_message ("shmget() failed: Disabling shared memory tile transport.");
- else
- {
- shm_addr = (guchar *) shmat (shm_ID, NULL, 0);
- if (shm_addr == (guchar *) -1)
- {
- g_message ("shmat() failed: Disabling shared memory tile transport.");
- shmctl (shm_ID, IPC_RMID, NULL);
- shm_ID = -1;
- }
-
- #ifdef IPC_RMID_DEFERRED_RELEASE
- if (shm_addr != (guchar *) -1)
- shmctl (shm_ID, IPC_RMID, NULL);
- #endif
- }
- #else
- #if defined(G_OS_WIN32) || defined(G_WITH_CYGWIN)
- /* Use Win32 shared memory mechanisms for
- * transfering tile data.
- */
- gint pid;
- gchar fileMapName[MAX_PATH];
- gint tileByteSize = TILE_WIDTH * TILE_HEIGHT * 4;
-
- /* Our shared memory id will be our process ID */
- pid = GetCurrentProcessId ();
-
- /* From the id, derive the file map name */
- g_snprintf (fileMapName, sizeof (fileMapName), "GIMP%d.SHM", pid);
-
- /* Create the file mapping into paging space */
- shm_handle = CreateFileMapping ((HANDLE) 0xFFFFFFFF, NULL,
- PAGE_READWRITE, 0,
- tileByteSize, fileMapName);
-
- if (shm_handle)
- {
- /* Map the shared memory into our address space for use */
- shm_addr = (guchar *) MapViewOfFile(shm_handle,
- FILE_MAP_ALL_ACCESS,
- 0, 0, tileByteSize);
-
- /* Verify that we mapped our view */
- if (shm_addr)
- shm_ID = pid;
- else
- {
- g_warning ("MapViewOfFile error: %d... disabling shared memory transport\n", GetLastError());
- }
- }
- else
- {
- g_warning ("CreateFileMapping error: %d... disabling shared memory transport\n", GetLastError());
- }
- #endif
- #endif
- }
-
- void
- plug_in_init (void)
- {
- extern gboolean use_shm;
-
- gchar *filename;
- GSList *tmp;
- GSList *tmp2;
- PlugInDef *plug_in_def;
- PlugInProcDef *proc_def;
- gfloat nplugins;
- gfloat nth;
-
- /* initialize the gimp protocol library and set the read and
- * write handlers.
- */
- gp_init ();
- wire_set_writer (plug_in_write);
- wire_set_flusher (plug_in_flush);
-
- /* allocate a piece of shared memory for use in transporting tiles
- * to plug-ins. if we can't allocate a piece of shared memory then
- * we'll fall back on sending the data over the pipe.
- */
- if (use_shm)
- plug_in_init_shm ();
-
- /* search for binaries in the plug-in directory path */
- datafiles_read_directories (plug_in_path, plug_in_init_file, MODE_EXECUTABLE);
-
- /* read the pluginrc file for cached data */
- filename = NULL;
- if (pluginrc_path)
- {
- if (g_path_is_absolute (pluginrc_path))
- filename = g_strdup (pluginrc_path);
- else
- filename = g_strdup_printf ("%s" G_DIR_SEPARATOR_S "%s",
- gimp_directory (), pluginrc_path);
- }
- else
- filename = gimp_personal_rc_file ("pluginrc");
-
- app_init_update_status (_("Resource configuration"), filename, -1);
- parse_gimprc_file (filename);
-
- /* query any plug-ins that have changed since we last wrote out
- * the pluginrc file.
- */
- tmp = plug_in_defs;
- app_init_update_status (_("Plug-ins"), "", 0);
- nplugins = g_slist_length (tmp);
- nth = 0;
- while (tmp)
- {
- plug_in_def = tmp->data;
- tmp = tmp->next;
-
- if (plug_in_def->query)
- {
- write_pluginrc = TRUE;
-
- if (be_verbose)
- g_print (_("query plug-in: \"%s\"\n"), plug_in_def->prog);
-
- plug_in_query (plug_in_def);
- }
-
- app_init_update_status (NULL, plug_in_def->prog, nth / nplugins);
- nth++;
- }
-
- /* insert the proc defs */
- for (tmp = gimprc_proc_defs; tmp; tmp = g_slist_next (tmp))
- {
- proc_def = g_new (PlugInProcDef, 1);
- *proc_def = *((PlugInProcDef*) tmp->data);
- plug_in_proc_def_insert (proc_def, NULL);
- }
-
- tmp = plug_in_defs;
- while (tmp)
- {
- plug_in_def = tmp->data;
- tmp = tmp->next;
-
- tmp2 = plug_in_def->proc_defs;
- while (tmp2)
- {
- proc_def = tmp2->data;
- tmp2 = tmp2->next;
-
- proc_def->mtime = plug_in_def->mtime;
- plug_in_proc_def_insert (proc_def, plug_in_proc_def_dead);
- }
- }
-
- /* write the pluginrc file if necessary */
- if (write_pluginrc)
- {
- if (be_verbose)
- g_print (_("writing \"%s\"\n"), filename);
-
- plug_in_write_rc (filename);
- }
-
- g_free (filename);
-
- /* add the plug-in procs to the procedure database */
- plug_in_add_to_db ();
-
- /* make the menu */
- plug_in_make_menu ();
-
- /* run the available extensions */
- if (be_verbose)
- g_print (_("Starting extensions: "));
-
- app_init_update_status (_("Extensions"), "", 0);
-
- tmp = proc_defs;
- nplugins = g_slist_length (tmp); nth = 0;
-
- while (tmp)
- {
- proc_def = tmp->data;
- tmp = tmp->next;
-
- if (proc_def->prog &&
- (proc_def->db_info.num_args == 0) &&
- (proc_def->db_info.proc_type == PDB_EXTENSION))
- {
- if (be_verbose)
- g_print ("%s ", proc_def->db_info.name);
-
- app_init_update_status (NULL, proc_def->db_info.name,
- nth / nplugins);
-
- plug_in_run (&proc_def->db_info, NULL, 0, FALSE, TRUE, -1);
- }
- }
-
- if (be_verbose)
- g_print ("\n");
-
- /* create help path list and free up stuff */
- for (tmp = plug_in_defs; tmp; tmp = g_slist_next (tmp))
- {
- plug_in_def = tmp->data;
-
- if (plug_in_def->help_path)
- {
- PlugInHelpPathDef *help_path_def;
-
- help_path_def = g_new (PlugInHelpPathDef, 1);
-
- help_path_def->prog_name = g_strdup (plug_in_def->prog);
- help_path_def->help_path = g_strdup (plug_in_def->help_path);
-
- help_path_defs = g_slist_prepend (help_path_defs, help_path_def);
- }
-
- plug_in_def_free (plug_in_def, FALSE);
- }
-
- g_slist_free (plug_in_defs);
- plug_in_defs = NULL;
- }
-
-
- void
- plug_in_kill (void)
- {
- GSList *tmp;
- PlugIn *plug_in;
-
- #if defined(G_OS_WIN32) || defined(G_WITH_CYGWIN)
- CloseHandle (shm_handle);
- #else
- #ifdef HAVE_SHM_H
- #ifndef IPC_RMID_DEFERRED_RELEASE
- if (shm_ID != -1)
- {
- shmdt ((gchar *) shm_addr);
- shmctl (shm_ID, IPC_RMID, NULL);
- }
- #else /* IPC_RMID_DEFERRED_RELEASE */
- if (shm_ID != -1)
- shmdt ((gchar *) shm_addr);
- #endif
- #endif
- #endif
-
- tmp = open_plug_ins;
- while (tmp)
- {
- plug_in = tmp->data;
- tmp = tmp->next;
-
- plug_in_destroy (plug_in);
- }
- }
-
- void
- plug_in_add (gchar *prog,
- gchar *menu_path,
- gchar *accelerator)
- {
- PlugInProcDef *proc_def;
- GSList *tmp;
-
- if (strncmp ("plug_in_", prog, 8) != 0)
- {
- gchar *t = g_strdup_printf ("plug_in_%s", prog);
- g_free (prog);
- prog = t;
- }
-
- tmp = gimprc_proc_defs;
- while (tmp)
- {
- proc_def = tmp->data;
- tmp = tmp->next;
-
- if (strcmp (proc_def->db_info.name, prog) == 0)
- {
- if (proc_def->db_info.name)
- g_free (proc_def->db_info.name);
- if (proc_def->menu_path)
- g_free (proc_def->menu_path);
- if (proc_def->accelerator)
- g_free (proc_def->accelerator);
- if (proc_def->extensions)
- g_free (proc_def->extensions);
- if (proc_def->prefixes)
- g_free (proc_def->prefixes);
- if (proc_def->magics)
- g_free (proc_def->magics);
- if (proc_def->image_types)
- g_free (proc_def->image_types);
-
- proc_def->db_info.name = prog;
- proc_def->menu_path = menu_path;
- proc_def->accelerator = accelerator;
- proc_def->prefixes = NULL;
- proc_def->extensions = NULL;
- proc_def->magics = NULL;
- proc_def->image_types = NULL;
- return;
- }
- }
-
- proc_def = g_new0 (PlugInProcDef, 1);
- proc_def->db_info.name = prog;
- proc_def->menu_path = menu_path;
- proc_def->accelerator = accelerator;
-
- gimprc_proc_defs = g_slist_prepend (gimprc_proc_defs, proc_def);
- }
-
- gchar *
- plug_in_image_types (gchar *name)
- {
- PlugInDef *plug_in_def;
- PlugInProcDef *proc_def;
- GSList *tmp;
-
- if (current_plug_in)
- {
- plug_in_def = current_plug_in->user_data;
- tmp = plug_in_def->proc_defs;
- }
- else
- {
- tmp = proc_defs;
- }
-
- while (tmp)
- {
- proc_def = tmp->data;
- tmp = tmp->next;
-
- if (strcmp (proc_def->db_info.name, name) == 0)
- return proc_def->image_types;
- }
-
- return NULL;
- }
-
- GSList *
- plug_in_extensions_parse (gchar *extensions)
- {
- GSList *list;
- gchar *extension;
- gchar *next_token;
-
- list = NULL;
-
- /* EXTENSIONS can be NULL. Avoid calling strtok if it is. */
- if (extensions)
- {
- extensions = g_strdup (extensions);
- next_token = extensions;
- extension = strtok (next_token, " \t,");
- while (extension)
- {
- list = g_slist_prepend (list, g_strdup (extension));
- extension = strtok (NULL, " \t,");
- }
- g_free (extensions);
- }
-
- return g_slist_reverse (list);
- }
-
- void
- plug_in_add_internal (PlugInProcDef *proc_def)
- {
- proc_defs = g_slist_prepend (proc_defs, proc_def);
- }
-
- PlugInProcDef *
- plug_in_file_handler (gchar *name,
- gchar *extensions,
- gchar *prefixes,
- gchar *magics)
- {
- PlugInDef *plug_in_def;
- PlugInProcDef *proc_def;
- GSList *tmp;
-
- if (current_plug_in)
- {
- plug_in_def = current_plug_in->user_data;
- tmp = plug_in_def->proc_defs;
- }
- else
- {
- tmp = proc_defs;
- }
-
- while (tmp)
- {
- proc_def = tmp->data;
- tmp = tmp->next;
-
- if (strcmp (proc_def->db_info.name, name) == 0)
- {
- /* EXTENSIONS can be proc_def->extensions */
- 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_in_extensions_parse (proc_def->extensions);
-
- /* PREFIXES can be proc_def->prefixes */
- 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_in_extensions_parse (proc_def->prefixes);
-
- /* MAGICS can be proc_def->magics */
- 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_in_extensions_parse (proc_def->magics);
- return proc_def;
- }
- }
-
- return NULL;
- }
-
-
- PlugInDef *
- plug_in_def_new (gchar *prog)
- {
- PlugInDef *plug_in_def;
-
- g_return_val_if_fail (prog != NULL, NULL);
-
- plug_in_def = g_new (PlugInDef, 1);
-
- plug_in_def->prog = g_strdup (prog);
- plug_in_def->proc_defs = NULL;
- plug_in_def->locale_domain = NULL;
- plug_in_def->locale_path = NULL;
- plug_in_def->help_path = NULL;
- plug_in_def->mtime = 0;
- plug_in_def->query = FALSE;
-
- return plug_in_def;
- }
-
-
- void
- plug_in_def_free (PlugInDef *plug_in_def,
- gboolean free_proc_defs)
- {
- GSList *list;
-
- g_free (plug_in_def->prog);
- if (plug_in_def->locale_domain)
- g_free (plug_in_def->locale_domain);
- if (plug_in_def->locale_path)
- g_free (plug_in_def->locale_path);
- if (plug_in_def->help_path)
- g_free (plug_in_def->help_path);
-
- if (free_proc_defs)
- {
- for (list = plug_in_def->proc_defs; list; list = list->next)
- plug_in_proc_def_destroy ((PlugInProcDef *)(list->data), FALSE);
- }
-
- if (plug_in_def->proc_defs)
- g_slist_free (plug_in_def->proc_defs);
-
- g_free (plug_in_def);
- }
-
-
- void
- plug_in_def_add (PlugInDef *plug_in_def)
- {
- PlugInDef *tplug_in_def;
- PlugInProcDef *proc_def;
- GSList *tmp;
- gchar *t1, *t2;
-
- t1 = g_basename (plug_in_def->prog);
-
- /* 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
- */
- for (tmp = plug_in_def->proc_defs; tmp; tmp = g_slist_next (tmp))
- {
- proc_def = tmp->data;
-
- if (!proc_def->extensions && !proc_def->prefixes && !proc_def->magics &&
- proc_def->menu_path &&
- (!strncmp (proc_def->menu_path, "<Load>", 6) ||
- !strncmp (proc_def->menu_path, "<Save>", 6)))
- {
- proc_def->extensions = g_strdup ("");
- }
- }
-
- for (tmp = plug_in_defs; tmp; tmp = g_slist_next (tmp))
- {
- tplug_in_def = tmp->data;
-
- t2 = g_basename (tplug_in_def->prog);
-
- if (strcmp (t1, t2) == 0)
- {
- if ((g_strcasecmp (plug_in_def->prog, tplug_in_def->prog) == 0) &&
- (plug_in_def->mtime == tplug_in_def->mtime))
- {
- /* Use cached plug-in entry */
- tmp->data = plug_in_def;
- plug_in_def_free (tplug_in_def, TRUE);
- }
- else
- {
- plug_in_def_free (plug_in_def, TRUE);
- }
-
- return;
- }
- }
-
- write_pluginrc = TRUE;
- g_print ("\"%s\" executable not found\n", plug_in_def->prog);
- plug_in_def_free (plug_in_def, FALSE);
- }
-
- gchar *
- plug_in_menu_path (gchar *name)
- {
- PlugInDef *plug_in_def;
- PlugInProcDef *proc_def;
- GSList *tmp, *tmp2;
-
- for (tmp = plug_in_defs; tmp; tmp = g_slist_next (tmp))
- {
- plug_in_def = tmp->data;
-
- for (tmp2 = plug_in_def->proc_defs; tmp2; tmp2 = g_slist_next (tmp2))
- {
- proc_def = tmp2->data;
-
- if (strcmp (proc_def->db_info.name, name) == 0)
- return proc_def->menu_path;
- }
- }
-
- for (tmp = proc_defs; tmp; tmp = g_slist_next (tmp))
- {
- proc_def = tmp->data;
-
- if (strcmp (proc_def->db_info.name, name) == 0)
- return proc_def->menu_path;
- }
-
- return NULL;
- }
-
- gchar *
- plug_in_help_path (gchar *prog_name)
- {
- PlugInHelpPathDef *help_path_def;
- GSList *list;
-
- if (!prog_name || !strlen (prog_name))
- return NULL;
-
- for (list = help_path_defs; list; list = g_slist_next (list))
- {
- help_path_def = (PlugInHelpPathDef *) list->data;
-
- if (help_path_def &&
- help_path_def->prog_name &&
- strcmp (help_path_def->prog_name, prog_name) == 0)
- return help_path_def->help_path;
- }
-
- return NULL;
- }
-
- PlugIn *
- plug_in_new (gchar *name)
- {
- PlugIn *plug_in;
- gchar *path;
-
- if (!g_path_is_absolute (name))
- {
- path = search_in_path (plug_in_path, name);
- if (!path)
- {
- g_message (_("Unable to locate Plug-In: \"%s\""), name);
- return NULL;
- }
- }
- else
- {
- path = name;
- }
-
- plug_in = g_new (PlugIn, 1);
-
- plug_in->open = FALSE;
- plug_in->destroy = FALSE;
- plug_in->query = FALSE;
- plug_in->synchronous = FALSE;
- plug_in->recurse = FALSE;
- plug_in->busy = FALSE;
- plug_in->pid = 0;
- plug_in->args[0] = g_strdup (path);
- plug_in->args[1] = g_strdup ("-gimp");
- plug_in->args[2] = NULL;
- plug_in->args[3] = NULL;
- plug_in->args[4] = NULL;
- plug_in->args[5] = NULL;
- plug_in->args[6] = NULL;
- plug_in->my_read = NULL;
- plug_in->my_write = NULL;
- plug_in->his_read = NULL;
- plug_in->his_write = NULL;
- plug_in->input_id = 0;
- plug_in->write_buffer_index = 0;
- plug_in->temp_proc_defs = NULL;
- plug_in->progress = NULL;
- plug_in->user_data = NULL;
-
- return plug_in;
- }
-
- void
- plug_in_destroy (PlugIn *plug_in)
- {
- if (plug_in)
- {
- plug_in_close (plug_in, TRUE);
-
- if (plug_in->args[0])
- g_free (plug_in->args[0]);
- if (plug_in->args[1])
- g_free (plug_in->args[1]);
- if (plug_in->args[2])
- g_free (plug_in->args[2]);
- if (plug_in->args[3])
- g_free (plug_in->args[3]);
- if (plug_in->args[4])
- g_free (plug_in->args[4]);
- if (plug_in->args[5])
- g_free (plug_in->args[5]);
-
- if (plug_in->progress)
- progress_end (plug_in->progress);
- plug_in->progress = NULL;
-
- if (plug_in == current_plug_in)
- plug_in_pop ();
-
- if (!plug_in->destroy)
- g_free (plug_in);
- }
- }
-
- #ifdef G_OS_WIN32
- /* The Microsoft _spawnv() does not allow to run scripts. But
- * this is essential to get scripting extension up and running.
- * Following the replacement function xspawnv().
- */
- gint
- xspawnv (gint mode,
- const gchar *cmdname,
- const gchar *const *argv)
- {
- gchar sExecutable[_MAX_PATH*2];
- gchar** sArgsList;
- gchar sCmndLine[1024];
- gchar* sPath;
- HINSTANCE hInst;
- gint i;
- gint pid;
-
- /* only use it if _spawnv fails */
- pid = _spawnv (mode, cmdname, argv);
- if (pid != -1) return pid;
-
- /* stuff parameters into one cmndline */
- sCmndLine[0] = 0;
- for (i = 1; argv[i] != NULL; i++)
- {
- strcat (sCmndLine, argv[i]);
- strcat (sCmndLine, " ");
- }
- /* remove last blank */
- sCmndLine[strlen (sCmndLine)-1] = 0;
-
- /* do we really need _spawnv (ShelExecute seems not to do it)*/
- if (32 <= (int) FindExecutable (cmdname,
- gimp_directory (),
- sExecutable))
- {
- /* g_print("_spawnlp %s %s %s", sExecutable, cmdname, sCmndLine); */
-
- pid = _spawnlp (mode, sExecutable, "-c", cmdname, sCmndLine, NULL);
- }
- else
- {
- g_warning ("Execution error for: %s", cmdname);
- return -1;
- }
- return pid;
- }
-
- #endif /* G_OS_WIN32 */
-
- gboolean
- plug_in_open (PlugIn *plug_in)
- {
- gint my_read[2];
- gint my_write[2];
-
- if (plug_in)
- {
- /* Open two pipes. (Bidirectional communication).
- */
- if ((pipe (my_read) == -1) || (pipe (my_write) == -1))
- {
- g_message ("pipe() failed: Unable to start Plug-In \"%s\"\n(%s)",
- g_basename (plug_in->args[0]), plug_in->args[0]);
- return FALSE;
- }
-
- #if defined(G_WITH_CYGWIN) || defined(__EMX__)
- /* Set to binary mode */
- setmode (my_read[0], _O_BINARY);
- setmode (my_write[0], _O_BINARY);
- setmode (my_read[1], _O_BINARY);
- setmode (my_write[1], _O_BINARY);
- #endif
-
- plug_in->my_read = g_io_channel_unix_new (my_read[0]);
- plug_in->my_write = g_io_channel_unix_new (my_write[1]);
- plug_in->his_read = g_io_channel_unix_new (my_write[0]);
- plug_in->his_write = g_io_channel_unix_new (my_read[1]);
-
- /* Remember the file descriptors for the pipes.
- */
- plug_in->args[2] =
- g_strdup_printf ("%d", g_io_channel_unix_get_fd (plug_in->his_read));
- plug_in->args[3] =
- g_strdup_printf ("%d", g_io_channel_unix_get_fd (plug_in->his_write));
-
- /* Set the rest of the command line arguments.
- */
- if (plug_in->query)
- {
- plug_in->args[4] = g_strdup ("-query");
- }
- else
- {
- plug_in->args[4] = g_strdup ("-run");
- }
-
- plug_in->args[5] = g_strdup_printf ("%d", (gint) stack_trace_mode);
-
- /* Fork another process. We'll remember the process id
- * so that we can later use it to kill the filter if
- * necessary.
- */
- #ifdef __EMX__
- fcntl (my_read[0], F_SETFD, 1);
- fcntl (my_write[1], F_SETFD, 1);
- #endif
- #if defined(G_OS_WIN32) || defined (G_WITH_CYGWIN) || defined(__EMX__)
- plug_in->pid = xspawnv (_P_NOWAIT, plug_in->args[0], plug_in->args);
- if (plug_in->pid == -1)
- #else
- plug_in->pid = fork ();
-
- if (plug_in->pid == 0)
- {
- g_io_channel_close (plug_in->my_read);
- g_io_channel_unref (plug_in->my_read);
- plug_in->my_read = NULL;
- g_io_channel_close (plug_in->my_write);
- g_io_channel_unref (plug_in->my_write);
- plug_in->my_write = NULL;
-
- /* Execute the filter. The "_exit" call should never
- * be reached, unless some strange error condition
- * exists.
- */
- execvp (plug_in->args[0], plug_in->args);
- _exit (1);
- }
- else if (plug_in->pid == -1)
- #endif
- {
- g_message ("fork() failed: Unable to run Plug-In: \"%s\"\n(%s)",
- g_basename (plug_in->args[0]), plug_in->args[0]);
- plug_in_destroy (plug_in);
- return FALSE;
- }
-
- g_io_channel_close (plug_in->his_read);
- g_io_channel_unref (plug_in->his_read);
- plug_in->his_read = NULL;
- g_io_channel_close (plug_in->his_write);
- g_io_channel_unref (plug_in->his_write);
- plug_in->his_write = NULL;
-
- if (!plug_in->synchronous)
- {
- plug_in->input_id =
- g_io_add_watch (plug_in->my_read,
- G_IO_IN | G_IO_PRI | G_IO_ERR | G_IO_HUP,
- plug_in_recv_message,
- plug_in);
-
- open_plug_ins = g_slist_prepend (open_plug_ins, plug_in);
- }
-
- plug_in->open = TRUE;
- return TRUE;
- }
-
- return FALSE;
- }
-
- void
- plug_in_close (PlugIn *plug_in,
- gboolean kill_it)
- {
- gint status;
- #ifndef G_OS_WIN32
- struct timeval tv;
- #endif
-
- if (plug_in && plug_in->open)
- {
- plug_in->open = FALSE;
-
- /* Ask the filter to exit gracefully
- */
- if (kill_it && plug_in->pid)
- {
- plug_in_push (plug_in);
- gp_quit_write (current_writechannel);
- plug_in_pop ();
-
- /* give the plug-in some time (10 ms) */
- #ifndef G_OS_WIN32
- tv.tv_sec = 0;
- tv.tv_usec = 100; /* But this is 0.1 ms? */
- select (0, NULL, NULL, NULL, &tv);
- #else
- Sleep (10);
- #endif
- }
-
- /* If necessary, kill the filter. */
- #ifndef G_OS_WIN32
- if (kill_it && plug_in->pid)
- status = kill (plug_in->pid, SIGKILL);
-
- /* Wait for the process to exit. This will happen
- * immediately if it was just killed.
- */
- if (plug_in->pid)
- waitpid (plug_in->pid, &status, 0);
- #else
- if (kill_it && plug_in->pid)
- {
- /* Trying to avoid TerminateProcess (does mostly work).
- * Otherwise some of our needed DLLs may get into an unstable state
- * (see Win32 API docs).
- */
- DWORD dwExitCode = STILL_ACTIVE;
- DWORD dwTries = 10;
- while ((STILL_ACTIVE == dwExitCode)
- && GetExitCodeProcess((HANDLE) plug_in->pid, &dwExitCode)
- && (dwTries > 0))
- {
- Sleep(10);
- dwTries--;
- }
- if (STILL_ACTIVE == dwExitCode)
- {
- g_warning("Terminating %s ...", plug_in->args[0]);
- TerminateProcess ((HANDLE) plug_in->pid, 0);
- }
- }
- #endif
-
- /* Remove the input handler. */
- if (plug_in->input_id)
- gdk_input_remove (plug_in->input_id);
-
- /* Close the pipes. */
- if (plug_in->my_read != NULL)
- {
- g_io_channel_close (plug_in->my_read);
- g_io_channel_unref (plug_in->my_read);
- plug_in->my_read = NULL;
- }
- if (plug_in->my_write != NULL)
- {
- g_io_channel_close (plug_in->my_write);
- g_io_channel_unref (plug_in->my_write);
- plug_in->my_write = NULL;
- }
- if (plug_in->his_read != NULL)
- {
- g_io_channel_close (plug_in->his_read);
- g_io_channel_unref (plug_in->his_read);
- plug_in->his_read = NULL;
- }
- if (plug_in->his_write != NULL)
- {
- g_io_channel_close (plug_in->his_write);
- g_io_channel_unref (plug_in->his_write);
- plug_in->his_write = NULL;
- }
-
- wire_clear_error ();
-
- /* Destroy the progress dialog if it exists. */
- if (plug_in->progress)
- progress_end (plug_in->progress);
- plug_in->progress = NULL;
-
- /* Set the fields to null values. */
- plug_in->pid = 0;
- plug_in->input_id = 0;
- plug_in->my_read = NULL;
- plug_in->my_write = NULL;
- plug_in->his_read = NULL;
- plug_in->his_write = NULL;
-
- if (plug_in->recurse)
- gtk_main_quit ();
-
- plug_in->synchronous = FALSE;
- plug_in->recurse = FALSE;
-
- /* Unregister any temporary procedures. */
- if (plug_in->temp_proc_defs)
- {
- GSList *list;
- PlugInProcDef *proc_def;
-
- for (list = plug_in->temp_proc_defs; list; list = g_slist_next (list))
- {
- proc_def = (PlugInProcDef *) list->data;
- plug_in_proc_def_remove (proc_def);
- }
-
- g_slist_free (plug_in->temp_proc_defs);
- plug_in->temp_proc_defs = NULL;
- }
-
- /* Close any dialogs that this plugin might have opened */
- brushes_check_dialogs ();
- patterns_check_dialogs ();
- gradients_check_dialogs ();
-
- open_plug_ins = g_slist_remove (open_plug_ins, plug_in);
- }
- }
-
- static Argument *
- plug_in_get_current_return_vals (ProcRecord *proc_rec)
- {
- Argument *return_vals;
- gint nargs;
-
- /* Return the status code plus the current return values. */
- nargs = proc_rec->num_values + 1;
- if (current_return_vals && current_return_nvals == nargs)
- {
- return_vals = current_return_vals;
- }
- else if (current_return_vals)
- {
- /* Allocate new return values of the correct size. */
- return_vals = procedural_db_return_args (proc_rec, FALSE);
-
- /* Copy all of the arguments we can. */
- memcpy (return_vals, current_return_vals,
- sizeof (Argument) * MIN (current_return_nvals, nargs));
-
- /* Free the old argument pointer. This will cause a memory leak
- only if there were more values returned than we need (which
- shouldn't ever happen). */
- g_free (current_return_vals);
- }
- else
- {
- /* Just return a dummy set of values. */
- return_vals = procedural_db_return_args (proc_rec, FALSE);
- }
-
- /* We have consumed any saved values, so clear them. */
- current_return_nvals = 0;
- current_return_vals = NULL;
-
- return return_vals;
- }
-
- Argument *
- plug_in_run (ProcRecord *proc_rec,
- Argument *args,
- gint argc,
- gboolean synchronous,
- gboolean destroy_values,
- gint gdisp_ID)
- {
- GPConfig config;
- GPProcRun proc_run;
- Argument *return_vals;
- PlugIn *plug_in;
-
- return_vals = NULL;
-
- if (proc_rec->proc_type == PDB_TEMPORARY)
- {
- return_vals = plug_in_temp_run (proc_rec, args, argc);
- goto done;
- }
-
- plug_in = plug_in_new (proc_rec->exec_method.plug_in.filename);
-
- if (plug_in)
- {
- if (plug_in_open (plug_in))
- {
- plug_in->recurse = synchronous;
-
- plug_in_push (plug_in);
-
- config.version = GP_VERSION;
- config.tile_width = TILE_WIDTH;
- config.tile_height = TILE_HEIGHT;
- config.shm_ID = shm_ID;
- config.gamma = gamma_val;
- config.install_cmap = install_cmap;
- config.use_xshm = gdk_get_use_xshm ();
- config.gdisp_ID = gdisp_ID;
-
- if (gtk_check_version (1, 2, 8))
- config.min_colors = CLAMP (min_colors, 27, 216);
- else
- config.min_colors = CLAMP (min_colors, 27, 256);
-
- proc_run.name = proc_rec->name;
- proc_run.nparams = argc;
- proc_run.params = plug_in_args_to_params (args, argc, FALSE);
-
- if (!gp_config_write (current_writechannel, &config) ||
- !gp_proc_run_write (current_writechannel, &proc_run) ||
- !wire_flush (current_writechannel))
- {
- return_vals = procedural_db_return_args (proc_rec, FALSE);
- goto done;
- }
-
- plug_in_pop ();
-
- plug_in_params_destroy (proc_run.params, proc_run.nparams, FALSE);
-
- /* If this is an automatically installed extension, wait for an
- * installation-confirmation message
- */
- if ((proc_rec->proc_type == PDB_EXTENSION) &&
- (proc_rec->num_args == 0))
- gtk_main ();
-
- if (plug_in->recurse)
- {
- gtk_main ();
- return_vals = plug_in_get_current_return_vals (proc_rec);
- }
- }
- }
-
- done:
- if (return_vals && destroy_values)
- {
- procedural_db_destroy_args (return_vals, proc_rec->num_values);
- return_vals = NULL;
- }
- return return_vals;
- }
-
- void
- plug_in_repeat (gboolean with_interface)
- {
- GDisplay *gdisplay;
- Argument *args;
- gint i;
-
- if (last_plug_in)
- {
- gdisplay = gdisplay_active ();
- if (!gdisplay) return;
-
- /* construct the procedures arguments */
- args = g_new (Argument, 3);
-
- /* initialize the first three argument types */
- for (i = 0; i < 3; i++)
- args[i].arg_type = last_plug_in->args[i].arg_type;
-
- /* initialize the first three plug-in arguments */
- args[0].value.pdb_int = (with_interface ? RUN_INTERACTIVE : RUN_WITH_LAST_VALS);
- args[1].value.pdb_int = pdb_image_to_id (gdisplay->gimage);
- args[2].value.pdb_int = drawable_ID (gimage_active_drawable (gdisplay->gimage));
-
- /* run the plug-in procedure */
- plug_in_run (last_plug_in, args, 3, FALSE, TRUE, gdisplay->ID);
-
- g_free (args);
- }
- }
-
- void
- plug_in_set_menu_sensitivity (GimpImageType type)
- {
- PlugInProcDef *proc_def;
- GSList *tmp;
- gboolean sensitive = FALSE;
-
- for (tmp = proc_defs; tmp; tmp = g_slist_next (tmp))
- {
- proc_def = tmp->data;
-
- if (proc_def->image_types_val && proc_def->menu_path)
- {
- switch (type)
- {
- case RGB_GIMAGE:
- sensitive = proc_def->image_types_val & PLUG_IN_RGB_IMAGE;
- break;
- case RGBA_GIMAGE:
- sensitive = proc_def->image_types_val & PLUG_IN_RGBA_IMAGE;
- break;
- case GRAY_GIMAGE:
- sensitive = proc_def->image_types_val & PLUG_IN_GRAY_IMAGE;
- break;
- case GRAYA_GIMAGE:
- sensitive = proc_def->image_types_val & PLUG_IN_GRAYA_IMAGE;
- break;
- case INDEXED_GIMAGE:
- sensitive = proc_def->image_types_val & PLUG_IN_INDEXED_IMAGE;
- break;
- case INDEXEDA_GIMAGE:
- sensitive = proc_def->image_types_val & PLUG_IN_INDEXEDA_IMAGE;
- break;
- default:
- sensitive = FALSE;
- break;
- }
-
- menus_set_sensitive (proc_def->menu_path, sensitive);
-
- if (last_plug_in && (last_plug_in == &(proc_def->db_info)))
- {
- menus_set_sensitive ("<Image>/Filters/Repeat Last", sensitive);
- menus_set_sensitive ("<Image>/Filters/Re-Show Last", sensitive);
- }
- }
- }
-
- if (!last_plug_in)
- {
- menus_set_sensitive ("<Image>/Filters/Repeat Last", FALSE);
- menus_set_sensitive ("<Image>/Filters/Re-Show Last", FALSE);
- }
- }
-
- static gboolean
- plug_in_recv_message (GIOChannel *channel,
- GIOCondition cond,
- gpointer data)
- {
- gboolean got_message = FALSE;
-
- if ((PlugIn *) data != current_plug_in)
- plug_in_push ((PlugIn *) data);
-
- if (current_readchannel == NULL)
- return TRUE;
-
- if (cond & (G_IO_IN | G_IO_PRI))
- {
- WireMessage msg;
-
- memset (&msg, 0, sizeof (WireMessage));
-
- if (!wire_read_msg (current_readchannel, &msg))
- {
- plug_in_close (current_plug_in, TRUE);
- }
- else
- {
- plug_in_handle_message (&msg);
- wire_destroy (&msg);
- got_message = TRUE;
- }
-
- }
-
- if (cond & (G_IO_ERR | G_IO_HUP))
- {
- if (current_plug_in->open)
- {
- plug_in_close (current_plug_in, TRUE);
- }
- }
-
- if (!got_message)
- g_message (_("Plug-In crashed: \"%s\"\n(%s)\n\n"
- "The dying Plug-In may have messed up GIMP's internal state.\n"
- "You may want to save your images and restart GIMP\n"
- "to be on the safe side."),
- g_basename (current_plug_in->args[0]),
- current_plug_in->args[0]);
-
- if (!current_plug_in->open)
- plug_in_destroy (current_plug_in);
- else
- plug_in_pop ();
-
- return TRUE;
- }
-
- static void
- plug_in_handle_message (WireMessage *msg)
- {
- switch (msg->type)
- {
- case GP_QUIT:
- plug_in_handle_quit ();
- break;
- case GP_CONFIG:
- g_warning ("plug_in_handle_message(): "
- "received a config message (should not happen)");
- plug_in_close (current_plug_in, TRUE);
- break;
- case GP_TILE_REQ:
- plug_in_handle_tile_req (msg->data);
- break;
- case GP_TILE_ACK:
- g_warning ("plug_in_handle_message(): "
- "received a tile ack message (should not happen)");
- plug_in_close (current_plug_in, TRUE);
- break;
- case GP_TILE_DATA:
- g_warning ("plug_in_handle_message(): "
- "received a tile data message (should not happen)");
- plug_in_close (current_plug_in, TRUE);
- break;
- case GP_PROC_RUN:
- plug_in_handle_proc_run (msg->data);
- break;
- case GP_PROC_RETURN:
- plug_in_handle_proc_return (msg->data);
- plug_in_close (current_plug_in, FALSE);
- break;
- case GP_TEMP_PROC_RUN:
- g_warning ("plug_in_handle_message(): "
- "received a temp proc run message (should not happen)");
- plug_in_close (current_plug_in, TRUE);
- break;
- case GP_TEMP_PROC_RETURN:
- plug_in_handle_proc_return (msg->data);
- gtk_main_quit ();
- break;
- case GP_PROC_INSTALL:
- plug_in_handle_proc_install (msg->data);
- break;
- case GP_PROC_UNINSTALL:
- plug_in_handle_proc_uninstall (msg->data);
- break;
- case GP_EXTENSION_ACK:
- gtk_main_quit ();
- break;
- }
- }
-
- static void
- plug_in_handle_quit (void)
- {
- plug_in_close (current_plug_in, FALSE);
- }
-
- static void
- plug_in_handle_tile_req (GPTileReq *tile_req)
- {
- GPTileData tile_data;
- GPTileData *tile_info;
- WireMessage msg;
- TileManager *tm;
- Tile *tile;
-
- if (tile_req->drawable_ID == -1)
- {
- tile_data.drawable_ID = -1;
- tile_data.tile_num = 0;
- tile_data.shadow = 0;
- tile_data.bpp = 0;
- tile_data.width = 0;
- tile_data.height = 0;
- tile_data.use_shm = (shm_ID == -1) ? FALSE : TRUE;
- tile_data.data = NULL;
-
- if (!gp_tile_data_write (current_writechannel, &tile_data))
- {
- g_warning ("plug_in_handle_tile_req: ERROR");
- plug_in_close (current_plug_in, TRUE);
- return;
- }
-
- if (!wire_read_msg (current_readchannel, &msg))
- {
- g_warning ("plug_in_handle_tile_req: ERROR");
- plug_in_close (current_plug_in, TRUE);
- return;
- }
-
- if (msg.type != GP_TILE_DATA)
- {
- g_warning ("expected tile data and received: %d", msg.type);
- plug_in_close (current_plug_in, TRUE);
- return;
- }
-
- tile_info = msg.data;
-
- if (tile_info->shadow)
- tm = drawable_shadow (drawable_get_ID (tile_info->drawable_ID));
- else
- tm = drawable_data (drawable_get_ID (tile_info->drawable_ID));
-
- if (!tm)
- {
- g_warning ("plug-in requested invalid drawable (killing)");
- plug_in_close (current_plug_in, TRUE);
- return;
- }
-
- tile = tile_manager_get (tm, tile_info->tile_num, TRUE, TRUE);
- if (!tile)
- {
- g_warning ("plug-in requested invalid tile (killing)");
- plug_in_close (current_plug_in, TRUE);
- return;
- }
-
- if (tile_data.use_shm)
- memcpy (tile_data_pointer (tile, 0, 0), shm_addr, tile_size (tile));
- else
- memcpy (tile_data_pointer (tile, 0, 0), tile_info->data, tile_size (tile));
-
- tile_release (tile, TRUE);
-
- wire_destroy (&msg);
- if (!gp_tile_ack_write (current_writechannel))
- {
- g_warning ("plug_in_handle_tile_req: ERROR");
- plug_in_close (current_plug_in, TRUE);
- return;
- }
- }
- else
- {
- if (tile_req->shadow)
- tm = drawable_shadow (drawable_get_ID (tile_req->drawable_ID));
- else
- tm = drawable_data (drawable_get_ID (tile_req->drawable_ID));
-
- if (!tm)
- {
- g_warning ("plug-in requested invalid drawable (killing)");
- plug_in_close (current_plug_in, TRUE);
- return;
- }
-
- tile = tile_manager_get (tm, tile_req->tile_num, TRUE, FALSE);
- if (!tile)
- {
- g_warning ("plug-in requested invalid tile (killing)");
- plug_in_close (current_plug_in, TRUE);
- return;
- }
-
- tile_data.drawable_ID = tile_req->drawable_ID;
- tile_data.tile_num = tile_req->tile_num;
- tile_data.shadow = tile_req->shadow;
- tile_data.bpp = tile_bpp (tile);
- tile_data.width = tile_ewidth (tile);
- tile_data.height = tile_eheight (tile);
- tile_data.use_shm = (shm_ID == -1) ? FALSE : TRUE;
-
- if (tile_data.use_shm)
- memcpy (shm_addr, tile_data_pointer (tile, 0, 0), tile_size (tile));
- else
- tile_data.data = tile_data_pointer (tile, 0, 0);
-
- if (!gp_tile_data_write (current_writechannel, &tile_data))
- {
- g_message ("plug_in_handle_tile_req: ERROR");
- plug_in_close (current_plug_in, TRUE);
- return;
- }
-
- tile_release (tile, FALSE);
-
- if (!wire_read_msg (current_readchannel, &msg))
- {
- g_message ("plug_in_handle_tile_req: ERROR");
- plug_in_close (current_plug_in, TRUE);
- return;
- }
-
- if (msg.type != GP_TILE_ACK)
- {
- g_warning ("expected tile ack and received: %d", msg.type);
- plug_in_close (current_plug_in, TRUE);
- return;
- }
-
- wire_destroy (&msg);
- }
- }
-
- static void
- plug_in_handle_proc_run (GPProcRun *proc_run)
- {
- GPProcReturn proc_return;
- ProcRecord *proc_rec;
- Argument *args;
- Argument *return_vals;
- PlugInBlocked *blocked;
-
- args = plug_in_params_to_args (proc_run->params, proc_run->nparams, FALSE);
- proc_rec = procedural_db_lookup (proc_run->name);
-
- if (proc_rec)
- {
- return_vals = procedural_db_execute (proc_run->name, args);
- }
- else
- {
- /* if the name lookup failed, construct a
- * dummy "executiuon error" return value --Michael
- */
- return_vals = g_new (Argument, 1);
- return_vals[0].arg_type = PDB_STATUS;
- return_vals[0].value.pdb_int = PDB_EXECUTION_ERROR;
- }
-
- if (return_vals)
- {
- proc_return.name = proc_run->name;
-
- if (proc_rec)
- {
- proc_return.nparams = proc_rec->num_values + 1;
- proc_return.params = plug_in_args_to_params (return_vals, proc_rec->num_values + 1, FALSE);
- }
- else
- {
- proc_return.nparams = 1;
- proc_return.params = plug_in_args_to_params (return_vals, 1, FALSE);
- }
-
- if (!gp_proc_return_write (current_writechannel, &proc_return))
- {
- g_warning ("plug_in_handle_proc_run: ERROR");
- plug_in_close (current_plug_in, TRUE);
- return;
- }
-
- plug_in_args_destroy (args, proc_run->nparams, FALSE);
- plug_in_args_destroy (return_vals, (proc_rec ? (proc_rec->num_values + 1) : 1), TRUE);
- plug_in_params_destroy (proc_return.params, proc_return.nparams, FALSE);
- }
- else
- {
- blocked = g_new (PlugInBlocked, 1);
- blocked->plug_in = current_plug_in;
- blocked->proc_name = g_strdup (proc_run->name);
- blocked_plug_ins = g_slist_prepend (blocked_plug_ins, blocked);
- }
- }
-
- static void
- plug_in_handle_proc_return (GPProcReturn *proc_return)
- {
- PlugInBlocked *blocked;
- GSList *tmp;
-
- if (current_plug_in->recurse)
- {
- current_return_vals = plug_in_params_to_args (proc_return->params,
- proc_return->nparams,
- TRUE);
- current_return_nvals = proc_return->nparams;
- }
- else
- {
- tmp = blocked_plug_ins;
- while (tmp)
- {
- blocked = tmp->data;
- tmp = tmp->next;
-
- if (strcmp (blocked->proc_name, proc_return->name) == 0)
- {
- plug_in_push (blocked->plug_in);
- if (!gp_proc_return_write (current_writechannel, proc_return))
- {
- g_message ("plug_in_handle_proc_run: ERROR");
- plug_in_close (current_plug_in, TRUE);
- return;
- }
- plug_in_pop ();
-
- blocked_plug_ins = g_slist_remove (blocked_plug_ins, blocked);
- g_free (blocked->proc_name);
- g_free (blocked);
- break;
- }
- }
- }
- }
-
- static void
- plug_in_handle_proc_install (GPProcInstall *proc_install)
- {
- PlugInDef *plug_in_def = NULL;
- PlugInProcDef *proc_def;
- ProcRecord *proc = NULL;
- PlugInMenuEntry *menu_entry;
- GSList *tmp = NULL;
- gchar *prog = NULL;
- gboolean add_proc_def;
- gint i;
-
- /* Argument checking
- * --only sanity check arguments when the procedure requests a menu path
- */
-
- if (proc_install->menu_path)
- {
- if (strncmp (proc_install->menu_path, "<Toolbox>", 9) == 0)
- {
- if ((proc_install->nparams < 1) ||
- (proc_install->params[0].type != PDB_INT32))
- {
- g_message ("Plug-In \"%s\"\n(%s)\n"
- "attempted to install procedure \"%s\"\n"
- "which does not take the standard Plug-In args.",
- g_basename (current_plug_in->args[0]),
- current_plug_in->args[0],
- proc_install->name);
- return;
- }
- }
- else if (strncmp (proc_install->menu_path, "<Image>", 7) == 0)
- {
- if ((proc_install->nparams < 3) ||
- (proc_install->params[0].type != PDB_INT32) ||
- (proc_install->params[1].type != PDB_IMAGE) ||
- (proc_install->params[2].type != PDB_DRAWABLE))
- {
- g_message ("Plug-In \"%s\"\n(%s)\n"
- "attempted to install procedure \"%s\"\n"
- "which does not take the standard Plug-In args.",
- g_basename (current_plug_in->args[0]),
- current_plug_in->args[0],
- proc_install->name);
- return;
- }
- }
- else if (strncmp (proc_install->menu_path, "<Load>", 6) == 0)
- {
- if ((proc_install->nparams < 3) ||
- (proc_install->params[0].type != PDB_INT32) ||
- (proc_install->params[1].type != PDB_STRING) ||
- (proc_install->params[2].type != PDB_STRING))
- {
- g_message ("Plug-In \"%s\"\n(%s)\n"
- "attempted to install procedure \"%s\"\n"
- "which does not take the standard Plug-In args.",
- g_basename (current_plug_in->args[0]),
- current_plug_in->args[0],
- proc_install->name);
- return;
- }
- }
- else if (strncmp (proc_install->menu_path, "<Save>", 6) == 0)
- {
- if ((proc_install->nparams < 5) ||
- (proc_install->params[0].type != PDB_INT32) ||
- (proc_install->params[1].type != PDB_IMAGE) ||
- (proc_install->params[2].type != PDB_DRAWABLE) ||
- (proc_install->params[3].type != PDB_STRING) ||
- (proc_install->params[4].type != PDB_STRING))
- {
- g_message ("Plug-In \"%s\"\n(%s)\n"
- "attempted to install procedure \"%s\"\n"
- "which does not take the standard Plug-In args.",
- g_basename (current_plug_in->args[0]),
- current_plug_in->args[0],
- proc_install->name);
- return;
- }
- }
- else
- {
- g_message ("Plug-In \"%s\"\n(%s)\n"
- "attempted to install procedure \"%s\"\n"
- "in an invalid menu location.\n"
- "Use either \"<Toolbox>\", \"<Image>\", "
- "\"<Load>\", or \"<Save>\".",
- g_basename (current_plug_in->args[0]),
- current_plug_in->args[0],
- proc_install->name);
- return;
- }
- }
-
- /* Sanity check for array arguments */
-
- for (i = 1; i < proc_install->nparams; i++)
- {
- if ((proc_install->params[i].type == PDB_INT32ARRAY ||
- proc_install->params[i].type == PDB_INT8ARRAY ||
- proc_install->params[i].type == PDB_FLOATARRAY ||
- proc_install->params[i].type == PDB_STRINGARRAY) &&
- proc_install->params[i-1].type != PDB_INT32)
- {
- g_message ("Plug-In \"%s\"\n(%s)\n"
- "attempted to install procedure \"%s\"\n"
- "which fails to comply with the array parameter\n"
- "passing standard. Argument %d is noncompliant.",
- g_basename (current_plug_in->args[0]),
- current_plug_in->args[0],
- proc_install->name, i);
- return;
- }
- }
-
-
- /* Initialization */
-
- proc_def = NULL;
-
- switch (proc_install->type)
- {
- case PDB_PLUGIN:
- case PDB_EXTENSION:
- plug_in_def = current_plug_in->user_data;
- prog = plug_in_def->prog;
-
- tmp = plug_in_def->proc_defs;
- break;
-
- case PDB_TEMPORARY:
- prog = "none";
-
- tmp = current_plug_in->temp_proc_defs;
- break;
- }
-
- while (tmp)
- {
- proc_def = tmp->data;
- tmp = tmp->next;
-
- if (strcmp (proc_def->db_info.name, proc_install->name) == 0)
- {
- if (proc_install->type == PDB_TEMPORARY)
- plug_in_proc_def_remove (proc_def);
- else
- plug_in_proc_def_destroy (proc_def, TRUE); /* destroys data_only */
-
- break;
- }
-
- proc_def = NULL;
- }
-
- add_proc_def = FALSE;
- if (!proc_def)
- {
- add_proc_def = TRUE;
- proc_def = g_new (PlugInProcDef, 1);
- }
-
- proc_def->prog = g_strdup (prog);
-
- proc_def->menu_path = g_strdup (proc_install->menu_path);
- proc_def->accelerator = NULL;
- proc_def->extensions = NULL;
- proc_def->prefixes = NULL;
- proc_def->magics = NULL;
- proc_def->image_types = g_strdup (proc_install->image_types);
- proc_def->image_types_val = plug_in_image_types_parse (proc_def->image_types);
- /* Install temp one use todays time */
- proc_def->mtime = time (NULL);
-
- proc = &proc_def->db_info;
-
- /* The procedural database procedure */
-
- proc->name = g_strdup (proc_install->name);
- proc->blurb = g_strdup (proc_install->blurb);
- proc->help = g_strdup (proc_install->help);
- proc->author = g_strdup (proc_install->author);
- proc->copyright = g_strdup (proc_install->copyright);
- proc->date = g_strdup (proc_install->date);
- proc->proc_type = proc_install->type;
-
- proc->num_args = proc_install->nparams;
- proc->num_values = proc_install->nreturn_vals;
-
- proc->args = g_new (ProcArg, proc->num_args);
- proc->values = g_new (ProcArg, proc->num_values);
-
- for (i = 0; i < proc->num_args; i++)
- {
- proc->args[i].arg_type = proc_install->params[i].type;
- proc->args[i].name = g_strdup (proc_install->params[i].name);
- proc->args[i].description = g_strdup (proc_install->params[i].description);
- }
-
- for (i = 0; i < proc->num_values; i++)
- {
- proc->values[i].arg_type = proc_install->return_vals[i].type;
- proc->values[i].name = g_strdup (proc_install->return_vals[i].name);
- proc->values[i].description = g_strdup (proc_install->return_vals[i].description);
- }
-
- switch (proc_install->type)
- {
- case PDB_PLUGIN:
- case PDB_EXTENSION:
- if (add_proc_def)
- plug_in_def->proc_defs = g_slist_prepend (plug_in_def->proc_defs, proc_def);
- break;
-
- case PDB_TEMPORARY:
- if (add_proc_def)
- current_plug_in->temp_proc_defs =
- g_slist_prepend (current_plug_in->temp_proc_defs, proc_def);
-
- proc_defs = g_slist_append (proc_defs, proc_def);
- proc->exec_method.temporary.plug_in = (void *) current_plug_in;
- procedural_db_register (proc);
-
- /* If there is a menu path specified, create a menu entry */
- if (proc_install->menu_path)
- {
- menu_entry = g_new (PlugInMenuEntry, 1);
- menu_entry->proc_def = proc_def;
-
- /* Below we use a hack to allow translations of Script-Fu paths.
- * Would be nice if we could solve this properly, but I haven't
- * found a way yet ... (Sven)
- */
- if (plug_in_def && plug_in_def->locale_domain)
- menu_entry->domain = plug_in_def->locale_domain;
- else if (strncmp (proc_def->db_info.name, "script_fu", 9) == 0)
- menu_entry->domain = "gimp-script-fu";
- else
- menu_entry->domain = std_plugins_domain;
-
- if (plug_in_def)
- menu_entry->help_path = plug_in_def->help_path;
- else
- menu_entry->help_path = NULL;
-
- /* plug_in_make_menu_entry frees the menu_entry for us */
- plug_in_make_menu_entry (NULL, menu_entry, NULL);
- }
- break;
- }
- }
-
- static void
- plug_in_handle_proc_uninstall (GPProcUninstall *proc_uninstall)
- {
- PlugInProcDef *proc_def;
- GSList *tmp;
-
- tmp = current_plug_in->temp_proc_defs;
- while (tmp)
- {
- proc_def = tmp->data;
- tmp = tmp->next;
-
- if (strcmp (proc_def->db_info.name, proc_uninstall->name) == 0)
- {
- current_plug_in->temp_proc_defs = g_slist_remove (current_plug_in->temp_proc_defs, proc_def);
- plug_in_proc_def_remove (proc_def);
- break;
- }
- }
- }
-
- static gboolean
- plug_in_write (GIOChannel *channel,
- guint8 *buf,
- gulong count)
- {
- gulong bytes;
-
- while (count > 0)
- {
- if ((current_write_buffer_index + count) >= WRITE_BUFFER_SIZE)
- {
- bytes = WRITE_BUFFER_SIZE - current_write_buffer_index;
- memcpy (¤t_write_buffer[current_write_buffer_index], buf, bytes);
- current_write_buffer_index += bytes;
- if (!wire_flush (channel))
- return FALSE;
- }
- else
- {
- bytes = count;
- memcpy (¤t_write_buffer[current_write_buffer_index], buf, bytes);
- current_write_buffer_index += bytes;
- }
-
- buf += bytes;
- count -= bytes;
- }
-
- return TRUE;
- }
-
- static gboolean
- plug_in_flush (GIOChannel *channel)
- {
- GIOError error;
- gint count;
- guint bytes;
-
- if (current_write_buffer_index > 0)
- {
- count = 0;
- while (count != current_write_buffer_index)
- {
- do {
- bytes = 0;
- error = g_io_channel_write (channel, ¤t_write_buffer[count],
- (current_write_buffer_index - count),
- &bytes);
- } while (error == G_IO_ERROR_AGAIN);
-
- if (error != G_IO_ERROR_NONE)
- return FALSE;
-
- count += bytes;
- }
-
- current_write_buffer_index = 0;
- }
-
- return TRUE;
- }
-
- static void
- plug_in_push (PlugIn *plug_in)
- {
- if (plug_in)
- {
- current_plug_in = plug_in;
- plug_in_stack = g_slist_prepend (plug_in_stack, current_plug_in);
-
- current_readchannel = current_plug_in->my_read;
- current_writechannel = current_plug_in->my_write;
- current_write_buffer_index = current_plug_in->write_buffer_index;
- current_write_buffer = current_plug_in->write_buffer;
- }
- else
- {
- current_readchannel = NULL;
- current_writechannel = NULL;
- current_write_buffer_index = 0;
- current_write_buffer = NULL;
- }
- }
-
- static void
- plug_in_pop (void)
- {
- GSList *tmp;
-
- if (current_plug_in)
- {
- current_plug_in->write_buffer_index = current_write_buffer_index;
-
- tmp = plug_in_stack;
- plug_in_stack = plug_in_stack->next;
- tmp->next = NULL;
- g_slist_free (tmp);
- }
-
- if (plug_in_stack)
- {
- current_plug_in = plug_in_stack->data;
- current_readchannel = current_plug_in->my_read;
- current_writechannel = current_plug_in->my_write;
- current_write_buffer_index = current_plug_in->write_buffer_index;
- current_write_buffer = current_plug_in->write_buffer;
- }
- else
- {
- current_plug_in = NULL;
- current_readchannel = NULL;
- current_writechannel = NULL;
- current_write_buffer_index = 0;
- current_write_buffer = NULL;
- }
- }
-
- static void
- plug_in_write_rc_string (FILE *fp,
- gchar *str)
- {
- fputc ('"', fp);
-
- if (str)
- while (*str)
- {
- if (*str == '\n')
- {
- fputc ('\\', fp);
- fputc ('n', fp);
- }
- else if (*str == '\r')
- {
- fputc ('\\', fp);
- fputc ('r', fp);
- }
- else if (*str == '\032') /* ^Z is problematic on Windows */
- {
- fputc ('\\', fp);
- fputc ('z', fp);
- }
- else
- {
- if ((*str == '"') || (*str == '\\'))
- fputc ('\\', fp);
- fputc (*str, fp);
- }
- str += 1;
- }
-
- fputc ('"', fp);
- }
-
- static void
- plug_in_write_rc (gchar *filename)
- {
- FILE *fp;
- PlugInDef *plug_in_def;
- PlugInProcDef *proc_def;
- GSList *tmp;
- GSList *tmp2;
- gint i;
-
- fp = fopen (filename, "w");
- if (!fp)
- return;
-
- tmp = plug_in_defs;
- while (tmp)
- {
- plug_in_def = tmp->data;
- tmp = tmp->next;
-
- if (plug_in_def->proc_defs)
- {
- fprintf (fp, "(plug-in-def ");
- plug_in_write_rc_string (fp, plug_in_def->prog);
- fprintf (fp, " %ld", (long) plug_in_def->mtime);
- tmp2 = plug_in_def->proc_defs;
- if (tmp2)
- fprintf (fp, "\n");
-
- while (tmp2)
- {
- proc_def = tmp2->data;
- tmp2 = tmp2->next;
-
- fprintf (fp, "\t(proc-def \"%s\" %d\n",
- proc_def->db_info.name, proc_def->db_info.proc_type);
- fprintf (fp, "\t\t");
- plug_in_write_rc_string (fp, proc_def->db_info.blurb);
- fprintf (fp, "\n\t\t");
- plug_in_write_rc_string (fp, proc_def->db_info.help);
- fprintf (fp, "\n\t\t");
- plug_in_write_rc_string (fp, proc_def->db_info.author);
- fprintf (fp, "\n\t\t");
- plug_in_write_rc_string (fp, proc_def->db_info.copyright);
- fprintf (fp, "\n\t\t");
- plug_in_write_rc_string (fp, proc_def->db_info.date);
- fprintf (fp, "\n\t\t");
- plug_in_write_rc_string (fp, proc_def->menu_path);
- fprintf (fp, "\n\t\t");
- plug_in_write_rc_string (fp, proc_def->extensions);
- fprintf (fp, "\n\t\t");
- plug_in_write_rc_string (fp, proc_def->prefixes);
- fprintf (fp, "\n\t\t");
- plug_in_write_rc_string (fp, proc_def->magics);
- fprintf (fp, "\n\t\t");
- plug_in_write_rc_string (fp, proc_def->image_types);
- fprintf (fp, "\n\t\t%d %d\n",
- proc_def->db_info.num_args, proc_def->db_info.num_values);
-
- for (i = 0; i < proc_def->db_info.num_args; i++)
- {
- fprintf (fp, "\t\t(proc-arg %d ",
- proc_def->db_info.args[i].arg_type);
-
- plug_in_write_rc_string (fp, proc_def->db_info.args[i].name);
- plug_in_write_rc_string (fp, proc_def->db_info.args[i].description);
-
- fprintf (fp, ")%s",
- (proc_def->db_info.num_values ||
- (i < (proc_def->db_info.num_args - 1))) ? "\n" : "");
- }
-
- for (i = 0; i < proc_def->db_info.num_values; i++)
- {
- fprintf (fp, "\t\t(proc-arg %d ",
- proc_def->db_info.values[i].arg_type);
-
- plug_in_write_rc_string (fp, proc_def->db_info.values[i].name);
- plug_in_write_rc_string (fp, proc_def->db_info.values[i].description);
-
- fprintf (fp, ")%s", (i < (proc_def->db_info.num_values - 1)) ? "\n" : "");
- }
-
- fprintf (fp, ")");
-
- if (tmp2)
- fprintf (fp, "\n");
- }
-
- if (plug_in_def->locale_domain)
- {
- fprintf (fp, "\n\t(locale-def \"%s\"", plug_in_def->locale_domain);
- if (plug_in_def->locale_path)
- fprintf (fp, " \"%s\")", plug_in_def->locale_path);
- else
- fprintf (fp, ")");
- }
-
- if (plug_in_def->help_path)
- {
- fprintf (fp, "\n\t(help-def \"%s\")", plug_in_def->help_path);
- }
-
- fprintf (fp, ")\n");
-
- if (tmp)
- fprintf (fp, "\n");
- }
-
- }
-
- fclose (fp);
- }
-
- static void
- plug_in_init_file (gchar *filename)
- {
- GSList *tmp;
- PlugInDef *plug_in_def;
- gchar *plug_in_name;
- gchar *name;
-
- name = g_basename (filename);
-
- plug_in_def = NULL;
- tmp = plug_in_defs;
-
- while (tmp)
- {
- plug_in_def = tmp->data;
- tmp = tmp->next;
-
- plug_in_name = g_basename (plug_in_def->prog);
-
- if (g_strcasecmp (name, plug_in_name) == 0)
- {
- g_print ("duplicate plug-in: \"%s\" (skipping)\n", filename);
- return;
- }
-
- plug_in_def = NULL;
- }
-
- plug_in_def = plug_in_def_new (filename);
- plug_in_def->mtime = datafile_mtime ();
- plug_in_def->query = TRUE;
-
- plug_in_defs = g_slist_append (plug_in_defs, plug_in_def);
- }
-
- static void
- plug_in_query (PlugInDef *plug_in_def)
- {
- PlugIn *plug_in;
- WireMessage msg;
-
- plug_in = plug_in_new (plug_in_def->prog);
- if (plug_in)
- {
- plug_in->query = TRUE;
- plug_in->synchronous = TRUE;
- plug_in->user_data = plug_in_def;
-
- if (plug_in_open (plug_in))
- {
- plug_in_push (plug_in);
-
- while (plug_in->open)
- {
- if (!wire_read_msg (current_readchannel, &msg))
- plug_in_close (current_plug_in, TRUE);
- else
- {
- plug_in_handle_message (&msg);
- wire_destroy (&msg);
- }
- }
-
- plug_in_pop ();
- plug_in_destroy (plug_in);
- }
- }
- }
-
- static void
- plug_in_add_to_db (void)
- {
- PlugInProcDef *proc_def;
- Argument args[4];
- Argument *return_vals;
- GSList *tmp;
-
- tmp = proc_defs;
-
- while (tmp)
- {
- proc_def = tmp->data;
- tmp = tmp->next;
-
- if (proc_def->prog && (proc_def->db_info.proc_type != PDB_INTERNAL))
- {
- proc_def->db_info.exec_method.plug_in.filename = proc_def->prog;
- procedural_db_register (&proc_def->db_info);
- }
- }
-
- for (tmp = proc_defs; tmp; tmp = tmp->next)
- {
- proc_def = tmp->data;
-
- if (proc_def->extensions || proc_def->prefixes || proc_def->magics)
- {
- args[0].arg_type = PDB_STRING;
- args[0].value.pdb_pointer = proc_def->db_info.name;
-
- args[1].arg_type = PDB_STRING;
- args[1].value.pdb_pointer = proc_def->extensions;
-
- args[2].arg_type = PDB_STRING;
- args[2].value.pdb_pointer = proc_def->prefixes;
-
- args[3].arg_type = PDB_STRING;
- args[3].value.pdb_pointer = proc_def->magics;
-
- if (proc_def->image_types)
- {
- return_vals = procedural_db_execute ("gimp_register_save_handler", args);
- g_free (return_vals);
- }
- else
- {
- return_vals = procedural_db_execute ("gimp_register_magic_load_handler", args);
- g_free (return_vals);
- }
- }
- }
- }
-
- /* The following function has to be a GTraverseFunction,
- * but is also called directly. Please note that it frees the
- * menu_entry strcuture. --Sven
- */
- static gint
- plug_in_make_menu_entry (gpointer foo,
- PlugInMenuEntry *menu_entry,
- gpointer bar)
- {
- GimpItemFactoryEntry entry;
- gchar *help_page;
-
- if (menu_entry->help_path)
- {
- help_page = g_strconcat (menu_entry->help_path,
- "@", /* HACK: locale subdir */
- g_basename (menu_entry->proc_def->prog),
- ".html",
- NULL);
- }
- else
- {
- help_page = g_strconcat ("filters/", /* _not_ G_DIR_SEPARATOR_S */
- g_basename (menu_entry->proc_def->prog),
- ".html",
- NULL);
- }
-
- g_strdown (help_page);
-
- entry.entry.path = menu_entry->proc_def->menu_path;
- entry.entry.accelerator = menu_entry->proc_def->accelerator;
- entry.entry.callback = plug_in_callback;
- entry.entry.callback_action = 0;
- entry.entry.item_type = NULL;
- entry.help_page = help_page;
- entry.description = NULL;
-
- menus_create_item_from_full_path (&entry,
- menu_entry->domain,
- &menu_entry->proc_def->db_info);
- g_free (menu_entry);
-
- return FALSE;
- }
-
- static void
- plug_in_make_menu (void)
- {
- PlugInDef *plug_in_def;
- PlugInProcDef *proc_def;
- PlugInMenuEntry *menu_entry;
- GSList *domains = NULL;
- GSList *procs;
- GSList *tmp;
- GTree *menu_entries;
-
- #ifdef ENABLE_NLS
- bindtextdomain (std_plugins_domain, LOCALEDIR);
- domains = g_slist_append (domains, std_plugins_domain);
- #endif
-
- #ifdef ENABLE_NLS
- menu_entries = g_tree_new ((GCompareFunc)strcoll);
- #else
- menu_entries = g_tree_new ((GCompareFunc)strcmp);
- #endif
-
- tmp = plug_in_defs;
- while (tmp)
- {
- plug_in_def = tmp->data;
- tmp = tmp->next;
-
- procs = plug_in_def->proc_defs;
-
- if (!procs)
- continue;
-
- #ifdef ENABLE_NLS
- {
- gchar *domain;
- GSList *list;
- gboolean found = FALSE;
-
- if (plug_in_def->locale_domain)
- {
- domain = plug_in_def->locale_domain;
- for (list = domains; list && !found; list = list->next)
- {
- if (strcmp (domain, (gchar*)(list->data)) == 0)
- found = TRUE;
- }
- if (!found)
- {
- domains = g_slist_append (domains, domain);
- if (plug_in_def->locale_path)
- bindtextdomain (domain, plug_in_def->locale_path);
- else
- bindtextdomain (domain, LOCALEDIR);
- }
- }
- }
- #endif /* ENABLE_NLS */
-
- while (procs)
- {
- proc_def = procs->data;
- procs = procs->next;
-
- if (proc_def->prog && proc_def->menu_path && (!proc_def->extensions &&
- !proc_def->prefixes &&
- !proc_def->magics))
- {
- menu_entry = g_new (PlugInMenuEntry, 1);
- menu_entry->proc_def = proc_def;
- menu_entry->domain = plug_in_def->locale_domain ?
- plug_in_def->locale_domain : std_plugins_domain;
- menu_entry->help_path = plug_in_def->help_path;
-
- g_tree_insert (menu_entries,
- dgettext (menu_entry->domain, proc_def->menu_path),
- menu_entry);
- }
- }
- }
-
- g_tree_traverse (menu_entries,
- (GTraverseFunc)plug_in_make_menu_entry, G_IN_ORDER, NULL);
- g_tree_destroy (menu_entries);
-
- g_slist_free (domains);
- }
-
-
- static void
- plug_in_callback (GtkWidget *widget,
- gpointer client_data)
- {
- GDisplay *gdisplay;
- ProcRecord *proc_rec;
- Argument *args;
- gint i;
- gint gdisp_ID = -1;
- gint argc = 0; /* calm down a gcc warning. */
-
- /* get the active gdisplay */
- gdisplay = gdisplay_active ();
-
- proc_rec = (ProcRecord *) client_data;
-
- /* construct the procedures arguments */
- args = g_new0 (Argument, proc_rec->num_args);
-
- /* initialize the argument types */
- for (i = 0; i < proc_rec->num_args; i++)
- args[i].arg_type = proc_rec->args[i].arg_type;
-
- switch (proc_rec->proc_type)
- {
- case PDB_EXTENSION:
- /* initialize the first argument */
- args[0].value.pdb_int = RUN_INTERACTIVE;
- argc = 1;
- break;
-
- case PDB_PLUGIN:
- if (gdisplay)
- {
- gdisp_ID = gdisplay->ID;
-
- /* initialize the first 3 plug-in arguments */
- args[0].value.pdb_int = RUN_INTERACTIVE;
- args[1].value.pdb_int = pdb_image_to_id (gdisplay->gimage);
- args[2].value.pdb_int = drawable_ID (gimage_active_drawable (gdisplay->gimage));
- argc = 3;
- }
- else
- {
- g_warning ("Uh-oh, no active gdisplay for the plug-in!");
- g_free (args);
- return;
- }
- break;
-
- case PDB_TEMPORARY:
- args[0].value.pdb_int = RUN_INTERACTIVE;
- argc = 1;
- if (proc_rec->num_args >= 3 &&
- proc_rec->args[1].arg_type == PDB_IMAGE &&
- proc_rec->args[2].arg_type == PDB_DRAWABLE)
- {
- if (gdisplay)
- {
- gdisp_ID = gdisplay->ID;
-
- args[1].value.pdb_int = pdb_image_to_id (gdisplay->gimage);
- args[2].value.pdb_int = drawable_ID (gimage_active_drawable (gdisplay->gimage));
- argc = 3;
- }
- else
- {
- g_warning ("Uh-oh, no active gdisplay for the temporary procedure!");
- g_free (args);
- return;
- }
- }
- break;
-
- default:
- g_error ("Unknown procedure type.");
- g_free (args);
- return;
- }
-
- /* run the plug-in procedure */
- plug_in_run (proc_rec, args, argc, FALSE, TRUE, gdisp_ID);
-
- if (proc_rec->proc_type == PDB_PLUGIN)
- last_plug_in = proc_rec;
-
- g_free (args);
- }
-
- static void
- plug_in_proc_def_insert (PlugInProcDef *proc_def,
- void (*superceed_fn)(void*))
- {
- PlugInProcDef *tmp_proc_def;
- GSList *tmp;
- GSList *prev;
- GSList *list;
-
- prev = NULL;
- tmp = proc_defs;
-
- while (tmp)
- {
- tmp_proc_def = tmp->data;
-
- if (strcmp (proc_def->db_info.name, tmp_proc_def->db_info.name) == 0)
- {
- tmp->data = proc_def;
-
- if (proc_def->menu_path)
- g_free (proc_def->menu_path);
- if (proc_def->accelerator)
- g_free (proc_def->accelerator);
-
- proc_def->menu_path = tmp_proc_def->menu_path;
- proc_def->accelerator = tmp_proc_def->accelerator;
-
- tmp_proc_def->menu_path = NULL;
- tmp_proc_def->accelerator = NULL;
-
- if (superceed_fn)
- (* superceed_fn) (tmp_proc_def);
-
- plug_in_proc_def_destroy (tmp_proc_def, FALSE);
- return;
- }
- else if (!proc_def->menu_path ||
- (tmp_proc_def->menu_path &&
- (strcmp (proc_def->menu_path, tmp_proc_def->menu_path) < 0)))
- {
- list = g_slist_alloc ();
- list->data = proc_def;
-
- list->next = tmp;
- if (prev)
- prev->next = list;
- else
- proc_defs = list;
- return;
- }
-
- prev = tmp;
- tmp = tmp->next;
- }
-
- proc_defs = g_slist_append (proc_defs, proc_def);
- }
-
- /* called when plug_in_proc_def_insert causes a proc_def to be
- * overridden and thus g_free()d.
- */
- static void
- plug_in_proc_def_dead (void *freed_proc_def)
- {
- GSList *tmp;
- PlugInDef *plug_in_def;
- PlugInProcDef *proc_def = freed_proc_def;
-
- g_warning ("removing duplicate PDB procedure \"%s\"",
- proc_def->db_info.name);
-
- /* search the plugin list to see if any plugins had references to
- * the recently freed proc_def.
- */
- for (tmp = plug_in_defs; tmp; tmp = g_slist_next (tmp))
- {
- plug_in_def = tmp->data;
-
- plug_in_def->proc_defs = g_slist_remove (plug_in_def->proc_defs,
- freed_proc_def);
- }
- }
-
- static void
- plug_in_proc_def_remove (PlugInProcDef *proc_def)
- {
- /* Destroy the menu item */
- if (proc_def->menu_path)
- menus_destroy (proc_def->menu_path);
-
- /* Unregister the procedural database entry */
- procedural_db_unregister (proc_def->db_info.name);
-
- /* Remove the defintion from the global list */
- proc_defs = g_slist_remove (proc_defs, proc_def);
-
- /* Destroy the definition */
- plug_in_proc_def_destroy (proc_def, TRUE);
- }
-
- static void
- plug_in_proc_def_destroy (PlugInProcDef *proc_def,
- gboolean data_only)
- {
- gint i;
-
- if (proc_def->prog)
- g_free (proc_def->prog);
- if (proc_def->menu_path)
- g_free (proc_def->menu_path);
- if (proc_def->accelerator)
- g_free (proc_def->accelerator);
- if (proc_def->extensions)
- g_free (proc_def->extensions);
- if (proc_def->prefixes)
- g_free (proc_def->prefixes);
- if (proc_def->magics)
- g_free (proc_def->magics);
- if (proc_def->image_types)
- g_free (proc_def->image_types);
- if (proc_def->db_info.name)
- g_free (proc_def->db_info.name);
- if (proc_def->db_info.blurb)
- g_free (proc_def->db_info.blurb);
- if (proc_def->db_info.help)
- g_free (proc_def->db_info.help);
- if (proc_def->db_info.author)
- g_free (proc_def->db_info.author);
- if (proc_def->db_info.copyright)
- g_free (proc_def->db_info.copyright);
- if (proc_def->db_info.date)
- g_free (proc_def->db_info.date);
-
- for (i = 0; i < proc_def->db_info.num_args; i++)
- {
- if (proc_def->db_info.args[i].name)
- g_free (proc_def->db_info.args[i].name);
- if (proc_def->db_info.args[i].description)
- g_free (proc_def->db_info.args[i].description);
- }
-
- for (i = 0; i < proc_def->db_info.num_values; i++)
- {
- if (proc_def->db_info.values[i].name)
- g_free (proc_def->db_info.values[i].name);
- if (proc_def->db_info.values[i].description)
- g_free (proc_def->db_info.values[i].description);
- }
-
- if (proc_def->db_info.args)
- g_free (proc_def->db_info.args);
- if (proc_def->db_info.values)
- g_free (proc_def->db_info.values);
-
- if (!data_only)
- g_free (proc_def);
- }
-
- static Argument *
- plug_in_temp_run (ProcRecord *proc_rec,
- Argument *args,
- gint argc)
- {
- Argument *return_vals;
- PlugIn *plug_in;
- GPProcRun proc_run;
- gint old_recurse;
-
- return_vals = NULL;
-
- plug_in = (PlugIn *) proc_rec->exec_method.temporary.plug_in;
-
- if (plug_in)
- {
- if (plug_in->busy)
- {
- return_vals = procedural_db_return_args (proc_rec, FALSE);
- goto done;
- }
-
- plug_in->busy = TRUE;
- plug_in_push (plug_in);
-
- proc_run.name = proc_rec->name;
- proc_run.nparams = argc;
- proc_run.params = plug_in_args_to_params (args, argc, FALSE);
-
- if (!gp_temp_proc_run_write (current_writechannel, &proc_run) ||
- !wire_flush (current_writechannel))
- {
- return_vals = procedural_db_return_args (proc_rec, FALSE);
- goto done;
- }
-
- plug_in_pop ();
-
- plug_in_params_destroy (proc_run.params, proc_run.nparams, FALSE);
-
- old_recurse = plug_in->recurse;
- plug_in->recurse = TRUE;
-
- /* gtk_main (); */
-
- /* return_vals = plug_in_get_current_return_vals (proc_rec); */
- return_vals = procedural_db_return_args (proc_rec, TRUE);
- plug_in->recurse = old_recurse;
- plug_in->busy = FALSE;
- }
-
- done:
- return return_vals;
- }
-
- static Argument*
- plug_in_params_to_args (GPParam *params,
- gint nparams,
- gboolean full_copy)
- {
- Argument *args;
- gchar **stringarray;
- guchar *colorarray;
- gint count;
- gint i, j;
-
- if (nparams == 0)
- return NULL;
-
- args = g_new (Argument, nparams);
-
- for (i = 0; i < nparams; i++)
- {
- args[i].arg_type = params[i].type;
-
- switch (args[i].arg_type)
- {
- case PDB_INT32:
- args[i].value.pdb_int = params[i].data.d_int32;
- break;
- case PDB_INT16:
- args[i].value.pdb_int = params[i].data.d_int16;
- break;
- case PDB_INT8:
- args[i].value.pdb_int = params[i].data.d_int8;
- break;
- case PDB_FLOAT:
- args[i].value.pdb_float = params[i].data.d_float;
- break;
- case PDB_STRING:
- if (full_copy)
- args[i].value.pdb_pointer = g_strdup (params[i].data.d_string);
- else
- args[i].value.pdb_pointer = params[i].data.d_string;
- break;
- case PDB_INT32ARRAY:
- if (full_copy)
- {
- count = args[i-1].value.pdb_int;
- args[i].value.pdb_pointer = g_new (gint32, count);
- memcpy (args[i].value.pdb_pointer, params[i].data.d_int32array, count * 4);
- }
- else
- {
- args[i].value.pdb_pointer = params[i].data.d_int32array;
- }
- break;
- case PDB_INT16ARRAY:
- if (full_copy)
- {
- count = args[i-1].value.pdb_int;
- args[i].value.pdb_pointer = g_new (gint16, count);
- memcpy (args[i].value.pdb_pointer, params[i].data.d_int16array, count * 2);
- }
- else
- {
- args[i].value.pdb_pointer = params[i].data.d_int16array;
- }
- break;
- case PDB_INT8ARRAY:
- if (full_copy)
- {
- count = args[i-1].value.pdb_int;
- args[i].value.pdb_pointer = g_new (gint8, count);
- memcpy (args[i].value.pdb_pointer, params[i].data.d_int8array, count);
- }
- else
- {
- args[i].value.pdb_pointer = params[i].data.d_int8array;
- }
- break;
- case PDB_FLOATARRAY:
- if (full_copy)
- {
- count = args[i-1].value.pdb_int;
- args[i].value.pdb_pointer = g_new (gdouble, count);
- memcpy (args[i].value.pdb_pointer, params[i].data.d_floatarray, count * 8);
- }
- else
- {
- args[i].value.pdb_pointer = params[i].data.d_floatarray;
- }
- break;
- case PDB_STRINGARRAY:
- if (full_copy)
- {
- args[i].value.pdb_pointer = g_new (gchar*, args[i-1].value.pdb_int);
- stringarray = args[i].value.pdb_pointer;
-
- for (j = 0; j < args[i-1].value.pdb_int; j++)
- stringarray[j] = g_strdup (params[i].data.d_stringarray[j]);
- }
- else
- {
- args[i].value.pdb_pointer = params[i].data.d_stringarray;
- }
- break;
- case PDB_COLOR:
- args[i].value.pdb_pointer = g_new (guchar, 3);
- colorarray = args[i].value.pdb_pointer;
- colorarray[0] = params[i].data.d_color.red;
- colorarray[1] = params[i].data.d_color.green;
- colorarray[2] = params[i].data.d_color.blue;
- break;
- case PDB_REGION:
- g_message ("the \"region\" arg type is not currently supported");
- break;
- case PDB_DISPLAY:
- args[i].value.pdb_int = params[i].data.d_display;
- break;
- case PDB_IMAGE:
- args[i].value.pdb_int = params[i].data.d_image;
- break;
- case PDB_LAYER:
- args[i].value.pdb_int = params[i].data.d_layer;
- break;
- case PDB_CHANNEL:
- args[i].value.pdb_int = params[i].data.d_channel;
- break;
- case PDB_DRAWABLE:
- args[i].value.pdb_int = params[i].data.d_drawable;
- break;
- case PDB_SELECTION:
- args[i].value.pdb_int = params[i].data.d_selection;
- break;
- case PDB_BOUNDARY:
- args[i].value.pdb_int = params[i].data.d_boundary;
- break;
- case PDB_PATH:
- args[i].value.pdb_int = params[i].data.d_path;
- break;
- case PDB_PARASITE:
- if (full_copy)
- args[i].value.pdb_pointer =
- gimp_parasite_copy ((GimpParasite *) &(params[i].data.d_parasite));
- else
- args[i].value.pdb_pointer = (void *)&(params[i].data.d_parasite);
- break;
- case PDB_STATUS:
- args[i].value.pdb_int = params[i].data.d_status;
- break;
- case PDB_END:
- break;
- }
- }
-
- return args;
- }
-
- static GPParam*
- plug_in_args_to_params (Argument *args,
- gint nargs,
- gboolean full_copy)
- {
- GPParam *params;
- gchar **stringarray;
- guchar *colorarray;
- gint i, j;
-
- if (nargs == 0)
- return NULL;
-
- params = g_new (GPParam, nargs);
-
- for (i = 0; i < nargs; i++)
- {
- params[i].type = args[i].arg_type;
-
- switch (args[i].arg_type)
- {
- case PDB_INT32:
- params[i].data.d_int32 = args[i].value.pdb_int;
- break;
- case PDB_INT16:
- params[i].data.d_int16 = args[i].value.pdb_int;
- break;
- case PDB_INT8:
- params[i].data.d_int8 = args[i].value.pdb_int;
- break;
- case PDB_FLOAT:
- params[i].data.d_float = args[i].value.pdb_float;
- break;
- case PDB_STRING:
- if (full_copy)
- params[i].data.d_string = g_strdup (args[i].value.pdb_pointer);
- else
- params[i].data.d_string = args[i].value.pdb_pointer;
- break;
- case PDB_INT32ARRAY:
- if (full_copy)
- {
- params[i].data.d_int32array = g_new (gint32, params[i-1].data.d_int32);
- memcpy (params[i].data.d_int32array,
- args[i].value.pdb_pointer,
- params[i-1].data.d_int32 * 4);
- }
- else
- {
- params[i].data.d_int32array = args[i].value.pdb_pointer;
- }
- break;
- case PDB_INT16ARRAY:
- if (full_copy)
- {
- params[i].data.d_int16array = g_new (gint16, params[i-1].data.d_int32);
- memcpy (params[i].data.d_int16array,
- args[i].value.pdb_pointer,
- params[i-1].data.d_int32 * 2);
- }
- else
- {
- params[i].data.d_int16array = args[i].value.pdb_pointer;
- }
- break;
- case PDB_INT8ARRAY:
- if (full_copy)
- {
- params[i].data.d_int8array = g_new (gint8, params[i-1].data.d_int32);
- memcpy (params[i].data.d_int8array,
- args[i].value.pdb_pointer,
- params[i-1].data.d_int32);
- }
- else
- {
- params[i].data.d_int8array = args[i].value.pdb_pointer;
- }
- break;
- case PDB_FLOATARRAY:
- if (full_copy)
- {
- params[i].data.d_floatarray = g_new (gdouble, params[i-1].data.d_int32);
- memcpy (params[i].data.d_floatarray,
- args[i].value.pdb_pointer,
- params[i-1].data.d_int32 * 8);
- }
- else
- {
- params[i].data.d_floatarray = args[i].value.pdb_pointer;
- }
- break;
- case PDB_STRINGARRAY:
- if (full_copy)
- {
- params[i].data.d_stringarray = g_new (gchar*, params[i-1].data.d_int32);
- stringarray = args[i].value.pdb_pointer;
-
- for (j = 0; j < params[i-1].data.d_int32; j++)
- params[i].data.d_stringarray[j] = g_strdup (stringarray[j]);
- }
- else
- {
- params[i].data.d_stringarray = args[i].value.pdb_pointer;
- }
- break;
- case PDB_COLOR:
- colorarray = args[i].value.pdb_pointer;
- if( colorarray )
- {
- params[i].data.d_color.red = colorarray[0];
- params[i].data.d_color.green = colorarray[1];
- params[i].data.d_color.blue = colorarray[2];
- }
- else
- {
- params[i].data.d_color.red = 0;
- params[i].data.d_color.green = 0;
- params[i].data.d_color.blue = 0;
- }
- break;
- case PDB_REGION:
- g_message ("the \"region\" arg type is not currently supported");
- break;
- case PDB_DISPLAY:
- params[i].data.d_display = args[i].value.pdb_int;
- break;
- case PDB_IMAGE:
- params[i].data.d_image = args[i].value.pdb_int;
- break;
- case PDB_LAYER:
- params[i].data.d_layer = args[i].value.pdb_int;
- break;
- case PDB_CHANNEL:
- params[i].data.d_channel = args[i].value.pdb_int;
- break;
- case PDB_DRAWABLE:
- params[i].data.d_drawable = args[i].value.pdb_int;
- break;
- case PDB_SELECTION:
- params[i].data.d_selection = args[i].value.pdb_int;
- break;
- case PDB_BOUNDARY:
- params[i].data.d_boundary = args[i].value.pdb_int;
- break;
- case PDB_PATH:
- params[i].data.d_path = args[i].value.pdb_int;
- break;
- case PDB_PARASITE:
- if (full_copy)
- {
- GimpParasite *tmp;
-
- tmp = gimp_parasite_copy (args[i].value.pdb_pointer);
- if (tmp == NULL)
- {
- params[i].data.d_parasite.name = 0;
- params[i].data.d_parasite.flags = 0;
- params[i].data.d_parasite.size = 0;
- params[i].data.d_parasite.data = 0;
- }
- else
- {
- memcpy (¶ms[i].data.d_parasite, tmp,
- sizeof (GimpParasite));
- g_free (tmp);
- }
- }
- else
- {
- if (args[i].value.pdb_pointer == NULL)
- {
- params[i].data.d_parasite.name = 0;
- params[i].data.d_parasite.flags = 0;
- params[i].data.d_parasite.size = 0;
- params[i].data.d_parasite.data = 0;
- }
- else
- memcpy (¶ms[i].data.d_parasite,
- (GimpParasite *) (args[i].value.pdb_pointer),
- sizeof (GimpParasite));
- }
- break;
- case PDB_STATUS:
- params[i].data.d_status = args[i].value.pdb_int;
- break;
- case PDB_END:
- break;
- }
- }
-
- return params;
- }
-
- static void
- plug_in_params_destroy (GPParam *params,
- gint nparams,
- gboolean full_destroy)
- {
- gint i, j;
-
- for (i = 0; i < nparams; i++)
- {
- switch (params[i].type)
- {
- case PDB_INT32:
- case PDB_INT16:
- case PDB_INT8:
- case PDB_FLOAT:
- break;
- case PDB_STRING:
- if (full_destroy)
- g_free (params[i].data.d_string);
- break;
- case PDB_INT32ARRAY:
- if (full_destroy)
- g_free (params[i].data.d_int32array);
- break;
- case PDB_INT16ARRAY:
- if (full_destroy)
- g_free (params[i].data.d_int16array);
- break;
- case PDB_INT8ARRAY:
- if (full_destroy)
- g_free (params[i].data.d_int8array);
- break;
- case PDB_FLOATARRAY:
- if (full_destroy)
- g_free (params[i].data.d_floatarray);
- break;
- case PDB_STRINGARRAY:
- if (full_destroy)
- {
- for (j = 0; j < params[i-1].data.d_int32; j++)
- g_free (params[i].data.d_stringarray[j]);
- g_free (params[i].data.d_stringarray);
- }
- break;
- case PDB_COLOR:
- break;
- case PDB_REGION:
- g_message ("the \"region\" arg type is not currently supported");
- break;
- case PDB_DISPLAY:
- case PDB_IMAGE:
- case PDB_LAYER:
- case PDB_CHANNEL:
- case PDB_DRAWABLE:
- case PDB_SELECTION:
- case PDB_BOUNDARY:
- case PDB_PATH:
- break;
- case PDB_PARASITE:
- if (full_destroy)
- if (params[i].data.d_parasite.data)
- {
- g_free (params[i].data.d_parasite.name);
- g_free (params[i].data.d_parasite.data);
- params[i].data.d_parasite.name = 0;
- params[i].data.d_parasite.data = 0;
- }
- break;
- case PDB_STATUS:
- break;
- case PDB_END:
- break;
- }
- }
-
- g_free (params);
- }
-
- static void
- plug_in_args_destroy (Argument *args,
- gint nargs,
- gboolean full_destroy)
- {
- gchar **stringarray;
- gint count;
- gint i, j;
-
- for (i = 0; i < nargs; i++)
- {
- switch (args[i].arg_type)
- {
- case PDB_INT32:
- case PDB_INT16:
- case PDB_INT8:
- case PDB_FLOAT:
- break;
- case PDB_STRING:
- if (full_destroy)
- g_free (args[i].value.pdb_pointer);
- break;
- case PDB_INT32ARRAY:
- if (full_destroy)
- g_free (args[i].value.pdb_pointer);
- break;
- case PDB_INT16ARRAY:
- if (full_destroy)
- g_free (args[i].value.pdb_pointer);
- break;
- case PDB_INT8ARRAY:
- if (full_destroy)
- g_free (args[i].value.pdb_pointer);
- break;
- case PDB_FLOATARRAY:
- if (full_destroy)
- g_free (args[i].value.pdb_pointer);
- break;
- case PDB_STRINGARRAY:
- if (full_destroy)
- {
- count = args[i-1].value.pdb_int;
- stringarray = args[i].value.pdb_pointer;
-
- for (j = 0; j < count; j++)
- g_free (stringarray[j]);
-
- g_free (args[i].value.pdb_pointer);
- }
- break;
- case PDB_COLOR:
- g_free (args[i].value.pdb_pointer);
- break;
- case PDB_REGION:
- g_message ("the \"region\" arg type is not currently supported");
- break;
- case PDB_DISPLAY:
- case PDB_IMAGE:
- case PDB_LAYER:
- case PDB_CHANNEL:
- case PDB_DRAWABLE:
- case PDB_SELECTION:
- case PDB_BOUNDARY:
- case PDB_PATH:
- break;
- case PDB_PARASITE:
- if (full_destroy)
- {
- gimp_parasite_free ((GimpParasite *) (args[i].value.pdb_pointer));
- args[i].value.pdb_pointer = NULL;
- }
- break;
- case PDB_STATUS:
- break;
- case PDB_END:
- break;
- }
- }
-
- g_free (args);
- }
-
- gint
- plug_in_image_types_parse (gchar *image_types)
- {
- gchar *type_spec = image_types;
- gint types = 0;
-
- /*
- * If the plug_in registers with image_type == NULL or "", return 0
- * By doing so it won't be touched by plug_in_set_menu_sensitivity()
- */
- if (!image_types)
- return types;
-
- while (*image_types)
- {
- while (*image_types &&
- ((*image_types == ' ') ||
- (*image_types == '\t') ||
- (*image_types == ',')))
- image_types++;
-
- if (*image_types)
- {
- if (strncmp (image_types, "RGBA", 4) == 0)
- {
- types |= PLUG_IN_RGBA_IMAGE;
- image_types += 4;
- }
- else if (strncmp (image_types, "RGB*", 4) == 0)
- {
- types |= PLUG_IN_RGB_IMAGE | PLUG_IN_RGBA_IMAGE;
- image_types += 4;
- }
- else if (strncmp (image_types, "RGB", 3) == 0)
- {
- types |= PLUG_IN_RGB_IMAGE;
- image_types += 3;
- }
- else if (strncmp (image_types, "GRAYA", 5) == 0)
- {
- types |= PLUG_IN_GRAYA_IMAGE;
- image_types += 5;
- }
- else if (strncmp (image_types, "GRAY*", 5) == 0)
- {
- types |= PLUG_IN_GRAY_IMAGE | PLUG_IN_GRAYA_IMAGE;
- image_types += 5;
- }
- else if (strncmp (image_types, "GRAY", 4) == 0)
- {
- types |= PLUG_IN_GRAY_IMAGE;
- image_types += 4;
- }
- else if (strncmp (image_types, "INDEXEDA", 8) == 0)
- {
- types |= PLUG_IN_INDEXEDA_IMAGE;
- image_types += 8;
- }
- else if (strncmp (image_types, "INDEXED*", 8) == 0)
- {
- types |= PLUG_IN_INDEXED_IMAGE | PLUG_IN_INDEXEDA_IMAGE;
- image_types += 8;
- }
- else if (strncmp (image_types, "INDEXED", 7) == 0)
- {
- types |= PLUG_IN_INDEXED_IMAGE;
- image_types += 7;
- }
- else if (strncmp (image_types, "*", 1) == 0)
- {
- types |= PLUG_IN_RGB_IMAGE | PLUG_IN_RGBA_IMAGE
- | PLUG_IN_GRAY_IMAGE | PLUG_IN_GRAYA_IMAGE
- | PLUG_IN_INDEXED_IMAGE | PLUG_IN_INDEXEDA_IMAGE;
- image_types += 1;
- }
- else
- {
- g_warning ("image_type contains unrecognizable parts: '%s'", type_spec);
- while (*image_types &&
- ((*image_types != ' ') ||
- (*image_types != '\t') ||
- (*image_types != ',')))
- image_types++;
- }
- }
- }
-
- return types;
- }
-
- static void
- plug_in_progress_cancel (GtkWidget *widget,
- PlugIn *plug_in)
- {
- plug_in_destroy (plug_in);
- }
-
- void
- plug_in_progress_init (PlugIn *plug_in,
- gchar *message,
- gint gdisp_ID)
- {
- GDisplay *gdisp = NULL;
-
- if (!message)
- message = plug_in->args[0];
-
- if (gdisp_ID > 0)
- gdisp = gdisplay_get_ID(gdisp_ID);
-
- if (plug_in->progress)
- plug_in->progress = progress_restart (plug_in->progress, message,
- plug_in_progress_cancel, plug_in);
- else
- plug_in->progress = progress_start (gdisp, message, TRUE,
- plug_in_progress_cancel, plug_in);
- }
-
- void
- plug_in_progress_update (PlugIn *plug_in,
- gdouble percentage)
- {
- if (!plug_in->progress)
- plug_in_progress_init (plug_in, NULL, -1);
-
- progress_update (plug_in->progress, percentage);
- }
-