writing-a-plug-in-1.xml 12.9 KB
Newer Older
1 2
<?xml version='1.0'?>
<!DOCTYPE webpage PUBLIC "-//Norman Walsh//DTD Website V2.4.1//EN"
3 4 5
                         "dtd/website.dtd" [
<!ENTITY writing-a-plug-in-2 SYSTEM "writing-a-plug-in-2.xml" NDATA XML>
]>
6 7 8 9 10 11 12 13 14 15 16 17 18 19

<webpage id="writing-a-plug-in-1" lang="en">

  <head>
    <title>How to write a GIMP plug-in</title>
    <titleabbrev>Writing A Plug-In</titleabbrev>
    <summary>Write your own</summary>
  </head>

  <para>
    Written By <ulink url="mailto:bolsh@NOSPAM.gimp.org">Dave Neary</ulink>
  </para>

  <para>
20
    In this article, I present GIMP plug-ins basics and introduce the
Sven Neumann's avatar
Sven Neumann committed
21 22
    libgimp API.  I will also show how to use the PDB to make our
    plug-in available to other script authors.
23 24 25 26 27 28
  </para>

  <section>
    <title>Introduction</title>

    <para>
29
      New developers are often intimidated by The GIMP size and its
Sven Neumann's avatar
Sven Neumann committed
30 31 32
      reputation.  They think that writing a plug-in would be a
      difficult task. The goal of these articles is to dumb this
      feeling down, by showing how easily one can make a C plug-in.
33 34 35
    </para>

    <para>
Sven Neumann's avatar
Sven Neumann committed
36 37 38
      In this part, I present a plug-in's basic elements. We will see
      how to install a plug-in and how to get data from an image and
      directly manipulate it.
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
    </para>
  </section>

  <section>
    <title>Architecture</title>

    <para role="images">
      <ulink url="architecture.png">
        <mediaobject>
          <imageobject>
            <imagedata fileref="architecture-small.png"/>
          </imageobject>
          <textobject>
            <phrase>Architecture</phrase>
          </textobject>
        </mediaobject>
        Architecture
      </ulink>
    </para>

    <para>
Sven Neumann's avatar
Sven Neumann committed
60
      The GIMP script interface is centered on the Procedural database
61
      (PDB). At startup, The GIMP looks into a predefined set of
Sven Neumann's avatar
Sven Neumann committed
62 63
      places for scripts and plug-ins, and asks each new script to
      identify itself.
64 65 66 67
    </para>

    <para>
      The plug-in declares itself to the PDB at that time, and passes
Sven Neumann's avatar
Sven Neumann committed
68 69
      informations like the position it wishes to get in the menu
      hierarchy, input parameters, and output parameters.
70 71 72
    </para>

    <para>
Sven Neumann's avatar
Sven Neumann committed
73 74 75
      When a script or a plug-in wants to use our plug-in, it gets
      through the PDB, which manages communicating parameters in one
      direction and the other in a transparent way.
76 77 78
    </para>

    <para>
Sven Neumann's avatar
Sven Neumann committed
79 80 81 82
      Internal functions that wish to get exposed to plug-ins have to
      be packaged first in the core, that will register them in the
      PDB, and secondly in the libgimp that will allow the function to
      be called as a normal one.
83 84 85
    </para>

    <para>
Sven Neumann's avatar
Sven Neumann committed
86 87
      This was the introduction - now, we will look closer at our
      first plug-in, a "Hello, world!".
88 89 90 91 92 93 94
    </para>
  </section>

  <section>
    <title>Compiling the plug-in</title>

    <para>
Sven Neumann's avatar
Sven Neumann committed
95 96 97
      To be able to compile simple plug-ins for The GIMP, one needs
      libgimp headers, as well as an associated utility named
      gimptool.
98 99 100
    </para>

    <para>
Sven Neumann's avatar
Sven Neumann committed
101 102 103
      With that utility, one can install a plug-in either in a private
      directory (~/.gimp-2.0/plug-ins), or in the global plug-in
      directory.
