libgimp: some fixes in GimpPlugin.

- We were leaking the result of query_procedures(). At least as far as
  the example port (help plug-in) shows, it returns a newly allocated
  array of strings, NULL-terminated. This needs to be freed by the
  calling code.
- Add documentations on GimpPlugIn virtual methods so that people know
  what to do with them, and what kind of data to return (like
  NULL-terminated array of procedure names for simple freeing).
- Fix _gimp_plug_in_init() which was registering the query procedures
  instead of the init ones. For this, I added a `init` boolean parameter
  to gimp_plug_in_register().
- Finally check the return value of gimp_plug_in_create_procedure(). It
  is possible that a plug-in not properly implemented returns NULL and
  we want to avoid the CRITICAL. Still output a warning as this is
  likely a plug-in development bug.
This commit is contained in:
Jehan 2019-07-31 12:20:20 +02:00
parent cd1ba1cd17
commit 1291769cc7
2 changed files with 82 additions and 8 deletions

View File

@ -28,7 +28,8 @@
/* local function prototpes */
static void gimp_plug_in_register (GimpPlugIn *plug_in);
static void gimp_plug_in_register (GimpPlugIn *plug_in,
gboolean init);
/* public functions */
@ -41,7 +42,7 @@ _gimp_plug_in_init (GimpPlugIn *plug_in)
if (! GIMP_PLUG_IN_GET_CLASS (plug_in)->init_procedures)
return;
gimp_plug_in_register (plug_in);
gimp_plug_in_register (plug_in, TRUE);
}
void
@ -52,7 +53,7 @@ _gimp_plug_in_query (GimpPlugIn *plug_in)
if (! GIMP_PLUG_IN_GET_CLASS (plug_in)->query_procedures)
return;
gimp_plug_in_register (plug_in);
gimp_plug_in_register (plug_in, FALSE);
}
void
@ -68,24 +69,38 @@ _gimp_plug_in_quit (GimpPlugIn *plug_in)
/* private functions */
static void
gimp_plug_in_register (GimpPlugIn *plug_in)
gimp_plug_in_register (GimpPlugIn *plug_in,
gboolean init)
{
gchar **procedures;
gint n_procedures;
gint i;
GList *list;
procedures = GIMP_PLUG_IN_GET_CLASS (plug_in)->query_procedures (plug_in,
&n_procedures);
if (init)
procedures = GIMP_PLUG_IN_GET_CLASS (plug_in)->init_procedures (plug_in,
&n_procedures);
else
procedures = GIMP_PLUG_IN_GET_CLASS (plug_in)->query_procedures (plug_in,
&n_procedures);
for (i = 0; i < n_procedures; i++)
{
GimpProcedure *procedure;
procedure = gimp_plug_in_create_procedure (plug_in, procedures[i]);
_gimp_procedure_register (procedure);
g_object_unref (procedure);
if (procedure)
{
_gimp_procedure_register (procedure);
g_object_unref (procedure);
}
else
{
g_warning ("Plug-in failed to create procedure '%s'\n",
procedures[i]);
}
}
g_clear_pointer (&procedures, g_strfreev);
if (plug_in->priv->translation_domain_name)
{

View File

@ -53,13 +53,72 @@ struct _GimpPlugInClass
{
GObjectClass parent_class;
/**
* quit:
* @plug_in: a #GimpPlugIn.
*
* This method can be overridden by a plug-in which needs to perform
* some actions upon quitting.
*/
void (* quit) (GimpPlugIn *plug_in);
/**
* init_procedures:
* @plug_in: a #GimpPlugIn.
* @n_procedures: (out) number of procedures.
*
* This method can be overridden by all plug-ins to return a newly
* allocated array of allocated strings naming procedures registered
* by this plug-in.
* This array of strings must be NULL-terminated (i.e. freeable by
* g_strfreev()).
*
* It is different from query_procedures() in that init happens at every
* startup, whereas query happens only once in the life of a plug-in
* (right after installation or update). Hence init_procedures()
* typically returns procedures dependent to runtime conditions (such
* as the presence of a third-party tool), whereas query_procedures()
* would usually return unconditional and always available procedures.
* Most of the time, you only want to override query_procedures() and
* leave init_procedures() untouched.
*
* Returns: (out) (array length=n_procedures) (transfer full) (element-type gchar):
* the names of the procedures registered by @plug_in.
*/
gchar ** (* init_procedures) (GimpPlugIn *plug_in,
gint *n_procedures);
/**
* query_procedures:
* @plug_in: a #GimpPlugIn.
* @n_procedures: (out) number of procedures.
*
* This method can be overridden by all plug-ins to return a newly
* allocated array of allocated strings naming the procedures
* registered by this plug-in.
* This array of strings must be NULL-terminated (i.e. freeable by
* g_strfreev()).
*
* See documentation of init_procedures() for differences.
*
* Returns: (out) (array length=n_procedures) (transfer full) (element-type gchar):
* the names of the procedures registered by @plug_in.
*/
gchar ** (* query_procedures) (GimpPlugIn *plug_in,
gint *n_procedures);
/**
* create_procedure:
* @plug_in: a #GimpPlugIn.
* @name: procedure name.
*
* This method should be overridden by all plug-ins and return a newly
* allocated #GimpProcedure named @name.
* It will be called for every @name as returned by query_procedures()
* so care must be taken.
*
* Returns: (out) (array length=n_procedures) (transfer full) (element-type gchar):
* the names of the procedures registered by @plug_in.
*/
GimpProcedure * (* create_procedure) (GimpPlugIn *plug_in,
const gchar *name);