Chapter 2. Essentials of a Plug-in

Table of Contents
MAIN
The Query Procedure
The Run Procedure
Review
Run: More details

There are some things every plug-in simply must have if it is to be considered a plug-in, no matter what its purpose. Mainly, the plug-in has to register itself in the GIMP's procedure database, and it has to have a function to run when GIMP calls for that procedure. Here we'll look at how these functions are called, and just what components they really need.

MAIN

Every C program has a main() function — the first function that is called when the program is executed. The typical GIMP plug-in's main function is, in its entirety, as follows:


	MAIN()
      

MAIN is a macro, defined in libgimp/gimp.h, which calls a gimp_main function, which in turn does all sorts of neat stuff. It tries to make sure the plug-in is being called by GIMP, sets up some signal handling, sets up communication between the plug-in and GIMP, and queries the plug-in if need be.

GIMP queries plug-ins on start-up, and it expects them to register themselves in the procedural database (PDB). But how does GIMP know what function to call when it queries? It checks the value of the global variable PLUG_IN_INFO, of type GimpPlugInInfo. From gimp.h:

Figure 2-1. The GimpPlugInInfo Structure


typedef void (* GimpInitProc)  (void);
typedef void (* GimpQuitProc)  (void);
typedef void (* GimpQueryProc) (void);
typedef void (* GimpRunProc)   (gchar      *name,
                                gint        nparams,
                                GimpParam  *param,
                                gint       *nreturn_vals,
                                GimpParam **return_vals);

struct _GimpPlugInInfo
{
  /* called when the gimp application initially starts up */
  GimpInitProc  init_proc;

  /* called when the gimp application exits */
  GimpQuitProc  quit_proc;

  /* called by the gimp so that the plug-in can inform the
   *  gimp of what it does. (ie. installing a procedure database
   *  procedure).
   */
  GimpQueryProc query_proc;

  /* called to run a procedure the plug-in installed in the
   *  procedure database.
   */
  GimpRunProc   run_proc;
};

So PLUG_IN_INFO consists of pointers to four functions. The first two are ran when GIMP starts and exits, not commonly used among the plug-ins, and so are usually set to NULL. The third is the query function, which many plug-in authors have chosen to name query(). The fourth is called when the plug-in's procedure is to be run, and is, surprisingly enough, often called run(). An example:

Example 2-1. Defining PLUG_IN_INFO


/* Function prototypes */
static void query (void);
static void run (gchar      *name,
		 gint        nparams,
		 GimpParam  *param,
		 gint       *nreturn_vals,
		 GimpParam **return_vals);

/* Setting PLUG_IN_INFO */
GimpPlugInInfo PLUG_IN_INFO =
{
  NULL,    /* init_proc */
  NULL,    /* quit_proc */
  query,   /* query_proc */
  run,     /* run_proc */
};

The Query Procedure

As mentioned, GIMP expects plug-ins to register themselves in the PDB when they're queried. This is done through gimp_install_procedure (again, from gimp.h):

Figure 2-2. gimp_install_procedure

void gimp_install_procedure(char* name, char* blurb, char* help, char* author, char* copyright, char* menu_path, char* image_types, GimpPDBProcType type, int nparams, int nreturn_vals, GimpParamDef* params, GimpParamDef* return_vals);

Parameters name through date should be fairly self-explanatory. On the rest, I'll make some comment:

menu_path

A string describing where in the menu the procedure should be installed. It begins with one of <Toolbox>, <Image>, <Load>, or <Save>, followed by the menu path. For example, the Maze plug-in's menu_path is "<Image>/Filters/Render/Patterns/Maze...".

GIMP uses this information not only to place the menu, but also to decide what type of procedure it is. This affects its decision on which parameters are necessary for the procedure. Note also that a menu_path isn't required if you wish to install a procedure without one, but that's not the case for most plug-ins.

Source reference: app/plug_in.c, plug_in_handle_proc_install

image_types

A string listing what image types the plug-in will accept; any of RGB, RGBA, RGB*, GRAY, GRAYA, GRAY*, INDEXED, INDEXEDA, INDEXED*. RGB* is simply shorthand for both RGB and RGBA (same applies for GRAY* and INDEXED*). The list may be separated by spaces, tabs, or commas. Example: "RGB*, INDEXED" means the plug-in likes all RGB images (with or without alpha), indexed-color images (only without alpha), but not grayscale images of any sort.

Source reference: app/plug_in.c, plug_in_image_types_parse

nparams, nreturn_vals

The number of parameters (or return values) the procedure uses.

