From 66ef10eec9f4acae19335373fe7cbbebed5ceb60 Mon Sep 17 00:00:00 2001 From: =?utf8?q?S=C3=A9bastien=20Wilmet?= Date: Thu, 18 Sep 2014 16:41:32 +0200 Subject: [PATCH] docs: syntax highlighting for the code examples In the sections Concepts, Tools and Tutorial. https://bugzilla.gnome.org/show_bug.cgi?id=736914 --- docs/reference/gobject/glib-genmarshal.xml | 12 +-- docs/reference/gobject/glib-mkenums.xml | 12 +-- docs/reference/gobject/tut_gobject.xml | 20 ++-- docs/reference/gobject/tut_gsignal.xml | 40 ++++---- docs/reference/gobject/tut_gtype.xml | 80 +++++++-------- docs/reference/gobject/tut_howto.xml | 156 ++++++++++++++--------------- docs/reference/gobject/tut_intro.xml | 8 +- docs/reference/gobject/tut_tools.xml | 4 +- 8 files changed, 166 insertions(+), 166 deletions(-) diff --git a/docs/reference/gobject/glib-genmarshal.xml b/docs/reference/gobject/glib-genmarshal.xml index 48dea06..50a4251 100644 --- a/docs/reference/gobject/glib-genmarshal.xml +++ b/docs/reference/gobject/glib-genmarshal.xml @@ -51,9 +51,9 @@ passed as additional arguments on the command line. The marshaller lists are processed line by line, a line can contain a comment in the form of - + # this is a comment - + or a marshaller specification of the form RTYPE:PTYPE @@ -329,7 +329,7 @@ Print version and exit. To generate marshallers for the following callback functions: - + void foo (gpointer data1, gpointer data2); void bar (gpointer data1, @@ -339,7 +339,7 @@ gfloat baz (gpointer data1, gboolean param1, guchar param2, gpointer data2); - + The marshaller.list file has to look like this: @@ -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: - + 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); - + See also diff --git a/docs/reference/gobject/glib-mkenums.xml b/docs/reference/gobject/glib-mkenums.xml index 6ede634..6baea6e 100644 --- a/docs/reference/gobject/glib-mkenums.xml +++ b/docs/reference/gobject/glib-mkenums.xml @@ -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: - + typedef enum { PREFIX_THE_XVALUE = 1 << 3, PREFIX_ANOTHER_VALUE = 1 << 4 } PrefixTheXEnum; - + @EnumName@ @@ -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: - + 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; - + @@ -272,10 +272,10 @@ Template for auto-generated comments, the default (for C code generations) is Read templates from the given file. The templates are enclosed in specially-formatted C comments - + /*** BEGIN section ***/ /*** END section ***/ - + where section may be file-header, file-production, file-tail, enumeration-production, value-header, diff --git a/docs/reference/gobject/tut_gobject.xml b/docs/reference/gobject/tut_gobject.xml index c3b8ed1..99d8907 100644 --- a/docs/reference/gobject/tut_gobject.xml +++ b/docs/reference/gobject/tut_gobject.xml @@ -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: - + GObject *(* constructor) (GType gtype, guint n_properties, GObjectConstructParam *properties); - + The example below shows how MamanBar overrides the parent's constructor: - + #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 */ } - + If the user instantiates an object MamanBar with: - + MamanBar *bar = g_object_new (MAMAN_TYPE_BAR, NULL); - + If this is the first instantiation of such an object, the maman_bar_class_init function will be invoked after any maman_bar_base_class_init 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. - + /* Refcounting */ @@ -293,7 +293,7 @@ void g_object_remove_weak_pointer (GObject *object, * Cycle handling */ void g_object_run_dispose (GObject *object); - + @@ -705,14 +705,14 @@ g_value_unset (&val); It is interesting to note that the g_object_set and g_object_set_valist (vararg version) functions can be used to set multiple properties at once. The client code shown above can then be re-written as: - + MamanBar *foo; foo = /* */; g_object_set (G_OBJECT (foo), "papa-number", 2, "maman-name", "test", NULL); - + This saves us from managing the GValues that we were needing to handle when using g_object_set_property. The code above will trigger one notify signal emission for each property modified. diff --git a/docs/reference/gobject/tut_gsignal.xml b/docs/reference/gobject/tut_gsignal.xml index 2d520af..1d3e743 100644 --- a/docs/reference/gobject/tut_gsignal.xml +++ b/docs/reference/gobject/tut_gsignal.xml @@ -15,9 +15,9 @@ which contains three objects: a function pointer (the callback itself) whose prototype looks like: - + return_type function_callback (... , gpointer user_data); - + 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 GCClosures which have a pretty minimal API or the even simpler g_signal_connect functions (which will be presented a bit later :). - + 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); - + @@ -128,7 +128,7 @@ GClosure *g_signal_type_cclosure_new (GType itype, The following code implements a simple marshaller in C for a C function which takes an integer as first parameter and returns void. - + 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); } - + @@ -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: - + return_type function_callback (gpointer instance, ... , gpointer user_data); - + @@ -205,7 +205,7 @@ return_type function_callback (gpointer instance, ... , gpointer user_data); To register a new signal on an existing type, we can use any of g_signal_newv, g_signal_new_valist or g_signal_new functions: - + 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); - + The number of parameters to these functions is a bit intimidating but they are relatively simple: @@ -310,12 +310,12 @@ guint g_signal_newv (const gchar *signal_name, Signal emission is done through the use of the g_signal_emit family of functions. - + void g_signal_emitv (const GValue *instance_and_params, guint signal_id, GQuark detail, GValue *return_value); - + 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, g_quark_from_string and g_quark_to_string. : - + gulong g_signal_connect_closure_by_id (gpointer instance, guint signal_id, GQuark detail, GClosure *closure, gboolean after); - + The two other functions hide the detail parameter in the signal name identification: - + 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); - + 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 signal_name::detail_name. Connecting to the signal @@ -471,7 +471,7 @@ gulong g_signal_connect_data (gpointer instance, Of the four main signal emission functions, three have an explicit detail parameter as a GQuark again: - + 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, ...); - + The fourth function hides it in its signal name parameter: - + void g_signal_emit_by_name (gpointer instance, const gchar *detailed_signal, ...); - + The format of the detailed_signal parameter is exactly the same as the format used by the g_signal_connect functions: signal_name::detail_name. diff --git a/docs/reference/gobject/tut_gtype.xml b/docs/reference/gobject/tut_gtype.xml index a01cd4a..b96e4d6 100644 --- a/docs/reference/gobject/tut_gtype.xml +++ b/docs/reference/gobject/tut_gtype.xml @@ -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. - + 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); - + @@ -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 GObject instance pointer (sample code for this is located in the source tarball for this document in sample/gtype/test.c): - + 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)); } - + 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) gtype.h and is thoroughly described in the API documentation provided with GObject (for once ;-) which is why we will not detail its exact semantics. - + typedef struct _GTypeValueTable GTypeValueTable; struct _GTypeValueTable { @@ -213,7 +213,7 @@ struct _GTypeValueTable GTypeCValue *collect_values, guint collect_flags); }; - + 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 gtype.h. For the example we used above, we would write the following trivial code to declare the macros: - + #define MAMAN_TYPE_BAR (maman_bar_get_type ()) #define MAMAN_BAR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MAMAN_TYPE_BAR, MamanBar)) #define MAMAN_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)) - + Stick to the naming klass as class is a registered c++ keyword. The following code shows how to implement the maman_bar_get_type function: - + GType maman_bar_get_type (void) { static GType type = 0; @@ -318,16 +318,16 @@ GType maman_bar_get_type (void) } return type; } - + If you have no special requirements you can use the G_DEFINE_TYPE macro to define a class: - + G_DEFINE_TYPE (MamanBar, maman_bar, G_TYPE_OBJECT) - + @@ -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 GTypeInfo structure with zeros since these types are also most of the time fundamental: - + 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); - + @@ -401,7 +401,7 @@ G_DEFINE_TYPE (MamanBar, maman_bar, G_TYPE_OBJECT) For example, the code below shows how you could register such a fundamental object type in the type system: - + typedef struct { GObject parent; /* instance members */ @@ -440,7 +440,7 @@ maman_bar_get_type (void) } return type; } - + Upon the first call to maman_bar_get_type, the type named BarType will be registered in the type system as inheriting from the type G_TYPE_OBJECT. @@ -452,7 +452,7 @@ maman_bar_get_type (void) a GTypeClass structure. All instance structures must contain as first member a GTypeInstance structure. The declaration of these C types, coming from gtype.h is shown below: - + struct _GTypeClass { GType g_type; @@ -461,7 +461,7 @@ struct _GTypeInstance { GTypeClass *g_class; }; - + 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 This relationship is best explained by an example: let's take object B which inherits from object A: - + /* A definitions */ typedef struct { GTypeInstance parent; @@ -493,7 +493,7 @@ typedef struct { void (*method_c) (void); void (*method_d) (void); } BClass; - + 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 { Thanks to these simple conditions, it is possible to detect the type of every object instance by doing: - + B *b; b->parent.parent.g_class->g_type - + or, more quickly: - + B *b; ((GTypeInstance*)b)->g_class->g_type - + @@ -521,10 +521,10 @@ B *b; instantiation of these types can be done with g_type_create_instance: - + GTypeInstance* g_type_create_instance (GType type); void g_type_free_instance (GTypeInstance *instance); - + g_type_create_instance 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 GTypeInterface. The following piece of code declares such an interface. - + #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); - + The interface function, maman_ibaz_do_action is implemented in a pretty simple way: - + void maman_ibaz_do_action (MamanIbaz *self) { MAMAN_IBAZ_GET_INTERFACE (self)->do_action (self); } - + maman_ibaz_get_type registers a type named MamanIbaz 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 maman_baz_get_type registers a new GType named MamanBaz which inherits from GObject and which implements the interface MamanIbaz. - + 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; } - + @@ -762,21 +762,21 @@ maman_baz_get_type (void) FooInterface). The GInterfaceInfo structure holds information about the implementation of the interface: - + struct _GInterfaceInfo { GInterfaceInitFunc interface_init; GInterfaceFinalizeFunc interface_finalize; gpointer interface_data; }; - + If you have no special requirements you can use the G_IMPLEMENT_INTERFACE macro to implement an interface: - + 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)); - + @@ -835,7 +835,7 @@ G_DEFINE_TYPE_WITH_CODE (MamanBaz, maman_baz, G_TYPE_OBJECT, default_init function is declared by G_DEFINE_INTERFACE which can be used to define the interface: - + 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 */ } - + Or you can do that yourself in a GType function for your interface: - + 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 */ } - + diff --git a/docs/reference/gobject/tut_howto.xml b/docs/reference/gobject/tut_howto.xml index dea09dc..7ca120c 100644 --- a/docs/reference/gobject/tut_howto.xml +++ b/docs/reference/gobject/tut_howto.xml @@ -88,7 +88,7 @@ MamanBar and its class MamanBarClass (name is case-sensitive). It is customary to declare them with code similar to the following: - + /* * Copyright/Licensing information. */ @@ -139,7 +139,7 @@ GType maman_bar_get_type (void); */ #endif /* __MAMAN_BAR_H__ */ - + 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. - + struct _MamanBarPrivate { int hsize; @@ -173,7 +173,7 @@ maman_bar_init (MamanBar *self) priv->hsize = 42; } - + @@ -183,7 +183,7 @@ maman_bar_init (MamanBar *self) and The Fast Pimpl Idiom for reference). If you opt to use this idiom, you can assign the pointer inside the instance initialization function, e.g.: - + 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; } - + @@ -238,7 +238,7 @@ maman_bar_init (MamanBar *self) on your header include strategy, this can be as simple as #include "maman-bar.h" or as complicated as tens of #include lines ending with #include "maman-bar.h": - + /* * Copyright information */ @@ -258,7 +258,7 @@ struct _MamanBarPrivate { /* * forward definitions */ - + @@ -273,9 +273,9 @@ struct _MamanBarPrivate { the whole .c file - + G_DEFINE_TYPE (MamanBar, maman_bar, G_TYPE_OBJECT) - + @@ -322,7 +322,7 @@ G_DEFINE_TYPE (MamanBar, maman_bar, G_TYPE_OBJECT) As such, I would recommend writing the following code first: - + 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. */ } - + @@ -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. - + 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"); } - + @@ -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. - + /* 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. */ } - + @@ -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. - + /* 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 */); } - + The code above simply redirects the do_action call to the relevant class function. @@ -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". - + 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 */); } - + @@ -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: - + /* declaration in maman-bar.h. */ struct _MamanBarClass { @@ -646,10 +646,10 @@ struct _MamanBarClass }; void maman_bar_do_any_action (MamanBar *self, /* parameters */); - + These class functions are often used to delegate part of the job to child classes: - + /* 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 */ } - + Again, it is possible to provide a default implementation for this private virtual class function: - + 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; } - + Children can then implement the subclass with code such as: - + 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; } - + @@ -754,7 +754,7 @@ maman_bar_subtype_class_init (MamanBarSubTypeClass *klass) directly, though, you should use the parent_class pointer created and initialized for us by the G_DEFINE_TYPE_* family of macros, for instance: - + 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 */ } - + @@ -791,7 +791,7 @@ b_method_to_call (B *obj, int a) As above, the first step is to get the header right. This interface defines two methods: - + #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__ */ - + This code is the same as the code for a normal GType which derives from a GObject except for a few details: @@ -859,7 +859,7 @@ void maman_ibaz_do_something (MamanIbaz *self); structure to access its associated interface function and call it. - + 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); } - + @@ -896,7 +896,7 @@ maman_ibaz_do_something (MamanIbaz *self) The first step is to define a normal GObject class, like: - + #ifndef __MAMAN_BAZ_H__ #define __MAMAN_BAZ_H__ @@ -928,7 +928,7 @@ struct _MamanBazClass GType maman_baz_get_type (void); #endif /* __MAMAN_BAZ_H__ */ - + @@ -945,13 +945,13 @@ GType maman_baz_get_type (void); and the G_IMPLEMENT_INTERFACE macros. - + 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)) - + 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 G_IMPLEMENT_INTERFACE. @@ -967,7 +967,7 @@ G_DEFINE_TYPE_WITH_CODE (MamanBar, maman_bar, G_TYPE_OBJECT, maman_baz_interface_init, the interface initialization function: inside it every virtual method of the interface must be assigned to its implementation: - + 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; } - + @@ -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: - + /* Make the MamanIbar interface require MamanIbaz interface. */ G_DEFINE_INTERFACE (MamanIbar, maman_ibar, MAMAN_TYPE_IBAZ); - + In the G_DEFINE_INTERFACE 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: - + 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)) - + It is very important to notice that the order in which interface implementations are added to the main object is not random: g_type_add_interface_static, @@ -1117,7 +1117,7 @@ G_DEFINE_TYPE_WITH_CODE (MamanBar, maman_bar, G_TYPE_OBJECT, line in the maman_ibaz_default_init as shown below: - + static void maman_ibaz_default_init (MamanIbazInteface *iface) { @@ -1128,7 +1128,7 @@ maman_ibaz_default_init (MamanIbazInteface *iface) "maman", G_PARAM_READWRITE)); } - + @@ -1147,7 +1147,7 @@ maman_ibaz_default_init (MamanIbazInteface *iface) instead of g_object_class_install_property. The following code snippet shows the modifications needed in the MamanBaz declaration and implementation above: - + struct _MamanBaz { @@ -1215,7 +1215,7 @@ maman_baz_class_init (MamanBazClass *klass) g_object_class_override_property (gobject_class, PROP_NAME, "name"); } - + @@ -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. - + static void maman_derived_ibaz_do_action (MamanIbaz *ibaz) { @@ -1270,7 +1270,7 @@ maman_derived_baz_init (MamanDerivedBaz *self) { } - + @@ -1291,7 +1291,7 @@ maman_derived_baz_init (MamanDerivedBaz *self) In this example MamanDerivedBaz overides the do_action interface method. In its overridden method it calls the base class implementation of the same interface method. - + static MamanIbazInterface *maman_ibaz_parent_interface = NULL; static void @@ -1324,7 +1324,7 @@ static void maman_derived_baz_init (MamanDerivedBaz *self) { } - + @@ -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. - + 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)); - + The MamanFile signal is registered in the class_init function: - + 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 */); - + and the signal is emitted in maman_file_write: - + 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 */); } - + 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 @@ -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 marshall.list which contains the following single line: - + VOID:POINTER,UINT - + and use the Makefile provided in sample/signal/Makefile to generate the file named maman-file-complex-marshall.c. This C file is finally included in maman-file-complex.c. @@ -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 MamanFileComplex (full source for this object is included in sample/signal/maman-file-complex.{h|c}): - + 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 */); - + 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. @@ -1492,7 +1492,7 @@ klass->write_signal_id = Of course, you need to implement completely the code for the default closure since I just provided a skeleton: - + 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); } - + Finally, the client code must invoke the maman_file_complex_write function which triggers the signal emission: - + 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); } - + @@ -1531,7 +1531,7 @@ void maman_file_complex_write (MamanFileComplex *self, guint8 *buffer, guint siz - + 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)); } - + The code above generates the following output on my machine: Complex Write event before: 0xbfffe280, 50 @@ -1618,7 +1618,7 @@ Complex Write event after: 0xbfffe280, 50 The following code shows the declaration of the MamanFileSimple class structure which contains the write function pointer. - + struct _MamanFileSimpleClass { GObjectClass parent; @@ -1627,10 +1627,10 @@ struct _MamanFileSimpleClass { /* signal default handlers */ void (*write) (MamanFileSimple *self, guint8 *buffer, guint size); }; - + The write function pointer is initialized in the class_init function of the object to default_write_signal_handler: - + 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; - + Finally, the signal is created with g_signal_new in the same class_init function: - + 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); - + Of note, here, is the 4th argument to the function: it is an integer calculated by the G_STRUCT_OFFSET macro which indicates the offset of the member write from the start of the MamanFileSimpleClass class structure. @@ -1762,7 +1762,7 @@ klass->write_signal_id = gobject.h contains the declaration of GObjectClass whose notify class function is the default handler for the notify signal: - + struct _GObjectClass { GTypeClass g_type_class; @@ -1773,14 +1773,14 @@ struct _GObjectClass void (*notify) (GObject *object, GParamSpec *pspec); }; - + gobject.c's g_object_do_class_init function registers the notify signal and initializes this class function to NULL: - + 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); } - + g_signal_new creates a GClosure 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. diff --git a/docs/reference/gobject/tut_intro.xml b/docs/reference/gobject/tut_intro.xml index 8cfcef7..7f9e096 100644 --- a/docs/reference/gobject/tut_intro.xml +++ b/docs/reference/gobject/tut_intro.xml @@ -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: - + my $tmp = 10; print "this is an integer converted to a string:" . $tmp . "\n"; - + Of course, it is also often possible to explicitly specify conversions when the default conversions provided by the language are not intuitive. @@ -88,7 +88,7 @@ print "this is an integer converted to a string:" . $tmp . "\n"; 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: - + static void function_foo (int foo) {} @@ -102,7 +102,7 @@ int main (int argc, char *argv[]) push $0xa call 0x80482f4 <function_foo> - + 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_foo. As you can see, C function calls are implemented by diff --git a/docs/reference/gobject/tut_tools.xml b/docs/reference/gobject/tut_tools.xml index b5effa6..3fd807d 100644 --- a/docs/reference/gobject/tut_tools.xml +++ b/docs/reference/gobject/tut_tools.xml @@ -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. - + /** * gtk_widget_freeze_child_notify: * @widget: a #GtkWidget @@ -113,7 +113,7 @@ void gtk_widget_freeze_child_notify (GtkWidget *widget) { ... - + Thorough -- 2.7.4