Mercurial > pidgin.yaz
comparison doc/SIGNAL-HOWTO.dox @ 19040:4167e2d7ebef
propagate from branch 'im.pidgin.pidgin' (head 3c06e81a006adebe420915ad7301ad1e6e82cab8)
to branch 'im.pidgin.soc.2007.certmgr' (head 5fbb842e1f275573ae8335395c1c01c231418663)
author | William Ehlhardt <williamehlhardt@gmail.com> |
---|---|
date | Tue, 24 Jul 2007 04:32:04 +0000 (2007-07-24) |
parents | c3e80350c270 |
children | f3e0b1221765 |
comparison
equal
deleted
inserted
replaced
18626:f05360b5470d | 19040:4167e2d7ebef |
---|---|
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 NULL, /* Callback return value type */ | |
29 1, /* Number of callback arguments (not including void *data) */ | |
30 purple_value_new(PURPLE_TYPE_SUBTYPE,PURPLE_SUBTYPE_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 value type | |
66 In our case, this is NULL, 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_value_new(PURPLE_TYPE_SUBTYPE,PURPLE_SUBTYPE_PLUGIN) specifies that | |
75 the first argument given to the callback will be a @c PurplePlugin* . You | |
76 will need as many "type of argument" arguments to purple_signal_register() as | |
77 you specified in "Number of arguments" above. | |
78 | |
79 @todo Describe this more. | |
80 | |
81 @See value.h | |
82 | |
83 @section connect Connecting to the signal | |
84 Once the signal is registered, you can connect callbacks to it. First, you | |
85 must define a callback function, such as this one from gtkplugin.c : | |
86 @code | |
87 static void plugin_load_cb(PurplePlugin *plugin, gpointer data) | |
88 { | |
89 GtkTreeView *view = (GtkTreeView *)data; | |
90 plugin_loading_common(plugin, view, TRUE); | |
91 } | |
92 @endcode | |
93 Note that the callback function prototype matches that specified in the call | |
94 to purple_signal_register() above. | |
95 | |
96 Once the callback function is defined, you can connect it to the signal. | |
97 Again from gtkplugin.c , in @c pidgin_plugin_dialog_show() : | |
98 @code | |
99 purple_signal_connect(purple_plugins_get_handle(), "plugin-load", /* What to connect to */ | |
100 plugin_dialog, /* Object receiving the signal */ | |
101 PURPLE_CALLBACK(plugin_load_cb), /* Callback function */ | |
102 event_view, /* Data to pass to the callback function | |
103 ); | |
104 @endcode | |
105 | |
106 The first two arguments ("What to connect to") specify the object emitting | |
107 the signal (the plugin module) and what signal to listen for ("plugin-load"). | |
108 | |
109 The object receiving the signal is @c plugin_dialog , the Pidgin plugins | |
110 dialog. When @c plugin_dialog is deleted, then | |
111 @c purple_signals_disconnect_by_handle(plugin_dialog) should be called to | |
112 remove all signal connections it is associated with. | |
113 | |
114 The callback function is given using a helper macro, and finally the | |
115 @c data argument to be passed to @c plugin_load_cb is given as @c event_view, | |
116 a pointer to the GTK widget that @c plugin_load_cb needs to update. | |
117 | |
118 @section emit-signal Emitting a signal | |
119 Connecting callbacks to signals is all well and good, but how do you "fire" | |
120 the signal and trigger the callback? At some point, you must "emit" the | |
121 signal, which immediately calls all connected callbacks. | |
122 | |
123 As seen in @c purple_plugin_load() in plugin.c : | |
124 @code | |
125 purple_signal_emit(purple_plugins_get_handle(), "plugin-load", plugin); | |
126 @endcode | |
127 This causes the signal "plugin-load" to be emitted from the plugin module | |
128 (given by @c purple_plugins_get_handle() ), with the newly loaded plugin as | |
129 the argument to pass to any registered callback functions. | |
130 | |
131 In our example, @c plugin_load_cb is called immediately as | |
132 @code | |
133 plugin_load_cb(plugin, event_view); | |
134 @endcode | |
135 and does whatever it does. | |
136 | |
137 */ |