Mercurial > pidgin
annotate src/signals.c @ 6629:bdc448cf4cb6
[gaim-migrate @ 7153]
Tim Ringenbach (marv_sf) writes:
" This patch makes sending colors in yahoo work. It also
makes a few changing to receiving them, and addresses
most of the problems with that patch (which I think
were all related to the fact it didn't do outgoing colors).
It now handles bold, italic, underline, font face, font
size, and font color in both directions. It disables
the background color button if the prpl is yahoo (in a
generic way), and farthermore strips out any <body>
tags that the user might try to type anyway (the yahoo
server purposely mangles them).
It also adds a line to g_strescape some debug messages
because I got tired them of changing the color of my
terminal.
I think I got all the bugs out. If you run with -d or
open the debug window, it will show you what both
conversion function returned, which should help track
down any problems."
committer: Tailor Script <tailor@pidgin.im>
author | Luke Schierer <lschiere@pidgin.im> |
---|---|
date | Tue, 26 Aug 2003 01:34:51 +0000 |
parents | 800ef4a51096 |
children | 7dba3e17cb21 |
rev | line source |
---|---|
6485 | 1 /** |
6488
e5e8d21bd4d8
[gaim-migrate @ 7002]
Christian Hammond <chipx86@chipx86.com>
parents:
6485
diff
changeset
|
2 * @file signals.c Signal API |
6485 | 3 * @ingroup core |
4 * | |
5 * gaim | |
6 * | |
7 * Copyright (C) 2003 Christian Hammond <chipx86@gnupdate.org> | |
8 * | |
9 * This program is free software; you can redistribute it and/or modify | |
10 * it under the terms of the GNU General Public License as published by | |
11 * the Free Software Foundation; either version 2 of the License, or | |
12 * (at your option) any later version. | |
13 * | |
14 * This program is distributed in the hope that it will be useful, | |
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
17 * GNU General Public License for more details. | |
18 * | |
19 * You should have received a copy of the GNU General Public License | |
20 * along with this program; if not, write to the Free Software | |
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
22 */ | |
23 #include "internal.h" | |
24 | |
25 #include "debug.h" | |
26 #include "signals.h" | |
6564
800ef4a51096
[gaim-migrate @ 7086]
Christian Hammond <chipx86@chipx86.com>
parents:
6553
diff
changeset
|
27 #include "value.h" |
6485 | 28 |
29 typedef struct | |
30 { | |
31 void *instance; | |
32 | |
33 GHashTable *signals; | |
34 size_t signal_count; | |
35 | |
36 gulong next_signal_id; | |
37 | |
38 } GaimInstanceData; | |
39 | |
40 typedef struct | |
41 { | |
42 gulong id; | |
43 | |
44 GaimSignalMarshalFunc marshal; | |
45 | |
6564
800ef4a51096
[gaim-migrate @ 7086]
Christian Hammond <chipx86@chipx86.com>
parents:
6553
diff
changeset
|
46 int num_values; |
800ef4a51096
[gaim-migrate @ 7086]
Christian Hammond <chipx86@chipx86.com>
parents:
6553
diff
changeset
|
47 GaimValue **values; |
800ef4a51096
[gaim-migrate @ 7086]
Christian Hammond <chipx86@chipx86.com>
parents:
6553
diff
changeset
|
48 GaimValue *ret_value; |
800ef4a51096
[gaim-migrate @ 7086]
Christian Hammond <chipx86@chipx86.com>
parents:
6553
diff
changeset
|
49 |
6485 | 50 GList *handlers; |
51 size_t handler_count; | |
52 | |
53 gulong next_handler_id; | |
54 | |
55 } GaimSignalData; | |
56 | |
57 typedef struct | |
58 { | |
59 gulong id; | |
60 GaimCallback cb; | |
61 void *handle; | |
62 void *data; | |
6547
adf168f002ad
[gaim-migrate @ 7069]
Christian Hammond <chipx86@chipx86.com>
parents:
6509
diff
changeset
|
63 gboolean use_vargs; |
6485 | 64 |
65 } GaimSignalHandlerData; | |
66 | |
67 static GHashTable *instance_table = NULL; | |
68 | |
69 static void | |
70 destroy_instance_data(GaimInstanceData *instance_data) | |
71 { | |
72 g_hash_table_destroy(instance_data->signals); | |
73 | |
74 g_free(instance_data); | |
75 } | |
76 | |
77 static void | |
78 destroy_signal_data(GaimSignalData *signal_data) | |
79 { | |
80 GaimSignalHandlerData *handler_data; | |
81 GList *l; | |
82 | |
83 for (l = signal_data->handlers; l != NULL; l = l->next) | |
84 { | |
85 handler_data = (GaimSignalHandlerData *)l->data; | |
86 | |
87 g_free(l->data); | |
88 } | |
89 | |
90 g_list_free(signal_data->handlers); | |
91 | |
6564
800ef4a51096
[gaim-migrate @ 7086]
Christian Hammond <chipx86@chipx86.com>
parents:
6553
diff
changeset
|
92 if (signal_data->values != NULL) |
800ef4a51096
[gaim-migrate @ 7086]
Christian Hammond <chipx86@chipx86.com>
parents:
6553
diff
changeset
|
93 { |
800ef4a51096
[gaim-migrate @ 7086]
Christian Hammond <chipx86@chipx86.com>
parents:
6553
diff
changeset
|
94 int i; |
800ef4a51096
[gaim-migrate @ 7086]
Christian Hammond <chipx86@chipx86.com>
parents:
6553
diff
changeset
|
95 |
800ef4a51096
[gaim-migrate @ 7086]
Christian Hammond <chipx86@chipx86.com>
parents:
6553
diff
changeset
|
96 for (i = 0; i < signal_data->num_values; i++) |
800ef4a51096
[gaim-migrate @ 7086]
Christian Hammond <chipx86@chipx86.com>
parents:
6553
diff
changeset
|
97 gaim_value_destroy((GaimValue *)signal_data->values[i]); |
800ef4a51096
[gaim-migrate @ 7086]
Christian Hammond <chipx86@chipx86.com>
parents:
6553
diff
changeset
|
98 |
800ef4a51096
[gaim-migrate @ 7086]
Christian Hammond <chipx86@chipx86.com>
parents:
6553
diff
changeset
|
99 g_free(signal_data->values); |
800ef4a51096
[gaim-migrate @ 7086]
Christian Hammond <chipx86@chipx86.com>
parents:
6553
diff
changeset
|
100 } |
800ef4a51096
[gaim-migrate @ 7086]
Christian Hammond <chipx86@chipx86.com>
parents:
6553
diff
changeset
|
101 |
6485 | 102 g_free(signal_data); |
103 } | |
104 | |
105 gulong | |
106 gaim_signal_register(void *instance, const char *signal, | |
6564
800ef4a51096
[gaim-migrate @ 7086]
Christian Hammond <chipx86@chipx86.com>
parents:
6553
diff
changeset
|
107 GaimSignalMarshalFunc marshal, |
800ef4a51096
[gaim-migrate @ 7086]
Christian Hammond <chipx86@chipx86.com>
parents:
6553
diff
changeset
|
108 GaimValue *ret_value, int num_values, ...) |
6485 | 109 { |
110 GaimInstanceData *instance_data; | |
111 GaimSignalData *signal_data; | |
6564
800ef4a51096
[gaim-migrate @ 7086]
Christian Hammond <chipx86@chipx86.com>
parents:
6553
diff
changeset
|
112 va_list args; |
6485 | 113 |
114 g_return_val_if_fail(instance != NULL, 0); | |
115 g_return_val_if_fail(signal != NULL, 0); | |
116 g_return_val_if_fail(marshal != NULL, 0); | |
117 | |
118 instance_data = | |
119 (GaimInstanceData *)g_hash_table_lookup(instance_table, instance); | |
120 | |
121 if (instance_data == NULL) | |
122 { | |
123 instance_data = g_new0(GaimInstanceData, 1); | |
124 | |
125 instance_data->instance = instance; | |
126 instance_data->next_signal_id = 1; | |
127 | |
128 instance_data->signals = | |
129 g_hash_table_new_full(g_str_hash, g_str_equal, g_free, | |
130 (GDestroyNotify)destroy_signal_data); | |
131 | |
132 g_hash_table_insert(instance_table, instance, instance_data); | |
133 } | |
134 | |
135 signal_data = g_new0(GaimSignalData, 1); | |
136 signal_data->id = instance_data->next_signal_id; | |
137 signal_data->marshal = marshal; | |
138 signal_data->next_handler_id = 1; | |
6564
800ef4a51096
[gaim-migrate @ 7086]
Christian Hammond <chipx86@chipx86.com>
parents:
6553
diff
changeset
|
139 signal_data->ret_value = ret_value; |
800ef4a51096
[gaim-migrate @ 7086]
Christian Hammond <chipx86@chipx86.com>
parents:
6553
diff
changeset
|
140 signal_data->num_values = num_values; |
800ef4a51096
[gaim-migrate @ 7086]
Christian Hammond <chipx86@chipx86.com>
parents:
6553
diff
changeset
|
141 |
800ef4a51096
[gaim-migrate @ 7086]
Christian Hammond <chipx86@chipx86.com>
parents:
6553
diff
changeset
|
142 if (num_values > 0) |
800ef4a51096
[gaim-migrate @ 7086]
Christian Hammond <chipx86@chipx86.com>
parents:
6553
diff
changeset
|
143 { |
800ef4a51096
[gaim-migrate @ 7086]
Christian Hammond <chipx86@chipx86.com>
parents:
6553
diff
changeset
|
144 int i; |
800ef4a51096
[gaim-migrate @ 7086]
Christian Hammond <chipx86@chipx86.com>
parents:
6553
diff
changeset
|
145 |
800ef4a51096
[gaim-migrate @ 7086]
Christian Hammond <chipx86@chipx86.com>
parents:
6553
diff
changeset
|
146 signal_data->values = g_new0(GaimValue *, num_values); |
800ef4a51096
[gaim-migrate @ 7086]
Christian Hammond <chipx86@chipx86.com>
parents:
6553
diff
changeset
|
147 |
800ef4a51096
[gaim-migrate @ 7086]
Christian Hammond <chipx86@chipx86.com>
parents:
6553
diff
changeset
|
148 va_start(args, num_values); |
800ef4a51096
[gaim-migrate @ 7086]
Christian Hammond <chipx86@chipx86.com>
parents:
6553
diff
changeset
|
149 |
800ef4a51096
[gaim-migrate @ 7086]
Christian Hammond <chipx86@chipx86.com>
parents:
6553
diff
changeset
|
150 for (i = 0; i < num_values; i++) |
800ef4a51096
[gaim-migrate @ 7086]
Christian Hammond <chipx86@chipx86.com>
parents:
6553
diff
changeset
|
151 signal_data->values[i] = va_arg(args, GaimValue *); |
800ef4a51096
[gaim-migrate @ 7086]
Christian Hammond <chipx86@chipx86.com>
parents:
6553
diff
changeset
|
152 |
800ef4a51096
[gaim-migrate @ 7086]
Christian Hammond <chipx86@chipx86.com>
parents:
6553
diff
changeset
|
153 va_end(args); |
800ef4a51096
[gaim-migrate @ 7086]
Christian Hammond <chipx86@chipx86.com>
parents:
6553
diff
changeset
|
154 } |
6485 | 155 |
156 g_hash_table_insert(instance_data->signals, | |
157 g_strdup(signal), signal_data); | |
158 | |
159 instance_data->next_signal_id++; | |
160 instance_data->signal_count++; | |
161 | |
162 return signal_data->id; | |
163 } | |
164 | |
165 void | |
166 gaim_signal_unregister(void *instance, const char *signal) | |
167 { | |
168 GaimInstanceData *instance_data; | |
169 | |
170 g_return_if_fail(instance != NULL); | |
171 g_return_if_fail(signal != NULL); | |
172 | |
173 instance_data = | |
174 (GaimInstanceData *)g_hash_table_lookup(instance_table, instance); | |
175 | |
176 g_return_if_fail(instance_data != NULL); | |
177 | |
178 g_hash_table_remove(instance_data->signals, signal); | |
179 | |
180 instance_data->signal_count--; | |
181 | |
182 if (instance_data->signal_count == 0) | |
183 { | |
184 /* Unregister the instance. */ | |
185 g_hash_table_remove(instance_table, instance); | |
186 } | |
187 } | |
188 | |
189 void | |
190 gaim_signals_unregister_by_instance(void *instance) | |
191 { | |
192 gboolean found; | |
193 | |
194 g_return_if_fail(instance != NULL); | |
195 | |
196 found = g_hash_table_remove(instance_table, instance); | |
197 | |
198 /* | |
199 * Makes things easier (more annoying?) for developers who don't have | |
200 * things registering and unregistering in the right order :) | |
201 */ | |
202 g_return_if_fail(found); | |
203 } | |
204 | |
6564
800ef4a51096
[gaim-migrate @ 7086]
Christian Hammond <chipx86@chipx86.com>
parents:
6553
diff
changeset
|
205 void |
800ef4a51096
[gaim-migrate @ 7086]
Christian Hammond <chipx86@chipx86.com>
parents:
6553
diff
changeset
|
206 gaim_signal_get_values(void *instance, const char *signal, |
800ef4a51096
[gaim-migrate @ 7086]
Christian Hammond <chipx86@chipx86.com>
parents:
6553
diff
changeset
|
207 GaimValue **ret_value, |
800ef4a51096
[gaim-migrate @ 7086]
Christian Hammond <chipx86@chipx86.com>
parents:
6553
diff
changeset
|
208 int *num_values, GaimValue ***values) |
800ef4a51096
[gaim-migrate @ 7086]
Christian Hammond <chipx86@chipx86.com>
parents:
6553
diff
changeset
|
209 { |
800ef4a51096
[gaim-migrate @ 7086]
Christian Hammond <chipx86@chipx86.com>
parents:
6553
diff
changeset
|
210 GaimInstanceData *instance_data; |
800ef4a51096
[gaim-migrate @ 7086]
Christian Hammond <chipx86@chipx86.com>
parents:
6553
diff
changeset
|
211 GaimSignalData *signal_data; |
800ef4a51096
[gaim-migrate @ 7086]
Christian Hammond <chipx86@chipx86.com>
parents:
6553
diff
changeset
|
212 |
800ef4a51096
[gaim-migrate @ 7086]
Christian Hammond <chipx86@chipx86.com>
parents:
6553
diff
changeset
|
213 g_return_if_fail(instance != NULL); |
800ef4a51096
[gaim-migrate @ 7086]
Christian Hammond <chipx86@chipx86.com>
parents:
6553
diff
changeset
|
214 g_return_if_fail(signal != NULL); |
800ef4a51096
[gaim-migrate @ 7086]
Christian Hammond <chipx86@chipx86.com>
parents:
6553
diff
changeset
|
215 g_return_if_fail(num_values != NULL); |
800ef4a51096
[gaim-migrate @ 7086]
Christian Hammond <chipx86@chipx86.com>
parents:
6553
diff
changeset
|
216 g_return_if_fail(values != NULL); |
800ef4a51096
[gaim-migrate @ 7086]
Christian Hammond <chipx86@chipx86.com>
parents:
6553
diff
changeset
|
217 |
800ef4a51096
[gaim-migrate @ 7086]
Christian Hammond <chipx86@chipx86.com>
parents:
6553
diff
changeset
|
218 /* Get the instance data */ |
800ef4a51096
[gaim-migrate @ 7086]
Christian Hammond <chipx86@chipx86.com>
parents:
6553
diff
changeset
|
219 instance_data = |
800ef4a51096
[gaim-migrate @ 7086]
Christian Hammond <chipx86@chipx86.com>
parents:
6553
diff
changeset
|
220 (GaimInstanceData *)g_hash_table_lookup(instance_table, instance); |
800ef4a51096
[gaim-migrate @ 7086]
Christian Hammond <chipx86@chipx86.com>
parents:
6553
diff
changeset
|
221 |
800ef4a51096
[gaim-migrate @ 7086]
Christian Hammond <chipx86@chipx86.com>
parents:
6553
diff
changeset
|
222 g_return_if_fail(instance_data != NULL); |
800ef4a51096
[gaim-migrate @ 7086]
Christian Hammond <chipx86@chipx86.com>
parents:
6553
diff
changeset
|
223 |
800ef4a51096
[gaim-migrate @ 7086]
Christian Hammond <chipx86@chipx86.com>
parents:
6553
diff
changeset
|
224 /* Get the signal data */ |
800ef4a51096
[gaim-migrate @ 7086]
Christian Hammond <chipx86@chipx86.com>
parents:
6553
diff
changeset
|
225 signal_data = |
800ef4a51096
[gaim-migrate @ 7086]
Christian Hammond <chipx86@chipx86.com>
parents:
6553
diff
changeset
|
226 (GaimSignalData *)g_hash_table_lookup(instance_data->signals, signal); |
800ef4a51096
[gaim-migrate @ 7086]
Christian Hammond <chipx86@chipx86.com>
parents:
6553
diff
changeset
|
227 |
800ef4a51096
[gaim-migrate @ 7086]
Christian Hammond <chipx86@chipx86.com>
parents:
6553
diff
changeset
|
228 g_return_if_fail(signal_data != NULL); |
800ef4a51096
[gaim-migrate @ 7086]
Christian Hammond <chipx86@chipx86.com>
parents:
6553
diff
changeset
|
229 |
800ef4a51096
[gaim-migrate @ 7086]
Christian Hammond <chipx86@chipx86.com>
parents:
6553
diff
changeset
|
230 *num_values = signal_data->num_values; |
800ef4a51096
[gaim-migrate @ 7086]
Christian Hammond <chipx86@chipx86.com>
parents:
6553
diff
changeset
|
231 *values = signal_data->values; |
800ef4a51096
[gaim-migrate @ 7086]
Christian Hammond <chipx86@chipx86.com>
parents:
6553
diff
changeset
|
232 |
800ef4a51096
[gaim-migrate @ 7086]
Christian Hammond <chipx86@chipx86.com>
parents:
6553
diff
changeset
|
233 if (ret_value != NULL) |
800ef4a51096
[gaim-migrate @ 7086]
Christian Hammond <chipx86@chipx86.com>
parents:
6553
diff
changeset
|
234 *ret_value = signal_data->ret_value; |
800ef4a51096
[gaim-migrate @ 7086]
Christian Hammond <chipx86@chipx86.com>
parents:
6553
diff
changeset
|
235 } |
800ef4a51096
[gaim-migrate @ 7086]
Christian Hammond <chipx86@chipx86.com>
parents:
6553
diff
changeset
|
236 |
6547
adf168f002ad
[gaim-migrate @ 7069]
Christian Hammond <chipx86@chipx86.com>
parents:
6509
diff
changeset
|
237 static gulong |
adf168f002ad
[gaim-migrate @ 7069]
Christian Hammond <chipx86@chipx86.com>
parents:
6509
diff
changeset
|
238 signal_connect_common(void *instance, const char *signal, void *handle, |
adf168f002ad
[gaim-migrate @ 7069]
Christian Hammond <chipx86@chipx86.com>
parents:
6509
diff
changeset
|
239 GaimCallback func, void *data, gboolean use_vargs) |
6485 | 240 { |
241 GaimInstanceData *instance_data; | |
242 GaimSignalData *signal_data; | |
243 GaimSignalHandlerData *handler_data; | |
244 | |
245 g_return_val_if_fail(instance != NULL, 0); | |
246 g_return_val_if_fail(signal != NULL, 0); | |
247 g_return_val_if_fail(handle != NULL, 0); | |
248 g_return_val_if_fail(func != NULL, 0); | |
249 | |
250 /* Get the instance data */ | |
251 instance_data = | |
252 (GaimInstanceData *)g_hash_table_lookup(instance_table, instance); | |
253 | |
254 g_return_val_if_fail(instance_data != NULL, 0); | |
255 | |
256 /* Get the signal data */ | |
257 signal_data = | |
258 (GaimSignalData *)g_hash_table_lookup(instance_data->signals, signal); | |
259 | |
260 if (signal_data == NULL) | |
261 { | |
262 gaim_debug(GAIM_DEBUG_ERROR, "signals", | |
263 "Signal data for %s not found!\n", signal); | |
264 return 0; | |
265 } | |
266 | |
267 /* Create the signal handler data */ | |
268 handler_data = g_new0(GaimSignalHandlerData, 1); | |
6547
adf168f002ad
[gaim-migrate @ 7069]
Christian Hammond <chipx86@chipx86.com>
parents:
6509
diff
changeset
|
269 handler_data->id = signal_data->next_handler_id; |
adf168f002ad
[gaim-migrate @ 7069]
Christian Hammond <chipx86@chipx86.com>
parents:
6509
diff
changeset
|
270 handler_data->cb = func; |
adf168f002ad
[gaim-migrate @ 7069]
Christian Hammond <chipx86@chipx86.com>
parents:
6509
diff
changeset
|
271 handler_data->handle = handle; |
adf168f002ad
[gaim-migrate @ 7069]
Christian Hammond <chipx86@chipx86.com>
parents:
6509
diff
changeset
|
272 handler_data->data = data; |
adf168f002ad
[gaim-migrate @ 7069]
Christian Hammond <chipx86@chipx86.com>
parents:
6509
diff
changeset
|
273 handler_data->use_vargs = use_vargs; |
6485 | 274 |
275 signal_data->handlers = g_list_append(signal_data->handlers, handler_data); | |
276 signal_data->handler_count++; | |
277 signal_data->next_handler_id++; | |
278 | |
279 return handler_data->id; | |
280 } | |
6553
9e4fa4853cfe
[gaim-migrate @ 7075]
Christian Hammond <chipx86@chipx86.com>
parents:
6547
diff
changeset
|
281 |
6547
adf168f002ad
[gaim-migrate @ 7069]
Christian Hammond <chipx86@chipx86.com>
parents:
6509
diff
changeset
|
282 gulong |
adf168f002ad
[gaim-migrate @ 7069]
Christian Hammond <chipx86@chipx86.com>
parents:
6509
diff
changeset
|
283 gaim_signal_connect(void *instance, const char *signal, void *handle, |
adf168f002ad
[gaim-migrate @ 7069]
Christian Hammond <chipx86@chipx86.com>
parents:
6509
diff
changeset
|
284 GaimCallback func, void *data) |
adf168f002ad
[gaim-migrate @ 7069]
Christian Hammond <chipx86@chipx86.com>
parents:
6509
diff
changeset
|
285 { |
adf168f002ad
[gaim-migrate @ 7069]
Christian Hammond <chipx86@chipx86.com>
parents:
6509
diff
changeset
|
286 return signal_connect_common(instance, signal, handle, func, data, FALSE); |
adf168f002ad
[gaim-migrate @ 7069]
Christian Hammond <chipx86@chipx86.com>
parents:
6509
diff
changeset
|
287 } |
adf168f002ad
[gaim-migrate @ 7069]
Christian Hammond <chipx86@chipx86.com>
parents:
6509
diff
changeset
|
288 |
adf168f002ad
[gaim-migrate @ 7069]
Christian Hammond <chipx86@chipx86.com>
parents:
6509
diff
changeset
|
289 gulong |
adf168f002ad
[gaim-migrate @ 7069]
Christian Hammond <chipx86@chipx86.com>
parents:
6509
diff
changeset
|
290 gaim_signal_connect_vargs(void *instance, const char *signal, void *handle, |
adf168f002ad
[gaim-migrate @ 7069]
Christian Hammond <chipx86@chipx86.com>
parents:
6509
diff
changeset
|
291 GaimCallback func, void *data) |
adf168f002ad
[gaim-migrate @ 7069]
Christian Hammond <chipx86@chipx86.com>
parents:
6509
diff
changeset
|
292 { |
adf168f002ad
[gaim-migrate @ 7069]
Christian Hammond <chipx86@chipx86.com>
parents:
6509
diff
changeset
|
293 return signal_connect_common(instance, signal, handle, func, data, TRUE); |
adf168f002ad
[gaim-migrate @ 7069]
Christian Hammond <chipx86@chipx86.com>
parents:
6509
diff
changeset
|
294 } |
6485 | 295 |
296 void | |
297 gaim_signal_disconnect(void *instance, const char *signal, | |
298 void *handle, GaimCallback func) | |
299 { | |
300 GaimInstanceData *instance_data; | |
301 GaimSignalData *signal_data; | |
302 GaimSignalHandlerData *handler_data; | |
303 GList *l; | |
304 gboolean found = FALSE; | |
305 | |
306 g_return_if_fail(instance != NULL); | |
307 g_return_if_fail(signal != NULL); | |
308 g_return_if_fail(handle != NULL); | |
309 g_return_if_fail(func != NULL); | |
310 | |
311 /* Get the instance data */ | |
312 instance_data = | |
313 (GaimInstanceData *)g_hash_table_lookup(instance_table, instance); | |
314 | |
315 g_return_if_fail(instance_data != NULL); | |
316 | |
317 /* Get the signal data */ | |
318 signal_data = | |
319 (GaimSignalData *)g_hash_table_lookup(instance_data->signals, signal); | |
320 | |
321 if (signal_data == NULL) | |
322 { | |
323 gaim_debug(GAIM_DEBUG_ERROR, "signals", | |
324 "Signal data for %s not found!\n", signal); | |
325 return; | |
326 } | |
327 | |
328 /* Find the handler data. */ | |
329 for (l = signal_data->handlers; l != NULL; l = l->next) | |
330 { | |
331 handler_data = (GaimSignalHandlerData *)l->data; | |
332 | |
333 if (handler_data->handle == handle && handler_data->cb == func) | |
334 { | |
335 g_free(handler_data); | |
336 | |
337 signal_data->handlers = g_list_remove(signal_data->handlers, | |
338 handler_data); | |
339 signal_data->handler_count--; | |
340 | |
341 found = TRUE; | |
342 | |
343 break; | |
344 } | |
345 } | |
346 | |
347 /* See note somewhere about this actually helping developers.. */ | |
348 g_return_if_fail(found); | |
349 } | |
350 | |
351 /* | |
352 * TODO: Make this all more efficient by storing a list of handlers, keyed | |
353 * to a handle. | |
354 */ | |
355 static void | |
356 disconnect_handle_from_signals(const char *signal, | |
357 GaimSignalData *signal_data, void *handle) | |
358 { | |
359 GList *l, *l_next; | |
360 GaimSignalHandlerData *handler_data; | |
361 | |
362 for (l = signal_data->handlers; l != NULL; l = l_next) | |
363 { | |
364 handler_data = (GaimSignalHandlerData *)l->data; | |
365 l_next = l->next; | |
366 | |
367 if (handler_data->handle == handle) | |
368 { | |
369 g_free(handler_data); | |
370 | |
371 signal_data->handler_count--; | |
372 signal_data->handlers = g_list_remove(signal_data->handlers, | |
373 handler_data); | |
374 } | |
375 } | |
376 } | |
377 | |
378 static void | |
379 disconnect_handle_from_instance(void *instance, | |
380 GaimInstanceData *instance_data, | |
381 void *handle) | |
382 { | |
383 g_hash_table_foreach(instance_data->signals, | |
384 (GHFunc)disconnect_handle_from_signals, handle); | |
385 } | |
386 | |
387 void | |
388 gaim_signals_disconnect_by_handle(void *handle) | |
389 { | |
390 g_return_if_fail(handle != NULL); | |
391 | |
392 g_hash_table_foreach(instance_table, | |
393 (GHFunc)disconnect_handle_from_instance, handle); | |
394 } | |
395 | |
396 void | |
397 gaim_signal_emit(void *instance, const char *signal, ...) | |
398 { | |
399 va_list args; | |
400 | |
401 va_start(args, signal); | |
402 gaim_signal_emit_vargs(instance, signal, args); | |
403 va_end(args); | |
404 } | |
405 | |
406 void | |
407 gaim_signal_emit_vargs(void *instance, const char *signal, va_list args) | |
408 { | |
409 GaimInstanceData *instance_data; | |
410 GaimSignalData *signal_data; | |
411 GaimSignalHandlerData *handler_data; | |
412 GList *l; | |
413 | |
414 g_return_if_fail(instance != NULL); | |
415 g_return_if_fail(signal != NULL); | |
416 | |
417 instance_data = | |
418 (GaimInstanceData *)g_hash_table_lookup(instance_table, instance); | |
419 | |
420 g_return_if_fail(instance_data != NULL); | |
421 | |
422 signal_data = | |
423 (GaimSignalData *)g_hash_table_lookup(instance_data->signals, signal); | |
424 | |
425 if (signal_data == NULL) | |
426 { | |
427 gaim_debug(GAIM_DEBUG_ERROR, "signals", | |
428 "Signal data for %s not found!\n", signal); | |
429 return; | |
430 } | |
431 | |
432 for (l = signal_data->handlers; l != NULL; l = l->next) | |
433 { | |
434 handler_data = (GaimSignalHandlerData *)l->data; | |
435 | |
6547
adf168f002ad
[gaim-migrate @ 7069]
Christian Hammond <chipx86@chipx86.com>
parents:
6509
diff
changeset
|
436 if (handler_data->use_vargs) |
adf168f002ad
[gaim-migrate @ 7069]
Christian Hammond <chipx86@chipx86.com>
parents:
6509
diff
changeset
|
437 { |
adf168f002ad
[gaim-migrate @ 7069]
Christian Hammond <chipx86@chipx86.com>
parents:
6509
diff
changeset
|
438 ((void (*)(va_list, void *))handler_data->cb)(args, |
adf168f002ad
[gaim-migrate @ 7069]
Christian Hammond <chipx86@chipx86.com>
parents:
6509
diff
changeset
|
439 handler_data->data); |
adf168f002ad
[gaim-migrate @ 7069]
Christian Hammond <chipx86@chipx86.com>
parents:
6509
diff
changeset
|
440 } |
adf168f002ad
[gaim-migrate @ 7069]
Christian Hammond <chipx86@chipx86.com>
parents:
6509
diff
changeset
|
441 else |
adf168f002ad
[gaim-migrate @ 7069]
Christian Hammond <chipx86@chipx86.com>
parents:
6509
diff
changeset
|
442 { |
adf168f002ad
[gaim-migrate @ 7069]
Christian Hammond <chipx86@chipx86.com>
parents:
6509
diff
changeset
|
443 signal_data->marshal(handler_data->cb, args, |
adf168f002ad
[gaim-migrate @ 7069]
Christian Hammond <chipx86@chipx86.com>
parents:
6509
diff
changeset
|
444 handler_data->data, NULL); |
adf168f002ad
[gaim-migrate @ 7069]
Christian Hammond <chipx86@chipx86.com>
parents:
6509
diff
changeset
|
445 } |
6485 | 446 } |
447 } | |
448 | |
449 void * | |
450 gaim_signal_emit_return_1(void *instance, const char *signal, ...) | |
451 { | |
452 void *ret_val; | |
453 va_list args; | |
454 | |
455 va_start(args, signal); | |
456 ret_val = gaim_signal_emit_vargs_return_1(instance, signal, args); | |
457 va_end(args); | |
458 | |
459 return ret_val; | |
460 } | |
461 | |
462 void * | |
463 gaim_signal_emit_vargs_return_1(void *instance, const char *signal, | |
464 va_list args) | |
465 { | |
466 GaimInstanceData *instance_data; | |
467 GaimSignalData *signal_data; | |
468 GaimSignalHandlerData *handler_data; | |
469 void *ret_val = NULL; | |
470 GList *l; | |
471 | |
472 g_return_val_if_fail(instance != NULL, NULL); | |
473 g_return_val_if_fail(signal != NULL, NULL); | |
474 | |
475 instance_data = | |
476 (GaimInstanceData *)g_hash_table_lookup(instance_table, instance); | |
477 | |
478 g_return_val_if_fail(instance_data != NULL, NULL); | |
479 | |
480 signal_data = | |
481 (GaimSignalData *)g_hash_table_lookup(instance_data->signals, signal); | |
482 | |
483 if (signal_data == NULL) | |
484 { | |
485 gaim_debug(GAIM_DEBUG_ERROR, "signals", | |
486 "Signal data for %s not found!\n", signal); | |
487 return 0; | |
488 } | |
489 | |
490 for (l = signal_data->handlers; l != NULL; l = l->next) | |
491 { | |
492 handler_data = (GaimSignalHandlerData *)l->data; | |
493 | |
6547
adf168f002ad
[gaim-migrate @ 7069]
Christian Hammond <chipx86@chipx86.com>
parents:
6509
diff
changeset
|
494 if (handler_data->use_vargs) |
adf168f002ad
[gaim-migrate @ 7069]
Christian Hammond <chipx86@chipx86.com>
parents:
6509
diff
changeset
|
495 { |
adf168f002ad
[gaim-migrate @ 7069]
Christian Hammond <chipx86@chipx86.com>
parents:
6509
diff
changeset
|
496 ret_val = ((void *(*)(va_list, void *))handler_data->cb)( |
adf168f002ad
[gaim-migrate @ 7069]
Christian Hammond <chipx86@chipx86.com>
parents:
6509
diff
changeset
|
497 args, handler_data->data); |
adf168f002ad
[gaim-migrate @ 7069]
Christian Hammond <chipx86@chipx86.com>
parents:
6509
diff
changeset
|
498 } |
adf168f002ad
[gaim-migrate @ 7069]
Christian Hammond <chipx86@chipx86.com>
parents:
6509
diff
changeset
|
499 else |
adf168f002ad
[gaim-migrate @ 7069]
Christian Hammond <chipx86@chipx86.com>
parents:
6509
diff
changeset
|
500 { |
adf168f002ad
[gaim-migrate @ 7069]
Christian Hammond <chipx86@chipx86.com>
parents:
6509
diff
changeset
|
501 signal_data->marshal(handler_data->cb, args, |
adf168f002ad
[gaim-migrate @ 7069]
Christian Hammond <chipx86@chipx86.com>
parents:
6509
diff
changeset
|
502 handler_data->data, &ret_val); |
adf168f002ad
[gaim-migrate @ 7069]
Christian Hammond <chipx86@chipx86.com>
parents:
6509
diff
changeset
|
503 } |
6485 | 504 } |
505 | |
506 return ret_val; | |
507 } | |
508 | |
509 void | |
510 gaim_signals_init() | |
511 { | |
512 g_return_if_fail(instance_table == NULL); | |
513 | |
514 instance_table = | |
515 g_hash_table_new_full(g_direct_hash, g_direct_equal, | |
516 NULL, (GDestroyNotify)destroy_instance_data); | |
517 } | |
518 | |
519 void | |
520 gaim_signals_uninit() | |
521 { | |
522 g_return_if_fail(instance_table != NULL); | |
523 | |
524 g_hash_table_destroy(instance_table); | |
525 instance_table = NULL; | |
526 } | |
527 | |
528 /************************************************************************** | |
529 * Marshallers | |
530 **************************************************************************/ | |
531 void | |
532 gaim_marshal_VOID(GaimCallback cb, va_list args, void *data, | |
533 void **return_val) | |
534 { | |
535 ((void (*)(void *))cb)(data); | |
536 } | |
537 | |
538 void | |
539 gaim_marshal_VOID__POINTER(GaimCallback cb, va_list args, void *data, | |
540 void **return_val) | |
541 { | |
6505 | 542 void *arg1 = va_arg(args, void *); |
543 | |
544 ((void (*)(void *, void *))cb)(arg1, data); | |
6485 | 545 } |
546 | |
547 void | |
548 gaim_marshal_VOID__POINTER_POINTER(GaimCallback cb, va_list args, | |
549 void *data, void **return_val) | |
550 { | |
6505 | 551 void *arg1 = va_arg(args, void *); |
552 void *arg2 = va_arg(args, void *); | |
553 | |
554 ((void (*)(void *, void *, void *))cb)(arg1, arg2, data); | |
6485 | 555 } |
556 | |
557 void | |
558 gaim_marshal_VOID__POINTER_POINTER_UINT(GaimCallback cb, va_list args, | |
559 void *data, void **return_val) | |
560 { | |
6505 | 561 void *arg1 = va_arg(args, void *); |
562 void *arg2 = va_arg(args, void *); | |
563 guint arg3 = va_arg(args, guint); | |
564 | |
565 ((void (*)(void *, void *, guint, void *))cb)(arg1, arg2, arg3, data); | |
6485 | 566 } |
567 | |
568 void | |
569 gaim_marshal_VOID__POINTER_POINTER_POINTER(GaimCallback cb, va_list args, | |
570 void *data, void **return_val) | |
571 { | |
6505 | 572 void *arg1 = va_arg(args, void *); |
573 void *arg2 = va_arg(args, void *); | |
574 void *arg3 = va_arg(args, void *); | |
575 | |
576 ((void (*)(void *, void *, void *, void *))cb)(arg1, arg2, arg3, data); | |
6485 | 577 } |
578 | |
579 void | |
580 gaim_marshal_VOID__POINTER_POINTER_POINTER_POINTER(GaimCallback cb, | |
581 va_list args, | |
582 void *data, | |
583 void **return_val) | |
584 { | |
6505 | 585 void *arg1 = va_arg(args, void *); |
586 void *arg2 = va_arg(args, void *); | |
587 void *arg3 = va_arg(args, void *); | |
588 void *arg4 = va_arg(args, void *); | |
589 | |
590 ((void (*)(void *, void *, void *, void *, void *))cb)(arg1, arg2, arg3, arg4, data); | |
6485 | 591 } |
6509 | 592 |
593 void | |
594 gaim_marshal_VOID__POINTER_POINTER_POINTER_UINT(GaimCallback cb, | |
595 va_list args, | |
596 void *data, | |
597 void **return_val) | |
598 { | |
599 void *arg1 = va_arg(args, void *); | |
600 void *arg2 = va_arg(args, void *); | |
601 void *arg3 = va_arg(args, void *); | |
602 guint arg4 = va_arg(args, guint); | |
603 | |
604 ((void (*)(void *, void *, void *, guint, void *))cb)(arg1, arg2, arg3, arg4, data); | |
605 } | |
606 | |
6485 | 607 void |
608 gaim_marshal_VOID__POINTER_POINTER_POINTER_UINT_UINT(GaimCallback cb, | |
609 va_list args, | |
610 void *data, | |
611 void **return_val) | |
612 { | |
6505 | 613 void *arg1 = va_arg(args, void *); |
614 void *arg2 = va_arg(args, void *); | |
615 void *arg3 = va_arg(args, void *); | |
616 guint arg4 = va_arg(args, guint); | |
617 guint arg5 = va_arg(args, guint); | |
618 | |
6485 | 619 ((void (*)(void *, void *, void *, guint, guint, void *))cb)( |
6505 | 620 arg1, arg2, arg3, arg4, arg5, data); |
6485 | 621 } |
622 | |
623 void | |
624 gaim_marshal_BOOLEAN__POINTER(GaimCallback cb, va_list args, void *data, | |
625 void **return_val) | |
626 { | |
627 gboolean ret_val; | |
6505 | 628 void *arg1 = va_arg(args, void *); |
6485 | 629 |
6505 | 630 ret_val = ((gboolean (*)(void *, void *))cb)(arg1, data); |
6485 | 631 |
632 if (return_val != NULL) | |
633 *return_val = GINT_TO_POINTER(ret_val); | |
634 } | |
635 | |
636 void | |
637 gaim_marshal_BOOLEAN__POINTER_POINTER(GaimCallback cb, va_list args, | |
638 void *data, void **return_val) | |
639 { | |
640 gboolean ret_val; | |
6505 | 641 void *arg1 = va_arg(args, void *); |
642 void *arg2 = va_arg(args, void *); | |
6485 | 643 |
6505 | 644 ret_val = ((gboolean (*)(void *, void *, void *))cb)(arg1, arg2, data); |
6485 | 645 |
646 if (return_val != NULL) | |
647 *return_val = GINT_TO_POINTER(ret_val); | |
648 } | |
649 | |
650 void | |
6509 | 651 gaim_marshal_BOOLEAN__POINTER_POINTER_POINTER(GaimCallback cb, va_list args, |
652 void *data, void **return_val) | |
653 { | |
654 gboolean ret_val; | |
655 void *arg1 = va_arg(args, void *); | |
656 void *arg2 = va_arg(args, void *); | |
657 void *arg3 = va_arg(args, void *); | |
658 | |
659 ret_val = ((gboolean (*)(void *, void *, void *, void *))cb)(arg1, arg2, | |
660 arg3, data); | |
661 | |
662 if (return_val != NULL) | |
663 *return_val = GINT_TO_POINTER(ret_val); | |
664 } | |
665 | |
666 void | |
667 gaim_marshal_BOOLEAN__POINTER_POINTER_UINT(GaimCallback cb, | |
668 va_list args, | |
669 void *data, | |
670 void **return_val) | |
671 { | |
672 gboolean ret_val; | |
673 void *arg1 = va_arg(args, void *); | |
674 void *arg2 = va_arg(args, void *); | |
675 guint arg3 = va_arg(args, guint); | |
676 | |
677 ret_val = ((gboolean (*)(void *, void *, guint, void *))cb)( | |
678 arg1, arg2, arg3, data); | |
679 | |
680 if (return_val != NULL) | |
681 *return_val = GINT_TO_POINTER(ret_val); | |
682 } | |
683 | |
684 void | |
6485 | 685 gaim_marshal_BOOLEAN__POINTER_POINTER_POINTER_UINT(GaimCallback cb, |
686 va_list args, | |
687 void *data, | |
688 void **return_val) | |
689 { | |
690 gboolean ret_val; | |
6505 | 691 void *arg1 = va_arg(args, void *); |
692 void *arg2 = va_arg(args, void *); | |
693 void *arg3 = va_arg(args, void *); | |
694 guint arg4 = va_arg(args, guint); | |
6485 | 695 |
696 ret_val = ((gboolean (*)(void *, void *, void *, guint, void *))cb)( | |
6505 | 697 arg1, arg2, arg3, arg4, data); |
6485 | 698 |
699 if (return_val != NULL) | |
700 *return_val = GINT_TO_POINTER(ret_val); | |
701 } | |
702 | |
703 void | |
704 gaim_marshal_BOOLEAN__POINTER_POINTER_POINTER_POINTER(GaimCallback cb, | |
705 va_list args, | |
706 void *data, | |
707 void **return_val) | |
708 { | |
709 gboolean ret_val; | |
6505 | 710 void *arg1 = va_arg(args, void *); |
711 void *arg2 = va_arg(args, void *); | |
712 void *arg3 = va_arg(args, void *); | |
713 void *arg4 = va_arg(args, void *); | |
6485 | 714 |
715 ret_val = ((gboolean (*)(void *, void *, void *, void *, void *))cb)( | |
6505 | 716 arg1, arg2, arg3, arg4, data); |
6485 | 717 |
718 if (return_val != NULL) | |
719 *return_val = GINT_TO_POINTER(ret_val); | |
720 } | |
721 | |
722 void | |
723 gaim_marshal_BOOLEAN__POINTER_POINTER_POINTER_POINTER_POINTER( | |
724 GaimCallback cb, va_list args, void *data, void **return_val) | |
725 { | |
726 gboolean ret_val; | |
6505 | 727 void *arg1 = va_arg(args, void *); |
728 void *arg2 = va_arg(args, void *); | |
729 void *arg3 = va_arg(args, void *); | |
730 void *arg4 = va_arg(args, void *); | |
731 void *arg5 = va_arg(args, void *); | |
6485 | 732 |
733 ret_val = | |
734 ((gboolean (*)(void *, void *, void *, void *, void *, void *))cb)( | |
6505 | 735 arg1, arg2, arg3, arg4, arg5, data); |
6485 | 736 |
737 if (return_val != NULL) | |
738 *return_val = GINT_TO_POINTER(ret_val); | |
739 } |