Provided by: libgtk2-perl-doc_1.249-2_all bug

NAME

       Gtk2::devel - The internal workings of the gtk2-perl language bindings

DESCRIPTION

       This document is a supplement to Glib::devel, and assumes you have read and understood all
       about how the base Glib bindings work.  Most of this will seem like nonsense, otherwise.

       Here we focus on the ways in which Gtk2 extends Glib's concepts for binding the Gtk+ C
       libraries to perl, a methodology and set of tools you can use to wrap your own GObject-
       based libraries.

GtkObject

       GtkObject adds the idea of a floating reference to GObject.  A GObject is created with one
       reference which must be explicitly removed by its owner.  GtkObject has a floating
       reference which is sunk by the code which wants to own it.  This makes it less painful to
       create lots of objects in a row (you don't have to unref them).

       To allow for this difference in procedure for taking ownership of an object, Glib allows
       you to register a "sink" function for a particular class.  When asked to create a wrapper
       that owns the object, gperl_new_object will compare the list of registered sink functions
       with the type of the object; if the object is descended from a type, that sink function
       will be run on the object.  The default one is g_object_unref(), of course.  (this is
       inspired by pygtk.)

       Thus, in Gtk2::Object's boot code, we register gtk_object_sink as the sink func for types
       derived from GtkObject.   Now all wrappers for these types will be owned the proper way.

       Of course, since gtk_object_sink() does nothing if the object isn't floating, it doesn't
       hurt anything if you always call gperl_new_object with "own" set to TRUE.  So, to make
       life a little easier, Gtk2 defines another function

        SV * gtk2perl_new_gtkobject (GtkObject * o);

       Which does nothing more than

        {
            return gperl_new_object (G_OBJECT (o), TRUE);
        }

       It's also important to know that this is largely done for you by the typemap.

Typemap scheme

       In the same way that the Glib module uses explicit one-to-one GType to package
       registrations, it is most foolproof to use an explicit, even exhaustive XS typemap.  In
       this way we avoid problems such as finding the proper set of regexes to map $var to the
       type macro and all sort of other problems of extensibility.  This of course means it must
       be autogenerated, but that's easy (and is described in the next section).

       The other main feature of the typemap is that it masks in a very sensible way the
       differences between GObject and GtkObject, and makes it very easy to specify whether a
       wrapper owns the object it wraps.  This is handled through the idea of a "variant", which
       is a term I made up just now because it sounds about right.

       Basically, a variant is the name of the class with some suffix.  For example, for the a
       GBoxed subclass such as GdkEvent, a header would do this:

        typedef GdkEvent GdkEvent_ornull;
        typedef GdkEvent GdkEvent_own;

        #define SvGdkEvent(s)           (gperl_get_boxed_check ((s), GDK_TYPE_EVENT))
        #define SvGdkEvent_ornull(s)    ((s)==&PL_sv_undef ? NULL : SvGdkEvent(s))

        #define newSVGdkEvent(e)        (gperl_new_boxed ((e), GDK_TYPE_EVENT, FALSE))
        #define newSVGdkEvent_own(e)    (gperl_new_boxed ((e), GDK_TYPE_EVENT, TRUE))
        #define newSVGdkEvent_ornull(e) (e == NULL ? &PL_sv_undef ? newSVGdkEvent (e))

       Then the typemap entries for its various variants would look like this:

        TYPEMAP
        GdkEvent *     T_GDK_TYPE_EVENT
        GdkEvent_ornull *      T_GDK_TYPE_EVENT_ORNULL
        GdkEvent_own * T_GDK_TYPE_EVENT_OWN

        INPUT
        T_GDK_TYPE_EVENT
               $var = SvGdkEvent ($arg);
        T_GDK_TYPE_EVENT_ORNULL
               $var = SvGdkEvent_ornull ($arg);

        OUTPUT
        T_GDK_TYPE_EVENT
               $arg = newSVGdkEvent ($var);
        T_GDK_TYPE_EVENT_ORNULL
               $arg = newSVGdkEvent_ornull ($var);
        T_GDK_TYPE_EVENT_OWN
               $arg = newSVGdkEvent_own ($var);

       And with that, your XS wrapper code can look as simple as this:

        GdkEvent_own *
        gdk_get_event (class)
                SV * class
            C_ARGS:
                /*void*/

        guint
        gdk_event_get_time (event)
                GdkEvent * event

       Isn't that nice and simple?

       We have different variants for different types, and some are applicable only to input or
       output.  The ones used by gtk2-perl generally follow the convention outlined in this
       table:

         Variant      I O  Description
         ------------ - -  -------------------------------------------
         GBoxed
         /* no ext */ * *  object will not be destroyed with wrapper
         _own           *  object will be destroyed with wrapper
         _copy          *  object will be copied (and copy will be owned)
         _ornull      * *  undef/NULL is legal
         _own_ornull    *  if object not NULL, wrapper will own object

         GObject
         /* no ext */ * *  object's refcount will be increased (=>not owned)
         _noinc         *  object's refcount will not be increased (=>owned)
         _ornull      * *  undef/NULL is legal

         GtkObject
         /* no ext */ * *  everything is peachy
         _ornull      * *  undef/NULL is legal

Autogeneration

       The typemap scheme described above is great, but involves creating a lot of typedefs and
       macros.  For a large library like Gtk, with over three hundred types to bind, you'd have
       to be crazy to write all of those by hand.

       Gtk2 handles this by using a code generation module to write the code for us as part of
       the Makefile.PL configuration step.  See Gtk2::CodeGen for details on how to use the
       generators.  Here I'll describe what gets generated and why.

   maps
       This is the starting point for autogeneration, the input for the code generator.  This map
       lists the TYPE macro for each of the GObject types in all of the gtk headers (including
       gdk, gdk-pixbuf, atk, and pango), along with the actual name of the class, name of the
       package into which it is to be blessed, and the base type (not exactly the fundamental
       type).  Most of those should be obvious except for the base type.  The base type is one of
       GEnum, GFlags, GBoxed, GObject, GInterface, or GtkObject.  This is the important flag
       which determines what kind of code gets created for each record; GObjects must be handled
       by completely different code than GBoxed objects, for instance.  As noted elsewhere, the
       distinction between GObject and GtkObject is not strictly necessary, but is kept for
       historical and aesthetic reasons.

       In this file, you can change the explicit name of an object.  If you don't like
       PangoFontDescription being Gtk2::Pango::FontDescription, you can change it to
       Gtk2::Pango::Font::Desc::ription if you were so inclined (but please don't).

       If you wish to use Gtk2's autogeneration tools in your own project, you'll need to create
       a maps file.  This can be done by hand, but that's tedious and error-prone; I used a
       script (called genmaps.pl in CVS) that actually scans the gtk header files and creates and
       runs a small program to generate the maps file.  The advantage here is that the type
       information comes directly from the code and I don't have to worry about clerical errors
       making the software incorrect.  In practice, this should need to be run only when new
       classes are added to the base libraries.

   gtk2perl-autogen.h
       This file contains the generated typedefs and cast macros.  This includes all the variant
       stuff described above.

   gtk2perl.typemap
       The exhaustive typemap uses the macros defined in gtk2perl-autogen.h so that you are
       assured to get the same results from typemap generated code as from hand-written perl
       stack manipulation.

   register.xsh
       Included from the BOOT section of the toplevel Gtk2 module (xs/Gtk2.xs), this file lists
       all of the types in the maps file as a series of calls to the appropriate package
       registration functions (gperl_register_boxed, gperl_register_object, or
       gperl_register_fundamental).  This is done before the boot code below so that hand-written
       code may override it.  This code gets executed when your perl script does a "use Gtk2".

   boot.xsh
       The Gtk2 module is made up of dozens of XS files but only one PM file.  Gtk2.pm calls
       bootstrap on Gtk2, but not on any of the others (because it doesn't know about them).  It
       is a module's boot code which binds the xsubs into perl, so it's imperative that the
       modules get booted!

       So, "Gtk2::CodeGen->write_boot" (called from Makefile.PL) scans the xs/ subdirectory for
       all the "MODULE = ..." lines in the XS files.  It maps these to boot code symbols, and
       generates code to call these symbols in boot.xsh, which is then included by the BOOT:
       section for the toplevel module, right after register.xsh.  (The generation code takes
       steps to avoid spitting out the same symbol more than once, and will not emit code to boot
       the toplevel module (or else you get an infinite loop).)

       Just a point of style; you can change packages in an XS file by repeating the MODULE = ...
       line with a different PACKAGE (and possibly PREFIX) value.  It's a good idea, however, to
       keep the MODULE the same, so that only one boot symbol gets generated per file.

SEE ALSO

       perl(1), perlxs(1), Gtk2(3pm), Glib(3pm), Glib::devel(3pm), Glib::xsapi(3pm),
       Gtk2::CodeGen(3pm)

AUTHOR

       muppet <scott at asofyet dot org>

COPYRIGHT

       Copyright (C) 2003 by the gtk2-perl team (see the file AUTHORS for the full list)

       This library is free software; you can redistribute it and/or modify it under the terms of
       the GNU Library General Public License as published by the Free Software Foundation;
       either version 2.1 of the License, or (at your option) any later version.

       This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
       without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
       See the GNU Library General Public License for more details.

       You should have received a copy of the GNU Library General Public License along with this
       library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
       Boston, MA  02111-1307  USA.