-<?xml version='1.0' encoding="ISO-8859-1"?>
- <chapter id="chapter-signal">
- <title>The GObject messaging system</title>
+<?xml version='1.0' encoding="UTF-8"?>
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+ "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+]>
+<chapter id="chapter-signal">
+ <title>The GObject messaging system</title>
+
+ <sect1 id="closure">
+ <title>Closures</title>
+
+ <para>
+ Closures are central to the concept of asynchronous signal delivery
+ which is widely used throughout GTK+ and GNOME applications. A closure is an
+ abstraction, a generic representation of a callback. It is a small structure
+ which contains three objects:
+ <itemizedlist>
+ <listitem><para>a function pointer (the callback itself) whose prototype looks like:
+<informalexample><programlisting>
+return_type function_callback (… , gpointer user_data);
+</programlisting></informalexample>
+ </para></listitem>
+ <listitem><para>
+ the <parameter>user_data</parameter> pointer which is passed to the callback upon invocation of the closure
+ </para></listitem>
+ <listitem><para>
+ a function pointer which represents the destructor of the closure: whenever the
+ closure's refcount reaches zero, this function will be called before the closure
+ structure is freed.
+ </para></listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+ The <link linkend="GClosure"><type>GClosure</type></link> structure represents the common functionality of all
+ closure implementations: there exists a different closure implementation for
+ each separate runtime which wants to use the GObject type system.
+ <footnote><para>
+ In practice, closures sit at the boundary of language runtimes: if you are
+ writing Python code and one of your Python callbacks receives a signal from
+ a GTK+ widget, the C code in GTK+ needs to execute your Python
+ code. The closure invoked by the GTK+ object invokes the Python callback:
+ it behaves as a normal C object for GTK+ and as a normal Python object for
+ Python code.
+ </para></footnote>
+ The GObject library provides a simple <link linkend="GCClosure"><type>GCClosure</type></link> type which
+ is a specific implementation of closures to be used with C/C++ callbacks.
+ </para>
+ <para>
+ A <link linkend="GClosure"><type>GClosure</type></link> provides simple services:
+ <itemizedlist>
+ <listitem><para>
+ Invocation (<function><link linkend="g-closure-invoke">g_closure_invoke</link></function>): this is what closures
+ were created for: they hide the details of callback invocation from the
+ callback invoker.</para>
+ </listitem>
+ <listitem><para>
+ Notification: the closure notifies listeners of certain events such as
+ closure invocation, closure invalidation and closure finalization. Listeners
+ can be registered with <function><link linkend="g-closure-add-finalize-notifier">g_closure_add_finalize_notifier</link></function>
+ (finalization notification), <function><link linkend="g-closure-add-invalidate-notifier">g_closure_add_invalidate_notifier</link></function>
+ (invalidation notification) and
+ <function><link linkend="g-closure-add-marshal-guards">g_closure_add_marshal_guards</link></function> (invocation notification).
+ There exist symmetric deregistration functions for finalization and invalidation
+ events (<function><link linkend="g-closure-remove-finalize-notifier">g_closure_remove_finalize_notifier</link></function> and
+ <function><link linkend="g-closure-remove-invalidate-notifier">g_closure_remove_invalidate_notifier</link></function>) but not for the invocation
+ process.
+ <footnote><para>
+ Closures are reference counted and notify listeners of their destruction in a two-stage
+ process: the invalidation notifiers are invoked before the finalization notifiers.
+ </para></footnote></para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <sect2>
+ <title>C Closures</title>
- <sect1 id="closure">
- <title>Closures</title>
+ <para>
+ If you are using C or C++
+ 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).
+ </para>
<para>
- Closures are central to the concept of asynchronous signal delivery
- which is widely used throughout GTK+ and GNOME applications. A Closure is an
- abstraction, a generic representation of a callback. It is a small structure
- which contains three objects:
- <itemizedlist>
- <listitem><para>a function pointer (the callback itself) whose prototype looks like:
-<programlisting>
-return_type function_callback (... , gpointer user_data);
-</programlisting>
- </para></listitem>
- <listitem><para>
- the user_data pointer which is passed to the callback upon invocation of the closure
- </para></listitem>
- <listitem><para>
- a function pointer which represents the destructor of the closure: whenever the
- closure's refcount reaches zero, this function will be called before the closure
- structure is freed.
- </para></listitem>
- </itemizedlist>
+ <function><link linkend="g-cclosure-new">g_cclosure_new</link></function> will create a new closure which can invoke the
+ user-provided callback_func with the user-provided
+ <parameter>user_data</parameter> as its last parameter. When the closure
+ is finalized (second stage of the destruction process), it will invoke
+ the <parameter>destroy_data</parameter> function if the user has
+ supplied one.
</para>
+
+ <para>
+ <function><link linkend="g-cclosure-new-swap">g_cclosure_new_swap</link></function> will create a new closure which can invoke the
+ user-provided <parameter>callback_func</parameter> with the
+ user-provided <parameter>user_data</parameter> as its first parameter
+ (instead of being the
+ last parameter as with <function><link linkend="g-cclosure-new">g_cclosure_new</link></function>). When the closure
+ is finalized (second stage of the destruction process), it will invoke
+ the <parameter>destroy_data</parameter> function if the user has
+ supplied one.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Non-C closures (for the fearless)</title>
<para>
- The <type><link linkend="GClosure">GClosure</link></type> structure represents the common functionality of all
- closure implementations: there exists a different Closure implementation for
- each separate runtime which wants to use the GObject type system.
- <footnote><para>
- In Practice, Closures sit at the boundary of language runtimes: if you are
- writing python code and one of your Python callback receives a signal from
- one of GTK+ widgets, the C code in GTK+ needs to execute your Python
- code. The Closure invoked by the GTK+ object invokes the Python callback:
- it behaves as a normal C object for GTK+ and as a normal Python object for
- python code.
- </para></footnote>
- The GObject library provides a simple <type><link linkend="GCClosure">GCClosure</link></type> type which
- is a specific implementation of closures to be used with C/C++ callbacks.
+ As was explained above, closures hide the details of callback invocation. In C,
+ callback invocation is just like function invocation: it is a matter of creating
+ the correct stack frame for the called function and executing a <emphasis>call</emphasis>
+ assembly instruction.
+ </para>
+
+ <para>
+ C closure marshallers transform the array of GValues which represent
+ the parameters to the target function into a C-style function parameter list, invoke
+ the user-supplied C function with this new parameter list, get the return value of the
+ function, transform it into a GValue and return this GValue to the marshaller caller.
</para>
+
<para>
- A <type><link linkend="GClosure">GClosure</link></type> provides simple services:
- <itemizedlist>
- <listitem><para>
- Invocation (<function><link linkend="g-closure-invoke">g_closure_invoke</link></function>): this is what closures
- were created for: they hide the details of callback invocation from the
- callback invocator.
- </para></listitem>
- <listitem><para>
- Notification: the closure notifies listeners of certain events such as
- closure invocation, closure invalidation and closure finalization. Listeners
- can be registered with <function><link linkend="g-closure-add-finalize-notifier">g_closure_add_finalize_notifier</link></function>
- (finalization notification), <function><link linkend="g-closure-add-invalidate-notifier">g_closure_add_invalidate_notifier</link></function>
- (invalidation notification) and
- <function><link linkend="g-closure-add-marshal-guards">g_closure_add_marshal_guards</link></function> (invocation notification).
- There exist symmetric de-registration functions for finalization and invalidation
- events (<function><link linkend="g-closure-remove-finalize-notifier">g_closure_remove_finalize_notifier</link></function> and
- <function><link linkend="g-closure-remove-invalidate-notifier">g_closure_remove_invalidate_notifier</link></function>) but not for the invocation
- process.
- <footnote><para>
- Closures are refcounted and notify listeners of their destruction in a two-stage
- process: the invalidation notifiers are invoked before the finalization notifiers.
- </para></footnote>
- </para></listitem>
- </itemizedlist>
+ A generic C closure marshaller is available as
+ <link linkend="g-cclosure-marshal-generic"><function>g_cclosure_marshal_generic</function></link>
+ which implements marshalling for all function types using libffi. Custom
+ marshallers for different types are not needed apart from performance
+ critical code where the libffi-based marshaller may be too slow.
</para>
- <sect2>
- <title>C Closures</title>
-
- <para>
- If you are using C or C++
- to connect a callback to a given event, you will either use the simple <type><link linkend="GCClosure">GCClosure</link></type>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>
-GClosure* g_cclosure_new (GCallback callback_func,
- gpointer user_data,
- GClosureNotify destroy_data);
-GClosure* g_cclosure_new_swap (GCallback callback_func,
- gpointer user_data,
- GClosureNotify destroy_data);
-GClosure* g_signal_type_cclosure_new (GType itype,
- guint struct_offset);
- </programlisting>
- </para>
-
- <para>
- <function><link linkend="g-cclosure-new">g_cclosure_new</link></function> will create a new closure which can invoke the
- user-provided callback_func with the user-provided user_data as last parameter. When the closure
- is finalized (second stage of the destruction process), it will invoke the destroy_data function
- if the user has supplied one.
- </para>
-
- <para>
- <function><link linkend="g-cclosure-new-swap">g_cclosure_new_swap</link></function> will create a new closure which can invoke the
- user-provided callback_func with the user-provided user_data as first parameter (instead of being the
- last parameter as with <function><link linkend="g-cclosure-new">g_cclosure_new</link></function>). When the closure
- is finalized (second stage of the destruction process), it will invoke the destroy_data
- function if the user has supplied one.
- </para>
- </sect2>
-
- <sect2>
- <title>non-C closures (for the fearless).</title>
-
- <para>
- As was explained above, Closures hide the details of callback invocation. In C,
- callback invocation is just like function invocation: it is a matter of creating
- the correct stack frame for the called function and executing a <emphasis>call</emphasis>
- assembly instruction.
- </para>
-
- <para>
- C closure marshallers transform the array of GValues which represent
- the parameters to the target function into a C-style function parameter list, invoke
- the user-supplied C function with this new parameter list, get the return value of the
- function, transform it into a GValue and return this GValue to the marshaller caller.
- </para>
-
- <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>
+ <para>
+ An example of a custom marshaller is given below, illustrating how
+ <type>GValue</type>s can be converted to a C function call. The
+ marshaller is for a C function which takes an integer as its first
+ parameter and returns void.
+<informalexample><programlisting>
g_cclosure_marshal_VOID__INT (GClosure *closure,
GValue *return_value,
guint n_param_values,
g_marshal_value_peek_int (param_values + 1),
data2);
}
- </programlisting>
- </para>
-
- <para>
- Of course, there exist other kinds of marshallers. For example, James Henstridge
- wrote a generic Python marshaller which is used by all python Closures (a python closure
- is used to have python-based callback be invoked by the closure invocation process).
- This python marshaller transforms the input GValue list representing the function
- parameters into a Python tuple which is the equivalent structure in python (you can
- look in <function>pyg_closure_marshal</function> in <filename>pygtype.c</filename>
- in the <emphasis>pygobject</emphasis> module in GNOME cvs server).
- </para>
-
- </sect2>
- </sect1>
-
- <sect1 id="signal">
- <title>Signals</title>
-
- <para>
- GObject's signals have nothing to do with standard UNIX signals: they connect
- arbitrary application-specific events with any number of listeners.
- For example, in GTK+, every user event (keystroke or mouse move) is received
- from the X server and generates a GTK+ event under the form of a signal emission
- on a given object instance.
+</programlisting></informalexample>
</para>
-
+
<para>
- Each signal is registered in the type system together with the type on which
- it can be emitted: users of the type are said to <emphasis>connect</emphasis>
- to the signal on a given type instance when they register a closure to be
- invoked upon the signal emission. Users can also emit the signal by themselves
- or stop the emission of the signal from within one of the closures connected
- to the signal.
+ There exist other kinds of marshallers, for example there is a generic
+ Python marshaller which is used by all Python closures (a Python closure
+ is used to invoke a callback written in Python). This Python marshaller
+ transforms the input GValue list representing the function parameters
+ into a Python tuple which is the equivalent structure in Python.
</para>
- <para>
- 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>
-return_type function_callback (gpointer instance, ... , gpointer user_data);
-</programlisting>
+ </sect2>
+ </sect1>
+
+ <sect1 id="signal">
+ <title>Signals</title>
+
+ <para>
+ GObject's signals have nothing to do with standard UNIX signals: they connect
+ arbitrary application-specific events with any number of listeners.
+ For example, in GTK+, every user event (keystroke or mouse move) is received
+ from the windowing system and generates a GTK+ event in the form of a signal emission
+ on the widget object instance.
+ </para>
+
+ <para>
+ Each signal is registered in the type system together with the type on which
+ it can be emitted: users of the type are said to <emphasis>connect</emphasis>
+ to the signal on a given type instance when they register a closure to be
+ invoked upon the signal emission. Users can also emit the signal by themselves
+ or stop the emission of the signal from within one of the closures connected
+ to the signal.
+ </para>
+
+ <para>
+ 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:
+<informalexample><programlisting>
+return_type function_callback (gpointer instance, …, gpointer user_data);
+</programlisting></informalexample>
+ </para>
+
+ <sect2 id="signal-registration">
+ <title>Signal registration</title>
+
+ <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:
+<informalexample><programlisting>
+guint g_signal_newv (const gchar *signal_name,
+ GType itype,
+ GSignalFlags signal_flags,
+ GClosure *class_closure,
+ GSignalAccumulator accumulator,
+ gpointer accu_data,
+ GSignalCMarshaller c_marshaller,
+ GType return_type,
+ guint n_params,
+ GType *param_types);
+</programlisting></informalexample>
+ The number of parameters to these functions is a bit intimidating but they are relatively
+ simple:
+ <itemizedlist>
+ <listitem><para>
+ <parameter>signal_name</parameter>: is a string which can be used to uniquely identify a given signal.
+ </para></listitem>
+ <listitem><para>
+ <parameter>itype</parameter>: is the instance type on which this signal can be emitted.
+ </para></listitem>
+ <listitem><para>
+ <parameter>signal_flags</parameter>: partly defines the order in which closures which were connected to the
+ signal are invoked.
+ </para></listitem>
+ <listitem><para>
+ <parameter>class_closure</parameter>: this is the default closure for the signal: if it is not NULL upon
+ the signal emission, it will be invoked upon this emission of the signal. The
+ moment where this closure is invoked compared to other closures connected to that
+ signal depends partly on the signal_flags.
+ </para></listitem>
+ <listitem><para>
+ <parameter>accumulator</parameter>: this is a function pointer which is invoked after each closure
+ has been invoked. If it returns FALSE, signal emission is stopped. If it returns
+ TRUE, signal emission proceeds normally. It is also used to compute the return
+ value of the signal based on the return value of all the invoked closures.
+ For example, an accumulator could ignore
+ <literal>NULL</literal> returns from closures; or it
+ could build a list of the values returned by the
+ closures.
+ </para></listitem>
+ <listitem><para>
+ <parameter>accu_data</parameter>: this pointer will be passed down to each invocation of the
+ accumulator during emission.
+ </para></listitem>
+ <listitem><para>
+ <parameter>c_marshaller</parameter>: this is the default C marshaller for any closure which is connected to
+ this signal.
+ </para></listitem>
+ <listitem><para>
+ <parameter>return_type</parameter>: this is the type of the return value of the signal.
+ </para></listitem>
+ <listitem><para>
+ <parameter>n_params</parameter>: this is the number of parameters this signal takes.
+ </para></listitem>
+ <listitem><para>
+ <parameter>param_types</parameter>: this is an array of GTypes which indicate the type of each parameter
+ of the signal. The length of this array is indicated by n_params.
+ </para></listitem>
+ </itemizedlist>
</para>
- <sect2 id="signal-registration">
- <title>Signal registration</title>
-
- <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>
-guint g_signal_newv (const gchar *signal_name,
- GType itype,
- GSignalFlags signal_flags,
- GClosure *class_closure,
- GSignalAccumulator accumulator,
- gpointer accu_data,
- GSignalCMarshaller c_marshaller,
- GType return_type,
- guint n_params,
- GType *param_types);
-</programlisting>
- The number of parameters to these functions is a bit intimidating but they are relatively
- simple:
- <itemizedlist>
- <listitem><para>
- signal_name: is a string which can be used to uniquely identify a given signal.
- </para></listitem>
- <listitem><para>
- itype: is the instance type on which this signal can be emitted.
- </para></listitem>
- <listitem><para>
- signal_flags: partly defines the order in which closures which were connected to the
- signal are invoked.
- </para></listitem>
- <listitem><para>
- class_closure: this is the default closure for the signal: if it is not NULL upon
- the signal emission, it will be invoked upon this emission of the signal. The
- moment where this closure is invoked compared to other closures connected to that
- signal depends partly on the signal_flags.
- </para></listitem>
- <listitem><para>
- accumulator: this is a function pointer which is invoked after each closure
- has been invoked. If it returns FALSE, signal emission is stopped. If it returns
- TRUE, signal emission proceeds normally. It is also used to compute the return
- value of the signal based on the return value of all the invoked closures.
- </para></listitem>
- <listitem><para>
- accumulator_data: this pointer will be passed down to each invocation of the
- accumulator during emission.
- </para></listitem>
- <listitem><para>
- c_marshaller: this is the default C marshaller for any closure which is connected to
- this signal.
- </para></listitem>
- <listitem><para>
- return_type: this is the type of the return value of the signal.
- </para></listitem>
- <listitem><para>
- n_params: this is the number of parameters this signal takes.
- </para></listitem>
- <listitem><para>
- param_types: this is an array of GTypes which indicate the type of each parameter
- of the signal. The length of this array is indicated by n_params.
- </para></listitem>
- </itemizedlist>
- </para>
+ <para>
+ As you can see from the above definition, a signal is basically a description
+ of the closures which can be connected to this signal and a description of the
+ order in which the closures connected to this signal will be invoked.
+ </para>
+
+ </sect2>
+
+ <sect2 id="signal-connection">
+ <title>Signal connection</title>
+
+ <para>
+ If you want to connect to a signal with a closure, you have three possibilities:
+ <itemizedlist>
+ <listitem><para>
+ You can register a class closure at signal registration: this is a
+ system-wide operation. i.e.: the class closure will be invoked during each emission
+ of a given signal on <emphasis>any</emphasis> of the instances of the type which supports that signal.
+ </para></listitem>
+ <listitem><para>
+ You can use <function><link linkend="g-signal-override-class-closure">g_signal_override_class_closure</link></function> which
+ overrides the class closure of a given type. It is possible to call this function
+ only on a derived type of the type on which the signal was registered.
+ This function is of use only to language bindings.
+ </para></listitem>
+ <listitem><para>
+ You can register a closure with the <function><link linkend="g-signal-connect">g_signal_connect</link></function>
+ family of functions. This is an instance-specific operation: the closure
+ will be invoked only during emission of a given signal on a given instance.
+ </para></listitem>
+ </itemizedlist>
+ It is also possible to connect a different kind of callback on a given signal:
+ emission hooks are invoked whenever a given signal is emitted whatever the instance on
+ which it is emitted. Emission hooks are used for example to get all mouse_clicked
+ emissions in an application to be able to emit the small mouse click sound.
+ Emission hooks are connected with <function><link linkend="g-signal-add-emission-hook">g_signal_add_emission_hook</link></function>
+ and removed with <function><link linkend="g-signal-remove-emission-hook">g_signal_remove_emission_hook</link></function>.
+ </para>
+
+ </sect2>
+
+ <sect2 id="signal-emission">
+ <title>Signal emission</title>
+
+ <para>
+ Signal emission is done through the use of the <function><link linkend="g-signal-emit">g_signal_emit</link></function> family
+ of functions.
+<informalexample><programlisting>
+void g_signal_emitv (const GValue *instance_and_params,
+ guint signal_id,
+ GQuark detail,
+ GValue *return_value);
+</programlisting></informalexample>
+ <itemizedlist>
+ <listitem><para>
+ The <parameter>instance_and_params</parameter> array of GValues contains the list of input
+ parameters to the signal. The first element of the array is the
+ instance pointer on which to invoke the signal. The following elements of
+ the array contain the list of parameters to the signal.
+ </para></listitem>
+ <listitem><para>
+ <parameter>signal_id</parameter> identifies the signal to invoke.
+ </para></listitem>
+ <listitem><para>
+ <parameter>detail</parameter> identifies the specific detail of the signal to invoke. A detail is a kind of
+ magic token/argument which is passed around during signal emission and which is used
+ by closures connected to the signal to filter out unwanted signal emissions. In most
+ cases, you can safely set this value to zero. See <xref linkend="signal-detail"/> for
+ more details about this parameter.
+ </para></listitem>
+ <listitem><para>
+ <parameter>return_value</parameter> holds the return value of the last closure invoked during emission if
+ no accumulator was specified. If an accumulator was specified during signal creation,
+ this accumulator is used to calculate the return value as a function of the return
+ values of all the closures invoked during emission.
+ If no closure is invoked during
+ emission, the <parameter>return_value</parameter> is nonetheless initialized to zero/null.
+ </para></listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+ Signal emission can be decomposed in 5 steps:
+ <orderedlist>
+ <listitem><para>
+ <literal>RUN_FIRST</literal>: if the
+ <link linkend="G-SIGNAL-RUN-FIRST:CAPS"><literal>G_SIGNAL_RUN_FIRST</literal></link> flag was used
+ during signal registration and if there exists a class closure for this signal,
+ the class closure is invoked.
+ </para></listitem>
+ <listitem><para>
+ <literal>EMISSION_HOOK</literal>: if any emission hook was added to
+ the signal, they are invoked from first to last added. Accumulate return values.
+ </para></listitem>
+ <listitem><para>
+ <literal>HANDLER_RUN_FIRST</literal>: if any closure were connected
+ with the <function><link linkend="g-signal-connect">g_signal_connect</link></function> family of
+ functions, and if they are not blocked (with the <function><link linkend="g-signal-handler-block">g_signal_handler_block</link></function>
+ family of functions) they are run here, from first to last connected.
+ </para></listitem>
+ <listitem><para>
+ <literal>RUN_LAST</literal>: if the <literal>G_SIGNAL_RUN_LAST</literal>
+ flag was set during registration and if a class closure
+ was set, it is invoked here.
+ </para></listitem>
+ <listitem><para>
+ <literal>HANDLER_RUN_LAST</literal>: if any closure were connected
+ with the <function>g_signal_connect_after</function> family of
+ functions, if they were not invoked during <literal>HANDLER_RUN_FIRST</literal> and if they
+ are not blocked, they are run here, from first to last connected.
+ </para></listitem>
+ <listitem><para>
+ <literal>RUN_CLEANUP</literal>: if the <literal>G_SIGNAL_RUN_CLEANUP</literal> flag
+ was set during registration and if a class closure was set,
+ it is invoked here. Signal emission is completed here.
+ </para></listitem>
+ </orderedlist>
+ </para>
+
+ <para>
+ If, at any point during emission (except in <literal>RUN_CLEANUP</literal> or
+ <literal>EMISSION_HOOK</literal> state), one of the closures stops the signal emission with
+ <function><link linkend="g-signal-stop-emission">g_signal_stop_emission</link></function>,
+ emission jumps to <literal>RUN_CLEANUP</literal> state.
+ </para>
+
+ <para>
+ If, at any point during emission, one of the closures or emission hook
+ emits the same signal on the same instance, emission is restarted from
+ the <literal>RUN_FIRST</literal> state.
+ </para>
+
+ <para>
+ The accumulator function is invoked in all states, after invocation
+ of each closure (except in <literal>RUN_EMISSION_HOOK</literal> and
+ <literal>RUN_CLEANUP</literal>). It accumulates
+ the closure return value into the signal return value and returns TRUE or
+ FALSE. If, at any point, it does not return TRUE, emission jumps
+ to <literal>RUN_CLEANUP</literal> state.
+ </para>
+
+ <para>
+ If no accumulator function was provided, the value returned by the last handler
+ run will be returned by <function><link linkend="g-signal-emit">g_signal_emit</link></function>.
+ </para>
+
+ </sect2>
+
+
+ <sect2 id="signal-detail">
+ <title>The <emphasis>detail</emphasis> argument</title>
+
+ <para>All the functions related to signal emission or signal connection have a parameter
+ named the <emphasis>detail</emphasis>. Sometimes, this parameter is hidden by the API
+ but it is always there, in one form or another.
+ </para>
+
+ <para>
+ Of the three main connection functions,
+ only one has an explicit detail parameter as a <link linkend="GQuark"><type>GQuark</type></link>:
+ <link linkend="g-signal-connect-closure-by-id"><function>g_signal_connect_closure_by_id</function></link>.
+ <footnote>
+ <para>A GQuark is an integer which uniquely represents a string. It is possible to transform
+ back and forth between the integer and string representations with the functions
+ <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>
+ </para>
+ <para>
+ The two other functions,
+ <link linkend="g-signal-connect-closure"><function>g_signal_connect_closure</function></link> and
+ <link linkend="g-signal-connect-data"><function>g_signal_connect_data</function></link>
+ hide the detail parameter in the signal name identification.
+ Their <parameter>detailed_signal</parameter> parameter is a
+ string which identifies the name of the signal to connect to.
+ The format of this string should match
+ <emphasis>signal_name::detail_name</emphasis>. For example,
+ connecting to the signal named
+ <emphasis>notify::cursor_position</emphasis> will actually
+ connect to the signal named <emphasis>notify</emphasis> with the
+ <emphasis>cursor_position</emphasis> detail.
+ Internally, the detail string is transformed to a GQuark if it is present.
+ </para>
+
+ <para>
+ Of the four main signal emission functions, one hides it in its
+ signal name parameter:
+ <link linkend="g-signal-connect"><function>g_signal_connect</function></link>.
+ The other three have an explicit detail parameter as a
+ <link linkend="GQuark"><type>GQuark</type></link> again:
+ <link linkend="g-signal-emit"><function>g_signal_emit</function></link>,
+ <link linkend="g-signal-emitv"><function>g_signal_emitv</function></link> and
+ <link linkend="g-signal-emit-valist"><function>g_signal_emit_valist</function></link>.
+ </para>
+
+ <para>
+ If a detail is provided by the user to the emission function, it is used during emission to match
+ against the closures which also provide a detail.
+ If a closure's detail does not match the detail provided by the user, it
+ will not be invoked (even though it is connected to a signal which is
+ being emitted).
+ </para>
+
+ <para>
+ This completely optional filtering mechanism is mainly used as an optimization for signals
+ which are often emitted for many different reasons: the clients can filter out which events they are
+ interested in before the closure's marshalling code runs. For example, this is used extensively
+ by the <link linkend="GObject-notify"><structfield>notify</structfield></link> signal of GObject: whenever a property is modified on a GObject,
+ instead of just emitting the <emphasis>notify</emphasis> signal, GObject associates as a detail to this
+ signal emission the name of the property modified. This allows clients who wish to be notified of changes
+ to only one property to filter most events before receiving them.
+ </para>
+
+ <para>
+ As a simple rule, users can and should set the detail parameter to zero: this will disable completely
+ this optional filtering for that signal.
+ </para>
+
+ </sect2>
+
+ </sect1>
+</chapter>
- <para>
- As you can see from the above definition, a signal is basically a description
- of the closures which can be connected to this signal and a description of the
- order in which the closures connected to this signal will be invoked.
- </para>
-
- </sect2>
-
- <sect2 id="signal-connection">
- <title>Signal connection</title>
-
- <para>
- If you want to connect to a signal with a closure, you have three possibilities:
- <itemizedlist>
- <listitem><para>
- You can register a class closure at signal registration: this is a
- system-wide operation. i.e.: the class_closure will be invoked during each emission
- of a given signal on all the instances of the type which supports that signal.
- </para></listitem>
- <listitem><para>
- You can use <function><link linkend="g-signal-override-class-closure">g_signal_override_class_closure</link></function> which
- overrides the class_closure of a given type. It is possible to call this function
- only on a derived type of the type on which the signal was registered.
- This function is of use only to language bindings.
- </para></listitem>
- <listitem><para>
- You can register a closure with the <function><link linkend="g-signal-connect">g_signal_connect</link></function>
- family of functions. This is an instance-specific operation: the closure
- will be invoked only during emission of a given signal on a given instance.
- </para></listitem>
- </itemizedlist>
- It is also possible to connect a different kind of callback on a given signal:
- emission hooks are invoked whenever a given signal is emitted whatever the instance on
- which it is emitted. Emission hooks are used for example to get all mouse_clicked
- emissions in an application to be able to emit the small mouse click sound.
- Emission hooks are connected with <function><link linkend="g-signal-add-emission-hook">g_signal_add_emission_hook</link></function>
- and removed with <function><link linkend="g-signal-remove-emission-hook">g_signal_remove_emission_hook</link></function>.
- </para>
-
- <para>
- </para>
-
- </sect2>
-
- <sect2 id="signal-emission">
- <title>Signal emission</title>
-
- <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>
-void g_signal_emitv (const GValue *instance_and_params,
- guint signal_id,
- GQuark detail,
- GValue *return_value);
-</programlisting>
- <itemizedlist>
- <listitem><para>
- The instance_and_params array of GValues contains the list of input
- parameters to the signal. The first element of the array is the
- instance pointer on which to invoke the signal. The following elements of
- the array contain the list of parameters to the signal.
- </para></listitem>
- <listitem><para>
- signal_id identifies the signal to invoke.
- </para></listitem>
- <listitem><para>
- detail identifies the specific detail of the signal to invoke. A detail is a kind of
- magic token/argument which is passed around during signal emission and which is used
- by closures connected to the signal to filter out unwanted signal emissions. In most
- cases, you can safely set this value to zero. See <xref linkend="signal-detail"/> for
- more details about this parameter.
- </para></listitem>
- <listitem><para>
- return_value holds the return value of the last closure invoked during emission if
- no accumulator was specified. If an accumulator was specified during signal creation,
- this accumulator is used to calculate the return_value as a function of the return
- values of all the closures invoked during emission.
- <footnote><para>
- James (again!!) gives a few non-trivial examples of accumulators:
- <quote>
- For instance, you may have an accumulator that ignores NULL returns from
- closures, and only accumulates the non-NULL ones. Another accumulator may try
- to return the list of values returned by the closures.
- </quote>
- </para></footnote>
- If no closure is invoked during
- emission, the return_value is nonetheless initialized to zero/null.
- </para></listitem>
- </itemizedlist>
- </para>
-
- <para>
- Internally, the GValue array is passed to the emission function proper,
- <function>signal_emit_unlocked_R</function> (implemented in <filename>gsignal.c</filename>).
- Signal emission can be decomposed in 5 steps:
- <itemizedlist>
- <listitem><para>
- <emphasis>RUN_FIRST</emphasis>: if the G_SIGNAL_RUN_FIRST flag was used
- during signal registration and if there exist a class_closure for this signal,
- the class_closure is invoked. Jump to <emphasis>EMISSION_HOOK</emphasis> state.
- </para></listitem>
- <listitem><para>
- <emphasis>EMISSION_HOOK</emphasis>: if any emission hook was added to
- the signal, they are invoked from first to last added. Accumulate return values
- and jump to <emphasis>HANDLER_RUN_FIRST</emphasis> state.
- </para></listitem>
- <listitem><para>
- <emphasis>HANDLER_RUN_FIRST</emphasis>: if any closure were connected
- with the <function><link linkend="g-signal-connect">g_signal_connect</link></function> family of
- functions, and if they are not blocked (with the <function><link linkend="g-signal-handler-block">g_signal_handler_block</link></function>
- family of functions) they are run here, from first to last connected.
- Jump to <emphasis>RUN_LAST</emphasis> state.
- </para></listitem>
- <listitem><para>
- <emphasis>RUN_LAST</emphasis>: if the G_SIGNAL_RUN_LAST
- flag was set during registration and if a class_closure
- was set, it is invoked here. Jump to
- <emphasis>HANDLER_RUN_LAST</emphasis> state.
- </para></listitem>
- <listitem><para>
- <emphasis>HANDLER_RUN_LAST</emphasis>: if any closure were connected
- with the <function>g_signal_connect_after</function> family of
- functions, if they were not invoked during HANDLER_RUN_FIRST and if they
- are not blocked, they are run here, from first to last connected.
- Jump to <emphasis>RUN_CLEANUP</emphasis> state.
- </para></listitem>
- <listitem><para>
- <emphasis>RUN_CLEANUP</emphasis>: if the G_SIGNAL_RUN_CLEANUP flag
- was set during registration and if a class_closure was set,
- it is invoked here. Signal emission is completed here.
- </para></listitem>
- </itemizedlist>
- </para>
-
- <para>
- If, at any point during emission (except in RUN_CLEANUP state), one of the
- closures or emission hook stops the signal emission with
- <function><link linkend="g-signal-stop">g_signal_stop</link></function>, emission jumps to CLEANUP state.
- </para>
-
- <para>
- If, at any point during emission, one of the closures or emission hook
- emits the same signal on the same instance, emission is restarted from
- the RUN_FIRST state.
- </para>
-
- <para>
- The accumulator function is invoked in all states, after invocation
- of each closure (except in EMISSION_HOOK and CLEANUP). It accumulates
- the closure return value into the signal return value and returns TRUE or
- FALSE. If, at any point, it does not return TRUE, emission jumps to CLEANUP state.
- </para>
-
- <para>
- If no accumulator function was provided, the value returned by the last handler
- run will be returned by <function><link linkend="g-signal-emit">g_signal_emit</link></function>.
- </para>
-
- </sect2>
-
-
- <sect2 id="signal-detail">
- <title>The <emphasis>detail</emphasis> argument</title>
-
- <para>All the functions related to signal emission or signal connection have a parameter
- named the <emphasis>detail</emphasis>. Sometimes, this parameter is hidden by the API
- but it is always there, under one form or another.
- </para>
-
- <para>
- Of the three main connection functions,
- only one has an explicit detail parameter as a <type><link linkend="GQuark">GQuark</link></type>
- <footnote>
- <para>A GQuark is an integer which uniquely represents a string. It is possible to transform
- back and forth between the integer and string representations with the functions
- <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>
-gulong g_signal_connect_closure_by_id (gpointer instance,
- guint signal_id,
- GQuark detail,
- GClosure *closure,
- gboolean after);
-</programlisting>
- The two other functions hide the detail parameter in the signal name identification:
-<programlisting>
-gulong g_signal_connect_closure (gpointer instance,
- const gchar *detailed_signal,
- GClosure *closure,
- gboolean after);
-gulong g_signal_connect_data (gpointer instance,
- const gchar *detailed_signal,
- GCallback c_handler,
- gpointer data,
- GClosureNotify destroy_data,
- GConnectFlags connect_flags);
-</programlisting>
- 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
- named <emphasis>notify::cursor_position</emphasis> will actually connect to the signal
- named <emphasis>notify</emphasis> with the <emphasis>cursor_position</emphasis> name.
- Internally, the detail string is transformed to a GQuark if it is present.
- </para>
-
- <para>
- Of the four main signal emission functions, three have an explicit detail parameter as a
- <type><link linkend="GQuark">GQuark</link></type> again:
-<programlisting>
-void g_signal_emitv (const GValue *instance_and_params,
- guint signal_id,
- GQuark detail,
- GValue *return_value);
-void g_signal_emit_valist (gpointer instance,
- guint signal_id,
- GQuark detail,
- va_list var_args);
-void g_signal_emit (gpointer instance,
- guint signal_id,
- GQuark detail,
- ...);
-</programlisting>
- The fourth function hides it in its signal name parameter:
-<programlisting>
-void g_signal_emit_by_name (gpointer instance,
- const gchar *detailed_signal,
- ...);
-</programlisting>
- 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>
-
- <para>
- If a detail is provided by the user to the emission function, it is used during emission to match
- against the closures which also provide a detail. The closures which provided a detail will not
- be invoked (even though they are connected to a signal which is being emitted) if their detail
- does not match the detail provided by the user.
- </para>
-
- <para>This completely optional filtering mechanism is mainly used as an optimization for signals
- which are often emitted for many different reasons: the clients can filter out which events they are
- interested into before the closure's marshalling code runs. For example, this is used extensively
- by the <emphasis>notify</emphasis> signal of GObject: whenever a property is modified on a GObject,
- instead of just emitting the <emphasis>notify</emphasis> signal, GObject associates as a detail to this
- signal emission the name of the property modified. This allows clients who wish to be notified of changes
- to only one property to filter most events before receiving them.
- </para>
-
- <para>As a simple rule, users can and should set the detail parameter to zero: this will disable completely
- this optional filtering.
- </para>
-
- </sect2>
-
- </sect1>
- </chapter>