mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-08-09 18:54:04 +02:00
integrate patch from Stefan Kost
This commit is contained in:
@@ -28,16 +28,18 @@
|
|||||||
<para>
|
<para>
|
||||||
The <function>g_object_new</function> family of functions can be used to instantiate any
|
The <function>g_object_new</function> family of functions can be used to instantiate any
|
||||||
GType which inherits from the GObject base type. All these functions make sure the class
|
GType which inherits from the GObject base type. All these functions make sure the class
|
||||||
has been correctly initialized by glib's type system and then invoke at one
|
and instance structures have been correctly initialized by glib's type system and
|
||||||
point or another the constructor class method which is used to:
|
then invoke at one point or another the constructor class method which is used to:
|
||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
<listitem><para>
|
<listitem><para>
|
||||||
Allocate memory through <function>g_type_create_instance</function>,
|
Allocate and clear memory through <function>g_type_create_instance</function>,
|
||||||
</para></listitem>
|
</para></listitem>
|
||||||
<listitem><para>
|
<listitem><para>
|
||||||
Initialize the object' instance with the construction properties.
|
Initialize the object' instance with the construction properties.
|
||||||
</para></listitem>
|
</para></listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
|
Although one can expect all class and instance members (except the fields
|
||||||
|
pointing to the parents) to be set to zero, some consider it good practice to explicitly set them.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
@@ -56,7 +58,7 @@
|
|||||||
#define MAMAN_TYPE_BAR (maman_bar_get_type ())
|
#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(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_BAR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MAMAN_TYPE_BAR, MamanBarClass))
|
||||||
#define MAMAN_IS_BAR(obj) (G_TYPE_CHECK_TYPE ((obj), MAMAN_TYPE_BAR))
|
#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_IS_BAR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MAMAN_TYPE_BAR))
|
||||||
#define MAMAN_BAR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MAMAN_TYPE_BAR, MamanBarClass))
|
#define MAMAN_BAR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MAMAN_TYPE_BAR, MamanBarClass))
|
||||||
|
|
||||||
@@ -285,7 +287,8 @@ MamanBar *bar = g_object_new (MAMAN_TYPE_BAR, NULL);
|
|||||||
The memory-management API for GObjects is a bit complicated but the idea behind it
|
The memory-management API for GObjects is a bit complicated but the idea behind it
|
||||||
is pretty simple: the goal is to provide a flexible model based on reference counting
|
is pretty simple: the goal is to provide a flexible model based on reference counting
|
||||||
which can be integrated in applications which use or require different memory management
|
which can be integrated in applications which use or require different memory management
|
||||||
models (such as garbage collection, aso...)
|
models (such as garbage collection, aso...). The methods which are used to
|
||||||
|
manipulate this reference count are described below.
|
||||||
<programlisting>
|
<programlisting>
|
||||||
/*
|
/*
|
||||||
Refcounting
|
Refcounting
|
||||||
@@ -319,10 +322,12 @@ void g_object_run_dispose (GObject *object);
|
|||||||
<title>Reference count</title>
|
<title>Reference count</title>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
<function>g_object_ref</function>/<function>g_object_unref</function> respectively
|
The functions <function>g_object_ref</function>/<function>g_object_unref</function> respectively
|
||||||
increase and decrease the reference count. None of these function is thread-safe.
|
increase and decrease the reference count. None of these function is thread-safe.
|
||||||
The reference count is, unsurprisingly, initialized to one by
|
The reference count is, unsurprisingly, initialized to one by
|
||||||
<function>g_object_new</function>. When the reference count reaches zero, that is,
|
<function>g_object_new</function> which means that the caller
|
||||||
|
is currenly the sole owner of the newly-created reference.
|
||||||
|
When the reference count reaches zero, that is,
|
||||||
when <function>g_object_unref</function> is called by the last client holding
|
when <function>g_object_unref</function> is called by the last client holding
|
||||||
a reference to the object, the <emphasis>dispose</emphasis> and the
|
a reference to the object, the <emphasis>dispose</emphasis> and the
|
||||||
<emphasis>finalize</emphasis> class methods are invoked.
|
<emphasis>finalize</emphasis> class methods are invoked.
|
||||||
@@ -334,8 +339,8 @@ void g_object_run_dispose (GObject *object);
|
|||||||
one of the <function>g_type_register_*</function> functions), the object's instance
|
one of the <function>g_type_register_*</function> functions), the object's instance
|
||||||
memory will be freed or returned to the object pool for this type.
|
memory will be freed or returned to the object pool for this type.
|
||||||
Once the object has been freed, if it was the last instance of the type, the type's class
|
Once the object has been freed, if it was the last instance of the type, the type's class
|
||||||
will be destroyed as described in <xref linkend="gtype-instantiable-classed"></xref> and
|
will be destroyed as described in <xref linkend="gtype-instantiable-classed"/> and
|
||||||
<xref linkend="gtype-non-instantiable-classed"></xref>.
|
<xref linkend="gtype-non-instantiable-classed"/>.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
@@ -383,7 +388,7 @@ void g_object_run_dispose (GObject *object);
|
|||||||
finalize should chain up to its parent implementation just before returning
|
finalize should chain up to its parent implementation just before returning
|
||||||
to the caller.
|
to the caller.
|
||||||
The reason why the destruction process is split is two different phases is
|
The reason why the destruction process is split is two different phases is
|
||||||
explained in <xref linkend="gobject-memory-cycles"></xref>.
|
explained in <xref linkend="gobject-memory-cycles"/>.
|
||||||
</entry>
|
</entry>
|
||||||
</row>
|
</row>
|
||||||
<row>
|
<row>
|
||||||
@@ -521,7 +526,7 @@ void g_object_run_dispose (GObject *object);
|
|||||||
|
|
||||||
enum {
|
enum {
|
||||||
MAMAN_BAR_CONSTRUCT_NAME = 1,
|
MAMAN_BAR_CONSTRUCT_NAME = 1,
|
||||||
MAMAN_BAR_PAPA_NUMBER = 2,
|
MAMAN_BAR_PAPA_NUMBER,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -554,7 +559,7 @@ maman_bar_set_property (GObject *object,
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* We don't have any other property... */
|
/* We don't have any other property... */
|
||||||
g_assert (FALSE);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID(object,property_id,pspec);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -578,7 +583,7 @@ maman_bar_get_property (GObject *object,
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* We don't have any other property... */
|
/* We don't have any other property... */
|
||||||
g_assert (FALSE);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID(object,property_id,pspec);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -282,10 +282,11 @@ struct _GTypeValueTable
|
|||||||
#define MAMAN_BAR_TYPE (maman_bar_get_type ())
|
#define MAMAN_BAR_TYPE (maman_bar_get_type ())
|
||||||
#define MAMAN_BAR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MAMAN_BAR_TYPE, MamanBar))
|
#define MAMAN_BAR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MAMAN_BAR_TYPE, MamanBar))
|
||||||
#define MAMAN_BAR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MAMAN_BAR_TYPE, MamanBarClass))
|
#define MAMAN_BAR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MAMAN_BAR_TYPE, MamanBarClass))
|
||||||
#define MAMAN_IS_BAR(obj) (G_TYPE_CHECK_TYPE ((obj), MAMAN_BAR_TYPE))
|
#define MAMAN_IS_BAR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MAMAN_BAR_TYPE))
|
||||||
#define MAMAN_IS_BAR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MAMAN_BAR_TYPE))
|
#define MAMAN_IS_BAR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MAMAN_BAR_TYPE))
|
||||||
#define MAMAN_BAR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MAMAN_BAR_TYPE, MamanBarClass))
|
#define MAMAN_BAR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MAMAN_BAR_TYPE, MamanBarClass))
|
||||||
</programlisting>
|
</programlisting>
|
||||||
|
<note>Stick to the naming <code>klass</code> as <code>class</code> is a registered c++ keyword.</note>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
@@ -609,7 +610,7 @@ The class initialization process is entirely implemented in
|
|||||||
<row>
|
<row>
|
||||||
<entry>First call to <function>g_type_create_instance</function> for target type</entry>
|
<entry>First call to <function>g_type_create_instance</function> for target type</entry>
|
||||||
<entry colspan="2">interface initialization, see
|
<entry colspan="2">interface initialization, see
|
||||||
<xref linkend="gtype-non-instantiable-classed-init"></xref></entry>
|
<xref linkend="gtype-non-instantiable-classed-init"/></entry>
|
||||||
</row>
|
</row>
|
||||||
<row>
|
<row>
|
||||||
<entry>Each call to <function>g_type_create_instance</function> for target type</entry>
|
<entry>Each call to <function>g_type_create_instance</function> for target type</entry>
|
||||||
@@ -619,7 +620,7 @@ The class initialization process is entirely implemented in
|
|||||||
<row>
|
<row>
|
||||||
<entry>Last call to <function>g_type_free_instance</function> for target type</entry>
|
<entry>Last call to <function>g_type_free_instance</function> for target type</entry>
|
||||||
<entry colspan="2">interface destruction, see
|
<entry colspan="2">interface destruction, see
|
||||||
<xref linkend="gtype-non-instantiable-classed-dest"></xref></entry>
|
<xref linkend="gtype-non-instantiable-classed-dest"/></entry>
|
||||||
<entry></entry>
|
<entry></entry>
|
||||||
</row>
|
</row>
|
||||||
<row>
|
<row>
|
||||||
@@ -646,7 +647,7 @@ The class initialization process is entirely implemented in
|
|||||||
<para>
|
<para>
|
||||||
GType's Interfaces are very similar to Java's interfaces. To declare one of these
|
GType's Interfaces are very similar to Java's interfaces. To declare one of these
|
||||||
you have to register a non-instantiable classed type which derives from
|
you have to register a non-instantiable classed type which derives from
|
||||||
GTypeInterface. The following piece of code declares such an interface.
|
<type>GTypeInterface</type>. The following piece of code declares such an interface.
|
||||||
<programlisting>
|
<programlisting>
|
||||||
#define MAMAN_IBAZ_TYPE (maman_ibaz_get_type ())
|
#define MAMAN_IBAZ_TYPE (maman_ibaz_get_type ())
|
||||||
#define MAMAN_IBAZ(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MAMAN_IBAZ_TYPE, MamanIbaz))
|
#define MAMAN_IBAZ(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MAMAN_IBAZ_TYPE, MamanIbaz))
|
||||||
@@ -765,7 +766,7 @@ struct _GInterfaceInfo
|
|||||||
<para>
|
<para>
|
||||||
When an instantiable classed type which registered an interface implementation
|
When an instantiable classed type which registered an interface implementation
|
||||||
is created for the first time, its class structure is initialized following the process
|
is created for the first time, its class structure is initialized following the process
|
||||||
described in <xref linkend="gtype-instantiable-classed"></xref>. Once the class structure is
|
described in <xref linkend="gtype-instantiable-classed"/>. Once the class structure is
|
||||||
initialized,the function <function>type_class_init_Wm</function> (implemented in <filename>
|
initialized,the function <function>type_class_init_Wm</function> (implemented in <filename>
|
||||||
gtype.c</filename>) initializes the interface implementations associated with
|
gtype.c</filename>) initializes the interface implementations associated with
|
||||||
that type by calling <function>type_iface_vtable_init_Wm</function> for each
|
that type by calling <function>type_iface_vtable_init_Wm</function> for each
|
||||||
@@ -857,7 +858,7 @@ maman_ibaz_base_init (gpointer g_class)
|
|||||||
</table>
|
</table>
|
||||||
It is highly unlikely (ie: I do not know of <emphasis>anyone</emphasis> who actually
|
It is highly unlikely (ie: I do not know of <emphasis>anyone</emphasis> who actually
|
||||||
used it) you will ever need other more fancy things such as the ones described in the
|
used it) you will ever need other more fancy things such as the ones described in the
|
||||||
following section (<xref linkend="gtype-non-instantiable-classed-dest"></xref>).
|
following section (<xref linkend="gtype-non-instantiable-classed-dest"/>).
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
</sect2>
|
</sect2>
|
||||||
@@ -879,7 +880,7 @@ maman_ibaz_base_init (gpointer g_class)
|
|||||||
|
|
||||||
<para>
|
<para>
|
||||||
Again, it is important to understand, as in
|
Again, it is important to understand, as in
|
||||||
<xref linkend="gtype-non-instantiable-classed-init"></xref>,
|
<xref linkend="gtype-non-instantiable-classed-init"/>,
|
||||||
that both <function>interface_finalize</function> and <function>base_finalize</function>
|
that both <function>interface_finalize</function> and <function>base_finalize</function>
|
||||||
are invoked exactly once for the destruction of each implementation of an interface. Thus,
|
are invoked exactly once for the destruction of each implementation of an interface. Thus,
|
||||||
if you were to use one of these functions, you would need to use a static integer variable
|
if you were to use one of these functions, you would need to use a static integer variable
|
||||||
|
@@ -77,6 +77,15 @@
|
|||||||
eyesight like me.
|
eyesight like me.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
When you need some private (internal) declarations in several (sub)classes,
|
||||||
|
you can define them in a private header file which is often named by
|
||||||
|
appending the <emphasis>private</emphasis> keyword to the public header name.
|
||||||
|
For example, one could use <filename>maman-bar-private.h</filename>,
|
||||||
|
<filename>maman_bar_private.h</filename> or <filename>mamanbarprivate.h</filename>.
|
||||||
|
Typically, such private header files are not installed.
|
||||||
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
The basic conventions for any header which exposes a GType are described in
|
The basic conventions for any header which exposes a GType are described in
|
||||||
<xref linkend="gtype-conventions"/>. Most GObject-based code also obeys onf of the following
|
<xref linkend="gtype-conventions"/>. Most GObject-based code also obeys onf of the following
|
||||||
@@ -143,8 +152,10 @@ struct _MamanBar {
|
|||||||
</para></listitem>
|
</para></listitem>
|
||||||
<listitem><para>
|
<listitem><para>
|
||||||
All of Nautilus code and a lot of Gnome libraries use private indirection members, as described
|
All of Nautilus code and a lot of Gnome libraries use private indirection members, as described
|
||||||
by Herb Sutter in his Pimpl articles (see <ulink>http://www.gotw.ca/publications/mill04.htm</ulink>: Herb summarizes the different
|
by Herb Sutter in his Pimpl articles
|
||||||
issues better than I will):
|
(see <ulink url="http://www.gotw.ca/gotw/024.htm">Compilation Firewalls</ulink>
|
||||||
|
and <ulink url="http://www.gotw.ca/gotw/028.htm">The Fast Pimpl Idiom</ulink>
|
||||||
|
: he summarizes the different issues better than I will).
|
||||||
<programlisting>
|
<programlisting>
|
||||||
typedef struct _MamanBarPrivate MamanBarPrivate;
|
typedef struct _MamanBarPrivate MamanBarPrivate;
|
||||||
struct _MamanBar {
|
struct _MamanBar {
|
||||||
@@ -154,6 +165,7 @@ struct _MamanBar {
|
|||||||
MamanBarPrivate *priv;
|
MamanBarPrivate *priv;
|
||||||
};
|
};
|
||||||
</programlisting>
|
</programlisting>
|
||||||
|
<note>Do not call this <code>private</code>, as that is a registered c++ keyword.</note>
|
||||||
The private structure is then defined in the .c file, instantiated in the object's
|
The private structure is then defined in the .c file, instantiated in the object's
|
||||||
<function>init</function> function and destroyed in the object's <function>finalize</function> function.
|
<function>init</function> function and destroyed in the object's <function>finalize</function> function.
|
||||||
<programlisting>
|
<programlisting>
|
||||||
@@ -436,7 +448,7 @@ if (self->private->dispose_has_run) {
|
|||||||
Just as with C++, there are many different ways to define object
|
Just as with C++, there are many different ways to define object
|
||||||
methods and extend them: the following list and sections draw on C++ vocabulary.
|
methods and extend them: the following list and sections draw on C++ vocabulary.
|
||||||
(Readers are expected to know basic C++ buzzwords. Those who have not had to
|
(Readers are expected to know basic C++ buzzwords. Those who have not had to
|
||||||
write C++ code recently can refer to <ulink>http://www.cplusplus.com/doc/tutorial/</ulink> to refresh their
|
write C++ code recently can refer to e.g. <ulink>http://www.cplusplus.com/doc/tutorial/</ulink> to refresh their
|
||||||
memories.)
|
memories.)
|
||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
<listitem><para>
|
<listitem><para>
|
||||||
@@ -931,8 +943,6 @@ baz_instance_init (GTypeInstance *instance,
|
|||||||
<sect2>
|
<sect2>
|
||||||
<title>Interface definition prerequisites</title>
|
<title>Interface definition prerequisites</title>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<para>To specify that an interface requires the presence of other interfaces when implemented,
|
<para>To specify that an interface requires the presence of other interfaces when implemented,
|
||||||
GObject introduces the concept of <emphasis>prerequisites</emphasis>: it is possible to associate
|
GObject introduces the concept of <emphasis>prerequisites</emphasis>: it is possible to associate
|
||||||
a list of prerequisite interfaces to an interface. For example, if object A wishes to implement interface
|
a list of prerequisite interfaces to an interface. For example, if object A wishes to implement interface
|
||||||
@@ -1039,6 +1049,172 @@ maman_bar_get_type (void)
|
|||||||
|
|
||||||
</sect2>
|
</sect2>
|
||||||
|
|
||||||
|
<sect2 id="howto-interface-properties">
|
||||||
|
<title>Interface Properties</title>
|
||||||
|
|
||||||
|
<para>Starting from version 2.4 of glib, gobject interfaces can also have properties.
|
||||||
|
Declaration of the interface properties is similar to declaring the properties of
|
||||||
|
ordinary gobject types as explained in <xref linkend="gobject-properties"/>,
|
||||||
|
except that <function>g_object_interface_install_property</function> is used to
|
||||||
|
declare the properties instead of <function>g_object_class_install_property</function>.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>To include a property named 'name' of type <type>string</type> in the
|
||||||
|
<type>maman_ibaz</type> interface example code above, we only need to add one
|
||||||
|
<footnote>
|
||||||
|
<para>That really is one line extended to six for the sake of clarity
|
||||||
|
</para>
|
||||||
|
</footnote>
|
||||||
|
line in the <function>maman_ibaz_base_init</function>
|
||||||
|
<footnote>
|
||||||
|
<para>The gobject_install_property can also be called from <function>class_init</function> but it must not be called after that point.
|
||||||
|
</para>
|
||||||
|
</footnote>
|
||||||
|
as shown below:
|
||||||
|
<programlisting>
|
||||||
|
static void
|
||||||
|
maman_ibaz_base_init (gpointer g_class)
|
||||||
|
{
|
||||||
|
static gboolean initialized = FALSE;
|
||||||
|
|
||||||
|
if (!initialized) {
|
||||||
|
/* create interface signals here. */
|
||||||
|
|
||||||
|
g_object_interface_install_property (g_class,
|
||||||
|
g_param_spec_string ("name",
|
||||||
|
"maman_ibaz_name",
|
||||||
|
"Name of the MamanIbaz",
|
||||||
|
"maman",
|
||||||
|
G_PARAM_READWRITE));
|
||||||
|
initialized = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</programlisting>
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>One point worth noting is that the declared property wasn't assigned an
|
||||||
|
integer ID. The reason being that integer IDs of properities are utilized only
|
||||||
|
inside the get and set methods and since interfaces do not implement properties,
|
||||||
|
there is no need to assign integer IDs to interface properties.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>The story for the implementers of the interface is also quite trivial.
|
||||||
|
An implementer shall declare and define it's properties in the usual way as
|
||||||
|
explained in <xref linkend="gobject-properties"/>, except for one small
|
||||||
|
change: it shall declare the properties of the interface it implements using
|
||||||
|
<function>g_object_class_override_property</function> instead of
|
||||||
|
<function>g_object_class_install_property</function>. The following code snipet
|
||||||
|
shows the modifications needed in the <type>MamanBaz</type> declaration and
|
||||||
|
implementation above:
|
||||||
|
<programlisting>
|
||||||
|
|
||||||
|
struct _MamanBaz {
|
||||||
|
GObject parent;
|
||||||
|
gint instance_member;
|
||||||
|
gchar *name; /* placeholder for property */
|
||||||
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
ARG_0,
|
||||||
|
ARG_NAME
|
||||||
|
};
|
||||||
|
|
||||||
|
GType
|
||||||
|
maman_baz_get_type (void)
|
||||||
|
{
|
||||||
|
static GType type = 0;
|
||||||
|
if (type == 0) {
|
||||||
|
static const GTypeInfo info = {
|
||||||
|
sizeof (MamanBazClass),
|
||||||
|
NULL, /* base_init */
|
||||||
|
NULL, /* base_finalize */
|
||||||
|
baz_class_init, /* class_init */
|
||||||
|
NULL, /* class_finalize */
|
||||||
|
NULL, /* class_data */
|
||||||
|
sizeof (MamanBaz),
|
||||||
|
0, /* n_preallocs */
|
||||||
|
baz_instance_init /* instance_init */
|
||||||
|
};
|
||||||
|
static const GInterfaceInfo ibaz_info = {
|
||||||
|
(GInterfaceInitFunc) baz_interface_init, /* interface_init */
|
||||||
|
NULL, /* interface_finalize */
|
||||||
|
NULL /* interface_data */
|
||||||
|
};
|
||||||
|
type = g_type_register_static (G_TYPE_OBJECT,
|
||||||
|
"MamanBazType",
|
||||||
|
&info, 0);
|
||||||
|
g_type_add_interface_static (type,
|
||||||
|
MAMAN_TYPE_IBAZ,
|
||||||
|
&ibaz_info);
|
||||||
|
}
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
maman_baz_class_init (MamanBazClass * klass)
|
||||||
|
{
|
||||||
|
GObjectClass *gobject_class;
|
||||||
|
|
||||||
|
gobject_class = (GObjectClass *) klass;
|
||||||
|
|
||||||
|
parent_class = g_type_class_ref (G_TYPE_OBJECT);
|
||||||
|
|
||||||
|
gobject_class->set_property = maman_baz_set_property;
|
||||||
|
gobject_class->get_property = maman_baz_get_property;
|
||||||
|
|
||||||
|
g_object_class_override_property (gobject_class, ARG_NAME, "name");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
maman_baz_set_property (GObject * object, guint prop_id,
|
||||||
|
const GValue * value, GParamSpec * pspec)
|
||||||
|
{
|
||||||
|
MamanBaz *baz;
|
||||||
|
GObject *obj;
|
||||||
|
|
||||||
|
/* it's not null if we got it, but it might not be ours */
|
||||||
|
g_return_if_fail (G_IS_MAMAN_BAZ (object));
|
||||||
|
|
||||||
|
baz = MAMAN_BAZ (object);
|
||||||
|
|
||||||
|
switch (prop_id) {
|
||||||
|
case ARG_NAME:
|
||||||
|
baz->name = g_value_get_string (value);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
maman_baz_get_property (GObject * object, guint prop_id,
|
||||||
|
GValue * value, GParamSpec * pspec)
|
||||||
|
{
|
||||||
|
MamanBaz *baz;
|
||||||
|
|
||||||
|
/* it's not null if we got it, but it might not be ours */
|
||||||
|
g_return_if_fail (G_IS_TEXT_PLUGIN (object));
|
||||||
|
|
||||||
|
baz = MAMAN_BAZ (object);
|
||||||
|
|
||||||
|
switch (prop_id) {
|
||||||
|
case ARG_NAME:
|
||||||
|
g_value_set_string (value, baz->name);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</programlisting>
|
||||||
|
</para>
|
||||||
|
|
||||||
|
</sect2>
|
||||||
|
|
||||||
|
|
||||||
</sect1>
|
</sect1>
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
@@ -1068,7 +1244,7 @@ maman_bar_get_type (void)
|
|||||||
just emit events which can be received by numerous clients.
|
just emit events which can be received by numerous clients.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<sect2>
|
<sect2 id="howto-simple-signals">
|
||||||
<title>Simple use of signals</title>
|
<title>Simple use of signals</title>
|
||||||
|
|
||||||
<para>The most basic use of signals is to implement simple event notification: for example, if we have a
|
<para>The most basic use of signals is to implement simple event notification: for example, if we have a
|
||||||
@@ -1117,8 +1293,16 @@ As shown above, you can safely set the details parameter to zero if you do not k
|
|||||||
For a discussion of what you could used it for, see <xref linkend="signal-detail"/>
|
For a discussion of what you could used it for, see <xref linkend="signal-detail"/>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
</para>
|
The signature of the signal handler in the above example is defined as
|
||||||
|
<function>g_cclosure_marshal_VOID__VOID</function>. Its name follows
|
||||||
|
a simple convention which encodes the function parameter and return value
|
||||||
|
types in the function name. Specifically, the value infront of the double
|
||||||
|
underscore is the type of the return value, while the value(s) after the
|
||||||
|
double underscore denote the parameter types.
|
||||||
|
The header <filename>gobject/gmarshal.h</filename> defines a set of commonly
|
||||||
|
needed closures that one can use.
|
||||||
|
</para>
|
||||||
|
|
||||||
</sect2>
|
</sect2>
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user