nparams, nreturn_vals

See below.

PDB Parameters

*params points to an array of parameter definitions. nparams is an integer that tells the number of parameters (equal to the length of the array). A parameter definition is of type GimpParamDef, which has three parts gimp.h:


struct _GimpParamDef
{
  GimpPDBArgType  type;
  gchar          *name;
  gchar          *description;
};
	    

Values for GimpPDBArgType are listed in gimpenums.h. Setting up parameters can be done like so:

Example 2-2. Establishing an array of parameters.


static GParamDef params[] =
  {
    { GIMP_PDB_INT32, "run_mode", "Interactive, non-interactive" },
    { GIMP_PDB_IMAGE, "image_id", "(unused)" },
    { GIMP_PDB_DRAWABLE, "drawable_id", "Drawable to draw on" },
    { GIMP_PDB_COLOR, "fgcolor",  "Color to draw with"}
  }
	  

You may be required to take certain parameters, depending on where in the menu you registered. You may ignore them once you get them, but they will be passed to you, so you must accept them nonetheless. (app/plug-in.c, plug_in_handle_proc_install):

Table 2-1. Menu locations and required parameters

Menu Location#Parameter typeDescription
<Toolbox>0INT32run mode
<Image>0INT32run mode
1IMAGEID of current image
2DRAWABLEID of current drawable
<Load>0INT32run mode
1STRINGFIXME
2STRINGFIXME
<Save>0INT32run mode
1IMAGEID of current image
2DRAWABLEID of current drawable
3STRINGFIXME
4STRINGFIXME

You may take any parameters you like in addition to the ones required. The required parameters must come first and in order, however.

Declaring return values works much the same way, with one note: Your procedure will have at least one return value (a status code), but that should not be counted in your nreturn_vals or included in your GParamDef return_vals.

The Run Procedure


/* called to run a procedure the plug-in installed in the
 *  procedure database.
 */
typedef void (* GimpRunProc)   (gchar      *name,
                                gint        nparams,
                                GimpParam  *param,
                                gint       *nreturn_vals,
                                GimpParam **return_vals);
	

The run procedure is where the action begins. Its responsibilities include making sure the plug-in was called correctly and setting return values, as well as making sure that your plug-in does whatever it is that it's supposed to do.

GIMP 1.1 Compatibility Note: In GIMP 1.1, the run parameter is always called with nparams == 3, when called in the normal interactive fashion (plug_in_callback, app/plug_in.c). This differs from GIMP 1.0 behaviour, where nparams was equal to whatever it was set to upon installation of the procedure in the query function.

GimpParam


struct _GimpParam
{
  GimpPDBArgType type;
  GimpParamData  data;
};
	  

union _GimpParamData
{
  gint32            d_int32;
  gint16            d_int16;
  gint8             d_int8;
  gdouble           d_float;
  gchar            *d_string;
  gint32           *d_int32array;
  gint16           *d_int16array;
  gint8            *d_int8array;
  gdouble          *d_floatarray;
  gchar           **d_stringarray;
  GimpParamColor    d_color;
  GimpParamRegion   d_region;
  gint32            d_display;
  gint32            d_image;
  gint32            d_layer;
  gint32            d_layer_mask;
  gint32            d_channel;
  gint32            d_drawable;
  gint32            d_selection;
  gint32            d_boundary;
  gint32            d_path;
  gint32            d_unit;
  GimpParasite      d_parasite;
  gint32            d_tattoo;
  gint32            d_status;
};
	  

Note that GimpParamData is a union, not a structure. It only holds one value at a time.

Return values

It's expected (in app/procedural_db.c that you return a status code as the first return value (the zeroth in C land). That's a GimpPDBArgType of GIMP_PDB_STATUS, and a value from GimpPDBStatusType (GIMP_PDB_EXECUTION_ERROR, GIMP_PDB_CALLING_ERROR, GIMP_PDB_PASS_THROUGH, GIMP_PDB_SUCCESS), or GIMP_PDB_CANCEL).

Review

What every plug-in needs:

  1. #include <libgimp/gimp.h>

  2. PLUG_IN_INFO

  3. MAIN

  4. A query function, with a call to gimp_install_procedure.

  5. A run function, setting a status code return value.

Run: More details

We've said what's required. Now, what's a good idea? This section previously contained some well-intentioned practical advise on how to implement what you just learned, but it was so terribly written that I can't bear to bring it back. So for learning about implementations, I'm afraid you'll be much better off reading source code until this gets re-written.

Move on to the next section to learn more things…