mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-02-03 17:56:17 +01:00
docs: syntax highlighting for the code examples
In the sections Concepts, Tools and Tutorial. https://bugzilla.gnome.org/show_bug.cgi?id=736914
This commit is contained in:
parent
1c6df7aaeb
commit
66ef10eec9
@ -51,9 +51,9 @@ passed as additional arguments on the command line.
|
||||
<para>
|
||||
The marshaller lists are processed line by line, a line can contain a
|
||||
comment in the form of
|
||||
<programlisting>
|
||||
<informalexample><programlisting>
|
||||
# this is a comment
|
||||
</programlisting>
|
||||
</programlisting></informalexample>
|
||||
or a marshaller specification of the form
|
||||
<programlisting>
|
||||
<replaceable>RTYPE</replaceable>:<replaceable>PTYPE</replaceable>
|
||||
@ -329,7 +329,7 @@ Print version and exit.
|
||||
<para>
|
||||
To generate marshallers for the following callback functions:
|
||||
</para>
|
||||
<programlisting>
|
||||
<informalexample><programlisting>
|
||||
void foo (gpointer data1,
|
||||
gpointer data2);
|
||||
void bar (gpointer data1,
|
||||
@ -339,7 +339,7 @@ gfloat baz (gpointer data1,
|
||||
gboolean param1,
|
||||
guchar param2,
|
||||
gpointer data2);
|
||||
</programlisting>
|
||||
</programlisting></informalexample>
|
||||
<para>
|
||||
The <filename>marshaller.list</filename> file has to look like this:
|
||||
</para>
|
||||
@ -368,7 +368,7 @@ g_cclosure_user_marshal_FLOAT__BOOLEAN_UCHAR().
|
||||
They can be used directly for GClosures or be passed in as the
|
||||
GSignalCMarshaller c_marshaller; argument upon creation of signals:
|
||||
</para>
|
||||
<programlisting>
|
||||
<informalexample><programlisting>
|
||||
GClosure *cc_foo, *cc_bar, *cc_baz;
|
||||
|
||||
cc_foo = g_cclosure_new (NULL, foo, NULL);
|
||||
@ -377,7 +377,7 @@ cc_bar = g_cclosure_new (NULL, bar, NULL);
|
||||
g_closure_set_marshal (cc_bar, g_cclosure_user_marshal_VOID__INT);
|
||||
cc_baz = g_cclosure_new (NULL, baz, NULL);
|
||||
g_closure_set_marshal (cc_baz, g_cclosure_user_marshal_FLOAT__BOOLEAN_UCHAR);
|
||||
</programlisting>
|
||||
</programlisting></informalexample>
|
||||
</refsect1>
|
||||
<refsect1><title>See also</title>
|
||||
<para>
|
||||
|
@ -50,13 +50,13 @@ in @ characters.
|
||||
Certain keywords enclosed in @ characters will be substituted in the
|
||||
emitted text. For the substitution examples of the keywords below,
|
||||
the following example enum definition is assumed:
|
||||
<programlisting>
|
||||
<informalexample><programlisting>
|
||||
typedef enum
|
||||
{
|
||||
PREFIX_THE_XVALUE = 1 << 3,
|
||||
PREFIX_ANOTHER_VALUE = 1 << 4
|
||||
} PrefixTheXEnum;
|
||||
</programlisting>
|
||||
</programlisting></informalexample>
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>@EnumName@</term>
|
||||
@ -185,7 +185,7 @@ Per value definition, the options "skip" and "nick" are supported.
|
||||
The former causes the value to be skipped, and the latter can be used to
|
||||
specify the otherwise auto-generated nickname.
|
||||
Examples:
|
||||
<programlisting>
|
||||
<informalexample><programlisting>
|
||||
typedef enum /*< skip >*/
|
||||
{
|
||||
PREFIX_FOO
|
||||
@ -197,7 +197,7 @@ typedef enum /*< flags,prefix=PREFIX >*/
|
||||
PREFIX_THE_SECOND_VALUE,
|
||||
PREFIX_THE_THIRD_VALUE, /*< nick=the-last-value >*/
|
||||
} PrefixTheFlagsEnum;
|
||||
</programlisting>
|
||||
</programlisting></informalexample>
|
||||
</para>
|
||||
</refsect2>
|
||||
</refsect1>
|
||||
@ -272,10 +272,10 @@ Template for auto-generated comments, the default (for C code generations) is
|
||||
<listitem><para>
|
||||
Read templates from the given file. The templates are enclosed in
|
||||
specially-formatted C comments
|
||||
<programlisting>
|
||||
<informalexample><programlisting>
|
||||
/*** BEGIN section ***/
|
||||
/*** END section ***/
|
||||
</programlisting>
|
||||
</programlisting></informalexample>
|
||||
where section may be <literal>file-header</literal>,
|
||||
<literal>file-production</literal>, <literal>file-tail</literal>,
|
||||
<literal>enumeration-production</literal>, <literal>value-header</literal>,
|
||||
|
@ -51,16 +51,16 @@
|
||||
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>
|
||||
<informalexample><programlisting>
|
||||
GObject *(* constructor) (GType gtype,
|
||||
guint n_properties,
|
||||
GObjectConstructParam *properties);
|
||||
</programlisting>
|
||||
</programlisting></informalexample>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The example below shows how <type>MamanBar</type> overrides the parent's constructor:
|
||||
<programlisting>
|
||||
<informalexample><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))
|
||||
@ -119,11 +119,11 @@ maman_bar_init (MamanBar *self)
|
||||
/* initialize the object */
|
||||
}
|
||||
|
||||
</programlisting>
|
||||
</programlisting></informalexample>
|
||||
If the user instantiates an object <type>MamanBar</type> with:
|
||||
<programlisting>
|
||||
<informalexample><programlisting>
|
||||
MamanBar *bar = g_object_new (MAMAN_TYPE_BAR, NULL);
|
||||
</programlisting>
|
||||
</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.
|
||||
@ -266,7 +266,7 @@ MamanBar *bar = g_object_new (MAMAN_TYPE_BAR, NULL);
|
||||
which can be integrated in applications which use or require different memory management
|
||||
models (such as garbage collection). The methods which are used to
|
||||
manipulate this reference count are described below.
|
||||
<programlisting>
|
||||
<informalexample><programlisting>
|
||||
/*
|
||||
Refcounting
|
||||
*/
|
||||
@ -293,7 +293,7 @@ void g_object_remove_weak_pointer (GObject *object,
|
||||
* Cycle handling
|
||||
*/
|
||||
void g_object_run_dispose (GObject *object);
|
||||
</programlisting>
|
||||
</programlisting></informalexample>
|
||||
</para>
|
||||
|
||||
<sect2 id="gobject-memory-refcount">
|
||||
@ -705,14 +705,14 @@ g_value_unset (&val);
|
||||
It is interesting to note that the <function><link linkend="g-object-set">g_object_set</link></function> and
|
||||
<function><link linkend="g-object-set-valist">g_object_set_valist</link></function> (vararg version) functions can be used to set
|
||||
multiple properties at once. The client code shown above can then be re-written as:
|
||||
<programlisting>
|
||||
<informalexample><programlisting>
|
||||
MamanBar *foo;
|
||||
foo = /* */;
|
||||
g_object_set (G_OBJECT (foo),
|
||||
"papa-number", 2,
|
||||
"maman-name", "test",
|
||||
NULL);
|
||||
</programlisting>
|
||||
</programlisting></informalexample>
|
||||
This saves us from managing the GValues that we were needing to handle when using
|
||||
<function><link linkend="g-object-set-property">g_object_set_property</link></function>.
|
||||
The code above will trigger one notify signal emission for each property modified.
|
||||
|
@ -15,9 +15,9 @@
|
||||
which contains three objects:
|
||||
<itemizedlist>
|
||||
<listitem><para>a function pointer (the callback itself) whose prototype looks like:
|
||||
<programlisting>
|
||||
<informalexample><programlisting>
|
||||
return_type function_callback (... , gpointer user_data);
|
||||
</programlisting>
|
||||
</programlisting></informalexample>
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
the user_data pointer which is passed to the callback upon invocation of the closure
|
||||
@ -80,7 +80,7 @@ return_type function_callback (... , gpointer user_data);
|
||||
to connect a callback to a given event, you will either use simple <link linkend="GCClosure"><type>GCClosure</type></link>s
|
||||
which have a pretty minimal API or the even simpler <function><link linkend="g-signal-connect">g_signal_connect</link></function>
|
||||
functions (which will be presented a bit later :).
|
||||
<programlisting>
|
||||
<informalexample><programlisting>
|
||||
GClosure *g_cclosure_new (GCallback callback_func,
|
||||
gpointer user_data,
|
||||
GClosureNotify destroy_data);
|
||||
@ -89,7 +89,7 @@ GClosure *g_cclosure_new_swap (GCallback callback_func,
|
||||
GClosureNotify destroy_data);
|
||||
GClosure *g_signal_type_cclosure_new (GType itype,
|
||||
guint struct_offset);
|
||||
</programlisting>
|
||||
</programlisting></informalexample>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
@ -128,7 +128,7 @@ GClosure *g_signal_type_cclosure_new (GType itype,
|
||||
<para>
|
||||
The following code implements a simple marshaller in C for a C function which takes an
|
||||
integer as first parameter and returns void.
|
||||
<programlisting>
|
||||
<informalexample><programlisting>
|
||||
g_cclosure_marshal_VOID__INT (GClosure *closure,
|
||||
GValue *return_value,
|
||||
guint n_param_values,
|
||||
@ -154,7 +154,7 @@ g_cclosure_marshal_VOID__INT (GClosure *closure,
|
||||
g_marshal_value_peek_int (param_values + 1),
|
||||
data2);
|
||||
}
|
||||
</programlisting>
|
||||
</programlisting></informalexample>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
@ -194,9 +194,9 @@ g_cclosure_marshal_VOID__INT (GClosure *closure,
|
||||
When a signal is emitted on a given type instance, all the closures
|
||||
connected to this signal on this type instance will be invoked. All the closures
|
||||
connected to such a signal represent callbacks whose signature looks like:
|
||||
<programlisting>
|
||||
<informalexample><programlisting>
|
||||
return_type function_callback (gpointer instance, ... , gpointer user_data);
|
||||
</programlisting>
|
||||
</programlisting></informalexample>
|
||||
</para>
|
||||
|
||||
<sect2 id="signal-registration">
|
||||
@ -205,7 +205,7 @@ return_type function_callback (gpointer instance, ... , gpointer user_data);
|
||||
<para>
|
||||
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>
|
||||
<informalexample><programlisting>
|
||||
guint g_signal_newv (const gchar *signal_name,
|
||||
GType itype,
|
||||
GSignalFlags signal_flags,
|
||||
@ -216,7 +216,7 @@ guint g_signal_newv (const gchar *signal_name,
|
||||
GType return_type,
|
||||
guint n_params,
|
||||
GType *param_types);
|
||||
</programlisting>
|
||||
</programlisting></informalexample>
|
||||
The number of parameters to these functions is a bit intimidating but they are relatively
|
||||
simple:
|
||||
<itemizedlist>
|
||||
@ -310,12 +310,12 @@ guint g_signal_newv (const gchar *signal_name,
|
||||
<para>
|
||||
Signal emission is done through the use of the <function><link linkend="g-signal-emit">g_signal_emit</link></function> family
|
||||
of functions.
|
||||
<programlisting>
|
||||
<informalexample><programlisting>
|
||||
void g_signal_emitv (const GValue *instance_and_params,
|
||||
guint signal_id,
|
||||
GQuark detail,
|
||||
GValue *return_value);
|
||||
</programlisting>
|
||||
</programlisting></informalexample>
|
||||
<itemizedlist>
|
||||
<listitem><para>
|
||||
The instance_and_params array of GValues contains the list of input
|
||||
@ -440,15 +440,15 @@ void g_signal_emitv (const GValue *instance_and_params,
|
||||
<function><link linkend="g-quark-from-string">g_quark_from_string</link></function> and <function><link linkend="g-quark-to-string">g_quark_to_string</link></function>.
|
||||
</para>
|
||||
</footnote>:
|
||||
<programlisting>
|
||||
<informalexample><programlisting>
|
||||
gulong g_signal_connect_closure_by_id (gpointer instance,
|
||||
guint signal_id,
|
||||
GQuark detail,
|
||||
GClosure *closure,
|
||||
gboolean after);
|
||||
</programlisting>
|
||||
</programlisting></informalexample>
|
||||
The two other functions hide the detail parameter in the signal name identification:
|
||||
<programlisting>
|
||||
<informalexample><programlisting>
|
||||
gulong g_signal_connect_closure (gpointer instance,
|
||||
const gchar *detailed_signal,
|
||||
GClosure *closure,
|
||||
@ -459,7 +459,7 @@ gulong g_signal_connect_data (gpointer instance,
|
||||
gpointer data,
|
||||
GClosureNotify destroy_data,
|
||||
GConnectFlags connect_flags);
|
||||
</programlisting>
|
||||
</programlisting></informalexample>
|
||||
Their detailed_signal parameter is a string which identifies the name of the signal
|
||||
to connect to. However, the format of this string is structured to look like
|
||||
<emphasis>signal_name::detail_name</emphasis>. Connecting to the signal
|
||||
@ -471,7 +471,7 @@ gulong g_signal_connect_data (gpointer instance,
|
||||
<para>
|
||||
Of the four main signal emission functions, three have an explicit detail parameter as a
|
||||
<link linkend="GQuark"><type>GQuark</type></link> again:
|
||||
<programlisting>
|
||||
<informalexample><programlisting>
|
||||
void g_signal_emitv (const GValue *instance_and_params,
|
||||
guint signal_id,
|
||||
GQuark detail,
|
||||
@ -484,13 +484,13 @@ void g_signal_emit (gpointer instance,
|
||||
guint signal_id,
|
||||
GQuark detail,
|
||||
...);
|
||||
</programlisting>
|
||||
</programlisting></informalexample>
|
||||
The fourth function hides it in its signal name parameter:
|
||||
<programlisting>
|
||||
<informalexample><programlisting>
|
||||
void g_signal_emit_by_name (gpointer instance,
|
||||
const gchar *detailed_signal,
|
||||
...);
|
||||
</programlisting>
|
||||
</programlisting></informalexample>
|
||||
The format of the detailed_signal parameter is exactly the same as the format used by
|
||||
the <function><link linkend="g-signal-connect">g_signal_connect</link></function> functions: <emphasis>signal_name::detail_name</emphasis>.
|
||||
</para>
|
||||
|
@ -9,7 +9,7 @@
|
||||
A type, as manipulated by the GLib type system, is much more generic than what
|
||||
is usually understood as an Object type. It is best explained by looking at the
|
||||
structure and the functions used to register new types in the type system.
|
||||
<programlisting>
|
||||
<informalexample><programlisting>
|
||||
typedef struct _GTypeInfo GTypeInfo;
|
||||
struct _GTypeInfo
|
||||
{
|
||||
@ -41,7 +41,7 @@ GType g_type_register_fundamental (GType type_id,
|
||||
const GTypeInfo *info,
|
||||
const GTypeFundamentalInfo *finfo,
|
||||
GTypeFlags flags);
|
||||
</programlisting>
|
||||
</programlisting></informalexample>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
@ -133,7 +133,7 @@ GType g_type_register_fundamental (GType type_id,
|
||||
The following code shows how you can copy around a 64 bit integer, as well as a <link linkend="GObject"><type>GObject</type></link>
|
||||
instance pointer (sample code for this is located in the source tarball for this document in
|
||||
<filename>sample/gtype/test.c</filename>):
|
||||
<programlisting>
|
||||
<informalexample><programlisting>
|
||||
static void test_int (void)
|
||||
{
|
||||
GValue a_value = G_VALUE_INIT;
|
||||
@ -179,7 +179,7 @@ static void test_object (void)
|
||||
g_object_unref (G_OBJECT (obj));
|
||||
g_object_unref (G_OBJECT (obj));
|
||||
}
|
||||
</programlisting>
|
||||
</programlisting></informalexample>
|
||||
The important point about the above code is that the exact semantics of the copy calls
|
||||
is undefined since they depend on the implementation of the copy function. Certain
|
||||
copy functions might decide to allocate a new chunk of memory and then to copy the
|
||||
@ -192,7 +192,7 @@ static void test_object (void)
|
||||
<filename>gtype.h</filename> and is thoroughly described in the
|
||||
API documentation provided with GObject (for once ;-) which is why we will
|
||||
not detail its exact semantics.
|
||||
<programlisting>
|
||||
<informalexample><programlisting>
|
||||
typedef struct _GTypeValueTable GTypeValueTable;
|
||||
struct _GTypeValueTable
|
||||
{
|
||||
@ -213,7 +213,7 @@ struct _GTypeValueTable
|
||||
GTypeCValue *collect_values,
|
||||
guint collect_flags);
|
||||
};
|
||||
</programlisting>
|
||||
</programlisting></informalexample>
|
||||
Interestingly, it is also very unlikely
|
||||
you will ever need to specify a value_table during type registration
|
||||
because these value_tables are inherited from the parent types for
|
||||
@ -290,21 +290,21 @@ struct _GTypeValueTable
|
||||
The implementation of these macros is pretty straightforward: a number of simple-to-use
|
||||
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:
|
||||
<programlisting>
|
||||
<informalexample><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_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))
|
||||
</programlisting>
|
||||
</programlisting></informalexample>
|
||||
<note><simpara>Stick to the naming <varname>klass</varname> as <varname>class</varname> is a registered c++ keyword.</simpara></note>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The following code shows how to implement the <function>maman_bar_get_type</function>
|
||||
function:
|
||||
<programlisting>
|
||||
<informalexample><programlisting>
|
||||
GType maman_bar_get_type (void)
|
||||
{
|
||||
static GType type = 0;
|
||||
@ -318,16 +318,16 @@ GType maman_bar_get_type (void)
|
||||
}
|
||||
return type;
|
||||
}
|
||||
</programlisting>
|
||||
</programlisting></informalexample>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
If you have no special requirements you can use the
|
||||
<function><link linkend="G-DEFINE-TYPE:CAPS">G_DEFINE_TYPE</link></function>
|
||||
macro to define a class:
|
||||
<programlisting>
|
||||
<informalexample><programlisting>
|
||||
G_DEFINE_TYPE (MamanBar, maman_bar, G_TYPE_OBJECT)
|
||||
</programlisting>
|
||||
</programlisting></informalexample>
|
||||
</para>
|
||||
|
||||
</sect1>
|
||||
@ -345,7 +345,7 @@ G_DEFINE_TYPE (MamanBar, maman_bar, G_TYPE_OBJECT)
|
||||
To register such a type in the type system, you just need to fill the
|
||||
<link linkend="GTypeInfo"><type>GTypeInfo</type></link> structure with zeros since these types are also most of the time
|
||||
fundamental:
|
||||
<programlisting>
|
||||
<informalexample><programlisting>
|
||||
GTypeInfo info = {
|
||||
0, /* class_size */
|
||||
NULL, /* base_init */
|
||||
@ -370,7 +370,7 @@ G_DEFINE_TYPE (MamanBar, maman_bar, G_TYPE_OBJECT)
|
||||
};
|
||||
info.value_table = &value_table;
|
||||
type = g_type_register_fundamental (G_TYPE_CHAR, "gchar", &info, &finfo, 0);
|
||||
</programlisting>
|
||||
</programlisting></informalexample>
|
||||
</para>
|
||||
|
||||
|
||||
@ -401,7 +401,7 @@ G_DEFINE_TYPE (MamanBar, maman_bar, G_TYPE_OBJECT)
|
||||
<para>
|
||||
For example, the code below shows how you could register
|
||||
such a fundamental object type in the type system:
|
||||
<programlisting>
|
||||
<informalexample><programlisting>
|
||||
typedef struct {
|
||||
GObject parent;
|
||||
/* instance members */
|
||||
@ -440,7 +440,7 @@ maman_bar_get_type (void)
|
||||
}
|
||||
return type;
|
||||
}
|
||||
</programlisting>
|
||||
</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
|
||||
from the type <emphasis>G_TYPE_OBJECT</emphasis>.
|
||||
@ -452,7 +452,7 @@ maman_bar_get_type (void)
|
||||
a <link linkend="GTypeClass"><type>GTypeClass</type></link> structure. All instance structures must contain as first
|
||||
member a <link linkend="GTypeInstance"><type>GTypeInstance</type></link> structure. The declaration of these C types,
|
||||
coming from <filename>gtype.h</filename> is shown below:
|
||||
<programlisting>
|
||||
<informalexample><programlisting>
|
||||
struct _GTypeClass
|
||||
{
|
||||
GType g_type;
|
||||
@ -461,7 +461,7 @@ struct _GTypeInstance
|
||||
{
|
||||
GTypeClass *g_class;
|
||||
};
|
||||
</programlisting>
|
||||
</programlisting></informalexample>
|
||||
These constraints allow the type system to make sure that every object instance
|
||||
(identified by a pointer to the object's instance structure) contains in its
|
||||
first bytes a pointer to the object's class structure.
|
||||
@ -469,7 +469,7 @@ struct _GTypeInstance
|
||||
<para>
|
||||
This relationship is best explained by an example: let's take object B which
|
||||
inherits from object A:
|
||||
<programlisting>
|
||||
<informalexample><programlisting>
|
||||
/* A definitions */
|
||||
typedef struct {
|
||||
GTypeInstance parent;
|
||||
@ -493,7 +493,7 @@ typedef struct {
|
||||
void (*method_c) (void);
|
||||
void (*method_d) (void);
|
||||
} BClass;
|
||||
</programlisting>
|
||||
</programlisting></informalexample>
|
||||
The C standard mandates that the first field of a C structure is stored starting
|
||||
in the first byte of the buffer used to hold the structure's fields in memory.
|
||||
This means that the first field of an instance of an object B is A's first field
|
||||
@ -504,15 +504,15 @@ typedef struct {
|
||||
<para>
|
||||
Thanks to these simple conditions, it is possible to detect the type of every
|
||||
object instance by doing:
|
||||
<programlisting>
|
||||
<informalexample><programlisting>
|
||||
B *b;
|
||||
b->parent.parent.g_class->g_type
|
||||
</programlisting>
|
||||
</programlisting></informalexample>
|
||||
or, more quickly:
|
||||
<programlisting>
|
||||
<informalexample><programlisting>
|
||||
B *b;
|
||||
((GTypeInstance*)b)->g_class->g_type
|
||||
</programlisting>
|
||||
</programlisting></informalexample>
|
||||
</para>
|
||||
|
||||
<sect2 id="gtype-instantiable-classed-init-done">
|
||||
@ -521,10 +521,10 @@ B *b;
|
||||
<para>
|
||||
instantiation of these types can be done with
|
||||
<function><link linkend="g-type-create-instance">g_type_create_instance</link></function>:
|
||||
<programlisting>
|
||||
<informalexample><programlisting>
|
||||
GTypeInstance* g_type_create_instance (GType type);
|
||||
void g_type_free_instance (GTypeInstance *instance);
|
||||
</programlisting>
|
||||
</programlisting></informalexample>
|
||||
<function><link linkend="g-type-create-instance">g_type_create_instance</link></function> will look up the type information
|
||||
structure associated to the type requested. Then, the instance size and instantiation
|
||||
policy (if the n_preallocs field is set to a non-zero value, the type system allocates
|
||||
@ -662,7 +662,7 @@ void g_type_free_instance (GTypeInstance *instance);
|
||||
To declare an interface you have to register a non-instantiable
|
||||
classed type which derives from
|
||||
<link linkend="GTypeInterface"><type>GTypeInterface</type></link>. The following piece of code declares such an interface.
|
||||
<programlisting>
|
||||
<informalexample><programlisting>
|
||||
#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))
|
||||
@ -680,15 +680,15 @@ struct _MamanIbazInterface {
|
||||
GType maman_ibaz_get_type (void);
|
||||
|
||||
void maman_ibaz_do_action (MamanIbaz *self);
|
||||
</programlisting>
|
||||
</programlisting></informalexample>
|
||||
The interface function, <function>maman_ibaz_do_action</function> is implemented
|
||||
in a pretty simple way:
|
||||
<programlisting>
|
||||
<informalexample><programlisting>
|
||||
void maman_ibaz_do_action (MamanIbaz *self)
|
||||
{
|
||||
MAMAN_IBAZ_GET_INTERFACE (self)->do_action (self);
|
||||
}
|
||||
</programlisting>
|
||||
</programlisting></informalexample>
|
||||
<function>maman_ibaz_get_type</function> registers a type named <emphasis>MamanIbaz</emphasis>
|
||||
which inherits from G_TYPE_INTERFACE. All interfaces must be children of G_TYPE_INTERFACE in the
|
||||
inheritance tree.
|
||||
@ -708,7 +708,7 @@ void maman_ibaz_do_action (MamanIbaz *self)
|
||||
interfaces. The function named <function>maman_baz_get_type</function> registers
|
||||
a new GType named MamanBaz which inherits from <link linkend="GObject"><type>GObject</type></link> and which
|
||||
implements the interface <type>MamanIbaz</type>.
|
||||
<programlisting>
|
||||
<informalexample><programlisting>
|
||||
static void maman_baz_do_action (MamanIbaz *self)
|
||||
{
|
||||
g_print ("Baz implementation of Ibaz interface Action.\n");
|
||||
@ -752,7 +752,7 @@ maman_baz_get_type (void)
|
||||
}
|
||||
return type;
|
||||
}
|
||||
</programlisting>
|
||||
</programlisting></informalexample>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
@ -762,21 +762,21 @@ maman_baz_get_type (void)
|
||||
<type>FooInterface</type>).
|
||||
The <link linkend="GInterfaceInfo"><type>GInterfaceInfo</type></link> structure holds
|
||||
information about the implementation of the interface:
|
||||
<programlisting>
|
||||
<informalexample><programlisting>
|
||||
struct _GInterfaceInfo
|
||||
{
|
||||
GInterfaceInitFunc interface_init;
|
||||
GInterfaceFinalizeFunc interface_finalize;
|
||||
gpointer interface_data;
|
||||
};
|
||||
</programlisting>
|
||||
</programlisting></informalexample>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
If you have no special requirements you can use the
|
||||
<link linkend="G-IMPLEMENT-INTERFACE:CAPS">G_IMPLEMENT_INTERFACE</link> macro
|
||||
to implement an interface:
|
||||
<programlisting>
|
||||
<informalexample><programlisting>
|
||||
static void
|
||||
maman_baz_do_action (MamanIbaz *self)
|
||||
{
|
||||
@ -792,7 +792,7 @@ maman_ibaz_interface_init (MamanIbazInterface *iface)
|
||||
G_DEFINE_TYPE_WITH_CODE (MamanBaz, maman_baz, G_TYPE_OBJECT,
|
||||
G_IMPLEMENT_INTERFACE (MAMAN_TYPE_IBAZ,
|
||||
maman_ibaz_interface_init));
|
||||
</programlisting>
|
||||
</programlisting></informalexample>
|
||||
</para>
|
||||
|
||||
<sect2 id="gtype-non-instantiable-classed-init">
|
||||
@ -835,7 +835,7 @@ G_DEFINE_TYPE_WITH_CODE (MamanBaz, maman_baz, G_TYPE_OBJECT,
|
||||
<function>default_init</function> function is declared by
|
||||
<link linkend="G-DEFINE-INTERFACE:CAPS">G_DEFINE_INTERFACE</link>
|
||||
which can be used to define the interface:
|
||||
<programlisting>
|
||||
<informalexample><programlisting>
|
||||
G_DEFINE_INTERFACE (MamanIbaz, maman_ibaz, G_TYPE_OBJECT);
|
||||
|
||||
static void
|
||||
@ -843,12 +843,12 @@ maman_ibaz_default_init (MamanIbazInterface *iface)
|
||||
{
|
||||
/* add properties and signals here, will only called once */
|
||||
}
|
||||
</programlisting>
|
||||
</programlisting></informalexample>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Or you can do that yourself in a GType function for your interface:
|
||||
<programlisting>
|
||||
<informalexample><programlisting>
|
||||
GType
|
||||
maman_ibaz_get_type (void)
|
||||
{
|
||||
@ -878,7 +878,7 @@ maman_ibaz_default_init (MamanIbazInterface *iface)
|
||||
{
|
||||
/* add properties and signals here, will only called once */
|
||||
}
|
||||
</programlisting>
|
||||
</programlisting></informalexample>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
|
@ -88,7 +88,7 @@
|
||||
<function>MamanBar</function> and its class <function>MamanBarClass</function>
|
||||
(name is case-sensitive). It is customary to declare them with code similar to the
|
||||
following:
|
||||
<programlisting>
|
||||
<informalexample><programlisting>
|
||||
/*
|
||||
* Copyright/Licensing information.
|
||||
*/
|
||||
@ -139,7 +139,7 @@ GType maman_bar_get_type (void);
|
||||
*/
|
||||
|
||||
#endif /* __MAMAN_BAR_H__ */
|
||||
</programlisting>
|
||||
</programlisting></informalexample>
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
Types that require per-instance private data should use the
|
||||
@ -150,7 +150,7 @@ GType maman_bar_get_type (void);
|
||||
function generated by the G_DEFINE_TYPE_* macros. It is automatically
|
||||
zero-filled on creation, so it is unnecessary to explicitly
|
||||
initialize pointer members to NULL.
|
||||
<programlisting>
|
||||
<informalexample><programlisting>
|
||||
struct _MamanBarPrivate
|
||||
{
|
||||
int hsize;
|
||||
@ -173,7 +173,7 @@ maman_bar_init (MamanBar *self)
|
||||
|
||||
priv->hsize = 42;
|
||||
}
|
||||
</programlisting>
|
||||
</programlisting></informalexample>
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
@ -183,7 +183,7 @@ maman_bar_init (MamanBar *self)
|
||||
and <ulink url="http://www.gotw.ca/gotw/028.htm">The Fast Pimpl Idiom</ulink>
|
||||
for reference). If you opt to use this idiom, you can assign the
|
||||
pointer inside the instance initialization function, e.g.:
|
||||
<programlisting>
|
||||
<informalexample><programlisting>
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (MamanBar, maman_bar, G_TYPE_OBJECT)
|
||||
|
||||
struct _MamanBarPrivate
|
||||
@ -202,7 +202,7 @@ maman_bar_init (MamanBar *self)
|
||||
self->priv = maman_bar_get_instance_private (self);
|
||||
self->priv->hsize = 42;
|
||||
}
|
||||
</programlisting>
|
||||
</programlisting></informalexample>
|
||||
</para></listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
@ -238,7 +238,7 @@ maman_bar_init (MamanBar *self)
|
||||
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>
|
||||
<informalexample><programlisting>
|
||||
/*
|
||||
* Copyright information
|
||||
*/
|
||||
@ -258,7 +258,7 @@ struct _MamanBarPrivate {
|
||||
/*
|
||||
* forward definitions
|
||||
*/
|
||||
</programlisting>
|
||||
</programlisting></informalexample>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
@ -273,9 +273,9 @@ struct _MamanBarPrivate {
|
||||
the whole .c file</simpara></listitem>
|
||||
</itemizedlist>
|
||||
|
||||
<programlisting>
|
||||
<informalexample><programlisting>
|
||||
G_DEFINE_TYPE (MamanBar, maman_bar, G_TYPE_OBJECT)
|
||||
</programlisting>
|
||||
</programlisting></informalexample>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
@ -322,7 +322,7 @@ G_DEFINE_TYPE (MamanBar, maman_bar, G_TYPE_OBJECT)
|
||||
|
||||
<para>
|
||||
As such, I would recommend writing the following code first:
|
||||
<programlisting>
|
||||
<informalexample><programlisting>
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (MamanBar, maman_bar, G_TYPE_OBJECT)
|
||||
|
||||
static void
|
||||
@ -338,7 +338,7 @@ maman_bar_init (MamanBar *self)
|
||||
/* initialize all public and private members to reasonable default values.
|
||||
* They are all automatically initialized to 0 to begin with. */
|
||||
}
|
||||
</programlisting>
|
||||
</programlisting></informalexample>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
@ -416,7 +416,7 @@ bar_class_init (MamanBarClass *klass)
|
||||
potential cycles due to the nature of the reference counting mechanism
|
||||
used by GObject, as well as dealing with temporary vivification of
|
||||
instances in case of signal emission during the destruction sequence.
|
||||
<programlisting>
|
||||
<informalexample><programlisting>
|
||||
struct _MamanBarPrivate
|
||||
{
|
||||
GObject *an_object;
|
||||
@ -480,7 +480,7 @@ maman_bar_init (MamanBar *self);
|
||||
self->priv->an_object = g_object_new (MAMAN_TYPE_BAZ, NULL);
|
||||
self->priv->a_string = g_strdup ("Maman");
|
||||
}
|
||||
</programlisting>
|
||||
</programlisting></informalexample>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
@ -522,7 +522,7 @@ maman_bar_init (MamanBar *self);
|
||||
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>
|
||||
<informalexample><programlisting>
|
||||
/* declaration in the header. */
|
||||
void maman_bar_do_action (MamanBar *self, /* parameters */);
|
||||
|
||||
@ -534,7 +534,7 @@ maman_bar_do_action (MamanBar *self, /* parameters */)
|
||||
|
||||
/* do stuff here. */
|
||||
}
|
||||
</programlisting>
|
||||
</programlisting></informalexample>
|
||||
</para>
|
||||
</sect2>
|
||||
|
||||
@ -547,7 +547,7 @@ maman_bar_do_action (MamanBar *self, /* parameters */)
|
||||
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>
|
||||
<informalexample><programlisting>
|
||||
/* declaration in maman-bar.h. */
|
||||
struct _MamanBarClass
|
||||
{
|
||||
@ -567,7 +567,7 @@ maman_bar_do_action (MamanBar *self, /* parameters */)
|
||||
|
||||
MAMAN_BAR_GET_CLASS (self)->do_action (self, /* parameters */);
|
||||
}
|
||||
</programlisting>
|
||||
</programlisting></informalexample>
|
||||
The code above simply redirects the do_action call to the relevant
|
||||
class function.
|
||||
</para>
|
||||
@ -579,7 +579,7 @@ maman_bar_do_action (MamanBar *self, /* parameters */)
|
||||
klass->do_action field to a pointer to the actual implementation.
|
||||
By default, class methods that are not inherited are initialized to
|
||||
NULL, and thus are to be considered "pure virtual".
|
||||
<programlisting>
|
||||
<informalexample><programlisting>
|
||||
static void
|
||||
maman_bar_real_do_action_two (MamanBar *self, /* parameters */)
|
||||
{
|
||||
@ -624,7 +624,7 @@ maman_bar_do_action_two (MamanBar *self, /* parameters */)
|
||||
|
||||
MAMAN_BAR_GET_CLASS (self)->do_action_two (self, /* parameters */);
|
||||
}
|
||||
</programlisting>
|
||||
</programlisting></informalexample>
|
||||
</para>
|
||||
</sect2>
|
||||
|
||||
@ -635,7 +635,7 @@ maman_bar_do_action_two (MamanBar *self, /* parameters */)
|
||||
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>
|
||||
<informalexample><programlisting>
|
||||
/* declaration in maman-bar.h. */
|
||||
struct _MamanBarClass
|
||||
{
|
||||
@ -646,10 +646,10 @@ struct _MamanBarClass
|
||||
};
|
||||
|
||||
void maman_bar_do_any_action (MamanBar *self, /* parameters */);
|
||||
</programlisting>
|
||||
</programlisting></informalexample>
|
||||
These class functions are often used to delegate part of the job
|
||||
to child classes:
|
||||
<programlisting>
|
||||
<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 */)
|
||||
@ -671,13 +671,13 @@ maman_bar_do_any_action (MamanBar *self, /* parameters */)
|
||||
|
||||
/* other random code here */
|
||||
}
|
||||
</programlisting>
|
||||
</programlisting></informalexample>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Again, it is possible to provide a default implementation for this
|
||||
private virtual class function:
|
||||
<programlisting>
|
||||
<informalexample><programlisting>
|
||||
static void
|
||||
maman_bar_class_init (MamanBarClass *klass)
|
||||
{
|
||||
@ -687,12 +687,12 @@ maman_bar_class_init (MamanBarClass *klass)
|
||||
/* merely virtual method. */
|
||||
klass->do_specific_action_two = maman_bar_real_do_specific_action_two;
|
||||
}
|
||||
</programlisting>
|
||||
</programlisting></informalexample>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Children can then implement the subclass with code such as:
|
||||
<programlisting>
|
||||
<informalexample><programlisting>
|
||||
static void
|
||||
maman_bar_subtype_class_init (MamanBarSubTypeClass *klass)
|
||||
{
|
||||
@ -701,7 +701,7 @@ maman_bar_subtype_class_init (MamanBarSubTypeClass *klass)
|
||||
/* implement pure virtual class function. */
|
||||
bar_class->do_specific_action_one = maman_bar_subtype_do_specific_action_one;
|
||||
}
|
||||
</programlisting>
|
||||
</programlisting></informalexample>
|
||||
</para>
|
||||
</sect2>
|
||||
</sect1>
|
||||
@ -754,7 +754,7 @@ maman_bar_subtype_class_init (MamanBarSubTypeClass *klass)
|
||||
directly, though, you should use the <function>parent_class</function>
|
||||
pointer created and initialized for us by the G_DEFINE_TYPE_* family of
|
||||
macros, for instance:
|
||||
<programlisting>
|
||||
<informalexample><programlisting>
|
||||
static void
|
||||
b_method_to_call (B *obj, int a)
|
||||
{
|
||||
@ -769,7 +769,7 @@ b_method_to_call (B *obj, int a)
|
||||
|
||||
/* do stuff after chain up */
|
||||
}
|
||||
</programlisting>
|
||||
</programlisting></informalexample>
|
||||
</para>
|
||||
|
||||
</sect1>
|
||||
@ -791,7 +791,7 @@ b_method_to_call (B *obj, int a)
|
||||
<para>
|
||||
As above, the first step is to get the header right. This interface
|
||||
defines two methods:
|
||||
<programlisting>
|
||||
<informalexample><programlisting>
|
||||
#ifndef __MAMAN_IBAZ_H__
|
||||
#define __MAMAN_IBAZ_H__
|
||||
|
||||
@ -820,7 +820,7 @@ void maman_ibaz_do_action (MamanIbaz *self);
|
||||
void maman_ibaz_do_something (MamanIbaz *self);
|
||||
|
||||
#endif /* __MAMAN_IBAZ_H__ */
|
||||
</programlisting>
|
||||
</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:
|
||||
<itemizedlist>
|
||||
@ -859,7 +859,7 @@ void maman_ibaz_do_something (MamanIbaz *self);
|
||||
structure to access its associated interface function and call it.
|
||||
</para></listitem>
|
||||
</itemizedlist>
|
||||
<programlisting>
|
||||
<informalexample><programlisting>
|
||||
G_DEFINE_INTERFACE (MamanIbaz, maman_ibaz, 0);
|
||||
|
||||
static void
|
||||
@ -883,7 +883,7 @@ maman_ibaz_do_something (MamanIbaz *self)
|
||||
|
||||
MAMAN_IBAZ_GET_INTERFACE (self)->do_something (self);
|
||||
}
|
||||
</programlisting>
|
||||
</programlisting></informalexample>
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
@ -896,7 +896,7 @@ maman_ibaz_do_something (MamanIbaz *self)
|
||||
|
||||
<para>
|
||||
The first step is to define a normal GObject class, like:
|
||||
<programlisting>
|
||||
<informalexample><programlisting>
|
||||
#ifndef __MAMAN_BAZ_H__
|
||||
#define __MAMAN_BAZ_H__
|
||||
|
||||
@ -928,7 +928,7 @@ struct _MamanBazClass
|
||||
GType maman_baz_get_type (void);
|
||||
|
||||
#endif /* __MAMAN_BAZ_H__ */
|
||||
</programlisting>
|
||||
</programlisting></informalexample>
|
||||
<!-- Ha ha! "nothing weird or scary". I actually laughed out loud. Oh boy.
|
||||
The fact that we're so intimate with GObject that all this doesn't look
|
||||
wierd, that's the scary thing. :) -->
|
||||
@ -945,13 +945,13 @@ GType maman_baz_get_type (void);
|
||||
and the
|
||||
<function><link linkend="G-IMPLEMENT-INTERFACE:CAPS">G_IMPLEMENT_INTERFACE</link></function>
|
||||
macros.
|
||||
<programlisting>
|
||||
<informalexample><programlisting>
|
||||
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>
|
||||
</programlisting></informalexample>
|
||||
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><link linkend="G-IMPLEMENT-INTERFACE:CAPS">G_IMPLEMENT_INTERFACE</link></function>.
|
||||
@ -967,7 +967,7 @@ G_DEFINE_TYPE_WITH_CODE (MamanBar, maman_bar, G_TYPE_OBJECT,
|
||||
<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>
|
||||
<informalexample><programlisting>
|
||||
static void
|
||||
maman_baz_do_action (MamanBaz *self)
|
||||
{
|
||||
@ -995,7 +995,7 @@ maman_baz_init (MamanBaz *self)
|
||||
MamanBaz *self = MAMAN_BAZ (instance);
|
||||
self->instance_member = 0xdeadbeaf;
|
||||
}
|
||||
</programlisting>
|
||||
</programlisting></informalexample>
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
@ -1015,17 +1015,17 @@ maman_baz_init (MamanBaz *self)
|
||||
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>
|
||||
<informalexample><programlisting>
|
||||
/* Make the MamanIbar interface require MamanIbaz interface. */
|
||||
G_DEFINE_INTERFACE (MamanIbar, maman_ibar, MAMAN_TYPE_IBAZ);
|
||||
</programlisting>
|
||||
</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 MamanIbaz interface is a prerequisite of the MamanIbar. The code
|
||||
below shows how an implementation can implement both interfaces and
|
||||
register their implementations:
|
||||
<programlisting>
|
||||
<informalexample><programlisting>
|
||||
static void
|
||||
maman_ibar_do_another_action (MamanIbar *ibar)
|
||||
{
|
||||
@ -1083,7 +1083,7 @@ G_DEFINE_TYPE_WITH_CODE (MamanBar, maman_bar, G_TYPE_OBJECT,
|
||||
maman_ibaz_interface_init)
|
||||
G_IMPLEMENT_INTERFACE (MAMAN_TYPE_IBAR,
|
||||
maman_ibar_interface_init))
|
||||
</programlisting>
|
||||
</programlisting></informalexample>
|
||||
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>,
|
||||
@ -1117,7 +1117,7 @@ G_DEFINE_TYPE_WITH_CODE (MamanBar, maman_bar, G_TYPE_OBJECT,
|
||||
</para>
|
||||
</footnote>
|
||||
line in the <function>maman_ibaz_default_init</function> as shown below:
|
||||
<programlisting>
|
||||
<informalexample><programlisting>
|
||||
static void
|
||||
maman_ibaz_default_init (MamanIbazInteface *iface)
|
||||
{
|
||||
@ -1128,7 +1128,7 @@ maman_ibaz_default_init (MamanIbazInteface *iface)
|
||||
"maman",
|
||||
G_PARAM_READWRITE));
|
||||
}
|
||||
</programlisting>
|
||||
</programlisting></informalexample>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
@ -1147,7 +1147,7 @@ maman_ibaz_default_init (MamanIbazInteface *iface)
|
||||
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>
|
||||
<informalexample><programlisting>
|
||||
|
||||
struct _MamanBaz
|
||||
{
|
||||
@ -1215,7 +1215,7 @@ maman_baz_class_init (MamanBazClass *klass)
|
||||
g_object_class_override_property (gobject_class, PROP_NAME, "name");
|
||||
}
|
||||
|
||||
</programlisting>
|
||||
</programlisting></informalexample>
|
||||
</para>
|
||||
|
||||
</sect1>
|
||||
@ -1235,7 +1235,7 @@ maman_baz_class_init (MamanBazClass *klass)
|
||||
implement the MamanIbaz interface. MamanDerivedBaz only implements one
|
||||
method of the MamanIbaz interface and uses the base class implementation
|
||||
of the other.
|
||||
<programlisting>
|
||||
<informalexample><programlisting>
|
||||
static void
|
||||
maman_derived_ibaz_do_action (MamanIbaz *ibaz)
|
||||
{
|
||||
@ -1270,7 +1270,7 @@ maman_derived_baz_init (MamanDerivedBaz *self)
|
||||
{
|
||||
|
||||
}
|
||||
</programlisting>
|
||||
</programlisting></informalexample>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
@ -1291,7 +1291,7 @@ maman_derived_baz_init (MamanDerivedBaz *self)
|
||||
In this example MamanDerivedBaz overides the
|
||||
<function>do_action</function> interface method. In its overridden method
|
||||
it calls the base class implementation of the same interface method.
|
||||
<programlisting>
|
||||
<informalexample><programlisting>
|
||||
static MamanIbazInterface *maman_ibaz_parent_interface = NULL;
|
||||
|
||||
static void
|
||||
@ -1324,7 +1324,7 @@ static void
|
||||
maman_derived_baz_init (MamanDerivedBaz *self)
|
||||
{
|
||||
}
|
||||
</programlisting>
|
||||
</programlisting></informalexample>
|
||||
</para>
|
||||
|
||||
</sect1>
|
||||
@ -1361,19 +1361,19 @@ maman_derived_baz_init (MamanDerivedBaz *self)
|
||||
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>
|
||||
<informalexample><programlisting>
|
||||
file = g_object_new (MAMAN_FILE_TYPE, NULL);
|
||||
|
||||
g_signal_connect (file, "changed", G_CALLBACK (changed_event), NULL);
|
||||
|
||||
maman_file_write (file, buffer, strlen (buffer));
|
||||
</programlisting>
|
||||
</programlisting></informalexample>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The <type>MamanFile</type> signal is registered in the class_init
|
||||
function:
|
||||
<programlisting>
|
||||
<informalexample><programlisting>
|
||||
file_signals[CHANGED] =
|
||||
g_signal_newv ("changed",
|
||||
G_TYPE_FROM_CLASS (gobject_class),
|
||||
@ -1385,9 +1385,9 @@ file_signals[CHANGED] =
|
||||
G_TYPE_NONE /* return_type */,
|
||||
0 /* n_params */,
|
||||
NULL /* param_types */);
|
||||
</programlisting>
|
||||
</programlisting></informalexample>
|
||||
and the signal is emitted in <function>maman_file_write</function>:
|
||||
<programlisting>
|
||||
<informalexample><programlisting>
|
||||
void
|
||||
maman_file_write (MamanFile *self,
|
||||
const guchar *buffer,
|
||||
@ -1398,7 +1398,7 @@ maman_file_write (MamanFile *self,
|
||||
/* Then, notify user of data written. */
|
||||
g_signal_emit (self, file_signals[CHANGED], 0 /* details */);
|
||||
}
|
||||
</programlisting>
|
||||
</programlisting></informalexample>
|
||||
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"/>
|
||||
@ -1451,9 +1451,9 @@ maman_file_write (MamanFile *self,
|
||||
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>
|
||||
<informalexample><programlisting>
|
||||
VOID:POINTER,UINT
|
||||
</programlisting>
|
||||
</programlisting></informalexample>
|
||||
and use the Makefile provided in <filename>sample/signal/Makefile</filename> to generate the file named
|
||||
<filename>maman-file-complex-marshall.c</filename>. This C file is finally included in
|
||||
<filename>maman-file-complex.c</filename>.
|
||||
@ -1463,7 +1463,7 @@ VOID:POINTER,UINT
|
||||
Once the marshaller is present, we register the signal and its marshaller in the class_init function
|
||||
of the object <type>MamanFileComplex</type> (full source for this object is included in
|
||||
<filename>sample/signal/maman-file-complex.{h|c}</filename>):
|
||||
<programlisting>
|
||||
<informalexample><programlisting>
|
||||
GClosure *default_closure;
|
||||
GType param_types[2];
|
||||
|
||||
@ -1484,7 +1484,7 @@ klass->write_signal_id =
|
||||
G_TYPE_NONE /* return_type */,
|
||||
2 /* n_params */,
|
||||
param_types /* param_types */);
|
||||
</programlisting>
|
||||
</programlisting></informalexample>
|
||||
The code shown above first creates the closure which contains the code to complete the file write. This
|
||||
closure is registered as the default class_closure of the newly created signal.
|
||||
</para>
|
||||
@ -1492,7 +1492,7 @@ klass->write_signal_id =
|
||||
<para>
|
||||
Of course, you need to implement completely the code for the default closure since I just provided
|
||||
a skeleton:
|
||||
<programlisting>
|
||||
<informalexample><programlisting>
|
||||
static void
|
||||
default_write_signal_handler (GObject *obj, guint8 *buffer, guint size, gpointer user_data)
|
||||
{
|
||||
@ -1500,13 +1500,13 @@ default_write_signal_handler (GObject *obj, guint8 *buffer, guint size, gpointer
|
||||
/* Here, we trigger the real file write. */
|
||||
g_print ("default signal handler: 0x%x %u\n", buffer, size);
|
||||
}
|
||||
</programlisting>
|
||||
</programlisting></informalexample>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Finally, the client code must invoke the <function>maman_file_complex_write</function> function which
|
||||
triggers the signal emission:
|
||||
<programlisting>
|
||||
<informalexample><programlisting>
|
||||
void maman_file_complex_write (MamanFileComplex *self, guint8 *buffer, guint size)
|
||||
{
|
||||
/* trigger event */
|
||||
@ -1515,7 +1515,7 @@ void maman_file_complex_write (MamanFileComplex *self, guint8 *buffer, guint siz
|
||||
0, /* details */
|
||||
buffer, size);
|
||||
}
|
||||
</programlisting>
|
||||
</programlisting></informalexample>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
@ -1531,7 +1531,7 @@ void maman_file_complex_write (MamanFileComplex *self, guint8 *buffer, guint siz
|
||||
</para>
|
||||
|
||||
<para>
|
||||
<programlisting>
|
||||
<informalexample><programlisting>
|
||||
static void complex_write_event_before (GObject *file, guint8 *buffer, guint size, gpointer user_data)
|
||||
{
|
||||
g_assert (user_data == NULL);
|
||||
@ -1563,7 +1563,7 @@ static void test_file_complex (void)
|
||||
|
||||
g_object_unref (G_OBJECT (file));
|
||||
}
|
||||
</programlisting>
|
||||
</programlisting></informalexample>
|
||||
The code above generates the following output on my machine:
|
||||
<programlisting>
|
||||
Complex Write event before: 0xbfffe280, 50
|
||||
@ -1618,7 +1618,7 @@ Complex Write event after: 0xbfffe280, 50
|
||||
|
||||
<para>The following code shows the declaration of the <type>MamanFileSimple</type> class structure which contains
|
||||
the <function>write</function> function pointer.
|
||||
<programlisting>
|
||||
<informalexample><programlisting>
|
||||
struct _MamanFileSimpleClass {
|
||||
GObjectClass parent;
|
||||
|
||||
@ -1627,10 +1627,10 @@ struct _MamanFileSimpleClass {
|
||||
/* signal default handlers */
|
||||
void (*write) (MamanFileSimple *self, guint8 *buffer, guint size);
|
||||
};
|
||||
</programlisting>
|
||||
</programlisting></informalexample>
|
||||
The <function>write</function> function pointer is initialized in the class_init function of the object
|
||||
to <function>default_write_signal_handler</function>:
|
||||
<programlisting>
|
||||
<informalexample><programlisting>
|
||||
static void
|
||||
maman_file_simple_class_init (gpointer g_class,
|
||||
gpointer g_class_data)
|
||||
@ -1639,9 +1639,9 @@ maman_file_simple_class_init (gpointer g_class,
|
||||
MamanFileSimpleClass *klass = MAMAN_FILE_SIMPLE_CLASS (g_class);
|
||||
|
||||
klass->write = default_write_signal_handler;
|
||||
</programlisting>
|
||||
</programlisting></informalexample>
|
||||
Finally, the signal is created with <function><link linkend="g-signal-new">g_signal_new</link></function> in the same class_init function:
|
||||
<programlisting>
|
||||
<informalexample><programlisting>
|
||||
klass->write_signal_id =
|
||||
g_signal_new ("write",
|
||||
G_TYPE_FROM_CLASS (g_class),
|
||||
@ -1654,7 +1654,7 @@ klass->write_signal_id =
|
||||
2 /* n_params */,
|
||||
G_TYPE_POINTER,
|
||||
G_TYPE_UINT);
|
||||
</programlisting>
|
||||
</programlisting></informalexample>
|
||||
Of note, here, is the 4th argument to the function: it is an integer calculated by the <function><link linkend="G-STRUCT-OFFSET">G_STRUCT_OFFSET</link></function>
|
||||
macro which indicates the offset of the member <emphasis>write</emphasis> from the start of the
|
||||
<type>MamanFileSimpleClass</type> class structure.
|
||||
@ -1762,7 +1762,7 @@ klass->write_signal_id =
|
||||
<filename>gobject.h</filename> contains the declaration of <link linkend="GObjectClass"><type>GObjectClass</type></link>
|
||||
whose notify class function is the default handler for the <emphasis>notify</emphasis>
|
||||
signal:
|
||||
<programlisting>
|
||||
<informalexample><programlisting>
|
||||
struct _GObjectClass
|
||||
{
|
||||
GTypeClass g_type_class;
|
||||
@ -1773,14 +1773,14 @@ struct _GObjectClass
|
||||
void (*notify) (GObject *object,
|
||||
GParamSpec *pspec);
|
||||
};
|
||||
</programlisting>
|
||||
</programlisting></informalexample>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
<filename>gobject.c</filename>'s <function><link linkend="g-object-do-class-init">g_object_do_class_init</link></function> function
|
||||
registers the <emphasis>notify</emphasis> signal and initializes this class function
|
||||
to NULL:
|
||||
<programlisting>
|
||||
<informalexample><programlisting>
|
||||
static void
|
||||
g_object_do_class_init (GObjectClass *class)
|
||||
{
|
||||
@ -1799,7 +1799,7 @@ g_object_do_class_init (GObjectClass *class)
|
||||
G_TYPE_NONE,
|
||||
1, G_TYPE_PARAM);
|
||||
}
|
||||
</programlisting>
|
||||
</programlisting></informalexample>
|
||||
<function><link linkend="g-signal-new">g_signal_new</link></function> creates a <link linkend="GClosure"><type>GClosure</type></link> which dereferences the
|
||||
type's class structure to access the class function pointer and invoke it if it not NULL. The
|
||||
class function is ignored it is set to NULL.
|
||||
|
@ -56,10 +56,10 @@
|
||||
The interpreter also often provides a lot of automatic conversions from one type to the other. For example,
|
||||
in Perl, a variable which holds an integer can be automatically converted to a string given the
|
||||
required context:
|
||||
<programlisting>
|
||||
<informalexample><programlisting>
|
||||
my $tmp = 10;
|
||||
print "this is an integer converted to a string:" . $tmp . "\n";
|
||||
</programlisting>
|
||||
</programlisting></informalexample>
|
||||
Of course, it is also often possible to explicitly specify conversions when the default conversions provided
|
||||
by the language are not intuitive.
|
||||
</para>
|
||||
@ -88,7 +88,7 @@ print "this is an integer converted to a string:" . $tmp . "\n";
|
||||
<para>
|
||||
For the sake of discussion, here is a sample C function and the associated 32 bit x86
|
||||
assembly code generated by GCC on my Linux box:
|
||||
<programlisting>
|
||||
<informalexample><programlisting>
|
||||
static void function_foo (int foo)
|
||||
{}
|
||||
|
||||
@ -102,7 +102,7 @@ int main (int argc, char *argv[])
|
||||
|
||||
push $0xa
|
||||
call 0x80482f4 <function_foo>
|
||||
</programlisting>
|
||||
</programlisting></informalexample>
|
||||
The assembly code shown above is pretty straightforward: the first instruction pushes
|
||||
the hexadecimal value 0xa (decimal value 10) as a 32-bit integer on the stack and calls
|
||||
<function>function_foo</function>. As you can see, C function calls are implemented by
|
||||
|
@ -99,7 +99,7 @@ break g_object_unref if _object == 0xcafebabe
|
||||
(a small program part of the libxslt library) to generate the final HTML
|
||||
output. Other tools can be used to generate PDF output from the source XML.
|
||||
The following code excerpt shows what these comments look like.
|
||||
<programlisting>
|
||||
<informalexample><programlisting>
|
||||
/**
|
||||
* gtk_widget_freeze_child_notify:
|
||||
* @widget: a #GtkWidget
|
||||
@ -113,7 +113,7 @@ void
|
||||
gtk_widget_freeze_child_notify (GtkWidget *widget)
|
||||
{
|
||||
...
|
||||
</programlisting>
|
||||
</programlisting></informalexample>
|
||||
</para>
|
||||
<para>
|
||||
Thorough
|
||||
|
Loading…
Reference in New Issue
Block a user