merged in docs form the gobject tutorial

This commit is contained in:
Stefan Kost
2005-04-22 10:27:37 +00:00
parent e8ae00303b
commit 9ce3590d4e
9 changed files with 377 additions and 321 deletions

View File

@@ -1,3 +1,15 @@
2005-04-22 Stefan Kost <ensonic@users.sf.net>
* gobject/Makefile.am:
* gobject/gobject-docs.sgml:
* gobject/tut_gobject.xml:
* gobject/tut_gsignal.xml:
* gobject/tut_gtype.xml:
* gobject/tut_howto.xml:
* gobject/tut_intro.xml:
* gobject/tut_tools.xml:
merged in docs form the gobject tutorial
2005-03-29 Matthias Clasen <mclasen@redhat.com> 2005-03-29 Matthias Clasen <mclasen@redhat.com>
* glib/tmpl/arrays_pointer.sgml: Clarify the docs for * glib/tmpl/arrays_pointer.sgml: Clarify the docs for

View File

@@ -34,14 +34,21 @@ GTKDOC_LIBS = \
# Extra options to supply to gtkdoc-mkdb # Extra options to supply to gtkdoc-mkdb
MKDB_OPTIONS= MKDB_OPTIONS=
# Images to copy into HTML directory
HTML_IMAGES =
# Extra SGML files that are included by $(DOC_MAIN_SGML_FILE) # Extra SGML files that are included by $(DOC_MAIN_SGML_FILE)
content_files = version.xml \ content_files = version.xml \
glib-mkenums.xml \ glib-mkenums.xml \
glib-genmarshal.xml \ glib-genmarshal.xml \
gobject-query.xml gobject-query.xml \
tut_gobject.xml \
tut_gsignal.xml \
tut_gtype.xml \
tut_howto.xml \
tut_intro.xml \
tut_tools.xml
# Images to copy into HTML directory
HTML_IMAGES = \
$(srcdir)/images/glue.png
# Extra options to supply to gtkdoc-fixref # Extra options to supply to gtkdoc-fixref
FIXXREF_OPTIONS=--extra-dir=$(srcdir)/../glib/html FIXXREF_OPTIONS=--extra-dir=$(srcdir)/../glib/html

View File

@@ -18,6 +18,14 @@
<!ENTITY glib-genmarshal SYSTEM "glib-genmarshal.xml"> <!ENTITY glib-genmarshal SYSTEM "glib-genmarshal.xml">
<!ENTITY gobject-query SYSTEM "gobject-query.xml"> <!ENTITY gobject-query SYSTEM "gobject-query.xml">
<!ENTITY version SYSTEM "version.xml"> <!ENTITY version SYSTEM "version.xml">
<!ENTITY tutorial-Intro SYSTEM "tut_intro.xml">
<!ENTITY tutorial-GType SYSTEM "tut_gtype.xml">
<!ENTITY tutorial-GObject SYSTEM "tut_gobject.xml">
<!ENTITY tutorial-GSignal SYSTEM "tut_gsignal.xml">
<!ENTITY tutorial-HowTo SYSTEM "tut_howto.xml">
<!ENTITY tutorial-Tools SYSTEM "tut_tools.xml">
]> ]>
<book id="index"> <book id="index">
<bookinfo> <bookinfo>
@@ -28,48 +36,56 @@
<preface> <preface>
<title>Introduction</title> <title>Introduction</title>
<para> <para>
Most modern programming languages come with their own native object Most modern programming languages come with their own native object
systems and additional fundamental algorithmic language constructs. systems and additional fundamental algorithmic language constructs.
Just as GLib serves as an implementation of such fundamental Just as GLib serves as an implementation of such fundamental
types and algorithms (linked lists, hash tables and so forth), the types and algorithms (linked lists, hash tables and so forth), the
GLib Object System provides the required implementations of a GLib Object System provides the required implementations of a
flexible extensible and intentionally easy to map (into other flexible extensible and intentionally easy to map (into other
languages) object oriented framework for C. languages) object oriented framework for C.
The substantial elements that are provided can be summarized as: The substantial elements that are provided can be summarized as:
<variablelist> <itemizedlist>
<varlistentry><term></term><listitem><para> <listitem><para>
* A generic type system to register arbitrary single-inherited A generic type system to register arbitrary single-inherited
flat and deep derived types as well as interfaces for flat and deep derived types as well as interfaces for
structured types. structured types.
It takes care of creation, initialization and memory management It takes care of creation, initialization and memory management
of the assorted object and class structures, maintains of the assorted object and class structures, maintains
parent/child relationships and deals with dynamic implementations parent/child relationships and deals with dynamic implementations
of such types. That is, their type specific implementations are of such types. That is, their type specific implementations are
relocatable/unloadable during runtime. relocatable/unloadable during runtime.
</para></listitem></varlistentry> </para></listitem>
<varlistentry><term></term><listitem><para> <listitem><para>
* A collection of fundamental type implementations, such as integers, A collection of fundamental type implementations, such as integers,
doubles, enums and structured types, to name a few. doubles, enums and structured types, to name a few.
</para></listitem></varlistentry> </para></listitem>
<varlistentry><term></term><listitem><para> <listitem><para>
* A sample fundamental type implementation to base object hierarchies A sample fundamental type implementation to base object hierarchies
upon - the GObject fundamental type. upon - the GObject fundamental type.
</para></listitem></varlistentry> </para></listitem>
<varlistentry><term></term><listitem><para> <listitem><para>
* A signal system that allows very flexible user customization of A signal system that allows very flexible user customization of
virtual/overridable object methods and can serve as a powerful virtual/overridable object methods and can serve as a powerful
notification mechanism. notification mechanism.
</para></listitem></varlistentry> </para></listitem>
<varlistentry><term></term><listitem><para> <listitem><para>
* An extensible parameter/value system, supporting all the provided An extensible parameter/value system, supporting all the provided
fundamental types that can be used to generically handle object fundamental types that can be used to generically handle object
properties or otherwise parameterized types. properties or otherwise parameterized types.
</para></listitem></varlistentry> </para></listitem>
</variablelist> </itemizedlist>
</para> </para>
</preface> </preface>
<reference> <part label="I">
<title>Concepts</title>
&tutorial-Intro;
&tutorial-GType;
&tutorial-GObject;
&tutorial-GSignal;
</part>
<reference label="II">
<title>API Reference</title> <title>API Reference</title>
&gobject-GType; &gobject-GType;
@@ -87,13 +103,23 @@
&gobject-Value-Arrays; &gobject-Value-Arrays;
</reference> </reference>
<reference> <reference label="III">
<title>Tools Reference</title> <title>Tools Reference</title>
&glib-mkenums; &glib-mkenums;
&glib-genmarshal; &glib-genmarshal;
&gobject-query; &gobject-query;
</reference> </reference>
<part label="IV">
<title>Tutorial</title>
&tutorial-HowTo;
</part>
<part label="V">
<title>Related Tools</title>
&tutorial-Tools;
</part>
<index> <index>
<title>Index</title> <title>Index</title>

View File

