/usr/share/perl5/Gtk2/devel.pod is in libgtk2-perl-doc 2:1.24992-1build1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 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 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 | =head1 NAME
Gtk2::devel - The internal workings of the gtk2-perl language bindings
=head1 DESCRIPTION
This document is a supplement to L<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.
=head1 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.
=head1 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
=head1 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 L<Gtk2::CodeGen> for details
on how to use the generators. Here I'll describe what gets generated and why.
=head2 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.
=head2 gtk2perl-autogen.h
This file contains the generated typedefs and cast macros. This includes all
the variant stuff described above.
=head2 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.
=head2 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".
=head2 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, C<< 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.
=head1 SEE ALSO
perl(1), perlxs(1), Gtk2(3pm), Glib(3pm), Glib::devel(3pm),
Glib::xsapi(3pm), Gtk2::CodeGen(3pm)
=head1 AUTHOR
muppet E<lt>scott at asofyet dot orgE<gt>
=head1 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.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
=cut
|