removed gimp_main_loop() and gimp_main_loop_quit() because they were a

2003-02-03  Michael Natterer  <mitch@gimp.org>

	* app/core/gimp.[ch]: removed gimp_main_loop() and
	gimp_main_loop_quit() because they were a temp_hack until plug-ins
	have their own main loops. Added gimp_threads_enter() and
	gimp_threads_leave() instead.

	* app/gui/gui.c: ditto: removed the main loop stuff and added
	functions which call GDK_THREADS_ENTER() and GDK_THREADS_LEAVE()
	instead.

	* app/app_procs.c: create the main GMainLoop here and use
	gimp_threads_enter,leave().

	* app/plug-in/plug-in.[ch]: added a ref_count per plug-in so the
	plug-in is not destroyed under our feet while running a recursive
	main loop. Added plug_in_ref(). Changed plug_in_destroy() to
	plug_in_unref(). Don't destroy the plug-in if plug_in_open()
	fails. Call gimp_threads_enter,leave() around g_main_loop_run().
	Changed the way plug_in_push,pop() are used: "current_plug_in" is
	no longer the plug-in which currently uses the wire, but the
	plug-in which currently preforms a PDB call (the former meaning
	was needed when wire callbacks had no plug-in context but needed
	to get the plug-in from the global "current_plug_in" variable).
	Removed all calls to plug_in_push,pop() from this file.

	* app/plug-in/plug-in-message.c (plug_in_handle_proc_run): added
	plug_in_push,pop() around procedural_db_execute(). No need
	to construct an error return value if the procedure was not found
	because procedural_db_execute() already does this.

	Removed all other plug_in_push,pop(). Added more checks to plug-in
	message handlers and kill the plug-in if it misbehaves. Cleanup.

	* app/plug-in/plug-in-progress.c (plug_in_progress_cancel): if the
	plug-in runs synchronously, provide a GIMP_PDB_CANCEL return value
	so we don't see error messages about the "failed" procedure.

	* app/plug-in/plug-in-run.c: removed plug_in_push,pop() stuff.
	Set the new plug_in->starting_ext boolean while starting an
	extension so the extension_ack handler knows that it wasn't called
	from a buggy plug-in. Cleanup.

	* app/plug-in/plug-ins.c: Cleanup.
This commit is contained in:
Michael Natterer 2003-02-03 13:21:31 +00:00 committed by Michael Natterer
parent 6d4e953412
commit 2db2ef6185
18 changed files with 541 additions and 456 deletions

View File

@ -1,3 +1,48 @@
2003-02-03 Michael Natterer <mitch@gimp.org>
* app/core/gimp.[ch]: removed gimp_main_loop() and
gimp_main_loop_quit() because they were a temp_hack until plug-ins
have their own main loops. Added gimp_threads_enter() and
gimp_threads_leave() instead.
* app/gui/gui.c: ditto: removed the main loop stuff and added
functions which call GDK_THREADS_ENTER() and GDK_THREADS_LEAVE()
instead.
* app/app_procs.c: create the main GMainLoop here and use
gimp_threads_enter,leave().
* app/plug-in/plug-in.[ch]: added a ref_count per plug-in so the
plug-in is not destroyed under our feet while running a recursive
main loop. Added plug_in_ref(). Changed plug_in_destroy() to
plug_in_unref(). Don't destroy the plug-in if plug_in_open()
fails. Call gimp_threads_enter,leave() around g_main_loop_run().
Changed the way plug_in_push,pop() are used: "current_plug_in" is
no longer the plug-in which currently uses the wire, but the
plug-in which currently preforms a PDB call (the former meaning
was needed when wire callbacks had no plug-in context but needed
to get the plug-in from the global "current_plug_in" variable).
Removed all calls to plug_in_push,pop() from this file.
* app/plug-in/plug-in-message.c (plug_in_handle_proc_run): added
plug_in_push,pop() around procedural_db_execute(). No need
to construct an error return value if the procedure was not found
because procedural_db_execute() already does this.
Removed all other plug_in_push,pop(). Added more checks to plug-in
message handlers and kill the plug-in if it misbehaves. Cleanup.
* app/plug-in/plug-in-progress.c (plug_in_progress_cancel): if the
plug-in runs synchronous, provide a GIMP_PDB_CANCEL return value
so we don't see error messages about the "failed" procedure.
* app/plug-in/plug-in-run.c: removed plug_in_push,pop() stuff.
Set the new plug_in->starting_ext boolean while starting an
extension so the extension_ack handler knows that it wasn't called
from a buggy plug-in. Cleanup.
* app/plug-in/plug-ins.c: Cleanup.
2003-02-03 Sven Neumann <neo@wintermute> 2003-02-03 Sven Neumann <neo@wintermute>
Some code cleanup while trying to fix bug #105062: Some code cleanup while trying to fix bug #105062:

View File

@ -246,7 +246,22 @@ app_init (gint gimp_argc,
gui_post_init (the_gimp); gui_post_init (the_gimp);
} }
gimp_main_loop (the_gimp); if (no_interface)
{
GMainLoop *loop;
loop = g_main_loop_new (NULL, FALSE);
gimp_threads_leave (the_gimp);
g_main_loop_run (loop);
gimp_threads_enter (the_gimp);
g_main_loop_unref (loop);
}
else
{
gtk_main ();
}
} }

View File

@ -182,10 +182,8 @@ gimp_init (Gimp *gimp)
gimp->message_handler = GIMP_CONSOLE; gimp->message_handler = GIMP_CONSOLE;
gimp->stack_trace_mode = GIMP_STACK_TRACE_NEVER; gimp->stack_trace_mode = GIMP_STACK_TRACE_NEVER;
gimp->main_loops = NULL; gimp->gui_threads_enter_func = NULL;
gimp->gui_threads_leave_func = NULL;
gimp->gui_main_loop_func = NULL;
gimp->gui_main_loop_quit_func = NULL;
gimp->gui_create_display_func = NULL; gimp->gui_create_display_func = NULL;
gimp->gui_set_busy_func = NULL; gimp->gui_set_busy_func = NULL;
gimp->gui_unset_busy_func = NULL; gimp->gui_unset_busy_func = NULL;
@ -769,47 +767,21 @@ gimp_exit (Gimp *gimp,
} }
void void
gimp_main_loop (Gimp *gimp) gimp_threads_enter (Gimp *gimp)
{ {
g_return_if_fail (GIMP_IS_GIMP (gimp)); g_return_if_fail (GIMP_IS_GIMP (gimp));
if (gimp->gui_main_loop_func) if (gimp->gui_threads_enter_func)
{ gimp->gui_threads_enter_func (gimp);
gimp->gui_main_loop_func (gimp);
}
else
{
GMainLoop *loop;
loop = g_main_loop_new (NULL, TRUE);
gimp->main_loops = g_list_prepend (gimp->main_loops, loop);
g_main_loop_run (loop);
gimp->main_loops = g_list_remove (gimp->main_loops, loop);
g_main_loop_unref (loop);
}
} }
void void
gimp_main_loop_quit (Gimp *gimp) gimp_threads_leave (Gimp *gimp)
{ {
g_return_if_fail (GIMP_IS_GIMP (gimp)); g_return_if_fail (GIMP_IS_GIMP (gimp));
if (gimp->gui_main_loop_func) if (gimp->gui_threads_leave_func)
{ gimp->gui_threads_leave_func (gimp);
gimp->gui_main_loop_quit_func (gimp);
}
else
{
GMainLoop *loop;
loop = (GMainLoop *) gimp->main_loops->data;
g_main_loop_quit (loop);
}
} }
void void

View File

