glib r7201 - in trunk/docs/reference: . gobject



Author: matthiasc
Date: Fri Jul 18 17:55:13 2008
New Revision: 7201
URL: http://svn.gnome.org/viewvc/glib?rev=7201&view=rev

Log:
Updates


Modified:
   trunk/docs/reference/ChangeLog
   trunk/docs/reference/gobject/tut_gobject.xml
   trunk/docs/reference/gobject/tut_gsignal.xml
   trunk/docs/reference/gobject/tut_gtype.xml
   trunk/docs/reference/gobject/tut_howto.xml

Modified: trunk/docs/reference/gobject/tut_gobject.xml
==============================================================================
--- trunk/docs/reference/gobject/tut_gobject.xml	(original)
+++ trunk/docs/reference/gobject/tut_gobject.xml	Fri Jul 18 17:55:13 2008
@@ -25,29 +25,33 @@
     <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
-      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
-      then invoke at one point or another the constructor class method which is used to:
+      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 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:
       <itemizedlist>
         <listitem><para>
             Allocate and clear memory through <function><link linkend="g-type-create-instance">g_type_create_instance</link></function>,
           </para></listitem>
         <listitem><para>
-            Initialize the object' instance with the construction properties.
+            Initialize the object's instance with the construction properties.
           </para></listitem>
       </itemizedlist>
      Although one can expect all class and instance members (except the fields
-     pointing to the parents) to be set to zero, some consider it good practice to explicitly set them.
+     pointing to the parents) to be set to zero, some consider it good practice
+     to explicitly set them.
     </para>
 
     <para>
-      Objects which inherit from GObject are allowed to override this constructor class method:
-      they should however chain to their parent constructor method before doing so:
+      Objects which inherit from GObject are allowed to override this
+      constructor class method: they should however chain to their parent
+      constructor method before doing so:
 <programlisting>
-  GObject*   (*constructor)     (GType                  type,
-                                 guint                  n_construct_properties,
-                                 GObjectConstructParam *construct_properties);
+  GObject *(* constructor) (GType                  gtype,
+                            guint                  n_properties,
+                            GObjectConstructParam *properties);
 </programlisting>
     </para>
 
@@ -56,101 +60,79 @@
 <programlisting>
 #define MAMAN_TYPE_BAR                  (maman_bar_get_type ())
 #define MAMAN_BAR(obj)                  (G_TYPE_CHECK_INSTANCE_CAST ((obj), MAMAN_TYPE_BAR, MamanBar))
+#define MAMAN_IS_BAR(obj)               (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MAMAN_TYPE_BAR))
 #define MAMAN_BAR_CLASS(klass)          (G_TYPE_CHECK_CLASS_CAST ((klass), MAMAN_TYPE_BAR, MamanBarClass))
-#define MAMAN_IS_BAR(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MAMAN_TYPE_BAR))
-#define MAMAN_IS_BAR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MAMAN_TYPE_BAR))
-#define MAMAN_BAR_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), MAMAN_TYPE_BAR, MamanBarClass))
+#define MAMAN_IS_BAR_CLASS(klass)       (G_TYPE_CHECK_CLASS_TYPE ((klass), MAMAN_TYPE_BAR))
+#define MAMAN_BAR_GET_CLASS(obj)        (G_TYPE_INSTANCE_GET_CLASS ((obj), MAMAN_TYPE_BAR, MamanBarClass))
 