104 105 106 107 108 109 110 111
    </para>

    <para>
      Syntax is
    </para>

    <programlisting>
    <![CDATA[
112
       gimptool-2.0 --install plugin.c or gimptool-2.0 --install-admin plugin.c
113 114 115 116
     ]]>
    </programlisting>

    <para>
Sven Neumann's avatar
Sven Neumann committed
117 118
      This utility, with other options, can also be used to install
      scripts, or uninstall plug-ins.
119 120 121 122
    </para>
  </section>

  <section>
123
    <title>Behaviour</title>
124 125

    <para>
Sven Neumann's avatar
Sven Neumann committed
126 127 128 129 130 131
      A GIMP plug-in can typically behave three different ways. It can
      take image data, modify it, and send back the modified image,
      like edge detection. It can generate an image and send it back,
      like some script-fus, or file reading plug-ins like jpeg. Or it
      can get an image, and process it without modifying its data,
      like a file saver plug-in.
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
    </para>
  </section>

  <section>
    <title>Essentials</title>

    <programlisting>
    <![CDATA[
      #include &lt;libgimp/gimp.h&gt;
     ]]>
    </programlisting>

    <para>
      This header makes all basic plug-in elements available to us.
    </para>

    <programlisting>
    <![CDATA[
      GimpPlugInInfo PLUG_IN_INFO = {
        init,
        quit,
        query,
        run
      };
     ]]>
    </programlisting>

    <para>
Sven Neumann's avatar
Sven Neumann committed
160 161 162 163
      This structure has to have that name. It contains four pointers
      to functions, which will be called at set times of the plug-in
      life. init and quit are optional, and thus can hold NULL values,
      but the last two functions, query and run, are mandatory.
164 165 166
    </para>

    <para>
Sven Neumann's avatar
Sven Neumann committed
167 168 169 170 171 172
      The init() function is called each time The GIMP starts up. This
      function is not typically used. Some plug-ins use it to make a
      secondary search that is not done by the core. This function is
      not used by any standard GIMP plug-in, but could be useful for
      example for a plug-in that would like to register some procedure
      conditionally on some files presence.
173 174 175
    </para>

    <para>
Sven Neumann's avatar
Sven Neumann committed
176 177
      The quit() function is not used much either. It is called when
      The GIMP is about to be closed, to allow it to free some
178
      resources. It is used in the script-fu plug-in.
179 180 181
    </para>

    <para>
Sven Neumann's avatar
Sven Neumann committed
182 183
      The query() function is called the first time the plug-in is
      present, and then each time the plug-in changes.
184 185 186
    </para>

    <para>
187
      The run() function is the plug-in's centrepiece. It is called
Sven Neumann's avatar
Sven Neumann committed
188 189 190 191 192
      when the plug-in is asked to run. It gets the plug-in name (as a
      plug-in can register several procedures), input parameters, and
      a pointer to output parameters, then determines if it is
      launched in a interactive way or by a script, and does all the
      plug-in processing. Its prototype is
193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210
    </para>

    <programlisting>
    <![CDATA[
      void run (const gchar      *name,
                gint              nparams,
                const GimpParam  *param,
                gint             *nreturn_vals,
                GimpParam       **return_vals);
     ]]>
    </programlisting>

  </section>

  <section>
    <title>MAIN ()</title>

    <para>
211
      MAIN is a C macro that holds a bit of dark magic to initialise
Sven Neumann's avatar
Sven Neumann committed
212 213
      arguments.  It also calls the appropriate PLUG_IN_INFO function
      depending on the timing. Your plug-in needs it.
214 215 216 217 218 219 220
    </para>
  </section>

  <section>
    <title>The query() function</title>

    <para>
Sven Neumann's avatar
Sven Neumann committed
221 222 223
      query() deals with the procedure registration and input
      arguments definition.  These informations are saved to speed up
      startup time, and refreshed only when the plug-in is modified.
