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