summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
Diffstat (limited to 'docs')
-rw-r--r--docs/reference/gobject/tut_gobject.xml142
-rw-r--r--docs/reference/gobject/tut_gtype.xml188
-rw-r--r--docs/reference/gobject/tut_howto.xml651
3 files changed, 548 insertions, 433 deletions
diff --git a/docs/reference/gobject/tut_gobject.xml b/docs/reference/gobject/tut_gobject.xml
index 557615f97..8097cb649 100644
--- a/docs/reference/gobject/tut_gobject.xml
+++ b/docs/reference/gobject/tut_gobject.xml
@@ -55,68 +55,68 @@
<para>
Objects which inherit from GObject are allowed to override this
constructed class method.
- The example below shows how <type>MamanBar</type> overrides the parent's construction process:
+ The example below shows how <type>ViewerFile</type> overrides the parent's construction process:
<informalexample><programlisting>
-#define MAMAN_TYPE_BAR maman_bar_get_type ()
-G_DECLARE_FINAL_TYPE (MamanBar, maman_bar, MAMAN, BAR, GObject)
+#define VIEWER_TYPE_FILE viewer_file_get_type ()
+G_DECLARE_FINAL_TYPE (ViewerFile, viewer_file, VIEWER, FILE, GObject)
-struct _MamanBar
+struct _ViewerFile
{
GObject parent_instance;
/* instance members */
};
-/* will create maman_bar_get_type and set maman_bar_parent_class */
-G_DEFINE_TYPE (MamanBar, maman_bar, G_TYPE_OBJECT);
+/* will create viewer_file_get_type and set viewer_file_parent_class */
+G_DEFINE_TYPE (ViewerFile, viewer_file, G_TYPE_OBJECT)
static void
-maman_bar_constructed (GObject *obj)
+viewer_file_constructed (GObject *obj)
{
/* update the object state depending on constructor properties */
/* Always chain up to the parent constructed function to complete object
* initialisation. */
- G_OBJECT_CLASS (maman_bar_parent_class)-&gt;constructed (obj);
+ G_OBJECT_CLASS (viewer_file_parent_class)-&gt;constructed (obj);
}
static void
-maman_bar_class_init (MamanBarClass *klass)
+viewer_file_class_init (ViewerFileClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
- object_class-&gt;constructed = maman_bar_constructed;
+ object_class-&gt;constructed = viewer_file_constructed;
}
static void
-maman_bar_init (MamanBar *self)
+viewer_file_init (ViewerFile *self)
{
/* initialize the object */
}
</programlisting></informalexample>
- If the user instantiates an object <type>MamanBar</type> with:
+ If the user instantiates an object <type>ViewerFile</type> with:
<informalexample><programlisting>
-MamanBar *bar = g_object_new (MAMAN_TYPE_BAR, NULL);
+ViewerFile *file = g_object_new (VIEWER_TYPE_FILE, NULL);
</programlisting></informalexample>
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.
+ <function>viewer_file_class_init</function> function will be invoked
+ after any <function>viewer_file_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>
+ correctly initialized. Here, <function>viewer_file_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>.
+ <function>viewer_file_constructor</function>.
</para>
<para>
Once <function><link linkend="g-object-new">g_object_new</link></function> has obtained a reference to an initialized
class structure, it invokes its constructor method to create an instance of the new
- object, if the constructor has been overridden in <function>maman_bar_class_init</function>.
+ object, if the constructor has been overridden in <function>viewer_file_class_init</function>.
Overridden constructors must chain up to their 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>
+ constructor, we can use the <literal>viewer_file_parent_class</literal>
pointer that has been set up for us by the
<link linkend="G-DEFINE-TYPE:CAPS"><literal>G_DEFINE_TYPE</literal></link>
macro.
@@ -467,32 +467,32 @@ MamanBar *bar = g_object_new (MAMAN_TYPE_BAR, NULL);
enum
{
- PROP_MAMAN_NAME = 1,
- PROP_PAPA_NUMBER,
+ PROP_FILENAME = 1,
+ PROP_ZOOM_LEVEL,
N_PROPERTIES
};
static GParamSpec *obj_properties[N_PROPERTIES] = { NULL, };
static void
-maman_bar_set_property (GObject *object,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec)
+viewer_file_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
{
- MamanBar *self = MAMAN_BAR (object);
+ ViewerFile *self = VIEWER_FILE (object);
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);
+ case PROP_FILENAME:
+ g_free (self-&gt;priv-&gt;filename);
+ self-&gt;priv-&gt;filename = g_value_dup_string (value);
+ g_print ("filename: %s\n", self-&gt;priv-&gt;filename);
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);
+ case PROP_ZOOM_LEVEL:
+ self-&gt;priv-&gt;zoom_level = g_value_get_uint (value);
+ g_print ("zoom level: &percnt;u\n", self-&gt;priv-&gt;zoom_level);
break;
default:
@@ -503,21 +503,21 @@ maman_bar_set_property (GObject *object,
}
static void
-maman_bar_get_property (GObject *object,
- guint property_id,
- GValue *value,
- GParamSpec *pspec)
+viewer_file_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
{
- MamanBar *self = MAMAN_BAR (object);
+ ViewerFile *self = VIEWER_FILE (object);
switch (property_id)
{
- case PROP_MAMAN_NAME:
- g_value_set_string (value, self-&gt;priv-&gt;name);
+ case PROP_FILENAME:
+ g_value_set_string (value, self-&gt;priv-&gt;filename);
break;
- case PROP_PAPA_NUMBER:
- g_value_set_uchar (value, self-&gt;priv-&gt;papa_number);
+ case PROP_ZOOM_LEVEL:
+ g_value_set_uint (value, self-&gt;priv-&gt;zoom_level);
break;
default:
@@ -528,28 +528,28 @@ maman_bar_get_property (GObject *object,
}
static void
-maman_bar_class_init (MamanBarClass *klass)
+viewer_file_class_init (ViewerFileClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
- object_class-&gt;set_property = maman_bar_set_property;
- object_class-&gt;get_property = maman_bar_get_property;
+ object_class-&gt;set_property = viewer_file_set_property;
+ object_class-&gt;get_property = viewer_file_get_property;
- obj_properties[PROP_MAMAN_NAME] =
- g_param_spec_string ("maman-name",
- "Maman construct prop",
- "Set maman's name",
- "no-name-set" /* default value */,
+ obj_properties[PROP_FILENAME] =
+ g_param_spec_string ("filename",
+ "Filename",
+ "Name of the file to load and display from.",
+ NULL /* default value */,
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE));
- obj_properties[PROP_PAPA_NUMBER] =
- g_param_spec_uchar ("papa-number",
- "Number of current Papa",
- "Set/Get papa's number",
- 0 /* minimum value */,
- 10 /* maximum value */,
- 2 /* default value */,
- G_PARAM_READWRITE));
+ obj_properties[PROP_ZOOM_LEVEL] =
+ g_param_spec_uint ("zoom-level",
+ "Zoom level",
+ "Zoom level to view the file at.",
+ 0 /* minimum value */,
+ 10 /* maximum value */,
+ 2 /* default value */,
+ G_PARAM_READWRITE));
g_object_class_install_properties (object_class,
N_PROPERTIES,
@@ -560,15 +560,15 @@ maman_bar_class_init (MamanBarClass *klass)
/* Use */
/************************************************/
-GObject *bar;
+ViewerFile *file;
GValue val = G_VALUE_INIT;
-bar = g_object_new (MAMAN_TYPE_BAR, NULL);
+file = g_object_new (VIEWER_TYPE_FILE, NULL);
-g_value_init (&amp;val, G_TYPE_CHAR);
+g_value_init (&amp;val, G_TYPE_UINT);
g_value_set_char (&amp;val, 11);
-g_object_set_property (G_OBJECT (bar), "papa-number", &amp;val);
+g_object_set_property (G_OBJECT (file), "zoom-level", &amp;val);
g_value_unset (&amp;val);
</programlisting></informalexample>
@@ -577,7 +577,7 @@ g_value_unset (&amp;val);
<para>
<function><link linkend="g-object-set-property">g_object_set_property</link></function> first ensures a property
- with this name was registered in bar's <function>class_init</function> handler. If so it walks the class hierarchy,
+ with this name was registered in <emphasis>file</emphasis>'s <function>class_init</function> handler. If so it walks the class hierarchy,
from bottom-most most-derived type, to top-most fundamental type to find the class
which registered that property. It then tries to convert the user-provided
<link linkend="GValue"><type>GValue</type></link>
@@ -615,13 +615,13 @@ g_value_unset (&amp;val);
If the user's GValue had been set to a valid value, <function><link linkend="g-object-set-property">g_object_set_property</link></function>
would have proceeded with calling the object's
<function>set_property</function> class method. Here, since our
- implementation of <type>Foo</type> did override this method, execution would jump to
- <function>foo_set_property</function> after having retrieved from the
+ implementation of <type>ViewerFile</type> did override this method, execution would jump to
+ <function>viewer_file_set_property</function> after having retrieved from the
<link linkend="GParamSpec"><type>GParamSpec</type></link> the <emphasis>param_id</emphasis>
<footnote>
<para>
It should be noted that the param_id used here need only to uniquely identify each
- <link linkend="GParamSpec"><type>GParamSpec</type></link> within the <type>FooClass</type> such that the switch
+ <link linkend="GParamSpec"><type>GParamSpec</type></link> within the <type>ViewerFileClass</type> such that the switch
used in the set and get methods actually works. Of course, this locally-unique
integer is purely an optimization: it would have been possible to use a set of
<emphasis>if (strcmp (a, b) == 0) {} else if (strcmp (a, b) == 0) {}</emphasis> statements.
@@ -667,11 +667,11 @@ g_value_unset (&amp;val);
<function><link linkend="g-object-set-valist">g_object_set_valist</link></function> (variadic version) functions can be used to set
multiple properties at once. The client code shown above can then be re-written as:
<informalexample><programlisting>
-MamanBar *foo;
-foo = /* */;
-g_object_set (G_OBJECT (foo),
- "papa-number", 2,
- "maman-name", "test",
+ViewerFile *file;
+file = /* */;
+g_object_set (G_OBJECT (file),
+ "zoom-level", 6,
+ "filename", "~/some-file.txt",
NULL);
</programlisting></informalexample>
This saves us from managing the GValues that we were needing to handle when using
diff --git a/docs/reference/gobject/tut_gtype.xml b/docs/reference/gobject/tut_gtype.xml
index a833b56f2..df63c2dee 100644
--- a/docs/reference/gobject/tut_gtype.xml
+++ b/docs/reference/gobject/tut_gtype.xml
@@ -154,9 +154,9 @@ static void test_object (void)
GObject *obj;
GValue obj_vala = G_VALUE_INIT;
GValue obj_valb = G_VALUE_INIT;
- obj = g_object_new (MAMAN_TYPE_BAR, NULL);
+ obj = g_object_new (VIEWER_TYPE_FILE, NULL);
- g_value_init (&amp;obj_vala, MAMAN_TYPE_BAR);
+ g_value_init (&amp;obj_vala, VIEWER_TYPE_FILE);
g_value_set_object (&amp;obj_vala, obj);
g_value_init (&amp;obj_valb, G_TYPE_OBJECT);
@@ -164,7 +164,7 @@ static void test_object (void)
/* g_value_copy's semantics for G_TYPE_OBJECT types is to copy the reference.
* This function thus calls g_object_ref.
* It is interesting to note that the assignment works here because
- * MAMAN_TYPE_BAR is a G_TYPE_OBJECT.
+ * VIEWER_TYPE_FILE is a G_TYPE_OBJECT.
*/
g_value_copy (&amp;obj_vala, &amp;obj_valb);
@@ -206,27 +206,20 @@ static void test_object (void)
</para></listitem>
<listitem><para>
Use the <function>object_method</function> pattern for function names: to invoke
- the method named foo on an instance of object type bar, call
- <function>bar_foo</function>.
+ the method named <function>save</function> on an instance of object type <type>file</type>, call
+ <function>file_save</function>.
</para></listitem>
<listitem><para>Use prefixing to avoid namespace conflicts with other projects.
- If your library (or application) is named <emphasis>Maman</emphasis>,
- <footnote>
- <para>
- <emphasis>Maman</emphasis> is the French word for <emphasis>mum</emphasis>
- or <emphasis>mother</emphasis> — nothing more and nothing less.
- </para>
- </footnote>
-
- prefix all your function names with <emphasis>maman_</emphasis>.
- For example: <function>maman_object_method</function>.
+ If your library (or application) is named <emphasis>Viewer</emphasis>,
+ prefix all your function names with <emphasis>viewer_</emphasis>.
+ For example: <function>viewer_object_method</function>.
</para></listitem>
<listitem><para>Create a macro named <function>PREFIX_TYPE_OBJECT</function> which always
returns the GType for the associated object type. For an object of type
- <emphasis>Bar</emphasis> in a library prefixed by <emphasis>maman</emphasis>,
- use: <function>MAMAN_TYPE_BAR</function>.
+ <emphasis>File</emphasis> in the <emphasis>Viewer</emphasis> namespace,
+ use: <function>VIEWER_TYPE_FILE</function>.
This macro is implemented using a function named
- <function>prefix_object_get_type</function>.
+ <function>prefix_object_get_type</function>; for example, <function>viewer_file_get_type</function>.
</para></listitem>
<listitem>
<para>
@@ -241,25 +234,28 @@ static void test_object (void)
dynamic type safety by doing runtime checks. It is possible to disable the dynamic
type checks in production builds (see <link linkend="glib-building">building GLib</link>).
For example, we would create
- <function>MAMAN_BAR (obj)</function> to keep the previous example.
+ <function>VIEWER_FILE (obj)</function> to keep the previous example.
</para></listitem>
<listitem><para><function>PREFIX_OBJECT_CLASS (klass)</function>, which
is strictly equivalent to the previous casting macro: it does static casting with
dynamic type checking of class structures. It is expected to return a pointer
to a class structure of type <type>PrefixObjectClass</type>. An example is:
- <function>MAMAN_BAR_CLASS</function>.
+ <function>VIEWER_FILE_CLASS</function>.
</para></listitem>
- <listitem><para><function>PREFIX_IS_BAR (obj)</function>, which
+ <listitem><para><function>PREFIX_IS_OBJECT (obj)</function>, which
returns a <type>gboolean</type> which indicates whether the input
- object instance pointer is non-<type>NULL</type> and of type BAR.
+ object instance pointer is non-<type>NULL</type> and of type <type>OBJECT</type>.
+ For example, <function>VIEWER_IS_FILE</function>.
</para></listitem>
<listitem><para><function>PREFIX_IS_OBJECT_CLASS (klass)</function>, which returns a boolean
if the input class pointer is a pointer to a class of type OBJECT.
+ For example, <function>VIEWER_IS_FILE_CLASS</function>.
</para></listitem>
<listitem><para><function>PREFIX_OBJECT_GET_CLASS (obj)</function>,
which returns the class pointer associated to an instance of a given type. This macro
is used for static and dynamic type safety purposes (just like the previous casting
macros).
+ For example, <function>VIEWER_FILE_GET_CLASS</function>.
</para></listitem>
</itemizedlist>
</listitem>
@@ -268,8 +264,8 @@ static void test_object (void)
macros are provided in <filename>gtype.h</filename>. For the example we used above, we would
write the following trivial code to declare the macros:
<informalexample><programlisting>
-#define MAMAN_TYPE_BAR maman_bar_get_type ()
-G_DECLARE_FINAL_TYPE (MamanBar, maman_bar, MAMAN, BAR, GObject)
+#define VIEWER_TYPE_FILE viewer_file_get_type ()
+G_DECLARE_FINAL_TYPE (ViewerFile, viewer_file, VIEWER, FILE, GObject)
</programlisting></informalexample>
</para>
@@ -278,15 +274,15 @@ G_DECLARE_FINAL_TYPE (MamanBar, maman_bar, MAMAN, BAR, GObject)
<function><link linkend="G-DEFINE-TYPE:CAPS">G_DEFINE_TYPE</link></function>
macro to define a class:
<informalexample><programlisting>
-G_DEFINE_TYPE (MamanBar, maman_bar, G_TYPE_OBJECT)
+G_DEFINE_TYPE (ViewerFile, viewer_file, G_TYPE_OBJECT)
</programlisting></informalexample>
</para>
<para>
- Otherwise, the <function>maman_bar_get_type</function> function must be
+ Otherwise, the <function>viewer_file_get_type</function> function must be
implemented manually:
<informalexample><programlisting>
-GType maman_bar_get_type (void)
+GType viewer_file_get_type (void)
{
static GType type = 0;
if (type == 0) {
@@ -294,7 +290,7 @@ GType maman_bar_get_type (void)
/* You fill this structure. */
};
type = g_type_register_static (G_TYPE_OBJECT,
- "MamanBarType",
+ "ViewerFile",
&amp;info, 0);
}
return type;
@@ -384,45 +380,51 @@ GType maman_bar_get_type (void)
<informalexample><programlisting>
typedef struct {
GObject parent;
+
/* instance members */
- int field_a;
-} MamanBar;
+ gchar *filename;
+} ViewerFile;
typedef struct {
GObjectClass parent;
+
/* class members */
- void (*do_action_public_virtual) (MamanBar *self, guint8 i);
+ /* the first is public, pure and virtual */
+ void (*open) (ViewerFile *self,
+ GError **error);
- void (*do_action_public_pure_virtual) (MamanBar *self, guint8 i);
-} MamanBarClass;
+ /* the second is public and virtual */
+ void (*close) (ViewerFile *self,
+ GError **error);
+} ViewerFileClass;
-#define MAMAN_TYPE_BAR (maman_bar_get_type ())
+#define VIEWER_TYPE_FILE (viewer_file_get_type ())
GType
-maman_bar_get_type (void)
+viewer_file_get_type (void)
{
static GType type = 0;
if (type == 0) {
const GTypeInfo info = {
- sizeof (MamanBarClass),
+ sizeof (ViewerFileClass),
NULL, /* base_init */
NULL, /* base_finalize */
- (GClassInitFunc) foo_class_init,
+ (GClassInitFunc) viewer_file_class_init,
NULL, /* class_finalize */
NULL, /* class_data */
- sizeof (MamanBar),
+ sizeof (ViewerFile),
0, /* n_preallocs */
(GInstanceInitFunc) NULL /* instance_init */
};
type = g_type_register_static (G_TYPE_OBJECT,
- "BarType",
+ "ViewerFile",
&amp;info, 0);
}
return type;
}
</programlisting></informalexample>
- Upon the first call to <function>maman_bar_get_type</function>, the type named
- <emphasis>BarType</emphasis> will be registered in the type system as inheriting
+ Upon the first call to <function>viewer_file_get_type</function>, the type named
+ <emphasis>ViewerFile</emphasis> will be registered in the type system as inheriting
from the type <emphasis>G_TYPE_OBJECT</emphasis>.
</para>
@@ -650,28 +652,37 @@ B *b;
classed type which derives from
<link linkend="GTypeInterface"><type>GTypeInterface</type></link>. The following piece of code declares such an interface.
<informalexample><programlisting>
-#define MAMAN_TYPE_IBAZ maman_ibaz_get_type ()
-G_DECLARE_INTERFACE(MamanIbaz, maman_ibaz, MAMAN, IBAZ, GObject)
+#define VIEWER_TYPE_EDITABLE viewer_editable_get_type ()
+G_DECLARE_INTERFACE (ViewerEditable, viewer_editable, VIEWER, EDITABLE, GObject)
-struct _MamanIbazInterface {
+struct _ViewerEditableInterface {
GTypeInterface parent;
- void (*do_action) (MamanIbaz *self);
+ void (*save) (ViewerEditable *self,
+ GError **error);
};
-void maman_ibaz_do_action (MamanIbaz *self);
+void viewer_editable_save (ViewerEditable *self,
+ GError **error);
</programlisting></informalexample>
- The interface function, <function>maman_ibaz_do_action</function> is implemented
+ The interface function, <function>viewer_editable_save</function> is implemented
in a pretty simple way:
<informalexample><programlisting>
-void maman_ibaz_do_action (MamanIbaz *self)
+void
+viewer_editable_save (ViewerEditable *self,
+ GError **error)
{
- g_return_if_fail (MAMAN_IS_IBAZ (self));
+ ViewerEditableinterface *iface;
+
+ g_return_if_fail (VIEWER_IS_EDITABLE (self));
+ g_return_if_fail (error == NULL || *error == NULL);
- MAMAN_IBAZ_GET_INTERFACE (self)->do_action (self);
+ iface = VIEWER_EDITABLE_GET_INTERFACE (self);
+ g_return_if_fail (iface->save != NULL);
+ iface->save (self);
}
</programlisting></informalexample>
- <function>maman_ibaz_get_type</function> registers a type named <emphasis>MamanIbaz</emphasis>
+ <function>viewer_editable_get_type</function> registers a type named <emphasis>ViewerEditable</emphasis>
which inherits from <type>G_TYPE_INTERFACE</type>. All interfaces must
be children of <type>G_TYPE_INTERFACE</type> in the inheritance tree.
</para>
@@ -681,7 +692,7 @@ void maman_ibaz_do_action (MamanIbaz *self)
a <link linkend="GTypeInterface"><type>GTypeInterface</type></link> structure. The interface structure is expected to
contain the function pointers of the interface methods. It is good style to
define helper functions for each of the interface methods which simply call
- the interface's method directly: <function>maman_ibaz_do_action</function>
+ the interface's method directly: <function>viewer_editable_save</function>
is one of these.
</para>
@@ -691,20 +702,20 @@ void maman_ibaz_do_action (MamanIbaz *self)
to implement an interface:
<informalexample><programlisting>
static void
-maman_baz_do_action (MamanIbaz *self)
+viewer_file_save (ViewerEditable *self)
{
- g_print ("Baz implementation of Ibaz interface Action.\n");
+ g_print ("File implementation of editable interface save method.\n");
}
static void
-maman_ibaz_interface_init (MamanIbazInterface *iface)
+viewer_file_editable_interface_init (ViewerEditableInterface *iface)
{
- iface->do_action = maman_baz_do_action;
+ iface->save = viewer_file_save;
}
-G_DEFINE_TYPE_WITH_CODE (MamanBaz, maman_baz, G_TYPE_OBJECT,
- G_IMPLEMENT_INTERFACE (MAMAN_TYPE_IBAZ,
- maman_ibaz_interface_init));
+G_DEFINE_TYPE_WITH_CODE (ViewerFile, viewer_file, VIEWER_TYPE_FILE,
+ G_IMPLEMENT_INTERFACE (VIEWER_TYPE_EDITABLE,
+ viewer_file_editable_interface_init));
</programlisting></informalexample>
</para>
@@ -712,51 +723,52 @@ G_DEFINE_TYPE_WITH_CODE (MamanBaz, maman_baz, G_TYPE_OBJECT,
If your code does have special requirements, you must write a custom
<function>get_type</function> function to register your GType which
inherits from some <link linkend="GObject"><type>GObject</type></link>
- and which implements the interface <type>MamanIbaz</type>. For
- example, this code registers a new <type>MamanBaz</type> class which
- implements <type>MamanIbaz</type>:
+ and which implements the interface <type>ViewerEditable</type>. For
+ example, this code registers a new <type>ViewerFile</type> class which
+ implements <type>ViewerEditable</type>:
<informalexample><programlisting>
static void
-maman_baz_do_action (MamanIbaz *self)
+viewer_file_save (ViewerEditable *editable)
{
- g_print ("Baz implementation of Ibaz interface Action.\n");
+ g_print ("File implementation of editable interface save method.\n");
}
static void
-baz_interface_init (gpointer g_iface,
- gpointer iface_data)
+viewer_file_editable_interface_init (gpointer g_iface,
+ gpointer iface_data)
{
- MamanIbazInterface *iface = (MamanIbazInterface *)g_iface;
- iface->do_action = maman_baz_do_action;
+ ViewerEditableInterface *iface = g_iface;
+
+ iface->save = viewer_file_save;
}
GType
-maman_baz_get_type (void)
+viewer_file_get_type (void)
{
static GType type = 0;
if (type == 0) {
const GTypeInfo info = {
- sizeof (MamanBazClass),
+ sizeof (ViewerFileClass),
NULL, /* base_init */
NULL, /* base_finalize */
NULL, /* class_init */
NULL, /* class_finalize */
NULL, /* class_data */
- sizeof (MamanBaz),
+ sizeof (ViewerFile),
0, /* n_preallocs */
NULL /* instance_init */
};
- const GInterfaceInfo ibaz_info = {
- (GInterfaceInitFunc) baz_interface_init, /* interface_init */
- NULL, /* interface_finalize */
- NULL /* interface_data */
+ const GInterfaceInfo editable_info = {
+ (GInterfaceInitFunc) viewer_file_editable_interface_init, /* interface_init */
+ NULL, /* interface_finalize */
+ NULL /* interface_data */
};
- type = g_type_register_static (G_TYPE_OBJECT,
- "MamanBazType",
+ type = g_type_register_static (VIEWER_TYPE_FILE,
+ "ViewerFile",
&amp;info, 0);
g_type_add_interface_static (type,
- MAMAN_TYPE_IBAZ,
- &amp;ibaz_info);
+ VIEWER_TYPE_EDITABLE,
+ &amp;editable_info);
}
return type;
}
@@ -824,12 +836,12 @@ struct _GInterfaceInfo
<link linkend="G-DEFINE-INTERFACE:CAPS">G_DEFINE_INTERFACE</link>
which can be used to define the interface:
<informalexample><programlisting>
-G_DEFINE_INTERFACE (MamanIbaz, maman_ibaz, G_TYPE_OBJECT);
+G_DEFINE_INTERFACE (ViewerEditable, viewer_editable, G_TYPE_OBJECT);
static void
-maman_ibaz_default_init (MamanIbazInterface *iface)
+viewer_editable_default_init (ViewerEditableInterface *iface)
{
- /* add properties and signals here, will only called once */
+ /* add properties and signals here, will only be called once */
}
</programlisting></informalexample>
</para>
@@ -838,15 +850,15 @@ maman_ibaz_default_init (MamanIbazInterface *iface)
Or you can do that yourself in a GType function for your interface:
<informalexample><programlisting>
GType
-maman_ibaz_get_type (void)
+viewer_editable_get_type (void)
{
static volatile gsize type_id = 0;
if (g_once_init_enter (&amp;type_id)) {
const GTypeInfo info = {
- sizeof (MamanIbazInterface),
+ sizeof (ViewerEditableInterface),
NULL, /* base_init */
NULL, /* base_finalize */
- maman_ibaz_default_init, /* class_init */
+ viewer_editable_default_init, /* class_init */
NULL, /* class_finalize */
NULL, /* class_data */
0, /* instance_size */
@@ -854,15 +866,15 @@ maman_ibaz_get_type (void)
NULL /* instance_init */
};
GType type = g_type_register_static (G_TYPE_INTERFACE,
- "MamanIbaz",
- &amp;info, 0);
+ "ViewerEditable",
+ &amp;info, 0);
g_once_init_leave (&amp;type_id, type);
}
return type_id;
}
static void
-maman_ibaz_default_init (MamanIbazInterface *iface)
+viewer_editable_default_init (ViewerEditableInterface *iface)
{
/* add properties and signals here, will only called once */
}
diff --git a/docs/reference/gobject/tut_howto.xml b/docs/reference/gobject/tut_howto.xml
index 701551d2a..d436984fe 100644
--- a/docs/reference/gobject/tut_howto.xml
+++ b/docs/reference/gobject/tut_howto.xml
@@ -20,6 +20,15 @@
example to create a custom class hierarchy, or to subclass a GTK+ widget.
</para>
+ <para>
+ Throughout the chapter, a running example of a file viewer program is used,
+ which has a <type>ViewerFile</type> class to represent a single file being
+ viewed, and various derived classes for different types of files with
+ special functionality, such as audio files. The example application also
+ supports editing files (for example, to tweak a photo being viewed), using
+ a <type>ViewerEditable</type> interface.
+ </para>
+
<sect1 id="howto-gobject-header">
<title>Boilerplate header code</title>
@@ -39,13 +48,13 @@
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>
+ <filename>viewer-file.h</filename> and <filename>viewer-file.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>
+ typename: <filename>viewer_file.h</filename> and
+ <filename>viewer_file.c</filename>.</para></listitem>
<listitem><para>Do not separate the prefix from the typename:
- <filename>mamanbar.h</filename> and <filename>mamanbar.c</filename>.
+ <filename>viewerfile.h</filename> and <filename>viewerfile.c</filename>.
(this is the convention used by GTK+)</para></listitem>
</itemizedlist>
Some people like the first two solutions better: it makes reading file
@@ -58,9 +67,9 @@
</para>
<para>
- If you want to declare a type named ‘bar’ in namespace ‘maman’, name the
- type instance <function>MamanBar</function> and its class
- <function>MamanBarClass</function> (names are case sensitive). The
+ If you want to declare a type named ‘file’ in namespace ‘viewer’, name the
+ type instance <function>ViewerFile</function> and its class
+ <function>ViewerFileClass</function> (names are case sensitive). The
recommended method of declaring a type differs based on whether the type
is final or derivable.
</para>
@@ -80,8 +89,8 @@
*/
/* inclusion guard */
-#ifndef __MAMAN_BAR_H__
-#define __MAMAN_BAR_H__
+#ifndef __VIEWER_FILE_H__
+#define __VIEWER_FILE_H__
#include &lt;glib-object.h&gt;
/*
@@ -93,17 +102,17 @@ G_BEGIN_DECLS
/*
* Type declaration.
*/
-#define MAMAN_TYPE_BAR maman_bar_get_type ()
-G_DECLARE_FINAL_TYPE (MamanBar, maman_bar, MAMAN, BAR, GObject)
+#define VIEWER_TYPE_FILE viewer_file_get_type ()
+G_DECLARE_FINAL_TYPE (ViewerFile, viewer_file, VIEWER, FILE, GObject)
/*
* Method definitions.
*/
-MamanBar *maman_bar_new (void);
+ViewerFile *viewer_file_new (void);
G_END_DECLS
-#endif /* __MAMAN_BAR_H__ */
+#endif /* __VIEWER_FILE_H__ */
</programlisting></informalexample>
</para>
@@ -118,8 +127,8 @@ G_END_DECLS
*/
/* inclusion guard */
-#ifndef __MAMAN_BAR_H__
-#define __MAMAN_BAR_H__
+#ifndef __VIEWER_FILE_H__
+#define __VIEWER_FILE_H__
#include &lt;glib-object.h&gt;
/*
@@ -131,16 +140,16 @@ G_BEGIN_DECLS
/*
* Type declaration.
*/
-#define MAMAN_TYPE_BAR maman_bar_get_type ()
-G_DECLARE_DERIVABLE_TYPE (MamanBar, maman_bar, MAMAN, BAR, GObject)
+#define VIEWER_TYPE_FILE viewer_file_get_type ()
+G_DECLARE_DERIVABLE_TYPE (ViewerFile, viewer_file, VIEWER, FILE, GObject)
-struct _MamanBarClass
+struct _ViewerFileClass
{
GObjectClass parent_class;
/* Class virtual function fields. */
- void (* handle_frob) (MamanBar *bar,
- guint n_frobs);
+ void (* open) (ViewerFile *file,
+ GError **error);
/* Padding to allow adding up to 12 new virtual functions without
* breaking ABI. */
@@ -150,11 +159,11 @@ struct _MamanBarClass
/*
* Method definitions.
*/
-MamanBar *maman_bar_new (void);
+ViewerFile *viewer_file_new (void);
G_END_DECLS
-#endif /* __MAMAN_BAR_H__ */
+#endif /* __VIEWER_FILE_H__ */
</programlisting></informalexample>
</para>
@@ -162,9 +171,9 @@ G_END_DECLS
The convention for header includes is to add the minimum number of
<function>#include</function> directives to the top of your headers needed
to compile that header. This
- allows client code to simply <function>#include "maman-bar.h"</function>,
+ allows client code to simply <function>#include "viewer-file.h"</function>,
without needing to know the prerequisites for
- <filename>maman-bar.h</filename>.
+ <filename>viewer-file.h</filename>.
</para>
</sect1>
@@ -179,13 +188,13 @@ G_END_DECLS
* Copyright information
*/
-#include "maman-bar.h"
+#include "viewer-file.h"
/* Private structure definition. */
typedef struct {
- gint member1;
+ gchar *filename;
/* stuff */
-} MamanBarPrivate;
+} ViewerFilePrivate;
/*
* forward definitions
@@ -198,7 +207,7 @@ typedef struct {
<function>G_DECLARE_FINAL_TYPE</function>, its instance structure should
be defined in the C file:
<informalexample><programlisting>
-struct _MamanBar
+struct _ViewerFile
{
GObject parent_instance;
@@ -216,7 +225,7 @@ struct _MamanBar
reduce the amount of boilerplate needed. This macro will:
<itemizedlist>
- <listitem><simpara>implement the <function>maman_bar_get_type</function>
+ <listitem><simpara>implement the <function>viewer_file_get_type</function>
function</simpara></listitem>
<listitem><simpara>define a parent class pointer accessible from
the whole .c file</simpara></listitem>
@@ -229,7 +238,7 @@ struct _MamanBar
If the class has been declared as final using
<function>G_DECLARE_FINAL_TYPE</function> (see
<xref linkend="howto-gobject-header"/>), private data should be placed in
- the instance structure, <type>MamanBar</type>, and
+ the instance structure, <type>ViewerFile</type>, and
<function>G_DEFINE_TYPE</function> should be used instead of
<function>G_DEFINE_TYPE_WITH_PRIVATE</function>. The instance structure
for a final class is not exposed publicly, and is not embedded in the
@@ -240,11 +249,11 @@ struct _MamanBar
<function>G_DEFINE_TYPE_WITH_PRIVATE</function> must be used.
<informalexample><programlisting>
-G_DEFINE_TYPE (MamanBar, maman_bar, G_TYPE_OBJECT)
+G_DEFINE_TYPE (ViewerFile, viewer_file, G_TYPE_OBJECT)
</programlisting></informalexample>
or
<informalexample><programlisting>
-G_DEFINE_TYPE_WITH_PRIVATE (MamanBar, maman_bar, G_TYPE_OBJECT)
+G_DEFINE_TYPE_WITH_PRIVATE (ViewerFile, viewer_file, G_TYPE_OBJECT)
</programlisting></informalexample>
</para>
@@ -295,17 +304,17 @@ G_DEFINE_TYPE_WITH_PRIVATE (MamanBar, maman_bar, G_TYPE_OBJECT)
<para>
You should write the following code first:
<informalexample><programlisting>
-G_DEFINE_TYPE_WITH_PRIVATE (MamanBar, maman_bar, G_TYPE_OBJECT)
+G_DEFINE_TYPE_WITH_PRIVATE (ViewerFile, viewer_file, G_TYPE_OBJECT)
static void
-maman_bar_class_init (MamanBarClass *klass)
+viewer_file_class_init (ViewerFileClass *klass)
{
}
static void
-maman_bar_init (MamanBar *self)
+viewer_file_init (ViewerFile *self)
{
- MamanBarPrivate *priv = maman_bar_get_instance_private (self);
+ ViewerFilePrivate *priv = viewer_file_get_instance_private (self);
/* initialize all public and private members to reasonable default values.
* They are all automatically initialized to 0 to begin with. */
@@ -328,28 +337,36 @@ maman_bar_init (MamanBar *self)
<informalexample><programlisting>
enum
{
- PROP_MAMAN = 1,
+ PROP_FILENAME = 1,
+ PROP_ZOOM_LEVEL,
N_PROPERTIES
};
static GParamSpec *obj_properties[N_PROPERTIES] = { NULL, };
static void
-bar_class_init (MamanBarClass *klass)
+viewer_file_class_init (ViewerFileClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
- object_class->set_property = bar_set_property;
- object_class->get_property = bar_get_property;
-
- obj_properties[PROP_MAMAN] =
- g_param_spec_string ("maman",
- "Maman construct prop",
- "Set maman's name",
- "no-name-set" /* default value */,
- G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_READWRITE |
- G_PARAM_STATIC_STRINGS));
+ object_class->set_property = viewer_file_set_property;
+ object_class->get_property = viewer_file_get_property;
+
+ obj_properties[PROP_FILENAME] =
+ g_param_spec_string ("filename",
+ "Filename",
+ "Name of the file to load and display from.",
+ NULL /* default value */,
+ G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE));
+
+ obj_properties[PROP_ZOOM_LEVEL] =
+ g_param_spec_uint ("zoom-level",
+ "Zoom level",
+ "Zoom level to view the file at.",
+ 0 /* minimum value */,
+ 10 /* maximum value */,
+ 2 /* default value */,
+ G_PARAM_READWRITE));
g_object_class_install_properties (object_class,
N_PROPERTIES,
@@ -395,19 +412,20 @@ bar_class_init (MamanBarClass *klass)
instances in case of signal emission during the destruction sequence.
See <xref linkend="gobject-memory-cycles"/> for more information.
<informalexample><programlisting>
-struct _MamanBarPrivate
+struct _ViewerFilePrivate
{
- GObject *an_object;
+ gchar *filename;
+ guint zoom_level;
- gchar *a_string;
+ GInputStream *input_stream;
};
-G_DEFINE_TYPE_WITH_PRIVATE (MamanBar, maman_bar, G_TYPE_OBJECT)
+G_DEFINE_TYPE_WITH_PRIVATE (ViewerFile, viewer_file, G_TYPE_OBJECT)
static void
-maman_bar_dispose (GObject *gobject)
+viewer_file_dispose (GObject *gobject)
{
- MamanBarPrivate *priv = maman_bar_get_instance_private (MAMAN_BAR (gobject));
+ ViewerFilePrivate *priv = viewer_file_get_instance_private (VIEWER_FILE (gobject));
/* In dispose(), you are supposed to free all types referenced from this
* object which might themselves hold a reference to self. Generally,
@@ -419,44 +437,44 @@ maman_bar_dispose (GObject *gobject)
* calling g_object_unref() on an invalid GObject by setting the member
* NULL; g_clear_object() does this for us.
*/
- g_clear_object (&amp;priv->an_object);
+ g_clear_object (&amp;priv->input_stream);
/* Always chain up to the parent class; there is no need to check if
* the parent class implements the dispose() virtual function: it is
* always guaranteed to do so
*/
- G_OBJECT_CLASS (maman_bar_parent_class)->dispose (gobject);
+ G_OBJECT_CLASS (viewer_file_parent_class)->dispose (gobject);
}
static void
-maman_bar_finalize (GObject *gobject)
+viewer_file_finalize (GObject *gobject)
{
- MamanBarPrivate *priv = maman_bar_get_instance_private (MAMAN_BAR (gobject));
+ ViewerFilePrivate *priv = viewer_file_get_instance_private (VIEWER_FILE (gobject));
- g_free (priv->a_string);
+ g_free (priv->filename);
/* Always chain up to the parent class; as with dispose(), finalize()
* is guaranteed to exist on the parent's class virtual function table
*/
- G_OBJECT_CLASS (maman_bar_parent_class)->finalize (gobject);
+ G_OBJECT_CLASS (viewer_file_parent_class)->finalize (gobject);
}
static void
-maman_bar_class_init (MamanBarClass *klass)
+viewer_file_class_init (ViewerFileClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
- object_class->dispose = maman_bar_dispose;
- object_class->finalize = maman_bar_finalize;
+ object_class->dispose = viewer_file_dispose;
+ object_class->finalize = viewer_file_finalize;
}
static void
-maman_bar_init (MamanBar *self);
+viewer_file_init (ViewerFile *self);
{
- MamanBarPrivate *priv = maman_bar_get_instance_private (self);
+ ViewerFilePrivate *priv = viewer_file_get_instance_private (self);
- priv->an_object = g_object_new (MAMAN_TYPE_BAZ, NULL);
- priv->a_string = g_strdup ("Maman");
+ priv->input_stream = g_object_new (VIEWER_TYPE_INPUT_STREAM, NULL);
+ priv->filename = /* would be set as a property */;
}
</programlisting></informalexample>
</para>
@@ -502,13 +520,16 @@ maman_bar_init (MamanBar *self);
in the source file.
<informalexample><programlisting>
/* declaration in the header. */
-void maman_bar_do_action (MamanBar *self, /* parameters */);
+void viewer_file_open (ViewerFile *self,
+ GError **error);
/* implementation in the source file */
void
-maman_bar_do_action (MamanBar *self, /* parameters */)
+viewer_file_open (ViewerFile *self,
+ GError **error)
{
- g_return_if_fail (MAMAN_IS_BAR (self));
+ g_return_if_fail (VIEWER_IS_FILE (self));
+ g_return_if_fail (error == NULL || *error == NULL);
/* do stuff here. */
}
@@ -549,39 +570,43 @@ maman_bar_do_action (MamanBar *self, /* parameters */)
<link linkend="G-DECLARE-DERIVABLE-TYPE:CAPS"><function>G_DECLARE_DERIVABLE_TYPE</function></link>
so the class structure can be defined.
<informalexample><programlisting>
-/* declaration in maman-bar.h. */
-#define MAMAN_TYPE_BAR maman_bar_get_type ()
-G_DECLARE_DERIVABLE_TYPE (MamanBar, maman_bar, MAMAN, BAR, GObject)
+/* declaration in viewer-file.h. */
+#define VIEWER_TYPE_FILE viewer_file_get_type ()
+G_DECLARE_DERIVABLE_TYPE (ViewerFile, viewer_file, VIEWER, FILE, GObject)
-struct _MamanBarClass
+struct _ViewerFileClass
{
GObjectClass parent_class;
/* stuff */
- void (*do_action) (MamanBar *self, /* parameters */);
+ void (*open) (ViewerFile *self,
+ GError **error);
/* Padding to allow adding up to 12 new virtual functions without
* breaking ABI. */
gpointer padding[12];
};
-void maman_bar_do_action (MamanBar *self, /* parameters */);
+void viewer_file_open (ViewerFile *self,
+ GError **error);
-/* implementation in maman-bar.c */
+/* implementation in viewer-file.c */
void
-maman_bar_do_action (MamanBar *self, /* parameters */)
+viewer_file_open (ViewerFile *self,
+ GError **error)
{
- MamanBarClass *klass;
+ ViewerFileClass *klass;
- g_return_if_fail (MAMAN_IS_BAR (self));
+ g_return_if_fail (VIEWER_IS_FILE (self));
+ g_return_if_fail (error == NULL || *error == NULL);
- klass = MAMAN_BAR_GET_CLASS (self);
- g_return_if_fail (klass->do_action != NULL);
+ klass = VIEWER_FILE_GET_CLASS (self);
+ g_return_if_fail (klass->open != NULL);
- klass->do_action (self, /* parameters */);
+ klass->open (self, error);
}
</programlisting></informalexample>
- The code above simply redirects the <function>do_action</function> call
+ The code above simply redirects the <function>open</function> call
to the relevant virtual function.
</para>
@@ -589,58 +614,63 @@ maman_bar_do_action (MamanBar *self, /* parameters */)
It is possible to provide a default
implementation for this class method in the object's
<function>class_init</function> function: initialize the
- <function>klass-&gt;do_action</function> field to a pointer to the
+ <function>klass-&gt;open</function> field to a pointer to the
actual implementation.
By default, class methods that are not inherited are initialized to
<function>NULL</function>, and thus are to be considered "pure virtual".
<informalexample><programlisting>
static void
-maman_bar_real_do_action_two (MamanBar *self, /* parameters */)
+viewer_file_real_close (ViewerFile *self,
+ GError **error)
{
/* Default implementation for the virtual method. */
}
static void
-maman_bar_class_init (MamanBarClass *klass)
+viewer_file_class_init (ViewerFileClass *klass)
{
/* this is not necessary, except for demonstration purposes.
*
* pure virtual method: mandates implementation in children.
*/
- klass->do_action_one = NULL;
+ klass->open = NULL;
/* merely virtual method. */
- klass->do_action_two = maman_bar_real_do_action_two;
+ klass->close = viewer_file_real_close;
}
void
-maman_bar_do_action_one (MamanBar *self, /* parameters */)
+viewer_file_open (ViewerFile *self,
+ GError **error)
{
- MamanBarClass *klass;
+ ViewerFileClass *klass;
- g_return_if_fail (MAMAN_IS_BAR (self));
+ g_return_if_fail (VIEWER_IS_FILE (self));
+ g_return_if_fail (error == NULL || *error == NULL);
- klass = MAMAN_BAR_GET_CLASS (self);
+ klass = VIEWER_FILE_GET_CLASS (self);
/* if the method is purely virtual, then it is a good idea to
* check that it has been overridden before calling it, and,
* depending on the intent of the class, either ignore it silently
* or warn the user.
*/
- g_return_if_fail (klass->do_action != NULL);
- klass->do_action_one (self, /* parameters */);
+ g_return_if_fail (klass->open != NULL);
+ klass->open (self, error);
}
void
-maman_bar_do_action_two (MamanBar *self, /* parameters */)
+viewer_file_close (ViewerFile *self,
+ GError **error)
{
- MamanBarClass *klass;
+ ViewerFileClass *klass;
- g_return_if_fail (MAMAN_IS_BAR (self));
+ g_return_if_fail (VIEWER_IS_FILE (self));
+ g_return_if_fail (error == NULL || *error == NULL);
- klass = MAMAN_BAR_GET_CLASS (self);
- if (klass->do_action_two != NULL)
- klass->do_action_two (self, /* parameters */);
+ klass = VIEWER_FILE_GET_CLASS (self);
+ if (klass->close != NULL)
+ klass->close (self, error);
}
</programlisting></informalexample>
</para>
@@ -655,46 +685,55 @@ maman_bar_do_action_two (MamanBar *self, /* parameters */)
have a public function to call directly. The header
file contains only a declaration of the virtual function:
<informalexample><programlisting>
-/* declaration in maman-bar.h. */
-struct _MamanBarClass
+/* declaration in viewer-file.h. */
+struct _ViewerFileClass
{
GObjectClass parent;
- /* stuff */
- void (* helper_do_specific_action) (MamanBar *self, /* parameters */);
+ /* Public virtual method as before. */
+ void (*open) (ViewerFile *self,
+ GError **error);
+
+ /* Private helper function to work out whether the file can be loaded via
+ * memory mapped I/O, or whether it has to be read as a stream. */
+ gboolean (*can_memory_map) (ViewerFile *self);
/* Padding to allow adding up to 12 new virtual functions without
* breaking ABI. */
gpointer padding[12];
};
-void maman_bar_do_any_action (MamanBar *self, /* parameters */);
+void viewer_file_open (ViewerFile *self, GError **error);
</programlisting></informalexample>
These virtual functions are often used to delegate part of the job
to child classes:
<informalexample><programlisting>
/* this accessor function is static: it is not exported outside of this file. */
-static void
-maman_bar_do_specific_action (MamanBar *self, /* parameters */)
+static gboolean
+viewer_file_can_memory_map (ViewerFile *self)
{
- MAMAN_BAR_GET_CLASS (self)->do_specific_action (self, /* parameters */);
+ return VIEWER_FILE_GET_CLASS (self)->can_memory_map (self);
}
void
-maman_bar_do_any_action (MamanBar *self, /* parameters */)
+viewer_file_open (ViewerFile *self,
+ GError **error)
{
- g_return_if_fail (MAMAN_IS_BAR (self));
-
- /* random code here */
+ g_return_if_fail (VIEWER_IS_FILE (self));
+ g_return_if_fail (error == NULL || *error == NULL);
- /*
- * 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 load the file using memory mapped I/O, if the implementation of the
+ * class determines that is possible using its private virtual method.
*/
- maman_bar_do_specific_action (self, /* parameters */);
-
- /* other random code here */
+ if (viewer_file_can_memory_map (self))
+ {
+ /* Load the file using memory mapped I/O. */
+ }
+ else
+ {
+ /* Fall back to trying to load the file using streaming I/O… */
+ }
}
</programlisting></informalexample>
</para>
@@ -703,28 +742,33 @@ maman_bar_do_any_action (MamanBar *self, /* parameters */)
Again, it is possible to provide a default implementation for this
private virtual function:
<informalexample><programlisting>
-static void
-maman_bar_class_init (MamanBarClass *klass)
+static gboolean
+viewer_file_real_can_memory_map (ViewerFile *self)
{
- /* pure virtual method: mandates implementation in children. */
- klass->do_specific_action_one = NULL;
+ /* As an example, always return false. Or, potentially return true if the
+ * file is local. */
+ return FALSE;
+}
- /* merely virtual method. */
- klass->do_specific_action_two = maman_bar_real_do_specific_action_two;
+static void
+viewer_file_class_init (ViewerFileClass *klass)
+{
+ /* non-pure virtual method; does not have to be implemented in children. */
+ klass->can_memory_map = viewer_file_real_can_memory_map;
}
</programlisting></informalexample>
</para>
<para>
- Children can then implement the subclass with code such as:
+ Derived classes can then override the method with code such as:
<informalexample><programlisting>
static void
-maman_bar_subtype_class_init (MamanBarSubTypeClass *klass)
+viewer_audio_file_class_init (ViewerAudioFileClass *klass)
{
- MamanBarClass *bar_class = MAMAN_BAR_CLASS (klass);
+ ViewerFileClass *file_class = VIEWER_FILE_CLASS (klass);
/* implement pure virtual function. */
- bar_class->do_specific_action_one = maman_bar_subtype_do_specific_action_one;
+ file_class->can_memory_map = viewer_audio_file_can_memory_map;
}
</programlisting></informalexample>
</para>
@@ -822,30 +866,38 @@ b_method_to_call (B *obj, gint some_param)
* Copyright/Licensing information.
*/
-#ifndef __MAMAN_IBAZ_H__
-#define __MAMAN_IBAZ_H__
+#ifndef __VIEWER_EDITABLE_H__
+#define __VIEWER_EDITABLE_H__
#include &lt;glib-object.h&gt;
G_BEGIN_DECLS
-#define MAMAN_TYPE_IBAZ maman_ibaz_get_type ()
-G_DECLARE_INTERFACE (MamanIbaz, maman_ibaz, MAMAN, IBAZ, GObject)
+#define VIEWER_TYPE_EDITABLE viewer_editable_get_type ()
+G_DECLARE_INTERFACE (ViewerEditable, viewer_editable, VIEWER, EDITABLE, GObject)
-struct _MamanIbazInterface
+struct _ViewerEditableInterface
{
GTypeInterface parent_iface;
- void (*do_action) (MamanIbaz *self);
- void (*do_something) (MamanIbaz *self);
+ void (*save) (ViewerEditable *self,
+ GError **error);
+ void (*undo) (ViewerEditable *self,
+ guint n_steps);
+ void (*redo) (ViewerEditable *self,
+ guint n_steps);
};
-void maman_ibaz_do_action (MamanIbaz *self);
-void maman_ibaz_do_something (MamanIbaz *self);
+void viewer_editable_save (ViewerEditable *self,
+ GError **error);
+void viewer_editable_undo (ViewerEditable *self,
+ guint n_steps);
+void viewer_editable_redo (ViewerEditable *self,
+ guint n_steps);
G_END_DECLS
-#endif /* __MAMAN_IBAZ_H__ */
+#endif /* __VIEWER_EDITABLE_H__ */
</programlisting></informalexample>
This code is the same as the code for a normal <link linkend="GType"><type>GType</type></link>
which derives from a <link linkend="GObject"><type>GObject</type></link> except for a few details:
@@ -856,58 +908,82 @@ G_END_DECLS
<link linkend="G-DECLARE-INTERFACE:CAPS"><function>G_DECLARE_INTERFACE</function></link>).
</para></listitem>
<listitem><para>
- The instance type, <type>MamanIbaz</type> is not fully defined: it is
+ The instance type, <type>ViewerEditable</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
+ The parent of the <type>ViewerEditableInterface</type> is
<type>GTypeInterface</type>, not <type>GObjectClass</type>.
</para></listitem>
</itemizedlist>
</para>
<para>
- The implementation of the <type>MamanIbaz</type> type itself is trivial:
+ The implementation of the <type>ViewerEditable</type> type itself is trivial:
<itemizedlist>
<listitem><para><function><link linkend="G-DEFINE-INTERFACE:CAPS">G_DEFINE_INTERFACE</link></function>
- creates a <function>maman_ibaz_get_type</function> function which registers the
+ creates a <function>viewer_editable_get_type</function> function which registers the
type in the type system. The third argument is used to define a
<link linkend="howto-interface-prerequisite">prerequisite interface</link>
(which we'll talk about more later). Just pass <code>0</code> for this
argument when an interface has no prerequisite.
</para></listitem>
- <listitem><para><function>maman_ibaz_default_init</function> is expected
+ <listitem><para><function>viewer_editable_default_init</function> is expected
to register the interface's signals if there are any (we will see a bit
later how to use them).</para></listitem>
- <listitem><para>The interface methods <function>maman_ibaz_do_action</function>
- and <function>maman_ibaz_do_something</function> dereference the interface
+ <listitem><para>The interface methods <function>viewer_editable_save</function>,
+ <function>viewer_editable_undo</function> and <function>viewer_editable_redo</function> dereference the interface
structure to access its associated interface function and call it.
</para></listitem>
</itemizedlist>
<informalexample><programlisting>
-G_DEFINE_INTERFACE (MamanIbaz, maman_ibaz, G_TYPE_OBJECT);
+G_DEFINE_INTERFACE (ViewerEditable, viewer_editable, G_TYPE_OBJECT);
static void
-maman_ibaz_default_init (MamanIbazInterface *iface)
+viewer_editable_default_init (ViewerEditableInterface *iface)
{
/* add properties and signals to the interface here */
}
void
-maman_ibaz_do_action (MamanIbaz *self)
+viewer_editable_save (ViewerEditable *self,
+ GError **error)
{
- g_return_if_fail (MAMAN_IS_IBAZ (self));
+ ViewerEditableInterface *iface;
- MAMAN_IBAZ_GET_IFACE (self)->do_action (self);
+ g_return_if_fail (VIEWER_IS_EDITABLE (self));
+ g_return_if_fail (error == NULL || *error == NULL);
+
+ iface = VIEWER_EDITABLE_GET_IFACE (self);
+ g_return_if_fail (iface->save != NULL);
+ iface->save (self, error);
}
void
-maman_ibaz_do_something (MamanIbaz *self)
+viewer_editable_undo (ViewerEditable *self,
+ guint n_steps)
{
- g_return_if_fail (MAMAN_IS_IBAZ (self));
+ ViewerEditableInterface *iface;
+
+ g_return_if_fail (VIEWER_IS_EDITABLE (self));
- MAMAN_IBAZ_GET_IFACE (self)->do_something (self);
+ iface = VIEWER_EDITABLE_GET_IFACE (self);
+ g_return_if_fail (iface->undo != NULL);
+ iface->undo (self, n_steps);
+}
+
+void
+viewer_editable_redo (ViewerEditable *self,
+ guint n_steps)
+{
+ ViewerEditableInterface *iface;
+
+ g_return_if_fail (VIEWER_IS_EDITABLE (self));
+
+ iface = VIEWER_EDITABLE_GET_IFACE (self);
+ g_return_if_fail (iface->redo != NULL);
+ iface->redo (self, n_steps);
}
</programlisting></informalexample>
</para>
@@ -926,7 +1002,7 @@ maman_ibaz_do_something (MamanIbaz *self)
</para>
<para>
- The second step is to implement <type>MamanBaz</type> by defining
+ The second step is to implement <type>ViewerFile</type> by defining
it using
<function><link linkend="G-DEFINE-TYPE-WITH-CODE:CAPS">G_DEFINE_TYPE_WITH_CODE</link></function>
and
@@ -934,11 +1010,11 @@ maman_ibaz_do_something (MamanIbaz *self)
instead of
<function><link linkend="G-DEFINE-TYPE:CAPS">G_DEFINE_TYPE</link></function>:
<informalexample><programlisting>
-static void maman_ibaz_interface_init (MamanIbazInterface *iface);
+static void viewer_file_editable_interface_init (ViewerEditableInterface *iface);
-G_DEFINE_TYPE_WITH_CODE (MamanBar, maman_bar, G_TYPE_OBJECT,
- G_IMPLEMENT_INTERFACE (MAMAN_TYPE_IBAZ,
- maman_ibaz_interface_init))
+G_DEFINE_TYPE_WITH_CODE (ViewerFile, viewer_file, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (VIEWER_TYPE_EDITABLE,
+ viewer_file_editable_interface_init))
</programlisting></informalexample>
This definition is very much like all the similar functions seen
previously. The only interface-specific code present here is the use of
@@ -952,35 +1028,46 @@ G_DEFINE_TYPE_WITH_CODE (MamanBar, maman_bar, G_TYPE_OBJECT,
</para></note>
<para>
- <function>maman_baz_interface_init</function>, the interface
+ <function>viewer_file_editable_interface_init</function>, the interface
initialization function: inside it every virtual method of the interface
must be assigned to its implementation:
<informalexample><programlisting>
static void
-maman_baz_do_action (MamanBaz *self)
+viewer_file_editable_save (ViewerFile *self,
+ GError **error)
{
- g_print ("Baz implementation of Ibaz interface Action: 0x%x.\n",
- self->instance_member);
+ g_print ("File implementation of editable interface save method: %s.\n",
+ self->filename);
}
static void
-maman_baz_do_something (MamanBaz *self)
+viewer_file_editable_undo (ViewerFile *self,
+ guint n_steps)
{
- g_print ("Baz implementation of Ibaz interface Something: 0x%x.\n",
- self->instance_member);
+ g_print ("File implementation of editable interface undo method: %s.\n",
+ self->filename);
}
static void
-maman_ibaz_interface_init (MamanIbazInterface *iface)
+viewer_file_editable_redo (ViewerFile *self,
+ guint n_steps)
{
- iface->do_action = maman_baz_do_action;
- iface->do_something = maman_baz_do_something;
+ g_print ("File implementation of editable interface redo method: %s.\n",
+ self->filename);
}
static void
-maman_baz_init (MamanBaz *self)
+viewer_file_editable_interface_init (ViewerEditableInterface *iface)
{
- self->instance_member = 0xdeadbeef;
+ iface->save = viewer_file_editable_save;
+ iface->undo = viewer_file_editable_undo;
+ iface->redo = viewer_file_editable_redo;
+}
+
+static void
+viewer_file_init (ViewerFile *self)
+{
+ /* Instance variable initialisation code. */
}
</programlisting></informalexample>
</para>
@@ -1003,74 +1090,87 @@ maman_baz_init (MamanBaz *self)
Java's interface I1 extends interface I2. The example below shows
the GObject equivalent:
<informalexample><programlisting>
-/* Make the MamanIbar interface require MamanIbaz interface. */
-G_DEFINE_INTERFACE (MamanIbar, maman_ibar, MAMAN_TYPE_IBAZ);
+/* Make the ViewerEditableLossy interface require ViewerEditable interface. */
+G_DEFINE_INTERFACE (ViewerEditableLossy, viewer_editable_lossy, VIEWER_TYPE_EDITABLE);
</programlisting></informalexample>
In the <function><link linkend="G-DEFINE-INTERFACE:CAPS">G_DEFINE_INTERFACE</link></function>
call above, the third parameter defines the prerequisite type. This
is the GType of either an interface or a class. In this case
- the <type>MamanIbaz</type> interface is a prerequisite of
- <type>MamanIbar</type>. The code
+ the <type>ViewerEditable</type> interface is a prerequisite of
+ <type>ViewerEditableLossy</type>. The code
below shows how an implementation can implement both interfaces and
register their implementations:
<informalexample><programlisting>
static void
-maman_ibar_do_another_action (MamanIbar *ibar)
+viewer_file_editable_lossy_compress (ViewerEditableLossy *editable)
{
- MamanBar *self = MAMAN_BAR (ibar);
+ ViewerFile *self = VIEWER_FILE (editable);
+
+ g_print ("File implementation of lossy editable interface compress method: %s.\n",
+ self->filename);
+}
- g_print ("Bar implementation of IBar interface Another Action: 0x%x.\n",
- self->instance_member);
+static void
+viewer_file_editable_lossy_interface_init (ViewerEditableLossyInterface *iface)
+{
+ iface->compress = viewer_file_editable_lossy_compress;
}
static void
-maman_ibar_interface_init (MamanIbarInterface *iface)
+viewer_file_editable_save (ViewerEditable *editable,
+ GError **error)
{
- iface->do_another_action = maman_ibar_do_another_action;
+ ViewerFile *self = VIEWER_FILE (editable);
+
+ g_print ("File implementation of editable interface save method: %s.\n",
+ self->filename);
}
static void
-maman_ibaz_do_action (MamanIbaz *ibaz)
+viewer_file_editable_undo (ViewerEditable *editable,
+ guint n_steps)
{
- MamanBar *self = MAMAN_BAR (ibaz);
+ ViewerFile *self = VIEWER_FILE (editable);
- g_print ("Bar implementation of Ibaz interface Action: 0x%x.\n",
- self->instance_member);
+ g_print ("File implementation of editable interface undo method: %s.\n",
+ self->filename);
}
static void
-maman_ibaz_do_something (MamanIbaz *ibaz)
+viewer_file_editable_redo (ViewerEditable *editable,
+ guint n_steps)
{
- MamanBar *self = MAMAN_BAR (ibaz);
+ ViewerFile *self = VIEWER_FILE (editable);
- g_print ("Bar implementation of Ibaz interface Something: 0x%x.\n",
- self->instance_member);
+ g_print ("File implementation of editable interface redo method: %s.\n",
+ self->filename);
}
static void
-maman_ibaz_interface_init (MamanIbazInterface *iface)
+viewer_file_editable_interface_init (ViewerEditableInterface *iface)
{
- iface->do_action = maman_ibaz_do_action;
- iface->do_something = maman_ibaz_do_something;
+ iface->save = viewer_file_editable_save;
+ iface->undo = viewer_file_editable_undo;
+ iface->redo = viewer_file_editable_redo;
}
static void
-maman_bar_class_init (MamanBarClass *klass)
+viewer_file_class_init (ViewerFileClass *klass)
{
/* Nothing here. */
}
static void
-maman_bar_init (MamanBar *self)
+viewer_file_init (ViewerFile *self)
{
- self->instance_member = 0x666;
+ /* Instance variable initialisation code. */
}
-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))
+G_DEFINE_TYPE_WITH_CODE (ViewerFile, viewer_file, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (VIEWER_TYPE_EDITABLE,
+ viewer_file_editable_interface_init)
+ G_IMPLEMENT_INTERFACE (VIEWER_TYPE_EDITABLE_LOSSY,
+ viewer_file_editable_lossy_interface_init))
</programlisting></informalexample>
It is very important to notice that the order in which interface
implementations are added to the main object is not random:
@@ -1096,19 +1196,22 @@ G_DEFINE_TYPE_WITH_CODE (MamanBar, maman_bar, G_TYPE_OBJECT,
</para>
<para>
- To include a property named 'name' of type <type>string</type> in the
- <type>MamanIbaz</type> interface example code above, we only need to
- add one call in <function>maman_ibaz_default_init</function> as shown
+ To include a property named 'autosave-frequency' of type <type>gdouble</type> in the
+ <type>ViewerEditable</type> interface example code above, we only need to
+ add one call in <function>viewer_editable_default_init</function> as shown
below:
<informalexample><programlisting>
static void
-maman_ibaz_default_init (MamanIbazInterface *iface)
+viewer_editable_default_init (ViewerEditableInterface *iface)
{
g_object_interface_install_property (iface,
- g_param_spec_string ("name",
- "Name",
- "Name of the MamanIbaz",
- "maman",
+ g_param_spec_double ("autosave-frequency",
+ "Autosave frequency",
+ "Frequency (in per-seconds) to autosave backups of the editable content at. "
+ "Or zero to disable autosaves.",
+ 0.0, /* minimum */
+ G_MAXDOUBLE, /* maximum */
+ 0.0, /* default */
G_PARAM_READWRITE));
}
</programlisting></informalexample>
@@ -1130,35 +1233,33 @@ maman_ibaz_default_init (MamanIbazInterface *iface)
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:
+ <type>ViewerFile</type> declaration and implementation above:
<informalexample><programlisting>
-struct _MamanBaz
+struct _ViewerFile
{
GObject parent_instance;
- gint instance_member;
- gchar *name;
+ gdouble autosave_frequency;
};
enum
{
- PROP_NAME = 1,
+ PROP_AUTOSAVE_FREQUENCY = 1,
N_PROPERTIES
};
static void
-maman_baz_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
+viewer_file_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
{
- MamanBaz *baz = MAMAN_BAZ (object);
+ ViewerFile *file = VIEWER_FILE (object);
switch (prop_id)
{
- case PROP_NAME:
- g_free (baz->name);
- baz->name = g_value_dup_string (value);
+ case PROP_AUTOSAVE_FREQUENCY:
+ file->autosave_frequency = g_value_get_double (value);
break;
default:
@@ -1168,17 +1269,17 @@ maman_baz_set_property (GObject *object,
}
static void
-maman_baz_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
+viewer_file_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
{
- MamanBaz *baz = MAMAN_BAZ (object);
+ ViewerFile *file = VIEWER_FILE (object);
switch (prop_id)
{
- case PROP_NAME:
- g_value_set_string (value, baz->name);
+ case PROP_AUTOSAVE_FREQUENCY:
+ g_value_set_double (value, file->autosave_frequency);
break;
default:
@@ -1188,14 +1289,14 @@ maman_baz_get_property (GObject *object,
}
static void
-maman_baz_class_init (MamanBazClass *klass)
+viewer_file_class_init (ViewerFileClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
- object_class->set_property = maman_baz_set_property;
- object_class->get_property = maman_baz_get_property;
+ object_class->set_property = viewer_file_set_property;
+ object_class->get_property = viewer_file_get_property;
- g_object_class_override_property (object_class, PROP_NAME, "name");
+ g_object_class_override_property (object_class, PROP_AUTOSAVE_FREQUENCY, "autosave-frequency");
}
</programlisting></informalexample>
</para>
@@ -1213,44 +1314,45 @@ maman_baz_class_init (MamanBazClass *klass)
</para>
<para>
- In this example, <type>MamanDerivedBaz</type> is derived from
- <type>MamanBaz</type>. Both implement the <type>MamanIbaz</type>
- interface. <type>MamanDerivedBaz</type> only implements one method of the
- <type>MamanIbaz</type> interface and uses the base class implementation of
+ In this example, <type>ViewerAudioFile</type> is derived from
+ <type>ViewerFile</type>. Both implement the <type>ViewerEditable</type>
+ interface. <type>ViewerAudioFile</type> only implements one method of the
+ <type>ViewerEditable</type> interface and uses the base class implementation of
the other.
<informalexample><programlisting>
static void
-maman_derived_ibaz_do_action (MamanIbaz *ibaz)
+viewer_audio_file_editable_save (ViewerEditable *editable,
+ GError **error)
{
- MamanDerivedBaz *self = MAMAN_DERIVED_BAZ (ibaz);
+ ViewerAudioFile *self = VIEWER_AUDIO_FILE (editable);
- g_print ("DerivedBaz implementation of Ibaz interface Action\n");
+ g_print ("Audio file implementation of editable interface save method.\n");
}
static void
-maman_derived_ibaz_interface_init (MamanIbazInterface *iface)
+viewer_audio_file_editable_interface_init (ViewerEditableInterface *iface)
{
- /* Override the implementation of do_action */
- iface->do_action = maman_derived_ibaz_do_action;
+ /* Override the implementation of save(). */
+ iface->save = viewer_audio_file_editable_save;
/*
- * Leave iface->do_something alone, it is already set to the
+ * Leave iface->undo and ->redo alone, they are already set to the
* base class implementation.
*/
}
-G_DEFINE_TYPE_WITH_CODE (MamanDerivedBaz, maman_derived_baz, MAMAN_TYPE_BAZ,
- G_IMPLEMENT_INTERFACE (MAMAN_TYPE_IBAZ,
- maman_derived_ibaz_interface_init))
+G_DEFINE_TYPE_WITH_CODE (ViewerAudioFile, viewer_audio_file, VIEWER_TYPE_FILE,
+ G_IMPLEMENT_INTERFACE (VIEWER_TYPE_EDITABLE,
+ viewer_audio_file_editable_interface_init))
static void
-maman_derived_baz_class_init (MamanDerivedBazClass *klass)
+viewer_audio_file_class_init (ViewerAudioFileClass *klass)
{
/* Nothing here. */
}
static void
-maman_derived_baz_init (MamanDerivedBaz *self)
+viewer_audio_file_init (ViewerAudioFile *self)
{
/* Nothing here. */
}
@@ -1272,43 +1374,44 @@ maman_derived_baz_init (MamanDerivedBaz *self)
</para>
<para>
- In this example <type>MamanDerivedBaz</type> overrides the
- <function>do_action</function> interface method. In its overridden method
+ In this example <type>ViewerAudioFile</type> overrides the
+ <function>save</function> interface method. In its overridden method
it calls the base class implementation of the same interface method.
<informalexample><programlisting>
-static MamanIbazInterface *maman_ibaz_parent_interface = NULL;
+static ViewerEditableInterface *viewer_editable_parent_interface = NULL;
static void
-maman_derived_ibaz_do_action (MamanIbaz *ibaz)
+viewer_audio_file_editable_save (ViewerEditable *editable,
+ GError **error)
{
- MamanDerivedBaz *self = MAMAN_DERIVED_BAZ (ibaz);
+ ViewerAudioFile *self = VIEWER_AUDIO_FILE (editable);
- g_print ("DerivedBaz implementation of Ibaz interface Action\n");
+ g_print ("Audio file implementation of editable interface save method.\n");
/* Now call the base implementation */
- maman_ibaz_parent_interface->do_action (ibaz);
+ viewer_editable_parent_interface->save (editable, error);
}
static void
-maman_derived_ibaz_interface_init (MamanIbazInterface *iface)
+viewer_audio_file_editable_interface_init (ViewerEditableInterface *iface)
{
- maman_ibaz_parent_interface = g_type_interface_peek_parent (iface);
+ viewer_editable_parent_interface = g_type_interface_peek_parent (iface);
- iface->do_action = maman_derived_ibaz_do_action;
+ iface->save = viewer_audio_file_editable_save;
}
-G_DEFINE_TYPE_WITH_CODE (MamanDerivedBaz, maman_derived_baz, MAMAN_TYPE_BAZ,
- G_IMPLEMENT_INTERFACE (MAMAN_TYPE_IBAZ,
- maman_derived_ibaz_interface_init))
+G_DEFINE_TYPE_WITH_CODE (ViewerAudioFile, viewer_audio_file, VIEWER_TYPE_FILE,
+ G_IMPLEMENT_INTERFACE (VIEWER_TYPE_EDITABLE,
+ viewer_audio_file_editable_interface_init))
static void
-maman_derived_baz_class_init (MamanDerivedBazClass *klass)
+viewer_audio_file_class_init (ViewerAudioFileClass *klass)
{
/* Nothing here. */
}
static void
-maman_derived_baz_init (MamanDerivedBaz *self)
+viewer_audio_file_init (ViewerAudioFile *self)
{
/* Nothing here. */
}
@@ -1344,22 +1447,22 @@ maman_derived_baz_init (MamanDerivedBaz *self)
<para>
The most basic use of signals is to implement event
- notification. For example, given a <type>MamanFile</type> object with
+ notification. For example, given a <type>ViewerFile</type> object with
a <function>write</function> method, a signal could be emitted whenever
the file is changed using that method.
The code below shows how the user can connect a callback to the
"changed" signal.
<informalexample><programlisting>
-file = g_object_new (MAMAN_FILE_TYPE, NULL);
+file = g_object_new (VIEWER_FILE_TYPE, NULL);
g_signal_connect (file, "changed", (GCallback) changed_event, NULL);
-maman_file_write (file, buffer, strlen (buffer));
+viewer_file_write (file, buffer, strlen (buffer));
</programlisting></informalexample>
</para>
<para>
- The <type>MamanFile</type> signal is registered in the
+ The <type>ViewerFile</type> signal is registered in the
<function>class_init</function> function:
<informalexample><programlisting>
file_signals[CHANGED] =
@@ -1374,14 +1477,14 @@ file_signals[CHANGED] =
0 /* n_params */,
NULL /* param_types */);
</programlisting></informalexample>
- and the signal is emitted in <function>maman_file_write</function>:
+ and the signal is emitted in <function>viewer_file_write</function>:
<informalexample><programlisting>
void
-maman_file_write (MamanFile *self,
- const guchar *buffer,
- gssize size)
+viewer_file_write (ViewerFile *self,
+ const guint8 *buffer,
+ gsize size)
{
- g_return_if_fail (MAMAN_IS_FILE (self));
+ g_return_if_fail (VIEWER_IS_FILE (self));
g_return_if_fail (buffer != NULL || size == 0);
/* First write data. */