@ -24,7 +24,7 @@
#include "gimpimage-new.h" #include "gimpimage-new.h"
typedef void (* GimpMainLoopFunc) (Gimp *gimp); typedef void (* GimpThreadFunc) (Gimp *gimp);
typedef GimpObject * (* GimpCreateDisplayFunc) (GimpImage *gimage, typedef GimpObject * (* GimpCreateDisplayFunc) (GimpImage *gimage,
guint scale); guint scale);
typedef void (* GimpSetBusyFunc) (Gimp *gimp); typedef void (* GimpSetBusyFunc) (Gimp *gimp);
@ -58,10 +58,8 @@ struct _Gimp
GimpMessageHandlerType message_handler; GimpMessageHandlerType message_handler;
GimpStackTraceMode stack_trace_mode; GimpStackTraceMode stack_trace_mode;
GList *main_loops; GimpThreadFunc gui_threads_enter_func;
GimpThreadFunc gui_threads_leave_func;
GimpMainLoopFunc gui_main_loop_func;
GimpMainLoopFunc gui_main_loop_quit_func;
GimpCreateDisplayFunc gui_create_display_func; GimpCreateDisplayFunc gui_create_display_func;
GimpSetBusyFunc gui_set_busy_func; GimpSetBusyFunc gui_set_busy_func;
GimpUnsetBusyFunc gui_unset_busy_func; GimpUnsetBusyFunc gui_unset_busy_func;
@ -161,8 +159,8 @@ void gimp_restore (Gimp *gimp,
void gimp_exit (Gimp *gimp, void gimp_exit (Gimp *gimp,
gboolean kill_it); gboolean kill_it);
void gimp_main_loop (Gimp *gimp); void gimp_threads_enter (Gimp *gimp);
void gimp_main_loop_quit (Gimp *gimp); void gimp_threads_leave (Gimp *gimp);
void gimp_set_busy (Gimp *gimp); void gimp_set_busy (Gimp *gimp);
void gimp_set_busy_until_idle (Gimp *gimp); void gimp_set_busy_until_idle (Gimp *gimp);

View File

@ -63,8 +63,8 @@
/* local function prototypes */ /* local function prototypes */
static void gui_main (Gimp *gimp); static void gui_threads_enter (Gimp *gimp);
static void gui_main_quit (Gimp *gimp); static void gui_threads_leave (Gimp *gimp);
static void gui_set_busy (Gimp *gimp); static void gui_set_busy (Gimp *gimp);
static void gui_unset_busy (Gimp *gimp); static void gui_unset_busy (Gimp *gimp);
static void gui_message (Gimp *gimp, static void gui_message (Gimp *gimp,
@ -239,8 +239,8 @@ gui_init (Gimp *gimp)
display_config = GIMP_DISPLAY_CONFIG (gimp->config); display_config = GIMP_DISPLAY_CONFIG (gimp->config);
gui_config = GIMP_GUI_CONFIG (gimp->config); gui_config = GIMP_GUI_CONFIG (gimp->config);
gimp->gui_main_loop_func = gui_main; gimp->gui_threads_enter_func = gui_threads_enter;
gimp->gui_main_loop_quit_func = gui_main_quit; gimp->gui_threads_leave_func = gui_threads_leave;
gimp->gui_set_busy_func = gui_set_busy; gimp->gui_set_busy_func = gui_set_busy;
gimp->gui_unset_busy_func = gui_unset_busy; gimp->gui_unset_busy_func = gui_unset_busy;
gimp->gui_message_func = gui_message; gimp->gui_message_func = gui_message;
@ -386,15 +386,15 @@ gui_get_screen_resolution (gdouble *xres,
/* private functions */ /* private functions */
static void static void
gui_main (Gimp *gimp) gui_threads_enter (Gimp *gimp)
{ {
gtk_main (); GDK_THREADS_ENTER ();
} }
static void static void
gui_main_quit (Gimp *gimp) gui_threads_leave (Gimp *gimp)
{ {
gtk_main_quit (); GDK_THREADS_LEAVE ();
} }
static void static void

View File

@ -337,19 +337,14 @@ plug_in_handle_proc_run (PlugIn *plug_in,
args = plug_in_params_to_args (proc_run->params, proc_run->nparams, FALSE); args = plug_in_params_to_args (proc_run->params, proc_run->nparams, FALSE);
proc_rec = procedural_db_lookup (plug_in->gimp, proc_run->name); proc_rec = procedural_db_lookup (plug_in->gimp, proc_run->name);
if (proc_rec) plug_in_push (plug_in);
{
return_vals = procedural_db_execute (plug_in->gimp, proc_run->name, args); /* Execute the procedure even if procedural_db_lookup() returned NULL,
} * procedural_db_execute() will return appropriate error return_vals.
else */
{ return_vals = procedural_db_execute (plug_in->gimp, proc_run->name, args);
/* if the name lookup failed, construct a
* dummy "executiuon error" return value --Michael plug_in_pop ();
*/
return_vals = g_new (Argument, 1);
return_vals[0].arg_type = GIMP_PDB_STATUS;
return_vals[0].value.pdb_int = GIMP_PDB_EXECUTION_ERROR;
}
if (return_vals) if (return_vals)
{ {
@ -423,8 +418,6 @@ plug_in_handle_proc_return_priv (PlugIn *plug_in,
if (blocked->proc_name && proc_return->name && if (blocked->proc_name && proc_return->name &&
strcmp (blocked->proc_name, proc_return->name) == 0) strcmp (blocked->proc_name, proc_return->name) == 0)
{ {
plug_in_push (blocked->plug_in);
if (! gp_proc_return_write (blocked->plug_in->my_write, if (! gp_proc_return_write (blocked->plug_in->my_write,
proc_return, proc_return,
blocked->plug_in)) blocked->plug_in))
@ -434,8 +427,6 @@ plug_in_handle_proc_return_priv (PlugIn *plug_in,
return; return;
} }
plug_in_pop ();
blocked_plug_ins = g_slist_remove (blocked_plug_ins, blocked); blocked_plug_ins = g_slist_remove (blocked_plug_ins, blocked);
g_free (blocked->proc_name); g_free (blocked->proc_name);
g_free (blocked); g_free (blocked);
@ -462,17 +453,19 @@ static void
plug_in_handle_temp_proc_return (PlugIn *plug_in, plug_in_handle_temp_proc_return (PlugIn *plug_in,
GPProcReturn *proc_return) GPProcReturn *proc_return)
{ {
if (! plug_in->in_temp_proc) if (plug_in->in_temp_proc)
{
plug_in_handle_proc_return_priv (plug_in, proc_return);
plug_in_main_loop_quit (plug_in);
}
else
{ {
g_warning ("plug_in_handle_temp_proc_return: " g_warning ("plug_in_handle_temp_proc_return: "
"received TEMP_PROC_RETURN while not in temp proc"); "received a temp_proc_return mesage while not running "
"a temp proc (should not happen)");
plug_in_close (plug_in, TRUE); plug_in_close (plug_in, TRUE);
return;
} }
plug_in_handle_proc_return_priv (plug_in, proc_return);
plug_in_main_loop_quit (plug_in);
} }
#endif #endif
@ -665,19 +658,20 @@ plug_in_handle_proc_install (PlugIn *plug_in,
if (strcmp (proc_def->db_info.name, proc_install->name) == 0) if (strcmp (proc_def->db_info.name, proc_install->name) == 0)
{ {
if (proc_install->type == GIMP_TEMPORARY) switch (proc_install->type)
{
plug_in->temp_proc_defs = g_slist_remove (plug_in->temp_proc_defs,
proc_def);
plug_ins_temp_proc_def_remove (plug_in->gimp, proc_def);
}
else
{ {
case GIMP_PLUGIN:
case GIMP_EXTENSION:
plug_in_def->proc_defs = g_slist_remove (plug_in_def->proc_defs, plug_in_def->proc_defs = g_slist_remove (plug_in_def->proc_defs,
proc_def); proc_def);
plug_in_proc_def_free (proc_def); plug_in_proc_def_free (proc_def);
break;
case GIMP_TEMPORARY:
plug_in->temp_proc_defs = g_slist_remove (plug_in->temp_proc_defs,
proc_def);
plug_ins_temp_proc_def_remove (plug_in->gimp, proc_def);
break;
} }
break; break;
@ -686,8 +680,7 @@ plug_in_handle_proc_install (PlugIn *plug_in,
proc_def = plug_in_proc_def_new (); proc_def = plug_in_proc_def_new ();
proc_def->prog = g_strdup (prog); proc_def->prog = g_strdup (prog);
proc_def->menu_path = g_strdup (proc_install->menu_path); proc_def->menu_path = g_strdup (proc_install->menu_path);
proc_def->accelerator = NULL; proc_def->accelerator = NULL;
proc_def->extensions = NULL; proc_def->extensions = NULL;
@ -779,12 +772,31 @@ plug_in_handle_proc_uninstall (PlugIn *plug_in,
static void static void
plug_in_handle_extension_ack (PlugIn *plug_in) plug_in_handle_extension_ack (PlugIn *plug_in)
{ {
plug_in_main_loop_quit (plug_in); if (plug_in->starting_ext)
{
plug_in_main_loop_quit (plug_in);
}
else
{
g_warning ("plug_in_handle_extension_ack: "
"received an extension_ack message while not starting "
"an extension (should not happen)");
plug_in_close (plug_in, TRUE);
}
} }
static void static void
plug_in_handle_has_init (PlugIn *plug_in) plug_in_handle_has_init (PlugIn *plug_in)
{ {
if (plug_in->query) if (plug_in->query)
plug_in_def_set_has_init (plug_in->plug_in_def, TRUE); {
plug_in_def_set_has_init (plug_in->plug_in_def, TRUE);
}
else
{
g_warning ("plug_in_handle_has_init: "
"received a has_init message while not in query() "
"(should not happen)");
plug_in_close (plug_in, TRUE);
}
} }

View File

@ -27,6 +27,8 @@
#endif #endif
#include "display/display-types.h" #include "display/display-types.h"
#include "pdb/procedural_db.h"
#include "display/gimpdisplay.h" #include "display/gimpdisplay.h"
#include "display/gimpprogress.h" #include "display/gimpprogress.h"
@ -98,5 +100,15 @@ static void
plug_in_progress_cancel (GtkWidget *widget, plug_in_progress_cancel (GtkWidget *widget,
PlugIn *plug_in) PlugIn *plug_in)
{ {
plug_in_destroy (plug_in); if (plug_in->recurse)
{
plug_in->return_vals = g_new (Argument, 1);
plug_in->n_return_vals = 1;
plug_in->return_vals->arg_type = GIMP_PDB_STATUS;
plug_in->return_vals->value.pdb_int = GIMP_PDB_CANCEL;
}
plug_in_close (plug_in, TRUE);
plug_in_unref (plug_in);
} }

View File

@ -171,7 +171,10 @@ plug_in_exit (Gimp *gimp)
list = list->next; list = list->next;
plug_in_destroy (plug_in); if (plug_in->open)
plug_in_close (plug_in, TRUE);
plug_in_unref (plug_in);
} }
} }
@ -194,8 +197,6 @@ plug_in_call_query (Gimp *gimp,
if (plug_in_open (plug_in)) if (plug_in_open (plug_in))
{ {
plug_in_push (plug_in);
while (plug_in->open) while (plug_in->open)
{ {
WireMessage msg; WireMessage msg;
@ -210,11 +211,9 @@ plug_in_call_query (Gimp *gimp,
wire_destroy (&msg); wire_destroy (&msg);
} }
} }
plug_in_pop ();
} }
plug_in_destroy (plug_in); plug_in_unref (plug_in);
} }
} }
@ -237,8 +236,6 @@ plug_in_call_init (Gimp *gimp,
if (plug_in_open (plug_in)) if (plug_in_open (plug_in))
{ {
plug_in_push (plug_in);
while (plug_in->open) while (plug_in->open)
{ {
WireMessage msg; WireMessage msg;
@ -253,11 +250,9 @@ plug_in_call_init (Gimp *gimp,
wire_destroy (&msg); wire_destroy (&msg);
} }
} }
plug_in_pop ();
} }
plug_in_destroy (plug_in); plug_in_unref (plug_in);
} }
} }
@ -275,12 +270,15 @@ plug_in_new (Gimp *gimp,
plug_in->gimp = gimp; plug_in->gimp = gimp;
plug_in->ref_count = 1;
plug_in->open = FALSE; plug_in->open = FALSE;
plug_in->query = FALSE; plug_in->query = FALSE;
plug_in->init = FALSE; plug_in->init = FALSE;
plug_in->synchronous = FALSE; plug_in->synchronous = FALSE;
plug_in->recurse = FALSE; plug_in->recurse = FALSE;
plug_in->in_temp_proc = FALSE; plug_in->in_temp_proc = FALSE;
plug_in->starting_ext = FALSE;
plug_in->pid = 0; plug_in->pid = 0;
plug_in->args[0] = g_strdup (name); plug_in->args[0] = g_strdup (name);
@ -312,33 +310,43 @@ plug_in_new (Gimp *gimp,
} }
void void
plug_in_destroy (PlugIn *plug_in) plug_in_ref (PlugIn *plug_in)
{ {
g_return_if_fail (plug_in != NULL); g_return_if_fail (plug_in != NULL);
if (plug_in->open) plug_in->ref_count++;
plug_in_close (plug_in, TRUE); }
if (plug_in->args[0]) void
g_free (plug_in->args[0]); plug_in_unref (PlugIn *plug_in)
if (plug_in->args[1]) {
g_free (plug_in->args[1]); g_return_if_fail (plug_in != NULL);
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) plug_in->ref_count--;
plug_in_progress_end (plug_in);
if (plug_in == current_plug_in) if (plug_in->ref_count < 1)
plug_in_pop (); {
if (plug_in->open)
plug_in_close (plug_in, TRUE);
g_free (plug_in); 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)
plug_in_progress_end (plug_in);
g_free (plug_in);
}
} }
static void static void
@ -433,9 +441,8 @@ plug_in_open (PlugIn *plug_in)
fcntl (my_write[1], F_SETFD, 1); fcntl (my_write[1], F_SETFD, 1);
#endif #endif
/* Fork another process. We'll remember the process id /* Fork another process. We'll remember the process id so that we
* so that we can later use it to kill the filter if * can later use it to kill the filter if necessary.
* necessary.
*/ */
envp = gimp_environ_table_get_envp (plug_in->gimp->environ_table); envp = gimp_environ_table_get_envp (plug_in->gimp->environ_table);
if (! g_spawn_async (NULL, plug_in->args, envp, if (! g_spawn_async (NULL, plug_in->args, envp,
@ -450,8 +457,6 @@ plug_in_open (PlugIn *plug_in)
plug_in->args[0], plug_in->args[0],
error->message); error->message);
g_error_free (error); g_error_free (error);
plug_in_destroy (plug_in);
return FALSE; return FALSE;
} }
@ -496,9 +501,7 @@ plug_in_close (PlugIn *plug_in,
/* Ask the filter to exit gracefully */ /* Ask the filter to exit gracefully */
if (kill_it && plug_in->pid) if (kill_it && plug_in->pid)
{ {
plug_in_push (plug_in);
gp_quit_write (plug_in->my_write, plug_in); gp_quit_write (plug_in->my_write, plug_in);
plug_in_pop ();
/* give the plug-in some time (10 ms) */ /* give the plug-in some time (10 ms) */
#ifndef G_OS_WIN32 #ifndef G_OS_WIN32
@ -625,9 +628,6 @@ plug_in_recv_message (GIOChannel *channel,
plug_in = (PlugIn *) data; plug_in = (PlugIn *) data;
if (plug_in != current_plug_in)
plug_in_push (plug_in);
if (plug_in->my_read == NULL) if (plug_in->my_read == NULL)
return TRUE; return TRUE;
@ -666,9 +666,7 @@ plug_in_recv_message (GIOChannel *channel,
plug_in->args[0]); plug_in->args[0]);
if (! plug_in->open) if (! plug_in->open)
plug_in_destroy (plug_in); plug_in_unref (plug_in);
else
plug_in_pop ();
return TRUE; return TRUE;
} }
@ -809,9 +807,9 @@ plug_in_main_loop (PlugIn *plug_in)
plug_in->main_loops = g_list_prepend (plug_in->main_loops, main_loop); plug_in->main_loops = g_list_prepend (plug_in->main_loops, main_loop);
GDK_THREADS_LEAVE(); gimp_threads_leave (plug_in->gimp);
g_main_loop_run (main_loop); g_main_loop_run (main_loop);
GDK_THREADS_ENTER (); gimp_threads_enter (plug_in->gimp);
g_main_loop_unref (main_loop); g_main_loop_unref (main_loop);
} }