224 225 226
    </para>

    <para>
Sven Neumann's avatar
Sven Neumann committed
227 228
      For our "Hello, world!" plug-in, the query function will look
      like this:
229 230 231 232
    </para>

    <programlisting>
    <![CDATA[
233 234
      static void
      query (void)
235 236 237 238
        {
          static GimpParamDef args[] = {
            {
              GIMP_PDB_INT32,
239
              "run-mode",
240 241 242 243 244 245 246 247 248 249 250 251 252 253 254
              "Run mode"
            },
            {
              GIMP_PDB_IMAGE,
              "image",
              "Input image"
            },
            {
              GIMP_PDB_DRAWABLE,
              "drawable",
              "Input drawable"
            }
          };

          gimp_install_procedure (
255
            "plug-in-hello",
256 257 258 259 260
            "Hello, world!",
            "Displays \"Hello, world!\" in a dialog",
            "David Neary",
            "Copyright David Neary",
            "2004",
261
            "_Hello world...",
262 263 264 265
            "RGB*, GRAY*",
            GIMP_PLUGIN,
            G_N_ELEMENTS (args), 0,
            args, NULL);
266 267

            gimp_plugin_menu_register ("plug-in-hello",
268
                                       "<Image>/Filters/Misc"); 
269 270 271 272 273
        }
     ]]>
    </programlisting>

    <para>
Sven Neumann's avatar
Sven Neumann committed
274 275
      GimpParamDef contains three things - the parameter type, its
      name, and a string describing the parameter.
276 277 278
    </para>

    <para>
Sven Neumann's avatar
Sven Neumann committed
279 280 281 282 283
      gimp_install_procedure declares the procedure name, some
      description and help strings, menu path where the plug-in should
      sit, image types handled by the plug-in, and at the end, input
      and output parameters number, as well as the parameters
      descriptors.
284 285 286
    </para>

    <para>
Sven Neumann's avatar
Sven Neumann committed
287 288 289
      "RGB*, GRAY*" declares the image types handled. It can be RGB,
      INDEXED or GRAY, with or without Alpha. So "RGB*, GRAY*"
      describes RGB, RGBA, GRAY or GRAY image type.
290 291 292
    </para>

    <para>
Sven Neumann's avatar
Sven Neumann committed
293 294
      GIMP_PLUGIN declares this procedure to be external, and not to
      be executed in The GIMP core.
295 296 297
    </para>

    <para>
Sven Neumann's avatar
Sven Neumann committed
298 299 300
      By adding a stub run function now, we can check that our plug-in
      has all the essential elements, and test that it registers
      itself in the PDB with the "Xtns->Plug-in Details" plug-in.
301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335
    </para>

    <para role="images">
      <ulink url="plug-in-details.png">
        <mediaobject>
          <imageobject>
            <imagedata fileref="plug-in-details-small.png"/>
          </imageobject>
          <textobject>
            <phrase>Plug-in details</phrase>
          </textobject>
        </mediaobject>
        Plug-in details
      </ulink>
    </para>

    <para role="images">
      <ulink url="plug-in-menu.png">
        <mediaobject>
          <imageobject>
            <imagedata fileref="plug-in-menu-small.png"/>
          </imageobject>
          <textobject>
            <phrase>Our plug-in is in the menus</phrase>
          </textobject>
        </mediaobject>
        Our plug-in is in the menus
      </ulink>
    </para>
  </section>

  <section>
    <title>The run() function</title>

    <para>
Sven Neumann's avatar
Sven Neumann committed
336 337
      The other required function for PLUG_IN_INFO is run. The core of
      the plug-in stands there.
338 339 340
    </para>

    <para>
Sven Neumann's avatar
Sven Neumann committed
341 342 343
      Output values (return_vals in the prototype) must have at least
      one value associated - the plug-in status. Typically, this
      parameter will hold "GIMP_PDB_SUCCESS".
