doc/reference/libpurple/SIGNAL-HOWTO.dox

branch
soc.2013.gobjectification.plugins
changeset 36900
423fbe5e5289
parent 34960
c28b627a2900
equal deleted inserted replaced
36899:b2591070c07b 36900:423fbe5e5289
1 /** @page signal-howto Signals HOWTO
2
3 @section Introduction
4 The libpurple signals interface is used for general event notification, such
5 as plugins being loaded or unloaded, allowing the GUI frontend to respond
6 appropriately to changing internal data. Unfortunately, its use is not at all
7 obvious from the information in the header files. This document uses code
8 snippets from the Pidgin/libpurple plugin systems to illustrate the proper
9 use of signals.
10
11 @section overview Overview of Signals
12 Signals in libpurple are very similar to those in GTK+. When certain events
13 happen, a named signal is "emitted" from a certain object. Emitting the
14 signal triggers a series of callbacks that have been "connected" to that
15 signal for that object. These callbacks take appropriate action in response
16 to the signal.
17
18 @section registering_signal Registering a Signal
19 The first step of using a signal is registering it with libpurple so that
20 callbacks may be connected to it. This is done using purple_signal_register()
21 Here is a slightly modified example from @c purple_plugins_init in
22 @c libpurple/plugin.c :
23
24 @code
25 purple_signal_register( purple_plugins_get_handle(), /* Instance */
26 "plugin-load", /* Signal name */
27 purple_marshal_VOID__POINTER,/* Marshal function */
28 G_TYPE_NONE, /* Callback return type */
29 1, /* Number of callback arguments (not including void *data) */
30 PURPLE_TYPE_PLUGIN /* Type of first callback argument */
31 );
32 @endcode
33
34 @subsection Instance
35 A reference to the object from which this signal is emitted, and to which
36 potential callbacks should be connected. In this case, it will be the entire
37 plugin module emitting the signal.
38
39 @subsection signalname Signal Name
40 Unique identifier for the signal itself.
41
42 @subsection therest Callback function definition
43 The rest of the arguments specify the form of the callback function.
44
45 @subsubsection marshalfunc Marshal Function
46 @c purple_marshal_VOID__POINTER represents the callback function prototype,
47 not including a "data" argument, explained later. The form is
48 @c purple_marshal_RETURNVALUETYPE__ARG1TYPE_ARG2TYPE_ETC. See signals.h for
49 more possible types.
50
51 In this case, the callback will have the form
52 @code
53 void cb(void *arg1, void *data)
54 @endcode
55
56 If @c purple_marshal_BOOLEAN__POINTER_POINTER_POINTER were specified, it
57 would be:
58 @code
59 gboolean cb(void *arg1, void *arg2, void *arg3, void *data)
60 @endcode
61
62 The @c void @c *data argument at the end of each callback function
63 provides the data argument given to purple_signal_connect() .
64
65 @subsubsection cb_ret_type Callback return type
66 In our case, this is G_TYPE_NONE, meaning "returns void".
67 @todo This could be described better.
68
69 @subsubsection num_args Number of arguments
70 The number of arguments (not including @c data ) that the callback function
71 will take.
72
73 @subsubsection type_arg Type of argument
74 @c PURPLE_TYPE_PLUGIN specifies that the first argument given to the callback
75 will be a @c PurplePlugin* . You will need as many "type of argument"
76 arguments to purple_signal_register() as you specified in
77 "Number of arguments" above.
78
79 @todo Describe this more.
80
81 @section connect Connecting to the signal
82 Once the signal is registered, you can connect callbacks to it. First, you
83 must define a callback function, such as this one from gtkplugin.c :
84 @code
85 static void plugin_load_cb(PurplePlugin *plugin, gpointer data)
86 {
87 GtkTreeView *view = (GtkTreeView *)data;
88 plugin_loading_common(plugin, view, TRUE);
89 }
90 @endcode
91 Note that the callback function prototype matches that specified in the call
92 to purple_signal_register() above.
93
94 Once the callback function is defined, you can connect it to the signal.
95 Again from gtkplugin.c , in @c pidgin_plugin_dialog_show() :
96 @code
97 purple_signal_connect(purple_plugins_get_handle(), "plugin-load", /* What to connect to */
98 plugin_dialog, /* Object receiving the signal */
99 PURPLE_CALLBACK(plugin_load_cb), /* Callback function */
100 event_view, /* Data to pass to the callback function
101 );
102 @endcode
103
104 The first two arguments ("What to connect to") specify the object emitting
105 the signal (the plugin module) and what signal to listen for ("plugin-load").
106
107 The object receiving the signal is @c plugin_dialog , the Pidgin plugins
108 dialog. When @c plugin_dialog is deleted, then
109 @c purple_signals_disconnect_by_handle(plugin_dialog) should be called to
110 remove all signal connections it is associated with.
111
112 The callback function is given using a helper macro, and finally the
113 @c data argument to be passed to @c plugin_load_cb is given as @c event_view,
114 a pointer to the GTK widget that @c plugin_load_cb needs to update.
115
116 @section emit-signal Emitting a signal
117 Connecting callbacks to signals is all well and good, but how do you "fire"
118 the signal and trigger the callback? At some point, you must "emit" the
119 signal, which immediately calls all connected callbacks.
120
121 As seen in @c purple_plugin_load() in plugin.c :
122 @code
123 purple_signal_emit(purple_plugins_get_handle(), "plugin-load", plugin);
124 @endcode
125 This causes the signal "plugin-load" to be emitted from the plugin module
126 (given by @c purple_plugins_get_handle() ), with the newly loaded plugin as
127 the argument to pass to any registered callback functions.
128
129 In our example, @c plugin_load_cb is called immediately as
130 @code
131 plugin_load_cb(plugin, event_view);
132 @endcode
133 and does whatever it does.
134
135 */

mercurial