Commit 54fe3402 authored by GMT 1999  Austin Donnelly's avatar GMT 1999 Austin Donnelly Committed by Austin Donnelly

New manpage plus bumper fun pack of bugfixes.

Sun Feb 14 01:27:29 GMT 1999  Austin Donnelly  <austin@gimp.org>

	New manpage plus bumper fun pack of bugfixes.

	* gimprc.5.in: NEW FILE: beginnings of some docs on gimprc file
	     format.
	* configure.in: generate gimprc.5 from gimprc.5.in
	* Makefile.am: install gimprc.5
	* .cvsignore: ignore gimprc.5, it's auto generated.

	* gimp.1: fix a few paths and URLs.  Mention the modules/
	     directory in user's gimpdir.

	* app/commands.c: cancel resize or scale dialogs when image
 	     they're for is destroyed, rather than segfaulting when Ok is
 	     clicked.  Thanks to Peter Teichman <peter@zeno.dorm.duke.edu>
 	     for pointing this one out.  Layer resize/scale still suffers
 	     from same problem, but Adam's working on L&C at the moment.

	* app/gdisplay.c: off-by one error on bounds check in making image
	     title.

	* app/module_db.c: some would consider it foolish returning to
 	     code you've just unloaded.  So don't do that.

	* app/plug_in.c: when superceeding a PDB function with a newer one
	     of the same name, remove pointers to the old one from the
	     plugins that originally registered them.  Fixes Nick Lamb's
	     pluginrc file corruption thing, and catches the (common?)
	     error of copying a plugin to a different name but failing to
	     change what it registers.  Also, if registering a file
	     loader/saver, make sure it has set an extension, prefix, or
	     magic number it's interested in - that way code that relies
	     on checking this doesn't get confused.
