Documentation fixes. Recommend macro type names such as

2007-11-13  Cody Russell  <bratsche@gnome.org>

        * docs/reference/gobject/gobject-docs.sgml:
        * docs/reference/gobject/tut_gsignal.xml:
        * docs/reference/gobject/tut_gtype.xml:
        * docs/reference/gobject/tut_intro.xml:
        * docs/reference/gobject/tut_tools.xml:
        * docs/reference/gobject/tut_howto.xml:
        * docs/reference/gobject/tut_gobject.xml: Documentation fixes.
        Recommend macro type names such as NAUTILUS_TYPE_WINDOW (not
        NAUTILUS_WINDOW_TYPE).  Fixed text which erroneously stated that 
        superclass initializers don't run when an object is 
        instantiated.  Fixed numerous spelling mistakes.  Minor grammar 
        edits. (#490637, Adam Dingle)


svn path=/trunk/; revision=5857
This commit is contained in:
Cody Russell 2007-11-13 07:10:42 +00:00 committed by Cody Russell
parent 1d174f072b
commit 515f42c9ed
8 changed files with 139 additions and 132 deletions

View File

@ -1,3 +1,18 @@
2007-11-13 Cody Russell <bratsche@gnome.org>
* docs/reference/gobject/gobject-docs.sgml:
* docs/reference/gobject/tut_gsignal.xml:
* docs/reference/gobject/tut_gtype.xml:
* docs/reference/gobject/tut_intro.xml:
* docs/reference/gobject/tut_tools.xml:
* docs/reference/gobject/tut_howto.xml:
* docs/reference/gobject/tut_gobject.xml: Documentation fixes.
Recommend macro type names such as NAUTILUS_TYPE_WINDOW (not
NAUTILUS_WINDOW_TYPE). Fixed text which erroneously stated that
superclass initializers don't run when an object is
instantiated. Fixed numerous spelling mistakes. Minor grammar
edits. (#490637, Adam Dingle)
2007-11-09 Matthias Clasen <mclasen@redhat.com>
* glib/gkeyfile.c: Coding style cleanups and doc

View File

@ -42,7 +42,7 @@
types and algorithms (linked lists, hash tables and so forth), the
GLib Object System provides the required implementations of a
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:
<itemizedlist>
<listitem><para>

View File

@ -3,7 +3,7 @@
<title>The GObject base class</title>
<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
for a base fundamental type named <type><link linkend="GObject">GObject</link></type>.
</para>
@ -16,13 +16,13 @@
<listitem><para>Generic per-object properties with set/get function pairs</para></listitem>
<listitem><para>Easy use of signals</para></listitem>
</itemizedlist>
All the GNOME libraries which use the GLib type system (like Gtk+ and GStreamer)
All the GNOME libraries which use the GLib type system (like GTK+ and GStreamer)
inherit from <type><link linkend="GObject">GObject</link></type> which is why it is important to understand
the details of how it works.
</para>
<sect1 id="gobject-instanciation">
<title>Object instanciation</title>
<sect1 id="gobject-instantiation">
<title>Object instantiation</title>
<para>
The <function><link linkend="g-object-new">g_object_new</link></function> family of functions can be used to instantiate any
@ -162,7 +162,7 @@ MamanBar *bar = g_object_new (MAMAN_TYPE_BAR, NULL);
is how we can find the parent constructor. An approach (used in GTK+ source code) would be
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 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 preferred way is to use the
<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>
@ -174,7 +174,7 @@ MamanBar *bar = g_object_new (MAMAN_TYPE_BAR, NULL);
was registered. After instance_init returns, the object is fully initialized and should be
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
(ie: the properties which were given to <function><link linkend="g-object-new">g_object_new</link></function>) and returns
(i.e. 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...
</para>
@ -325,7 +325,7 @@ void g_object_run_dispose (GObject *object);
increase and decrease the reference count.These functions are thread-safe as of GLib 2.8.
The reference count is, unsurprisingly, initialized to one by
<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 currently the sole owner of the newly-created reference.
When the reference count reaches zero, that is,
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
@ -515,7 +515,7 @@ void g_object_run_dispose (GObject *object);
<para>
One of GObject's nice features is its generic get/set mechanism for object
properties. When an object
is instanciated, the object's class_init handler should be used to register
is instantiated, the object's class_init handler should be used to register
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>).
</para>
@ -657,7 +657,7 @@ g_object_set_property (G_OBJECT (bar), "papa-number", &amp;val);
relying on these transformations.
</para>
</footnote>
which matches and conversion will be caried out if needed.
which matches and conversion will be carried out if needed.
</para>
<para>
@ -704,12 +704,12 @@ g_object_set_property (G_OBJECT (bar), "papa-number", &amp;val);
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"
signal will be emitted once for each of these changed properties as soon as the property
change notification is thawn: no property change is lost for the "notify" signal. Signal
change notification is thawed: no property change is lost for the "notify" signal. Signal
can only be delayed by the notification freezing mechanism.
</para>
<para>
It sounds like a tedious task to set up GValues everytime when one wants to modify a property.
It sounds like a tedious task to set up GValues every time when one wants to modify a property.
In practice one will rarely do this. The functions <function><link linkend="g-object-set-property">g_object_set_property</link></function>
and <function><link linkend="g-object-get-property">g_object_get_property</link></function>
are meant to be used by language bindings. For application there is an easier way and
@ -760,7 +760,7 @@ g_object_set (G_OBJECT (foo),
</sect2>
<!-- @todo tell here about how to pass use handle properties in derived classe -->
<!-- @todo tell here about how to pass use handle properties in derived classes -->
</sect1>

View File

@ -7,7 +7,7 @@
<para>
Closures are central to the concept of asynchronous signal delivery
which is widely used throughout GTK+ and GNOME applications. A Closure is an
which is widely used throughout GTK+ and GNOME applications. A closure is an
abstraction, a generic representation of a callback. It is a small structure
which contains three objects:
<itemizedlist>
@ -32,12 +32,12 @@ return_type function_callback (... , gpointer user_data);
closure implementations: there exists a different Closure implementation for
each separate runtime which wants to use the GObject type system.
<footnote><para>
In Practice, Closures sit at the boundary of language runtimes: if you are
writing python code and one of your Python callback receives a signal from
one of GTK+ widgets, the C code in GTK+ needs to execute your Python
code. The Closure invoked by the GTK+ object invokes the Python callback:
In practice, closures sit at the boundary of language runtimes: if you are
writing Python code and one of your Python callbacks receives a signal from
a GTK+ widget, the C code in GTK+ needs to execute your Python
code. The closure invoked by the GTK+ object invokes the Python callback:
it behaves as a normal C object for GTK+ and as a normal Python object for
python code.
Python code.
</para></footnote>
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.
@ -48,7 +48,7 @@ return_type function_callback (... , gpointer user_data);
<listitem><para>
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
callback invocator.</para>
callback invoker.</para>
</listitem>
<listitem><para>
Notification: the closure notifies listeners of certain events such as
@ -57,12 +57,12 @@ return_type function_callback (... , gpointer user_data);
(finalization notification), <function><link linkend="g-closure-add-invalidate-notifier">g_closure_add_invalidate_notifier</link></function>
(invalidation notification) and
<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 deregistration functions for finalization and invalidation
events (<function><link linkend="g-closure-remove-finalize-notifier">g_closure_remove_finalize_notifier</link></function> and
<function><link linkend="g-closure-remove-invalidate-notifier">g_closure_remove_invalidate_notifier</link></function>) but not for the invocation
process.
<footnote><para>
Closures are refcounted and notify listeners of their destruction in a two-stage
Closures are reference counted and notify listeners of their destruction in a two-stage
process: the invalidation notifiers are invoked before the finalization notifiers.
</para></footnote></para>
</listitem>
@ -74,7 +74,7 @@ return_type function_callback (... , gpointer user_data);
<para>
If you are using C or C++
to connect a callback to a given event, you will either use the simple <type><link linkend="GCClosure">GCClosure</link></type>s
to connect a callback to a given event, you will either use simple <type><link linkend="GCClosure">GCClosure</link></type>s
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 :).
<programlisting>
@ -106,10 +106,10 @@ GClosure* g_signal_type_cclosure_new (GType itype,
</sect2>
<sect2>
<title>non-C closures (for the fearless).</title>
<title>Non-C closures (for the fearless)</title>
<para>
As was explained above, Closures hide the details of callback invocation. In C,
As was explained above, closures hide the details of callback invocation. In C,
callback invocation is just like function invocation: it is a matter of creating
the correct stack frame for the called function and executing a <emphasis>call</emphasis>
assembly instruction.
@ -156,12 +156,12 @@ g_cclosure_marshal_VOID__INT (GClosure *closure,
<para>
Of course, there exist other kinds of marshallers. For example, James Henstridge
wrote a generic Python marshaller which is used by all python Closures (a python closure
is used to have python-based callback be invoked by the closure invocation process).
This python marshaller transforms the input GValue list representing the function
parameters into a Python tuple which is the equivalent structure in python (you can
wrote a generic Python marshaller which is used by all Python closures (a Python closure
is used to have Python-based callback be invoked by the closure invocation process).
This Python marshaller transforms the input GValue list representing the function
parameters into a Python tuple which is the equivalent structure in Python (you can
look in <function>pyg_closure_marshal</function> in <filename>pygtype.c</filename>
in the <emphasis>pygobject</emphasis> module in GNOME cvs server).
in the <emphasis>pygobject</emphasis> module in the GNOME Subversion server).
</para>
</sect2>

View File

@ -1,9 +1,9 @@
<?xml version='1.0' encoding="ISO-8859-1"?>
<chapter id="chapter-gtype">
<title>The Glib Dynamic Type System</title>
<title>The GLib Dynamic Type System</title>
<para>
A type, as manipulated by the Glib type system, is much more generic than what
A type, as manipulated by the GLib type system, is much more generic than what
is usually understood as an Object type. It is best explained by looking at the
structure and the functions used to register new types in the type system.
<programlisting>
@ -53,7 +53,7 @@ GType g_type_register_fundamental (GType type_id,
new fundamental types.
<footnote>
<para>
Please, note that there exist another registration function: the
Please note that there exists another registration function: the
<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>
version.
@ -71,7 +71,7 @@ GType g_type_register_fundamental (GType type_id,
</para>
<para>
Fundamental and non-Fundamental types are defined by:
Fundamental and non-fundamental types are defined by:
<itemizedlist>
<listitem><para>
class size: the class_size field in <type><link linkend="GTypeInfo">GTypeInfo</link></type>.
@ -89,7 +89,7 @@ GType g_type_register_fundamental (GType type_id,
<type><link linkend="GTypeInfo">GTypeInfo</link></type>.
</para></listitem>
<listitem><para>
instanciation policy (C++ type of new operator): the n_preallocs
instantiation policy (C++ type of new operator): the n_preallocs
field in <type><link linkend="GTypeInfo">GTypeInfo</link></type>.
</para></listitem>
<listitem><para>
@ -102,7 +102,7 @@ GType g_type_register_fundamental (GType type_id,
</itemizedlist>
Fundamental types are also defined by a set of <type><link linkend="GTypeFundamentalFlags">GTypeFundamentalFlags</link></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><link linkend="g-type-register-static">g_type_register_static</link></function>
and <function><link linkend="g-type-register-dynamic">g_type_register_dynamic</link></function>.
</para>
@ -111,7 +111,7 @@ GType g_type_register_fundamental (GType type_id,
<title>Copy functions</title>
<para>
The major common point between <emphasis>all</emphasis> glib types (fundamental and
The major common point between <emphasis>all</emphasis> GLib types (fundamental and
non-fundamental, classed and non-classed, instantiable and non-instantiable) is that
they can all be manipulated through a single API to copy/assign them.
</para>
@ -177,7 +177,7 @@ static void test_object (void)
g_object_unref (G_OBJECT (obj));
}
</programlisting>
The important point about the above code is that the exact semantic of the copy calls
The important point about the above code is that the exact semantics of the copy calls
is undefined since they depend on the implementation of the copy function. Certain
copy functions might decide to allocate a new chunk of memory and then to copy the
data from the source to the destination. Others might want to simply increment
@ -215,7 +215,7 @@ struct _GTypeValueTable
you will ever need to specify a value_table during type registration
because these value_tables are inherited from the parent types for
non-fundamental types which means that unless you want to write a
fundamental type (not a great idea !), you will not need to provide
fundamental type (not a great idea!), you will not need to provide
a new value_table since you will inherit the value_table structure
from your parent type.
</para>
@ -238,7 +238,7 @@ struct _GTypeValueTable
If your library (or application) is named <emphasis>Maman</emphasis>,
<footnote>
<para>
<emphasis>Maman</emphasis> is the french word for <emphasis>mum</emphasis>
<emphasis>Maman</emphasis> is the French word for <emphasis>mum</emphasis>
or <emphasis>mother</emphasis> - nothing more and nothing less.
</para>
</footnote>
@ -329,7 +329,7 @@ G_DEFINE_TYPE (MamanBar, maman_bar, G_TYPE_OBJECT)
</sect1>
<sect1 id="gtype-non-instantiable">
<title>Non-Instantiable non-classed fundamental types</title>
<title>Non-instantiable non-classed fundamental types</title>
<para>
A lot of types are not instantiable by the type system and do not have
@ -372,7 +372,7 @@ G_DEFINE_TYPE (MamanBar, maman_bar, G_TYPE_OBJECT)
<para>
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 instantiate an instance of that type ? Most of these types
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
type's value_table. <type><link linkend="GValue">GValue</link></type>s (and by extension these trivial fundamental
@ -390,7 +390,7 @@ G_DEFINE_TYPE (MamanBar, maman_bar, G_TYPE_OBJECT)
Although <type><link linkend="GObject">GObject</link></type>s (detailed in <xref linkend="chapter-gobject"/>)
are the most well known type of instantiable
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 developed and they are all built on the fundamental
features described below.
</para>
@ -515,14 +515,14 @@ B *b;
<title>Initialization and Destruction</title>
<para>
Instanciation of these types can be done with
instantiation of these types can be done with
<function><link linkend="g-type-create-instance">g_type_create_instance</link></function>:
<programlisting>
GTypeInstance* g_type_create_instance (GType type);
void g_type_free_instance (GTypeInstance *instance);
</programlisting>
<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
<function><link linkend="g-type-create-instance">g_type_create_instance</link></function> will look up the type information
structure associated to the type requested. Then, the instance size and instantiation
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)
declared by the user are used to get a buffer to hold the object's instance
@ -569,7 +569,7 @@ void g_type_free_instance (GTypeInstance *instance);
(in <filename>gtype.c</filename>.
</para>
</footnote>
(the concept of destruction is sometimes partly refered to as finalization
(the concept of destruction is sometimes partly referred to as finalization
in GType) is the symmetric process of the initialization: interfaces are
destroyed first.
Then, the most derived
@ -581,27 +581,19 @@ void g_type_free_instance (GTypeInstance *instance);
<para>
As many readers have now understood it, the base initialization/finalization process is
very similar to the C++ Constructor/Destructor paradigm. The practical details are quite different
though and it is important not to get confused by the superficial similarities. Typically, what
most users have grown to know as a C++ constructor (that is, a list of
object methods invoked on the object instance once for each type of the inheritance hierachy) does
not exist in GType and must be built on top of the facilities offered by GType. Similarly,
very similar to the C++ constructor/destructor paradigm. The practical details are different
though and it is important not to get confused by superficial similarities.
GTypes have no instance destruction mechanism. It is
the user's responsibility to implement correct destruction semantics on top
of the existing GType code. (this is what GObject does. See
<xref linkend="chapter-gobject"/>)
</para>
<para>
For example, if the object B which derives from A is instantiated, GType will only invoke the
instance_init callback of object B while a C++ runtime will invoke the constructor of the object
type A first and then of the object type B. Furthermore, the C++ code equivalent to the base_init
Furthermore, C++ code equivalent to the base_init
and class_init callbacks of GType is usually not needed because C++ cannot really create object
types at runtime.
</para>
<para>
The instanciation/finalization process can be summarized as follows:
The instantiation/finalization process can be summarized as follows:
<table id="gtype-init-fini-table">
<title>GType Instantiation/Finalization</title>
<tgroup cols="3">
@ -666,15 +658,15 @@ void g_type_free_instance (GTypeInstance *instance);
</sect1>
<sect1 id="gtype-non-instantiable-classed">
<title>Non-instantiable classed types: Interfaces.</title>
<title>Non-instantiable classed types: interfaces</title>
<para>
GType's Interfaces are very similar to Java's interfaces. They allow
GType's interfaces are very similar to Java's interfaces. They allow
to describe a common API that several classes will adhere to.
Imagine the play, pause and stop buttons on hifi equipment - those can
be seen as a playback interface. Once you know what the do, you can
control your cd-player, mp3-player or anything that uses these symbols.
To declare an interfacce you have to register a non-instantiable
Imagine the play, pause and stop buttons on hi-fi equipment - those can
be seen as a playback interface. Once you know what they do, you can
control your CD player, MP3 player or anything that uses these symbols.
To declare an interface you have to register a non-instantiable
classed type which derives from
<type><link linkend="GTypeInterface">GTypeInterface</link></type>. The following piece of code declares such an interface.
<programlisting>
@ -886,7 +878,7 @@ maman_ibaz_base_init (gpointer g_iface)
</tbody>
</tgroup>
</table>
It is highly unlikely (ie: I do not know of <emphasis>anyone</emphasis> who actually
It is highly unlikely (i.e. I do not know of <emphasis>anyone</emphasis> who actually
used it) you will ever need other more fancy things such as the ones described in the
following section (<xref linkend="gtype-non-instantiable-classed-dest"/>).
</para>

View File

@ -2,20 +2,20 @@
<partintro>
<para>
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 use-cases are presented from most likely to less likely.
the most common scenario use cases I could come up with.
The use cases are presented from most likely to less likely.
</para>
</partintro>
<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>
Clearly, this is one of the most common question people ask: they just want to crank code and
Clearly, this is one of the most common questions people ask: they just want to crank code and
implement a subclass of a GObject. Sometimes because they want to create their own class hierarchy,
sometimes because they want to subclass one of GTK+'s widget. This chapter will focus on the
implementation of a subtype of GObject. The sample source code
associated to this section can be found in the documentation's source tarball, in the
associated with this section can be found in the documentation's source tarball, in the
<filename>sample/gobject</filename> directory:
<itemizedlist>
<listitem><para><filename>maman-bar.{h|c}</filename>: this is the source for a object which derives from
@ -42,7 +42,7 @@
which is followed not only by GTK+'s code but also by most users of GObject. If you feel the need
not to obey the rules stated below, think about it twice:
<itemizedlist>
<listitem><para>If your users are a bit accustomed to GTK+ code or any Glib code, they will
<listitem><para>If your users are a bit accustomed to GTK+ code or any GLib code, they will
be a bit surprised and getting used to the conventions you decided upon will take time (money) and
will make them grumpy (not a good thing)
</para></listitem>
@ -84,7 +84,7 @@
<para>
The basic conventions for any header which exposes a GType are described in
<xref linkend="gtype-conventions"/>. Most GObject-based code also obeys onf of the following
<xref linkend="gtype-conventions"/>. Most GObject-based code also obeys one of of the following
conventions: pick one and stick to it.
<itemizedlist>
<listitem><para>
@ -121,7 +121,7 @@ struct _MamanBarClass {
/* class members */
};
/* used by MAMAN_BAR_TYPE */
/* used by MAMAN_TYPE_BAR */
GType maman_bar_get_type (void);
/*
@ -181,13 +181,13 @@ maman_bar_init (GTypeInstance *instance, gpointer g_class) {
</para></listitem>
<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>maman_bar_class_init</function> using
<function><link linkend="g-type-class-add-private">g_type_class_add_private</link></function>.
Instead of allocating memory in <function>maman_bar_init</function> a pointer to the private memory area is
stored in the instance to allow convenient access to this structure.
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 don't need to free or allocate the private structure, only the objects or pointers that it may contain.
Another advantage of this to the previous version is that is lessens memory fragmentation,
as the public and private parts of the instance memory are allocated at once.
<programlisting>
@ -208,7 +208,7 @@ maman_bar_class_init (MamanBarClass *klass)
static void
maman_bar_init (GTypeInstance *instance, gpointer g_class) {
MamanBar *self = MAMAN_BAR (instance);
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, MAMAN_BAR_TYPE, MamanBarPrivate);
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, MAMAN_TYPE_BAR, MamanBarPrivate);
/* do stuff */
}
</programlisting>
@ -308,7 +308,7 @@ maman_bar_get_type (void)
<para>
<xref linkend="gobject-construction-table"/> shows what user-provided functions
are invoked during object instanciation and in which order they are invoked.
are invoked during object instantiation and in which order they are invoked.
A user looking for the equivalent of the simple C++ constructor function should use
the instance_init method. It will be invoked after all the parent's instance_init
functions have been invoked. It cannot take arbitrary construction parameters
@ -333,7 +333,7 @@ maman_bar_init (GTypeInstance *instance,
self->private = g_new0 (MamanBarPrivate, 1);
/* initialize all public and private members to reasonable default values. */
/* If you need specific consruction properties to complete initialization,
/* If you need specific construction properties to complete initialization,
* delay initialization completion until the property is set.
*/
}
@ -386,7 +386,7 @@ bar_class_init (MamanBarClass *klass)
<para>Some people sometimes need to construct their object but only after the construction properties
have been set. This is possible through the use of the constructor class method as described in
<xref linkend="gobject-instanciation"/>. However, I have yet to see <emphasis>any</emphasis> reasonable
<xref linkend="gobject-instantiation"/>. However, I have yet to see <emphasis>any</emphasis> reasonable
use of this feature. As such, to initialize your object instances, use by default the base_init function
and construction properties.
</para>
@ -685,21 +685,21 @@ maman_bar_subtype_class_init (MamanBarSubTypeClass *klass)
<itemizedlist>
<listitem><para>You need to change the behaviour of a class without modifying its code. You create
a subclass to inherit its implementation, re-implement a public virtual method to modify the behaviour
slightly and chain up to ensure that the previous behaviour is not really modifed, just extended.
slightly and chain up to ensure that the previous behaviour is not really modified, just extended.
</para></listitem>
<listitem><para>You are lazy, you have access to the source code of the parent class but you don't want
to modify it to add method calls to new specialized method calls: it is faster to hack the child class
to chain up than to modify the parent to call down.</para></listitem>
<listitem><para>You need to implement the Chain Of Responsability pattern: each object of the inheritance
tree chains up to its parent (typically, at the begining or the end of the method) to ensure that
<listitem><para>You need to implement the Chain Of Responsibility pattern: each object of the inheritance
tree chains up to its parent (typically, at the beginning or the end of the method) to ensure that
they each handler is run in turn.</para></listitem>
</itemizedlist>
I am personally not really convinced any of the last two uses are really a good idea but since this
programming idiom is often used, this section attemps to explain how to implement it.
programming idiom is often used, this section attempts to explain how to implement it.
</para>
<para>
To explicitely chain up to the implementation of the virtual method in the parent class,
To explicitly chain up to the implementation of the virtual method in the parent class,
you first need a handle to the original parent class structure. This pointer can then be used to
access the original class function pointer and invoke it directly.
<footnote>
@ -746,10 +746,10 @@ b_method_to_call (B *obj, int a)
<chapter id="howto-interface">
<title>How To define and implement Interfaces?</title>
<title>How to define and implement interfaces</title>
<sect1 id="howto-interface-define">
<title>How To define Interfaces?</title>
<title>How to define interfaces</title>
<para>
The bulk of interface definition has already been shown in <xref linkend="gtype-non-instantiable-classed"/>
@ -814,7 +814,7 @@ void maman_ibaz_do_action (MamanIbaz *self);
to make sure not to run the initialization code twice (as described in
<xref linkend="gtype-non-instantiable-classed-init"/>,
<function>base_init</function> is run once for each interface implementation
instanciation)</para></listitem>
instantiation)</para></listitem>
<listitem><para><function>maman_ibaz_do_action</function> dereferences the class
structure to access its associated class function and calls it.
</para></listitem>
@ -1089,7 +1089,7 @@ maman_bar_get_type (void)
<title>Interface Properties</title>
<para>
Starting from version 2.4 of glib, GObject interfaces can also have properties.
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
ordinary GObject types as explained in <xref linkend="gobject-properties"/>,
except that <function><link linkend="g-object-interface-install-property">g_object_interface_install_property</link></function> is used to
@ -1135,7 +1135,7 @@ maman_ibaz_base_init (gpointer g_iface)
<para>
One point worth noting is that the declared property wasn't assigned an
integer ID. The reason being that integer IDs of properities are utilized only
integer ID. The reason being that integer IDs of properties are utilized only
inside the get and set methods and since interfaces do not implement properties,
there is no need to assign integer IDs to interface properties.
</para>
@ -1146,7 +1146,7 @@ maman_ibaz_base_init (gpointer g_iface)
explained in <xref linkend="gobject-properties"/>, except for one small
change: it shall declare the properties of the interface it implements using
<function><link linkend="g-object-class-override-property">g_object_class_override_property</link></function> instead of
<function><link linkend="g-object-class-install-property">g_object_class_install_property</link></function>. The following code snipet
<function><link linkend="g-object-class-install-property">g_object_class_install_property</link></function>. The following code snippet
shows the modifications needed in the <type>MamanBaz</type> declaration and
implementation above:
<programlisting>
@ -1260,14 +1260,14 @@ maman_baz_get_property (GObject * object, guint prop_id,
<!-- End Howto Interfaces -->
<chapter id="howto-signals">
<title>Howto create and use signals</title>
<title>How to create and use signals</title>
<para>
The signal system which was built in GType is pretty complex and flexible: it is possible for its users
to connect at runtime any number of callbacks (implemented in any language for which a binding exists)
<footnote>
<para>A python callback can be connected to any signal on any C-based GObject.
<para>A Python callback can be connected to any signal on any C-based GObject.
</para>
</footnote>
@ -1311,7 +1311,7 @@ klass->write_signal_id =
0 /* n_params */,
NULL /* param_types */);
</programlisting>
and the signal is emited in <function>maman_file_write</function>:
and the signal is emitted in <function>maman_file_write</function>:
<programlisting>
void maman_file_write (MamanFile *self, guint8 *buffer, guint32 size)
{
@ -1330,7 +1330,7 @@ void maman_file_write (MamanFile *self, guint8 *buffer, guint32 size)
The signature of the signal handler in the above example is defined as
<function>g_cclosure_marshal_VOID__VOID</function>. Its name follows
a simple convention which encodes the function parameter and return value
types in the function name. Specifically, the value infront of the double
types in the function name. Specifically, the value in front of the double
underscore is the type of the return value, while the value(s) after the
double underscore denote the parameter types.
The header <filename>gobject/gmarshal.h</filename> defines a set of commonly
@ -1357,7 +1357,7 @@ void maman_file_write (MamanFile *self, guint8 *buffer, guint32 size)
<para>
The first step to implement this idea is to change the signature of the signal: we need to pass
around the buffer to write and its size. To do this, we use our own marshaller which will be generated
through glib's genmarshall tool. We thus create a file named <filename>marshall.list</filename> which contains
through GLib's genmarshall tool. We thus create a file named <filename>marshall.list</filename> which contains
the following single line:
<programlisting>
VOID:POINTER,UINT
@ -1488,11 +1488,11 @@ Complex Write event after: 0xbfffe280, 50
there is a much <emphasis>simpler</emphasis>
<footnote>
<para>I personally think that this method is horribly mind-twisting: it adds a new indirection
which unecessarily complicates the overall code path. However, because this method is widely used
which unnecessarily complicates the overall code path. However, because this method is widely used
by all of GTK+ and GObject code, readers need to understand it. The reason why this is done that way
in most of GTK+ is related to the fact that the ancestor of GObject did not provide any other way to
create a signal with a default handler than this one. Some people have tried to justify that it is done
that way because it is better, faster (I am extremly doubtfull about the faster bit. As a matter of fact,
that way because it is better, faster (I am extremely doubtful about the faster bit. As a matter of fact,
the better bit also mystifies me ;-). I have the feeling no one really knows and everyone does it
because they copy/pasted code from code which did the same. It is probably better to leave this
specific trivia to hacker legends domain...
@ -1527,7 +1527,7 @@ struct _MamanFileSimpleClass {
void (*write) (MamanFileSimple *self, guint8 *buffer, guint size);
};
</programlisting>
The <function>write</function> function pointer is initialied in the class_init function of the object
The <function>write</function> function pointer is initialized in the class_init function of the object
to <function>default_write_signal_handler</function>:
<programlisting>
static void
@ -1565,7 +1565,7 @@ klass->write_signal_id =
</para>
<para>
While the complete code for this type of default handler looks less clutered as shown in
While the complete code for this type of default handler looks less cluttered as shown in
<filename>sample/signal/maman-file-simple.{h|c}</filename>, it contains numerous subtleties.
The main subtle point which everyone must be aware of is that the signature of the default
handler created that way does not have a user_data argument:
@ -1600,7 +1600,7 @@ klass->write_signal_id =
<itemizedlist>
<listitem><para>stop the emission of the signal at anytime</para></listitem>
<listitem><para>override the default handler of the signal if it is stored as a function
pointer in the class structure (which is the prefered way to create a default signal handler,
pointer in the class structure (which is the preferred way to create a default signal handler,
as discussed in the previous section).</para></listitem>
</itemizedlist>
</para>

View File

@ -13,10 +13,10 @@
</para>
<para>
A lot of programmers are used to work with compiled-only or dynamically interpreted-only
A lot of programmers are used to working with compiled-only or dynamically interpreted-only
languages and do not understand the challenges associated with cross-language interoperability.
This introduction tries to provide an insight into these challenges. describes briefly
the solution choosen by GLib.
This introduction tries to provide an insight into these challenges and briefly describes
the solution chosen by GLib.
</para>
<para>
@ -47,7 +47,7 @@
</para>
<para>
Perl and Python which are interpreted languages do not really provide type definitions similar
Perl and Python are interpreted languages which do not really provide type definitions similar
to those used by C. Perl and Python programmers manipulate variables and the type of the variables
is decided only upon the first assignment or upon the first use which forces a type on the variable.
The interpreter also often provides a lot of automatic conversions from one type to the other. For example,
@ -57,7 +57,7 @@
my $tmp = 10;
print "this is an integer converted to a string:" . $tmp . "\n";
</programlisting>
Of course, it is also often possible to explicitely specify conversions when the default conversions provided
Of course, it is also often possible to explicitly specify conversions when the default conversions provided
by the language are not intuitive.
</para>
@ -79,12 +79,12 @@ print "this is an integer converted to a string:" . $tmp . "\n";
function calling convention and the mapping of the C types to the machine types used by the platform you
are on, you can resolve the name of each function to find where the code associated to this function
is located in memory, and then construct a valid argument list for the function. Finally, all you have to
do is triger a call to the target C function with the argument list.
do is trigger a call to the target C function with the argument list.
</para>
<para>
For the sake of discussion, here is a sample C function and the associated 32 bit x86
assembly code generated by gcc on my linux box:
assembly code generated by GCC on my Linux box:
<programlisting>
static void function_foo (int foo)
{}
@ -101,35 +101,35 @@ push $0xa
call 0x80482f4 &lt;function_foo>
</programlisting>
The assembly code shown above is pretty straightforward: the first instruction pushes
the hexadecimal value 0xa (decimal value 10) as a 32 bit integer on the stack and calls
the hexadecimal value 0xa (decimal value 10) as a 32-bit integer on the stack and calls
<function>function_foo</function>. As you can see, C function calls are implemented by
gcc by native function calls (this is probably the fastest implementation possible).
</para>
<para>
Now, let's say we want to call the C function <function>function_foo</function> from
a python program. To do this, the python interpreter needs to:
a Python program. To do this, the Python interpreter needs to:
<itemizedlist>
<listitem><para>Find where the function is located. This means probably find the binary generated by the C compiler
which exports this functions.</para></listitem>
<listitem><para>Find where the function is located. This probably means finding the binary generated by the C compiler
which exports this function.</para></listitem>
<listitem><para>Load the code of the function in executable memory.</para></listitem>
<listitem><para>Convert the python parameters to C-compatible parameters before calling
<listitem><para>Convert the Python parameters to C-compatible parameters before calling
the function.</para></listitem>
<listitem><para>Call the function with the right calling convention</para></listitem>
<listitem><para>Convert the return values of the C function to python-compatible
variables to return them to the python code.</para></listitem>
<listitem><para>Call the function with the right calling convention.</para></listitem>
<listitem><para>Convert the return values of the C function to Python-compatible
variables to return them to the Python code.</para></listitem>
</itemizedlist>
</para>
<para>
The process described above is pretty complex and there are a lot of ways to make it entirely automatic
and transparent to the C and the Python programmers:
and transparent to C and Python programmers:
<itemizedlist>
<listitem><para>The first solution is to write by hand a lot of glue code, once for each function exported or imported,
which does the python to C parameter conversion and the C to python return value conversion. This glue code is then
linked with the interpreter which allows python programs to call a python functions which delegates the work to the
C function.</para></listitem>
<listitem><para>Another nicer solution is to automatically generate the glue code, once for each function exported or
which does the Python-to-C parameter conversion and the C-to-Python return value conversion. This glue code is then
linked with the interpreter which allows Python programs to call Python functions which delegate work to
C functions.</para></listitem>
<listitem><para>Another, nicer solution is to automatically generate the glue code, once for each function exported or
imported, with a special compiler which
reads the original function signature.</para></listitem>
<listitem><para>The solution used by GLib is to use the GType library which holds at runtime a description of

View File

@ -30,7 +30,7 @@
Yet another tool that you may find helpful when working with
GObjects is <ulink
url="http://sourceforge.net/projects/g-inspector">G-Inspector</ulink>. It
is able to display Glib/Gtk+ objects and their properties.
is able to display GLib/GTK+ objects and their properties.
</para>
</chapter>
@ -47,8 +47,8 @@
which can be used to automate the task of tracking down the location
of invalid code with regard to reference counting. This application
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.
It supports a filter-rule mechanism to let you trace only the objects you are
interested in and it can be used together with GDB.
</para>
<para>
<indexterm><primary>g_trap_object_ref</primary></indexterm>
@ -66,14 +66,14 @@ static volatile GObject *g_trap_object_ref;
<chapter id="tools-gtkdoc">
<title>Writing API docs</title>
<para>The API documentation for most of the Glib, GObject, GTK+ and GNOME
<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.
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>
/**
@ -92,9 +92,9 @@ gtk_widget_freeze_child_notify (GtkWidget *widget)
</programlisting>
</para>
<para>
The great thoroughful
Thorough
<ulink url="http://developer.gnome.org/arch/doc/authors.html">documentation</ulink>
on how to setup and use gtk-doc in your
project is provided on the gnome developer website.
on how to set up and use gtk-doc in your
project is provided on the GNOME developer website.
</para>
</chapter>