View File

@ -30,12 +30,15 @@ struct _PlugIn
{ {
Gimp *gimp; Gimp *gimp;
gint ref_count;
guint open : 1; /* Is the plug-in open? */ guint open : 1; /* Is the plug-in open? */
guint query : 1; /* Are we querying the plug-in? */ guint query : 1; /* Are we querying the plug-in? */
guint init : 1; /* Are we initialing the plug-in? */ guint init : 1; /* Are we initialing the plug-in? */
guint synchronous : 1; /* Is the plug-in running synchronously? */ guint synchronous : 1; /* Is the plug-in running synchronously? */
guint recurse : 1; /* Do we have an own GMainLoop? */ guint recurse : 1; /* Do we have an own GMainLoop? */
guint in_temp_proc : 1; /* Is the plug-in busy with a temp proc? */ guint in_temp_proc : 1; /* Is the plug-in busy with a temp proc? */
guint starting_ext : 1; /* Does the plug-in wait for extension_ack?*/
pid_t pid; /* Plug-ins process id */ pid_t pid; /* Plug-ins process id */
gchar *args[7]; /* Plug-ins command line arguments */ gchar *args[7]; /* Plug-ins command line arguments */
@ -44,7 +47,7 @@ struct _PlugIn
GIOChannel *his_read; /* Plug-in's read and write channels */ GIOChannel *his_read; /* Plug-in's read and write channels */
GIOChannel *his_write; GIOChannel *his_write;
guint32 input_id; /* Id of input proc */ guint input_id; /* Id of input proc */
gchar write_buffer[WRITE_BUFFER_SIZE]; /* Buffer for writing */ gchar write_buffer[WRITE_BUFFER_SIZE]; /* Buffer for writing */
gint write_buffer_index; /* Buffer index for writing */ gint write_buffer_index; /* Buffer index for writing */
@ -61,41 +64,29 @@ struct _PlugIn
}; };
void plug_in_init (Gimp *gimp); void plug_in_init (Gimp *gimp);
void plug_in_exit (Gimp *gimp); void plug_in_exit (Gimp *gimp);
void plug_in_call_query (Gimp *gimp, void plug_in_call_query (Gimp *gimp,
PlugInDef *plug_in_def); PlugInDef *plug_in_def);
void plug_in_call_init (Gimp *gimp, void plug_in_call_init (Gimp *gimp,
PlugInDef *plug_in_def); PlugInDef *plug_in_def);
/* Create a new plug-in structure PlugIn * plug_in_new (Gimp *gimp,
*/ gchar *name);
PlugIn * plug_in_new (Gimp *gimp,
gchar *name);
/* Destroy a plug-in structure. void plug_in_ref (PlugIn *plug_in);
* This will close the plug-in first if necessary. void plug_in_unref (PlugIn *plug_in);
*/
void plug_in_destroy (PlugIn *plug_in);
gboolean plug_in_open (PlugIn *plug_in);
void plug_in_close (PlugIn *plug_in,
gboolean kill_it);
/* Open a plug-in. This cause the plug-in to run. void plug_in_push (PlugIn *plug_in);
* If returns TRUE, you must destroy the plugin.
* If returns FALSE, you must not destroy the plugin.
*/
gboolean plug_in_open (PlugIn *plug_in);
/* Close a plug-in. This kills the plug-in and releases its resources.
*/
void plug_in_close (PlugIn *plug_in,
gboolean kill_it);
void plug_in_push (PlugIn *plug_in);
void plug_in_pop (void); void plug_in_pop (void);
void plug_in_main_loop (PlugIn *plug_in); void plug_in_main_loop (PlugIn *plug_in);
void plug_in_main_loop_quit (PlugIn *plug_in); void plug_in_main_loop_quit (PlugIn *plug_in);
extern PlugIn *current_plug_in; extern PlugIn *current_plug_in;

