• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1<?xml version='1.0' encoding="ISO-8859-1"?>
2<chapter id="chapter-signal">
3  <title>The GObject messaging system</title>
4
5  <sect1 id="closure">
6    <title>Closures</title>
7
8    <para>
9      Closures are central to the concept of asynchronous signal delivery
10      which is widely used throughout GTK+ and GNOME applications. A closure is an
11      abstraction, a generic representation of a callback. It is a small structure
12      which contains three objects:
13      <itemizedlist>
14        <listitem><para>a function pointer (the callback itself) whose prototype looks like:
15<programlisting>
16return_type function_callback (... , gpointer user_data);
17</programlisting>
18        </para></listitem>
19        <listitem><para>
20           the user_data pointer which is passed to the callback upon invocation of the closure
21          </para></listitem>
22        <listitem><para>
23           a function pointer which represents the destructor of the closure: whenever the
24           closure's refcount reaches zero, this function will be called before the closure
25           structure is freed.
26          </para></listitem>
27      </itemizedlist>
28    </para>
29
30    <para>
31      The <type><link linkend="GClosure">GClosure</link></type> structure represents the common functionality of all
32      closure implementations: there exists a different Closure implementation for
33      each separate runtime which wants to use the GObject type system.
34      <footnote><para>
35        In practice, closures sit at the boundary of language runtimes: if you are
36        writing Python code and one of your Python callbacks receives a signal from
37        a GTK+ widget, the C code in GTK+ needs to execute your Python
38        code. The closure invoked by the GTK+ object invokes the Python callback:
39        it behaves as a normal C object for GTK+ and as a normal Python object for
40        Python code.
41      </para></footnote>
42      The GObject library provides a simple <type><link linkend="GCClosure">GCClosure</link></type> type which
43      is a specific implementation of closures to be used with C/C++ callbacks.
44    </para>
45    <para>
46      A <type><link linkend="GClosure">GClosure</link></type> provides simple services:
47      <itemizedlist>
48        <listitem><para>
49          Invocation (<function><link linkend="g-closure-invoke">g_closure_invoke</link></function>): this is what closures
50          were created for: they hide the details of callback invocation from the
51          callback invoker.</para>
52        </listitem>
53        <listitem><para>
54          Notification: the closure notifies listeners of certain events such as
55          closure invocation, closure invalidation and closure finalization. Listeners
56          can be registered with <function><link linkend="g-closure-add-finalize-notifier">g_closure_add_finalize_notifier</link></function>
57          (finalization notification), <function><link linkend="g-closure-add-invalidate-notifier">g_closure_add_invalidate_notifier</link></function>
58          (invalidation notification) and
59          <function><link linkend="g-closure-add-marshal-guards">g_closure_add_marshal_guards</link></function> (invocation notification).
60          There exist symmetric deregistration functions for finalization and invalidation
61          events (<function><link linkend="g-closure-remove-finalize-notifier">g_closure_remove_finalize_notifier</link></function> and
62          <function><link linkend="g-closure-remove-invalidate-notifier">g_closure_remove_invalidate_notifier</link></function>) but not for the invocation
63          process.
64          <footnote><para>
65            Closures are reference counted and notify listeners of their destruction in a two-stage
66            process: the invalidation notifiers are invoked before the finalization notifiers.
67          </para></footnote></para>
68        </listitem>
69      </itemizedlist>
70    </para>
71
72    <sect2>
73      <title>C Closures</title>
74
75      <para>
76        If you are using C or C++
77        to connect a callback to a given event, you will either use simple <type><link linkend="GCClosure">GCClosure</link></type>s
78        which have a pretty minimal API or the even simpler <function><link linkend="g-signal-connect">g_signal_connect</link></function>
79        functions (which will be presented a bit later :).
80<programlisting>
81GClosure *g_cclosure_new             (GCallback      callback_func,
82                                      gpointer       user_data,
83                                      GClosureNotify destroy_data);
84GClosure *g_cclosure_new_swap        (GCallback      callback_func,
85                                      gpointer       user_data,
86                                      GClosureNotify destroy_data);
87GClosure *g_signal_type_cclosure_new (GType          itype,
88                                      guint          struct_offset);
89</programlisting>
90      </para>
91
92      <para>
93        <function><link linkend="g-cclosure-new">g_cclosure_new</link></function> will create a new closure which can invoke the
94        user-provided callback_func with the user-provided user_data as last parameter. When the closure
95        is finalized (second stage of the destruction process), it will invoke the destroy_data function
96        if the user has supplied one.
97      </para>
98
99      <para>
100        <function><link linkend="g-cclosure-new-swap">g_cclosure_new_swap</link></function> will create a new closure which can invoke the
101        user-provided callback_func with the user-provided user_data as first parameter (instead of being the
102        last parameter as with <function><link linkend="g-cclosure-new">g_cclosure_new</link></function>). When the closure
103        is finalized (second stage of the destruction process), it will invoke the destroy_data
104        function if the user has supplied one.
105      </para>
106    </sect2>
107
108    <sect2>
109      <title>Non-C closures (for the fearless)</title>
110
111      <para>
112        As was explained above, closures hide the details of callback invocation. In C,
113        callback invocation is just like function invocation: it is a matter of creating
114        the correct stack frame for the called function and executing a <emphasis>call</emphasis>
115        assembly instruction.
116      </para>
117
118      <para>
119        C closure marshallers transform the array of GValues which represent
120        the parameters to the target function into a C-style function parameter list, invoke
121        the user-supplied C function with this new parameter list, get the return value of the
122        function, transform it into a GValue and return this GValue to the marshaller caller.
123      </para>
124
125      <para>
126        The following code implements a simple marshaller in C for a C function which takes an
127        integer as first parameter and returns void.
128<programlisting>
129g_cclosure_marshal_VOID__INT (GClosure     *closure,
130                              GValue       *return_value,
131                              guint         n_param_values,
132                              const GValue *param_values,
133                              gpointer      invocation_hint,
134                              gpointer      marshal_data)
135{
136  typedef void (*GMarshalFunc_VOID__INT) (gpointer     data1,
137                                          gint         arg_1,
138                                          gpointer     data2);
139  register GMarshalFunc_VOID__INT callback;
140  register GCClosure *cc = (GCClosure*) closure;
141  register gpointer data1, data2;
142
143  g_return_if_fail (n_param_values == 2);
144
145  data1 = g_value_peek_pointer (param_values + 0);
146  data2 = closure->data;
147
148  callback = (GMarshalFunc_VOID__INT) (marshal_data ? marshal_data : cc->callback);
149
150  callback (data1,
151            g_marshal_value_peek_int (param_values + 1),
152            data2);
153}
154</programlisting>
155      </para>
156
157      <para>
158        Of course, there exist other kinds of marshallers. For example, James Henstridge
159        wrote a generic Python marshaller which is used by all Python closures (a Python closure
160        is used to have Python-based callback be invoked by the closure invocation process).
161        This Python marshaller transforms the input GValue list representing the function
162        parameters into a Python tuple which is the equivalent structure in Python (you can
163        look in <function>pyg_closure_marshal</function> in <filename>pygtype.c</filename>
164        in the <emphasis>pygobject</emphasis> module in the GNOME Subversion server).
165      </para>
166
167    </sect2>
168  </sect1>
169
170  <sect1 id="signal">
171    <title>Signals</title>
172
173    <para>
174      GObject's signals have nothing to do with standard UNIX signals: they connect
175      arbitrary application-specific events with any number of listeners.
176      For example, in GTK+, every user event (keystroke or mouse move) is received
177      from the X server and generates a GTK+ event under the form of a signal emission
178      on a given object instance.
179    </para>
180
181    <para>
182      Each signal is registered in the type system together with the type on which
183      it can be emitted: users of the type are said to <emphasis>connect</emphasis>
184      to the signal on a given type instance when they register a closure to be
185      invoked upon the signal emission. Users can also emit the signal by themselves
186      or stop the emission of the signal from within one of the closures connected
187      to the signal.
188    </para>
189
190    <para>
191      When a signal is emitted on a given type instance, all the closures
192      connected to this signal on this type instance will be invoked. All the closures
193      connected to such a signal represent callbacks whose signature looks like:
194<programlisting>
195return_type function_callback (gpointer instance, ... , gpointer user_data);
196</programlisting>
197    </para>
198
199    <sect2 id="signal-registration">
200      <title>Signal registration</title>
201
202	  <para>
203		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>,
204		<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:
205<programlisting>
206guint g_signal_newv (const gchar        *signal_name,
207                     GType               itype,
208                     GSignalFlags        signal_flags,
209                     GClosure           *class_closure,
210                     GSignalAccumulator  accumulator,
211                     gpointer            accu_data,
212                     GSignalCMarshaller  c_marshaller,
213                     GType               return_type,
214                     guint               n_params,
215                     GType              *param_types);
216</programlisting>
217		The number of parameters to these functions is a bit intimidating but they are relatively
218		simple:
219		<itemizedlist>
220		  <listitem><para>
221			  signal_name: is a string which can be used to uniquely identify a given signal.
222			</para></listitem>
223		  <listitem><para>
224			  itype: is the instance type on which this signal can be emitted.
225			</para></listitem>
226		  <listitem><para>
227			  signal_flags: partly defines the order in which closures which were connected to the
228			  signal are invoked.
229			</para></listitem>
230		  <listitem><para>
231			  class_closure: this is the default closure for the signal: if it is not NULL upon
232			  the signal emission, it will be invoked upon this emission of the signal. The
233			  moment where this closure is invoked compared to other closures connected to that
234			  signal depends partly on the signal_flags.
235			</para></listitem>
236			<listitem><para>
237			  accumulator: this is a function pointer which is invoked after each closure
238			  has been invoked. If it returns FALSE, signal emission is stopped. If it returns
239			  TRUE, signal emission proceeds normally. It is also used to compute the return
240			  value of the signal based on the return value of all the invoked closures.
241			</para></listitem>
242		  <listitem><para>
243			  accumulator_data: this pointer will be passed down to each invocation of the
244			  accumulator during emission.
245			</para></listitem>
246		  <listitem><para>
247			  c_marshaller: this is the default C marshaller for any closure which is connected to
248			this signal.
249			</para></listitem>
250		  <listitem><para>
251			  return_type: this is the type of the return value of the signal.
252			</para></listitem>
253		  <listitem><para>
254			  n_params: this is the number of parameters this signal takes.
255			</para></listitem>
256		  <listitem><para>
257			  param_types: this is an array of GTypes which indicate the type of each parameter
258			  of the signal. The length of this array is indicated by n_params.
259			</para></listitem>
260		</itemizedlist>
261      </para>
262
263	  <para>
264		As you can see from the above definition, a signal is basically a description
265		of the closures which can be connected to this signal and a description of the
266		order in which the closures connected to this signal will be invoked.
267	  </para>
268
269	</sect2>
270
271	<sect2 id="signal-connection">
272	  <title>Signal connection</title>
273
274	  <para>
275		If you want to connect to a signal with a closure, you have three possibilities:
276		<itemizedlist>
277		  <listitem><para>
278		  You can register a class closure at signal registration: this is a
279		  system-wide operation. i.e.: the class_closure will be invoked during each emission
280		  of a given signal on all the instances of the type which supports that signal.
281			</para></listitem>
282		  <listitem><para>
283		  You can use <function><link linkend="g-signal-override-class-closure">g_signal_override_class_closure</link></function> which
284		  overrides the class_closure of a given type. It is possible to call this function
285		  only on a derived type of the type on which the signal was registered.
286		  This function is of use only to language bindings.
287			</para></listitem>
288		  <listitem><para>
289		  You can register a closure with the <function><link linkend="g-signal-connect">g_signal_connect</link></function>
290		  family of functions. This is an instance-specific operation: the closure
291		  will be invoked only during emission of a given signal on a given instance.
292			</para></listitem>
293		</itemizedlist>
294		It is also possible to connect a different kind of callback on a given signal:
295		emission hooks are invoked whenever a given signal is emitted whatever the instance on
296		which it is emitted. Emission hooks are used for example to get all mouse_clicked
297		emissions in an application to be able to emit the small mouse click sound.
298		Emission hooks are connected with <function><link linkend="g-signal-add-emission-hook">g_signal_add_emission_hook</link></function>
299		and removed with <function><link linkend="g-signal-remove-emission-hook">g_signal_remove_emission_hook</link></function>.
300	  </para>
301
302	</sect2>
303
304	<sect2 id="signal-emission">
305	  <title>Signal emission</title>
306
307	  <para>
308		Signal emission is done through the use of the <function><link linkend="g-signal-emit">g_signal_emit</link></function> family
309		of functions.
310<programlisting>
311void g_signal_emitv (const GValue *instance_and_params,
312                     guint         signal_id,
313                     GQuark        detail,
314                     GValue       *return_value);
315</programlisting>
316		<itemizedlist>
317		  <listitem><para>
318			The instance_and_params array of GValues contains the list of input
319			parameters to the signal. The first element of the array is the
320			instance pointer on which to invoke the signal. The following elements of
321			the array contain the list of parameters to the signal.
322			</para></listitem>
323		  <listitem><para>
324			signal_id identifies the signal to invoke.
325			</para></listitem>
326		  <listitem><para>
327			detail identifies the specific detail of the signal to invoke. A detail is a kind of
328			magic token/argument which is passed around during signal emission and which is used
329			by closures connected to the signal to filter out unwanted signal emissions. In most
330			cases, you can safely set this value to zero. See <xref linkend="signal-detail"/> for
331			more details about this parameter.
332			</para></listitem>
333		  <listitem><para>
334			return_value holds the return value of the last closure invoked during emission if
335			no accumulator was specified. If an accumulator was specified during signal creation,
336			this accumulator is used to calculate the return_value as a function of the return
337			values of all the closures invoked during emission.
338			<footnote><para>
339			  James (again!!) gives a few non-trivial examples of accumulators:
340			  <quote>
341				For instance, you may have an accumulator that ignores NULL returns from
342				closures, and only accumulates the non-NULL ones. Another accumulator may try
343				to return the list of values returned by the closures.
344			  </quote>
345			</para></footnote>
346			If no closure is invoked during
347			emission, the return_value is nonetheless initialized to zero/null.
348			</para></listitem>
349		  </itemizedlist>
350		</para>
351
352	  <para>
353		Internally, the GValue array is passed to the emission function proper,
354		<function>signal_emit_unlocked_R</function> (implemented in <filename>gsignal.c</filename>).
355		Signal emission can be decomposed in 5 steps:
356		<itemizedlist>
357		  <listitem><para>
358			<emphasis>RUN_FIRST</emphasis>: if the G_SIGNAL_RUN_FIRST flag was used
359			during signal registration and if there exist a class_closure for this signal,
360			the class_closure is invoked. Jump to <emphasis>EMISSION_HOOK</emphasis> state.
361			</para></listitem>
362		  <listitem><para>
363			<emphasis>EMISSION_HOOK</emphasis>: if any emission hook was added to
364			the signal, they are invoked from first to last added. Accumulate return values
365			and jump to <emphasis>HANDLER_RUN_FIRST</emphasis> state.
366			</para></listitem>
367		  <listitem><para>
368			<emphasis>HANDLER_RUN_FIRST</emphasis>: if any closure were connected
369			with the <function><link linkend="g-signal-connect">g_signal_connect</link></function> family of
370			functions, and if they are not blocked (with the <function><link linkend="g-signal-handler-block">g_signal_handler_block</link></function>
371			family of functions) they are run here, from first to last connected.
372			Jump to <emphasis>RUN_LAST</emphasis> state.
373			</para></listitem>
374		  <listitem><para>
375			<emphasis>RUN_LAST</emphasis>: if the G_SIGNAL_RUN_LAST
376			flag was set during registration and if a class_closure
377			was set, it is invoked here. Jump to
378			<emphasis>HANDLER_RUN_LAST</emphasis> state.
379			</para></listitem>
380		  <listitem><para>
381			<emphasis>HANDLER_RUN_LAST</emphasis>: if any closure were connected
382			with the <function>g_signal_connect_after</function> family of
383			functions, if they were not invoked during HANDLER_RUN_FIRST and if they
384			are not blocked, they are run here, from first to last connected.
385			Jump to  <emphasis>RUN_CLEANUP</emphasis> state.
386			</para></listitem>
387		  <listitem><para>
388			<emphasis>RUN_CLEANUP</emphasis>: if the G_SIGNAL_RUN_CLEANUP flag
389			was set during registration and if a class_closure was set,
390			it is invoked here. Signal emission is completed here.
391			</para></listitem>
392		</itemizedlist>
393	  </para>
394
395	  <para>
396		If, at any point during emission (except in RUN_CLEANUP state), one of the
397		closures or emission hook stops the signal emission with
398		<function><link linkend="g-signal-stop">g_signal_stop</link></function>, emission jumps to CLEANUP state.
399	  </para>
400
401	  <para>
402		If, at any point during emission, one of the closures or emission hook
403		emits the same signal on the same instance, emission is restarted from
404		the RUN_FIRST state.
405	  </para>
406
407	  <para>
408		The accumulator function is invoked in all states, after invocation
409		of each closure (except in EMISSION_HOOK and CLEANUP). It accumulates
410		the closure return value into the signal return value and returns TRUE or
411		FALSE. If, at any point, it does not return TRUE, emission jumps to CLEANUP state.
412	  </para>
413
414	  <para>
415		If no accumulator function was provided, the value returned by the last handler
416		run will be returned by <function><link linkend="g-signal-emit">g_signal_emit</link></function>.
417	  </para>
418
419	</sect2>
420
421
422	<sect2 id="signal-detail">
423	  <title>The <emphasis>detail</emphasis> argument</title>
424
425	  <para>All the functions related to signal emission or signal connection have a parameter
426		named the <emphasis>detail</emphasis>. Sometimes, this parameter is hidden by the API
427		but it is always there, under one form or another.
428	  </para>
429
430	  <para>
431	    Of the three main connection functions,
432		only one has an explicit detail parameter as a <type><link linkend="GQuark">GQuark</link></type>
433		<footnote>
434		  <para>A GQuark is an integer which uniquely represents a string. It is possible to transform
435		   back and forth between the integer and string representations with the functions
436		   <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>.
437		  </para>
438		</footnote>:
439<programlisting>
440gulong     g_signal_connect_closure_by_id          (gpointer          instance,
441                           guint          signal_id,
442                           GQuark          detail,
443                           GClosure         *closure,
444                           gboolean          after);
445</programlisting>
446        The two other functions hide the detail parameter in the signal name identification:
447<programlisting>
448gulong     g_signal_connect_closure          (gpointer          instance,
449                           const gchar       *detailed_signal,
450                           GClosure         *closure,
451                           gboolean          after);
452gulong     g_signal_connect_data              (gpointer          instance,
453                           const gchar     *detailed_signal,
454                           GCallback      c_handler,
455                           gpointer          data,
456                           GClosureNotify      destroy_data,
457                           GConnectFlags      connect_flags);
458</programlisting>
459		Their detailed_signal parameter is a string which identifies the name of the signal
460		to connect to. However, the format of this string is structured to look like
461		<emphasis>signal_name::detail_name</emphasis>. Connecting to the signal
462		named <emphasis>notify::cursor_position</emphasis> will actually connect to the signal
463		named <emphasis>notify</emphasis> with the <emphasis>cursor_position</emphasis> name.
464		Internally, the detail string is transformed to a GQuark if it is present.
465	  </para>
466
467	  <para>
468		Of the four main signal emission functions, three have an explicit detail parameter as a
469		<type><link linkend="GQuark">GQuark</link></type> again:
470<programlisting>
471void                  g_signal_emitv        (const GValue       *instance_and_params,
472                         guint               signal_id,
473                         GQuark              detail,
474                         GValue             *return_value);
475void                  g_signal_emit_valist  (gpointer            instance,
476                         guint               signal_id,
477                         GQuark              detail,
478                         va_list             var_args);
479void                  g_signal_emit         (gpointer            instance,
480                         guint               signal_id,
481                         GQuark              detail,
482                         ...);
483</programlisting>
484        The fourth function hides it in its signal name parameter:
485<programlisting>
486void                  g_signal_emit_by_name (gpointer            instance,
487                         const gchar        *detailed_signal,
488                         ...);
489</programlisting>
490        The format of the detailed_signal parameter is exactly the same as the format used by
491        the <function><link linkend="g-signal-connect">g_signal_connect</link></function> functions: <emphasis>signal_name::detail_name</emphasis>.
492	  </para>
493
494	  <para>
495        If a detail is provided by the user to the emission function, it is used during emission to match
496        against the closures which also provide a detail.
497        If the closures' detail does not match the detail provided by the user, they will not be invoked
498        (even though they are connected to a signal which is being emitted).
499	  </para>
500
501	  <para>
502		This completely optional filtering mechanism is mainly used as an optimization for signals
503		which are often emitted for many different reasons: the clients can filter out which events they are
504		interested in before the closure's marshalling code runs. For example, this is used extensively
505		by the <emphasis>notify</emphasis> signal of GObject: whenever a property is modified on a GObject,
506		instead of just emitting the <emphasis>notify</emphasis> signal, GObject associates as a detail to this
507		signal emission the name of the property modified. This allows clients who wish to be notified of changes
508		to only one property to filter most events before receiving them.
509	  </para>
510
511	  <para>
512		As a simple rule, users can and should set the detail parameter to zero: this will disable completely
513        this optional filtering.
514	  </para>
515
516	</sect2>
517
518  </sect1>
519</chapter>
520
521