-typedef struct _MamanBar MamanBar;
-typedef struct _MamanBarClass MamanBarClass;
+typedef struct _MamanBar        MamanBar;
+typedef struct _MamanBarClass   MamanBarClass;
+
+struct _MamanBar
+{
+  GObject parent_instance;
 
-struct _MamanBar {
-  GObject parent;
   /* instance members */
 };
 
-struct _MamanBarClass {
-  GObjectClass parent;
+struct _MamanBarClass
+{
+  GObjectClass parent_class;
 
   /* class members */
 };
 
-/* used by MAMAN_TYPE_BAR */
-GType maman_bar_get_type (void);
+/* will create maman_bar_get_type and set maman_bar_parent_class */
+G_DEFINE_TYPE (MamanBar, maman_bar, G_TYPE_OBJECT);
 
 static GObject *
-maman_bar_constructor (GType                  type,
-                       guint                  n_construct_properties,
-                       GObjectConstructParam *construct_properties)
+maman_bar_constructor (GType                  gtype,
+                       guint                  n_properties,
+                       GObjectConstructParam *properties)
 {
   GObject *obj;
 
   {
-    /* Invoke parent constructor. */
+    /* Always chain up to the parent constructor */
     MamanBarClass *klass;
     GObjectClass *parent_class;  
-    klass = MAMAN_BAR_CLASS (g_type_class_peek (MAMAN_TYPE_BAR));
-    parent_class = G_OBJECT_CLASS (g_type_class_peek_parent (klass));
-    obj = parent_class->constructor (type,
-                                     n_construct_properties,
-                                     construct_properties);
+    parent_class = G_OBJECT_CLASS (maman_bar_parent_class);
+    obj = parent_class-&gt;constructor (gtype, n_properties, properties);
   }
   
-  /* do stuff. */
+  /* update the object state depending on constructor properties */
 
   return obj;
 }
 
 static void
-maman_bar_instance_init (GTypeInstance   *instance,
-                         gpointer         g_class)
+maman_bar_class_init (MamanBarClass *klass)
 {
-  MamanBar *self = (MamanBar *)instance;
-  /* do stuff */
+  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+  gobject_class-&gt;constructor = maman_bar_constructor;
 }
 
 static void
-maman_bar_class_init (gpointer g_class,
-                      gpointer g_class_data)
+maman_bar_init (MamanBar *self)
 {
-  GObjectClass *gobject_class = G_OBJECT_CLASS (g_class);
-  MamanBarClass *klass = MAMAN_BAR_CLASS (g_class);
-
-  gobject_class->constructor = maman_bar_constructor;
+  /* initialize the object */
 }
 
-GType maman_bar_get_type (void)
-{
-  static GType type = 0;
-  if (type == 0) {
-    static const GTypeInfo info = {
-      sizeof (MamanBarClass),
-      NULL,   /* base_init */
-      NULL,   /* base_finalize */
-      maman_bar_class_init,   /* class_init */
-      NULL,   /* class_finalize */
-      NULL,   /* class_data */
-      sizeof (MamanBar),
-      0,      /* n_preallocs */
-      maman_bar_instance_init    /* instance_init */
-    };
-    type = g_type_register_static (G_TYPE_OBJECT,
-                                   "MamanBarType",
-                                   &amp;info, 0);
-  }
-  return type;
-}
 </programlisting>
       If the user instantiates an object <type>MamanBar</type> with:
 <programlisting>
 MamanBar *bar = g_object_new (MAMAN_TYPE_BAR, NULL);
 </programlisting>        
-      If this is the first instantiation of such an object, the <function>maman_b_class_init</function>
-      function will be invoked after any <function>maman_b_base_class_init</function> function. 
-      This will make sure the class structure of this new object is correctly initialized. Here, 
-      <function>maman_bar_class_init</function> is expected to override the object's class methods
-      and setup the class' own methods. In the example above, the constructor method is the only 
-      overridden method: it is set to <function>maman_bar_constructor</function>.
+      If this is the first instantiation of such an object, the
+      <function>maman_bar_class_init</function> function will be invoked
+      after any <function>maman_bar_base_class_init</function> function.
+      This will make sure the class structure of this new object is
+      correctly initialized. Here, <function>maman_bar_class_init</function>
+      is expected to override the object's class methods and setup the
+      class' own methods. In the example above, the constructor method is
+      the only overridden method: it is set to
+      <function>maman_bar_constructor</function>.
     </para>
 
     <para>
@@ -158,12 +140,11 @@
       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> 
       to <function>maman_bar_constructor</function>, the latter is called and, because it
-      was implemented correctly, it chains up to its parent's constructor. The problem here
-      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 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.
+      was implemented correctly, it chains up to its parent's constructor. In
+      order to find the parent class and chain up to the parent class
+      constructor, we can use the <literal>maman_bar_parent_class</literal>
+      pointer that has been set up for us by the
+      <literal>G_DEFINE_TYPE</literal> macro.
     </para>
 
     <para>
@@ -179,16 +160,13 @@
     </para>
 
     <para>
-      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
-      lists the functions invoked by <function><link linkend="g-object-new">g_object_new</link></function> and their order of
-      invocation.
+      The process described above might seem a bit complicated, but it can be
+      summarized easily by the table below which lists the functions invoked
+      by <function><link linkend="g-object-new">g_object_new</link></function>
+      and their order of invocation:
     </para>
 
     <para>
-      The array below lists the functions invoked by <function><link linkend="g-object-new">g_object_new</link></function> and 
-      their order of invocation:
-
       <table id="gobject-construction-table">
         <title><function><link linkend="g-object-new">g_object_new</link></function></title>
         <tgroup cols="3">
@@ -266,16 +244,16 @@
     </para>
 
     <para>
-      Readers should feel concerned about one little twist in the order in which functions 
-      are invoked: while, technically, the class' constructor method is called
-      <emphasis>before</emphasis> the GType's instance_init function (since 
-      <function><link linkend="g-type-create-instance">g_type_create_instance</link></function> which calls instance_init is called by
+      Readers should feel concerned about one little twist in the order in
+      which functions are invoked: while, technically, the class' constructor
+      method is called <emphasis>before</emphasis> the GType's instance_init
+      function (since <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 
-      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>
-      GType's instance_init function since the user-provided constructor 
-      <emphasis>must</emphasis> (you've been warned) chain up <emphasis>before</emphasis>
-      doing anything useful.
+      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> GType's instance_init function since the
+      user-provided constructor <emphasis>must</emphasis> (you've been warned)
+      chain up <emphasis>before</emphasis> doing anything useful.
     </para>
   </sect1>
 
@@ -296,24 +274,25 @@
 void        g_object_unref                    (gpointer        object);
 
 /*
-  Weak References
-*/
-typedef void (*GWeakNotify)                (gpointer      data,
-                                         GObject      *where_the_object_was);
-void            g_object_weak_ref                      (GObject              *object,
-                                               GWeakNotify     notify,
-                                               gpointer               data);
-void            g_object_weak_unref                      (GObject              *object,
-                                               GWeakNotify     notify,
-                                               gpointer               data);
-void        g_object_add_weak_pointer         (GObject        *object, 
-                                               gpointer       *weak_pointer_location);
-void        g_object_remove_weak_pointer      (GObject        *object, 
-                                               gpointer       *weak_pointer_location);
+ * Weak References
+ */
+typedef void (*GWeakNotify) (gpointer  data,
+                             GObject  *where_the_object_was);
+
+void g_object_weak_ref            (GObject     *object,
+                                   GWeakNotify  notify,
+                                   gpointer     data);
+void g_object_weak_unref          (GObject     *object,
+                                   GWeakNotify  notify,
+                                   gpointer     data);
+void g_object_add_weak_pointer    (GObject     *object, 
+                                   gpointer    *weak_pointer_location);
+void g_object_remove_weak_pointer (GObject     *object, 
+                                   gpointer    *weak_pointer_location);
 /*
-  Cycle handling
-*/
-void        g_object_run_dispose              (GObject              *object);
+ * Cycle handling
+ */
+void g_object_run_dispose         (GObject     *object);
 </programlisting>
     </para>
 
@@ -528,17 +507,13 @@
 /* Implementation                               */
 /************************************************/
 
-enum {
-  MAMAN_BAR_CONSTRUCT_NAME = 1,
-  MAMAN_BAR_PAPA_NUMBER,
-};
-
-static void
-maman_bar_instance_init (GTypeInstance   *instance,
-                         gpointer         g_class)
+enum
 {
-  MamanBar *self = (MamanBar *)instance;
-}
+  PROP_0,
+
+  PROP_MAMAN_NAME,
+  PROP_PAPA_NUMBER
+};
 
 static void
 maman_bar_set_property (GObject      *object,
@@ -546,61 +521,61 @@
                         const GValue *value,
                         GParamSpec   *pspec)
 {
-  MamanBar *self = (MamanBar *) object;
+  MamanBar *self = MAMAN_BAR (object);
 
-  switch (property_id) {
-  case MAMAN_BAR_CONSTRUCT_NAME: {
-    g_free (self->priv->name);
-    self->priv->name = g_value_dup_string (value);
-    g_print ("maman: %s\n",self->priv->name);
-  }
-    break;
-  case MAMAN_BAR_PAPA_NUMBER: {
-    self->priv->papa_number = g_value_get_uchar (value);
-    g_print ("papa: %u\n",self->priv->papa_number);
-  }
-    break;
-  default:
-    /* We don't have any other property... */
-    G_OBJECT_WARN_INVALID_PROPERTY_ID(object,property_id,pspec);
-    break;
-  }
+  switch (property_id)
+    {
+    case PROP_MAMAN_NAME:
+      g_free (self-&gt;priv-&gt;name);
+      self-&gt;priv-&gt;name = g_value_dup_string (value);
+      g_print ("maman: %s\n", self-&gt;priv-&gt;name);
+      break;
+
+    case PROP_PAPA_NUMBER:
+      self-&gt;priv-&gt;papa_number = g_value_get_uchar (value);
+      g_print ("papa: &percnt;u\n", self-&gt;priv-&gt;papa_number);
+      break;
+
+    default:
+      /* We don't have any other property... */
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+      break;
+    }
 }
 
 static void
-maman_bar_get_property (GObject      *object,
-                        guint         property_id,
-                        GValue       *value,
-                        GParamSpec   *pspec)
+maman_bar_get_property (GObject    *object,
+                        guint       property_id,
+                        GValue     *value,
+                        GParamSpec *pspec)
 {
-  MamanBar *self = (MamanBar *) object;
+  MamanBar *self = MAMAN_BAR (object);
 
-  switch (property_id) {
-  case MAMAN_BAR_CONSTRUCT_NAME: {
-    g_value_set_string (value, self->priv->name);
-  }
-    break;
-  case MAMAN_BAR_PAPA_NUMBER: {
-    g_value_set_uchar (value, self->priv->papa_number);
-  }
-    break;
-  default:
-    /* We don't have any other property... */
-    G_OBJECT_WARN_INVALID_PROPERTY_ID(object,property_id,pspec);
-    break;
-  }
+  switch (property_id)
+    {
+    case PROP_MAMAN_NAME:
+      g_value_set_string (value, self-&gt;priv-&gt;name);
+      break;
+
+    case PROP_PAPA_NUMBER:
+      g_value_set_uchar (value, self-&gt;priv-&gt;papa_number);
+      break;
+
+    default:
+      /* We don't have any other property... */
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+      break;
+    }
 }
 
 static void
-maman_bar_class_init (gpointer g_class,
-                      gpointer g_class_data)
+maman_bar_class_init (MamanBarClass *klass)
 {
   GObjectClass *gobject_class = G_OBJECT_CLASS (g_class);
-  MamanBarClass *klass = MAMAN_BAR_CLASS (g_class);
   GParamSpec *pspec;
 
-  gobject_class->set_property = maman_bar_set_property;
-  gobject_class->get_property = maman_bar_get_property;
+  gobject_class-&gt;set_property = maman_bar_set_property;
+  gobject_class-&gt;get_property = maman_bar_get_property;
 
   pspec = g_param_spec_string ("maman-name",
                                "Maman construct prop",
@@ -608,7 +583,7 @@
                                "no-name-set" /* default value */,
                                G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
   g_object_class_install_property (gobject_class,
-                                   MAMAN_BAR_CONSTRUCT_NAME,
+                                   PROP_MAMAN_NAME_NAME,
                                    pspec);
 
   pspec = g_param_spec_uchar ("papa-number",
@@ -619,7 +594,7 @@
                               2  /* default value */,
                               G_PARAM_READWRITE);
   g_object_class_install_property (gobject_class,
-                                   MAMAN_BAR_PAPA_NUMBER,
+                                   PROP_PAPA_NUMBER,
                                    pspec);
 }
 
@@ -628,11 +603,16 @@
 /************************************************/
 
 GObject *bar;
-GValue val = {0,};
+GValue val = { 0, };
+
 bar = g_object_new (MAMAN_TYPE_SUBBAR, NULL);
+
 g_value_init (&amp;val, G_TYPE_CHAR);
 g_value_set_char (&amp;val, 11);
+
 g_object_set_property (G_OBJECT (bar), "papa-number", &amp;val);
+
+g_value_unset (&amp;val);
 </programlisting>
       The client code just above looks simple but a lot of things happen under the hood:
     </para>
@@ -765,7 +745,3 @@
   </sect1>
 
 </chapter>
-
-
-
-

Modified: trunk/docs/reference/gobject/tut_gsignal.xml
==============================================================================
--- trunk/docs/reference/gobject/tut_gsignal.xml	(original)
+++ trunk/docs/reference/gobject/tut_gsignal.xml	Fri Jul 18 17:55:13 2008
@@ -78,14 +78,14 @@
         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>
-GClosure* g_cclosure_new (GCallback        callback_func,
-                          gpointer         user_data,
-                          GClosureNotify   destroy_data);
-GClosure* g_cclosure_new_swap (GCallback        callback_func,
-                               gpointer         user_data,
-                               GClosureNotify   destroy_data);
-GClosure* g_signal_type_cclosure_new (GType  itype,
-                                      guint  struct_offset);
+GClosure *g_cclosure_new             (GCallback      callback_func,
+                                      gpointer       user_data,
+                                      GClosureNotify destroy_data);
+GClosure *g_cclosure_new_swap        (GCallback      callback_func,
+                                      gpointer       user_data,
+                                      GClosureNotify destroy_data);
+GClosure *g_signal_type_cclosure_new (GType          itype,
+                                      guint          struct_offset);
 </programlisting>
       </para>
 
@@ -203,16 +203,16 @@
 		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><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>
-guint                 g_signal_newv         (const gchar        *signal_name,
-                                             GType               itype,
-                                             GSignalFlags        signal_flags,
-                                             GClosure           *class_closure,
-                                             GSignalAccumulator  accumulator,
-                                             gpointer            accu_data,
-                                             GSignalCMarshaller  c_marshaller,
-                                             GType               return_type,
-                                             guint               n_params,
-                                             GType              *param_types);
+guint g_signal_newv (const gchar        *signal_name,
+                     GType               itype,
+                     GSignalFlags        signal_flags,
+                     GClosure           *class_closure,
+                     GSignalAccumulator  accumulator,
+                     gpointer            accu_data,
+                     GSignalCMarshaller  c_marshaller,
+                     GType               return_type,
+                     guint               n_params,
+                     GType              *param_types);
 </programlisting>
 		The number of parameters to these functions is a bit intimidating but they are relatively
 		simple:
@@ -308,10 +308,10 @@
 		Signal emission is done through the use of the <function><link linkend="g-signal-emit">g_signal_emit</link></function> family 
 		of functions.
 <programlisting>
-void                  g_signal_emitv        (const GValue       *instance_and_params,
-                         guint               signal_id,
-                         GQuark              detail,
-                         GValue             *return_value);
+void g_signal_emitv (const GValue *instance_and_params,
+                     guint         signal_id,
+                     GQuark        detail,
+                     GValue       *return_value);
 </programlisting>
 		<itemizedlist>
 		  <listitem><para>

Modified: trunk/docs/reference/gobject/tut_gtype.xml
==============================================================================
--- trunk/docs/reference/gobject/tut_gtype.xml	(original)
+++ trunk/docs/reference/gobject/tut_gtype.xml	Fri Jul 18 17:55:13 2008
@@ -787,7 +787,7 @@
             When an instantiable classed type which registered an interface implementation
             is created for the first time, its class structure is initialized following the process
             described in <xref linkend="gtype-instantiable-classed"/>. Once the class structure is 
-              initialized,the function <function>type_class_init_Wm</function> (implemented in <filename>
+              initialized, the function <function>type_class_init_Wm</function> (implemented in <filename>
               gtype.c</filename>) initializes the interface implementations associated with
               that type by calling <function>type_iface_vtable_init_Wm</function> for each
               interface.

Modified: trunk/docs/reference/gobject/tut_howto.xml
==============================================================================
--- trunk/docs/reference/gobject/tut_howto.xml	(original)
+++ trunk/docs/reference/gobject/tut_howto.xml	Fri Jul 18 17:55:13 2008
@@ -11,81 +11,66 @@
   <title>How to define and implement a new GObject</title>
   
   <para>
-    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 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 
-      <type><link linkend="GObject">GObject</link></type> and which shows how to declare different types of methods on the object.
-      </para></listitem>
-      <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.
-      </para></listitem>
-      <listitem><para><filename>maman-foo.{h|c}</filename>: this is the source for an object which derives from 
-      <type><link linkend="GObject">GObject</link></type> and which declares a signal.
-      </para></listitem>
-      <listitem><para><filename>test.c</filename>: this is the main source which instantiates an instance of
-      type and exercises their API.
-      </para></listitem>
-    </itemizedlist>
+    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.
   </para>
 
   <sect1 id="howto-gobject-header">
     <title>Boilerplate header code</title>
     
     <para>
-      The first step before writing the code for your GObject is to write the type's header which contains
-      the needed type, function and macro definitions. Each of these elements is nothing but a convention
-      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:
+      The first step before writing the code for your GObject is to write the
+      type's header which contains the needed type, function and macro
+      definitions. Each of these elements is nothing but a convention 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
-            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>
-        <listitem><para>
-            You must assess the fact that these conventions might have been designed by both smart
-            and experienced people: maybe they were at least partly right. Try  to put your ego aside.
-          </para></listitem>
+        <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>
+        <listitem><para>You must assess the fact that these conventions might
+        have been designed by both smart and experienced people: maybe they
+        were at least partly right. Try  to put your ego aside.</para></listitem>
       </itemizedlist>
     </para>
 
     <para>
       Pick a name convention for your headers and source code and stick to it:
       <itemizedlist>
-        <listitem><para>
-            use a dash to separate the prefix from the typename: <filename>maman-bar.h</filename> and 
-            <filename>maman-bar.c</filename> (this is the convention used by Nautilus and most GNOME libraries).
-          </para></listitem>
-        <listitem><para>
-            use an underscore to separate the prefix from the typename: <filename>maman_bar.h</filename> and 
-            <filename>maman_bar.c</filename>.
-          </para></listitem>
-        <listitem><para>
-            Do not separate the prefix from the typename: <filename>mamanbar.h</filename> and 
-            <filename>mamanbar.c</filename>. (this is the convention used by GTK+)
-          </para></listitem>
+        <listitem><para>use a dash to separate the prefix from the typename:
+        <filename>maman-bar.h</filename> and <filename>maman-bar.c</filename>
+        (this is the convention used by Nautilus and most GNOME libraries).</para></listitem>
+        <listitem><para>use an underscore to separate the prefix from the
+        typename: <filename>maman_bar.h</filename> and
+        <filename>maman_bar.c</filename>.</para></listitem>
+        <listitem><para>Do not separate the prefix from the typename:
+        <filename>mamanbar.h</filename> and <filename>mamanbar.c</filename>.
+        (this is the convention used by GTK+)</para></listitem>
       </itemizedlist>
-      I personally like the first solution better: it makes reading file names easier for those with poor
-      eyesight like me.
+      I personally like the first solution better: it makes reading file names
+      easier for those with poor eyesight like me.
     </para>
 
     <para>
-      When you need some private (internal) declarations in several (sub)classes,
-      you can define them in a private header file which is often named by
-      appending the <emphasis>private</emphasis> keyword to the public header name.
-      For example, one could use <filename>maman-bar-private.h</filename>, 
-      <filename>maman_bar_private.h</filename> or <filename>mamanbarprivate.h</filename>.
-      Typically, such private header files are not installed.
+      When you need some private (internal) declarations in several
+      (sub)classes, you can define them in a private header file which
+      is often named by appending the <emphasis>private</emphasis> keyword
+      to the public header name. For example, one could use
+      <filename>maman-bar-private.h</filename>,
+      <filename>maman_bar_private.h</filename> or
+      <filename>mamanbarprivate.h</filename>. Typically, such private header
+      files are not installed.
     </para>
 
     <para>
-      The basic conventions for any header which exposes a GType are described in 
-      <xref linkend="gtype-conventions"/>. Most GObject-based code also obeys one of of the following
-      conventions: pick one and stick to it.
+      The basic conventions for any header which exposes a GType are described
+      in <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>
             If you want to declare a type named bar with prefix maman, name the type instance
@@ -97,9 +82,11 @@
  * Copyright/Licensing information.
  */
 
-#ifndef MAMAN_BAR_H
-#define MAMAN_BAR_H
+/* inclusion guard */
+#ifndef __MAMAN_BAR_H__
+#define __MAMAN_BAR_H__
 
+#include &lt;glib-object.h&gt;
 /*
  * Potentially, include other headers on which this header depends.
  */
@@ -107,17 +94,27 @@
 /*
  * Type macros.
  */
+#define MAMAN_TYPE_BAR                  (maman_bar_get_type ())
+#define MAMAN_BAR(obj)                  (G_TYPE_CHECK_INSTANCE_CAST ((obj), MAMAN_TYPE_BAR, MamanBar))
+#define MAMAN_IS_BAR(obj)               (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MAMAN_TYPE_BAR))
+#define MAMAN_BAR_CLASS(klass)          (G_TYPE_CHECK_CLASS_CAST ((klass), MAMAN_TYPE_BAR, MamanBarClass))
+#define MAMAN_IS_BAR_CLASS(klass)       (G_TYPE_CHECK_CLASS_TYPE ((klass), MAMAN_TYPE_BAR))
+#define MAMAN_BAR_GET_CLASS(obj)        (G_TYPE_INSTANCE_GET_CLASS ((obj), MAMAN_TYPE_BAR, MamanBarClass))
 
-typedef struct _MamanBar MamanBar;
-typedef struct _MamanBarClass MamanBarClass;
+typedef struct _MamanBar        MamanBar;
+typedef struct _MamanBarClass   MamanBarClass;
+
+struct _MamanBar
+{
+  GObject parent_instance;
 
-struct _MamanBar {
-  GObject parent;
   /* instance members */
 };
 
-struct _MamanBarClass {
-  GObjectClass parent;
+struct _MamanBarClass
+{
+  GObjectClass parent_class;
+
   /* class members */
 };
 
@@ -128,17 +125,20 @@
  * Method definitions.
  */
 
-#endif
+#endif /* __MAMAN_BAR_H__ */
 </programlisting>
           </para></listitem>
         <listitem><para>
-            Most GTK+ types declare their private fields in the public header with a /* private */ comment, 
-            relying on their user's intelligence not to try to play with these fields. Fields not marked private
-            are considered public by default. The /* protected */ comment (same semantics as those of C++)
-            is also used, mainly in the GType library, in code written by Tim Janik.
+            Most GTK+ types declare their private fields in the public header
+            with a /* private */ comment, relying on their user's intelligence
+            not to try to play with these fields. Fields not marked private
+            are considered public by default. The /* protected */ comment
+            (same semantics as those of C++) is also used, mainly in the GType
+            library, in code written by Tim Janik.
 <programlisting>
-struct _MamanBar {
-  GObject parent;
+struct _MamanBar
+{
+  GObject parent_instance;
 
   /*&lt; private &gt;*/
   int hsize;
@@ -146,92 +146,85 @@
 </programlisting>
           </para></listitem>
         <listitem><para>
-            All of Nautilus code and a lot of GNOME libraries use private indirection members, as described
-            by Herb Sutter in his Pimpl articles
-            (see <ulink url="http://www.gotw.ca/gotw/024.htm";>Compilation Firewalls</ulink>
-            and <ulink url="http://www.gotw.ca/gotw/028.htm";>The Fast Pimpl Idiom</ulink>
-            : he summarizes the different issues better than I will).
+            All of Nautilus code and a lot of GNOME libraries use private
+            indirection members, as described by Herb Sutter in his Pimpl
+            articles(see <ulink url="http://www.gotw.ca/gotw/024.htm";>Compilation Firewalls</ulink>
+            and <ulink url="http://www.gotw.ca/gotw/028.htm";>The Fast Pimpl Idiom</ulink>:
+            he summarizes the different issues better than I will).
 <programlisting>
 typedef struct _MamanBarPrivate MamanBarPrivate;
-struct _MamanBar {
-  GObject parent;
+
+struct _MamanBar
+{
+  GObject parent_instance;
     
   /*&lt; private &gt;*/
   MamanBarPrivate *priv;
 };
 </programlisting>
-            <note><simpara>Do not call this <varname>private</varname>, as that is a registered c++ keyword.</simpara></note>
-            The private structure is then defined in the .c file, instantiated in the object's
-            <function>init</function> function and destroyed in the object's <function>finalize</function> function.
-<programlisting>
-static void
-maman_bar_finalize (GObject *object) {
-  MamanBar *self = MAMAN_BAR (object);
-  /* do stuff */
-  g_free (self->priv);
-}
-
-static void
-maman_bar_init (GTypeInstance *instance, gpointer g_class) {
-  MamanBar *self = MAMAN_BAR (instance);
-  self->priv = g_new0 (MamanBarPrivate,1);
-  /* do stuff */
-}
-</programlisting>
-          </para></listitem>
+            <note><simpara>Do not call this <varname>private</varname>, as
+            that is a registered c++ keyword.</simpara></note>
 
-          <listitem><para>
-            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 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.
+            The private structure is then defined in the .c file, using the
+            g_type_class_add_private() function to notify the presence of
+            a private memory area for each instance and it can either
+            be retrieved using <function>G_TYPE_INSTANCE_GET_PRIVATE()</function>
+            each time is needed, or assigned to the <literal>priv</literal>
+            member of the instance structure inside the object's
+            <function>init</function> function.
 <programlisting>
-typedef struct _MamanBarPrivate MamanBarPrivate;
+#define MAMAN_BAR_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), MAMAN_TYPE_BAR, MamanBarPrivate))
 
-struct _MamanBarPrivate {
-  int private_field;
-};
+struct _MamanBarPrivate
+{
+  int hsize;
+}
 
 static void
 maman_bar_class_init (MamanBarClass *klass)
 {
-  ...
   g_type_class_add_private (klass, sizeof (MamanBarPrivate));
-  ...
 }
 
 static void
-maman_bar_init (GTypeInstance *instance, gpointer g_class) {
-  MamanBar *self = MAMAN_BAR (instance);
-  self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, MAMAN_TYPE_BAR, MamanBarPrivate);
-  /* do stuff */
+maman_bar_init (MamanBar *self)
+{
+  MamanBarPrivate *priv;
+
+  self->priv = priv = MAMAN_BAR_GET_PRIVATE (self);
+
+  priv->hsize = 42;
 }
 </programlisting>
           </para></listitem>
 
+          <listitem><para>
+            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.
+          </para></listitem>
       </itemizedlist>
     </para>
 
     <para>
-      Finally, there are different header include conventions. Again, pick one and stick to it. I personally
-      use indifferently any of the two, depending on the codebase I work on: the rule is consistency.
+      Finally, there are different header include conventions. Again, pick one
+      and stick to it. I personally use indifferently any of the two, depending
+      on the codebase I work on: the rule, as always, is consistency.
       <itemizedlist>
         <listitem><para>
-            Some people add at the top of their headers a number of #include directives to pull in
-            all the headers needed to compile client code. This allows client code to simply  
-            #include "maman-bar.h".
+            Some people add at the top of their headers a number of #include
+            directives to pull in all the headers needed to compile client
+            code. This allows client code to simply #include "maman-bar.h".
           </para></listitem>
         <listitem><para>
-            Other do not #include anything and expect the client to #include themselves the headers 
-            they need before including your header. This speeds up compilation because it minimizes the
-            amount of pre-processor work. This can be used in conjunction with the re-declaration of certain 
-            unused types in the client code to minimize compile-time dependencies and thus speed up 
-            compilation.
+            Other do not #include anything and expect the client to #include
+            themselves the headers they need before including your header. This
+            speeds up compilation because it minimizes the amount of
+            pre-processor work. This can be used in conjunction with the
+            re-declaration of certain unused types in the client code to
+            minimize compile-time dependencies and thus speed up compilation.
           </para></listitem>
       </itemizedlist>
     </para>
@@ -242,9 +235,10 @@
     <title>Boilerplate code</title>
 
     <para>
-      In your code, the first step is to #include the needed headers: depending on your header include strategy, this
-      can be as simple as #include "maman-bar.h" or as complicated as tens of #include lines ending with 
-      #include "maman-bar.h":
+      In your code, the first step is to #include the needed headers: depending
+      on your header include strategy, this can be as simple as
+      <literal>#include "maman-bar.h"</literal> or as complicated as tens
+      of #include lines ending with <literal>#include "maman-bar.h"</literal>:
 <programlisting>
 /*
  * Copyright information
@@ -269,32 +263,29 @@
     </para>
 
     <para>
-      Implement <function>maman_bar_get_type</function> and make sure the code compiles:
+      Call the <function>G_DEFINE_TYPE</function> macro using the name
+      of the type, the prefix of the functions and the parent GType to
+      reduce the amount of boilerplate needed. This macro will:
+
+      <itemizedlist>
+        <listitem><simpara>implement the <function>maman_bar_get_type</function>
+        function</simpara></listitem>
+        <listitem><simpara>define a parent class pointer accessible from
+        the whole .c file</simpara></listitem>
+      </itemizedlist>
+
 <programlisting>
-GType
-maman_bar_get_type (void)
-{
-  static GType type = 0;
-  if (type == 0) {
-    static const GTypeInfo info = {
-      sizeof (MamanBarClass),
-      NULL,   /* base_init */
-      NULL,   /* base_finalize */
-      NULL,   /* class_init */
-      NULL,   /* class_finalize */
-      NULL,   /* class_data */
-      sizeof (MamanBar),
-      0,      /* n_preallocs */
-      NULL    /* instance_init */
-      };
-      type = g_type_register_static (G_TYPE_OBJECT,
-                                     "MamanBarType",
-                                     &amp;info, 0);
-    }
-    return type;
-}
+G_DEFINE_TYPE (MamanBar, maman_bar, G_TYPE_OBJECT);
 </programlisting>
     </para>
+
+    <para>
+      It is also possible to use the
+      <function>G_DEFINE_TYPE_WITH_CODE</function> macro to control the
+      get_type function implementation - for instance, to add a call to
+      <function>G_IMPLEMENT_INTERFACE</function> macro which will
+      call the <function>g_type_implement_interface</function> function.
+    </para>
   </sect1>
 
   <sect1 id="howto-gobject-construction">
@@ -326,22 +317,17 @@
       As such, I would recommend writing the following code first:
 <programlisting>
 static void
-maman_bar_init (GTypeInstance   *instance,
-                gpointer         g_class)
+maman_bar_init (MamanBar *self)
 {
-  MamanBar *self = (MamanBar *)instance;
-  self->private = g_new0 (MamanBarPrivate, 1);
+  self->private = MAMAN_BAR_GET_PRIVATE (self); 
 
   /* initialize all public and private members to reasonable default values. */
+
   /* If you need specific construction properties to complete initialization,
    * delay initialization completion until the property is set. 
    */
 }
 </programlisting>
-      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 
-      of the object and make sure <function>maman_bar_init</function> is called (add a 
-      <function><link linkend="g-print">g_print</link></function> call in it).
     </para>
 
     <para>
@@ -364,8 +350,7 @@
                                           "Maman construct prop",
                                           "Set maman's name",
                                           "no-name-set" /* default value */,
-                                          G_PARAM_CONSTRUCT_ONLY |G_PARAM_READWRITE);
-
+                                          G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
   g_object_class_install_property (gobject_class,
                                    PROP_MAMAN,
                                    maman_param_spec);
@@ -384,44 +369,45 @@
       should have a good reason to do so.
     </para>
 
-      <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-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>
+    <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-instantiation"/> or, more simply, using
+      the constructed class method available since GLib 2.12.
+    </para>
   </sect1>
 
   <sect1 id="howto-gobject-destruction">
     <title>Object Destruction</title>
 
     <para>
-      Again, it is often difficult to figure out which mechanism to use to hook into the object's
-      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"/>.
+      Again, it is often difficult to figure out which mechanism to use to
+      hook into the object's 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"/>.
     </para>
 
     <para>
-      The destruction process of your object must be split is two different phases: you must override
-      both the dispose and the finalize class methods.
+      The destruction process of your object might be split in two different
+      phases: dispose and the finalize.
 <programlisting>
-struct _MamanBarPrivate {
-  gboolean dispose_has_run;
+#define MAMAN_BAR_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), MAMAN_TYPE_BAR, MamanBarPrivate))
+
+struct _MamanBarPrivate
+{
+  GObject *an_object;
+
+  gchar *a_string;
 };
 
-static GObjectClass *parent_class = NULL;
+G_DEFINE_TYPE (MamanBar, maman_bar, G_TYPE_OBJECT);
 
 static void
-bar_dispose (GObject *obj)
+maman_bar_dispose (GObject *gobject)
 {
-  MamanBar *self = (MamanBar *)obj;
-
-  if (self->priv->dispose_has_run) {
-   /* If dispose did already run, return. */
-    return;
-  }
-  /* Make sure dispose does not run twice. */
-  object->priv->dispose_has_run = TRUE;
+  MamanBar *self = MAMAN_BAR (gobject);
 
   /* 
    * In dispose, you are supposed to free all types referenced from this
@@ -430,56 +416,63 @@
    * reference.
    */
 
-   /* Chain up to the parent class */
-   G_OBJECT_CLASS (parent_class)->dispose (obj);
+  /* dispose might be called multiple times, so we must guard against
+   * calling g_object_unref() on an invalid GObject.
+   */
+  if (self->priv->an_object)
+    {
+      g_object_unref (self->priv->an_object);
+
+      self->priv->an_object = NULL;
+    }
+
+  /* Chain up to the parent class */
+  G_OBJECT_CLASS (maman_bar_parent_class)->dispose (gobject);
 }
 
 static void
-bar_finalize (GObject *obj)
+maman_bar_finalize (GObject *gobject)
 {
-  MamanBar *self = (MamanBar *)obj;
+  MamanBar *self = MAMAN_BAR (gobject);
+
+  g_free (self->priv->a_string);
 
-   /* Chain up to the parent class */
-   G_OBJECT_CLASS (parent_class)->finalize (obj);
+  /* Chain up to the parent class */
+  G_OBJECT_CLASS (maman_bar_parent_class)->finalize (gobject);
 }
 
 static void
-bar_class_init (BarClass *klass)
+maman_bar_class_init (MamanBarClass *klass)
 {
   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 
-  gobject_class->dispose = bar_dispose;
-  gobject_class->finalize = bar_finalize;
+  gobject_class->dispose = maman_bar_dispose;
+  gobject_class->finalize = maman_bar_finalize;
 
-  parent_class = g_type_class_peek_parent (klass);
-  g_type_class_add_private(klass,sizeof(MamanBarPrivate));
+  g_type_class_add_private (klass, sizeof (MamanBarPrivate));
 }
 
 static void
-maman_bar_init (GTypeInstance   *instance,
-                gpointer         g_class)
+maman_bar_init (MamanBar *self);
 {
-  MamanBar *self = (MamanBar *)instance;
-  self->priv = G_TYPE_INSTANCE_GET_PRIVATE(self, BT_TYPE_PATTERN, BtPatternPrivate);
-  self->priv->dispose_has_run = FALSE;
+  self->priv = MAMAN_BAR_GET_PRIVATE (self);
 
+  self->priv->an_object = g_object_new (MAMAN_TYPE_BAZ, NULL);
+  self->priv->a_string = g_strdup ("Maman");
 }
 </programlisting>
     </para>
 
     <para>
-      Add similar code to your GObject, make sure the code still builds and runs: dispose and finalize must be called
-      during the last unref.
-      It is possible that object methods might be invoked after dispose is run and before finalize runs. GObject
-      does not consider this to be a program error: you must gracefully detect this and neither crash nor warn
-      the user. To do this, you need something like the following code at the start of each object method, to make
-      sure the object's data is still valid before manipulating it:
-<programlisting>
-if (self->private->dispose_has_run) {
-  /* Dispose has run. Data is not valid anymore. */
-  return;
-}
-</programlisting>
+      Add similar code to your GObject, make sure the code still builds
+      and runs: dispose and finalize must be called during the last unref.
+    </para>
+
+    <para>
+      It is possible that object methods might be invoked after dispose is
+      run and before finalize runs. GObject does not consider this to be a
+      program error: you must gracefully detect this and neither crash nor
+      warn the user.
     </para>
   </sect1>
 
@@ -488,10 +481,11 @@
 
     <para>
       Just as with C++, there are many different ways to define object
-      methods and extend them: the following list and sections draw on C++ vocabulary.
-      (Readers are expected to know basic C++ buzzwords. Those who have not had to
-      write C++ code recently can refer to e.g. <ulink url="http://www.cplusplus.com/doc/tutorial/"/> to refresh their 
-      memories.)
+      methods and extend them: the following list and sections draw on
+      C++ vocabulary. (Readers are expected to know basic C++ buzzwords.
+      Those who have not had to write C++ code recently can refer to e.g.
+      <ulink url="http://www.cplusplus.com/doc/tutorial/"/> to refresh
+      their memories.)
       <itemizedlist>
         <listitem><para>
             non-virtual public methods,
@@ -509,15 +503,20 @@
       <title>Non-virtual public methods</title>
 
       <para>
-        These are the simplest: you want to provide a simple method which can act on your object. All you need
-        to do is to provide a function prototype in the header and an implementation of that prototype
+        These are the simplest: you want to provide a simple method which
+        can act on your object. All you need to do is to provide a function
+        prototype in the header and an implementation of that prototype
         in the source file.
 <programlisting>
 /* declaration in the header. */
 void maman_bar_do_action (MamanBar *self, /* parameters */);
+
 /* implementation in the source file */
-void maman_bar_do_action (MamanBar *self, /* parameters */)
+void
+maman_bar_do_action (MamanBar *self, /* parameters */)
 {
+  g_return_if_fail (MAMAN_IS_BAR (self));
+
   /* do stuff here. */
 }
 </programlisting>
@@ -530,52 +529,66 @@
       <title>Virtual public methods</title>
 
       <para>
-        This is the preferred way to create polymorphic GObjects. All you need to do is to
-        define the common method and its class function in the public header, implement the
-        common method in the source file and re-implement the class function in each object 
-        which inherits from you.
+        This is the preferred way to create polymorphic GObjects. All you
+        need to do is to define the common method and its class function in
+        the public header, implement the common method in the source file
+        and re-implement the class function in each object which inherits
+        from you.
 <programlisting>
 /* declaration in maman-bar.h. */
-struct _MamanBarClass {
-  GObjectClass parent;
+struct _MamanBarClass
+{
+  GObjectClass parent_class;
 
   /* stuff */
   void (*do_action) (MamanBar *self, /* parameters */);
 };
+
 void maman_bar_do_action (MamanBar *self, /* parameters */);
+
 /* implementation in maman-bar.c */
-void maman_bar_do_action (MamanBar *self, /* parameters */)
+void
+maman_bar_do_action (MamanBar *self, /* parameters */)
 {
+  g_return_if_fail (MAMAN_IS_BAR (self));
+
   MAMAN_BAR_GET_CLASS (self)->do_action (self, /* parameters */);
 }
 </programlisting>
-        The code above simply redirects the do_action call to the relevant class function. Some users,
-        concerned about performance, do not provide the <function>maman_bar_do_action</function>
-        wrapper function and require users to dereference the class pointer themselves. This is not such
-        a great idea in terms of encapsulation and makes it difficult to change the object's implementation
-        afterwards, should this be needed.
+        The code above simply redirects the do_action call to the relevant
+        class function. Some users, concerned about performance, do not
+        provide the <function>maman_bar_do_action</function> wrapper function
+        and require users to dereference the class pointer themselves. This
+        is not such a great idea in terms of encapsulation and makes it
+        difficult to change the object's implementation afterwards, should
+        this be needed.
       </para>
 
       <para>
-        Other users, also concerned by performance issues, declare the <function>maman_bar_do_action</function>
-        function inline in the header file. This, however, makes it difficult to change the
-        object's implementation later (although easier than requiring users to directly dereference the class 
-        function) and is often difficult to write in a portable way (the <emphasis>inline</emphasis> keyword
-        is not part of the C standard).
+        Other users, also concerned by performance issues, declare
+        the <function>maman_bar_do_action</function> function inline in the
+        header file. This, however, makes it difficult to change the
+        object's implementation later (although easier than requiring users
+        to directly dereference the class function) and is often difficult
+        to write in a portable way (the <emphasis>inline</emphasis> keyword
+        is part of the C99 standard but not every compiler supports it).
       </para>
 
       <para>
-        In doubt, unless a user shows you hard numbers about the performance cost of the function call,
-        just <function>maman_bar_do_action</function> in the source file.
+        In doubt, unless a user shows you hard numbers about the performance
+        cost of the function call, just implement <function>maman_bar_do_action</function>
+        in the source file.
       </para>
 
       <para>
-        Please, note that it is possible for you to provide a default implementation for this class method in
-        the object's class_init function: initialize the klass->do_action field to a pointer to the actual
-        implementation. You can also make this class method pure virtual by initializing the klass->do_action
-        field to NULL:
+        Please, note that it is possible for you to provide a default
+        implementation for this class method in the object's
+        <function>class_init</function> function: initialize the
+        klass-&gt;do_action field to a pointer to the actual implementation.
+        You can also make this class method pure virtual by initializing
+        the klass-&gt;do_action field to NULL:
 <programlisting>
-static void 
+static void
 maman_bar_real_do_action_two (MamanBar *self, /* parameters */)
 {
   /* Default implementation for the virtual method. */
@@ -586,16 +599,24 @@
 {
   /* pure virtual method: mandates implementation in children. */
   klass->do_action_one = NULL;
+
   /* merely virtual method. */
   klass->do_action_two = maman_bar_real_do_action_two;
 }
 
-void maman_bar_do_action_one (MamanBar *self, /* parameters */)
+void
+maman_bar_do_action_one (MamanBar *self, /* parameters */)
 {
+  g_return_if_fail (MAMAN_IS_BAR (self));
+
   MAMAN_BAR_GET_CLASS (self)->do_action_one (self, /* parameters */);
 }
-void maman_bar_do_action_two (MamanBar *self, /* parameters */)
+
+void
+maman_bar_do_action_two (MamanBar *self, /* parameters */)
 {
+  g_return_if_fail (MAMAN_IS_BAR (self));
+
   MAMAN_BAR_GET_CLASS (self)->do_action_two (self, /* parameters */);
 }
 </programlisting>
@@ -606,19 +627,23 @@
       <title>Virtual private Methods</title>
 
       <para>
-        These are very similar to Virtual Public methods. They just don't have a public function to call the
-        function directly. The header file contains only a declaration of the class function:
+        These are very similar to Virtual Public methods. They just don't
+        have a public function to call the function directly. The header
+        file contains only a declaration of the class function:
 <programlisting>
 /* declaration in maman-bar.h. */
-struct _MamanBarClass {
+struct _MamanBarClass
+{
   GObjectClass parent;
 
   /* stuff */
-  void (*helper_do_specific_action) (MamanBar *self, /* parameters */);
+  void (* helper_do_specific_action) (MamanBar *self, /* parameters */);
 };
+
 void maman_bar_do_any_action (MamanBar *self, /* parameters */);
 </programlisting>
-        These class functions are often used to delegate part of the job to child classes:
+        These class functions are often used to delegate part of the job
+        to child classes:
 <programlisting>
 /* this accessor function is static: it is not exported outside of this file. */
 static void 
@@ -627,13 +652,15 @@
   MAMAN_BAR_GET_CLASS (self)->do_specific_action (self, /* parameters */);
 }
 
-void maman_bar_do_any_action (MamanBar *self, /* parameters */)
+void
+maman_bar_do_any_action (MamanBar *self, /* parameters */)
 {
   /* random code here */
 
   /* 
-   * Try to execute the requested action. Maybe the requested action cannot be implemented
-   * here. So, we delegate its implementation to the child class:
+   * Try to execute the requested action. Maybe the requested action
+   * cannot be implemented here. So, we delegate its implementation
+   * to the child class:
    */
   maman_bar_do_specific_action (self, /* parameters */);
 
@@ -643,13 +670,15 @@
       </para>
 
       <para>
-        Again, it is possible to provide a default implementation for this private virtual class function:
+        Again, it is possible to provide a default implementation for this
+        private virtual class function:
 <programlisting>
 static void
 maman_bar_class_init (MamanBarClass *klass)
 {
   /* pure virtual method: mandates implementation in children. */
   klass->do_specific_action_one = NULL;
+
   /* merely virtual method. */
   klass->do_specific_action_two = maman_bar_real_do_specific_action_two;
 }
@@ -663,6 +692,7 @@
 maman_bar_subtype_class_init (MamanBarSubTypeClass *klass)
 {
   MamanBarClass *bar_class = MAMAN_BAR_CLASS (klass);
+
   /* implement pure virtual class function. */
   bar_class->do_specific_action_one = maman_bar_subtype_do_specific_action_one;
 }
@@ -674,7 +704,8 @@
   <sect1 id="howto-gobject-chainup">
     <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:
       <itemizedlist>
         <listitem><para>Parent class A defines a public virtual method named <function>foo</function> and 
         provides a default implementation.</para></listitem>
@@ -725,18 +756,17 @@
 {
   BClass *klass;
   AClass *parent_class;
+
   klass = B_GET_CLASS (obj);
   parent_class = g_type_class_peek_parent (klass);
 
   /* do stuff before chain up */
+
   parent_class->method_to_call (obj, a);
+
   /* do stuff after chain up */
 }
 </programlisting>
-   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><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>
-   does this.
   </para>
 
   </sect1>
@@ -744,7 +774,6 @@
 </chapter>
 <!-- End Howto GObject -->
 
-
 <chapter id="howto-interface">
   <title>How to define and implement interfaces</title>
 
@@ -753,30 +782,29 @@
   
   <para>
     The bulk of interface definition has already been shown in <xref linkend="gtype-non-instantiable-classed"/>
-    but I feel it is needed to show exactly how to create an interface. The sample source code
-    associated to this section can be found in the documentation's source tarball, in the 
-    <filename>sample/interface/maman-ibaz.{h|c}</filename> file.
+    but I feel it is needed to show exactly how to create an interface.
   </para>
 
   <para>
     As above, the first step is to get the header right:
 <programlisting>
-#ifndef MAMAN_IBAZ_H
-#define MAMAN_IBAZ_H
+#ifndef __MAMAN_IBAZ_H__
+#define __MAMAN_IBAZ_H__
 
 #include &lt;glib-object.h&gt;
 
-#define MAMAN_TYPE_IBAZ                (maman_ibaz_get_type ())
-#define MAMAN_IBAZ(obj)                (G_TYPE_CHECK_INSTANCE_CAST ((obj), MAMAN_TYPE_IBAZ, MamanIbaz))
-#define MAMAN_IS_IBAZ(obj)             (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MAMAN_TYPE_IBAZ))
-#define MAMAN_IBAZ_GET_INTERFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), MAMAN_TYPE_IBAZ, MamanIbazInterface))
+#define MAMAN_TYPE_IBAZ                 (maman_ibaz_get_type ())
+#define MAMAN_IBAZ(obj)                 (G_TYPE_CHECK_INSTANCE_CAST ((obj), MAMAN_TYPE_IBAZ, MamanIbaz))
+#define MAMAN_IS_IBAZ(obj)              (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MAMAN_TYPE_IBAZ))
+#define MAMAN_IBAZ_GET_INTERFACE(inst)  (G_TYPE_INSTANCE_GET_INTERFACE ((inst), MAMAN_TYPE_IBAZ, MamanIbazInterface))
 
 
-typedef struct _MamanIbaz MamanIbaz; /* dummy object */
-typedef struct _MamanIbazInterface MamanIbazInterface;
+typedef struct _MamanIbaz               MamanIbaz; /* dummy object */
+typedef struct _MamanIbazInterface      MamanIbazInterface;
 
-struct _MamanIbazInterface {
-  GTypeInterface parent;
+struct _MamanIbazInterface
+{
+  GTypeInterface parent_iface;
 
   void (*do_action) (MamanIbaz *self);
 };
@@ -785,7 +813,7 @@
 
 void maman_ibaz_do_action (MamanIbaz *self);
 
-#endif /*MAMAN_IBAZ_H*/
+#endif /* __MAMAN_IBAZ_H__ */
 </programlisting>
     This code is the same as the code for a normal <type><link linkend="GType">GType</link></type>
     which derives from a <type><link linkend="GObject">GObject</link></type> except for a few details:
@@ -796,8 +824,13 @@
                   but with <function><link linkend="G_TYPE_INSTANCE_GET_INTERFACE">G_TYPE_INSTANCE_GET_INTERFACE</link></function>.
       </para></listitem>
       <listitem><para>
-        The instance type, <type>MamanIbaz</type> is not fully defined: it is used merely as an abstract 
-        type which represents an instance of whatever object which implements the interface.
+        The instance type, <type>MamanIbaz</type> is not fully defined: it is
+        used merely as an abstract type which represents an instance of
+        whatever object which implements the interface.
+      </para></listitem>
+      <listitem><para>
+        The parent of the <type>MamanIbazInterface</type> is not
+        <type>GObjectClass</type> but <type>GTypeInterface</type>.
       </para></listitem>
     </itemizedlist>
   </para>
@@ -815,45 +848,48 @@
       <xref linkend="gtype-non-instantiable-classed-init"/>, 
       <function>base_init</function> is run once for each interface implementation 
       instantiation)</para></listitem>
-      <listitem><para><function>maman_ibaz_do_action</function> dereferences the class
-      structure to access its associated class function and calls it.
+      <listitem><para><function>maman_ibaz_do_action</function> dereferences
+      the class structure to access its associated class function and calls it.
       </para></listitem>
     </itemizedlist>
 <programlisting>
 static void
 maman_ibaz_base_init (gpointer g_class)
 {
-  static gboolean initialized = FALSE;
+  static gboolean is_initialized = FALSE;
+
+  if (!is_initialized)
+    {
+      /* add properties and signals to the interface here */
 
-  if (!initialized) {
-    /* create interface signals here. */
-    initialized = TRUE;
-  }
+      is_initialized = TRUE;
+    }
 }
 
 GType
 maman_ibaz_get_type (void)
 {
-  static GType type = 0;
-  if (type == 0) {
-    static const GTypeInfo info = {
-      sizeof (MamanIbazInterface),
-      maman_ibaz_base_init,   /* base_init */
-      NULL,   /* base_finalize */
-      NULL,   /* class_init */
-      NULL,   /* class_finalize */
-      NULL,   /* class_data */
-      0,
-      0,      /* n_preallocs */
-      NULL    /* instance_init */
-    };
-    type = g_type_register_static (G_TYPE_INTERFACE, "MamanIbaz", &amp;info, 0);
-  }
+  static GType iface_type = 0;
+  if (iface_type == 0)
+    {
+      static const GTypeInfo info = {
+        sizeof (MamanIbazInterface),
+        maman_ibaz_base_init,   /* base_init */
+        NULL,   /* base_finalize */
+      };
+
+      iface_type = g_type_register_static (G_TYPE_INTERFACE, "MamanIbaz",
+                                           &amp;info, 0);
+    }
+
   return type;
 }
 
-void maman_ibaz_do_action (MamanIbaz *self)
+void
+maman_ibaz_do_action (MamanIbaz *self)
 {
+  g_return_if_fail (MAMAN_IS_IBAZ (self));
+
   MAMAN_IBAZ_GET_INTERFACE (self)->do_action (self);
 }
 </programlisting>
@@ -864,114 +900,94 @@
     <title>How To define implement an Interface?</title>
   
     <para>
-      Once the interface is defined, implementing it is rather trivial. Source code showing how to do this
-      for the <type>IBaz</type> interface defined in the previous section is located in 
-      <filename>sample/interface/maman-baz.{h|c}</filename>.
+      Once the interface is defined, implementing it is rather trivial.
     </para>
   
     <para>
-      The first step is to define a normal GType. Here, we have decided to use a GType which derives from
-      GObject. Its name is <type>MamanBaz</type>:
+      The first step is to define a normal GObject class, like:
 <programlisting>
-#ifndef MAMAN_BAZ_H
-#define MAMAN_BAZ_H
+#ifndef __MAMAN_BAZ_H__
+#define __MAMAN_BAZ_H__
 
-#include &lt;glib-object.h>
+#include &lt;glib-object.h&gt;
 
 #define MAMAN_TYPE_BAZ             (maman_baz_get_type ())
 #define MAMAN_BAZ(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), MAMAN_TYPE_BAZ, Mamanbaz))
-#define MAMAN_BAZ_CLASS(vtable)    (G_TYPE_CHECK_CLASS_CAST ((vtable), MAMAN_TYPE_BAZ, MamanbazClass))
 #define MAMAN_IS_BAZ(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MAMAN_TYPE_BAZ))
-#define MAMAN_IS_BAZ_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE ((vtable), MAMAN_TYPE_BAZ))
-#define MAMAN_BAZ_GET_CLASS(inst)  (G_TYPE_INSTANCE_GET_CLASS ((inst), MAMAN_TYPE_BAZ, MamanbazClass))
+#define MAMAN_BAZ_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), MAMAN_TYPE_BAZ, MamanbazClass))
+#define MAMAN_IS_BAZ_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), MAMAN_TYPE_BAZ))
+#define MAMAN_BAZ_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), MAMAN_TYPE_BAZ, MamanbazClass))
+
 
+typedef struct _MamanBaz        MamanBaz;
+typedef struct _MamanBazClass   MamanBazClass;
 
-typedef struct _MamanBaz MamanBaz;
-typedef struct _MamanBazClass MamanBazClass;
+struct _MamanBaz
+{
+  GObject parent_instance;
 
-struct _MamanBaz {
-  GObject parent;
   int instance_member;
 };
 
-struct _MamanBazClass {
-  GObjectClass parent;
+struct _MamanBazClass
+{
+  GObjectClass parent_class;
 };
 
 GType maman_baz_get_type (void);
 
-
-#endif //MAMAN_BAZ_H
+#endif /* __MAMAN_BAZ_H__ */
 </programlisting>
-      There is clearly nothing specifically weird or scary about this header: it does not define any weird API
-      or derives from a weird type.
+      There is clearly nothing specifically weird or scary about this header:
+      it does not define any weird API or derives from a weird type.
     </para>
   
     <para>
-      The second step is to implement <function>maman_baz_get_type</function>:
+      The second step is to implement <type>MamanBaz</type> by defining
+      its GType. Instead of using <function>G_DEFINE_TYPE</function> we
+      use <function>G_DEFINE_TYPE_WITH_CODE</function> and the
+      <function>G_IMPLEMENT_INTERFACE</function> macros.
 <programlisting>
-GType 
-maman_baz_get_type (void)
-{
-  static GType type = 0;
-  if (type == 0) {
-    static const GTypeInfo info = {
-      sizeof (MamanBazClass),
-      NULL,   /* base_init */
-      NULL,   /* base_finalize */
-      NULL,   /* class_init */
-      NULL,   /* class_finalize */
-      NULL,   /* class_data */
-      sizeof (MamanBaz),
-      0,      /* n_preallocs */
-      baz_instance_init    /* instance_init */
-    };
-    static const GInterfaceInfo ibaz_info = {
-      (GInterfaceInitFunc) baz_interface_init,    /* interface_init */
-      NULL,               /* interface_finalize */
-      NULL                /* interface_data */
-    };
-    type = g_type_register_static (G_TYPE_OBJECT,
-                                   "MamanBazType",
-                                   &amp;info, 0);
-    g_type_add_interface_static (type,
-                                 MAMAN_TYPE_IBAZ,
-                                 &amp;ibaz_info);
-  }
-  return type;
-}
+static void maman_ibaz_interface_init (MamanIbazInterface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (MamanBar, maman_bar, G_TYPE_OBJECT,
+                         G_IMPLEMENT_INTERFACE (MAMAN_TYPE_IBAZ,
+                                                maman_ibaz_interface_init));
 </programlisting>
-      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><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><link linkend="GType">GType</link></type> also implements the interface 
-      <function>MAMAN_TYPE_IBAZ</function>.
+      This definition 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_IMPLEMENT_INTERFACE</function>. 
     </para>
+
+    <note><para>Classes can implement multiple interfaces by using multiple
+    calls to <function>G_IMPLEMENT_INTERFACE</function> inside the call
+    to <function>G_DEFINE_TYPE_WITH_CODE</function>.</para></note>
   
     <para>
-      <function>baz_interface_init</function>, the interface initialization function, is also pretty simple:
+      <function>maman_baz_interface_init</function>, the interface
+      initialization function: inside it every virtual method of the interface
+      must be assigned to its implementation:
 <programlisting>
-static void baz_do_action (MamanBaz *self)
+static void
+maman_baz_do_action (MamanBaz *self)
 {
-  g_print ("Baz implementation of IBaz interface Action: 0x%x.\n", self->instance_member);
+  g_print ("Baz implementation of IBaz interface Action: 0x%x.\n",
+           self->instance_member);
 }
+
 static void
-baz_interface_init (gpointer   g_iface,
-                    gpointer   iface_data)
+maman_ibaz_interface_init (MamanIbazInterface *iface)
 {
-  MamanIbazInteface *iface = (MamanIbazInteface *)g_iface;
-  iface->do_action = (void (*) (MamanIbaz *self))baz_do_action;
+  iface->do_action = baz_do_action;
 }
+
 static void
-baz_instance_init (GTypeInstance   *instance,
-                   gpointer         g_class)
+maman_baz_init (MamanBaz *self)
 {
-  MamanBaz *self = MAMAN_BAZ(instance);
+  MamanBaz *self = MAMAN_BAZ (instance);
   self->instance_member = 0xdeadbeaf;
 }
 </programlisting>
-      <function>baz_interface_init</function> merely initializes the interface methods to the implementations
-      defined by <type>MamanBaz</type>: <function>maman_baz_do_action</function> does nothing very useful 
-      but it could :)
     </para>
   
   </sect1>
@@ -980,125 +996,103 @@
     <title>Interface definition prerequisites</title>
   
     <para>
-      To specify that an interface requires the presence of other interfaces when implemented, 
-      GObject introduces the concept of <emphasis>prerequisites</emphasis>: it is possible to associate
-      a list of prerequisite interfaces to an interface. For example, if object A wishes to implement interface
-      I1, and if interface I1 has a prerequisite on interface I2, A has to implement both I1 and I2.
+      To specify that an interface requires the presence of other interfaces
+      when implemented, GObject introduces the concept of
+      <emphasis>prerequisites</emphasis>: it is possible to associate
+      a list of prerequisite interfaces to an interface. For example, if
+      object A wishes to implement interface I1, and if interface I1 has a
+      prerequisite on interface I2, A has to implement both I1 and I2.
     </para>
   
     <para>
-      The mechanism described above is, in practice, very similar to Java's interface I1 extends 
-      interface I2. The example below shows the GObject equivalent:
-  
+      The mechanism described above is, in practice, very similar to
+      Java's interface I1 extends interface I2. The example below shows
+      the GObject equivalent:
 <programlisting>
+  /* inside the GType function of the MamanIbar interface */
   type = g_type_register_static (G_TYPE_INTERFACE, "MamanIbar", &amp;info, 0);
+
   /* Make the MamanIbar interface require MamanIbaz interface. */
   g_type_interface_add_prerequisite (type, MAMAN_TYPE_IBAZ);
 </programlisting>
-      The code shown above adds the MamanIbaz interface to the list of prerequisites of MamanIbar while the 
-      code below shows how an implementation can implement both interfaces and register their implementations:
+      The code shown above adds the MamanIbaz interface to the list of
+      prerequisites of MamanIbar while the code below shows how an
+      implementation can implement both interfaces and register their
+      implementations:
 <programlisting>
-static void ibar_do_another_action (MamanBar *self)
+static void
+maman_ibar_do_another_action (MamanIbar *ibar)
 {
-  g_print ("Bar implementation of IBar interface Another Action: 0x%x.\n", self->instance_member);
+  MamanBar *self = MAMAN_BAR (ibar);
+
+  g_print ("Bar implementation of IBar interface Another Action: 0x%x.\n",
+           self->instance_member);
 }
 
 static void
-ibar_interface_init (gpointer   g_iface,
-                     gpointer   iface_data)
+maman_ibar_interface_init (MamanIbarInterface *iface)
 {
-  MamanIbarInterface *iface = (MamanIbarInterface *)g_iface;
-  iface->do_another_action = (void (*) (MamanIbar *self))ibar_do_another_action;
+  iface->do_another_action = maman_ibar_do_another_action;
 }
 
-
-static void ibaz_do_action (MamanBar *self)
+static void
+maman_ibaz_do_action (MamanIbaz *ibaz)
 {
-  g_print ("Bar implementation of IBaz interface Action: 0x%x.\n", self->instance_member);
+  MamanBar *self = MAMAN_BAR (ibaz);
+
+  g_print ("Bar implementation of IBaz interface Action: 0x%x.\n",
+           self->instance_member);
 }
 
 static void
-ibaz_interface_init (gpointer   g_iface,
-                    gpointer   iface_data)
+maman_ibaz_interface_init (MamanIbazInterface *iface)
 {
-  MamanIbazInterface *iface = (MamanIbazInterface *)g_iface;
-  iface->do_action = (void (*) (MamanIbaz *self))ibaz_do_action;
+  iface->do_action = maman_ibaz_do_action;
 }
 
 static void
-bar_instance_init (GTypeInstance   *instance,
-                   gpointer         g_class)
+maman_bar_class_init (MamanBarClass *klass)
 {
-  MamanBar *self = (MamanBar *)instance;
-  self->instance_member = 0x666;
+
 }
 
-GType 
-maman_bar_get_type (void)
+static void
+maman_bar_init (MamanBar *self)
 {
-  static GType type = 0;
-  if (type == 0) {
-    static const GTypeInfo info = {
-      sizeof (MamanBarClass),
-      NULL,   /* base_init */
-      NULL,   /* base_finalize */
-      NULL,   /* class_init */
-      NULL,   /* class_finalize */
-      NULL,   /* class_data */
-      sizeof (MamanBar),
-      0,      /* n_preallocs */
-      bar_instance_init    /* instance_init */
-    };
-    static const GInterfaceInfo ibar_info = {
-      (GInterfaceInitFunc) ibar_interface_init,   /* interface_init */
-      NULL,                                       /* interface_finalize */
-      NULL                                        /* interface_data */
-    };
-    static const GInterfaceInfo ibaz_info = {
-      (GInterfaceInitFunc) ibaz_interface_init,   /* interface_init */
-      NULL,                                       /* interface_finalize */
-      NULL                                        /* interface_data */
-    };
-    type = g_type_register_static (G_TYPE_OBJECT,
-                                   "MamanBarType",
-                                   &amp;info, 0);
-    g_type_add_interface_static (type,
-                                 MAMAN_TYPE_IBAZ,
-                                 &amp;ibaz_info);
-    g_type_add_interface_static (type,
-                                 MAMAN_TYPE_IBAR,
-                                 &amp;ibar_info);
-  }
-  return type;
+  self->instance_member = 0x666;
 }
-</programlisting>
-      It is very important to notice that the order in which interface implementations are added to the main object
-      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.
-    </para>
-  
-    <para>
-      Complete source code showing how to define the MamanIbar interface which requires MamanIbaz and how to 
-      implement the MamanIbar interface is located in <filename>sample/interface/maman-ibar.{h|c}</filename> 
-      and <filename>sample/interface/maman-bar.{h|c}</filename>.
+
+G_DEFINE_TYPE_WITH_CODE (MamanBar, maman_bar, G_TYPE_OBJECT,
+                         G_IMPLEMENT_INTERFACE (MAMAN_TYPE_IBAZ,
+                                                maman_ibaz_interface_init)
+                         G_IMPLEMENT_INTERFACE (MAMAN_TYPE_IBAR,
+                                                maman_ibar_interface_init));
+</programlisting>
+      It is very important to notice that the order in which interface
+      implementations are added to the main object is not random:
+      <function><link linkend="g-type-add-interface-static">g_type_add_interface_static</link></function>,
+      which is called by <function>G_IMPLEMENT_INTERFACE</function>, must be
+      invoked first on the interfaces which have no prerequisites and then on
+      the others.
     </para>
-  
   </sect1>
   
   <sect1 id="howto-interface-properties">
     <title>Interface Properties</title>
   
     <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 
-      ordinary GObject types as explained in <xref linkend="gobject-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 
       declare the properties instead of <function><link linkend="g-object-class-install-property">g_object_class_install_property</link></function>.
     </para>
   
     <para>
       To include a property named 'name' of type <type>string</type> in the 
-      <type>maman_ibaz</type> interface example code above, we only need to add one 
+      <type>maman_ibaz</type> interface example code above, we only need to
+      add one 
       <footnote>
         <para>
           That really is one line extended to six for the sake of clarity
@@ -1107,8 +1101,9 @@
       line in the <function>maman_ibaz_base_init</function>
       <footnote>
         <para>
-          The <function><link linkend="g-object-interface-install-property">g_object_interface_install_property</link></function> can also be called from
-          <function>class_init</function> but it must not be called after that point.
+          The <function><link linkend="g-object-interface-install-property">g_object_interface_install_property</link></function>
+          can also be called from <function>class_init</function> but it must
+          not be called after that point.
         </para>
       </footnote>
       as shown below:
@@ -1116,140 +1111,106 @@
 static void
 maman_ibaz_base_init (gpointer g_iface)
 {
-  static gboolean initialized = FALSE;
-
-  if (!initialized) {
-    /* create interface signals here. */
+  static gboolean is_initialized = FALSE;
 
-    g_object_interface_install_property (g_iface,
-                g_param_spec_string ("name",
-                    "maman_ibaz_name",
-                    "Name of the MamanIbaz",
-                    "maman",
-                    G_PARAM_READWRITE));
-    initialized = TRUE;
-  }
+  if (!is_initialized)
+    {
+      g_object_interface_install_property (g_iface,
+                                           g_param_spec_string ("name",
+                                                                "Name",
+                                                                "Name of the MamanIbaz",
+                                                                "maman",
+                                                                G_PARAM_READWRITE));
+      is_initialized = TRUE;
+    }
 }
 </programlisting>
     </para>
   
     <para>
       One point worth noting is that the declared property wasn't assigned an 
-      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.
+      integer ID. The reason being that integer IDs of properties are used
+      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>
     
     <para>
-      The story for the implementers of the interface is also quite trivial. 
-      An implementer shall declare and define it's properties in the usual way as 
-      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 snippet 
-      shows the modifications needed in the <type>MamanBaz</type> declaration and 
-      implementation above:
+      An implementation shall declare and define it's properties in the usual
+      way as explained in <xref linkend="gobject-properties"/>, except for one
+      small change: it must 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 snippet shows the modifications needed in the
+      <type>MamanBaz</type> declaration and implementation above:
 <programlisting>
 
-struct _MamanBaz {
-  GObject parent;
+struct _MamanBaz
+{
+  GObject parent_instance;
+
   gint instance_member;
-  gchar *name;        /* placeholder for property */
+  gchar *name;
 };
 
 enum
 {
-  ARG_0,
-  ARG_NAME
-};
-
-GType 
-maman_baz_get_type (void)
-{
-  static GType type = 0;
-  if (type == 0) {
-    static const GTypeInfo info = {
-      sizeof (MamanBazClass),
-      NULL,   /* base_init */
-      NULL,   /* base_finalize */
-      baz_class_init, /* class_init */
-      NULL,   /* class_finalize */
-      NULL,   /* class_data */
-      sizeof (MamanBaz),
-      0,      /* n_preallocs */
-      baz_instance_init    /* instance_init */
-    };
-    static const GInterfaceInfo ibaz_info = {
-      (GInterfaceInitFunc) baz_interface_init,    /* interface_init */
-      NULL,               /* interface_finalize */
-      NULL                /* interface_data */
-    };
-    type = g_type_register_static (G_TYPE_OBJECT,
-                                   "MamanBazType",
-                                   &amp;info, 0);
-    g_type_add_interface_static (type,
-                                 MAMAN_TYPE_IBAZ,
-                                 &amp;ibaz_info);
-  }
-  return type;
-}
-
-static void
-maman_baz_class_init (MamanBazClass * klass)
-{
-  GObjectClass *gobject_class;
-
-  gobject_class = (GObjectClass *) klass;
-
-  parent_class = g_type_class_ref (G_TYPE_OBJECT);
-
-  gobject_class->set_property = maman_baz_set_property;
-  gobject_class->get_property = maman_baz_get_property;
+  PROP_0,
 
-  g_object_class_override_property (gobject_class, ARG_NAME, "name");
-}
+  PROP_NAME
+};
 
 static void
-maman_baz_set_property (GObject * object, guint prop_id,
-                        const GValue * value, GParamSpec * pspec)
+maman_baz_set_property (GObject      *object,
+                        guint         property_id,
+                        const GValue *value,
+                        GParamSpec   *pspec)
 {
-  MamanBaz *baz;
+  MamanBaz *baz = MAMAN_BAZ (object);
   GObject *obj;
 
-  /* it's not null if we got it, but it might not be ours */
-  g_return_if_fail (G_IS_MAMAN_BAZ (object));
-
-  baz = MAMAN_BAZ (object);
-
-  switch (prop_id) {
+  switch (prop_id)
+    {
     case ARG_NAME:
-      baz->name = g_value_get_string (value);
+      g_free (baz->name);
+      baz->name = g_value_dup_string (value);
       break;
+
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
-  }
+    }
 }
 
 static void
-maman_baz_get_property (GObject * object, guint prop_id,
-                        GValue * value, GParamSpec * pspec)
+maman_baz_get_property (GObject    *object,
+                        guint       prop_id,
+                        GValue     *value,
+                        GParamSpec *pspec)
 {
-  MamanBaz *baz;
+  MamanBaz *baz = MAMAN_BAZ (object);
 
-  /* it's not null if we got it, but it might not be ours */
-  g_return_if_fail (G_IS_TEXT_PLUGIN (object));
-
-  baz = MAMAN_BAZ (object);
-
-  switch (prop_id) {
+  switch (prop_id)
+    {
     case ARG_NAME:
       g_value_set_string (value, baz->name);
       break;
+
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
-  }
+    }
+}
+
+static void
+maman_baz_class_init (MamanBazClass *klass)
+{
+  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+  gobject_class->set_property = maman_baz_set_property;
+  gobject_class->get_property = maman_baz_get_property;
+
+  g_object_class_override_property (gobject_class, PROP_NAME, "name");
 }
 
 </programlisting>
@@ -1262,50 +1223,52 @@
 <chapter id="howto-signals">
   <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)
+    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>
-
     to any signal and to stop the emission of any signal at any 
-    state of the signal emission process. This flexibility makes it possible to use GSignal for much more than 
-    just emit events which can be received by numerous clients. 
+    state of the signal emission process. This flexibility makes it
+    possible to use GSignal for much more than just emit signals which
+    can be received by numerous clients. 
   </para>
 
   <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 
-      MamanFile object, and if this object has a write method, we might wish to be notified whenever someone 
-      uses this method. The code below shows how the user can connect a callback to the write signal. Full code
-      for this simple example is located in <filename>sample/signal/maman-file.{h|c}</filename> and
-      in <filename>sample/signal/test.c</filename>
+      The most basic use of signals is to implement simple event
+      notification: for example, if we have a MamanFile object, and
+      if this object has a write method, we might wish to be notified
+      whenever someone has changed something via our MamanFile instance.
+      The code below shows how the user can connect a callback to the
+      "changed" signal.
 <programlisting>
 file = g_object_new (MAMAN_FILE_TYPE, NULL);
 
-g_signal_connect (G_OBJECT (file), "write",
-                  (GCallback)write_event,
-                  NULL);
+g_signal_connect (file, "changed", G_CALLBACK (changed_event), NULL);
 
-maman_file_write (file, buffer, 50);
+maman_file_write (file, buffer, strlen (buffer));
 </programlisting>
     </para>
     
     <para>
-      The <type>MamanFile</type> signal is registered in the class_init function:
+      The <type>MamanFile</type> signal is registered in the class_init
+      function:
 <programlisting>
-klass->write_signal_id = 
-  g_signal_newv ("write",
-                 G_TYPE_FROM_CLASS (g_class),
+file_signals[CHANGED] = 
+  g_signal_newv ("changed",
+                 G_TYPE_FROM_CLASS (gobject_class),
                  G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS,
-                 NULL /* class closure */,
+                 NULL /* closure */,
                  NULL /* accumulator */,
-                 NULL /* accu_data */,
+                 NULL /* accumulator data */,
                  g_cclosure_marshal_VOID__VOID,
                  G_TYPE_NONE /* return_type */,
                  0     /* n_params */,
@@ -1313,51 +1276,68 @@
 </programlisting>
       and the signal is emitted in <function>maman_file_write</function>:
 <programlisting>
-void maman_file_write (MamanFile *self, guint8 *buffer, guint32 size)
+void
+maman_file_write (MamanFile    *self,
+                  const guchar *buffer,
+                  gssize        size)
 {
   /* First write data. */
+
   /* Then, notify user of data written. */
-  g_signal_emit (self, MAMAN_FILE_GET_CLASS (self)->write_signal_id,
-                 0 /* details */, 
-                 NULL);
+  g_signal_emit (self, file_signals[CHANGED], 0 /* details */);
 }
 </programlisting>
-      As shown above, you can safely set the details parameter to zero if you do not know what it can be used for.
-      For a discussion of what you could used it for, see <xref linkend="signal-detail"/>
+      As shown above, you can safely set the details parameter to zero if
+      you do not know what it can be used for. For a discussion of what you
+      could used it for, see <xref linkend="signal-detail"/>
     </para>
 
     <para>
       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 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
-      needed closures that one can use.
+      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.
+    </para>
+
+    <para>
+      The header <filename>gobject/gmarshal.h</filename> defines a set of
+      commonly needed closures that one can use. If you want to have complex
+      marshallers for your signals you should probably use glib-genmarshal
+      to autogenerate them from a file containing their return and
+      parameter types.
     </para>
   </sect1>
 
+<!-- 
+  this is utterly wrong and should be completely removed - or rewritten
+  with a better example than writing a buffer using synchronous signals.
+
   <sect1>
     <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
-      even more flexibility to this file change notification mechanism. One of the key ideas is to make the process
-      of writing data to the file part of the signal emission process to allow users to be notified either
-      before or after the data is written to the file.
+      The previous implementation does the job but the signal facility of
+      GObject can be used to provide even more flexibility to this file
+      change notification mechanism. One of the key ideas is to make the
+      process of writing data to the file part of the signal emission
+      process to allow users to be notified either before or after the
+      data is written to the file.
     </para>
     
     <para>
-      To integrate the process of writing the data to the file into the signal emission mechanism, we can
-      register a default class closure for this signal which will be invoked during the signal emission, just like 
-      any other user-connected signal handler. 
+      To integrate the process of writing the data to the file into the
+      signal emission mechanism, we can register a default class closure
+      for this signal which will be invoked during the signal emission,
+      just like any other user-connected signal handler. 
     </para>
     
     <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
+      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 glib-genmarshal tool. We thus create a file named <filename>marshall.list</filename> which contains
       the following single line:
 <programlisting>
 VOID:POINTER,UINT
@@ -1480,6 +1460,15 @@
 </programlisting>
     </para>
 
+-->
+
+<!--
+  this is also utterly wrong on so many levels that I don't even want
+  to enumerate them. it's also full of completely irrelevant footnotes
+  about personal preferences demonstrating a severe lack of whatsoever
+  clue. the whole idea of storing the signal ids inside the Class
+  structure is so fundamentally flawed that I'll require a frontal
+  lobotomy just to forget I've ever seen it.
 
     <sect2>
     <title>How most people do the same thing with less code</title>
@@ -1583,7 +1572,13 @@
    </sect2>
 
   </sect1>
+-->
 
+<!--
+  yet another pointless section. if we are scared of possible abuses
+  from the users then we should not be mentioning it inside a tutorial
+  for beginners. but, obviously, there's nothing to be afraid of - it's
+  just that this section must be completely reworded.
 
   <sect1>
     <title>How users can abuse signals (and why some think it is good)</title>
@@ -1634,6 +1629,8 @@
 
   </sect1>
 
+-->
+
 </chapter>
 
 <!--



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]