View File

@ -82,60 +82,66 @@ plug_in_run (Gimp *gimp,
if (plug_in) if (plug_in)
{ {
if (plug_in_open (plug_in)) GPConfig config;
GPProcRun proc_run;
if (! plug_in_open (plug_in))
{ {
GPConfig config; plug_in_unref (plug_in);
GPProcRun proc_run; goto done;
}
plug_in->recurse = synchronous; 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 = plug_in_shm_get_ID (gimp);
config.gamma = gimp->config->gamma_val;
config.install_cmap = gimp->config->install_cmap;
config.show_tool_tips = GIMP_GUI_CONFIG (gimp->config)->show_tool_tips;
config.min_colors = CLAMP (gimp->config->min_colors, 27, 256);
config.gdisp_ID = gdisp_ID;
config.version = GP_VERSION; proc_run.name = proc_rec->name;
config.tile_width = TILE_WIDTH; proc_run.nparams = argc;
config.tile_height = TILE_HEIGHT; proc_run.params = plug_in_args_to_params (args, argc, FALSE);
config.shm_ID = plug_in_shm_get_ID (gimp);
config.gamma = gimp->config->gamma_val;
config.install_cmap = gimp->config->install_cmap;
config.show_tool_tips = GIMP_GUI_CONFIG (gimp->config)->show_tool_tips;
config.min_colors = CLAMP (gimp->config->min_colors, 27, 256);
config.gdisp_ID = gdisp_ID;
proc_run.name = proc_rec->name; if (! gp_config_write (plug_in->my_write, &config, plug_in) ||
proc_run.nparams = argc; ! gp_proc_run_write (plug_in->my_write, &proc_run, plug_in) ||
proc_run.params = plug_in_args_to_params (args, argc, FALSE); ! wire_flush (plug_in->my_write, plug_in))
{
return_vals = procedural_db_return_args (proc_rec, FALSE);
goto done;
}
if (! gp_config_write (plug_in->my_write, &config, plug_in) || plug_in_params_destroy (proc_run.params, proc_run.nparams, FALSE);
! gp_proc_run_write (plug_in->my_write, &proc_run, plug_in) ||
! wire_flush (plug_in->my_write, plug_in))
{
return_vals = procedural_db_return_args (proc_rec, FALSE);
goto done;
}
plug_in_pop (); plug_in_ref (plug_in);
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 == GIMP_EXTENSION) && (proc_rec->num_args == 0))
{
plug_in->starting_ext = TRUE;
/* If this is an automatically installed extension, wait for an plug_in_main_loop (plug_in);
* installation-confirmation message
*/
if ((proc_rec->proc_type == GIMP_EXTENSION) &&
(proc_rec->num_args == 0))
{
plug_in_main_loop (plug_in);
}
/* If this plug-in is requested to run synchronously, wait for plug_in->starting_ext = FALSE;
* its return values }
*/
if (plug_in->recurse)
{
plug_in_main_loop (plug_in);
return_vals = plug_in_get_return_vals (plug_in, proc_rec); /* If this plug-in is requested to run synchronously, wait for
} * it's return values
} */
if (plug_in->recurse)
{
plug_in_main_loop (plug_in);
return_vals = plug_in_get_return_vals (plug_in, proc_rec);
}
plug_in_unref (plug_in);
} }
done: done:
@ -188,17 +194,16 @@ plug_in_temp_run (ProcRecord *proc_rec,
Argument *args, Argument *args,
gint argc) gint argc)
{ {
Argument *return_vals; Argument *return_vals = NULL;
PlugIn *plug_in; PlugIn *plug_in;
GPProcRun proc_run;
gint old_recurse;
return_vals = NULL;
plug_in = (PlugIn *) proc_rec->exec_method.temporary.plug_in; plug_in = (PlugIn *) proc_rec->exec_method.temporary.plug_in;
if (plug_in) if (plug_in)
{ {
GPProcRun proc_run;
gboolean old_recurse;
if (plug_in->in_temp_proc) if (plug_in->in_temp_proc)
{ {
return_vals = procedural_db_return_args (proc_rec, FALSE); return_vals = procedural_db_return_args (proc_rec, FALSE);
@ -207,8 +212,6 @@ plug_in_temp_run (ProcRecord *proc_rec,
plug_in->in_temp_proc = TRUE; plug_in->in_temp_proc = TRUE;
plug_in_push (plug_in);
proc_run.name = proc_rec->name; proc_run.name = proc_rec->name;
proc_run.nparams = argc; proc_run.nparams = argc;
proc_run.params = plug_in_args_to_params (args, argc, FALSE); proc_run.params = plug_in_args_to_params (args, argc, FALSE);
@ -220,16 +223,16 @@ plug_in_temp_run (ProcRecord *proc_rec,
goto done; goto done;
} }
plug_in_pop ();
plug_in_params_destroy (proc_run.params, proc_run.nparams, FALSE); plug_in_params_destroy (proc_run.params, proc_run.nparams, FALSE);
old_recurse = plug_in->recurse; old_recurse = plug_in->recurse;
plug_in->recurse = TRUE; plug_in->recurse = TRUE;
#ifdef ENABLE_TEMP_RETURN #ifdef ENABLE_TEMP_RETURN
plug_in_ref (plug_in);
plug_in_main_loop (plug_in); plug_in_main_loop (plug_in);
return_vals = plug_in_get_return_vals (proc_rec); return_vals = plug_in_get_return_vals (proc_rec);
#else #else
return_vals = procedural_db_return_args (proc_rec, TRUE); return_vals = procedural_db_return_args (proc_rec, TRUE);
@ -238,6 +241,10 @@ plug_in_temp_run (ProcRecord *proc_rec,
plug_in->recurse = old_recurse; plug_in->recurse = old_recurse;
plug_in->in_temp_proc = FALSE; plug_in->in_temp_proc = FALSE;
#ifdef ENABLE_TEMP_RETURN
plug_in_unref (plug_in);
#endif
} }
done: done:
@ -256,6 +263,7 @@ plug_in_get_return_vals (PlugIn *plug_in,
/* Return the status code plus the current return values. */ /* Return the status code plus the current return values. */
nargs = proc_rec->num_values + 1; nargs = proc_rec->num_values + 1;
if (plug_in->return_vals && plug_in->n_return_vals == nargs) if (plug_in->return_vals && plug_in->n_return_vals == nargs)
{ {
return_vals = plug_in->return_vals; return_vals = plug_in->return_vals;
@ -270,8 +278,9 @@ plug_in_get_return_vals (PlugIn *plug_in,
sizeof (Argument) * MIN (plug_in->n_return_vals, nargs)); sizeof (Argument) * MIN (plug_in->n_return_vals, nargs));
/* Free the old argument pointer. This will cause a memory leak /* Free the old argument pointer. This will cause a memory leak
only if there were more values returned than we need (which * only if there were more values returned than we need (which
shouldn't ever happen). */ * shouldn't ever happen).
*/
g_free (plug_in->return_vals); g_free (plug_in->return_vals);
} }
else else

View File

@ -82,60 +82,66 @@ plug_in_run (Gimp *gimp,
if (plug_in) if (plug_in)
{ {
if (plug_in_open (plug_in)) GPConfig config;
GPProcRun proc_run;
if (! plug_in_open (plug_in))
{ {
GPConfig config; plug_in_unref (plug_in);
GPProcRun proc_run; goto done;
}
plug_in->recurse = synchronous; 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 = plug_in_shm_get_ID (gimp);
config.gamma = gimp->config->gamma_val;
config.install_cmap = gimp->config->install_cmap;
config.show_tool_tips = GIMP_GUI_CONFIG (gimp->config)->show_tool_tips;
config.min_colors = CLAMP (gimp->config->min_colors, 27, 256);
config.gdisp_ID = gdisp_ID;
config.version = GP_VERSION; proc_run.name = proc_rec->name;
config.tile_width = TILE_WIDTH; proc_run.nparams = argc;
config.tile_height = TILE_HEIGHT; proc_run.params = plug_in_args_to_params (args, argc, FALSE);
config.shm_ID = plug_in_shm_get_ID (gimp);
config.gamma = gimp->config->gamma_val;
config.install_cmap = gimp->config->install_cmap;
config.show_tool_tips = GIMP_GUI_CONFIG (gimp->config)->show_tool_tips;
config.min_colors = CLAMP (gimp->config->min_colors, 27, 256);
config.gdisp_ID = gdisp_ID;
proc_run.name = proc_rec->name; if (! gp_config_write (plug_in->my_write, &config, plug_in) ||
proc_run.nparams = argc; ! gp_proc_run_write (plug_in->my_write, &proc_run, plug_in) ||
proc_run.params = plug_in_args_to_params (args, argc, FALSE); ! wire_flush (plug_in->my_write, plug_in))
{
return_vals = procedural_db_return_args (proc_rec, FALSE);
goto done;
}
if (! gp_config_write (plug_in->my_write, &config, plug_in) || plug_in_params_destroy (proc_run.params, proc_run.nparams, FALSE);
! gp_proc_run_write (plug_in->my_write, &proc_run, plug_in) ||
! wire_flush (plug_in->my_write, plug_in))
{
return_vals = procedural_db_return_args (proc_rec, FALSE);
goto done;
}
plug_in_pop (); plug_in_ref (plug_in);
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 == GIMP_EXTENSION) && (proc_rec->num_args == 0))
{
plug_in->starting_ext = TRUE;
/* If this is an automatically installed extension, wait for an plug_in_main_loop (plug_in);
* installation-confirmation message
*/
if ((proc_rec->proc_type == GIMP_EXTENSION) &&
(proc_rec->num_args == 0))
{
plug_in_main_loop (plug_in);
}
/* If this plug-in is requested to run synchronously, wait for plug_in->starting_ext = FALSE;
* its return values }
*/
if (plug_in->recurse)
{
plug_in_main_loop (plug_in);
return_vals = plug_in_get_return_vals (plug_in, proc_rec); /* If this plug-in is requested to run synchronously, wait for
} * it's return values
} */
if (plug_in->recurse)
{
plug_in_main_loop (plug_in);
return_vals = plug_in_get_return_vals (plug_in, proc_rec);
}
plug_in_unref (plug_in);
} }
done: done:
@ -188,17 +194,16 @@ plug_in_temp_run (ProcRecord *proc_rec,
Argument *args, Argument *args,
gint argc) gint argc)
{ {
Argument *return_vals; Argument *return_vals = NULL;
PlugIn *plug_in; PlugIn *plug_in;
GPProcRun proc_run;
gint old_recurse;
return_vals = NULL;
plug_in = (PlugIn *) proc_rec->exec_method.temporary.plug_in; plug_in = (PlugIn *) proc_rec->exec_method.temporary.plug_in;
if (plug_in) if (plug_in)
{ {
GPProcRun proc_run;
gboolean old_recurse;
if (plug_in->in_temp_proc) if (plug_in->in_temp_proc)
{ {
return_vals = procedural_db_return_args (proc_rec, FALSE); return_vals = procedural_db_return_args (proc_rec, FALSE);
@ -207,8 +212,6 @@ plug_in_temp_run (ProcRecord *proc_rec,
plug_in->in_temp_proc = TRUE; plug_in->in_temp_proc = TRUE;
plug_in_push (plug_in);
proc_run.name = proc_rec->name; proc_run.name = proc_rec->name;
proc_run.nparams = argc; proc_run.nparams = argc;
proc_run.params = plug_in_args_to_params (args, argc, FALSE); proc_run.params = plug_in_args_to_params (args, argc, FALSE);
@ -220,16 +223,16 @@ plug_in_temp_run (ProcRecord *proc_rec,
goto done; goto done;
} }
plug_in_pop ();
plug_in_params_destroy (proc_run.params, proc_run.nparams, FALSE); plug_in_params_destroy (proc_run.params, proc_run.nparams, FALSE);
old_recurse = plug_in->recurse; old_recurse = plug_in->recurse;
plug_in->recurse = TRUE; plug_in->recurse = TRUE;
#ifdef ENABLE_TEMP_RETURN #ifdef ENABLE_TEMP_RETURN
plug_in_ref (plug_in);
plug_in_main_loop (plug_in); plug_in_main_loop (plug_in);
return_vals = plug_in_get_return_vals (proc_rec); return_vals = plug_in_get_return_vals (proc_rec);
#else #else
return_vals = procedural_db_return_args (proc_rec, TRUE); return_vals = procedural_db_return_args (proc_rec, TRUE);
@ -238,6 +241,10 @@ plug_in_temp_run (ProcRecord *proc_rec,
plug_in->recurse = old_recurse; plug_in->recurse = old_recurse;
plug_in->in_temp_proc = FALSE; plug_in->in_temp_proc = FALSE;
#ifdef ENABLE_TEMP_RETURN
plug_in_unref (plug_in);
#endif
} }
done: done:
@ -256,6 +263,7 @@ plug_in_get_return_vals (PlugIn *plug_in,
/* Return the status code plus the current return values. */ /* Return the status code plus the current return values. */
nargs = proc_rec->num_values + 1; nargs = proc_rec->num_values + 1;
if (plug_in->return_vals && plug_in->n_return_vals == nargs) if (plug_in->return_vals && plug_in->n_return_vals == nargs)
{ {
return_vals = plug_in->return_vals; return_vals = plug_in->return_vals;
@ -270,8 +278,9 @@ plug_in_get_return_vals (PlugIn *plug_in,
sizeof (Argument) * MIN (plug_in->n_return_vals, nargs)); sizeof (Argument) * MIN (plug_in->n_return_vals, nargs));
/* Free the old argument pointer. This will cause a memory leak /* Free the old argument pointer. This will cause a memory leak
only if there were more values returned than we need (which * only if there were more values returned than we need (which
shouldn't ever happen). */ * shouldn't ever happen).
*/
g_free (plug_in->return_vals); g_free (plug_in->return_vals);
} }
else else

View File

@ -75,9 +75,9 @@ struct _PlugInHelpPathDef
}; };
static void plug_ins_init_file (GimpDatafileData *file_data); static void plug_ins_init_file (GimpDatafileData *file_data);
static void plug_ins_add_to_db (Gimp *gimp); static void plug_ins_add_to_db (Gimp *gimp);
static PlugInProcDef * plug_ins_proc_def_insert (PlugInProcDef *proc_def); static PlugInProcDef * plug_ins_proc_def_insert (PlugInProcDef *proc_def);
GSList *proc_defs = NULL; GSList *proc_defs = NULL;
@ -779,8 +779,6 @@ static void
plug_ins_add_to_db (Gimp *gimp) plug_ins_add_to_db (Gimp *gimp)
{ {
PlugInProcDef *proc_def; PlugInProcDef *proc_def;
Argument args[4];
Argument *return_vals;
GSList *list; GSList *list;
for (list = proc_defs; list; list = g_slist_next (list)) for (list = proc_defs; list; list = g_slist_next (list))
@ -800,6 +798,9 @@ plug_ins_add_to_db (Gimp *gimp)
if (proc_def->extensions || proc_def->prefixes || proc_def->magics) if (proc_def->extensions || proc_def->prefixes || proc_def->magics)
{ {
Argument args[4];
Argument *return_vals;
args[0].arg_type = GIMP_PDB_STRING; args[0].arg_type = GIMP_PDB_STRING;
args[0].value.pdb_pointer = proc_def->db_info.name; args[0].value.pdb_pointer = proc_def->db_info.name;

View File

@ -337,19 +337,14 @@ plug_in_handle_proc_run (PlugIn *plug_in,
args = plug_in_params_to_args (proc_run->params, proc_run->nparams, FALSE); args = plug_in_params_to_args (proc_run->params, proc_run->nparams, FALSE);
proc_rec = procedural_db_lookup (plug_in->gimp, proc_run->name); proc_rec = procedural_db_lookup (plug_in->gimp, proc_run->name);
if (proc_rec) plug_in_push (plug_in);
{
return_vals = procedural_db_execute (plug_in->gimp, proc_run->name, args); /* Execute the procedure even if procedural_db_lookup() returned NULL,
} * procedural_db_execute() will return appropriate error return_vals.
else */
{ return_vals = procedural_db_execute (plug_in->gimp, proc_run->name, args);
/* if the name lookup failed, construct a
* dummy "executiuon error" return value --Michael plug_in_pop ();
*/
return_vals = g_new (Argument, 1);
return_vals[0].arg_type = GIMP_PDB_STATUS;
return_vals[0].value.pdb_int = GIMP_PDB_EXECUTION_ERROR;
}
if (return_vals) if (return_vals)
{ {
@ -423,8 +418,6 @@ plug_in_handle_proc_return_priv (PlugIn *plug_in,
if (blocked->proc_name && proc_return->name && if (blocked->proc_name && proc_return->name &&
strcmp (blocked->proc_name, proc_return->name) == 0) strcmp (blocked->proc_name, proc_return->name) == 0)
{ {
plug_in_push (blocked->plug_in);
if (! gp_proc_return_write (blocked->plug_in->my_write, if (! gp_proc_return_write (blocked->plug_in->my_write,
proc_return, proc_return,
blocked->plug_in)) blocked->plug_in))
@ -434,8 +427,6 @@ plug_in_handle_proc_return_priv (PlugIn *plug_in,
return; return;
} }
plug_in_pop ();
blocked_plug_ins = g_slist_remove (blocked_plug_ins, blocked); blocked_plug_ins = g_slist_remove (blocked_plug_ins, blocked);
g_free (blocked->proc_name); g_free (blocked->proc_name);
g_free (blocked); g_free (blocked);
@ -462,17 +453,19 @@ static void
plug_in_handle_temp_proc_return (PlugIn *plug_in, plug_in_handle_temp_proc_return (PlugIn *plug_in,
GPProcReturn *proc_return) GPProcReturn *proc_return)
{ {
if (! plug_in->in_temp_proc) if (plug_in->in_temp_proc)
{
plug_in_handle_proc_return_priv (plug_in, proc_return);
plug_in_main_loop_quit (plug_in);
}
else
{ {
g_warning ("plug_in_handle_temp_proc_return: " g_warning ("plug_in_handle_temp_proc_return: "
"received TEMP_PROC_RETURN while not in temp proc"); "received a temp_proc_return mesage while not running "
"a temp proc (should not happen)");
plug_in_close (plug_in, TRUE); plug_in_close (plug_in, TRUE);
return;
} }
plug_in_handle_proc_return_priv (plug_in, proc_return);
plug_in_main_loop_quit (plug_in);
} }
#endif #endif
@ -665,19 +658,20 @@ plug_in_handle_proc_install (PlugIn *plug_in,
if (strcmp (proc_def->db_info.name, proc_install->name) == 0) if (strcmp (proc_def->db_info.name, proc_install->name) == 0)
{ {
if (proc_install->type == GIMP_TEMPORARY) switch (proc_install->type)
{
plug_in->temp_proc_defs = g_slist_remove (plug_in->temp_proc_defs,
proc_def);
plug_ins_temp_proc_def_remove (plug_in->gimp, proc_def);
}
else
{ {
case GIMP_PLUGIN:
case GIMP_EXTENSION:
plug_in_def->proc_defs = g_slist_remove (plug_in_def->proc_defs, plug_in_def->proc_defs = g_slist_remove (plug_in_def->proc_defs,
proc_def); proc_def);
plug_in_proc_def_free (proc_def); plug_in_proc_def_free (proc_def);
break;
case GIMP_TEMPORARY:
plug_in->temp_proc_defs = g_slist_remove (plug_in->temp_proc_defs,
proc_def);
plug_ins_temp_proc_def_remove (plug_in->gimp, proc_def);
break;
} }
break; break;
@ -686,8 +680,7 @@ plug_in_handle_proc_install (PlugIn *plug_in,
proc_def = plug_in_proc_def_new (); proc_def = plug_in_proc_def_new ();
proc_def->prog = g_strdup (prog); proc_def->prog = g_strdup (prog);
proc_def->menu_path = g_strdup (proc_install->menu_path); proc_def->menu_path = g_strdup (proc_install->menu_path);
proc_def->accelerator = NULL; proc_def->accelerator = NULL;
proc_def->extensions = NULL; proc_def->extensions = NULL;
@ -779,12 +772,31 @@ plug_in_handle_proc_uninstall (PlugIn *plug_in,
static void static void
plug_in_handle_extension_ack (PlugIn *plug_in) plug_in_handle_extension_ack (PlugIn *plug_in)
{ {
plug_in_main_loop_quit (plug_in); if (plug_in->starting_ext)
{
plug_in_main_loop_quit (plug_in);
}
else
{
g_warning ("plug_in_handle_extension_ack: "
"received an extension_ack message while not starting "
"an extension (should not happen)");
plug_in_close (plug_in, TRUE);
}
} }
static void static void
plug_in_handle_has_init (PlugIn *plug_in) plug_in_handle_has_init (PlugIn *plug_in)
{ {
if (plug_in->query) if (plug_in->query)
plug_in_def_set_has_init (plug_in->plug_in_def, TRUE); {
plug_in_def_set_has_init (plug_in->plug_in_def, TRUE);
}
else
{
g_warning ("plug_in_handle_has_init: "
"received a has_init message while not in query() "
"(should not happen)");
plug_in_close (plug_in, TRUE);
}
} }

View File

@ -27,6 +27,8 @@
#endif #endif
#include "display/display-types.h" #include "display/display-types.h"
#include "pdb/procedural_db.h"
#include "display/gimpdisplay.h" #include "display/gimpdisplay.h"
#include "display/gimpprogress.h" #include "display/gimpprogress.h"
@ -98,5 +100,15 @@ static void
plug_in_progress_cancel (GtkWidget *widget, plug_in_progress_cancel (GtkWidget *widget,
PlugIn *plug_in) PlugIn *plug_in)
{ {
plug_in_destroy (plug_in); if (plug_in->recurse)
{
plug_in->return_vals = g_new (Argument, 1);
plug_in->n_return_vals = 1;
plug_in->return_vals->arg_type = GIMP_PDB_STATUS;
plug_in->return_vals->value.pdb_int = GIMP_PDB_CANCEL;
}
plug_in_close (plug_in, TRUE);
plug_in_unref (plug_in);
} }

View File

@ -82,60 +82,66 @@ plug_in_run (Gimp *gimp,
if (plug_in) if (plug_in)
{ {
if (plug_in_open (plug_in)) GPConfig config;
GPProcRun proc_run;
if (! plug_in_open (plug_in))
{ {
GPConfig config; plug_in_unref (plug_in);
GPProcRun proc_run; goto done;
}
plug_in->recurse = synchronous; 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 = plug_in_shm_get_ID (gimp);
config.gamma = gimp->config->gamma_val;
config.install_cmap = gimp->config->install_cmap;
config.show_tool_tips = GIMP_GUI_CONFIG (gimp->config)->show_tool_tips;
config.min_colors = CLAMP (gimp->config->min_colors, 27, 256);
config.gdisp_ID = gdisp_ID;
config.version = GP_VERSION; proc_run.name = proc_rec->name;
config.tile_width = TILE_WIDTH; proc_run.nparams = argc;
config.tile_height = TILE_HEIGHT; proc_run.params = plug_in_args_to_params (args, argc, FALSE);
config.shm_ID = plug_in_shm_get_ID (gimp);
config.gamma = gimp->config->gamma_val;
config.install_cmap = gimp->config->install_cmap;
config.show_tool_tips = GIMP_GUI_CONFIG (gimp->config)->show_tool_tips;
config.min_colors = CLAMP (gimp->config->min_colors, 27, 256);
config.gdisp_ID = gdisp_ID;
proc_run.name = proc_rec->name; if (! gp_config_write (plug_in->my_write, &config, plug_in) ||
proc_run.nparams = argc; ! gp_proc_run_write (plug_in->my_write, &proc_run, plug_in) ||
proc_run.params = plug_in_args_to_params (args, argc, FALSE); ! wire_flush (plug_in->my_write, plug_in))
{
return_vals = procedural_db_return_args (proc_rec, FALSE);
goto done;
}
if (! gp_config_write (plug_in->my_write, &config, plug_in) || plug_in_params_destroy (proc_run.params, proc_run.nparams, FALSE);
! gp_proc_run_write (plug_in->my_write, &proc_run, plug_in) ||
! wire_flush (plug_in->my_write, plug_in))
{
return_vals = procedural_db_return_args (proc_rec, FALSE);
goto done;
}
plug_in_pop (); plug_in_ref (plug_in);
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 == GIMP_EXTENSION) && (proc_rec->num_args == 0))
{
plug_in->starting_ext = TRUE;
/* If this is an automatically installed extension, wait for an plug_in_main_loop (plug_in);
* installation-confirmation message
*/
if ((proc_rec->proc_type == GIMP_EXTENSION) &&
(proc_rec->num_args == 0))
{
plug_in_main_loop (plug_in);
}
/* If this plug-in is requested to run synchronously, wait for plug_in->starting_ext = FALSE;
* its return values }
*/
if (plug_in->recurse)
{
plug_in_main_loop (plug_in);
return_vals = plug_in_get_return_vals (plug_in, proc_rec); /* If this plug-in is requested to run synchronously, wait for
} * it's return values
} */
if (plug_in->recurse)
{
plug_in_main_loop (plug_in);
return_vals = plug_in_get_return_vals (plug_in, proc_rec);
}
plug_in_unref (plug_in);
} }
done: done:
@ -188,17 +194,16 @@ plug_in_temp_run (ProcRecord *proc_rec,
Argument *args, Argument *args,
gint argc) gint argc)
{ {
Argument *return_vals; Argument *return_vals = NULL;
PlugIn *plug_in; PlugIn *plug_in;
GPProcRun proc_run;
gint old_recurse;
return_vals = NULL;
plug_in = (PlugIn *) proc_rec->exec_method.temporary.plug_in; plug_in = (PlugIn *) proc_rec->exec_method.temporary.plug_in;
if (plug_in) if (plug_in)
{ {
GPProcRun proc_run;
gboolean old_recurse;
if (plug_in->in_temp_proc) if (plug_in->in_temp_proc)
{ {
return_vals = procedural_db_return_args (proc_rec, FALSE); return_vals = procedural_db_return_args (proc_rec, FALSE);
@ -207,8 +212,6 @@ plug_in_temp_run (ProcRecord *proc_rec,
plug_in->in_temp_proc = TRUE; plug_in->in_temp_proc = TRUE;
plug_in_push (plug_in);
proc_run.name = proc_rec->name; proc_run.name = proc_rec->name;
proc_run.nparams = argc; proc_run.nparams = argc;
proc_run.params = plug_in_args_to_params (args, argc, FALSE); proc_run.params = plug_in_args_to_params (args, argc, FALSE);
@ -220,16 +223,16 @@ plug_in_temp_run (ProcRecord *proc_rec,
goto done; goto done;
} }
plug_in_pop ();
plug_in_params_destroy (proc_run.params, proc_run.nparams, FALSE); plug_in_params_destroy (proc_run.params, proc_run.nparams, FALSE);
old_recurse = plug_in->recurse; old_recurse = plug_in->recurse;
plug_in->recurse = TRUE; plug_in->recurse = TRUE;
#ifdef ENABLE_TEMP_RETURN #ifdef ENABLE_TEMP_RETURN
plug_in_ref (plug_in);
plug_in_main_loop (plug_in); plug_in_main_loop (plug_in);
return_vals = plug_in_get_return_vals (proc_rec); return_vals = plug_in_get_return_vals (proc_rec);
#else #else
return_vals = procedural_db_return_args (proc_rec, TRUE); return_vals = procedural_db_return_args (proc_rec, TRUE);
@ -238,6 +241,10 @@ plug_in_temp_run (ProcRecord *proc_rec,
plug_in->recurse = old_recurse; plug_in->recurse = old_recurse;
plug_in->in_temp_proc = FALSE; plug_in->in_temp_proc = FALSE;
#ifdef ENABLE_TEMP_RETURN
plug_in_unref (plug_in);
#endif
} }
done: done:
@ -256,6 +263,7 @@ plug_in_get_return_vals (PlugIn *plug_in,
/* Return the status code plus the current return values. */ /* Return the status code plus the current return values. */
nargs = proc_rec->num_values + 1; nargs = proc_rec->num_values + 1;
if (plug_in->return_vals && plug_in->n_return_vals == nargs) if (plug_in->return_vals && plug_in->n_return_vals == nargs)
{ {
return_vals = plug_in->return_vals; return_vals = plug_in->return_vals;
@ -270,8 +278,9 @@ plug_in_get_return_vals (PlugIn *plug_in,
sizeof (Argument) * MIN (plug_in->n_return_vals, nargs)); sizeof (Argument) * MIN (plug_in->n_return_vals, nargs));
/* Free the old argument pointer. This will cause a memory leak /* Free the old argument pointer. This will cause a memory leak
only if there were more values returned than we need (which * only if there were more values returned than we need (which
shouldn't ever happen). */ * shouldn't ever happen).
*/
g_free (plug_in->return_vals); g_free (plug_in->return_vals);
} }
else else

View File

@ -171,7 +171,10 @@ plug_in_exit (Gimp *gimp)
list = list->next; list = list->next;
plug_in_destroy (plug_in); if (plug_in->open)
plug_in_close (plug_in, TRUE);
plug_in_unref (plug_in);
} }
} }
@ -194,8 +197,6 @@ plug_in_call_query (Gimp *gimp,
if (plug_in_open (plug_in)) if (plug_in_open (plug_in))
{ {
plug_in_push (plug_in);
while (plug_in->open) while (plug_in->open)
{ {
WireMessage msg; WireMessage msg;
@ -210,11 +211,9 @@ plug_in_call_query (Gimp *gimp,
wire_destroy (&msg); wire_destroy (&msg);
} }
} }
plug_in_pop ();
} }
plug_in_destroy (plug_in); plug_in_unref (plug_in);
} }
} }
@ -237,8 +236,6 @@ plug_in_call_init (Gimp *gimp,
if (plug_in_open (plug_in)) if (plug_in_open (plug_in))
{ {
plug_in_push (plug_in);
while (plug_in->open) while (plug_in->open)
{ {
WireMessage msg; WireMessage msg;
@ -253,11 +250,9 @@ plug_in_call_init (Gimp *gimp,
wire_destroy (&msg); wire_destroy (&msg);
} }
} }
plug_in_pop ();
} }
plug_in_destroy (plug_in); plug_in_unref (plug_in);
} }
} }
@ -275,12 +270,15 @@ plug_in_new (Gimp *gimp,
plug_in->gimp = gimp; plug_in->gimp = gimp;
plug_in->ref_count = 1;
plug_in->open = FALSE; plug_in->open = FALSE;
plug_in->query = FALSE; plug_in->query = FALSE;
plug_in->init = FALSE; plug_in->init = FALSE;
plug_in->synchronous = FALSE; plug_in->synchronous = FALSE;
plug_in->recurse = FALSE; plug_in->recurse = FALSE;
plug_in->in_temp_proc = FALSE; plug_in->in_temp_proc = FALSE;
plug_in->starting_ext = FALSE;
plug_in->pid = 0; plug_in->pid = 0;
plug_in->args[0] = g_strdup (name); plug_in->args[0] = g_strdup (name);
@ -312,33 +310,43 @@ plug_in_new (Gimp *gimp,
} }
void void
plug_in_destroy (PlugIn *plug_in) plug_in_ref (PlugIn *plug_in)
{ {
g_return_if_fail (plug_in != NULL); g_return_if_fail (plug_in != NULL);
if (plug_in->open) plug_in->ref_count++;
plug_in_close (plug_in, TRUE); }
if (plug_in->args[0]) void
g_free (plug_in->args[0]); plug_in_unref (PlugIn *plug_in)
if (plug_in->args[1]) {
g_free (plug_in->args[1]); g_return_if_fail (plug_in != NULL);
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) plug_in->ref_count--;
plug_in_progress_end (plug_in);
if (plug_in == current_plug_in) if (plug_in->ref_count < 1)
plug_in_pop (); {
if (plug_in->open)
plug_in_close (plug_in, TRUE);
g_free (plug_in); 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)
plug_in_progress_end (plug_in);
g_free (plug_in);
}
} }
static void static void
@ -433,9 +441,8 @@ plug_in_open (PlugIn *plug_in)
fcntl (my_write[1], F_SETFD, 1); fcntl (my_write[1], F_SETFD, 1);
#endif #endif
/* Fork another process. We'll remember the process id /* Fork another process. We'll remember the process id so that we
* so that we can later use it to kill the filter if * can later use it to kill the filter if necessary.
* necessary.
*/ */
envp = gimp_environ_table_get_envp (plug_in->gimp->environ_table); envp = gimp_environ_table_get_envp (plug_in->gimp->environ_table);
if (! g_spawn_async (NULL, plug_in->args, envp, if (! g_spawn_async (NULL, plug_in->args, envp,
@ -450,8 +457,6 @@ plug_in_open (PlugIn *plug_in)
plug_in->args[0], plug_in->args[0],
error->message); error->message);
g_error_free (error); g_error_free (error);
plug_in_destroy (plug_in);
return FALSE; return FALSE;
} }
@ -496,9 +501,7 @@ plug_in_close (PlugIn *plug_in,
/* Ask the filter to exit gracefully */ /* Ask the filter to exit gracefully */
if (kill_it && plug_in->pid) if (kill_it && plug_in->pid)
{ {
plug_in_push (plug_in);
gp_quit_write (plug_in->my_write, plug_in); gp_quit_write (plug_in->my_write, plug_in);
plug_in_pop ();
/* give the plug-in some time (10 ms) */ /* give the plug-in some time (10 ms) */
#ifndef G_OS_WIN32 #ifndef G_OS_WIN32
@ -625,9 +628,6 @@ plug_in_recv_message (GIOChannel *channel,
plug_in = (PlugIn *) data; plug_in = (PlugIn *) data;
if (plug_in != current_plug_in)
plug_in_push (plug_in);
if (plug_in->my_read == NULL) if (plug_in->my_read == NULL)
return TRUE; return TRUE;
@ -666,9 +666,7 @@ plug_in_recv_message (GIOChannel *channel,
plug_in->args[0]); plug_in->args[0]);
if (! plug_in->open) if (! plug_in->open)
plug_in_destroy (plug_in); plug_in_unref (plug_in);
else
plug_in_pop ();
return TRUE; return TRUE;
} }
@ -809,9 +807,9 @@ plug_in_main_loop (PlugIn *plug_in)
plug_in->main_loops = g_list_prepend (plug_in->main_loops, main_loop); plug_in->main_loops = g_list_prepend (plug_in->main_loops, main_loop);
GDK_THREADS_LEAVE(); gimp_threads_leave (plug_in->gimp);
g_main_loop_run (main_loop); g_main_loop_run (main_loop);
GDK_THREADS_ENTER (); gimp_threads_enter (plug_in->gimp);
g_main_loop_unref (main_loop); g_main_loop_unref (main_loop);
} }

View File

@ -30,12 +30,15 @@ struct _PlugIn
{ {
Gimp *gimp; Gimp *gimp;
gint ref_count;
guint open : 1; /* Is the plug-in open? */ guint open : 1; /* Is the plug-in open? */
guint query : 1; /* Are we querying the plug-in? */ guint query : 1; /* Are we querying the plug-in? */
guint init : 1; /* Are we initialing the plug-in? */ guint init : 1; /* Are we initialing the plug-in? */
guint synchronous : 1; /* Is the plug-in running synchronously? */ guint synchronous : 1; /* Is the plug-in running synchronously? */
guint recurse : 1; /* Do we have an own GMainLoop? */ guint recurse : 1; /* Do we have an own GMainLoop? */
guint in_temp_proc : 1; /* Is the plug-in busy with a temp proc? */ guint in_temp_proc : 1; /* Is the plug-in busy with a temp proc? */
guint starting_ext : 1; /* Does the plug-in wait for extension_ack?*/
pid_t pid; /* Plug-ins process id */ pid_t pid; /* Plug-ins process id */
gchar *args[7]; /* Plug-ins command line arguments */ gchar *args[7]; /* Plug-ins command line arguments */
@ -44,7 +47,7 @@ struct _PlugIn
GIOChannel *his_read; /* Plug-in's read and write channels */ GIOChannel *his_read; /* Plug-in's read and write channels */
GIOChannel *his_write; GIOChannel *his_write;
guint32 input_id; /* Id of input proc */ guint input_id; /* Id of input proc */
gchar write_buffer[WRITE_BUFFER_SIZE]; /* Buffer for writing */ gchar write_buffer[WRITE_BUFFER_SIZE]; /* Buffer for writing */
gint write_buffer_index; /* Buffer index for writing */ gint write_buffer_index; /* Buffer index for writing */
@ -61,41 +64,29 @@ struct _PlugIn
}; };
void plug_in_init (Gimp *gimp); void plug_in_init (Gimp *gimp);
void plug_in_exit (Gimp *gimp); void plug_in_exit (Gimp *gimp);
void plug_in_call_query (Gimp *gimp, void plug_in_call_query (Gimp *gimp,
PlugInDef *plug_in_def); PlugInDef *plug_in_def);
void plug_in_call_init (Gimp *gimp, void plug_in_call_init (Gimp *gimp,
PlugInDef *plug_in_def); PlugInDef *plug_in_def);
/* Create a new plug-in structure PlugIn * plug_in_new (Gimp *gimp,
*/ gchar *name);
PlugIn * plug_in_new (Gimp *gimp,
gchar *name);
/* Destroy a plug-in structure. void plug_in_ref (PlugIn *plug_in);
* This will close the plug-in first if necessary. void plug_in_unref (PlugIn *plug_in);
*/
void plug_in_destroy (PlugIn *plug_in);
gboolean plug_in_open (PlugIn *plug_in);
void plug_in_close (PlugIn *plug_in,
gboolean kill_it);
/* Open a plug-in. This cause the plug-in to run. void plug_in_push (PlugIn *plug_in);
* If returns TRUE, you must destroy the plugin.
* If returns FALSE, you must not destroy the plugin.
*/
gboolean plug_in_open (PlugIn *plug_in);
/* Close a plug-in. This kills the plug-in and releases its resources.
*/
void plug_in_close (PlugIn *plug_in,
gboolean kill_it);
void plug_in_push (PlugIn *plug_in);
void plug_in_pop (void); void plug_in_pop (void);
void plug_in_main_loop (PlugIn *plug_in); void plug_in_main_loop (PlugIn *plug_in);
void plug_in_main_loop_quit (PlugIn *plug_in); void plug_in_main_loop_quit (PlugIn *plug_in);
extern PlugIn *current_plug_in; extern PlugIn *current_plug_in;

View File

@ -75,9 +75,9 @@ struct _PlugInHelpPathDef
}; };
static void plug_ins_init_file (GimpDatafileData *file_data); static void plug_ins_init_file (GimpDatafileData *file_data);
static void plug_ins_add_to_db (Gimp *gimp); static void plug_ins_add_to_db (Gimp *gimp);
static PlugInProcDef * plug_ins_proc_def_insert (PlugInProcDef *proc_def); static PlugInProcDef * plug_ins_proc_def_insert (PlugInProcDef *proc_def);
GSList *proc_defs = NULL; GSList *proc_defs = NULL;
@ -779,8 +779,6 @@ static void
plug_ins_add_to_db (Gimp *gimp) plug_ins_add_to_db (Gimp *gimp)
{ {
PlugInProcDef *proc_def; PlugInProcDef *proc_def;
Argument args[4];
Argument *return_vals;
GSList *list; GSList *list;
for (list = proc_defs; list; list = g_slist_next (list)) for (list = proc_defs; list; list = g_slist_next (list))
@ -800,6 +798,9 @@ plug_ins_add_to_db (Gimp *gimp)
if (proc_def->extensions || proc_def->prefixes || proc_def->magics) if (proc_def->extensions || proc_def->prefixes || proc_def->magics)
{ {
Argument args[4];
Argument *return_vals;
args[0].arg_type = GIMP_PDB_STRING; args[0].arg_type = GIMP_PDB_STRING;
args[0].value.pdb_pointer = proc_def->db_info.name; args[0].value.pdb_pointer = proc_def->db_info.name;