| 1 /** |
|
| 2 * @file signals.c Signal API |
|
| 3 * @ingroup core |
|
| 4 * |
|
| 5 * gaim |
|
| 6 * |
|
| 7 * Gaim is the legal property of its developers, whose names are too numerous |
|
| 8 * to list here. Please refer to the COPYRIGHT file distributed with this |
|
| 9 * source distribution. |
|
| 10 * |
|
| 11 * This program is free software; you can redistribute it and/or modify |
|
| 12 * it under the terms of the GNU General Public License as published by |
|
| 13 * the Free Software Foundation; either version 2 of the License, or |
|
| 14 * (at your option) any later version. |
|
| 15 * |
|
| 16 * This program is distributed in the hope that it will be useful, |
|
| 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
| 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
| 19 * GNU General Public License for more details. |
|
| 20 * |
|
| 21 * You should have received a copy of the GNU General Public License |
|
| 22 * along with this program; if not, write to the Free Software |
|
| 23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|
| 24 */ |
|
| 25 #include "internal.h" |
|
| 26 |
|
| 27 #include "dbus-maybe.h" |
|
| 28 #include "debug.h" |
|
| 29 #include "signals.h" |
|
| 30 #include "value.h" |
|
| 31 |
|
| 32 /* must include this to use G_VA_COPY */ |
|
| 33 #include <string.h> |
|
| 34 |
|
| 35 typedef struct |
|
| 36 { |
|
| 37 void *instance; |
|
| 38 |
|
| 39 GHashTable *signals; |
|
| 40 size_t signal_count; |
|
| 41 |
|
| 42 gulong next_signal_id; |
|
| 43 |
|
| 44 } GaimInstanceData; |
|
| 45 |
|
| 46 typedef struct |
|
| 47 { |
|
| 48 gulong id; |
|
| 49 |
|
| 50 GaimSignalMarshalFunc marshal; |
|
| 51 |
|
| 52 int num_values; |
|
| 53 GaimValue **values; |
|
| 54 GaimValue *ret_value; |
|
| 55 |
|
| 56 GList *handlers; |
|
| 57 size_t handler_count; |
|
| 58 |
|
| 59 gulong next_handler_id; |
|
| 60 } GaimSignalData; |
|
| 61 |
|
| 62 typedef struct |
|
| 63 { |
|
| 64 gulong id; |
|
| 65 GaimCallback cb; |
|
| 66 void *handle; |
|
| 67 void *data; |
|
| 68 gboolean use_vargs; |
|
| 69 int priority; |
|
| 70 |
|
| 71 } GaimSignalHandlerData; |
|
| 72 |
|
| 73 static GHashTable *instance_table = NULL; |
|
| 74 |
|
| 75 static void |
|
| 76 destroy_instance_data(GaimInstanceData *instance_data) |
|
| 77 { |
|
| 78 g_hash_table_destroy(instance_data->signals); |
|
| 79 |
|
| 80 g_free(instance_data); |
|
| 81 } |
|
| 82 |
|
| 83 static void |
|
| 84 destroy_signal_data(GaimSignalData *signal_data) |
|
| 85 { |
|
| 86 g_list_foreach(signal_data->handlers, (GFunc)g_free, NULL); |
|
| 87 g_list_free(signal_data->handlers); |
|
| 88 |
|
| 89 if (signal_data->values != NULL) |
|
| 90 { |
|
| 91 int i; |
|
| 92 |
|
| 93 for (i = 0; i < signal_data->num_values; i++) |
|
| 94 gaim_value_destroy((GaimValue *)signal_data->values[i]); |
|
| 95 |
|
| 96 g_free(signal_data->values); |
|
| 97 } |
|
| 98 |
|
| 99 if (signal_data->ret_value != NULL) |
|
| 100 gaim_value_destroy(signal_data->ret_value); |
|
| 101 g_free(signal_data); |
|
| 102 } |
|
| 103 |
|
| 104 gulong |
|
| 105 gaim_signal_register(void *instance, const char *signal, |
|
| 106 GaimSignalMarshalFunc marshal, |
|
| 107 GaimValue *ret_value, int num_values, ...) |
|
| 108 { |
|
| 109 GaimInstanceData *instance_data; |
|
| 110 GaimSignalData *signal_data; |
|
| 111 va_list args; |
|
| 112 |
|
| 113 g_return_val_if_fail(instance != NULL, 0); |
|
| 114 g_return_val_if_fail(signal != NULL, 0); |
|
| 115 g_return_val_if_fail(marshal != NULL, 0); |
|
| 116 |
|
| 117 instance_data = |
|
| 118 (GaimInstanceData *)g_hash_table_lookup(instance_table, instance); |
|
| 119 |
|
| 120 if (instance_data == NULL) |
|
| 121 { |
|
| 122 instance_data = g_new0(GaimInstanceData, 1); |
|
| 123 |
|
| 124 instance_data->instance = instance; |
|
| 125 instance_data->next_signal_id = 1; |
|
| 126 |
|
| 127 instance_data->signals = |
|
| 128 g_hash_table_new_full(g_str_hash, g_str_equal, g_free, |
|
| 129 (GDestroyNotify)destroy_signal_data); |
|
| 130 |
|
| 131 g_hash_table_insert(instance_table, instance, instance_data); |
|
| 132 } |
|
| 133 |
|
| 134 signal_data = g_new0(GaimSignalData, 1); |
|
| 135 signal_data->id = instance_data->next_signal_id; |
|
| 136 signal_data->marshal = marshal; |
|
| 137 signal_data->next_handler_id = 1; |
|
| 138 signal_data->ret_value = ret_value; |
|
| 139 signal_data->num_values = num_values; |
|
| 140 |
|
| 141 if (num_values > 0) |
|
| 142 { |
|
| 143 int i; |
|
| 144 |
|
| 145 signal_data->values = g_new0(GaimValue *, num_values); |
|
| 146 |
|
| 147 va_start(args, num_values); |
|
| 148 |
|
| 149 for (i = 0; i < num_values; i++) |
|
| 150 signal_data->values[i] = va_arg(args, GaimValue *); |
|
| 151 |
|
| 152 va_end(args); |
|
| 153 } |
|
| 154 |
|
| 155 g_hash_table_insert(instance_data->signals, |
|
| 156 g_strdup(signal), signal_data); |
|
| 157 |
|
| 158 instance_data->next_signal_id++; |
|
| 159 instance_data->signal_count++; |
|
| 160 |
|
| 161 return signal_data->id; |
|
| 162 } |
|
| 163 |
|
| 164 void |
|
| 165 gaim_signal_unregister(void *instance, const char *signal) |
|
| 166 { |
|
| 167 GaimInstanceData *instance_data; |
|
| 168 |
|
| 169 g_return_if_fail(instance != NULL); |
|
| 170 g_return_if_fail(signal != NULL); |
|
| 171 |
|
| 172 instance_data = |
|
| 173 (GaimInstanceData *)g_hash_table_lookup(instance_table, instance); |
|
| 174 |
|
| 175 g_return_if_fail(instance_data != NULL); |
|
| 176 |
|
| 177 g_hash_table_remove(instance_data->signals, signal); |
|
| 178 |
|
| 179 instance_data->signal_count--; |
|
| 180 |
|
| 181 if (instance_data->signal_count == 0) |
|
| 182 { |
|
| 183 /* Unregister the instance. */ |
|
| 184 g_hash_table_remove(instance_table, instance); |
|
| 185 } |
|
| 186 } |
|
| 187 |
|
| 188 void |
|
| 189 gaim_signals_unregister_by_instance(void *instance) |
|
| 190 { |
|
| 191 gboolean found; |
|
| 192 |
|
| 193 g_return_if_fail(instance != NULL); |
|
| 194 |
|
| 195 found = g_hash_table_remove(instance_table, instance); |
|
| 196 |
|
| 197 /* |
|
| 198 * Makes things easier (more annoying?) for developers who don't have |
|
| 199 * things registering and unregistering in the right order :) |
|
| 200 */ |
|
| 201 g_return_if_fail(found); |
|
| 202 } |
|
| 203 |
|
| 204 void |
|
| 205 gaim_signal_get_values(void *instance, const char *signal, |
|
| 206 GaimValue **ret_value, |
|
| 207 int *num_values, GaimValue ***values) |
|
| 208 { |
|
| 209 GaimInstanceData *instance_data; |
|
| 210 GaimSignalData *signal_data; |
|
| 211 |
|
| 212 g_return_if_fail(instance != NULL); |
|
| 213 g_return_if_fail(signal != NULL); |
|
| 214 g_return_if_fail(num_values != NULL); |
|
| 215 g_return_if_fail(values != NULL); |
|
| 216 |
|
| 217 /* Get the instance data */ |
|
| 218 instance_data = |
|
| 219 (GaimInstanceData *)g_hash_table_lookup(instance_table, instance); |
|
| 220 |
|
| 221 g_return_if_fail(instance_data != NULL); |
|
| 222 |
|
| 223 /* Get the signal data */ |
|
| 224 signal_data = |
|
| 225 (GaimSignalData *)g_hash_table_lookup(instance_data->signals, signal); |
|
| 226 |
|
| 227 g_return_if_fail(signal_data != NULL); |
|
| 228 |
|
| 229 *num_values = signal_data->num_values; |
|
| 230 *values = signal_data->values; |
|
| 231 |
|
| 232 if (ret_value != NULL) |
|
| 233 *ret_value = signal_data->ret_value; |
|
| 234 } |
|
| 235 |
|
| 236 static gint handler_priority(void * a, void * b) { |
|
| 237 GaimSignalHandlerData *ah = (GaimSignalHandlerData*)a; |
|
| 238 GaimSignalHandlerData *bh = (GaimSignalHandlerData*)b; |
|
| 239 if (ah->priority > bh->priority) return 1; |
|
| 240 if (ah->priority < bh->priority) return -1; |
|
| 241 return 0; |
|
| 242 } |
|
| 243 |
|
| 244 static gulong |
|
| 245 signal_connect_common(void *instance, const char *signal, void *handle, |
|
| 246 GaimCallback func, void *data, int priority, gboolean use_vargs) |
|
| 247 { |
|
| 248 GaimInstanceData *instance_data; |
|
| 249 GaimSignalData *signal_data; |
|
| 250 GaimSignalHandlerData *handler_data; |
|
| 251 |
|
| 252 g_return_val_if_fail(instance != NULL, 0); |
|
| 253 g_return_val_if_fail(signal != NULL, 0); |
|
| 254 g_return_val_if_fail(handle != NULL, 0); |
|
| 255 g_return_val_if_fail(func != NULL, 0); |
|
| 256 |
|
| 257 /* Get the instance data */ |
|
| 258 instance_data = |
|
| 259 (GaimInstanceData *)g_hash_table_lookup(instance_table, instance); |
|
| 260 |
|
| 261 if (instance_data == NULL) |
|
| 262 { |
|
| 263 gaim_debug_warning("signals", "Something tried to register a callback " |
|
| 264 "for the '%s' signal, but we do not have any signals " |
|
| 265 "registered with the given handle\n", signal); |
|
| 266 g_return_val_if_reached(0); |
|
| 267 } |
|
| 268 |
|
| 269 /* Get the signal data */ |
|
| 270 signal_data = |
|
| 271 (GaimSignalData *)g_hash_table_lookup(instance_data->signals, signal); |
|
| 272 |
|
| 273 if (signal_data == NULL) |
|
| 274 { |
|
| 275 gaim_debug(GAIM_DEBUG_ERROR, "signals", |
|
| 276 "Signal data for %s not found!\n", signal); |
|
| 277 return 0; |
|
| 278 } |
|
| 279 |
|
| 280 /* Create the signal handler data */ |
|
| 281 handler_data = g_new0(GaimSignalHandlerData, 1); |
|
| 282 handler_data->id = signal_data->next_handler_id; |
|
| 283 handler_data->cb = func; |
|
| 284 handler_data->handle = handle; |
|
| 285 handler_data->data = data; |
|
| 286 handler_data->use_vargs = use_vargs; |
|
| 287 handler_data->priority = priority; |
|
| 288 |
|
| 289 signal_data->handlers = g_list_insert_sorted(signal_data->handlers, handler_data, (GCompareFunc)handler_priority); |
|
| 290 signal_data->handler_count++; |
|
| 291 signal_data->next_handler_id++; |
|
| 292 |
|
| 293 return handler_data->id; |
|
| 294 } |
|
| 295 |
|
| 296 gulong |
|
| 297 gaim_signal_connect_priority(void *instance, const char *signal, void *handle, |
|
| 298 GaimCallback func, void *data, int priority) |
|
| 299 { |
|
| 300 return signal_connect_common(instance, signal, handle, func, data, priority, FALSE); |
|
| 301 } |
|
| 302 |
|
| 303 gulong |
|
| 304 gaim_signal_connect(void *instance, const char *signal, void *handle, |
|
| 305 GaimCallback func, void *data) |
|
| 306 { |
|
| 307 return signal_connect_common(instance, signal, handle, func, data, GAIM_SIGNAL_PRIORITY_DEFAULT, FALSE); |
|
| 308 } |
|
| 309 |
|
| 310 gulong |
|
| 311 gaim_signal_connect_priority_vargs(void *instance, const char *signal, void *handle, |
|
| 312 GaimCallback func, void *data, int priority) |
|
| 313 { |
|
| 314 return signal_connect_common(instance, signal, handle, func, data, priority, TRUE); |
|
| 315 } |
|
| 316 |
|
| 317 gulong |
|
| 318 gaim_signal_connect_vargs(void *instance, const char *signal, void *handle, |
|
| 319 GaimCallback func, void *data) |
|
| 320 { |
|
| 321 return signal_connect_common(instance, signal, handle, func, data, GAIM_SIGNAL_PRIORITY_DEFAULT, TRUE); |
|
| 322 } |
|
| 323 |
|
| 324 void |
|
| 325 gaim_signal_disconnect(void *instance, const char *signal, |
|
| 326 void *handle, GaimCallback func) |
|
| 327 { |
|
| 328 GaimInstanceData *instance_data; |
|
| 329 GaimSignalData *signal_data; |
|
| 330 GaimSignalHandlerData *handler_data; |
|
| 331 GList *l; |
|
| 332 gboolean found = FALSE; |
|
| 333 |
|
| 334 g_return_if_fail(instance != NULL); |
|
| 335 g_return_if_fail(signal != NULL); |
|
| 336 g_return_if_fail(handle != NULL); |
|
| 337 g_return_if_fail(func != NULL); |
|
| 338 |
|
| 339 /* Get the instance data */ |
|
| 340 instance_data = |
|
| 341 (GaimInstanceData *)g_hash_table_lookup(instance_table, instance); |
|
| 342 |
|
| 343 g_return_if_fail(instance_data != NULL); |
|
| 344 |
|
| 345 /* Get the signal data */ |
|
| 346 signal_data = |
|
| 347 (GaimSignalData *)g_hash_table_lookup(instance_data->signals, signal); |
|
| 348 |
|
| 349 if (signal_data == NULL) |
|
| 350 { |
|
| 351 gaim_debug(GAIM_DEBUG_ERROR, "signals", |
|
| 352 "Signal data for %s not found!\n", signal); |
|
| 353 return; |
|
| 354 } |
|
| 355 |
|
| 356 /* Find the handler data. */ |
|
| 357 for (l = signal_data->handlers; l != NULL; l = l->next) |
|
| 358 { |
|
| 359 handler_data = (GaimSignalHandlerData *)l->data; |
|
| 360 |
|
| 361 if (handler_data->handle == handle && handler_data->cb == func) |
|
| 362 { |
|
| 363 g_free(handler_data); |
|
| 364 |
|
| 365 signal_data->handlers = g_list_remove(signal_data->handlers, |
|
| 366 handler_data); |
|
| 367 signal_data->handler_count--; |
|
| 368 |
|
| 369 found = TRUE; |
|
| 370 |
|
| 371 break; |
|
| 372 } |
|
| 373 } |
|
| 374 |
|
| 375 /* See note somewhere about this actually helping developers.. */ |
|
| 376 g_return_if_fail(found); |
|
| 377 } |
|
| 378 |
|
| 379 /* |
|
| 380 * TODO: Make this all more efficient by storing a list of handlers, keyed |
|
| 381 * to a handle. |
|
| 382 */ |
|
| 383 static void |
|
| 384 disconnect_handle_from_signals(const char *signal, |
|
| 385 GaimSignalData *signal_data, void *handle) |
|
| 386 { |
|
| 387 GList *l, *l_next; |
|
| 388 GaimSignalHandlerData *handler_data; |
|
| 389 |
|
| 390 for (l = signal_data->handlers; l != NULL; l = l_next) |
|
| 391 { |
|
| 392 handler_data = (GaimSignalHandlerData *)l->data; |
|
| 393 l_next = l->next; |
|
| 394 |
|
| 395 if (handler_data->handle == handle) |
|
| 396 { |
|
| 397 g_free(handler_data); |
|
| 398 |
|
| 399 signal_data->handler_count--; |
|
| 400 signal_data->handlers = g_list_remove(signal_data->handlers, |
|
| 401 handler_data); |
|
| 402 } |
|
| 403 } |
|
| 404 } |
|
| 405 |
|
| 406 static void |
|
| 407 disconnect_handle_from_instance(void *instance, |
|
| 408 GaimInstanceData *instance_data, |
|
| 409 void *handle) |
|
| 410 { |
|
| 411 g_hash_table_foreach(instance_data->signals, |
|
| 412 (GHFunc)disconnect_handle_from_signals, handle); |
|
| 413 } |
|
| 414 |
|
| 415 void |
|
| 416 gaim_signals_disconnect_by_handle(void *handle) |
|
| 417 { |
|
| 418 g_return_if_fail(handle != NULL); |
|
| 419 |
|
| 420 g_hash_table_foreach(instance_table, |
|
| 421 (GHFunc)disconnect_handle_from_instance, handle); |
|
| 422 } |
|
| 423 |
|
| 424 void |
|
| 425 gaim_signal_emit(void *instance, const char *signal, ...) |
|
| 426 { |
|
| 427 va_list args; |
|
| 428 |
|
| 429 g_return_if_fail(instance != NULL); |
|
| 430 g_return_if_fail(signal != NULL); |
|
| 431 |
|
| 432 va_start(args, signal); |
|
| 433 gaim_signal_emit_vargs(instance, signal, args); |
|
| 434 va_end(args); |
|
| 435 } |
|
| 436 |
|
| 437 void |
|
| 438 gaim_signal_emit_vargs(void *instance, const char *signal, va_list args) |
|
| 439 { |
|
| 440 GaimInstanceData *instance_data; |
|
| 441 GaimSignalData *signal_data; |
|
| 442 GaimSignalHandlerData *handler_data; |
|
| 443 GList *l, *l_next; |
|
| 444 va_list tmp; |
|
| 445 |
|
| 446 g_return_if_fail(instance != NULL); |
|
| 447 g_return_if_fail(signal != NULL); |
|
| 448 |
|
| 449 instance_data = |
|
| 450 (GaimInstanceData *)g_hash_table_lookup(instance_table, instance); |
|
| 451 |
|
| 452 g_return_if_fail(instance_data != NULL); |
|
| 453 |
|
| 454 signal_data = |
|
| 455 (GaimSignalData *)g_hash_table_lookup(instance_data->signals, signal); |
|
| 456 |
|
| 457 if (signal_data == NULL) |
|
| 458 { |
|
| 459 gaim_debug(GAIM_DEBUG_ERROR, "signals", |
|
| 460 "Signal data for %s not found!\n", signal); |
|
| 461 return; |
|
| 462 } |
|
| 463 |
|
| 464 for (l = signal_data->handlers; l != NULL; l = l_next) |
|
| 465 { |
|
| 466 l_next = l->next; |
|
| 467 |
|
| 468 handler_data = (GaimSignalHandlerData *)l->data; |
|
| 469 |
|
| 470 /* This is necessary because a va_list may only be |
|
| 471 * evaluated once */ |
|
| 472 G_VA_COPY(tmp, args); |
|
| 473 |
|
| 474 if (handler_data->use_vargs) |
|
| 475 { |
|
| 476 ((void (*)(va_list, void *))handler_data->cb)(tmp, |
|
| 477 handler_data->data); |
|
| 478 } |
|
| 479 else |
|
| 480 { |
|
| 481 signal_data->marshal(handler_data->cb, tmp, |
|
| 482 handler_data->data, NULL); |
|
| 483 } |
|
| 484 |
|
| 485 va_end(tmp); |
|
| 486 } |
|
| 487 |
|
| 488 #ifdef HAVE_DBUS |
|
| 489 gaim_dbus_signal_emit_gaim(signal, signal_data->num_values, |
|
| 490 signal_data->values, args); |
|
| 491 #endif /* HAVE_DBUS */ |
|
| 492 |
|
| 493 } |
|
| 494 |
|
| 495 void * |
|
| 496 gaim_signal_emit_return_1(void *instance, const char *signal, ...) |
|
| 497 { |
|
| 498 void *ret_val; |
|
| 499 va_list args; |
|
| 500 |
|
| 501 g_return_val_if_fail(instance != NULL, NULL); |
|
| 502 g_return_val_if_fail(signal != NULL, NULL); |
|
| 503 |
|
| 504 va_start(args, signal); |
|
| 505 ret_val = gaim_signal_emit_vargs_return_1(instance, signal, args); |
|
| 506 va_end(args); |
|
| 507 |
|
| 508 return ret_val; |
|
| 509 } |
|
| 510 |
|
| 511 void * |
|
| 512 gaim_signal_emit_vargs_return_1(void *instance, const char *signal, |
|
| 513 va_list args) |
|
| 514 { |
|
| 515 GaimInstanceData *instance_data; |
|
| 516 GaimSignalData *signal_data; |
|
| 517 GaimSignalHandlerData *handler_data; |
|
| 518 GList *l, *l_next; |
|
| 519 va_list tmp; |
|
| 520 |
|
| 521 g_return_val_if_fail(instance != NULL, NULL); |
|
| 522 g_return_val_if_fail(signal != NULL, NULL); |
|
| 523 |
|
| 524 instance_data = |
|
| 525 (GaimInstanceData *)g_hash_table_lookup(instance_table, instance); |
|
| 526 |
|
| 527 g_return_val_if_fail(instance_data != NULL, NULL); |
|
| 528 |
|
| 529 signal_data = |
|
| 530 (GaimSignalData *)g_hash_table_lookup(instance_data->signals, signal); |
|
| 531 |
|
| 532 if (signal_data == NULL) |
|
| 533 { |
|
| 534 gaim_debug(GAIM_DEBUG_ERROR, "signals", |
|
| 535 "Signal data for %s not found!\n", signal); |
|
| 536 return 0; |
|
| 537 } |
|
| 538 |
|
| 539 #ifdef HAVE_DBUS |
|
| 540 G_VA_COPY(tmp, args); |
|
| 541 gaim_dbus_signal_emit_gaim(signal, signal_data->num_values, |
|
| 542 signal_data->values, tmp); |
|
| 543 va_end(tmp); |
|
| 544 #endif /* HAVE_DBUS */ |
|
| 545 |
|
| 546 for (l = signal_data->handlers; l != NULL; l = l_next) |
|
| 547 { |
|
| 548 void *ret_val = NULL; |
|
| 549 |
|
| 550 l_next = l->next; |
|
| 551 |
|
| 552 handler_data = (GaimSignalHandlerData *)l->data; |
|
| 553 |
|
| 554 G_VA_COPY(tmp, args); |
|
| 555 if (handler_data->use_vargs) |
|
| 556 { |
|
| 557 ret_val = ((void *(*)(va_list, void *))handler_data->cb)( |
|
| 558 tmp, handler_data->data); |
|
| 559 } |
|
| 560 else |
|
| 561 { |
|
| 562 signal_data->marshal(handler_data->cb, tmp, |
|
| 563 handler_data->data, &ret_val); |
|
| 564 } |
|
| 565 va_end(tmp); |
|
| 566 |
|
| 567 if (ret_val != NULL) |
|
| 568 return ret_val; |
|
| 569 } |
|
| 570 |
|
| 571 return NULL; |
|
| 572 } |
|
| 573 |
|
| 574 void |
|
| 575 gaim_signals_init() |
|
| 576 { |
|
| 577 g_return_if_fail(instance_table == NULL); |
|
| 578 |
|
| 579 instance_table = |
|
| 580 g_hash_table_new_full(g_direct_hash, g_direct_equal, |
|
| 581 NULL, (GDestroyNotify)destroy_instance_data); |
|
| 582 } |
|
| 583 |
|
| 584 void |
|
| 585 gaim_signals_uninit() |
|
| 586 { |
|
| 587 g_return_if_fail(instance_table != NULL); |
|
| 588 |
|
| 589 g_hash_table_destroy(instance_table); |
|
| 590 instance_table = NULL; |
|
| 591 } |
|
| 592 |
|
| 593 /************************************************************************** |
|
| 594 * Marshallers |
|
| 595 **************************************************************************/ |
|
| 596 void |
|
| 597 gaim_marshal_VOID(GaimCallback cb, va_list args, void *data, |
|
| 598 void **return_val) |
|
| 599 { |
|
| 600 ((void (*)(void *))cb)(data); |
|
| 601 } |
|
| 602 |
|
| 603 void |
|
| 604 gaim_marshal_VOID__INT(GaimCallback cb, va_list args, void *data, |
|
| 605 void **return_val) |
|
| 606 { |
|
| 607 gint arg1 = va_arg(args, gint); |
|
| 608 |
|
| 609 ((void (*)(gint, void *))cb)(arg1, data); |
|
| 610 } |
|
| 611 |
|
| 612 void |
|
| 613 gaim_marshal_VOID__INT_INT(GaimCallback cb, va_list args, void *data, |
|
| 614 void **return_val) |
|
| 615 { |
|
| 616 gint arg1 = va_arg(args, gint); |
|
| 617 gint arg2 = va_arg(args, gint); |
|
| 618 |
|
| 619 ((void (*)(gint, gint, void *))cb)(arg1, arg2, data); |
|
| 620 } |
|
| 621 |
|
| 622 void |
|
| 623 gaim_marshal_VOID__POINTER(GaimCallback cb, va_list args, void *data, |
|
| 624 void **return_val) |
|
| 625 { |
|
| 626 void *arg1 = va_arg(args, void *); |
|
| 627 |
|
| 628 ((void (*)(void *, void *))cb)(arg1, data); |
|
| 629 } |
|
| 630 |
|
| 631 void |
|
| 632 gaim_marshal_VOID__POINTER_UINT(GaimCallback cb, va_list args, |
|
| 633 void *data, void **return_val) |
|
| 634 { |
|
| 635 void *arg1 = va_arg(args, void *); |
|
| 636 guint arg2 = va_arg(args, guint); |
|
| 637 |
|
| 638 ((void (*)(void *, guint, void *))cb)(arg1, arg2, data); |
|
| 639 } |
|
| 640 |
|
| 641 void gaim_marshal_VOID__POINTER_INT_INT(GaimCallback cb, va_list args, |
|
| 642 void *data, void **return_val) |
|
| 643 { |
|
| 644 void *arg1 = va_arg(args, void *); |
|
| 645 gint arg2 = va_arg(args, gint); |
|
| 646 gint arg3 = va_arg(args, gint); |
|
| 647 |
|
| 648 ((void (*)(void *, gint, gint, void *))cb)(arg1, arg2, arg3, data); |
|
| 649 } |
|
| 650 |
|
| 651 void |
|
| 652 gaim_marshal_VOID__POINTER_POINTER(GaimCallback cb, va_list args, |
|
| 653 void *data, void **return_val) |
|
| 654 { |
|
| 655 void *arg1 = va_arg(args, void *); |
|
| 656 void *arg2 = va_arg(args, void *); |
|
| 657 |
|
| 658 ((void (*)(void *, void *, void *))cb)(arg1, arg2, data); |
|
| 659 } |
|
| 660 |
|
| 661 void |
|
| 662 gaim_marshal_VOID__POINTER_POINTER_UINT(GaimCallback cb, va_list args, |
|
| 663 void *data, void **return_val) |
|
| 664 { |
|
| 665 void *arg1 = va_arg(args, void *); |
|
| 666 void *arg2 = va_arg(args, void *); |
|
| 667 guint arg3 = va_arg(args, guint); |
|
| 668 |
|
| 669 ((void (*)(void *, void *, guint, void *))cb)(arg1, arg2, arg3, data); |
|
| 670 } |
|
| 671 |
|
| 672 void |
|
| 673 gaim_marshal_VOID__POINTER_POINTER_UINT_UINT(GaimCallback 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 guint arg4 = va_arg(args, guint); |
|
| 680 |
|
| 681 ((void (*)(void *, void *, guint, guint, void *))cb)(arg1, arg2, arg3, arg4, data); |
|
| 682 } |
|
| 683 |
|
| 684 void |
|
| 685 gaim_marshal_VOID__POINTER_POINTER_POINTER(GaimCallback cb, va_list args, |
|
| 686 void *data, void **return_val) |
|
| 687 { |
|
| 688 void *arg1 = va_arg(args, void *); |
|
| 689 void *arg2 = va_arg(args, void *); |
|
| 690 void *arg3 = va_arg(args, void *); |
|
| 691 |
|
| 692 ((void (*)(void *, void *, void *, void *))cb)(arg1, arg2, arg3, data); |
|
| 693 } |
|
| 694 |
|
| 695 void |
|
| 696 gaim_marshal_VOID__POINTER_POINTER_POINTER_POINTER(GaimCallback cb, |
|
| 697 va_list args, |
|
| 698 void *data, |
|
| 699 void **return_val) |
|
| 700 { |
|
| 701 void *arg1 = va_arg(args, void *); |
|
| 702 void *arg2 = va_arg(args, void *); |
|
| 703 void *arg3 = va_arg(args, void *); |
|
| 704 void *arg4 = va_arg(args, void *); |
|
| 705 |
|
| 706 ((void (*)(void *, void *, void *, void *, void *))cb)(arg1, arg2, arg3, arg4, data); |
|
| 707 } |
|
| 708 |
|
| 709 void |
|
| 710 gaim_marshal_VOID__POINTER_POINTER_POINTER_POINTER_POINTER(GaimCallback cb, |
|
| 711 va_list args, |
|
| 712 void *data, |
|
| 713 void **return_val) |
|
| 714 { |
|
| 715 void *arg1 = va_arg(args, void *); |
|
| 716 void *arg2 = va_arg(args, void *); |
|
| 717 void *arg3 = va_arg(args, void *); |
|
| 718 void *arg4 = va_arg(args, void *); |
|
| 719 void *arg5 = va_arg(args, void *); |
|
| 720 |
|
| 721 ((void (*)(void *, void *, void *, void *, void *, void *))cb)(arg1, arg2, arg3, arg4, arg5, data); |
|
| 722 } |
|
| 723 |
|
| 724 void |
|
| 725 gaim_marshal_VOID__POINTER_POINTER_POINTER_UINT(GaimCallback cb, |
|
| 726 va_list args, |
|
| 727 void *data, |
|
| 728 void **return_val) |
|
| 729 { |
|
| 730 void *arg1 = va_arg(args, void *); |
|
| 731 void *arg2 = va_arg(args, void *); |
|
| 732 void *arg3 = va_arg(args, void *); |
|
| 733 guint arg4 = va_arg(args, guint); |
|
| 734 |
|
| 735 ((void (*)(void *, void *, void *, guint, void *))cb)(arg1, arg2, arg3, arg4, data); |
|
| 736 } |
|
| 737 |
|
| 738 void |
|
| 739 gaim_marshal_VOID__POINTER_POINTER_POINTER_POINTER_UINT(GaimCallback cb, |
|
| 740 va_list args, |
|
| 741 void *data, |
|
| 742 void **return_val) |
|
| 743 { |
|
| 744 void *arg1 = va_arg(args, void *); |
|
| 745 void *arg2 = va_arg(args, void *); |
|
| 746 void *arg3 = va_arg(args, void *); |
|
| 747 void *arg4 = va_arg(args, void *); |
|
| 748 guint arg5 = va_arg(args, guint); |
|
| 749 |
|
| 750 ((void (*)(void *, void *, void *, void *, guint, void *))cb)(arg1, arg2, arg3, arg4, arg5, data); |
|
| 751 } |
|
| 752 |
|
| 753 void |
|
| 754 gaim_marshal_VOID__POINTER_POINTER_POINTER_UINT_UINT(GaimCallback cb, |
|
| 755 va_list args, |
|
| 756 void *data, |
|
| 757 void **return_val) |
|
| 758 { |
|
| 759 void *arg1 = va_arg(args, void *); |
|
| 760 void *arg2 = va_arg(args, void *); |
|
| 761 void *arg3 = va_arg(args, void *); |
|
| 762 guint arg4 = va_arg(args, guint); |
|
| 763 guint arg5 = va_arg(args, guint); |
|
| 764 |
|
| 765 ((void (*)(void *, void *, void *, guint, guint, void *))cb)( |
|
| 766 arg1, arg2, arg3, arg4, arg5, data); |
|
| 767 } |
|
| 768 |
|
| 769 void |
|
| 770 gaim_marshal_INT__INT(GaimCallback cb, va_list args, void *data, |
|
| 771 void **return_val) |
|
| 772 { |
|
| 773 gint ret_val; |
|
| 774 gint arg1 = va_arg(args, gint); |
|
| 775 |
|
| 776 ret_val = ((gint (*)(gint, void *))cb)(arg1, data); |
|
| 777 |
|
| 778 if (return_val != NULL) |
|
| 779 *return_val = GINT_TO_POINTER(ret_val); |
|
| 780 } |
|
| 781 |
|
| 782 void |
|
| 783 gaim_marshal_INT__INT_INT(GaimCallback cb, va_list args, void *data, |
|
| 784 void **return_val) |
|
| 785 { |
|
| 786 gint ret_val; |
|
| 787 gint arg1 = va_arg(args, gint); |
|
| 788 gint arg2 = va_arg(args, gint); |
|
| 789 |
|
| 790 ret_val = ((gint (*)(gint, gint, void *))cb)(arg1, arg2, data); |
|
| 791 |
|
| 792 if (return_val != NULL) |
|
| 793 *return_val = GINT_TO_POINTER(ret_val); |
|
| 794 } |
|
| 795 |
|
| 796 |
|
| 797 void |
|
| 798 gaim_marshal_INT__POINTER_POINTER_POINTER_POINTER_POINTER( |
|
| 799 GaimCallback cb, va_list args, void *data, void **return_val) |
|
| 800 { |
|
| 801 gint ret_val; |
|
| 802 void *arg1 = va_arg(args, void *); |
|
| 803 void *arg2 = va_arg(args, void *); |
|
| 804 void *arg3 = va_arg(args, void *); |
|
| 805 void *arg4 = va_arg(args, void *); |
|
| 806 void *arg5 = va_arg(args, void *); |
|
| 807 |
|
| 808 ret_val = |
|
| 809 ((gint (*)(void *, void *, void *, void *, void *, void *))cb)( |
|
| 810 arg1, arg2, arg3, arg4, arg5, data); |
|
| 811 |
|
| 812 if (return_val != NULL) |
|
| 813 *return_val = GINT_TO_POINTER(ret_val); |
|
| 814 } |
|
| 815 |
|
| 816 void |
|
| 817 gaim_marshal_BOOLEAN__POINTER(GaimCallback cb, va_list args, void *data, |
|
| 818 void **return_val) |
|
| 819 { |
|
| 820 gboolean ret_val; |
|
| 821 void *arg1 = va_arg(args, void *); |
|
| 822 |
|
| 823 ret_val = ((gboolean (*)(void *, void *))cb)(arg1, data); |
|
| 824 |
|
| 825 if (return_val != NULL) |
|
| 826 *return_val = GINT_TO_POINTER(ret_val); |
|
| 827 } |
|
| 828 |
|
| 829 void |
|
| 830 gaim_marshal_BOOLEAN__POINTER_POINTER(GaimCallback cb, va_list args, |
|
| 831 void *data, void **return_val) |
|
| 832 { |
|
| 833 gboolean ret_val; |
|
| 834 void *arg1 = va_arg(args, void *); |
|
| 835 void *arg2 = va_arg(args, void *); |
|
| 836 |
|
| 837 ret_val = ((gboolean (*)(void *, void *, void *))cb)(arg1, arg2, data); |
|
| 838 |
|
| 839 if (return_val != NULL) |
|
| 840 *return_val = GINT_TO_POINTER(ret_val); |
|
| 841 } |
|
| 842 |
|
| 843 void |
|
| 844 gaim_marshal_BOOLEAN__POINTER_POINTER_POINTER(GaimCallback cb, va_list args, |
|
| 845 void *data, void **return_val) |
|
| 846 { |
|
| 847 gboolean ret_val; |
|
| 848 void *arg1 = va_arg(args, void *); |
|
| 849 void *arg2 = va_arg(args, void *); |
|
| 850 void *arg3 = va_arg(args, void *); |
|
| 851 |
|
| 852 ret_val = ((gboolean (*)(void *, void *, void *, void *))cb)(arg1, arg2, |
|
| 853 arg3, data); |
|
| 854 |
|
| 855 if (return_val != NULL) |
|
| 856 *return_val = GINT_TO_POINTER(ret_val); |
|
| 857 } |
|
| 858 |
|
| 859 void |
|
| 860 gaim_marshal_BOOLEAN__POINTER_POINTER_UINT(GaimCallback cb, |
|
| 861 va_list args, |
|
| 862 void *data, |
|
| 863 void **return_val) |
|
| 864 { |
|
| 865 gboolean ret_val; |
|
| 866 void *arg1 = va_arg(args, void *); |
|
| 867 void *arg2 = va_arg(args, void *); |
|
| 868 guint arg3 = va_arg(args, guint); |
|
| 869 |
|
| 870 ret_val = ((gboolean (*)(void *, void *, guint, void *))cb)( |
|
| 871 arg1, arg2, arg3, data); |
|
| 872 |
|
| 873 if (return_val != NULL) |
|
| 874 *return_val = GINT_TO_POINTER(ret_val); |
|
| 875 } |
|
| 876 |
|
| 877 void |
|
| 878 gaim_marshal_BOOLEAN__POINTER_POINTER_POINTER_UINT(GaimCallback cb, |
|
| 879 va_list args, |
|
| 880 void *data, |
|
| 881 void **return_val) |
|
| 882 { |
|
| 883 gboolean ret_val; |
|
| 884 void *arg1 = va_arg(args, void *); |
|
| 885 void *arg2 = va_arg(args, void *); |
|
| 886 void *arg3 = va_arg(args, void *); |
|
| 887 guint arg4 = va_arg(args, guint); |
|
| 888 |
|
| 889 ret_val = ((gboolean (*)(void *, void *, void *, guint, void *))cb)( |
|
| 890 arg1, arg2, arg3, arg4, data); |
|
| 891 |
|
| 892 if (return_val != NULL) |
|
| 893 *return_val = GINT_TO_POINTER(ret_val); |
|
| 894 } |
|
| 895 |
|
| 896 void |
|
| 897 gaim_marshal_BOOLEAN__POINTER_POINTER_POINTER_POINTER(GaimCallback cb, |
|
| 898 va_list args, |
|
| 899 void *data, |
|
| 900 void **return_val) |
|
| 901 { |
|
| 902 gboolean ret_val; |
|
| 903 void *arg1 = va_arg(args, void *); |
|
| 904 void *arg2 = va_arg(args, void *); |
|
| 905 void *arg3 = va_arg(args, void *); |
|
| 906 void *arg4 = va_arg(args, void *); |
|
| 907 |
|
| 908 ret_val = ((gboolean (*)(void *, void *, void *, void *, void *))cb)( |
|
| 909 arg1, arg2, arg3, arg4, data); |
|
| 910 |
|
| 911 if (return_val != NULL) |
|
| 912 *return_val = GINT_TO_POINTER(ret_val); |
|
| 913 } |
|
| 914 |
|
| 915 void |
|
| 916 gaim_marshal_BOOLEAN__POINTER_POINTER_POINTER_POINTER_POINTER( |
|
| 917 GaimCallback cb, va_list args, void *data, void **return_val) |
|
| 918 { |
|
| 919 gboolean ret_val; |
|
| 920 void *arg1 = va_arg(args, void *); |
|
| 921 void *arg2 = va_arg(args, void *); |
|
| 922 void *arg3 = va_arg(args, void *); |
|
| 923 void *arg4 = va_arg(args, void *); |
|
| 924 void *arg5 = va_arg(args, void *); |
|
| 925 |
|
| 926 ret_val = |
|
| 927 ((gboolean (*)(void *, void *, void *, void *, void *, void *))cb)( |
|
| 928 arg1, arg2, arg3, arg4, arg5, data); |
|
| 929 |
|
| 930 if (return_val != NULL) |
|
| 931 *return_val = GINT_TO_POINTER(ret_val); |
|
| 932 } |
|
| 933 |
|
| 934 void |
|
| 935 gaim_marshal_BOOLEAN__INT_POINTER(GaimCallback cb, va_list args, void *data, |
|
| 936 void **return_val) |
|
| 937 { |
|
| 938 gboolean ret_val; |
|
| 939 gint arg1 = va_arg(args, gint); |
|
| 940 void *arg2 = va_arg(args, void *); |
|
| 941 |
|
| 942 ret_val = ((gboolean (*)(gint, void *, void *))cb)(arg1, arg2, data); |
|
| 943 |
|
| 944 if (return_val != NULL) |
|
| 945 *return_val = GINT_TO_POINTER(ret_val); |
|
| 946 } |
|
| 947 |
|
| 948 void |
|
| 949 gaim_marshal_POINTER__POINTER_INT( |
|
| 950 GaimCallback cb, va_list args, void *data, |
|
| 951 void **return_val) |
|
| 952 { |
|
| 953 gpointer ret_val; |
|
| 954 void *arg1 = va_arg(args, void *); |
|
| 955 gint arg2 = va_arg(args, gint); |
|
| 956 |
|
| 957 ret_val = ((gpointer(*)(void *, gint, void *))cb)(arg1, arg2, data); |
|
| 958 |
|
| 959 if (return_val != NULL) |
|
| 960 *return_val = ret_val; |
|
| 961 } |
|
| 962 |
|
| 963 void |
|
| 964 gaim_marshal_POINTER__POINTER_INT64( |
|
| 965 GaimCallback cb, va_list args, void *data, |
|
| 966 void **return_val) |
|
| 967 { |
|
| 968 gpointer ret_val; |
|
| 969 void *arg1 = va_arg(args, void *); |
|
| 970 gint64 arg2 = va_arg(args, gint64); |
|
| 971 |
|
| 972 ret_val = ((gpointer(*)(void *, gint64, void *))cb)(arg1, arg2, data); |
|
| 973 |
|
| 974 if (return_val != NULL) |
|
| 975 *return_val = ret_val; |
|
| 976 } |
|
| 977 |
|
| 978 void |
|
| 979 gaim_marshal_POINTER__POINTER_POINTER(GaimCallback cb, va_list args, void *data, |
|
| 980 void **return_val) |
|
| 981 { |
|
| 982 gpointer ret_val; |
|
| 983 void *arg1 = va_arg(args, void *); |
|
| 984 void *arg2 = va_arg(args, void *); |
|
| 985 |
|
| 986 ret_val = ((gpointer (*)(void *, void *, void *))cb)(arg1, arg2, data); |
|
| 987 |
|
| 988 if (return_val != NULL) |
|
| 989 *return_val = ret_val; |
|
| 990 } |
|