Imported Upstream version 2.55.0
[platform/upstream/glib.git] / docs / reference / gobject / tut_gsignal.xml
index 87f6c75..4ed4211 100644 (file)
@@ -1,6 +1,6 @@
-<?xml version='1.0' encoding="ISO-8859-1"?>
-<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" 
-               "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
+<?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>
       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>
+<informalexample><programlisting>
+return_type function_callback ( , gpointer user_data);
+</programlisting></informalexample>
         </para></listitem>
         <listitem><para>
-           the user_data pointer which is passed to the callback upon invocation of the closure
+           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
@@ -32,7 +32,7 @@ return_type function_callback (... , gpointer user_data);
 
     <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
+      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
@@ -79,32 +79,27 @@ return_type function_callback (... , gpointer user_data);
         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 :).
-<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>
+        functions (which will be presented a bit later).
       </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.
+        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 callback_func with the user-provided user_data as first parameter (instead of being 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 destroy_data 
-        function if the user has supplied one.
+        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>
 
@@ -124,11 +119,21 @@ GClosure *g_signal_type_cclosure_new (GType          itype,
         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 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>
+
       <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>
+        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,
@@ -154,17 +159,15 @@ g_cclosure_marshal_VOID__INT (GClosure     *closure,
             g_marshal_value_peek_int (param_values + 1),
             data2);
 }
-</programlisting>
+</programlisting></informalexample>
       </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 the GNOME source code repository).
+        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>
 
     </sect2>
@@ -177,8 +180,8 @@ g_cclosure_marshal_VOID__INT (GClosure     *closure,
       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.
+      from the windowing system and generates a GTK+ event in the form of a signal emission
+      on the widget object instance.
     </para>
 
     <para>
@@ -194,9 +197,9 @@ g_cclosure_marshal_VOID__INT (GClosure     *closure,
       When a signal is emitted on a given type instance, all the closures
       connected to this signal on this type instance will be invoked. All the closures
       connected to such a signal represent callbacks whose signature looks like:
-<programlisting>
-return_type function_callback (gpointer instance, ... , gpointer user_data);
-</programlisting>
+<informalexample><programlisting>
+return_type function_callback (gpointer instance, , gpointer user_data);
+</programlisting></informalexample>
     </para>
 
     <sect2 id="signal-registration">
@@ -205,7 +208,7 @@ return_type function_callback (gpointer instance, ... , gpointer user_data);
          <para>
                To register a new signal on an existing type, we can use any of <function><link linkend="g-signal-newv">g_signal_newv</link></function>,
                <function><link linkend="g-signal-new-valist">g_signal_new_valist</link></function> or <function><link linkend="g-signal-new">g_signal_new</link></function> functions:
-<programlisting>
+<informalexample><programlisting>
 guint g_signal_newv (const gchar        *signal_name,
                      GType               itype,
                      GSignalFlags        signal_flags,
@@ -216,48 +219,52 @@ guint g_signal_newv (const gchar        *signal_name,
                      GType               return_type,
                      guint               n_params,
                      GType              *param_types);
-</programlisting>
+</programlisting></informalexample>
                The number of parameters to these functions is a bit intimidating but they are relatively
                simple:
                <itemizedlist>
                  <listitem><para>
-                         signal_name: is a string which can be used to uniquely identify a given signal.
+                         <parameter>signal_name</parameter>: 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.
+                         <parameter>itype</parameter>: 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
+                         <parameter>signal_flags</parameter>: 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
+                         <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>
-                         accumulator: this is a function pointer which is invoked after each closure
+                         <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>
-                         accumulator_data: this pointer will be passed down to each invocation of the
+                         <parameter>accu_data</parameter>: 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
+                         <parameter>c_marshaller</parameter>: 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.
+                         <parameter>return_type</parameter>: 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.
+                         <parameter>n_params</parameter>: 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
+                         <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>
@@ -279,12 +286,12 @@ guint g_signal_newv (const gchar        *signal_name,
                <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.
+                 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
+                 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>
@@ -310,108 +317,98 @@ guint g_signal_newv (const gchar        *signal_name,
          <para>
                Signal emission is done through the use of the <function><link linkend="g-signal-emit">g_signal_emit</link></function> family 
                of functions.
-<programlisting>
+<informalexample><programlisting>
 void g_signal_emitv (const GValue *instance_and_params,
                      guint         signal_id,
                      GQuark        detail,
                      GValue       *return_value);
-</programlisting>
+</programlisting></informalexample>
                <itemizedlist>
                  <listitem><para>
-                       The instance_and_params array of GValues contains the list of input
+                       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>
-                       signal_id identifies the signal to invoke.
+                       <parameter>signal_id</parameter> 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 
+                       <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>
-                       return_value holds the return value of the last closure invoked during emission if
+                       <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
+                       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.
+                       emission, the <parameter>return_value</parameter> 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>
+               <orderedlist>
                  <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.
+                       <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>
-                       <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. 
+                       <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>
-                       <emphasis>HANDLER_RUN_FIRST</emphasis>: if any closure were connected
+                       <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.
-                       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.
+                       <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>
-                       <emphasis>HANDLER_RUN_LAST</emphasis>: if any closure were connected
+                       <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 HANDLER_RUN_FIRST and if they 
+                       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.
-                       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,
+                       <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>
-               </itemizedlist>      
+               </orderedlist>
          </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.
+               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 RUN_FIRST state.
+               the <literal>RUN_FIRST</literal> state.
          </para>
   
          <para>
                The accumulator function is invoked in all states, after invocation
-               of each closure (except in EMISSION_HOOK and CLEANUP). It accumulates
+               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 CLEANUP state.
+               FALSE. If, at any point, it does not return TRUE, emission jumps
+               to <literal>RUN_CLEANUP</literal> state.
          </para>
 
          <para>
@@ -427,85 +424,60 @@ void g_signal_emitv (const GValue *instance_and_params,
 
          <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. 
+               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>
+               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>:
-<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.
+               </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, three have an explicit detail parameter as a 
-               <link linkend="GQuark"><type>GQuark</type></link> 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>.
+           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 the closures' detail does not match the detail provided by the user, they will not be invoked
-        (even though they are connected to a signal which is being emitted).
+        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 <emphasis>notify</emphasis> signal of GObject: whenever a property is modified on a GObject,
+               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.
@@ -513,7 +485,7 @@ void                  g_signal_emit_by_name (gpointer            instance,
 
          <para>
                As a simple rule, users can and should set the detail parameter to zero: this will disable completely
-        this optional filtering.
+        this optional filtering for that signal.
          </para>
 
        </sect2>