1 /**
2 * @file signals.c Signal API
3 * @ingroup core
4 */
5
6 /* purple
7 *
8 * Purple is the legal property of its developers, whose names are too numerous
9 * to list here. Please refer to the COPYRIGHT file distributed with this
10 * source distribution.
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
25 */
26 #include "internal.h"
27
28 #include "dbus-maybe.h"
29 #include "debug.h"
30 #include "glibcompat.h"
31 #include "signals.h"
32 #include "value.h"
33
34 /* must include this to use G_VA_COPY */
35 #include <string.h>
36
37 typedef struct
38 {
39 void *instance;
40
41 GHashTable *signals;
42 size_t signal_count;
43
44 gulong next_signal_id;
45
46 } PurpleInstanceData;
47
48 typedef struct
49 {
50 gulong id;
51
52 PurpleSignalMarshalFunc marshal;
53
54 int num_values;
55 PurpleValue **values;
56 PurpleValue *ret_value;
57
58 GList *handlers;
59 size_t handler_count;
60
61 gulong next_handler_id;
62 } PurpleSignalData;
63
64 typedef struct
65 {
66 gulong id;
67 PurpleCallback cb;
68 void *handle;
69 void *data;
70 gboolean use_vargs;
71 int priority;
72
73 } PurpleSignalHandlerData;
74
75 static GHashTable *instance_table = NULL;
76
77 static void
destroy_instance_data(PurpleInstanceData * instance_data)78 destroy_instance_data(PurpleInstanceData *instance_data)
79 {
80 g_hash_table_destroy(instance_data->signals);
81
82 g_free(instance_data);
83 }
84
85 static void
destroy_signal_data(PurpleSignalData * signal_data)86 destroy_signal_data(PurpleSignalData *signal_data)
87 {
88 g_list_free_full(signal_data->handlers, (GDestroyNotify)g_free);
89
90 if (signal_data->values != NULL)
91 {
92 int i;
93
94 for (i = 0; i < signal_data->num_values; i++)
95 purple_value_destroy((PurpleValue *)signal_data->values[i]);
96
97 g_free(signal_data->values);
98 }
99
100 if (signal_data->ret_value != NULL)
101 purple_value_destroy(signal_data->ret_value);
102 g_free(signal_data);
103 }
104
105 gulong
purple_signal_register(void * instance,const char * signal,PurpleSignalMarshalFunc marshal,PurpleValue * ret_value,int num_values,...)106 purple_signal_register(void *instance, const char *signal,
107 PurpleSignalMarshalFunc marshal,
108 PurpleValue *ret_value, int num_values, ...)
109 {
110 PurpleInstanceData *instance_data;
111 PurpleSignalData *signal_data;
112 va_list args;
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 (PurpleInstanceData *)g_hash_table_lookup(instance_table, instance);
120
121 if (instance_data == NULL)
122 {
123 instance_data = g_new0(PurpleInstanceData, 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(PurpleSignalData, 1);
136 signal_data->id = instance_data->next_signal_id;
137 signal_data->marshal = marshal;
138 signal_data->next_handler_id = 1;
139 signal_data->ret_value = ret_value;
140 signal_data->num_values = num_values;
141
142 if (num_values > 0)
143 {
144 int i;
145
146 signal_data->values = g_new0(PurpleValue *, num_values);
147
148 va_start(args, num_values);
149
150 for (i = 0; i < num_values; i++)
151 signal_data->values[i] = va_arg(args, PurpleValue *);
152
153 va_end(args);
154 }
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
purple_signal_unregister(void * instance,const char * signal)166 purple_signal_unregister(void *instance, const char *signal)
167 {
168 PurpleInstanceData *instance_data;
169
170 g_return_if_fail(instance != NULL);
171 g_return_if_fail(signal != NULL);
172
173 instance_data =
174 (PurpleInstanceData *)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
purple_signals_unregister_by_instance(void * instance)190 purple_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
205 void
purple_signal_get_values(void * instance,const char * signal,PurpleValue ** ret_value,int * num_values,PurpleValue *** values)206 purple_signal_get_values(void *instance, const char *signal,
207 PurpleValue **ret_value,
208 int *num_values, PurpleValue ***values)
209 {
210 PurpleInstanceData *instance_data;
211 PurpleSignalData *signal_data;
212
213 g_return_if_fail(instance != NULL);
214 g_return_if_fail(signal != NULL);
215 g_return_if_fail(num_values != NULL);
216 g_return_if_fail(values != NULL);
217
218 /* Get the instance data */
219 instance_data =
220 (PurpleInstanceData *)g_hash_table_lookup(instance_table, instance);
221
222 g_return_if_fail(instance_data != NULL);
223
224 /* Get the signal data */
225 signal_data =
226 (PurpleSignalData *)g_hash_table_lookup(instance_data->signals, signal);
227
228 g_return_if_fail(signal_data != NULL);
229
230 *num_values = signal_data->num_values;
231 *values = signal_data->values;
232
233 if (ret_value != NULL)
234 *ret_value = signal_data->ret_value;
235 }
236
handler_priority(void * a,void * b)237 static gint handler_priority(void * a, void * b) {
238 PurpleSignalHandlerData *ah = (PurpleSignalHandlerData*)a;
239 PurpleSignalHandlerData *bh = (PurpleSignalHandlerData*)b;
240 if (ah->priority > bh->priority) return 1;
241 if (ah->priority < bh->priority) return -1;
242 return 0;
243 }
244
245 static gulong
signal_connect_common(void * instance,const char * signal,void * handle,PurpleCallback func,void * data,int priority,gboolean use_vargs)246 signal_connect_common(void *instance, const char *signal, void *handle,
247 PurpleCallback func, void *data, int priority, gboolean use_vargs)
248 {
249 PurpleInstanceData *instance_data;
250 PurpleSignalData *signal_data;
251 PurpleSignalHandlerData *handler_data;
252
253 g_return_val_if_fail(instance != NULL, 0);
254 g_return_val_if_fail(signal != NULL, 0);
255 g_return_val_if_fail(handle != NULL, 0);
256 g_return_val_if_fail(func != NULL, 0);
257
258 /* Get the instance data */
259 instance_data =
260 (PurpleInstanceData *)g_hash_table_lookup(instance_table, instance);
261
262 if (instance_data == NULL)
263 {
264 purple_debug_warning("signals", "Something tried to register a callback "
265 "for the '%s' signal, but we do not have any signals "
266 "registered with the given handle\n", signal);
267 g_return_val_if_reached(0);
268 }
269
270 /* Get the signal data */
271 signal_data =
272 (PurpleSignalData *)g_hash_table_lookup(instance_data->signals, signal);
273
274 if (signal_data == NULL)
275 {
276 purple_debug(PURPLE_DEBUG_ERROR, "signals",
277 "Signal data for %s not found!\n", signal);
278 return 0;
279 }
280
281 /* Create the signal handler data */
282 handler_data = g_new0(PurpleSignalHandlerData, 1);
283 handler_data->id = signal_data->next_handler_id;
284 handler_data->cb = func;
285 handler_data->handle = handle;
286 handler_data->data = data;
287 handler_data->use_vargs = use_vargs;
288 handler_data->priority = priority;
289
290 signal_data->handlers = g_list_insert_sorted(signal_data->handlers, handler_data, (GCompareFunc)handler_priority);
291 signal_data->handler_count++;
292 signal_data->next_handler_id++;
293
294 return handler_data->id;
295 }
296
297 gulong
purple_signal_connect_priority(void * instance,const char * signal,void * handle,PurpleCallback func,void * data,int priority)298 purple_signal_connect_priority(void *instance, const char *signal, void *handle,
299 PurpleCallback func, void *data, int priority)
300 {
301 return signal_connect_common(instance, signal, handle, func, data, priority, FALSE);
302 }
303
304 gulong
purple_signal_connect(void * instance,const char * signal,void * handle,PurpleCallback func,void * data)305 purple_signal_connect(void *instance, const char *signal, void *handle,
306 PurpleCallback func, void *data)
307 {
308 return signal_connect_common(instance, signal, handle, func, data, PURPLE_SIGNAL_PRIORITY_DEFAULT, FALSE);
309 }
310
311 gulong
purple_signal_connect_priority_vargs(void * instance,const char * signal,void * handle,PurpleCallback func,void * data,int priority)312 purple_signal_connect_priority_vargs(void *instance, const char *signal, void *handle,
313 PurpleCallback func, void *data, int priority)
314 {
315 return signal_connect_common(instance, signal, handle, func, data, priority, TRUE);
316 }
317
318 gulong
purple_signal_connect_vargs(void * instance,const char * signal,void * handle,PurpleCallback func,void * data)319 purple_signal_connect_vargs(void *instance, const char *signal, void *handle,
320 PurpleCallback func, void *data)
321 {
322 return signal_connect_common(instance, signal, handle, func, data, PURPLE_SIGNAL_PRIORITY_DEFAULT, TRUE);
323 }
324
325 void
purple_signal_disconnect(void * instance,const char * signal,void * handle,PurpleCallback func)326 purple_signal_disconnect(void *instance, const char *signal,
327 void *handle, PurpleCallback func)
328 {
329 PurpleInstanceData *instance_data;
330 PurpleSignalData *signal_data;
331 PurpleSignalHandlerData *handler_data;
332 GList *l;
333 gboolean found = FALSE;
334
335 g_return_if_fail(instance != NULL);
336 g_return_if_fail(signal != NULL);
337 g_return_if_fail(handle != NULL);
338 g_return_if_fail(func != NULL);
339
340 /* Get the instance data */
341 instance_data =
342 (PurpleInstanceData *)g_hash_table_lookup(instance_table, instance);
343
344 g_return_if_fail(instance_data != NULL);
345
346 /* Get the signal data */
347 signal_data =
348 (PurpleSignalData *)g_hash_table_lookup(instance_data->signals, signal);
349
350 if (signal_data == NULL)
351 {
352 purple_debug(PURPLE_DEBUG_ERROR, "signals",
353 "Signal data for %s not found!\n", signal);
354 return;
355 }
356
357 /* Find the handler data. */
358 for (l = signal_data->handlers; l != NULL; l = l->next)
359 {
360 handler_data = (PurpleSignalHandlerData *)l->data;
361
362 if (handler_data->handle == handle && handler_data->cb == func)
363 {
364 g_free(handler_data);
365
366 signal_data->handlers = g_list_delete_link(signal_data->handlers,
367 l);
368 signal_data->handler_count--;
369
370 found = TRUE;
371
372 break;
373 }
374 }
375
376 /* See note somewhere about this actually helping developers.. */
377 g_return_if_fail(found);
378 }
379
380 /*
381 * TODO: Make this all more efficient by storing a list of handlers, keyed
382 * to a handle.
383 */
384 static void
disconnect_handle_from_signals(const char * signal,PurpleSignalData * signal_data,void * handle)385 disconnect_handle_from_signals(const char *signal,
386 PurpleSignalData *signal_data, void *handle)
387 {
388 GList *l, *l_next;
389 PurpleSignalHandlerData *handler_data;
390
391 for (l = signal_data->handlers; l != NULL; l = l_next)
392 {
393 handler_data = (PurpleSignalHandlerData *)l->data;
394 l_next = l->next;
395
396 if (handler_data->handle == handle)
397 {
398 g_free(handler_data);
399
400 signal_data->handler_count--;
401 signal_data->handlers = g_list_delete_link(signal_data->handlers,
402 l);
403 }
404 }
405 }
406
407 static void
disconnect_handle_from_instance(void * instance,PurpleInstanceData * instance_data,void * handle)408 disconnect_handle_from_instance(void *instance,
409 PurpleInstanceData *instance_data,
410 void *handle)
411 {
412 g_hash_table_foreach(instance_data->signals,
413 (GHFunc)disconnect_handle_from_signals, handle);
414 }
415
416 void
purple_signals_disconnect_by_handle(void * handle)417 purple_signals_disconnect_by_handle(void *handle)
418 {
419 g_return_if_fail(handle != NULL);
420
421 g_hash_table_foreach(instance_table,
422 (GHFunc)disconnect_handle_from_instance, handle);
423 }
424
425 void
purple_signal_emit(void * instance,const char * signal,...)426 purple_signal_emit(void *instance, const char *signal, ...)
427 {
428 va_list args;
429
430 g_return_if_fail(instance != NULL);
431 g_return_if_fail(signal != NULL);
432
433 va_start(args, signal);
434 purple_signal_emit_vargs(instance, signal, args);
435 va_end(args);
436 }
437
438 void
purple_signal_emit_vargs(void * instance,const char * signal,va_list args)439 purple_signal_emit_vargs(void *instance, const char *signal, va_list args)
440 {
441 PurpleInstanceData *instance_data;
442 PurpleSignalData *signal_data;
443 PurpleSignalHandlerData *handler_data;
444 GList *l, *l_next;
445 va_list tmp;
446
447 g_return_if_fail(instance != NULL);
448 g_return_if_fail(signal != NULL);
449
450 instance_data =
451 (PurpleInstanceData *)g_hash_table_lookup(instance_table, instance);
452
453 g_return_if_fail(instance_data != NULL);
454
455 signal_data =
456 (PurpleSignalData *)g_hash_table_lookup(instance_data->signals, signal);
457
458 if (signal_data == NULL)
459 {
460 purple_debug(PURPLE_DEBUG_ERROR, "signals",
461 "Signal data for %s not found!\n", signal);
462 return;
463 }
464
465 for (l = signal_data->handlers; l != NULL; l = l_next)
466 {
467 l_next = l->next;
468
469 handler_data = (PurpleSignalHandlerData *)l->data;
470
471 /* This is necessary because a va_list may only be
472 * evaluated once */
473 G_VA_COPY(tmp, args);
474
475 if (handler_data->use_vargs)
476 {
477 ((void (*)(va_list, void *))handler_data->cb)(tmp,
478 handler_data->data);
479 }
480 else
481 {
482 signal_data->marshal(handler_data->cb, tmp,
483 handler_data->data, NULL);
484 }
485
486 va_end(tmp);
487 }
488
489 #ifdef HAVE_DBUS
490 purple_dbus_signal_emit_purple(signal, signal_data->num_values,
491 signal_data->values, args);
492 #endif /* HAVE_DBUS */
493
494 }
495
496 void *
purple_signal_emit_return_1(void * instance,const char * signal,...)497 purple_signal_emit_return_1(void *instance, const char *signal, ...)
498 {
499 void *ret_val;
500 va_list args;
501
502 g_return_val_if_fail(instance != NULL, NULL);
503 g_return_val_if_fail(signal != NULL, NULL);
504
505 va_start(args, signal);
506 ret_val = purple_signal_emit_vargs_return_1(instance, signal, args);
507 va_end(args);
508
509 return ret_val;
510 }
511
512 void *
purple_signal_emit_vargs_return_1(void * instance,const char * signal,va_list args)513 purple_signal_emit_vargs_return_1(void *instance, const char *signal,
514 va_list args)
515 {
516 PurpleInstanceData *instance_data;
517 PurpleSignalData *signal_data;
518 PurpleSignalHandlerData *handler_data;
519 GList *l, *l_next;
520 va_list tmp;
521
522 g_return_val_if_fail(instance != NULL, NULL);
523 g_return_val_if_fail(signal != NULL, NULL);
524
525 instance_data =
526 (PurpleInstanceData *)g_hash_table_lookup(instance_table, instance);
527
528 g_return_val_if_fail(instance_data != NULL, NULL);
529
530 signal_data =
531 (PurpleSignalData *)g_hash_table_lookup(instance_data->signals, signal);
532
533 if (signal_data == NULL)
534 {
535 purple_debug(PURPLE_DEBUG_ERROR, "signals",
536 "Signal data for %s not found!\n", signal);
537 return 0;
538 }
539
540 #ifdef HAVE_DBUS
541 G_VA_COPY(tmp, args);
542 purple_dbus_signal_emit_purple(signal, signal_data->num_values,
543 signal_data->values, tmp);
544 va_end(tmp);
545 #endif /* HAVE_DBUS */
546
547 for (l = signal_data->handlers; l != NULL; l = l_next)
548 {
549 void *ret_val = NULL;
550
551 l_next = l->next;
552
553 handler_data = (PurpleSignalHandlerData *)l->data;
554
555 G_VA_COPY(tmp, args);
556 if (handler_data->use_vargs)
557 {
558 ret_val = ((void *(*)(va_list, void *))handler_data->cb)(
559 tmp, handler_data->data);
560 }
561 else
562 {
563 signal_data->marshal(handler_data->cb, tmp,
564 handler_data->data, &ret_val);
565 }
566 va_end(tmp);
567
568 if (ret_val != NULL)
569 return ret_val;
570 }
571
572 return NULL;
573 }
574
575 void
purple_signals_init()576 purple_signals_init()
577 {
578 g_return_if_fail(instance_table == NULL);
579
580 instance_table =
581 g_hash_table_new_full(g_direct_hash, g_direct_equal,
582 NULL, (GDestroyNotify)destroy_instance_data);
583 }
584
585 void
purple_signals_uninit()586 purple_signals_uninit()
587 {
588 g_return_if_fail(instance_table != NULL);
589
590 g_hash_table_destroy(instance_table);
591 instance_table = NULL;
592 }
593
594 /**************************************************************************
595 * Marshallers
596 **************************************************************************/
597 void
purple_marshal_VOID(PurpleCallback cb,va_list args,void * data,void ** return_val)598 purple_marshal_VOID(PurpleCallback cb, va_list args, void *data,
599 void **return_val)
600 {
601 ((void (*)(void *))cb)(data);
602 }
603
604 void
purple_marshal_VOID__INT(PurpleCallback cb,va_list args,void * data,void ** return_val)605 purple_marshal_VOID__INT(PurpleCallback cb, va_list args, void *data,
606 void **return_val)
607 {
608 gint arg1 = va_arg(args, gint);
609
610 ((void (*)(gint, void *))cb)(arg1, data);
611 }
612
613 void
purple_marshal_VOID__INT_INT(PurpleCallback cb,va_list args,void * data,void ** return_val)614 purple_marshal_VOID__INT_INT(PurpleCallback cb, va_list args, void *data,
615 void **return_val)
616 {
617 gint arg1 = va_arg(args, gint);
618 gint arg2 = va_arg(args, gint);
619
620 ((void (*)(gint, gint, void *))cb)(arg1, arg2, data);
621 }
622
623 void
purple_marshal_VOID__POINTER(PurpleCallback cb,va_list args,void * data,void ** return_val)624 purple_marshal_VOID__POINTER(PurpleCallback cb, va_list args, void *data,
625 void **return_val)
626 {
627 void *arg1 = va_arg(args, void *);
628
629 ((void (*)(void *, void *))cb)(arg1, data);
630 }
631
632 void
purple_marshal_VOID__POINTER_UINT(PurpleCallback cb,va_list args,void * data,void ** return_val)633 purple_marshal_VOID__POINTER_UINT(PurpleCallback cb, va_list args,
634 void *data, void **return_val)
635 {
636 void *arg1 = va_arg(args, void *);
637 guint arg2 = va_arg(args, guint);
638
639 ((void (*)(void *, guint, void *))cb)(arg1, arg2, data);
640 }
641
purple_marshal_VOID__POINTER_INT_INT(PurpleCallback cb,va_list args,void * data,void ** return_val)642 void purple_marshal_VOID__POINTER_INT_INT(PurpleCallback cb, va_list args,
643 void *data, void **return_val)
644 {
645 void *arg1 = va_arg(args, void *);
646 gint arg2 = va_arg(args, gint);
647 gint arg3 = va_arg(args, gint);
648
649 ((void (*)(void *, gint, gint, void *))cb)(arg1, arg2, arg3, data);
650 }
651
purple_marshal_VOID__POINTER_INT_POINTER(PurpleCallback cb,va_list args,void * data,void ** return_val)652 void purple_marshal_VOID__POINTER_INT_POINTER(PurpleCallback cb, va_list args,
653 void *data, void **return_val)
654 {
655 void *arg1 = va_arg(args, void *);
656 gint arg2 = va_arg(args, gint);
657 void *arg3 = va_arg(args, void *);
658
659 ((void (*)(void *, gint, void *, void *))cb)(arg1, arg2, arg3, data);
660 }
661
662 void
purple_marshal_VOID__POINTER_POINTER(PurpleCallback cb,va_list args,void * data,void ** return_val)663 purple_marshal_VOID__POINTER_POINTER(PurpleCallback cb, va_list args,
664 void *data, void **return_val)
665 {
666 void *arg1 = va_arg(args, void *);
667 void *arg2 = va_arg(args, void *);
668
669 ((void (*)(void *, void *, void *))cb)(arg1, arg2, data);
670 }
671
672 void
purple_marshal_VOID__POINTER_POINTER_UINT(PurpleCallback cb,va_list args,void * data,void ** return_val)673 purple_marshal_VOID__POINTER_POINTER_UINT(PurpleCallback cb, va_list args,
674 void *data, void **return_val)
675 {
676 void *arg1 = va_arg(args, void *);
677 void *arg2 = va_arg(args, void *);
678 guint arg3 = va_arg(args, guint);
679
680 ((void (*)(void *, void *, guint, void *))cb)(arg1, arg2, arg3, data);
681 }
682
683 void
purple_marshal_VOID__POINTER_POINTER_UINT_UINT(PurpleCallback cb,va_list args,void * data,void ** return_val)684 purple_marshal_VOID__POINTER_POINTER_UINT_UINT(PurpleCallback cb, va_list args,
685 void *data, void **return_val)
686 {
687 void *arg1 = va_arg(args, void *);
688 void *arg2 = va_arg(args, void *);
689 guint arg3 = va_arg(args, guint);
690 guint arg4 = va_arg(args, guint);
691
692 ((void (*)(void *, void *, guint, guint, void *))cb)(arg1, arg2, arg3, arg4, data);
693 }
694
695 void
purple_marshal_VOID__POINTER_POINTER_POINTER(PurpleCallback cb,va_list args,void * data,void ** return_val)696 purple_marshal_VOID__POINTER_POINTER_POINTER(PurpleCallback cb, va_list args,
697 void *data, void **return_val)
698 {
699 void *arg1 = va_arg(args, void *);
700 void *arg2 = va_arg(args, void *);
701 void *arg3 = va_arg(args, void *);
702
703 ((void (*)(void *, void *, void *, void *))cb)(arg1, arg2, arg3, data);
704 }
705
706 void
purple_marshal_VOID__POINTER_POINTER_POINTER_POINTER(PurpleCallback cb,va_list args,void * data,void ** return_val)707 purple_marshal_VOID__POINTER_POINTER_POINTER_POINTER(PurpleCallback cb,
708 va_list args,
709 void *data,
710 void **return_val)
711 {
712 void *arg1 = va_arg(args, void *);
713 void *arg2 = va_arg(args, void *);
714 void *arg3 = va_arg(args, void *);
715 void *arg4 = va_arg(args, void *);
716
717 ((void (*)(void *, void *, void *, void *, void *))cb)(arg1, arg2, arg3, arg4, data);
718 }
719
720 void
purple_marshal_VOID__POINTER_POINTER_POINTER_POINTER_POINTER(PurpleCallback cb,va_list args,void * data,void ** return_val)721 purple_marshal_VOID__POINTER_POINTER_POINTER_POINTER_POINTER(PurpleCallback cb,
722 va_list args,
723 void *data,
724 void **return_val)
725 {
726 void *arg1 = va_arg(args, void *);
727 void *arg2 = va_arg(args, void *);
728 void *arg3 = va_arg(args, void *);
729 void *arg4 = va_arg(args, void *);
730 void *arg5 = va_arg(args, void *);
731
732 ((void (*)(void *, void *, void *, void *, void *, void *))cb)(arg1, arg2, arg3, arg4, arg5, data);
733 }
734
735 void
purple_marshal_VOID__POINTER_POINTER_POINTER_UINT(PurpleCallback cb,va_list args,void * data,void ** return_val)736 purple_marshal_VOID__POINTER_POINTER_POINTER_UINT(PurpleCallback cb,
737 va_list args,
738 void *data,
739 void **return_val)
740 {
741 void *arg1 = va_arg(args, void *);
742 void *arg2 = va_arg(args, void *);
743 void *arg3 = va_arg(args, void *);
744 guint arg4 = va_arg(args, guint);
745
746 ((void (*)(void *, void *, void *, guint, void *))cb)(arg1, arg2, arg3, arg4, data);
747 }
748
749 void
purple_marshal_VOID__POINTER_POINTER_POINTER_POINTER_UINT(PurpleCallback cb,va_list args,void * data,void ** return_val)750 purple_marshal_VOID__POINTER_POINTER_POINTER_POINTER_UINT(PurpleCallback cb,
751 va_list args,
752 void *data,
753 void **return_val)
754 {
755 void *arg1 = va_arg(args, void *);
756 void *arg2 = va_arg(args, void *);
757 void *arg3 = va_arg(args, void *);
758 void *arg4 = va_arg(args, void *);
759 guint arg5 = va_arg(args, guint);
760
761 ((void (*)(void *, void *, void *, void *, guint, void *))cb)(arg1, arg2, arg3, arg4, arg5, data);
762 }
763
764 void
purple_marshal_VOID__POINTER_POINTER_POINTER_UINT_UINT(PurpleCallback cb,va_list args,void * data,void ** return_val)765 purple_marshal_VOID__POINTER_POINTER_POINTER_UINT_UINT(PurpleCallback cb,
766 va_list args,
767 void *data,
768 void **return_val)
769 {
770 void *arg1 = va_arg(args, void *);
771 void *arg2 = va_arg(args, void *);
772 void *arg3 = va_arg(args, void *);
773 guint arg4 = va_arg(args, guint);
774 guint arg5 = va_arg(args, guint);
775
776 ((void (*)(void *, void *, void *, guint, guint, void *))cb)(
777 arg1, arg2, arg3, arg4, arg5, data);
778 }
779
780 void
purple_marshal_INT__INT(PurpleCallback cb,va_list args,void * data,void ** return_val)781 purple_marshal_INT__INT(PurpleCallback cb, va_list args, void *data,
782 void **return_val)
783 {
784 gint ret_val;
785 gint arg1 = va_arg(args, gint);
786
787 ret_val = ((gint (*)(gint, void *))cb)(arg1, data);
788
789 if (return_val != NULL)
790 *return_val = GINT_TO_POINTER(ret_val);
791 }
792
793 void
purple_marshal_INT__INT_INT(PurpleCallback cb,va_list args,void * data,void ** return_val)794 purple_marshal_INT__INT_INT(PurpleCallback cb, va_list args, void *data,
795 void **return_val)
796 {
797 gint ret_val;
798 gint arg1 = va_arg(args, gint);
799 gint arg2 = va_arg(args, gint);
800
801 ret_val = ((gint (*)(gint, gint, void *))cb)(arg1, arg2, data);
802
803 if (return_val != NULL)
804 *return_val = GINT_TO_POINTER(ret_val);
805 }
806
807 void
purple_marshal_INT__POINTER_POINTER(PurpleCallback cb,va_list args,void * data,void ** return_val)808 purple_marshal_INT__POINTER_POINTER(PurpleCallback cb, va_list args, void *data,
809 void **return_val)
810 {
811 gint ret_val;
812 void *arg1 = va_arg(args, void *);
813 void *arg2 = va_arg(args, void *);
814
815 ret_val = ((gint (*)(void *, void *, void *))cb)(arg1, arg2, data);
816
817 if (return_val != NULL)
818 *return_val = GINT_TO_POINTER(ret_val);
819 }
820
821 void
purple_marshal_INT__POINTER_POINTER_POINTER(PurpleCallback cb,va_list args,void * data,void ** return_val)822 purple_marshal_INT__POINTER_POINTER_POINTER(
823 PurpleCallback cb, va_list args, void *data, void **return_val)
824 {
825 gint ret_val;
826 void *arg1 = va_arg(args, void *);
827 void *arg2 = va_arg(args, void *);
828 void *arg3 = va_arg(args, void *);
829
830 ret_val = ((gint (*)(void *, void *, void *, void *))cb)(arg1, arg2, arg3, data);
831
832 if (return_val != NULL)
833 *return_val = GINT_TO_POINTER(ret_val);
834 }
835
836 void
purple_marshal_INT__POINTER_POINTER_POINTER_POINTER_POINTER(PurpleCallback cb,va_list args,void * data,void ** return_val)837 purple_marshal_INT__POINTER_POINTER_POINTER_POINTER_POINTER(
838 PurpleCallback cb, va_list args, void *data, void **return_val)
839 {
840 gint ret_val;
841 void *arg1 = va_arg(args, void *);
842 void *arg2 = va_arg(args, void *);
843 void *arg3 = va_arg(args, void *);
844 void *arg4 = va_arg(args, void *);
845 void *arg5 = va_arg(args, void *);
846
847 ret_val =
848 ((gint (*)(void *, void *, void *, void *, void *, void *))cb)(
849 arg1, arg2, arg3, arg4, arg5, data);
850
851 if (return_val != NULL)
852 *return_val = GINT_TO_POINTER(ret_val);
853 }
854
855 void
purple_marshal_BOOLEAN__POINTER(PurpleCallback cb,va_list args,void * data,void ** return_val)856 purple_marshal_BOOLEAN__POINTER(PurpleCallback cb, va_list args, void *data,
857 void **return_val)
858 {
859 gboolean ret_val;
860 void *arg1 = va_arg(args, void *);
861
862 ret_val = ((gboolean (*)(void *, void *))cb)(arg1, data);
863
864 if (return_val != NULL)
865 *return_val = GINT_TO_POINTER(ret_val);
866 }
867
868 void
purple_marshal_BOOLEAN__POINTER_POINTER(PurpleCallback cb,va_list args,void * data,void ** return_val)869 purple_marshal_BOOLEAN__POINTER_POINTER(PurpleCallback cb, va_list args,
870 void *data, void **return_val)
871 {
872 gboolean ret_val;
873 void *arg1 = va_arg(args, void *);
874 void *arg2 = va_arg(args, void *);
875
876 ret_val = ((gboolean (*)(void *, void *, void *))cb)(arg1, arg2, data);
877
878 if (return_val != NULL)
879 *return_val = GINT_TO_POINTER(ret_val);
880 }
881
882 void
purple_marshal_BOOLEAN__POINTER_BOOLEAN(PurpleCallback cb,va_list args,void * data,void ** return_val)883 purple_marshal_BOOLEAN__POINTER_BOOLEAN(PurpleCallback cb, va_list args,
884 void *data, void **return_val)
885 {
886 gboolean ret_val;
887 void *arg1 = va_arg(args, void *);
888 gboolean arg2 = va_arg(args, gboolean);
889
890 ret_val = ((gboolean (*)(void *, gboolean, void *))cb)(arg1, arg2, data);
891
892 if (return_val != NULL)
893 *return_val = GINT_TO_POINTER(ret_val);
894 }
895
896 void
purple_marshal_BOOLEAN__POINTER_POINTER_POINTER(PurpleCallback cb,va_list args,void * data,void ** return_val)897 purple_marshal_BOOLEAN__POINTER_POINTER_POINTER(PurpleCallback cb, va_list args,
898 void *data, void **return_val)
899 {
900 gboolean ret_val;
901 void *arg1 = va_arg(args, void *);
902 void *arg2 = va_arg(args, void *);
903 void *arg3 = va_arg(args, void *);
904
905 ret_val = ((gboolean (*)(void *, void *, void *, void *))cb)(arg1, arg2,
906 arg3, data);
907
908 if (return_val != NULL)
909 *return_val = GINT_TO_POINTER(ret_val);
910 }
911
912 void
purple_marshal_BOOLEAN__POINTER_POINTER_UINT(PurpleCallback cb,va_list args,void * data,void ** return_val)913 purple_marshal_BOOLEAN__POINTER_POINTER_UINT(PurpleCallback cb,
914 va_list args,
915 void *data,
916 void **return_val)
917 {
918 gboolean ret_val;
919 void *arg1 = va_arg(args, void *);
920 void *arg2 = va_arg(args, void *);
921 guint arg3 = va_arg(args, guint);
922
923 ret_val = ((gboolean (*)(void *, void *, guint, void *))cb)(
924 arg1, arg2, arg3, data);
925
926 if (return_val != NULL)
927 *return_val = GINT_TO_POINTER(ret_val);
928 }
929
930 void
purple_marshal_BOOLEAN__POINTER_POINTER_POINTER_UINT(PurpleCallback cb,va_list args,void * data,void ** return_val)931 purple_marshal_BOOLEAN__POINTER_POINTER_POINTER_UINT(PurpleCallback cb,
932 va_list args,
933 void *data,
934 void **return_val)
935 {
936 gboolean ret_val;
937 void *arg1 = va_arg(args, void *);
938 void *arg2 = va_arg(args, void *);
939 void *arg3 = va_arg(args, void *);
940 guint arg4 = va_arg(args, guint);
941
942 ret_val = ((gboolean (*)(void *, void *, void *, guint, void *))cb)(
943 arg1, arg2, arg3, arg4, data);
944
945 if (return_val != NULL)
946 *return_val = GINT_TO_POINTER(ret_val);
947 }
948
949 void
purple_marshal_BOOLEAN__POINTER_POINTER_POINTER_POINTER(PurpleCallback cb,va_list args,void * data,void ** return_val)950 purple_marshal_BOOLEAN__POINTER_POINTER_POINTER_POINTER(PurpleCallback cb,
951 va_list args,
952 void *data,
953 void **return_val)
954 {
955 gboolean ret_val;
956 void *arg1 = va_arg(args, void *);
957 void *arg2 = va_arg(args, void *);
958 void *arg3 = va_arg(args, void *);
959 void *arg4 = va_arg(args, void *);
960
961 ret_val = ((gboolean (*)(void *, void *, void *, void *, void *))cb)(
962 arg1, arg2, arg3, arg4, data);
963
964 if (return_val != NULL)
965 *return_val = GINT_TO_POINTER(ret_val);
966 }
967
968 void
purple_marshal_BOOLEAN__POINTER_POINTER_POINTER_POINTER_POINTER(PurpleCallback cb,va_list args,void * data,void ** return_val)969 purple_marshal_BOOLEAN__POINTER_POINTER_POINTER_POINTER_POINTER(
970 PurpleCallback cb, va_list args, void *data, void **return_val)
971 {
972 gboolean ret_val;
973 void *arg1 = va_arg(args, void *);
974 void *arg2 = va_arg(args, void *);
975 void *arg3 = va_arg(args, void *);
976 void *arg4 = va_arg(args, void *);
977 void *arg5 = va_arg(args, void *);
978
979 ret_val =
980 ((gboolean (*)(void *, void *, void *, void *, void *, void *))cb)(
981 arg1, arg2, arg3, arg4, arg5, data);
982
983 if (return_val != NULL)
984 *return_val = GINT_TO_POINTER(ret_val);
985 }
986
987 void
purple_marshal_BOOLEAN__POINTER_POINTER_POINTER_POINTER_UINT(PurpleCallback cb,va_list args,void * data,void ** return_val)988 purple_marshal_BOOLEAN__POINTER_POINTER_POINTER_POINTER_UINT(
989 PurpleCallback cb, va_list args, void *data, void **return_val)
990 {
991 gboolean ret_val;
992 void *arg1 = va_arg(args, void *);
993 void *arg2 = va_arg(args, void *);
994 void *arg3 = va_arg(args, void *);
995 void *arg4 = va_arg(args, void *);
996 guint arg5 = va_arg(args, guint);
997
998 ret_val =
999 ((gboolean (*)(void *, void *, void *, void *, guint, void *))cb)(
1000 arg1, arg2, arg3, arg4, arg5, data);
1001
1002 if (return_val != NULL)
1003 *return_val = GINT_TO_POINTER(ret_val);
1004 }
1005
1006 void
purple_marshal_BOOLEAN__POINTER_POINTER_POINTER_POINTER_POINTER_POINTER(PurpleCallback cb,va_list args,void * data,void ** return_val)1007 purple_marshal_BOOLEAN__POINTER_POINTER_POINTER_POINTER_POINTER_POINTER(
1008 PurpleCallback cb, va_list args, void *data, void **return_val)
1009 {
1010 gboolean ret_val;
1011 void *arg1 = va_arg(args, void *);
1012 void *arg2 = va_arg(args, void *);
1013 void *arg3 = va_arg(args, void *);
1014 void *arg4 = va_arg(args, void *);
1015 void *arg5 = va_arg(args, void *);
1016 void *arg6 = va_arg(args, void *);
1017
1018 ret_val =
1019 ((gboolean (*)(void *, void *, void *, void *, void *, void *, void *))cb)(
1020 arg1, arg2, arg3, arg4, arg5, arg6, data);
1021
1022 if (return_val != NULL)
1023 *return_val = GINT_TO_POINTER(ret_val);
1024 }
1025
1026 void
purple_marshal_BOOLEAN__INT_POINTER(PurpleCallback cb,va_list args,void * data,void ** return_val)1027 purple_marshal_BOOLEAN__INT_POINTER(PurpleCallback cb, va_list args, void *data,
1028 void **return_val)
1029 {
1030 gboolean ret_val;
1031 gint arg1 = va_arg(args, gint);
1032 void *arg2 = va_arg(args, void *);
1033
1034 ret_val = ((gboolean (*)(gint, void *, void *))cb)(arg1, arg2, data);
1035
1036 if (return_val != NULL)
1037 *return_val = GINT_TO_POINTER(ret_val);
1038 }
1039
1040 void
purple_marshal_POINTER__POINTER(PurpleCallback cb,va_list args,void * data,void ** return_val)1041 purple_marshal_POINTER__POINTER(
1042 PurpleCallback cb, va_list args, void *data,
1043 void **return_val)
1044 {
1045 gpointer ret_val;
1046 void *arg1 = va_arg(args, void *);
1047
1048 ret_val = ((gpointer(*)(void *, void *))cb)(arg1, data);
1049
1050 if (return_val != NULL)
1051 *return_val = ret_val;
1052 }
1053
1054
1055 void
purple_marshal_POINTER__POINTER_INT(PurpleCallback cb,va_list args,void * data,void ** return_val)1056 purple_marshal_POINTER__POINTER_INT(
1057 PurpleCallback cb, va_list args, void *data,
1058 void **return_val)
1059 {
1060 gpointer ret_val;
1061 void *arg1 = va_arg(args, void *);
1062 gint arg2 = va_arg(args, gint);
1063
1064 ret_val = ((gpointer(*)(void *, gint, void *))cb)(arg1, arg2, data);
1065
1066 if (return_val != NULL)
1067 *return_val = ret_val;
1068 }
1069
1070 void
purple_marshal_POINTER__POINTER_INT64(PurpleCallback cb,va_list args,void * data,void ** return_val)1071 purple_marshal_POINTER__POINTER_INT64(
1072 PurpleCallback cb, va_list args, void *data,
1073 void **return_val)
1074 {
1075 gpointer ret_val;
1076 void *arg1 = va_arg(args, void *);
1077 gint64 arg2 = va_arg(args, gint64);
1078
1079 ret_val = ((gpointer(*)(void *, gint64, void *))cb)(arg1, arg2, data);
1080
1081 if (return_val != NULL)
1082 *return_val = ret_val;
1083 }
1084
1085 void
purple_marshal_POINTER__POINTER_INT_BOOLEAN(PurpleCallback cb,va_list args,void * data,void ** return_val)1086 purple_marshal_POINTER__POINTER_INT_BOOLEAN(
1087 PurpleCallback cb, va_list args, void *data,
1088 void **return_val)
1089 {
1090 gpointer ret_val;
1091 void *arg1 = va_arg(args, void *);
1092 gint arg2 = va_arg(args, gint);
1093 gboolean arg3 = va_arg(args, gboolean);
1094
1095 ret_val = ((gpointer(*)(void *, gint, gboolean, void *))cb)(arg1, arg2, arg3, data);
1096
1097 if (return_val != NULL)
1098 *return_val = ret_val;
1099 }
1100
1101 void
purple_marshal_POINTER__POINTER_INT64_BOOLEAN(PurpleCallback cb,va_list args,void * data,void ** return_val)1102 purple_marshal_POINTER__POINTER_INT64_BOOLEAN(
1103 PurpleCallback cb, va_list args, void *data,
1104 void **return_val)
1105 {
1106 gpointer ret_val;
1107 void *arg1 = va_arg(args, void *);
1108 gint64 arg2 = va_arg(args, gint64);
1109 gboolean arg3 = va_arg(args, gboolean);
1110
1111 ret_val = ((gpointer(*)(void *, gint64, gboolean, void *))cb)(arg1, arg2, arg3, data);
1112
1113 if (return_val != NULL)
1114 *return_val = ret_val;
1115 }
1116
1117 void
purple_marshal_POINTER__POINTER_POINTER(PurpleCallback cb,va_list args,void * data,void ** return_val)1118 purple_marshal_POINTER__POINTER_POINTER(PurpleCallback cb, va_list args, void *data,
1119 void **return_val)
1120 {
1121 gpointer ret_val;
1122 void *arg1 = va_arg(args, void *);
1123 void *arg2 = va_arg(args, void *);
1124
1125 ret_val = ((gpointer (*)(void *, void *, void *))cb)(arg1, arg2, data);
1126
1127 if (return_val != NULL)
1128 *return_val = ret_val;
1129 }
1130