@@ -1,16 +1,16 @@
<?xml version='1.0' encoding="ISO-8859-1"?> <?xml version='1.0' encoding="ISO-8859-1"?>
<chapter id="chapter-gobject"> <chapter id="chapter-gobject">
<title>GObject: what brings everything together.</title> <title>The GObject base class</title>
<para> <para>
The two previous chapters discussed the details of Glib's Dynamic Type System The two previous chapters discussed the details of Glib's Dynamic Type System
and its signal control system. The GObject library also contains an implementation and its signal control system. The GObject library also contains an implementation
for a base fundamental type named <type>GObject</type>. for a base fundamental type named <type><link linkend="GObject">GObject</link></type>.
</para> </para>
<para> <para>
<type>GObject</type> is a fundamental classed instantiable type. It implements: <type><link linkend="GObject">GObject</link></type> is a fundamental classed instantiable type. It implements:
<itemizedlist> <itemizedlist>
<listitem><para>Memory management with reference counting</para></listitem> <listitem><para>Memory management with reference counting</para></listitem>
<listitem><para>Construction/Destruction of instances</para></listitem> <listitem><para>Construction/Destruction of instances</para></listitem>
@@ -18,7 +18,7 @@
<listitem><para>Easy use of signals</para></listitem> <listitem><para>Easy use of signals</para></listitem>
</itemizedlist> </itemizedlist>
All the GTK+ objects and all of the objects in Gnome libraries which use the glib type All the GTK+ objects and all of the objects in Gnome libraries which use the glib type
system inherit from <type>GObject</type> which is why it is important to understand system inherit from <type><link linkend="GObject">GObject</link></type> which is why it is important to understand
the details of how it works. the details of how it works.
</para> </para>
@@ -26,13 +26,13 @@
<title>Object instanciation</title> <title>Object instanciation</title>
<para> <para>
The <function>g_object_new</function> family of functions can be used to instantiate any The <function><link linkend="g-object-new">g_object_new</link></function> family of functions can be used to instantiate any
GType which inherits from the GObject base type. All these functions make sure the class GType which inherits from the GObject base type. All these functions make sure the class
and instance structures have been correctly initialized by glib's type system and and instance structures have been correctly initialized by glib's type system and
then invoke at one point or another the constructor class method which is used to: then invoke at one point or another the constructor class method which is used to:
<itemizedlist> <itemizedlist>
<listitem><para> <listitem><para>
Allocate and clear memory through <function>g_type_create_instance</function>, Allocate and clear memory through <function><link linkend="g-type-create-instance">g_type_create_instance</link></function>,
</para></listitem> </para></listitem>
<listitem><para> <listitem><para>
Initialize the object' instance with the construction properties. Initialize the object' instance with the construction properties.
@@ -155,7 +155,7 @@ MamanBar *bar = g_object_new (MAMAN_TYPE_BAR, NULL);
</para> </para>
<para> <para>
Once <function>g_object_new</function> has obtained a reference to an initialized Once <function><link linkend="g-object-new">g_object_new</link></function> has obtained a reference to an initialized
class structure, it invokes its constructor method to create an instance of the new class structure, it invokes its constructor method to create an instance of the new
object. Since it has just been overridden by <function>maman_bar_class_init</function> object. Since it has just been overridden by <function>maman_bar_class_init</function>
to <function>maman_bar_constructor</function>, the latter is called and, because it to <function>maman_bar_constructor</function>, the latter is called and, because it
@@ -164,34 +164,34 @@ MamanBar *bar = g_object_new (MAMAN_TYPE_BAR, NULL);
to save the original constructor in a static variable from <function>maman_bar_class_init</function> to save the original constructor in a static variable from <function>maman_bar_class_init</function>
and then to re-use it from <function>maman_bar_constructor</function>. This is clearly possible and then to re-use it from <function>maman_bar_constructor</function>. This is clearly possible
and very simple but I was told it was not nice and the prefered way is to use the and very simple but I was told it was not nice and the prefered way is to use the
<function>g_type_class_peek</function> and <function>g_type_class_peek_parent</function> functions. <function><link linkend="g-type-class-peek">g_type_class_peek</link></function> and <function><link linkend="g-type-class-peek-parent">g_type_class_peek_parent</link></function> functions.
</para> </para>
<para> <para>
Finally, at one point or another, <function>g_object_constructor</function> is invoked Finally, at one point or another, <function>g_object_constructor</function> is invoked
by the last constructor in the chain. This function allocates the object's instance' buffer by the last constructor in the chain. This function allocates the object's instance' buffer
through <function>g_type_create_instance</function> through <function><link linkend="g-type-create-instance">g_type_create_instance</link></function>
which means that the instance_init function is invoked at this point if one which means that the instance_init function is invoked at this point if one
was registered. After instance_init returns, the object is fully initialized and should be was registered. After instance_init returns, the object is fully initialized and should be
ready to answer any user-request. When <function>g_type_create_instance</function> ready to answer any user-request. When <function><link linkend="g-type-create-instance">g_type_create_instance</link></function>
returns, <function>g_object_constructor</function> sets the construction properties returns, <function>g_object_constructor</function> sets the construction properties
(ie: the properties which were given to <function>g_object_new</function>) and returns (ie: the properties which were given to <function><link linkend="g-object-new">g_object_new</link></function>) and returns
to the user's constructor which is then allowed to do useful instance initialization... to the user's constructor which is then allowed to do useful instance initialization...
</para> </para>
<para> <para>
The process described above might seem a bit complicated (it <emphasis>is</emphasis> actually The process described above might seem a bit complicated (it <emphasis>is</emphasis> actually
overly complicated in my opinion..) but it can be summarized easily by the table below which overly complicated in my opinion..) but it can be summarized easily by the table below which
lists the functions invoked by <function>g_object_new</function> and their order of lists the functions invoked by <function><link linkend="g-object-new">g_object_new</link></function> and their order of
invocation. invocation.
</para> </para>
<para> <para>
The array below lists the functions invoked by <function>g_object_new</function> and The array below lists the functions invoked by <function><link linkend="g-object-new">g_object_new</link></function> and
their order of invocation: their order of invocation:
<table id="gobject-construction-table"> <table id="gobject-construction-table">
<title><function>g_object_new</function></title> <title><function><link linkend="g-object-new">g_object_new</link></function></title>
<tgroup cols="3"> <tgroup cols="3">
<colspec colwidth="*" colnum="1" align="left"/> <colspec colwidth="*" colnum="1" align="left"/>
<colspec colwidth="*" colnum="2" align="left"/> <colspec colwidth="*" colnum="2" align="left"/>
@@ -207,7 +207,7 @@ MamanBar *bar = g_object_new (MAMAN_TYPE_BAR, NULL);
</thead> </thead>
<tbody> <tbody>
<row> <row>
<entry>First call to <function>g_object_new</function> for target type</entry> <entry>First call to <function><link linkend="g-object-new">g_object_new</link></function> for target type</entry>
<entry>target type's base_init function</entry> <entry>target type's base_init function</entry>
<entry>On the inheritance tree of classes from fundamental type to target type. <entry>On the inheritance tree of classes from fundamental type to target type.
base_init is invoked once for each class structure.</entry> base_init is invoked once for each class structure.</entry>
@@ -217,7 +217,7 @@ MamanBar *bar = g_object_new (MAMAN_TYPE_BAR, NULL);
</entry> </entry>
</row> </row>
<row> <row>
<entry>First call to <function>g_object_new</function> for target type</entry> <entry>First call to <function><link linkend="g-object-new">g_object_new</link></function> for target type</entry>
<entry>target type's class_init function</entry> <entry>target type's class_init function</entry>
<entry>On target type's class structure</entry> <entry>On target type's class structure</entry>
<entry> <entry>
@@ -227,19 +227,19 @@ MamanBar *bar = g_object_new (MAMAN_TYPE_BAR, NULL);
</entry> </entry>
</row> </row>
<row> <row>
<entry>First call to <function>g_object_new</function> for target type</entry> <entry>First call to <function><link linkend="g-object-new">g_object_new</link></function> for target type</entry>
<entry>interface' base_init function</entry> <entry>interface' base_init function</entry>
<entry>On interface' vtable</entry> <entry>On interface' vtable</entry>
<entry></entry> <entry></entry>
</row> </row>
<row> <row>
<entry>First call to <function>g_object_new</function> for target type</entry> <entry>First call to <function><link linkend="g-object-new">g_object_new</link></function> for target type</entry>
<entry>interface' interface_init function</entry> <entry>interface' interface_init function</entry>
<entry>On interface' vtable</entry> <entry>On interface' vtable</entry>
<entry></entry> <entry></entry>
</row> </row>
<row> <row>
<entry>Each call to <function>g_object_new</function> for target type</entry> <entry>Each call to <function><link linkend="g-object-new">g_object_new</link></function> for target type</entry>
<entry>target type's class constructor method: GObjectClass->constructor</entry> <entry>target type's class constructor method: GObjectClass->constructor</entry>
<entry>On object's instance</entry> <entry>On object's instance</entry>
<entry> <entry>
@@ -250,7 +250,7 @@ MamanBar *bar = g_object_new (MAMAN_TYPE_BAR, NULL);
</entry> </entry>
</row> </row>
<row> <row>
<entry>Each call to <function>g_object_new</function> for target type</entry> <entry>Each call to <function><link linkend="g-object-new">g_object_new</link></function> for target type</entry>
<entry>type's instance_init function</entry> <entry>type's instance_init function</entry>
<entry>On the inheritance tree of classes from fundamental type to target type. <entry>On the inheritance tree of classes from fundamental type to target type.
the instance_init provided for each type is invoked once for each instance the instance_init provided for each type is invoked once for each instance
@@ -270,7 +270,7 @@ MamanBar *bar = g_object_new (MAMAN_TYPE_BAR, NULL);
Readers should feel concerned about one little twist in the order in which functions Readers should feel concerned about one little twist in the order in which functions
are invoked: while, technically, the class' constructor method is called are invoked: while, technically, the class' constructor method is called
<emphasis>before</emphasis> the GType's instance_init function (since <emphasis>before</emphasis> the GType's instance_init function (since
<function>g_type_create_instance</function> which calls instance_init is called by <function><link linkend="g-type-create-instance">g_type_create_instance</link></function> which calls instance_init is called by
<function>g_object_constructor</function> which is the top-level class <function>g_object_constructor</function> which is the top-level class
constructor method and to which users are expected to chain to), the user's code constructor method and to which users are expected to chain to), the user's code
which runs in a user-provided constructor will always run <emphasis>after</emphasis> which runs in a user-provided constructor will always run <emphasis>after</emphasis>
@@ -322,19 +322,19 @@ void g_object_run_dispose (GObject *object);
<title>Reference count</title> <title>Reference count</title>
<para> <para>
The functions <function>g_object_ref</function>/<function>g_object_unref</function> respectively The functions <function><link linkend="g-object-ref">g_object_ref</link></function>/<function><link linkend="g-object-unref">g_object_unref</link></function> respectively
increase and decrease the reference count. None of these function is thread-safe. increase and decrease the reference count. None of these function is thread-safe.
The reference count is, unsurprisingly, initialized to one by The reference count is, unsurprisingly, initialized to one by
<function>g_object_new</function> which means that the caller <function><link linkend="g-object-new">g_object_new</link></function> which means that the caller
is currenly the sole owner of the newly-created reference. is currenly the sole owner of the newly-created reference.
When the reference count reaches zero, that is, When the reference count reaches zero, that is,
when <function>g_object_unref</function> is called by the last client holding when <function><link linkend="g-object-unref">g_object_unref</link></function> is called by the last client holding
a reference to the object, the <emphasis>dispose</emphasis> and the a reference to the object, the <emphasis>dispose</emphasis> and the
<emphasis>finalize</emphasis> class methods are invoked. <emphasis>finalize</emphasis> class methods are invoked.
</para> </para>
<para> <para>
Finally, after <emphasis>finalize</emphasis> is invoked, Finally, after <emphasis>finalize</emphasis> is invoked,
<function>g_type_free_instance</function> is called to free the object instance. <function><link linkend="g-type-free-instance">g_type_free_instance</link></function> is called to free the object instance.
Depending on the memory allocation policy decided when the type was registered (through Depending on the memory allocation policy decided when the type was registered (through
one of the <function>g_type_register_*</function> functions), the object's instance one of the <function>g_type_register_*</function> functions), the object's instance
memory will be freed or returned to the object pool for this type. memory will be freed or returned to the object pool for this type.
@@ -346,7 +346,7 @@ void g_object_run_dispose (GObject *object);
<para> <para>
The table below summarizes the destruction process of a GObject: The table below summarizes the destruction process of a GObject:
<table id="gobject-destruction-table"> <table id="gobject-destruction-table">
<title><function>g_object_unref</function></title> <title><function><link linkend="g-object-unref">g_object_unref</link></function></title>
<tgroup cols="3"> <tgroup cols="3">
<colspec colwidth="*" colnum="1" align="left"/> <colspec colwidth="*" colnum="1" align="left"/>
<colspec colwidth="*" colnum="2" align="left"/> <colspec colwidth="*" colnum="2" align="left"/>
@@ -362,7 +362,7 @@ void g_object_run_dispose (GObject *object);
</thead> </thead>
<tbody> <tbody>
<row> <row>
<entry>Last call to <function>g_object_unref</function> for an instance <entry>Last call to <function><link linkend="g-object-unref">g_object_unref</link></function> for an instance
of target type</entry> of target type</entry>
<entry>target type's dispose class function</entry> <entry>target type's dispose class function</entry>
<entry>GObject instance</entry> <entry>GObject instance</entry>
@@ -376,7 +376,7 @@ void g_object_run_dispose (GObject *object);
</entry> </entry>
</row> </row>
<row> <row>
<entry>Last call to <function>g_object_unref</function> for an instance <entry>Last call to <function><link linkend="g-object-unref">g_object_unref</link></function> for an instance
of target type of target type
</entry> </entry>
<entry>target type's finalize class function</entry> <entry>target type's finalize class function</entry>
@@ -392,28 +392,28 @@ void g_object_run_dispose (GObject *object);
</entry> </entry>
</row> </row>
<row> <row>
<entry>Last call to <function>g_object_unref</function> for the last <entry>Last call to <function><link linkend="g-object-unref">g_object_unref</link></function> for the last
instance of target type</entry> instance of target type</entry>
<entry>interface' interface_finalize function</entry> <entry>interface' interface_finalize function</entry>
<entry>On interface' vtable</entry> <entry>On interface' vtable</entry>
<entry>Never used in practice. Unlikely you will need it.</entry> <entry>Never used in practice. Unlikely you will need it.</entry>
</row> </row>
<row> <row>
<entry>Last call to <function>g_object_unref</function>for the last <entry>Last call to <function><link linkend="g-object-unref">g_object_unref</link></function>for the last
instance of target type</entry> instance of target type</entry>
<entry>interface' base_finalize function</entry> <entry>interface' base_finalize function</entry>
<entry>On interface' vtable</entry> <entry>On interface' vtable</entry>
<entry>Never used in practice. Unlikely you will need it.</entry> <entry>Never used in practice. Unlikely you will need it.</entry>
</row> </row>
<row> <row>
<entry>Last call to <function>g_object_unref</function> for the last <entry>Last call to <function><link linkend="g-object-unref">g_object_unref</link></function> for the last
instance of target type</entry> instance of target type</entry>
<entry>target type's class_finalize function</entry> <entry>target type's class_finalize function</entry>
<entry>On target type's class structure</entry> <entry>On target type's class structure</entry>
<entry>Never used in practice. Unlikely you will need it.</entry> <entry>Never used in practice. Unlikely you will need it.</entry>
</row> </row>
<row> <row>
<entry>Last call to <function>g_object_unref</function> for the last <entry>Last call to <function><link linkend="g-object-unref">g_object_unref</link></function> for the last
instance of target type</entry> instance of target type</entry>
<entry>type's base_finalize function</entry> <entry>type's base_finalize function</entry>
<entry>On the inheritance tree of classes from fundamental type to target type. <entry>On the inheritance tree of classes from fundamental type to target type.
@@ -432,7 +432,7 @@ void g_object_run_dispose (GObject *object);
<para> <para>
Weak References are used to monitor object finalization: Weak References are used to monitor object finalization:
<function>g_object_weak_ref</function> adds a monitoring callback which does <function><link linkend="g-object-weak-ref">g_object_weak_ref</link></function> adds a monitoring callback which does
not hold a reference to the object but which is invoked when the object runs not hold a reference to the object but which is invoked when the object runs
its dispose method. As such, each weak ref can be invoked more than once upon its dispose method. As such, each weak ref can be invoked more than once upon
object finalization (since dispose can run more than once during object object finalization (since dispose can run more than once during object
@@ -440,13 +440,13 @@ void g_object_run_dispose (GObject *object);
</para> </para>
<para> <para>
<function>g_object_weak_unref</function> can be used to remove a monitoring <function><link linkend="g-object-weak-unref">g_object_weak_unref</link></function> can be used to remove a monitoring
callback from the object. callback from the object.
</para> </para>
<para> <para>
Weak References are also used to implement <function>g_object_add_weak_pointer</function> Weak References are also used to implement <function><link linkend="g-object-add-weak-pointer">g_object_add_weak_pointer</link></function>
and <function>g_object_remove_weak_pointer</function>. These functions add a weak reference and <function><link linkend="g-object-remove-weak-pointer">g_object_remove_weak_pointer</link></function>. These functions add a weak reference
to the object they are applied to which makes sure to nullify the pointer given by the user to the object they are applied to which makes sure to nullify the pointer given by the user
when object is finalized. when object is finalized.
</para> </para>
@@ -473,7 +473,7 @@ void g_object_run_dispose (GObject *object);
<para> <para>
This two-step destruction process is very useful to break reference counting cycles. This two-step destruction process is very useful to break reference counting cycles.
While the detection of the cycles is up to the external code, once the cycles have been While the detection of the cycles is up to the external code, once the cycles have been
detected, the external code can invoke <function>g_object_dispose</function> which detected, the external code can invoke <function><link linkend="g-object-dispose">g_object_dispose</link></function> which
will indeed break any existing cycles since it will run the dispose handler associated will indeed break any existing cycles since it will run the dispose handler associated
to the object and thus release all references to other objects. to the object and thus release all references to other objects.
</para> </para>
@@ -483,7 +483,7 @@ void g_object_run_dispose (GObject *object);
we stated a bit sooner: the dispose handler can be invoked multiple times. Let's say we we stated a bit sooner: the dispose handler can be invoked multiple times. Let's say we
have a reference count cycle: object A references B which itself references object A. have a reference count cycle: object A references B which itself references object A.
Let's say we have detected the cycle and we want to destroy the two objects. One way to Let's say we have detected the cycle and we want to destroy the two objects. One way to
do this would be to invoke <function>g_object_dispose</function> on one of the do this would be to invoke <function><link linkend="g-object-dispose">g_object_dispose</link></function> on one of the
objects. objects.
</para> </para>
@@ -512,7 +512,7 @@ void g_object_run_dispose (GObject *object);
One of GObject's nice features is its generic get/set mechanism for object One of GObject's nice features is its generic get/set mechanism for object
properties. When an object properties. When an object
is instanciated, the object's class_init handler should be used to register is instanciated, the object's class_init handler should be used to register
the object's properties with <function>g_object_class_install_property</function> the object's properties with <function><link linkend="g-object-class-install-property">g_object_class_install_property</link></function>
(implemented in <filename>gobject.c</filename>). (implemented in <filename>gobject.c</filename>).
</para> </para>
@@ -635,9 +635,9 @@ g_object_set_property (G_OBJECT (bar), "papa-number", &amp;val);
</para> </para>
<para> <para>
<function>g_object_set_property</function> first ensures a property <function><link linkend="g-object-set-property">g_object_set_property</link></function> first ensures a property
with this name was registered in bar's class_init handler. If so, it calls with this name was registered in bar's class_init handler. If so, it calls
<function>object_set_property</function> which first walks the class hierarchy, <function><link linkend="object-set-property">object_set_property</link></function> which first walks the class hierarchy,
from bottom, most derived type, to top, fundamental type to find the class from bottom, most derived type, to top, fundamental type to find the class
which registered that property. It then tries to convert the user-provided GValue which registered that property. It then tries to convert the user-provided GValue
into a GValue whose type if that of the associated property. into a GValue whose type if that of the associated property.
@@ -646,7 +646,7 @@ g_object_set_property (G_OBJECT (bar), "papa-number", &amp;val);
<para> <para>
If the user provides a signed char GValue, as is shown If the user provides a signed char GValue, as is shown
here, and if the object's property was registered as an unsigned int, here, and if the object's property was registered as an unsigned int,
<function>g_value_transform</function> will try to transform the input signed char into <function><link linkend="g-value-transform">g_value_transform</link></function> will try to transform the input signed char into
an unsigned int. Of course, the success of the transformation depends on the availability an unsigned int. Of course, the success of the transformation depends on the availability
of the required transform function. In practice, there will almost always be a transformation of the required transform function. In practice, there will almost always be a transformation
<footnote> <footnote>
@@ -658,46 +658,46 @@ g_object_set_property (G_OBJECT (bar), "papa-number", &amp;val);
</para> </para>
<para> <para>
After transformation, the <type>GValue</type> is validated by After transformation, the <type><link linkend="GValue">GValue</link></type> is validated by
<function>g_param_value_validate</function> which makes sure the user's <function><link linkend="g-param-value-validate">g_param_value_validate</link></function> which makes sure the user's
data stored in the <type>GValue</type> matches the characteristics specified by data stored in the <type><link linkend="GValue">GValue</link></type> matches the characteristics specified by
the property's <type>GParamSpec</type>. Here, the <type>GParamSpec</type> we the property's <type><link linkend="GParamSpec">GParamSpec</link></type>. Here, the <type><link linkend="GParamSpec">GParamSpec</link></type> we
provided in class_init has a validation function which makes sure that the GValue provided in class_init has a validation function which makes sure that the GValue
contains a value which respects the minimum and maximum bounds of the contains a value which respects the minimum and maximum bounds of the
<type>GParamSpec</type>. In the example above, the client's GValue does not <type><link linkend="GParamSpec">GParamSpec</link></type>. In the example above, the client's GValue does not
respect these constraints (it is set to 11, while the maximum is 10). As such, the respect these constraints (it is set to 11, while the maximum is 10). As such, the
<function>g_object_set_property</function> function will return with an error. <function><link linkend="g-object-set-property">g_object_set_property</link></function> function will return with an error.
</para> </para>
<para> <para>
If the user's GValue had been set to a valid value, <function>object_set_property</function> If the user's GValue had been set to a valid value, <function><link linkend="g-object-set-property">g_object_set_property</link></function>
would have proceeded with calling the object's set_property class method. Here, since our would have proceeded with calling the object's set_property class method. Here, since our
implementation of Foo did override this method, the code path would jump to implementation of Foo did override this method, the code path would jump to
<function>foo_set_property</function> after having retrieved from the <function>foo_set_property</function> after having retrieved from the
<type>GParamSpec</type> the <emphasis>param_id</emphasis> <type><link linkend="GParamSpec">GParamSpec</link></type> the <emphasis>param_id</emphasis>
<footnote> <footnote>
<para> <para>
It should be noted that the param_id used here need only to uniquely identify each It should be noted that the param_id used here need only to uniquely identify each
<type>GParamSpec</type> within the <type>FooClass</type> such that the switch <type><link linkend="GParamSpec">GParamSpec</link></type> within the <type><link linkend="FooClass">FooClass</link></type> such that the switch
used in the set and get methods actually works. Of course, this locally-unique used in the set and get methods actually works. Of course, this locally-unique
integer is purely an optimization: it would have been possible to use a set of integer is purely an optimization: it would have been possible to use a set of
<emphasis>if (strcmp (a, b) == 0) {} else if (strcmp (a, b) == 0) {}</emphasis> statements. <emphasis>if (strcmp (a, b) == 0) {} else if (strcmp (a, b) == 0) {}</emphasis> statements.
</para> </para>
</footnote> </footnote>
which had been stored by which had been stored by
<function>g_object_class_install_property</function>. <function><link linkend="g-object-class-install-property">g_object_class_install_property</link></function>.
</para> </para>
<para> <para>
Once the property has been set by the object's set_property class method, the code path Once the property has been set by the object's set_property class method, the code path
returns to <function>g_object_set_property</function> which calls returns to <function><link linkend="g-object-set-property">g_object_set_property</link></function> which calls
<function>g_object_notify_queue_thaw</function>. This function makes sure that <function><link linkend="g-object-notify-queue-thaw">g_object_notify_queue_thaw</link></function>. This function makes sure that
the "notify" signal is emitted on the object's instance with the changed property as the "notify" signal is emitted on the object's instance with the changed property as
parameter unless notifications were frozen by <function>g_object_freeze_notify</function>. parameter unless notifications were frozen by <function><link linkend="g-object-freeze-notify">g_object_freeze_notify</link></function>.
</para> </para>
<para> <para>
<function>g_object_thaw_notify</function> can be used to re-enable notification of <function><link linkend="g-object-thaw-notify">g_object_thaw_notify</link></function> can be used to re-enable notification of
property modifications through the "notify" signal. It is important to remember that property modifications through the "notify" signal. It is important to remember that
even if properties are changed while property change notification is frozen, the "notify" even if properties are changed while property change notification is frozen, the "notify"
signal will be emitted once for each of these changed properties as soon as the property signal will be emitted once for each of these changed properties as soon as the property
@@ -710,8 +710,8 @@ g_object_set_property (G_OBJECT (bar), "papa-number", &amp;val);
<para> <para>
It is interesting to note that the <function>g_object_set</function> and It is interesting to note that the <function><link linkend="g-object-set">g_object_set</link></function> and
<function>g_object_set_valist</function> (vararg version) functions can be used to set <function><link linkend="g-object-set-valist">g_object_set_valist</link></function> (vararg version) functions can be used to set
multiple properties at once. The client code shown above can then be re-written as: multiple properties at once. The client code shown above can then be re-written as:
<programlisting> <programlisting>
MamanBar *foo; MamanBar *foo;
@@ -725,16 +725,16 @@ g_object_set (G_OBJECT (foo),
</para> </para>
<para> <para>
Of course, the _get versions are also available: <function>g_object_get</function> Of course, the _get versions are also available: <function><link linkend="g-object-get">g_object_get</link></function>
and <function>g_object_get_valist</function> (vararg version) can be used to get numerous and <function><link linkend="g-object-get-valist">g_object_get_valist</link></function> (vararg version) can be used to get numerous
properties at once. properties at once.
</para> </para>
<para> <para>
Really attentive readers now understand how <function>g_object_new</function>, Really attentive readers now understand how <function><link linkend="g-object-new">g_object_new</link></function>,
<function>g_object_newv</function> and <function>g_object_new_valist</function> <function><link linkend="g-object-newv">g_object_newv</link></function> and <function><link linkend="g-object-new-valist">g_object_new_valist</link></function>
work: they parse the user-provided variable number of parameters and invoke work: they parse the user-provided variable number of parameters and invoke
<function>g_object_set</function> on each pair of parameters only after the object has been successfully constructed. <function><link linkend="g-object-set">g_object_set</link></function> on each pair of parameters only after the object has been successfully constructed.
Of course, the "notify" signal will be emitted for each property set. Of course, the "notify" signal will be emitted for each property set.
</para> </para>

View File

@@ -1,6 +1,6 @@
<?xml version='1.0' encoding="ISO-8859-1"?> <?xml version='1.0' encoding="ISO-8859-1"?>
<chapter id="chapter-signal"> <chapter id="chapter-signal">
<title>Signals</title> <title>The GObject messaging system</title>
<sect1 id="closure"> <sect1 id="closure">
<title>Closures</title> <title>Closures</title>
@@ -28,7 +28,7 @@ return_type function_callback (... , gpointer user_data);
</para> </para>
<para> <para>
The <type>GClosure</type> structure represents the common functionality of all The <type><link linkend="GClosure">GClosure</link></type> structure represents the common functionality of all
closure implementations: there exist a different Closure implementation for closure implementations: there exist a different Closure implementation for
each separate runtime which wants to use the GObject type system. each separate runtime which wants to use the GObject type system.
<footnote><para> <footnote><para>
@@ -39,27 +39,27 @@ return_type function_callback (... , gpointer user_data);
it behaves as a normal C object for GTK+ and as a normal Python object for it behaves as a normal C object for GTK+ and as a normal Python object for
python code. python code.
</para></footnote> </para></footnote>
The GObject library provides a simple <type>GCClosure</type> type which The GObject library provides a simple <type><link linkend="GCClosure">GCClosure</link></type> type which
is a specific implementation of closures to be used with C/C++ callbacks. is a specific implementation of closures to be used with C/C++ callbacks.
</para> </para>
<para> <para>
A <type>GClosure</type> provides simple services: A <type><link linkend="GClosure">GClosure</link></type> provides simple services:
<itemizedlist> <itemizedlist>
<listitem><para> <listitem><para>
Invocation (<function>g_closure_invoke</function>): this is what closures Invocation (<function><link linkend="g-closure-invoke">g_closure_invoke</link></function>): this is what closures
were created for: they hide the details of callback invocation from the were created for: they hide the details of callback invocation from the
callback invocator. callback invocator.
</para></listitem> </para></listitem>
<listitem><para> <listitem><para>
Notification: the closure notifies listeners of certain events such as Notification: the closure notifies listeners of certain events such as
closure invocation, closure invalidation and closure finalization. Listeners closure invocation, closure invalidation and closure finalization. Listeners
can be registered with <function>g_closure_add_finalize_notifier</function> can be registered with <function><link linkend="g-closure-add-finalize-notifier">g_closure_add_finalize_notifier</link></function>
(finalization notification), <function>g_closure_add_invalidate_notifier</function> (finalization notification), <function><link linkend="g-closure-add-invalidate-notifier">g_closure_add_invalidate_notifier</link></function>
(invalidation notification) and (invalidation notification) and
<function>g_closure_add_marshal_guards</function> (invocation notification). <function><link linkend="g-closure-add-marshal-guards">g_closure_add_marshal_guards</link></function> (invocation notification).
There exist symmetric de-registration functions for finalization and invalidation There exist symmetric de-registration functions for finalization and invalidation
events (<function>g_closure_remove_finalize_notifier</function> and events (<function><link linkend="g-closure-remove-finalize-notifier">g_closure_remove_finalize_notifier</link></function> and
<function>g_closure_remove_invalidate_notifier</function>) but not for the invocation <function><link linkend="g-closure-remove-invalidate-notifier">g_closure_remove_invalidate_notifier</link></function>) but not for the invocation
process. process.
<footnote><para> <footnote><para>
Closures are refcounted and notify listeners of their destruction in a two-stage Closures are refcounted and notify listeners of their destruction in a two-stage
@@ -74,8 +74,8 @@ return_type function_callback (... , gpointer user_data);
<para> <para>
If you are using C or C++ If you are using C or C++
to connect a callback to a given event, you will either use the simple <type>GCClosure</type>s to connect a callback to a given event, you will either use the simple <type><link linkend="GCClosure">GCClosure</link></type>s
which have a pretty minimal API or the even simpler <function>g_signal_connect</function> which have a pretty minimal API or the even simpler <function><link linkend="g-signal-connect">g_signal_connect</link></function>
functions (which will be presented a bit later :). functions (which will be presented a bit later :).
<programlisting> <programlisting>
GClosure* g_cclosure_new (GCallback callback_func, GClosure* g_cclosure_new (GCallback callback_func,
@@ -90,16 +90,16 @@ GClosure* g_signal_type_cclosure_new (GType itype,
</para> </para>
<para> <para>
<function>g_cclosure_new</function> will create a new closure which can invoke the <function><link linkend="g-cclosure-new">g_cclosure_new</link></function> will create a new closure which can invoke the
user-provided callback_func with the user-provided user_data as last parameter. When the closure user-provided callback_func with the user-provided user_data as last parameter. When the closure
is finalized (second stage of the destruction process), it will invoke the destroy_data function is finalized (second stage of the destruction process), it will invoke the destroy_data function
if the user has supplied one. if the user has supplied one.
</para> </para>
<para> <para>
<function>g_cclosure_new_swap</function> will create a new closure which can invoke the <function><link linkend="g-cclosure-new-swap">g_cclosure_new_swap</link></function> will create a new closure which can invoke the
user-provided callback_func with the user-provided user_data as first parameter (instead of being the user-provided callback_func with the user-provided user_data as first parameter (instead of being the
last parameter as with <function>g_cclosure_new</function>). When the closure last parameter as with <function><link linkend="g-cclosure-new">g_cclosure_new</link></function>). When the closure
is finalized (second stage of the destruction process), it will invoke the destroy_data is finalized (second stage of the destruction process), it will invoke the destroy_data
function if the user has supplied one. function if the user has supplied one.
</para> </para>
@@ -200,8 +200,8 @@ return_type function_callback (gpointer instance, ... , gpointer user_data);
<title>Signal registration</title> <title>Signal registration</title>
<para> <para>
To register a new signal on an existing type, we can use any of <function>g_signal_newv</function>, To register a new signal on an existing type, we can use any of <function><link linkend="g-signal-newv">g_signal_newv</link></function>,
<function>g_signal_new_valist</function> or <function>g_signal_new</function> functions: <function><link linkend="g-signal-new-valist">g_signal_new_valist</link></function> or <function><link linkend="g-signal-new">g_signal_new</link></function> functions:
<programlisting> <programlisting>
guint g_signal_newv (const gchar *signal_name, guint g_signal_newv (const gchar *signal_name,
GType itype, GType itype,
@@ -280,13 +280,13 @@ guint g_signal_newv (const gchar *signal_name,
of a given signal on all the instances of the type which supports that signal. of a given signal on all the instances of the type which supports that signal.
</para></listitem> </para></listitem>
<listitem><para> <listitem><para>
You can use <function>g_signal_override_class_closure</function> which You can use <function><link linkend="g-signal-override-class-closure">g_signal_override_class_closure</link></function> which
overrides the class_closure of a given type. It is possible to call this function overrides the class_closure of a given type. It is possible to call this function
only on a derived type of the type on which the signal was registered. only on a derived type of the type on which the signal was registered.
This function is of use only to language bindings. This function is of use only to language bindings.
</para></listitem> </para></listitem>
<listitem><para> <listitem><para>
You can register a closure with the <function>g_signal_connect</function> You can register a closure with the <function><link linkend="g-signal-connect">g_signal_connect</link></function>
family of functions. This is an instance-specific operation: the closure family of functions. This is an instance-specific operation: the closure
will be invoked only during emission of a given signal on a given instance. will be invoked only during emission of a given signal on a given instance.
</para></listitem> </para></listitem>
@@ -295,8 +295,8 @@ guint g_signal_newv (const gchar *signal_name,
emission hooks are invoked whenever a given signal is emitted whatever the instance on emission hooks are invoked whenever a given signal is emitted whatever the instance on
which it is emitted. Emission hooks are used for example to get all mouse_clicked which it is emitted. Emission hooks are used for example to get all mouse_clicked
emissions in an application to be able to emit the small mouse click sound. emissions in an application to be able to emit the small mouse click sound.
Emission hooks are connected with <function>g_signal_add_emission_hook</function> Emission hooks are connected with <function><link linkend="g-signal-add-emission-hook">g_signal_add_emission_hook</link></function>
and removed with <function>g_signal_remove_emission_hook</function>. and removed with <function><link linkend="g-signal-remove-emission-hook">g_signal_remove_emission_hook</link></function>.
</para> </para>
<para> <para>
@@ -308,7 +308,7 @@ guint g_signal_newv (const gchar *signal_name,
<title>Signal emission</title> <title>Signal emission</title>
<para> <para>
Signal emission is done through the use of the <function>g_signal_emit</function> family Signal emission is done through the use of the <function><link linkend="g-signal-emit">g_signal_emit</link></function> family
of functions. of functions.
<programlisting> <programlisting>
void g_signal_emitv (const GValue *instance_and_params, void g_signal_emitv (const GValue *instance_and_params,
@@ -369,8 +369,8 @@ void g_signal_emitv (const GValue *instance_and_pa
</para></listitem> </para></listitem>
<listitem><para> <listitem><para>
<emphasis>HANDLER_RUN_FIRST</emphasis>: if any closure were connected <emphasis>HANDLER_RUN_FIRST</emphasis>: if any closure were connected
with the <function>g_signal_connect</function> family of with the <function><link linkend="g-signal-connect">g_signal_connect</link></function> family of
functions, and if they are not blocked (with the <function>g_signal_handler_block</function> functions, and if they are not blocked (with the <function><link linkend="g-signal-handler-block">g_signal_handler_block</link></function>
family of functions) they are run here, from first to last connected. family of functions) they are run here, from first to last connected.
Jump to <emphasis>RUN_LAST</emphasis> state. Jump to <emphasis>RUN_LAST</emphasis> state.
</para></listitem> </para></listitem>
@@ -398,7 +398,7 @@ void g_signal_emitv (const GValue *instance_and_pa
<para> <para>
If, at any point during emission (except in RUN_CLEANUP state), one of the If, at any point during emission (except in RUN_CLEANUP state), one of the
closures or emission hook stops the signal emission with closures or emission hook stops the signal emission with
<function>g_signal_stop</function>, emission jumps to CLEANUP state. <function><link linkend="g-signal-stop">g_signal_stop</link></function>, emission jumps to CLEANUP state.
</para> </para>
<para> <para>
@@ -416,7 +416,7 @@ void g_signal_emitv (const GValue *instance_and_pa
<para> <para>
If no accumulator function was provided, the value returned by the last handler If no accumulator function was provided, the value returned by the last handler
run will be returned by <function>g_signal_emit</function>. run will be returned by <function><link linkend="g-signal-emit">g_signal_emit</link></function>.
</para> </para>
</sect2> </sect2>
@@ -432,11 +432,11 @@ void g_signal_emitv (const GValue *instance_and_pa
<para> <para>
Of the three main connection functions, Of the three main connection functions,
only one has an explicit detail parameter as a <type>GQuark</type> only one has an explicit detail parameter as a <type><link linkend="GQuark">GQuark</link></type>
<footnote> <footnote>
<para>A GQuark is an integer which uniquely represents a string. It is possible to transform <para>A GQuark is an integer which uniquely represents a string. It is possible to transform
back and forth between the integer and string representations with the functions back and forth between the integer and string representations with the functions
<function>g_quark_from_string</function> and <function>g_quark_to_string</function>. <function><link linkend="g-quark-from-string">g_quark_from_string</link></function> and <function><link linkend="g-quark-to-string">g_quark_to_string</link></function>.
</para> </para>
</footnote>: </footnote>:
<programlisting> <programlisting>
@@ -469,7 +469,7 @@ gulong g_signal_connect_data (gpointer instance,
<para> <para>
Of the four main signal emission functions, three have an explicit detail parameter as a Of the four main signal emission functions, three have an explicit detail parameter as a
<type>GQuark</type> again: <type><link linkend="GQuark">GQuark</link></type> again:
<programlisting> <programlisting>
void g_signal_emitv (const GValue *instance_and_params, void g_signal_emitv (const GValue *instance_and_params,
guint signal_id, guint signal_id,
@@ -491,7 +491,7 @@ void g_signal_emit_by_name (gpointer instance,
...); ...);
</programlisting> </programlisting>
The format of the detailed_signal parameter is exactly the same as the format used by The format of the detailed_signal parameter is exactly the same as the format used by
the <function>g_signal_connect</function> functions: <emphasis>signal_name::detail_name</emphasis>. the <function><link linkend="g-signal-connect">g_signal_connect</link></function> functions: <emphasis>signal_name::detail_name</emphasis>.
</para> </para>
<para> <para>

View File

@@ -42,19 +42,19 @@ GType g_type_register_fundamental (GType type_id,
</para> </para>
<para> <para>
<function>g_type_register_static</function> and <function><link linkend="g-type-register-static">g_type_register_static</link></function> and
<function>g_type_register_fundamental</function> <function><link linkend="g-type-register-fundamental">g_type_register_fundamental</link></function>
are the C functions, defined in are the C functions, defined in
<filename>gtype.h</filename> and implemented in <filename>gtype.c</filename> <filename>gtype.h</filename> and implemented in <filename>gtype.c</filename>
which you should use to register a new type in the program's type system. which you should use to register a new <type><link linkend="GType">GType</link></type> in the program's type system.
It is not likely you will ever need to use It is not likely you will ever need to use
<function>g_type_register_fundamental</function> (you have to be Tim Janik <function><link linkend="g-type-register-fundamental">g_type_register_fundamental</link></function> (you have to be Tim Janik
to do that) but in case you want to, the last chapter explains how to create to do that) but in case you want to, the last chapter explains how to create
new fundamental types. new fundamental types.
<footnote> <footnote>
<para> <para>
Please, note that there exist another registration function: the Please, note that there exist another registration function: the
<function>g_type_register_dynamic</function>. We will not discuss this <function><link linkend="g-type-register-dynamic">g_type_register_dynamic</link></function>. We will not discuss this
function here since its use is very similar to the <function>_static</function> function here since its use is very similar to the <function>_static</function>
version. version.
</para> </para>
@@ -64,7 +64,7 @@ GType g_type_register_fundamental (GType type_id,
<para> <para>
Fundamental types are top-level types which do not derive from any other type Fundamental types are top-level types which do not derive from any other type
while other non-fundamental types derive from other types. while other non-fundamental types derive from other types.
Upon initialization by <function>g_type_init</function>, the type system not Upon initialization by <function><link linkend="g-type-init">g_type_init</link></function>, the type system not
only initializes its internal data structures but it also registers a number of core only initializes its internal data structures but it also registers a number of core
types: some of these are fundamental types. Others are types derived from these types: some of these are fundamental types. Others are types derived from these
fundamental types. fundamental types.
@@ -74,37 +74,37 @@ GType g_type_register_fundamental (GType type_id,
Fundamental and non-Fundamental types are defined by: Fundamental and non-Fundamental types are defined by:
<itemizedlist> <itemizedlist>
<listitem><para> <listitem><para>
class size: the class_size field in <type>GTypeInfo</type>. class size: the class_size field in <type><link linkend="GTypeInfo">GTypeInfo</link></type>.
</para></listitem> </para></listitem>
<listitem><para> <listitem><para>
class initialization functions (C++ constructor): the base_init and class initialization functions (C++ constructor): the base_init and
class_init fields in <type>GTypeInfo</type>. class_init fields in <type><link linkend="GTypeInfo">GTypeInfo</link></type>.
</para></listitem> </para></listitem>
<listitem><para> <listitem><para>
class destruction functions (C++ destructor): the base_finalize and class destruction functions (C++ destructor): the base_finalize and
class_finalize fields in <type>GTypeInfo</type>. class_finalize fields in <type><link linkend="GTypeInfo">GTypeInfo</link></type>.
</para></listitem> </para></listitem>
<listitem><para> <listitem><para>
instance size (C++ parameter to new): the instance_size field in instance size (C++ parameter to new): the instance_size field in
<type>GTypeInfo</type>. <type><link linkend="GTypeInfo">GTypeInfo</link></type>.
</para></listitem> </para></listitem>
<listitem><para> <listitem><para>
instanciation policy (C++ type of new operator): the n_preallocs instanciation policy (C++ type of new operator): the n_preallocs
field in <type>GTypeInfo</type>. field in <type><link linkend="GTypeInfo">GTypeInfo</link></type>.
</para></listitem> </para></listitem>
<listitem><para> <listitem><para>
copy functions (C++ copy operators): the value_table field in copy functions (C++ copy operators): the value_table field in
<type>GTypeInfo</type>. <type><link linkend="GTypeInfo">GTypeInfo</link></type>.
</para></listitem> </para></listitem>
<listitem><para> <listitem><para>
XXX: <type>GTypeFlags</type>. XXX: <type><link linkend="GTypeFlags">GTypeFlags</link></type>.
</para></listitem> </para></listitem>
</itemizedlist> </itemizedlist>
Fundamental types are also defined by a set of <type>GTypeFundamentalFlags</type> Fundamental types are also defined by a set of <type><link linkend="GTypeFundamentalFlags">GTypeFundamentalFlags</link></type>
which are stored in a <type>GTypeFundamentalInfo</type>. which are stored in a <type><link linkend="GTypeFundamentalInfo">GTypeFundamentalInfo</link></type>.
Non-Fundamental types are furthermore defined by the type of their parent which is Non-Fundamental types are furthermore defined by the type of their parent which is
passed as the parent_type parameter to <function>g_type_register_static</function> passed as the parent_type parameter to <function><link linkend="g-type-register-static">g_type_register_static</link></function>
and <function>g_type_register_dynamic</function>. and <function><link linkend="g-type-register-dynamic">g_type_register_dynamic</link></function>.
</para> </para>
<sect1 id="gtype-copy"> <sect1 id="gtype-copy">
@@ -117,17 +117,17 @@ GType g_type_register_fundamental (GType type_id,
</para> </para>
<para> <para>
The <type>GValue</type> structure is used as an abstract container for all of these The <type><link linkend="GValue">GValue</link></type> structure is used as an abstract container for all of these
types. Its simplistic API (defined in <filename>gobject/gvalue.h</filename>) can be types. Its simplistic API (defined in <filename>gobject/gvalue.h</filename>) can be
used to invoke the value_table functions registered used to invoke the value_table functions registered
during type registration: for example <function>g_value_copy</function> copies the during type registration: for example <function><link linkend="g-value-copy">g_value_copy</link></function> copies the
content of a <type>GValue</type> to another <type>GValue</type>. This is similar content of a <type><link linkend="GValue">GValue</link></type> to another <type><link linkend="GValue">GValue</link></type>. This is similar
to a C++ assignment which invokes the C++ copy operator to modify the default to a C++ assignment which invokes the C++ copy operator to modify the default
bit-by-bit copy semantics of C++/C structures/classes. bit-by-bit copy semantics of C++/C structures/classes.
</para> </para>
<para> <para>
The following code shows how you can copy around a 64 bit integer, as well as a <type>GObject</type> The following code shows how you can copy around a 64 bit integer, as well as a <type><link linkend="GObject">GObject</link></type>
instance pointer (sample code for this is located in the source tarball for this document in instance pointer (sample code for this is located in the source tarball for this document in
<filename>sample/gtype/test.c</filename>): <filename>sample/gtype/test.c</filename>):
<programlisting> <programlisting>
@@ -322,7 +322,7 @@ GType maman_bar_get_type (void)
<para> <para>
To register such a type in the type system, you just need to fill the To register such a type in the type system, you just need to fill the
<type>GTypeInfo</type> structure with zeros since these types are also most of the time <type><link linkend="GTypeInfo">GTypeInfo</link></type> structure with zeros since these types are also most of the time
fundamental: fundamental:
<programlisting> <programlisting>
GTypeInfo info = { GTypeInfo info = {
@@ -356,9 +356,9 @@ GType maman_bar_get_type (void)
<para> <para>
Having non-instantiable types might seem a bit useless: what good is a type Having non-instantiable types might seem a bit useless: what good is a type
if you cannot instanciate an instance of that type ? Most of these types if you cannot instanciate an instance of that type ? Most of these types
are used in conjunction with <type>GValue</type>s: a GValue is initialized are used in conjunction with <type><link linkend="GValue">GValue</link></type>s: a GValue is initialized
with an integer or a string and it is passed around by using the registered with an integer or a string and it is passed around by using the registered
type's value_table. <type>GValue</type>s (and by extension these trivial fundamental type's value_table. <type><link linkend="GValue">GValue</link></type>s (and by extension these trivial fundamental
types) are most useful when used in conjunction with object properties and signals. types) are most useful when used in conjunction with object properties and signals.
</para> </para>
@@ -370,7 +370,7 @@ GType maman_bar_get_type (void)
<para> <para>
Types which are registered with a class and are declared instantiable are Types which are registered with a class and are declared instantiable are
what most closely resembles an <emphasis>object</emphasis>. what most closely resembles an <emphasis>object</emphasis>.
Although <type>GObject</type>s (detailed in <xref linkend="chapter-gobject"/>) Although <type><link linkend="GObject">GObject</link></type>s (detailed in <xref linkend="chapter-gobject"/>)
are the most well known type of instantiable are the most well known type of instantiable
classed types, other kinds of similar objects used as the base of an inheritance classed types, other kinds of similar objects used as the base of an inheritance
hierarchy have been externally developped and they are all built on the fundamental hierarchy have been externally developped and they are all built on the fundamental
@@ -428,8 +428,8 @@ maman_bar_get_type (void)
<para> <para>
Every object must define two structures: its class structure and its Every object must define two structures: its class structure and its
instance structure. All class structures must contain as first member instance structure. All class structures must contain as first member
a <type>GTypeClass</type> structure. All instance structures must contain as first a <type><link linkend="GTypeClass">GTypeClass</link></type> structure. All instance structures must contain as first
member a <type>GTypeInstance</type> structure. The declaration of these C types, member a <type><link linkend="GTypeInstance">GTypeInstance</link></type> structure. The declaration of these C types,
coming from <filename>gtype.h</filename> is shown below: coming from <filename>gtype.h</filename> is shown below:
<programlisting> <programlisting>
struct _GTypeClass struct _GTypeClass
@@ -496,12 +496,12 @@ B *b;
<para> <para>
Instanciation of these types can be done with Instanciation of these types can be done with
<function>g_type_create_instance</function>: <function><link linkend="g-type-create-instance">g_type_create_instance</link></function>:
<programlisting> <programlisting>
GTypeInstance* g_type_create_instance (GType type); GTypeInstance* g_type_create_instance (GType type);
void g_type_free_instance (GTypeInstance *instance); void g_type_free_instance (GTypeInstance *instance);
</programlisting> </programlisting>
<function>g_type_create_instance</function> will lookup the type information <function><link linkend="g-type-create-instance">g_type_create_instance</link></function> will lookup the type information
structure associated to the type requested. Then, the instance size and instanciation structure associated to the type requested. Then, the instance size and instanciation
policy (if the n_preallocs field is set to a non-zero value, the type system allocates policy (if the n_preallocs field is set to a non-zero value, the type system allocates
the object's instance structures in chunks rather than mallocing for every instance) the object's instance structures in chunks rather than mallocing for every instance)
@@ -514,9 +514,9 @@ void g_type_free_instance (GTypeInstance *instance);
a class structure: it allocates a buffer to hold the object's class structure and a class structure: it allocates a buffer to hold the object's class structure and
initializes it. It first copies the parent's class structure over this structure initializes it. It first copies the parent's class structure over this structure
(if there is no parent, it initializes it to zero). It then invokes the (if there is no parent, it initializes it to zero). It then invokes the
base_class_initialization functions (<type>GBaseInitFunc</type>) from topmost base_class_initialization functions (<type><link linkend="GBaseInitFunc">GBaseInitFunc</link></type>) from topmost
fundamental object to bottom-most most derived object. The object's class_init fundamental object to bottom-most most derived object. The object's class_init
(<type>GClassInitFunc</type>) function is invoked afterwards to complete (<type><link linkend="GClassInitFunc">GClassInitFunc</link></type>) function is invoked afterwards to complete
initialization of the class structure. initialization of the class structure.
Finally, the object's interfaces are initialized (we will discuss interface initialization Finally, the object's interfaces are initialized (we will discuss interface initialization
in more detail later). in more detail later).
@@ -531,12 +531,12 @@ The class initialization process is entirely implemented in
<para> <para>
Once the type system has a pointer to an initialized class structure, it sets the object's Once the type system has a pointer to an initialized class structure, it sets the object's
instance class pointer to the object's class structure and invokes the object's instance class pointer to the object's class structure and invokes the object's
instance_init (<type>GInstanceInitFunc</type>)functions, from top-most fundamental instance_init (<type><link linkend="GInstanceInitFunc">GInstanceInitFunc</link></type>)functions, from top-most fundamental
type to bottom-most most derived type. type to bottom-most most derived type.
</para> </para>
<para> <para>
Object instance destruction through <function>g_type_free_instance</function> is very simple: Object instance destruction through <function><link linkend="g-type-free-instance">g_type_free_instance</link></function> is very simple:
the instance structure is returned to the instance pool if there is one and if this was the the instance structure is returned to the instance pool if there is one and if this was the
last living instance of the object, the class is destroyed. last living instance of the object, the class is destroyed.
</para> </para>
@@ -552,8 +552,8 @@ The class initialization process is entirely implemented in
in Gtype) is the symmetric process of the initialization: interfaces are in Gtype) is the symmetric process of the initialization: interfaces are
destroyed first. destroyed first.
Then, the most derived Then, the most derived
class_finalize (<type>ClassFinalizeFunc</type>) function is invoked. The class_finalize (<type><link linkend="ClassFinalizeFunc">ClassFinalizeFunc</link></type>) function is invoked. The
base_class_finalize (<type>GBaseFinalizeFunc</type>) functions are base_class_finalize (<type><link linkend="GBaseFinalizeFunc">GBaseFinalizeFunc</link></type>) functions are
Finally invoked from bottom-most most-derived type to top-most fundamental type and Finally invoked from bottom-most most-derived type to top-most fundamental type and
the class structure is freed. the class structure is freed.
</para> </para>
@@ -597,39 +597,39 @@ The class initialization process is entirely implemented in
</thead> </thead>
<tbody> <tbody>
<row> <row>
<entry>First call to <function>g_type_create_instance</function> for target type</entry> <entry>First call to <function><link linkend="g-type-create-instance">g_type_create_instance</link></function> for target type</entry>
<entry>type's base_init function</entry> <entry>type's base_init function</entry>
<entry>On the inheritance tree of classes from fundamental type to target type. <entry>On the inheritance tree of classes from fundamental type to target type.
base_init is invoked once for each class structure.</entry> base_init is invoked once for each class structure.</entry>
</row> </row>
<row> <row>
<entry>First call to <function>g_type_create_instance</function> for target type</entry> <entry>First call to <function><link linkend="g-type-create-instance">g_type_create_instance</link></function> for target type</entry>
<entry>target type's class_init function</entry> <entry>target type's class_init function</entry>
<entry>On target type's class structure</entry> <entry>On target type's class structure</entry>
</row> </row>
<row> <row>
<entry>First call to <function>g_type_create_instance</function> for target type</entry> <entry>First call to <function><link linkend="g-type-create-instance">g_type_create_instance</link></function> for target type</entry>
<entry colspan="2">interface initialization, see <entry colspan="2">interface initialization, see
<xref linkend="gtype-non-instantiable-classed-init"/></entry> <xref linkend="gtype-non-instantiable-classed-init"/></entry>
</row> </row>
<row> <row>
<entry>Each call to <function>g_type_create_instance</function> for target type</entry> <entry>Each call to <function><link linkend="g-type-create-instance">g_type_create_instance</link></function> for target type</entry>
<entry>target type's instance_init function</entry> <entry>target type's instance_init function</entry>
<entry>On object's instance</entry> <entry>On object's instance</entry>
</row> </row>
<row> <row>
<entry>Last call to <function>g_type_free_instance</function> for target type</entry> <entry>Last call to <function><link linkend="g-type-free-instance">g_type_free_instance</link></function> for target type</entry>
<entry colspan="2">interface destruction, see <entry colspan="2">interface destruction, see
<xref linkend="gtype-non-instantiable-classed-dest"/></entry> <xref linkend="gtype-non-instantiable-classed-dest"/></entry>
<entry></entry> <entry></entry>
</row> </row>
<row> <row>
<entry>Last call to <function>g_type_free_instance</function> for target type</entry> <entry>Last call to <function><link linkend="g-type-free-instance">g_type_free_instance</link></function> for target type</entry>
<entry>target type's class_finalize function</entry> <entry>target type's class_finalize function</entry>
<entry>On target type's class structure</entry> <entry>On target type's class structure</entry>
</row> </row>
<row> <row>
<entry>Last call to <function>g_type_free_instance</function> for target type</entry> <entry>Last call to <function><link linkend="g-type-free-instance">g_type_free_instance</link></function> for target type</entry>
<entry>type's base_finalize function</entry> <entry>type's base_finalize function</entry>
<entry>On the inheritance tree of classes from fundamental type to target type. <entry>On the inheritance tree of classes from fundamental type to target type.
base_init is invoked once for each class structure.</entry> base_init is invoked once for each class structure.</entry>
@@ -647,7 +647,7 @@ The class initialization process is entirely implemented in
<para> <para>
GType's Interfaces are very similar to Java's interfaces. To declare one of these GType's Interfaces are very similar to Java's interfaces. To declare one of these
you have to register a non-instantiable classed type which derives from you have to register a non-instantiable classed type which derives from
<type>GTypeInterface</type>. The following piece of code declares such an interface. <type><link linkend="GTypeInterface">GTypeInterface</link></type>. The following piece of code declares such an interface.
<programlisting> <programlisting>
#define MAMAN_IBAZ_TYPE (maman_ibaz_get_type ()) #define MAMAN_IBAZ_TYPE (maman_ibaz_get_type ())
#define MAMAN_IBAZ(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MAMAN_IBAZ_TYPE, MamanIbaz)) #define MAMAN_IBAZ(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MAMAN_IBAZ_TYPE, MamanIbaz))
@@ -684,7 +684,7 @@ void maman_ibaz_do_action (MamanIbaz *self)
<para> <para>
An interface is defined by only one structure which must contain as first member An interface is defined by only one structure which must contain as first member
a <type>GTypeInterface</type> structure. The interface structure is expected to a <type><link linkend="GTypeInterface">GTypeInterface</link></type> structure. The interface structure is expected to
contain the function pointers of the interface methods. It is good style to contain the function pointers of the interface methods. It is good style to
define helper functions for each of the interface methods which simply call define helper functions for each of the interface methods which simply call
the interface' method directly: <function>maman_ibaz_do_action</function> the interface' method directly: <function>maman_ibaz_do_action</function>
@@ -694,7 +694,7 @@ void maman_ibaz_do_action (MamanIbaz *self)
<para> <para>
Once an interface type is registered, you must register implementations for these Once an interface type is registered, you must register implementations for these
interfaces. The function named <function>maman_baz_get_type</function> registers interfaces. The function named <function>maman_baz_get_type</function> registers
a new GType named MamanBaz which inherits from <type>GObject</type> and which a new GType named MamanBaz which inherits from <type><link linkend="GObject">GObject</link></type> and which
implements the interface <type>MamanIBaz</type>. implements the interface <type>MamanIBaz</type>.
<programlisting> <programlisting>
static void maman_baz_do_action (MamanIbaz *self) static void maman_baz_do_action (MamanIbaz *self)
@@ -745,10 +745,11 @@ maman_baz_get_type (void)
</para> </para>
<para> <para>
<function>g_type_add_interface_static</function> records in the type system that <function><link linkend="g-type-add-interface-static">g_type_add_interface_static</link></function> records in the type system that
a given type implements also <type>FooInterface</type> a given type implements also <type>FooInterface</type>
(<function>foo_interface_get_type</function> returns the type of (<function>foo_interface_get_type</function> returns the type of
<type>FooInterface</type>). The <type>GInterfaceInfo</type> structure holds <type>FooInterface</type>).
The <type><link linkend="GInterfaceInfo">GInterfaceInfo</link></type> structure holds
information about the implementation of the interface: information about the implementation of the interface:
<programlisting> <programlisting>
struct _GInterfaceInfo struct _GInterfaceInfo
@@ -819,7 +820,7 @@ maman_ibaz_base_init (gpointer g_class)
<para> <para>
The above process can be summarized as follows: The above process can be summarized as follows:
<table> <table>
<title><function>Interface Initialization</function></title> <title>Interface Initialization</title>
<tgroup cols="3"> <tgroup cols="3">
<colspec colwidth="*" colnum="1" align="left"/> <colspec colwidth="*" colnum="1" align="left"/>
<colspec colwidth="*" colnum="2" align="left"/> <colspec colwidth="*" colnum="2" align="left"/>
@@ -835,7 +836,7 @@ maman_ibaz_base_init (gpointer g_class)
</thead> </thead>
<tbody> <tbody>
<row> <row>
<entry>First call to <function>g_type_create_instance</function> for type <entry>First call to <function><link linkend="g-type-create-instance">g_type_create_instance</link></function> for type
implementing interface</entry> implementing interface</entry>
<entry>interface' base_init function</entry> <entry>interface' base_init function</entry>
<entry>On interface' vtable</entry> <entry>On interface' vtable</entry>
@@ -844,7 +845,7 @@ maman_ibaz_base_init (gpointer g_class)
twice.).</entry> twice.).</entry>
</row> </row>
<row> <row>
<entry>First call to <function>g_type_create_instance</function> for type <entry>First call to <function><link linkend="g-type-create-instance">g_type_create_instance</link></function> for type
implementing interface</entry> implementing interface</entry>
<entry>interface' interface_init function</entry> <entry>interface' interface_init function</entry>
<entry>On interface' vtable</entry> <entry>On interface' vtable</entry>
@@ -891,7 +892,7 @@ maman_ibaz_base_init (gpointer g_class)
<para> <para>
The above process can be summarized as follows: The above process can be summarized as follows:
<table> <table>
<title><function>Interface Finalization</function></title> <title>Interface Finalization</title>
<tgroup cols="3"> <tgroup cols="3">
<colspec colwidth="*" colnum="1" align="left"/> <colspec colwidth="*" colnum="1" align="left"/>
<colspec colwidth="*" colnum="2" align="left"/> <colspec colwidth="*" colnum="2" align="left"/>
@@ -906,13 +907,13 @@ maman_ibaz_base_init (gpointer g_class)
</thead> </thead>
<tbody> <tbody>
<row> <row>
<entry>Last call to <function>g_type_free_instance</function> for type <entry>Last call to <function><link linkend="g-type-free-instance">g_type_free_instance</link></function> for type
implementing interface</entry> implementing interface</entry>
<entry>interface' interface_finalize function</entry> <entry>interface' interface_finalize function</entry>
<entry>On interface' vtable</entry> <entry>On interface' vtable</entry>
</row> </row>
<row> <row>
<entry>Last call to <function>g_type_free_instance</function>for type <entry>Last call to <function><link linkend="g-type-free-instance">g_type_free_instance</link></function>for type
implementing interface</entry> implementing interface</entry>
<entry>interface' base_finalize function</entry> <entry>interface' base_finalize function</entry>
<entry>On interface' vtable</entry> <entry>On interface' vtable</entry>

View File

@@ -1,17 +1,16 @@
<chapter id="howto"> <partintro>
<title>How To ?</title>
<para> <para>
This chapter tries to answer the real-life questions of users and presents This chapter tries to answer the real-life questions of users and presents
the most common scenario use-cases I could come up with. the most common scenario use-cases I could come up with.
The use-cases are presented from most likely to less likely. The use-cases are presented from most likely to less likely.
</para> </para>
</partintro>
<!-- <!--
Howto GObject Howto GObject
--> -->
<sect1 id="howto-gobject"> <chapter id="howto-gobject">
<title>How To define and implement a new GObject ?</title> <title>How To define and implement a new GObject ?</title>
<para> <para>
@@ -23,13 +22,13 @@
<filename>sample/gobject</filename> directory: <filename>sample/gobject</filename> directory:
<itemizedlist> <itemizedlist>
<listitem><para><filename>maman-bar.{h|c}</filename>: this is the source for a object which derives from <listitem><para><filename>maman-bar.{h|c}</filename>: this is the source for a object which derives from
<type>GObject</type> and which shows how to declare different types of methods on the object. <type><link linkend="GObject">GObject</link></type> and which shows how to declare different types of methods on the object.
</para></listitem> </para></listitem>
<listitem><para><filename>maman-subbar.{h|c}</filename>: this is the source for a object which derives from <listitem><para><filename>maman-subbar.{h|c}</filename>: this is the source for a object which derives from
<type>MamanBar</type> and which shows how to override some of its parent's methods. <type>MamanBar</type> and which shows how to override some of its parent's methods.
</para></listitem> </para></listitem>
<listitem><para><filename>maman-foo.{h|c}</filename>: this is the source for an object which derives from <listitem><para><filename>maman-foo.{h|c}</filename>: this is the source for an object which derives from
<type>GObject</type> and which declares a signal. <type><link linkend="GObject">GObject</link></type> and which declares a signal.
</para></listitem> </para></listitem>
<listitem><para><filename>test.c</filename>: this is the main source which instantiates an instance of <listitem><para><filename>test.c</filename>: this is the main source which instantiates an instance of
type and exercises their API. type and exercises their API.
@@ -37,7 +36,7 @@
</itemizedlist> </itemizedlist>
</para> </para>
<sect2 id="howto-gobject-header"> <sect1 id="howto-gobject-header">
<title>Boilerplate header code</title> <title>Boilerplate header code</title>
<para> <para>
@@ -186,7 +185,7 @@ static void maman_bar_init(GTypeInstance *instance, gpointer g_class) {
<listitem><para> <listitem><para>
A similar alternative, available since Glib version 2.4, is to define a private structure in the .c file, A similar alternative, available since Glib version 2.4, is to define a private structure in the .c file,
declare it as a private structure in <function>class_init</function> using declare it as a private structure in <function>class_init</function> using
<function>g_type_class_add_private</function> and declare a macro to allow convenient access to this structure. <function><link linkend="g-type-class-add-private">g_type_class_add_private</link></function> and declare a macro to allow convenient access to this structure.
A private structure will then be attached to each newly created object by the GObject system. A private structure will then be attached to each newly created object by the GObject system.
You dont need to free or allocate the private structure, only the objects or pointers that it may contain. You dont need to free or allocate the private structure, only the objects or pointers that it may contain.
<programlisting> <programlisting>
@@ -238,9 +237,9 @@ maman_bar_get_private_field (MamanBar *self)
</itemizedlist> </itemizedlist>
</para> </para>
</sect2> </sect1>
<sect2 id="howto-gobject-code"> <sect1 id="howto-gobject-code">
<title>Boilerplate code</title> <title>Boilerplate code</title>
<para> <para>
@@ -297,9 +296,9 @@ maman_bar_get_type (void)
} }
</programlisting> </programlisting>
</para> </para>
</sect2> </sect1>
<sect2 id="howto-gobject-construction"> <sect1 id="howto-gobject-construction">
<title>Object Construction</title> <title>Object Construction</title>
<para> <para>
@@ -320,7 +319,7 @@ maman_bar_get_type (void)
<para> <para>
Construction properties will be set only after all instance_init functions have run. Construction properties will be set only after all instance_init functions have run.
No object reference will be returned to the client of <function>g_object_new></function> No object reference will be returned to the client of <function><link linkend="g-object-new>">g_object_new></link></function>
until all the construction properties have been set. until all the construction properties have been set.
</para> </para>
@@ -343,14 +342,14 @@ maman_bar_init (GTypeInstance *instance,
And make sure that you set <function>maman_bar_init</function> as the type's instance_init function And make sure that you set <function>maman_bar_init</function> as the type's instance_init function
in <function>maman_bar_get_type</function>. Make sure the code builds and runs: create an instance in <function>maman_bar_get_type</function>. Make sure the code builds and runs: create an instance
of the object and make sure <function>maman_bar_init</function> is called (add a of the object and make sure <function>maman_bar_init</function> is called (add a
<function>g_print</function> call in it). <function><link linkend="g-print">g_print</link></function> call in it).
</para> </para>
<para> <para>
Now, if you need special construction properties, install the properties in the class_init function, Now, if you need special construction properties, install the properties in the class_init function,
override the set and get methods and implement the get and set methods as described in override the set and get methods and implement the get and set methods as described in
<xref linkend="gobject-properties"/>. Make sure that these properties use a construct only <xref linkend="gobject-properties"/>. Make sure that these properties use a construct only
<type>GParamSpec</type> by setting the param spec's flag field to G_PARAM_CONSTRUCT_ONLY: this helps <type><link linkend="GParamSpec">GParamSpec</link></type> by setting the param spec's flag field to G_PARAM_CONSTRUCT_ONLY: this helps
GType ensure that these properties are not set again later by malicious user code. GType ensure that these properties are not set again later by malicious user code.
<programlisting> <programlisting>
static void static void
@@ -375,7 +374,7 @@ bar_class_init (MamanBarClass *klass)
</programlisting> </programlisting>
If you need this, make sure you can build and run code similar to the code shown above. Make sure If you need this, make sure you can build and run code similar to the code shown above. Make sure
your construct properties can set correctly during construction, make sure you cannot set them your construct properties can set correctly during construction, make sure you cannot set them
afterwards and make sure that if your users do not call <function>g_object_new</function> afterwards and make sure that if your users do not call <function><link linkend="g-object-new">g_object_new</link></function>
with the required construction properties, these will be initialized with the default values. with the required construction properties, these will be initialized with the default values.
</para> </para>
@@ -392,14 +391,14 @@ bar_class_init (MamanBarClass *klass)
use of this feature. As such, to initialize your object instances, use by default the base_init function use of this feature. As such, to initialize your object instances, use by default the base_init function
and construction properties. and construction properties.
</para> </para>
</sect2> </sect1>
<sect2 id="howto-gobject-destruction"> <sect1 id="howto-gobject-destruction">
<title>Object Destruction</title> <title>Object Destruction</title>
<para> <para>
Again, it is often difficult to figure out which mechanism to use to hook into the object's Again, it is often difficult to figure out which mechanism to use to hook into the object's
destruction process: when the last <function>g_object_unref</function> function call is made, destruction process: when the last <function><link linkend="g-object-unref">g_object_unref</link></function> function call is made,
a lot of things happen as described in <xref linkend="gobject-destruction-table"/>. a lot of things happen as described in <xref linkend="gobject-destruction-table"/>.
</para> </para>
@@ -487,9 +486,9 @@ if (self->private->dispose_has_run) {
} }
</programlisting> </programlisting>
</para> </para>
</sect2> </sect1>
<sect2 id="howto-gobject-methods"> <sect1 id="howto-gobject-methods">
<title>Object methods</title> <title>Object methods</title>
<para> <para>
@@ -511,7 +510,7 @@ if (self->private->dispose_has_run) {
</itemizedlist> </itemizedlist>
</para> </para>
<sect3> <sect2>
<title>Non-virtual public methods</title> <title>Non-virtual public methods</title>
<para> <para>
@@ -530,9 +529,9 @@ void maman_bar_do_action (MamanBar *self, /* parameters */)
</para> </para>
<para>There is really nothing scary about this.</para> <para>There is really nothing scary about this.</para>
</sect3> </sect2>
<sect3> <sect2>
<title>Virtual public methods</title> <title>Virtual public methods</title>
<para> <para>
@@ -606,9 +605,9 @@ void maman_bar_do_action_two (MamanBar *self, /* parameters */)
} }
</programlisting> </programlisting>
</para> </para>
</sect3> </sect2>
<sect3> <sect2>
<title>Virtual private Methods</title> <title>Virtual private Methods</title>
<para> <para>
@@ -674,10 +673,10 @@ maman_bar_subtype_class_init (MamanBarSubTypeClass *klass)
} }
</programlisting> </programlisting>
</para> </para>
</sect3> </sect2>
</sect2> </sect1>
<sect2 id="howto-gobject-chainup"> <sect1 id="howto-gobject-chainup">
<title>Chaining up</title> <title>Chaining up</title>
<para>Chaining up is often loosely defined by the following set of conditions: <para>Chaining up is often loosely defined by the following set of conditions:
@@ -720,7 +719,7 @@ maman_bar_subtype_class_init (MamanBarSubTypeClass *klass)
</footnote> </footnote>
</para> </para>
<para>The function <function>g_type_class_peek_parent</function> is used to access the original parent <para>The function <function><link linkend="g-type-class-peek-parent">g_type_class_peek_parent</link></function> is used to access the original parent
class structure. Its input is a pointer to the class of the derived object and it returns a pointer class structure. Its input is a pointer to the class of the derived object and it returns a pointer
to the original parent class structure. The code below shows how you could use it: to the original parent class structure. The code below shows how you could use it:
<programlisting> <programlisting>
@@ -738,14 +737,14 @@ b_method_to_call (B *obj, int a)
} }
</programlisting> </programlisting>
A lot of people who use this idiom in GTK+ store the parent class structure pointer in a global static A lot of people who use this idiom in GTK+ store the parent class structure pointer in a global static
variable to avoid the costly call to <function>g_type_class_peek_parent</function> for each function call. variable to avoid the costly call to <function><link linkend="g-type-class-peek-parent">g_type_class_peek_parent</link></function> for each function call.
Typically, the class_init callback initializes the global static variable. <filename>gtk/gtkhscale.c</filename> Typically, the class_init callback initializes the global static variable. <filename>gtk/gtkhscale.c</filename>
does this. does this.
</para> </para>
</sect2> </sect1>
</sect1> </chapter>
<!-- <!--
End Howto GObject End Howto GObject
@@ -756,10 +755,10 @@ b_method_to_call (B *obj, int a)
Howto Interfaces Howto Interfaces
--> -->
<sect1 id="howto-interface"> <chapter id="howto-interface">
<title>How To define and implement Interfaces ?</title> <title>How To define and implement Interfaces ?</title>
<sect2 id="howto-interface-define"> <sect1 id="howto-interface-define">
<title>How To define Interfaces ?</title> <title>How To define Interfaces ?</title>
<para> <para>
@@ -800,8 +799,8 @@ void maman_ibaz_do_action (MamanIbaz *self);
#endif /*MAMAN_IBAZ_H*/ #endif /*MAMAN_IBAZ_H*/
</programlisting> </programlisting>
This code is almost exactly similar to the code for a normal <type>GType</type> This code is almost exactly similar to the code for a normal <type><link linkend="GType">GType</link></type>
which derives from a <type>GObject</type> except for a few details: which derives from a <type><link linkend="GObject">GObject</link></type> except for a few details:
<itemizedlist> <itemizedlist>
<listitem><para> <listitem><para>
The <function>_GET_CLASS</function> macro is not implemented with The <function>_GET_CLASS</function> macro is not implemented with
@@ -870,9 +869,9 @@ void maman_ibaz_do_action (MamanIbaz *self)
} }
</programlisting> </programlisting>
</para> </para>
</sect2> </sect1>
<sect2 id="howto-interface-implement"> <sect1 id="howto-interface-implement">
<title>How To define and implement an implementation of an Interface ?</title> <title>How To define and implement an implementation of an Interface ?</title>
<para> <para>
@@ -954,8 +953,8 @@ maman_baz_get_type (void)
} }
</programlisting> </programlisting>
This function is very much like all the similar functions we looked at previously. The only interface-specific This function is very much like all the similar functions we looked at previously. The only interface-specific
code present here is the call to <function>g_type_add_interface_static</function> which is used to inform code present here is the call to <function><link linkend="g-type-add-interface-static">g_type_add_interface_static</link></function> which is used to inform
the type system that this just-registered <type>GType</type> also implements the interface the type system that this just-registered <type><link linkend="GType">GType</link></type> also implements the interface
<function>MAMAN_TYPE_IBAZ</function>. <function>MAMAN_TYPE_IBAZ</function>.
</para> </para>
@@ -986,9 +985,9 @@ baz_instance_init (GTypeInstance *instance,
but it could :) but it could :)
</para> </para>
</sect2> </sect1>
<sect2> <sect1>
<title>Interface definition prerequisites</title> <title>Interface definition prerequisites</title>
<para>To specify that an interface requires the presence of other interfaces when implemented, <para>To specify that an interface requires the presence of other interfaces when implemented,
@@ -1085,7 +1084,7 @@ maman_bar_get_type (void)
} }
</programlisting> </programlisting>
It is very important to notice that the order in which interface implementations are added to the main object It is very important to notice that the order in which interface implementations are added to the main object
is not random: <function>g_type_interface_static</function> must be invoked first on the interfaces which have is not random: <function><link linkend="g-type-add-interface-static">g_type_add_interface_static</link></function> must be invoked first on the interfaces which have
no prerequisites and then on the others. no prerequisites and then on the others.
</para> </para>
@@ -1095,16 +1094,16 @@ maman_bar_get_type (void)
and <filename>sample/interface/maman-bar.{h|c}</filename>. and <filename>sample/interface/maman-bar.{h|c}</filename>.
</para> </para>
</sect2> </sect1>
<sect2 id="howto-interface-properties"> <sect1 id="howto-interface-properties">
<title>Interface Properties</title> <title>Interface Properties</title>
<para>Starting from version 2.4 of glib, gobject interfaces can also have properties. <para>Starting from version 2.4 of glib, gobject interfaces can also have properties.
Declaration of the interface properties is similar to declaring the properties of Declaration of the interface properties is similar to declaring the properties of
ordinary gobject types as explained in <xref linkend="gobject-properties"/>, ordinary gobject types as explained in <xref linkend="gobject-properties"/>,
except that <function>g_object_interface_install_property</function> is used to except that <function><link linkend="g-object-interface-install-property">g_object_interface_install_property</link></function> is used to
declare the properties instead of <function>g_object_class_install_property</function>. declare the properties instead of <function><link linkend="g-object-class-install-property">g_object_class_install_property</link></function>.
</para> </para>
<para>To include a property named 'name' of type <type>string</type> in the <para>To include a property named 'name' of type <type>string</type> in the
@@ -1150,8 +1149,8 @@ maman_ibaz_base_init (gpointer g_class)
An implementer shall declare and define it's properties in the usual way as An implementer shall declare and define it's properties in the usual way as
explained in <xref linkend="gobject-properties"/>, except for one small explained in <xref linkend="gobject-properties"/>, except for one small
change: it shall declare the properties of the interface it implements using change: it shall declare the properties of the interface it implements using
<function>g_object_class_override_property</function> instead of <function><link linkend="g-object-class-override-property">g_object_class_override_property</link></function> instead of
<function>g_object_class_install_property</function>. The following code snipet <function><link linkend="g-object-class-install-property">g_object_class_install_property</link></function>. The following code snipet
shows the modifications needed in the <type>MamanBaz</type> declaration and shows the modifications needed in the <type>MamanBaz</type> declaration and
implementation above: implementation above:
<programlisting> <programlisting>
@@ -1260,10 +1259,10 @@ maman_baz_get_property (GObject * object, guint prop_id,
</programlisting> </programlisting>
</para> </para>
</sect2> </sect1>
</sect1> </chapter>
<!-- <!--
End Howto Interfaces End Howto Interfaces
@@ -1275,7 +1274,7 @@ maman_baz_get_property (GObject * object, guint prop_id,
--> -->
<sect1 id="howto-signals"> <chapter id="howto-signals">
<title>Howto create and use signals</title> <title>Howto create and use signals</title>
@@ -1292,7 +1291,7 @@ maman_baz_get_property (GObject * object, guint prop_id,
just emit events which can be received by numerous clients. just emit events which can be received by numerous clients.
</para> </para>
<sect2 id="howto-simple-signals"> <sect1 id="howto-simple-signals">
<title>Simple use of signals</title> <title>Simple use of signals</title>
<para>The most basic use of signals is to implement simple event notification: for example, if we have a <para>The most basic use of signals is to implement simple event notification: for example, if we have a
@@ -1352,10 +1351,10 @@ The header <filename>gobject/gmarshal.h</filename> defines a set of commonly
needed closures that one can use. needed closures that one can use.
</para> </para>
</sect2> </sect1>
<sect2> <sect1>
<title>How to provide more flexibility to users ?</title> <title>How to provide more flexibility to users ?</title>
<para>The previous implementation does the job but the signal facility of GObject can be used to provide <para>The previous implementation does the job but the signal facility of GObject can be used to provide
@@ -1440,8 +1439,8 @@ void maman_file_complex_write (MamanFileComplex *self, guint8 *buffer, guint siz
<para>The client code (as shown in <filename>sample/signal/test.c</filename> and below) can now connect signal handlers before <para>The client code (as shown in <filename>sample/signal/test.c</filename> and below) can now connect signal handlers before
and after the file write is completed: since the default signal handler which does the write itself runs during the and after the file write is completed: since the default signal handler which does the write itself runs during the
RUN_LAST phase of the signal emission, it will run after all handlers connected with <function>g_signal_connect</function> RUN_LAST phase of the signal emission, it will run after all handlers connected with <function><link linkend="g-signal-connect">g_signal_connect</link></function>
and before all handlers connected with <function>g_signal_connect_after</function>. If you intent to write a GObject and before all handlers connected with <function><link linkend="g-signal-connect-after">g_signal_connect_after</link></function>. If you intent to write a GObject
which emits signals, I would thus urge you to create all your signals with the G_SIGNAL_RUN_LAST such that your users which emits signals, I would thus urge you to create all your signals with the G_SIGNAL_RUN_LAST such that your users
have a maximum of flexibility as to when to get the event. Here, we combined it with G_SIGNAL_NO_RECURSE and have a maximum of flexibility as to when to get the event. Here, we combined it with G_SIGNAL_NO_RECURSE and
G_SIGNAL_NO_HOOKS to ensure our users will not try to do really weird things with our GObject. I strongly advise you G_SIGNAL_NO_HOOKS to ensure our users will not try to do really weird things with our GObject. I strongly advise you
@@ -1492,7 +1491,7 @@ Complex Write event after: 0xbfffe280, 50
</para> </para>
<sect3> <sect2>
<title>How most people do the same thing with less code</title> <title>How most people do the same thing with less code</title>
<para>For many historic reasons related to how the ancestor of GObject used to work in GTK+ 1.x versions, <para>For many historic reasons related to how the ancestor of GObject used to work in GTK+ 1.x versions,
@@ -1510,13 +1509,13 @@ Complex Write event after: 0xbfffe280, 50
</para> </para>
</footnote> </footnote>
way to create a signal with a default handler than to create way to create a signal with a default handler than to create
a closure by hand and to use the <function>g_signal_newv</function>. a closure by hand and to use the <function><link linkend="g-signal-newv">g_signal_newv</link></function>.
</para> </para>
<para>For example, <function>g_signal_new</function> can be used to create a signal which uses a default <para>For example, <function><link linkend="g-signal-new">g_signal_new</link></function> can be used to create a signal which uses a default
handler which is stored in the class structure of the object. More specifically, the class structure handler which is stored in the class structure of the object. More specifically, the class structure
contains a function pointer which is accessed during signal emission to invoke the default handler and contains a function pointer which is accessed during signal emission to invoke the default handler and
the user is expected to provide to <function>g_signal_new</function> the offset from the start of the the user is expected to provide to <function><link linkend="g-signal-new">g_signal_new</link></function> the offset from the start of the
class structure to the function pointer. class structure to the function pointer.
<footnote> <footnote>
<para>I would like to point out here that the reason why the default handler of a signal is named everywhere <para>I would like to point out here that the reason why the default handler of a signal is named everywhere
@@ -1550,7 +1549,7 @@ maman_file_simple_class_init (gpointer g_class,
klass->write = default_write_signal_handler; klass->write = default_write_signal_handler;
</programlisting> </programlisting>
Finally, the signal is created with <function>g_signal_new</function> in the same class_init function: Finally, the signal is created with <function><link linkend="g-signal-new">g_signal_new</link></function> in the same class_init function:
<programlisting> <programlisting>
klass->write_signal_id = klass->write_signal_id =
g_signal_new ("write", g_signal_new ("write",
@@ -1565,7 +1564,7 @@ klass->write_signal_id =
G_TYPE_POINTER, G_TYPE_POINTER,
G_TYPE_UINT); G_TYPE_UINT);
</programlisting> </programlisting>
Of note, here, is the 4th argument to the function: it is an integer calculated by the <function>G_STRUCT_OFFSET</function> Of note, here, is the 4th argument to the function: it is an integer calculated by the <function><link linkend="G-STRUCT-OFFSET">G_STRUCT_OFFSET</link></function>
macro which indicates the offset of the member <emphasis>write</emphasis> from the start of the macro which indicates the offset of the member <emphasis>write</emphasis> from the start of the
<type>MamanFileSimpleClass</type> class structure. <type>MamanFileSimpleClass</type> class structure.
<footnote> <footnote>
@@ -1586,24 +1585,24 @@ klass->write_signal_id =
</para> </para>
<para>If you have doubts about which method to use, I would advise you to use the second one which <para>If you have doubts about which method to use, I would advise you to use the second one which
involves <function>g_signal_new</function> rather than <function>g_signal_newv</function>: involves <function><link linkend="g-signal-new">g_signal_new</link></function> rather than <function><link linkend="g-signal-newv">g_signal_newv</link></function>:
it is better to write code which looks like the vast majority of other GTK+/Gobject code than to it is better to write code which looks like the vast majority of other GTK+/Gobject code than to
do it your own way. However, now, you know why. do it your own way. However, now, you know why.
</para> </para>
</sect3> </sect2>
</sect2> </sect1>
<sect2> <sect1>
<title>How users can abuse signals (and why some think it is good)</title> <title>How users can abuse signals (and why some think it is good)</title>
<para>Now that you know how to create signals to which the users can connect easily and at any point in <para>Now that you know how to create signals to which the users can connect easily and at any point in
the signal emission process thanks to <function>g_signal_connect</function>, the signal emission process thanks to <function><link linkend="g-signal-connect">g_signal_connect</link></function>,
<function>g_signal_connect_after</function> and G_SIGNAL_RUN_LAST, it is time to look into how your <function><link linkend="g-signal-connect-after">g_signal_connect_after</link></function> and G_SIGNAL_RUN_LAST, it is time to look into how your
users can and will screw you. This is also interesting to know how you too, can screw other people. users can and will screw you. This is also interesting to know how you too, can screw other people.
This will make you feel good and eleet. This will make you feel good and eleet.
</para> </para>
@@ -1625,7 +1624,7 @@ klass->write_signal_id =
</para> </para>
<para>If all you want to do is to stop the signal emission from one of the callbacks you connected yourself, <para>If all you want to do is to stop the signal emission from one of the callbacks you connected yourself,
you can call <function>g_signal_stop_by_name</function>. Its use is very simple which is why I won't detail you can call <function><link linkend="g-signal-stop-by-name">g_signal_stop_by_name</link></function>. Its use is very simple which is why I won't detail
it further. it further.
</para> </para>
@@ -1640,12 +1639,12 @@ klass->write_signal_id =
which is why I won't bother to show exactly how to do it here again.</para> which is why I won't bother to show exactly how to do it here again.</para>
</sect2>
</sect1> </sect1>
</chapter>
<!-- <!--
<sect3> <sect2>
<title>Warning on signal creation and default closure</title> <title>Warning on signal creation and default closure</title>
<para> <para>
@@ -1655,10 +1654,10 @@ klass->write_signal_id =
</para> </para>
<para> <para>
Usually, the <function>g_signal_new</function> function is preferred over Usually, the <function><link linkend="g-signal-new">g_signal_new</link></function> function is preferred over
<function>g_signal_newv</function>. When <function>g_signal_new</function> <function><link linkend="g-signal-newv">g_signal_newv</link></function>. When <function><link linkend="g-signal-new">g_signal_new</link></function>
is used, the default closure is exported as a class function. For example, is used, the default closure is exported as a class function. For example,
<filename>gobject.h</filename> contains the declaration of <type>GObjectClass</type> <filename>gobject.h</filename> contains the declaration of <type><link linkend="GObjectClass">GObjectClass</link></type>
whose notify class function is the default handler for the <emphasis>notify</emphasis> whose notify class function is the default handler for the <emphasis>notify</emphasis>
signal: signal:
<programlisting> <programlisting>
@@ -1676,7 +1675,7 @@ struct _GObjectClass
</para> </para>
<para> <para>
<filename>gobject.c</filename>'s <function>g_object_do_class_init</function> function <filename>gobject.c</filename>'s <function><link linkend="g-object-do-class-init">g_object_do_class_init</link></function> function
registers the <emphasis>notify</emphasis> signal and initializes this class function registers the <emphasis>notify</emphasis> signal and initializes this class function
to NULL: to NULL:
<programlisting> <programlisting>
@@ -1699,7 +1698,7 @@ g_object_do_class_init (GObjectClass *class)
1, G_TYPE_PARAM); 1, G_TYPE_PARAM);
} }
</programlisting> </programlisting>
<function>g_signal_new</function> creates a <type>GClosure</type> which de-references the <function><link linkend="g-signal-new">g_signal_new</link></function> creates a <type><link linkend="GClosure">GClosure</link></type> which de-references the
type's class structure to access the class function pointer and invoke it if it not NULL. The type's class structure to access the class function pointer and invoke it if it not NULL. The
class function is ignored it is set to NULL. class function is ignored it is set to NULL.
</para> </para>
@@ -1721,20 +1720,13 @@ g_object_do_class_init (GObjectClass *class)
supposedly more efficient. supposedly more efficient.
</para> </para>
</sect3> </sect2>
--> -->
<!-- <!--
<sect1 id="howto-doc"> <capter1 id="howto-doc">
<title>How to generate API documentation for your type ?</title> <title>How to generate API documentation for your type ?</title>
</sect1>
-->
</chapter> </chapter>
-->

View File

@@ -1,5 +1,5 @@
<chapter> <chapter>
<title>Introduction</title> <title>Background</title>
<para> <para>
GObject, and its lower-level type system, GType, are used by GTK+ and most Gnome libraries to GObject, and its lower-level type system, GType, are used by GTK+ and most Gnome libraries to
@@ -18,7 +18,7 @@ the solution choosen by GLib.
</para> </para>
<para>The following chapters go into greater detail into how GType and GObject work and <para>The following chapters go into greater detail into how GType and GObject work and
how you can use them as a C programmer. I personally find it useful to keep in mind that how you can use them as a C programmer. It is useful to keep in mind that
allowing access to C objects from other interpreted languages was one of the major design allowing access to C objects from other interpreted languages was one of the major design
goals: this can often explain the sometimes rather convoluted APIs and features present goals: this can often explain the sometimes rather convoluted APIs and features present
in this library. in this library.

View File

@@ -1,35 +1,55 @@
<chapter id="tools"> <partintro>
<title>GObject related tools</title> <para>
Several useful developer tools have been build around GObject technology.
Next sections briefly introduce them and link to the respective project pages.
</para>
</partintro>
<sect1 id="tools-refdb"> <chapter id="tools-gob">
<title>Debugging reference count problems</title> <title>GObject builder</title>
<para> <para>
The reference counting scheme used by GObject does solve quite Writing gobjects can be a tedious task. It requires a lot of typing and just
a few memory management problems but also introduces new sources of bugs. doing copy and paste needs care. On obvious idea is to use some sort of
In large applications, finding the exact spot where a the reference count templates for the class skelletons. Then a tool could generate the real c
of an Object is not properly handled can be very difficult. Hopefully, files from them.
there exist at a too named <ulink url="http://refdbg.sf.net/">refdbg/</ulink> <ulink url="http://www.5z.com/jirka/gob.html">GOB/</ulink> (or GOB2) is suc
which can be used to automate the task of tracking down the location h a tool. It is a preprocessor for making GObjects with inline C code so
of invalid code with regard to reference counting. This application that generated files are not edited.
intercepts the reference counting calls and tries to detect invalid behavior. Syntax is inspired by Java and Yacc or Lex. The implementation is
It suports a filter-rule mechanism to let you trace only the objects you are intentionally kept simple, and no C actual code parsing is done.
interested in and it can be used together with gdb. </para>
</para> </chapter>
</sect1>
<sect1 id="tools-gtkdoc"> <chapter id="tools-refdb">
<title>Writing API docs</title> <title>Debugging reference count problems</title>
<para>The API documentation for most of the Glib, GObject, GTK+ and GNOME <para>
libraries is built with a combination of complex tools. Typically, the part of The reference counting scheme used by GObject does solve quite
the documentation which describes the behavior of each function is extracted a few memory management problems but also introduces new sources of bugs.
from the specially-formatted source code comments by a tool named gtk-doc which In large applications, finding the exact spot where a the reference count
generates docbook xml and merges this docbook xml with a set of master xml of an Object is not properly handled can be very difficult. Hopefully,
docbook files. These xml docbook files are finally processed with xsltproc there exist at a too named <ulink url="http://refdbg.sf.net/">refdbg/</ulink>
(a small program part of the libxslt library) to generate the final html which can be used to automate the task of tracking down the location
output. Other tools can be used to generate pdf output from the source xml. of invalid code with regard to reference counting. This application
The following code excerpt shows what these comments look like. intercepts the reference counting calls and tries to detect invalid behavior.
It suports a filter-rule mechanism to let you trace only the objects you are
interested in and it can be used together with gdb.
</para>
</chapter>
<chapter id="tools-gtkdoc">
<title>Writing API docs</title>
<para>The API documentation for most of the Glib, GObject, GTK+ and GNOME
libraries is built with a combination of complex tools. Typically, the part of
the documentation which describes the behavior of each function is extracted
from the specially-formatted source code comments by a tool named gtk-doc which
generates docbook xml and merges this docbook xml with a set of master xml
docbook files. These xml docbook files are finally processed with xsltproc
(a small program part of the libxslt library) to generate the final html
output. Other tools can be used to generate pdf output from the source xml.
The following code excerpt shows what these comments look like.
<programlisting> <programlisting>
/** /**
* gtk_widget_freeze_child_notify: * gtk_widget_freeze_child_notify:
@@ -45,14 +65,12 @@ gtk_widget_freeze_child_notify (GtkWidget *widget)
{ {
... ...
</programlisting> </programlisting>
</para> </para>
<para> <para>
The great thoroughful The great thoroughful
<ulink url="http://developer.gnome.org/arch/doc/authors.html">documentation</ulink> <ulink url="http://developer.gnome.org/arch/doc/authors.html">documentation</ulink>
on how to setup and use gtk-doc in your on how to setup and use gtk-doc in your
project is provided on the gnome developer website. project is provided on the gnome developer website.
gtk-doc generates gtk-doc generates
</para> </para>
</sect1>
</chapter> </chapter>