parent 446a11e9
......@@ -6,6 +6,7 @@ config.h
config.cache
stamp-h
gimprc
gimprc.5
config.status
libtool
aclocal.m4
......
Sun Feb 14 01:27:29 GMT 1999 Austin Donnelly <austin@gimp.org>
New manpage plus bumper fun pack of bugfixes.
* gimprc.5.in: NEW FILE: beginnings of some docs on gimprc file
format.
* configure.in: generate gimprc.5 from gimprc.5.in
* Makefile.am: install gimprc.5
* .cvsignore: ignore gimprc.5, it's auto generated.
* gimp.1: fix a few paths and URLs. Mention the modules/
directory in user's gimpdir.
* app/commands.c: cancel resize or scale dialogs when image
they're for is destroyed, rather than segfaulting when Ok is
clicked. Thanks to Peter Teichman <peter@zeno.dorm.duke.edu>
for pointing this one out. Layer resize/scale still suffers
from same problem, but Adam's working on L&C at the moment.
* app/gdisplay.c: off-by one error on bounds check in making image
title.
* app/module_db.c: some would consider it foolish returning to
code you've just unloaded. So don't do that.
* app/plug_in.c: when superceeding a PDB function with a newer one
of the same name, remove pointers to the old one from the
plugins that originally registered them. Fixes Nick Lamb's
pluginrc file corruption thing, and catches the (common?)
error of copying a plugin to a different name but failing to
change what it registers. Also, if registering a file
loader/saver, make sure it has set an extension, prefix, or
magic number it's interested in - that way code that relies
on checking this doesn't get confused.
Sat Feb 13 19:05:16 CET 1999 Marc Lehmann <pcg@goof.com>
* app/internal_procs.c
......
......@@ -25,6 +25,7 @@ EXTRA_DIST = \
gimpdata_DATA = \
gimprc \
gimprc_user \
gimprc.5 \
gtkrc \
gimp_logo.ppm \
gimp_splash.ppm \
......@@ -35,7 +36,7 @@ gimpdata_DATA = \
gimpdata_SCRIPTS = user_install
man_MANS=gimp.1 gimptool.1
man_MANS=gimp.1 gimptool.1 gimprc.5
m4datadir = $(datadir)/aclocal
m4data_DATA = gimp.m4
......
......@@ -789,6 +789,11 @@ image_resize_cmd_callback (GtkWidget *widget,
GTK_SIGNAL_FUNC (image_delete_callback),
image_resize);
/* handle the image disappearing under our feet */
gtk_signal_connect (GTK_OBJECT (gdisp->gimage), "destroy",
GTK_SIGNAL_FUNC (image_cancel_callback),
image_resize);
/* the main vbox */
vbox = gtk_vbox_new (FALSE, 1);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 1);
......@@ -836,6 +841,11 @@ image_scale_cmd_callback (GtkWidget *widget,
GTK_SIGNAL_FUNC (image_delete_callback),
image_scale);
/* handle the image disappearing under our feet */
gtk_signal_connect (GTK_OBJECT (gdisp->gimage), "destroy",
GTK_SIGNAL_FUNC (image_cancel_callback),
image_scale);
/* the main vbox */
vbox = gtk_vbox_new (FALSE, 1);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 1);
......@@ -1134,6 +1144,11 @@ image_resize_callback (GtkWidget *w,
GImage *gimage;
image_resize = (ImageResize *) client_data;
gtk_signal_disconnect_by_func (GTK_OBJECT (image_resize->gimage),
GTK_SIGNAL_FUNC (image_cancel_callback),
image_resize);
if ((gimage = image_resize->gimage) != NULL)
{
if (image_resize->resize->width > 0 &&
......@@ -1166,6 +1181,11 @@ image_scale_callback (GtkWidget *w,
GImage *gimage;
image_scale = (ImageResize *) client_data;
gtk_signal_disconnect_by_func (GTK_OBJECT (image_scale->gimage),
GTK_SIGNAL_FUNC (image_cancel_callback),
image_scale);
if ((gimage = image_scale->gimage) != NULL)
{
if (image_scale->resize->width > 0 &&
......@@ -1207,6 +1227,10 @@ image_cancel_callback (GtkWidget *w,
image_resize = (ImageResize *) client_data;
gtk_signal_disconnect_by_func (GTK_OBJECT (image_resize->gimage),
GTK_SIGNAL_FUNC (image_cancel_callback),
image_resize);
gtk_widget_destroy (image_resize->shell);
resize_widget_free (image_resize->resize);
g_free (image_resize);
......
......@@ -106,7 +106,9 @@ static void plug_in_add_to_db (void);
static void plug_in_make_menu (void);
static void plug_in_callback (GtkWidget *widget,
gpointer client_data);
static void plug_in_proc_def_insert (PlugInProcDef *proc_def);
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,
int data_only);
......@@ -394,6 +396,7 @@ ProcRecord plugin_query_proc =
};
void
plug_in_init ()
{
......@@ -500,7 +503,7 @@ plug_in_init ()
{
proc_def = g_new (PlugInProcDef, 1);
*proc_def = *((PlugInProcDef*) tmp->data);
plug_in_proc_def_insert (proc_def);
plug_in_proc_def_insert (proc_def, NULL);
tmp = tmp->next;
}
......@@ -517,7 +520,7 @@ plug_in_init ()
tmp2 = tmp2->next;
proc_def->mtime = plug_in_def->mtime;
plug_in_proc_def_insert (proc_def);
plug_in_proc_def_insert (proc_def, plug_in_proc_def_dead);
}
}
......@@ -788,6 +791,7 @@ plug_in_def_add (PlugInDef *plug_in_def)
{
GSList *tmp;
PlugInDef *tplug_in_def;
PlugInProcDef *proc_def;
char *t1, *t2;
t1 = strrchr (plug_in_def->prog, '/');
......@@ -796,6 +800,27 @@ plug_in_def_add (PlugInDef *plug_in_def)
else
t1 = 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 */
tmp = plug_in_def->proc_defs;
while (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("");
}
tmp = tmp->next;
}
tmp = plug_in_defs;
while (tmp)
{
......@@ -2388,7 +2413,8 @@ plug_in_callback (GtkWidget *widget,
}
static void
plug_in_proc_def_insert (PlugInProcDef *proc_def)
plug_in_proc_def_insert (PlugInProcDef *proc_def,
void (*superceed_fn)(void*))
{
PlugInProcDef *tmp_proc_def;
GSList *tmp, *prev;
......@@ -2416,6 +2442,9 @@ plug_in_proc_def_insert (PlugInProcDef *proc_def)
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;
}
......@@ -2441,6 +2470,31 @@ plug_in_proc_def_insert (PlugInProcDef *proc_def)
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. */
tmp = plug_in_defs;
while (tmp)
{
plug_in_def = tmp->data;
plug_in_def->proc_defs = g_slist_remove (plug_in_def->proc_defs,
freed_proc_def);
tmp = tmp->next;
}
}
static void
plug_in_proc_def_remove (PlugInProcDef *proc_def)
{
......
......@@ -789,6 +789,11 @@ image_resize_cmd_callback (GtkWidget *widget,
GTK_SIGNAL_FUNC (image_delete_callback),
image_resize);
/* handle the image disappearing under our feet */
gtk_signal_connect (GTK_OBJECT (gdisp->gimage), "destroy",
GTK_SIGNAL_FUNC (image_cancel_callback),
image_resize);
/* the main vbox */
vbox = gtk_vbox_new (FALSE, 1);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 1);
......@@ -836,6 +841,11 @@ image_scale_cmd_callback (GtkWidget *widget,
GTK_SIGNAL_FUNC (image_delete_callback),
image_scale);
/* handle the image disappearing under our feet */
gtk_signal_connect (GTK_OBJECT (gdisp->gimage), "destroy",
GTK_SIGNAL_FUNC (image_cancel_callback),
image_scale);
/* the main vbox */
vbox = gtk_vbox_new (FALSE, 1);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 1);
......@@ -1134,6 +1144,11 @@ image_resize_callback (GtkWidget *w,
GImage *gimage;
image_resize = (ImageResize *) client_data;
gtk_signal_disconnect_by_func (GTK_OBJECT (image_resize->gimage),
GTK_SIGNAL_FUNC (image_cancel_callback),
image_resize);
if ((gimage = image_resize->gimage) != NULL)
{
if (image_resize->resize->width > 0 &&
......@@ -1166,6 +1181,11 @@ image_scale_callback (GtkWidget *w,
GImage *gimage;
image_scale = (ImageResize *) client_data;
gtk_signal_disconnect_by_func (GTK_OBJECT (image_scale->gimage),
GTK_SIGNAL_FUNC (image_cancel_callback),
image_scale);
if ((gimage = image_scale->gimage) != NULL)
{
if (image_scale->resize->width > 0 &&
......@@ -1207,6 +1227,10 @@ image_cancel_callback (GtkWidget *w,
image_resize = (ImageResize *) client_data;
gtk_signal_disconnect_by_func (GTK_OBJECT (image_resize->gimage),
GTK_SIGNAL_FUNC (image_cancel_callback),
image_resize);
gtk_widget_destroy (image_resize->shell);
resize_widget_free (image_resize->resize);
g_free (image_resize);
......
......@@ -271,7 +271,7 @@ gdisplay_format_title (GDisplay *gdisp,
format++;
}
title[MIN(i, title_len)] = 0;
title[MIN(i, title_len-1)] = 0;
}
......
......@@ -60,6 +60,7 @@ typedef struct {
gboolean ondisk; /* TRUE if file still exists */
/* stuff from now on may be NULL depending on the state the module is in */
GimpModuleInfo *info; /* returned values from module_init */
gint refs; /* how many time we're running in the module */
GModule *module; /* handle on the module */
gchar *last_module_error;
GimpModuleInitFunc *init;
......@@ -111,6 +112,10 @@ static void browser_load_unload_callback (GtkWidget *widget, gpointer data);
static void browser_refresh_callback (GtkWidget *widget, gpointer data);
static void make_list_item (gpointer data, gpointer user_data);
static void gimp_module_ref (module_info *mod);
static void gimp_module_unref (module_info *mod);
/**************************************************************/
/* Exported functions */
......@@ -457,8 +462,11 @@ mod_unload_completed_callback (void *data)
g_return_if_fail (mod->state == ST_UNLOAD_REQUESTED);
g_module_close (mod->module);
mod->module = NULL;
if (mod->refs == 0)
{
g_module_close (mod->module);
mod->module = NULL;
}
mod->info = NULL;
mod->state = ST_UNLOADED_OK;
......@@ -477,8 +485,12 @@ mod_unload (module_info *mod, gboolean verbose)
mod->state = ST_UNLOAD_REQUESTED;
/* send the unload request */
/* send the unload request. Need to ref the module so we don't
* accidentally unload it while this call is in progress (eg if the
* callback is called before the unload function returns). */
gimp_module_ref (mod);
mod->unload (mod->info->shutdown_data, mod_unload_completed_callback, mod);
gimp_module_unref (mod);
}
......@@ -819,3 +831,29 @@ browser_refresh_callback (GtkWidget *widget, gpointer data)
datafiles_read_directories (module_path,
module_initialize, 0 /* no flags */);
}
static void
gimp_module_ref (module_info *mod)
{
g_return_if_fail (mod->refs >= 0);
g_return_if_fail (mod->module != NULL);
mod->refs++;
}
static void
gimp_module_unref (module_info *mod)
{
g_return_if_fail (mod->refs > 0);
g_return_if_fail (mod->module != NULL);
mod->refs--;
if (mod->refs == 0)
{
g_module_close (mod->module);
mod->module = NULL;
}
}
/* End of module_db.c */
......@@ -271,7 +271,7 @@ gdisplay_format_title (GDisplay *gdisp,
format++;
}
title[MIN(i, title_len)] = 0;
title[MIN(i, title_len-1)] = 0;
}
......
......@@ -271,7 +271,7 @@ gdisplay_format_title (GDisplay *gdisp,
format++;
}
title[MIN(i, title_len)] = 0;
title[MIN(i, title_len-1)] = 0;
}
......
......@@ -789,6 +789,11 @@ image_resize_cmd_callback (GtkWidget *widget,
GTK_SIGNAL_FUNC (image_delete_callback),
image_resize);
/* handle the image disappearing under our feet */
gtk_signal_connect (GTK_OBJECT (gdisp->gimage), "destroy",
GTK_SIGNAL_FUNC (image_cancel_callback),
image_resize);
/* the main vbox */
vbox = gtk_vbox_new (FALSE, 1);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 1);
......@@ -836,6 +841,11 @@ image_scale_cmd_callback (GtkWidget *widget,
GTK_SIGNAL_FUNC (image_delete_callback),
image_scale);
/* handle the image disappearing under our feet */
gtk_signal_connect (GTK_OBJECT (gdisp->gimage), "destroy",
GTK_SIGNAL_FUNC (image_cancel_callback),
image_scale);
/* the main vbox */
vbox = gtk_vbox_new (FALSE, 1);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 1);
......@@ -1134,6 +1144,11 @@ image_resize_callback (GtkWidget *w,
GImage *gimage;
image_resize = (ImageResize *) client_data;
gtk_signal_disconnect_by_func (GTK_OBJECT (image_resize->gimage),
GTK_SIGNAL_FUNC (image_cancel_callback),
image_resize);
if ((gimage = image_resize->gimage) != NULL)
{
if (image_resize->resize->width > 0 &&
......@@ -1166,6 +1181,11 @@ image_scale_callback (GtkWidget *w,
GImage *gimage;
image_scale = (ImageResize *) client_data;
gtk_signal_disconnect_by_func (GTK_OBJECT (image_scale->gimage),
GTK_SIGNAL_FUNC (image_cancel_callback),
image_scale);
if ((gimage = image_scale->gimage) != NULL)
{
if (image_scale->resize->width > 0 &&
......@@ -1207,6 +1227,10 @@ image_cancel_callback (GtkWidget *w,
image_resize = (ImageResize *) client_data;
gtk_signal_disconnect_by_func (GTK_OBJECT (image_resize->gimage),
GTK_SIGNAL_FUNC (image_cancel_callback),
image_resize);
gtk_widget_destroy (image_resize->shell);
resize_widget_free (image_resize->resize);
g_free (image_resize);
......
......@@ -789,6 +789,11 @@ image_resize_cmd_callback (GtkWidget *widget,
GTK_SIGNAL_FUNC (image_delete_callback),
image_resize);
/* handle the image disappearing under our feet */
gtk_signal_connect (GTK_OBJECT (gdisp->gimage), "destroy",
GTK_SIGNAL_FUNC (image_cancel_callback),
image_resize);
/* the main vbox */
vbox = gtk_vbox_new (FALSE, 1);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 1);
......@@ -836,6 +841,11 @@ image_scale_cmd_callback (GtkWidget *widget,
GTK_SIGNAL_FUNC (image_delete_callback),
image_scale);
/* handle the image disappearing under our feet */
gtk_signal_connect (GTK_OBJECT (gdisp->gimage), "destroy",
GTK_SIGNAL_FUNC (image_cancel_callback),
image_scale);
/* the main vbox */
vbox = gtk_vbox_new (FALSE, 1);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 1);
......@@ -1134,6 +1144,11 @@ image_resize_callback (GtkWidget *w,
GImage *gimage;
image_resize = (ImageResize *) client_data;
gtk_signal_disconnect_by_func (GTK_OBJECT (image_resize->gimage),
GTK_SIGNAL_FUNC (image_cancel_callback),
image_resize);
if ((gimage = image_resize->gimage) != NULL)
{
if (image_resize->resize->width > 0 &&
......@@ -1166,6 +1181,11 @@ image_scale_callback (GtkWidget *w,
GImage *gimage;
image_scale = (ImageResize *) client_data;
gtk_signal_disconnect_by_func (GTK_OBJECT (image_scale->gimage),
GTK_SIGNAL_FUNC (image_cancel_callback),
image_scale);
if ((gimage = image_scale->gimage) != NULL)
{
if (image_scale->resize->width > 0 &&
......@@ -1207,6 +1227,10 @@ image_cancel_callback (GtkWidget *w,
image_resize = (ImageResize *) client_data;
gtk_signal_disconnect_by_func (GTK_OBJECT (image_resize->gimage),
GTK_SIGNAL_FUNC (image_cancel_callback),
image_resize);
gtk_widget_destroy (image_resize->shell);
resize_widget_free (image_resize->resize);
g_free (image_resize);
......
......@@ -60,6 +60,7 @@ typedef struct {
gboolean ondisk; /* TRUE if file still exists */
/* stuff from now on may be NULL depending on the state the module is in */
GimpModuleInfo *info; /* returned values from module_init */
gint refs; /* how many time we're running in the module */
GModule *module; /* handle on the module */
gchar *last_module_error;
GimpModuleInitFunc *init;
......@@ -111,6 +112,10 @@ static void browser_load_unload_callback (GtkWidget *widget, gpointer data);
static void browser_refresh_callback (GtkWidget *widget, gpointer data);
static void make_list_item (gpointer data, gpointer user_data);
static void gimp_module_ref (module_info *mod);
static void gimp_module_unref (module_info *mod);
/**************************************************************/
/* Exported functions */
......@@ -457,8 +462,11 @@ mod_unload_completed_callback (void *data)
g_return_if_fail (mod->state == ST_UNLOAD_REQUESTED);
g_module_close (mod->module);
mod->module = NULL;
if (mod->refs == 0)
{
g_module_close (mod->module);
mod->module = NULL;
}
mod->info = NULL;
mod->state = ST_UNLOADED_OK;
......@@ -477,8 +485,12 @@ mod_unload (module_info *mod, gboolean verbose)
mod->state = ST_UNLOAD_REQUESTED;
/* send the unload request */
/* send the unload request. Need to ref the module so we don't
* accidentally unload it while this call is in progress (eg if the
* callback is called before the unload function returns). */
gimp_module_ref (mod);
mod->unload (mod->info->shutdown_data, mod_unload_completed_callback, mod);
gimp_module_unref (mod);
}
......@@ -819,3 +831,29 @@ browser_refresh_callback (GtkWidget *widget, gpointer data)
datafiles_read_directories (module_path,
module_initialize, 0 /* no flags */);
}
static void
gimp_module_ref (module_info *mod)
{
g_return_if_fail (mod->refs >= 0);
g_return_if_fail (mod->module != NULL);
mod->refs++;
}
static void
gimp_module_unref (module_info *mod)
{
g_return_if_fail (mod->refs > 0);
g_return_if_fail (mod->module != NULL);
mod->refs--;
if (mod->refs == 0)
{
g_module_close (mod->module);
mod->module = NULL;
}
}
/* End of module_db.c */
......@@ -106,7 +106,9 @@ static void plug_in_add_to_db (void);
static void plug_in_make_menu (void);
static void plug_in_callback (GtkWidget *widget,
gpointer client_data);
static void plug_in_proc_def_insert (PlugInProcDef *proc_def);
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,
int data_only);
......@@ -394,6 +396,7 @@ ProcRecord plugin_query_proc =
};
void
plug_in_init ()
{
......@@ -500,7 +503,7 @@ plug_in_init ()
{
proc_def = g_new (PlugInProcDef, 1);
*proc_def = *((PlugInProcDef*) tmp->data);
plug_in_proc_def_insert (proc_def);
plug_in_proc_def_insert (proc_def, NULL);
tmp = tmp->next;
}
......@@ -517,7 +520,7 @@ plug_in_init ()
tmp2 = tmp2->next;
proc_def->mtime = plug_in_def->mtime;
plug_in_proc_def_insert (proc_def);
plug_in_proc_def_insert (proc_def, plug_in_proc_def_dead);
}
}
......@@ -788,6 +791,7 @@ plug_in_def_add (PlugInDef *plug_in_def)
{
GSList *tmp;
PlugInDef *tplug_in_def;
PlugInProcDef *proc_def;
char *t1, *t2;
t1 = strrchr (plug_in_def->prog, '/');
......@@ -796,6 +800,27 @@ plug_in_def_add (PlugInDef *plug_in_def)
else
t1 = 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 */
tmp = plug_in_def->proc_defs;
while (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("");
}
tmp = tmp->next;
}
tmp = plug_in_defs;
while (tmp)
{
......@@ -2388,7 +2413,8 @@ plug_in_callback (GtkWidget *widget,
}
static void
plug_in_proc_def_insert (PlugInProcDef *proc_def)
plug_in_proc_def_insert (PlugInProcDef *proc_def,
void (*superceed_fn)(void*))
{
PlugInProcDef *tmp_proc_def;
GSList *tmp, *prev;
......@@ -2416,6 +2442,9 @@ plug_in_proc_def_insert (PlugInProcDef *proc_def)
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;
}
......@@ -2441,6 +2470,31 @@ plug_in_proc_def_insert (PlugInProcDef *proc_def)
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. */
tmp = plug_in_defs;
while (tmp)
{
plug_in_def = tmp->data;
plug_in_def->proc_defs = g_slist_remove (plug_in_def->proc_defs,
freed_proc_def);
tmp = tmp->next;
}
}
static void
plug_in_proc_def_remove (PlugInProcDef *proc_def)
{
......
......@@ -106,7 +106,9 @@ static void plug_in_add_to_db (void);
static void plug_in_make_menu (void);
static void plug_in_callback (GtkWidget *widget,
gpointer client_data);
static void plug_in_proc_def_insert (PlugInProcDef *proc_def);
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,
int data_only);
......@@ -394,6 +396,7 @@ ProcRecord plugin_query_proc =
};
void
plug_in_init ()
{
......@@ -500,7 +503,7 @@ plug_in_init ()
{
proc_def = g_new (PlugInProcDef, 1);
*proc_def = *((PlugInProcDef*) tmp->data);
plug_in_proc_def_insert (proc_def);
plug_in_proc_def_insert (proc_def, NULL);