344 345 346 347 348 349 350
    </para>
  </section>

  <section>
    <title>Run-modes</title>

    <para>
Sven Neumann's avatar
Sven Neumann committed
351 352 353
      One can run a plug-in in several different ways, it can be run
      from a GIMP menu if The GIMP is run interactively, or from a
      script or a batch, or from the "Filters->Repeat Last" shortcut.
354 355 356 357 358 359 360 361 362
    </para>

    <para>
      The "run_mode" input parameter can hold one of these values:
      "GIMP_RUN_INTERACTIVE", "GIMP_RUN_NONINTERACTIVE" or
      "GIMP_RUN_WITH_LAST_VALS".
    </para>

    <para>
Sven Neumann's avatar
Sven Neumann committed
363 364 365
      "GIMP_RUN_INTERACTIVE" is typically the only case where one
      creates an options dialog. Otherwise, one directly calls the
      processing with values from input parameters or from memory.
366 367 368
    </para>

    <para>
Sven Neumann's avatar
Sven Neumann committed
369 370 371
      For our test plug-in, we will simply display a dialog containing
      a "Hello, world!" message. Thankfully, this is really easy with
      GTK+. Our run function could be:
372 373 374 375
    </para>

    <programlisting>
    <![CDATA[
376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400
      static void
      run (const gchar      *name,
           gint              nparams,
           const GimpParam  *param,
           gint             *nreturn_vals,
           GimpParam       **return_vals)
      {
        static GimpParam  values[1];
        GimpPDBStatusType status = GIMP_PDB_SUCCESS;
        GimpRunMode       run_mode;

        /* Setting mandatory output values */
        *nreturn_vals = 1;
        *return_vals  = values;

        values[0].type = GIMP_PDB_STATUS;
        values[0].data.d_status = status;

        /* Getting run_mode - we won't display a dialog if 
         * we are in NONINTERACTIVE mode */
        run_mode = param[0].data.d_int32;

        if (run_mode != GIMP_RUN_NONINTERACTIVE)
          g_message("Hello, world!\n");
      }
401 402 403 404
     ]]>
    </programlisting>

    <para>
Sven Neumann's avatar
Sven Neumann committed
405
      Now, when we run our plug-in, there is action:
406 407 408 409 410 411 412 413 414 415 416 417
    </para>
    
    <para role="images">
      <mediaobject>
        <imageobject>
          <imagedata fileref="hello.png"/>
        </imageobject>
        <textobject>
          <phrase>Hello, world!</phrase>
        </textobject>
      </mediaobject>
    </para>
418 419

    <para>
420
      Have a look at the full <ulink url="hello.c">hello.c</ulink> plug-in code.
421
    </para>
422 423 424 425 426 427
  </section>

  <section>
    <title>Next part</title>

    <para>
428 429 430 431 432
      In <olink targetdocent="writing-a-plug-in-2">next part</olink>
      we will go on, making a more useful plug-in that will get its
      hands on image data. We will see how to use The GIMP image
      architecture to make the plug-in perform better, processing the
      image tile by tile.
433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450
    </para>
  </section>

  <section>
    <para role="images">
      <ulink url="http://creativecommons.org/licenses/by-nc-sa/2.5/">
        <mediaobject>
          <imageobject>
            <imagedata fileref="http://creativecommons.org/images/public/somerights20.gif"/>
          </imageobject>
          <textobject>
            <phrase>Creative Commons License</phrase>
          </textobject>
        </mediaobject>
      </ulink>
    </para>

    <para>
Sven Neumann's avatar
Sven Neumann committed
451 452 453 454
      This work is licensed under a <ulink
      url="http://creativecommons.org/licenses/by-nc-sa/2.5/">Creative
      Commons Attribution-NonCommercial-ShareAlike 2.5
      License</ulink>.
455 456
    </para>
  </section>
Sven Neumann's avatar
Sven Neumann committed
457

458 459
</webpage>