1 /* GObject - GLib Type, Object, Parameter and Signal Library 2 * Copyright (C) 2000-2001 Red Hat, Inc. 3 * 4 * This library is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Lesser General Public 6 * License as published by the Free Software Foundation; either 7 * version 2 of the License, or (at your option) any later version. 8 * 9 * This library is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * Lesser General Public License for more details. 13 * 14 * You should have received a copy of the GNU Lesser General 15 * Public License along with this library; if not, write to the 16 * Free Software Foundation, Inc., 59 Temple Place, Suite 330, 17 * Boston, MA 02111-1307, USA. 18 * 19 * this code is based on the original GtkSignal implementation 20 * for the Gtk+ library by Peter Mattis <petm (at) xcf.berkeley.edu> 21 */ 22 23 /* 24 * MT safe 25 */ 26 27 #include "config.h" 28 29 #include <string.h> 30 #include <signal.h> 31 32 #include "gsignal.h" 33 #include "gbsearcharray.h" 34 #include "gvaluecollector.h" 35 #include "gvaluetypes.h" 36 #include "gboxed.h" 37 #include "gobject.h" 38 #include "genums.h" 39 #include "gobjectalias.h" 40 41 42 /** 43 * SECTION:signals 44 * @short_description: A means for customization of object behaviour 45 * and a general purpose notification mechanism 46 * @title: Signals 47 * 48 * The basic concept of the signal system is that of the 49 * <emphasis>emission</emphasis> of a signal. Signals are introduced 50 * per-type and are identified through strings. Signals introduced 51 * for a parent type are available in derived types as well, so 52 * basically they are a per-type facility that is inherited. A signal 53 * emission mainly involves invocation of a certain set of callbacks 54 * in precisely defined manner. There are two main categories of such 55 * callbacks, per-object 56 * <footnote><para>Although signals can deal with any kind of instantiatable 57 * type, i'm referring to those types as "object types" in the following, 58 * simply because that is the context most users will encounter signals in. 59 * </para></footnote> 60 * ones and user provided ones. 61 * The per-object callbacks are most often referred to as "object method 62 * handler" or "default (signal) handler", while user provided callbacks are 63 * usually just called "signal handler". 64 * The object method handler is provided at signal creation time (this most 65 * frequently happens at the end of an object class' creation), while user 66 * provided handlers are frequently connected and disconnected to/from a certain 67 * signal on certain object instances. 68 * 69 * A signal emission consists of five stages, unless prematurely stopped: 70 * <variablelist> 71 * <varlistentry><term></term><listitem><para> 72 * 1 - Invocation of the object method handler for %G_SIGNAL_RUN_FIRST signals 73 * </para></listitem></varlistentry> 74 * <varlistentry><term></term><listitem><para> 75 * 2 - Invocation of normal user-provided signal handlers (<emphasis>after</emphasis> flag %FALSE) 76 * </para></listitem></varlistentry> 77 * <varlistentry><term></term><listitem><para> 78 * 3 - Invocation of the object method handler for %G_SIGNAL_RUN_LAST signals 79 * </para></listitem></varlistentry> 80 * <varlistentry><term></term><listitem><para> 81 * 4 - Invocation of user provided signal handlers, connected with an <emphasis>after</emphasis> flag of %TRUE 82 * </para></listitem></varlistentry> 83 * <varlistentry><term></term><listitem><para> 84 * 5 - Invocation of the object method handler for %G_SIGNAL_RUN_CLEANUP signals 85 * </para></listitem></varlistentry> 86 * </variablelist> 87 * The user-provided signal handlers are called in the order they were 88 * connected in. 89 * All handlers may prematurely stop a signal emission, and any number of 90 * handlers may be connected, disconnected, blocked or unblocked during 91 * a signal emission. 92 * There are certain criteria for skipping user handlers in stages 2 and 4 93 * of a signal emission. 94 * First, user handlers may be <emphasis>blocked</emphasis>, blocked handlers are omitted 95 * during callback invocation, to return from the "blocked" state, a 96 * handler has to get unblocked exactly the same amount of times 97 * it has been blocked before. 98 * Second, upon emission of a %G_SIGNAL_DETAILED signal, an additional 99 * "detail" argument passed in to g_signal_emit() has to match the detail 100 * argument of the signal handler currently subject to invocation. 101 * Specification of no detail argument for signal handlers (omission of the 102 * detail part of the signal specification upon connection) serves as a 103 * wildcard and matches any detail argument passed in to emission. 104 */ 105 106 107 #define REPORT_BUG "please report occurrence circumstances to gtk-devel-list (at) gnome.org" 108 #ifdef G_ENABLE_DEBUG 109 #define IF_DEBUG(debug_type, cond) if ((_g_type_debug_flags & G_TYPE_DEBUG_ ## debug_type) || cond) 110 static volatile gpointer g_trace_instance_signals = NULL; 111 static volatile gpointer g_trap_instance_signals = NULL; 112 #endif /* G_ENABLE_DEBUG */ 113 114 115 /* --- typedefs --- */ 116 typedef struct _SignalNode SignalNode; 117 typedef struct _SignalKey SignalKey; 118 typedef struct _Emission Emission; 119 typedef struct _Handler Handler; 120 typedef struct _HandlerList HandlerList; 121 typedef struct _HandlerMatch HandlerMatch; 122 typedef enum 123 { 124 EMISSION_STOP, 125 EMISSION_RUN, 126 EMISSION_HOOK, 127 EMISSION_RESTART 128 } EmissionState; 129 130 131 /* --- prototypes --- */ 132 static inline guint signal_id_lookup (GQuark quark, 133 GType itype); 134 static void signal_destroy_R (SignalNode *signal_node); 135 static inline HandlerList* handler_list_ensure (guint signal_id, 136 gpointer instance); 137 static inline HandlerList* handler_list_lookup (guint signal_id, 138 gpointer instance); 139 static inline Handler* handler_new (gboolean after); 140 static void handler_insert (guint signal_id, 141 gpointer instance, 142 Handler *handler); 143 static Handler* handler_lookup (gpointer instance, 144 gulong handler_id, 145 guint *signal_id_p); 146 static inline HandlerMatch* handler_match_prepend (HandlerMatch *list, 147 Handler *handler, 148 guint signal_id); 149 static inline HandlerMatch* handler_match_free1_R (HandlerMatch *node, 150 gpointer instance); 151 static HandlerMatch* handlers_find (gpointer instance, 152 GSignalMatchType mask, 153 guint signal_id, 154 GQuark detail, 155 GClosure *closure, 156 gpointer func, 157 gpointer data, 158 gboolean one_and_only); 159 static inline void handler_ref (Handler *handler); 160 static inline void handler_unref_R (guint signal_id, 161 gpointer instance, 162 Handler *handler); 163 static gint handler_lists_cmp (gconstpointer node1, 164 gconstpointer node2); 165 static inline void emission_push (Emission **emission_list_p, 166 Emission *emission); 167 static inline void emission_pop (Emission **emission_list_p, 168 Emission *emission); 169 static inline Emission* emission_find (Emission *emission_list, 170 guint signal_id, 171 GQuark detail, 172 gpointer instance); 173 static gint class_closures_cmp (gconstpointer node1, 174 gconstpointer node2); 175 static gint signal_key_cmp (gconstpointer node1, 176 gconstpointer node2); 177 static gboolean signal_emit_unlocked_R (SignalNode *node, 178 GQuark detail, 179 gpointer instance, 180 GValue *return_value, 181 const GValue *instance_and_params); 182 static const gchar * type_debug_name (GType type); 183 184 185 /* --- structures --- */ 186 typedef struct 187 { 188 GSignalAccumulator func; 189 gpointer data; 190 } SignalAccumulator; 191 typedef struct 192 { 193 GHook hook; 194 GQuark detail; 195 } SignalHook; 196 #define SIGNAL_HOOK(hook) ((SignalHook*) (hook)) 197 198 struct _SignalNode 199 { 200 /* permanent portion */ 201 guint signal_id; 202 GType itype; 203 const gchar *name; 204 guint destroyed : 1; 205 206 /* reinitializable portion */ 207 guint test_class_offset : 12; 208 guint flags : 8; 209 guint n_params : 8; 210 GType *param_types; /* mangled with G_SIGNAL_TYPE_STATIC_SCOPE flag */ 211 GType return_type; /* mangled with G_SIGNAL_TYPE_STATIC_SCOPE flag */ 212 GBSearchArray *class_closure_bsa; 213 SignalAccumulator *accumulator; 214 GSignalCMarshaller c_marshaller; 215 GHookList *emission_hooks; 216 }; 217 #define MAX_TEST_CLASS_OFFSET (4096) /* 2^12, 12 bits for test_class_offset */ 218 #define TEST_CLASS_MAGIC (1) /* indicates NULL class closure, candidate for NOP optimization */ 219 220 struct _SignalKey 221 { 222 GType itype; 223 GQuark quark; 224 guint signal_id; 225 }; 226 227 struct _Emission 228 { 229 Emission *next; 230 gpointer instance; 231 GSignalInvocationHint ihint; 232 EmissionState state; 233 GType chain_type; 234 }; 235 236 struct _HandlerList 237 { 238 guint signal_id; 239 Handler *handlers; 240 Handler *tail_before; /* normal signal handlers are appended here */ 241 Handler *tail_after; /* CONNECT_AFTER handlers are appended here */ 242 }; 243 244 struct _Handler 245 { 246 gulong sequential_number; 247 Handler *next; 248 Handler *prev; 249 GQuark detail; 250 guint ref_count; 251 guint block_count : 16; 252 #define HANDLER_MAX_BLOCK_COUNT (1 << 16) 253 guint after : 1; 254 GClosure *closure; 255 }; 256 struct _HandlerMatch 257 { 258 Handler *handler; 259 HandlerMatch *next; 260 guint signal_id; 261 }; 262 263 typedef struct 264 { 265 GType instance_type; /* 0 for default closure */ 266 GClosure *closure; 267 } ClassClosure; 268 269 270 /* --- variables --- */ 271 static GBSearchArray *g_signal_key_bsa = NULL; 272 static const GBSearchConfig g_signal_key_bconfig = { 273 sizeof (SignalKey), 274 signal_key_cmp, 275 G_BSEARCH_ARRAY_ALIGN_POWER2, 276 }; 277 static GBSearchConfig g_signal_hlbsa_bconfig = { 278 sizeof (HandlerList), 279 handler_lists_cmp, 280 0, 281 }; 282 static GBSearchConfig g_class_closure_bconfig = { 283 sizeof (ClassClosure), 284 class_closures_cmp, 285 0, 286 }; 287 static GHashTable *g_handler_list_bsa_ht = NULL; 288 static Emission *g_recursive_emissions = NULL; 289 static Emission *g_restart_emissions = NULL; 290 static gulong g_handler_sequential_number = 1; 291 G_LOCK_DEFINE_STATIC (g_signal_mutex); 292 #define SIGNAL_LOCK() G_LOCK (g_signal_mutex) 293 #define SIGNAL_UNLOCK() G_UNLOCK (g_signal_mutex) 294 295 296 /* --- signal nodes --- */ 297 static guint g_n_signal_nodes = 0; 298 static SignalNode **g_signal_nodes = NULL; 299 300 static inline SignalNode* 301 LOOKUP_SIGNAL_NODE (register guint signal_id) 302 { 303 if (signal_id < g_n_signal_nodes) 304 return g_signal_nodes[signal_id]; 305 else 306 return NULL; 307 } 308 309 310 /* --- functions --- */ 311 static inline guint 312 signal_id_lookup (GQuark quark, 313 GType itype) 314 { 315 GType *ifaces, type = itype; 316 SignalKey key; 317 guint n_ifaces; 318 319 key.quark = quark; 320 321 /* try looking up signals for this type and its ancestors */ 322 do 323 { 324 SignalKey *signal_key; 325 326 key.itype = type; 327 signal_key = g_bsearch_array_lookup (g_signal_key_bsa, &g_signal_key_bconfig, &key); 328 329 if (signal_key) 330 return signal_key->signal_id; 331 332 type = g_type_parent (type); 333 } 334 while (type); 335 336 /* no luck, try interfaces it exports */ 337 ifaces = g_type_interfaces (itype, &n_ifaces); 338 while (n_ifaces--) 339 { 340 SignalKey *signal_key; 341 342 key.itype = ifaces[n_ifaces]; 343 signal_key = g_bsearch_array_lookup (g_signal_key_bsa, &g_signal_key_bconfig, &key); 344 345 if (signal_key) 346 { 347 g_free (ifaces); 348 return signal_key->signal_id; 349 } 350 } 351 g_free (ifaces); 352 353 return 0; 354 } 355 356 static gint 357 class_closures_cmp (gconstpointer node1, 358 gconstpointer node2) 359 { 360 const ClassClosure *c1 = node1, *c2 = node2; 361 362 return G_BSEARCH_ARRAY_CMP (c1->instance_type, c2->instance_type); 363 } 364 365 static gint 366 handler_lists_cmp (gconstpointer node1, 367 gconstpointer node2) 368 { 369 const HandlerList *hlist1 = node1, *hlist2 = node2; 370 371 return G_BSEARCH_ARRAY_CMP (hlist1->signal_id, hlist2->signal_id); 372 } 373 374 static inline HandlerList* 375 handler_list_ensure (guint signal_id, 376 gpointer instance) 377 { 378 GBSearchArray *hlbsa = g_hash_table_lookup (g_handler_list_bsa_ht, instance); 379 HandlerList key; 380 381 key.signal_id = signal_id; 382 key.handlers = NULL; 383 key.tail_before = NULL; 384 key.tail_after = NULL; 385 if (!hlbsa) 386 { 387 hlbsa = g_bsearch_array_create (&g_signal_hlbsa_bconfig); 388 hlbsa = g_bsearch_array_insert (hlbsa, &g_signal_hlbsa_bconfig, &key); 389 g_hash_table_insert (g_handler_list_bsa_ht, instance, hlbsa); 390 } 391 else 392 { 393 GBSearchArray *o = hlbsa; 394 395 hlbsa = g_bsearch_array_insert (o, &g_signal_hlbsa_bconfig, &key); 396 if (hlbsa != o) 397 g_hash_table_insert (g_handler_list_bsa_ht, instance, hlbsa); 398 } 399 return g_bsearch_array_lookup (hlbsa, &g_signal_hlbsa_bconfig, &key); 400 } 401 402 static inline HandlerList* 403 handler_list_lookup (guint signal_id, 404 gpointer instance) 405 { 406 GBSearchArray *hlbsa = g_hash_table_lookup (g_handler_list_bsa_ht, instance); 407 HandlerList key; 408 409 key.signal_id = signal_id; 410 411 return hlbsa ? g_bsearch_array_lookup (hlbsa, &g_signal_hlbsa_bconfig, &key) : NULL; 412 } 413 414 static Handler* 415 handler_lookup (gpointer instance, 416 gulong handler_id, 417 guint *signal_id_p) 418 { 419 GBSearchArray *hlbsa = g_hash_table_lookup (g_handler_list_bsa_ht, instance); 420 421 if (hlbsa) 422 { 423 guint i; 424 425 for (i = 0; i < hlbsa->n_nodes; i++) 426 { 427 HandlerList *hlist = g_bsearch_array_get_nth (hlbsa, &g_signal_hlbsa_bconfig, i); 428 Handler *handler; 429 430 for (handler = hlist->handlers; handler; handler = handler->next) 431 if (handler->sequential_number == handler_id) 432 { 433 if (signal_id_p) 434 *signal_id_p = hlist->signal_id; 435 436 return handler; 437 } 438 } 439 } 440 441 return NULL; 442 } 443 444 static inline HandlerMatch* 445 handler_match_prepend (HandlerMatch *list, 446 Handler *handler, 447 guint signal_id) 448 { 449 HandlerMatch *node; 450 451 node = g_slice_new (HandlerMatch); 452 node->handler = handler; 453 node->next = list; 454 node->signal_id = signal_id; 455 handler_ref (handler); 456 457 return node; 458 } 459 static inline HandlerMatch* 460 handler_match_free1_R (HandlerMatch *node, 461 gpointer instance) 462 { 463 HandlerMatch *next = node->next; 464 465 handler_unref_R (node->signal_id, instance, node->handler); 466 g_slice_free (HandlerMatch, node); 467 468 return next; 469 } 470 471 static HandlerMatch* 472 handlers_find (gpointer instance, 473 GSignalMatchType mask, 474 guint signal_id, 475 GQuark detail, 476 GClosure *closure, 477 gpointer func, 478 gpointer data, 479 gboolean one_and_only) 480 { 481 HandlerMatch *mlist = NULL; 482 483 if (mask & G_SIGNAL_MATCH_ID) 484 { 485 HandlerList *hlist = handler_list_lookup (signal_id, instance); 486 Handler *handler; 487 SignalNode *node = NULL; 488 489 if (mask & G_SIGNAL_MATCH_FUNC) 490 { 491 node = LOOKUP_SIGNAL_NODE (signal_id); 492 if (!node || !node->c_marshaller) 493 return NULL; 494 } 495 496 mask = ~mask; 497 for (handler = hlist ? hlist->handlers : NULL; handler; handler = handler->next) 498 if (handler->sequential_number && 499 ((mask & G_SIGNAL_MATCH_DETAIL) || handler->detail == detail) && 500 ((mask & G_SIGNAL_MATCH_CLOSURE) || handler->closure == closure) && 501 ((mask & G_SIGNAL_MATCH_DATA) || handler->closure->data == data) && 502 ((mask & G_SIGNAL_MATCH_UNBLOCKED) || handler->block_count == 0) && 503 ((mask & G_SIGNAL_MATCH_FUNC) || (handler->closure->marshal == node->c_marshaller && 504 handler->closure->meta_marshal == 0 && 505 ((GCClosure*) handler->closure)->callback == func))) 506 { 507 mlist = handler_match_prepend (mlist, handler, signal_id); 508 if (one_and_only) 509 return mlist; 510 } 511 } 512 else 513 { 514 GBSearchArray *hlbsa = g_hash_table_lookup (g_handler_list_bsa_ht, instance); 515 516 mask = ~mask; 517 if (hlbsa) 518 { 519 guint i; 520 521 for (i = 0; i < hlbsa->n_nodes; i++) 522 { 523 HandlerList *hlist = g_bsearch_array_get_nth (hlbsa, &g_signal_hlbsa_bconfig, i); 524 SignalNode *node = NULL; 525 Handler *handler; 526 527 if (!(mask & G_SIGNAL_MATCH_FUNC)) 528 { 529 node = LOOKUP_SIGNAL_NODE (hlist->signal_id); 530 if (!node->c_marshaller) 531 continue; 532 } 533 534 for (handler = hlist->handlers; handler; handler = handler->next) 535 if (handler->sequential_number && 536 ((mask & G_SIGNAL_MATCH_DETAIL) || handler->detail == detail) && 537 ((mask & G_SIGNAL_MATCH_CLOSURE) || handler->closure == closure) && 538 ((mask & G_SIGNAL_MATCH_DATA) || handler->closure->data == data) && 539 ((mask & G_SIGNAL_MATCH_UNBLOCKED) || handler->block_count == 0) && 540 ((mask & G_SIGNAL_MATCH_FUNC) || (handler->closure->marshal == node->c_marshaller && 541 handler->closure->meta_marshal == 0 && 542 ((GCClosure*) handler->closure)->callback == func))) 543 { 544 mlist = handler_match_prepend (mlist, handler, hlist->signal_id); 545 if (one_and_only) 546 return mlist; 547 } 548 } 549 } 550 } 551 552 return mlist; 553 } 554 555 static inline Handler* 556 handler_new (gboolean after) 557 { 558 Handler *handler = g_slice_new (Handler); 559 #ifndef G_DISABLE_CHECKS 560 if (g_handler_sequential_number < 1) 561 g_error (G_STRLOC ": handler id overflow, %s", REPORT_BUG); 562 #endif 563 564 handler->sequential_number = g_handler_sequential_number++; 565 handler->prev = NULL; 566 handler->next = NULL; 567 handler->detail = 0; 568 handler->ref_count = 1; 569 handler->block_count = 0; 570 handler->after = after != FALSE; 571 handler->closure = NULL; 572 573 return handler; 574 } 575 576 static inline void 577 handler_ref (Handler *handler) 578 { 579 g_return_if_fail (handler->ref_count > 0); 580 581 g_atomic_int_inc ((int *)&handler->ref_count); 582 } 583 584 static inline void 585 handler_unref_R (guint signal_id, 586 gpointer instance, 587 Handler *handler) 588 { 589 gboolean is_zero; 590 591 g_return_if_fail (handler->ref_count > 0); 592 593 is_zero = g_atomic_int_dec_and_test ((int *)&handler->ref_count); 594 595 if (G_UNLIKELY (is_zero)) 596 { 597 HandlerList *hlist = NULL; 598 599 if (handler->next) 600 handler->next->prev = handler->prev; 601 if (handler->prev) /* watch out for g_signal_handlers_destroy()! */ 602 handler->prev->next = handler->next; 603 else 604 { 605 hlist = handler_list_lookup (signal_id, instance); 606 hlist->handlers = handler->next; 607 } 608 609 if (instance) 610 { 611 /* check if we are removing the handler pointed to by tail_before */ 612 if (!handler->after && (!handler->next || handler->next->after)) 613 { 614 if (!hlist) 615 hlist = handler_list_lookup (signal_id, instance); 616 if (hlist) 617 { 618 g_assert (hlist->tail_before == handler); /* paranoid */ 619 hlist->tail_before = handler->prev; 620 } 621 } 622 623 /* check if we are removing the handler pointed to by tail_after */ 624 if (!handler->next) 625 { 626 if (!hlist) 627 hlist = handler_list_lookup (signal_id, instance); 628 if (hlist) 629 { 630 g_assert (hlist->tail_after == handler); /* paranoid */ 631 hlist->tail_after = handler->prev; 632 } 633 } 634 } 635 636 SIGNAL_UNLOCK (); 637 g_closure_unref (handler->closure); 638 SIGNAL_LOCK (); 639 g_slice_free (Handler, handler); 640 } 641 } 642 643 static void 644 handler_insert (guint signal_id, 645 gpointer instance, 646 Handler *handler) 647 { 648 HandlerList *hlist; 649 650 g_assert (handler->prev == NULL && handler->next == NULL); /* paranoid */ 651 652 hlist = handler_list_ensure (signal_id, instance); 653 if (!hlist->handlers) 654 { 655 hlist->handlers = handler; 656 if (!handler->after) 657 hlist->tail_before = handler; 658 } 659 else if (handler->after) 660 { 661 handler->prev = hlist->tail_after; 662 hlist->tail_after->next = handler; 663 } 664 else 665 { 666 if (hlist->tail_before) 667 { 668 handler->next = hlist->tail_before->next; 669 if (handler->next) 670 handler->next->prev = handler; 671 handler->prev = hlist->tail_before; 672 hlist->tail_before->next = handler; 673 } 674 else /* insert !after handler into a list of only after handlers */ 675 { 676 handler->next = hlist->handlers; 677 if (handler->next) 678 handler->next->prev = handler; 679 hlist->handlers = handler; 680 } 681 hlist->tail_before = handler; 682 } 683 684 if (!handler->next) 685 hlist->tail_after = handler; 686 } 687 688 static inline void 689 emission_push (Emission **emission_list_p, 690 Emission *emission) 691 { 692 emission->next = *emission_list_p; 693 *emission_list_p = emission; 694 } 695 696 static inline void 697 emission_pop (Emission **emission_list_p, 698 Emission *emission) 699 { 700 Emission *node, *last = NULL; 701 702 for (node = *emission_list_p; node; last = node, node = last->next) 703 if (node == emission) 704 { 705 if (last) 706 last->next = node->next; 707 else 708 *emission_list_p = node->next; 709 return; 710 } 711 g_assert_not_reached (); 712 } 713 714 static inline Emission* 715 emission_find (Emission *emission_list, 716 guint signal_id, 717 GQuark detail, 718 gpointer instance) 719 { 720 Emission *emission; 721 722 for (emission = emission_list; emission; emission = emission->next) 723 if (emission->instance == instance && 724 emission->ihint.signal_id == signal_id && 725 emission->ihint.detail == detail) 726 return emission; 727 return NULL; 728 } 729 730 static inline Emission* 731 emission_find_innermost (gpointer instance) 732 { 733 Emission *emission, *s = NULL, *c = NULL; 734 735 for (emission = g_restart_emissions; emission; emission = emission->next) 736 if (emission->instance == instance) 737 { 738 s = emission; 739 break; 740 } 741 for (emission = g_recursive_emissions; emission; emission = emission->next) 742 if (emission->instance == instance) 743 { 744 c = emission; 745 break; 746 } 747 if (!s) 748 return c; 749 else if (!c) 750 return s; 751 else 752 return G_HAVE_GROWING_STACK ? MAX (c, s) : MIN (c, s); 753 } 754 755 static gint 756 signal_key_cmp (gconstpointer node1, 757 gconstpointer node2) 758 { 759 const SignalKey *key1 = node1, *key2 = node2; 760 761 if (key1->itype == key2->itype) 762 return G_BSEARCH_ARRAY_CMP (key1->quark, key2->quark); 763 else 764 return G_BSEARCH_ARRAY_CMP (key1->itype, key2->itype); 765 } 766 767 void 768 g_signal_init (void) 769 { 770 SIGNAL_LOCK (); 771 if (!g_n_signal_nodes) 772 { 773 /* setup handler list binary searchable array hash table (in german, that'd be one word ;) */ 774 g_handler_list_bsa_ht = g_hash_table_new (g_direct_hash, NULL); 775 g_signal_key_bsa = g_bsearch_array_create (&g_signal_key_bconfig); 776 777 /* invalid (0) signal_id */ 778 g_n_signal_nodes = 1; 779 g_signal_nodes = g_renew (SignalNode*, g_signal_nodes, g_n_signal_nodes); 780 g_signal_nodes[0] = NULL; 781 } 782 SIGNAL_UNLOCK (); 783 } 784 785 void 786 _g_signals_destroy (GType itype) 787 { 788 guint i; 789 790 SIGNAL_LOCK (); 791 for (i = 1; i < g_n_signal_nodes; i++) 792 { 793 SignalNode *node = g_signal_nodes[i]; 794 795 if (node->itype == itype) 796 { 797 if (node->destroyed) 798 g_warning (G_STRLOC ": signal \"%s\" of type `%s' already destroyed", 799 node->name, 800 type_debug_name (node->itype)); 801 else 802 signal_destroy_R (node); 803 } 804 } 805 SIGNAL_UNLOCK (); 806 } 807 808 /** 809 * g_signal_stop_emission: 810 * @instance: the object whose signal handlers you wish to stop. 811 * @signal_id: the signal identifier, as returned by g_signal_lookup(). 812 * @detail: the detail which the signal was emitted with. 813 * 814 * Stops a signal's current emission. 815 * 816 * This will prevent the default method from running, if the signal was 817 * %G_SIGNAL_RUN_LAST and you connected normally (i.e. without the "after" 818 * flag). 819 * 820 * Prints a warning if used on a signal which isn't being emitted. 821 */ 822 void 823 g_signal_stop_emission (gpointer instance, 824 guint signal_id, 825 GQuark detail) 826 { 827 SignalNode *node; 828 829 g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance)); 830 g_return_if_fail (signal_id > 0); 831 832 SIGNAL_LOCK (); 833 node = LOOKUP_SIGNAL_NODE (signal_id); 834 if (node && detail && !(node->flags & G_SIGNAL_DETAILED)) 835 { 836 g_warning ("%s: signal id `%u' does not support detail (%u)", G_STRLOC, signal_id, detail); 837 SIGNAL_UNLOCK (); 838 return; 839 } 840 if (node && g_type_is_a (G_TYPE_FROM_INSTANCE (instance), node->itype)) 841 { 842 Emission *emission_list = node->flags & G_SIGNAL_NO_RECURSE ? g_restart_emissions : g_recursive_emissions; 843 Emission *emission = emission_find (emission_list, signal_id, detail, instance); 844 845 if (emission) 846 { 847 if (emission->state == EMISSION_HOOK) 848 g_warning (G_STRLOC ": emission of signal \"%s\" for instance `%p' cannot be stopped from emission hook", 849 node->name, instance); 850 else if (emission->state == EMISSION_RUN) 851 emission->state = EMISSION_STOP; 852 } 853 else 854 g_warning (G_STRLOC ": no emission of signal \"%s\" to stop for instance `%p'", 855 node->name, instance); 856 } 857 else 858 g_warning ("%s: signal id `%u' is invalid for instance `%p'", G_STRLOC, signal_id, instance); 859 SIGNAL_UNLOCK (); 860 } 861 862 static void 863 signal_finalize_hook (GHookList *hook_list, 864 GHook *hook) 865 { 866 GDestroyNotify destroy = hook->destroy; 867 868 if (destroy) 869 { 870 hook->destroy = NULL; 871 SIGNAL_UNLOCK (); 872 destroy (hook->data); 873 SIGNAL_LOCK (); 874 } 875 } 876 877 /** 878 * g_signal_add_emission_hook: 879 * @signal_id: the signal identifier, as returned by g_signal_lookup(). 880 * @detail: the detail on which to call the hook. 881 * @hook_func: a #GSignalEmissionHook function. 882 * @hook_data: user data for @hook_func. 883 * @data_destroy: a #GDestroyNotify for @hook_data. 884 * 885 * Adds an emission hook for a signal, which will get called for any emission 886 * of that signal, independent of the instance. This is possible only 887 * for signals which don't have #G_SIGNAL_NO_HOOKS flag set. 888 * 889 * Returns: the hook id, for later use with g_signal_remove_emission_hook(). 890 */ 891 gulong 892 g_signal_add_emission_hook (guint signal_id, 893 GQuark detail, 894 GSignalEmissionHook hook_func, 895 gpointer hook_data, 896 GDestroyNotify data_destroy) 897 { 898 static gulong seq_hook_id = 1; 899 SignalNode *node; 900 GHook *hook; 901 SignalHook *signal_hook; 902 903 g_return_val_if_fail (signal_id > 0, 0); 904 g_return_val_if_fail (hook_func != NULL, 0); 905 906 SIGNAL_LOCK (); 907 node = LOOKUP_SIGNAL_NODE (signal_id); 908 if (!node || node->destroyed) 909 { 910 g_warning ("%s: invalid signal id `%u'", G_STRLOC, signal_id); 911 SIGNAL_UNLOCK (); 912 return 0; 913 } 914 if (node->flags & G_SIGNAL_NO_HOOKS) 915 { 916 g_warning ("%s: signal id `%u' does not support emission hooks (G_SIGNAL_NO_HOOKS flag set)", G_STRLOC, signal_id); 917 SIGNAL_UNLOCK (); 918 return 0; 919 } 920 if (detail && !(node->flags & G_SIGNAL_DETAILED)) 921 { 922 g_warning ("%s: signal id `%u' does not support detail (%u)", G_STRLOC, signal_id, detail); 923 SIGNAL_UNLOCK (); 924 return 0; 925 } 926 if (!node->emission_hooks) 927 { 928 node->emission_hooks = g_new (GHookList, 1); 929 g_hook_list_init (node->emission_hooks, sizeof (SignalHook)); 930 node->emission_hooks->finalize_hook = signal_finalize_hook; 931 } 932 hook = g_hook_alloc (node->emission_hooks); 933 hook->data = hook_data; 934 hook->func = (gpointer) hook_func; 935 hook->destroy = data_destroy; 936 signal_hook = SIGNAL_HOOK (hook); 937 signal_hook->detail = detail; 938 node->emission_hooks->seq_id = seq_hook_id; 939 g_hook_append (node->emission_hooks, hook); 940 seq_hook_id = node->emission_hooks->seq_id; 941 SIGNAL_UNLOCK (); 942 943 return hook->hook_id; 944 } 945 946 /** 947 * g_signal_remove_emission_hook: 948 * @signal_id: the id of the signal 949 * @hook_id: the id of the emission hook, as returned by 950 * g_signal_add_emission_hook() 951 * 952 * Deletes an emission hook. 953 */ 954 void 955 g_signal_remove_emission_hook (guint signal_id, 956 gulong hook_id) 957 { 958 SignalNode *node; 959 960 g_return_if_fail (signal_id > 0); 961 g_return_if_fail (hook_id > 0); 962 963 SIGNAL_LOCK (); 964 node = LOOKUP_SIGNAL_NODE (signal_id); 965 if (!node || node->destroyed) 966 g_warning ("%s: invalid signal id `%u'", G_STRLOC, signal_id); 967 else if (!node->emission_hooks || !g_hook_destroy (node->emission_hooks, hook_id)) 968 g_warning ("%s: signal \"%s\" had no hook (%lu) to remove", G_STRLOC, node->name, hook_id); 969 SIGNAL_UNLOCK (); 970 } 971 972 static inline guint 973 signal_parse_name (const gchar *name, 974 GType itype, 975 GQuark *detail_p, 976 gboolean force_quark) 977 { 978 const gchar *colon = strchr (name, ':'); 979 guint signal_id; 980 981 if (!colon) 982 { 983 signal_id = signal_id_lookup (g_quark_try_string (name), itype); 984 if (signal_id && detail_p) 985 *detail_p = 0; 986 } 987 else if (colon[1] == ':') 988 { 989 gchar buffer[32]; 990 guint l = colon - name; 991 992 if (l < 32) 993 { 994 memcpy (buffer, name, l); 995 buffer[l] = 0; 996 signal_id = signal_id_lookup (g_quark_try_string (buffer), itype); 997 } 998 else 999 { 1000 gchar *signal = g_new (gchar, l + 1); 1001 1002 memcpy (signal, name, l); 1003 signal[l] = 0; 1004 signal_id = signal_id_lookup (g_quark_try_string (signal), itype); 1005 g_free (signal); 1006 } 1007 1008 if (signal_id && detail_p) 1009 *detail_p = colon[2] ? (force_quark ? g_quark_from_string : g_quark_try_string) (colon + 2) : 0; 1010 } 1011 else 1012 signal_id = 0; 1013 return signal_id; 1014 } 1015 1016 /** 1017 * g_signal_parse_name: 1018 * @detailed_signal: a string of the form "signal-name::detail". 1019 * @itype: The interface/instance type that introduced "signal-name". 1020 * @signal_id_p: Location to store the signal id. 1021 * @detail_p: Location to store the detail quark. 1022 * @force_detail_quark: %TRUE forces creation of a #GQuark for the detail. 1023 * 1024 * Internal function to parse a signal name into its @signal_id 1025 * and @detail quark. 1026 * 1027 * Returns: Whether the signal name could successfully be parsed and @signal_id_p and @detail_p contain valid return values. 1028 */ 1029 gboolean 1030 g_signal_parse_name (const gchar *detailed_signal, 1031 GType itype, 1032 guint *signal_id_p, 1033 GQuark *detail_p, 1034 gboolean force_detail_quark) 1035 { 1036 SignalNode *node; 1037 GQuark detail = 0; 1038 guint signal_id; 1039 1040 g_return_val_if_fail (detailed_signal != NULL, FALSE); 1041 g_return_val_if_fail (G_TYPE_IS_INSTANTIATABLE (itype) || G_TYPE_IS_INTERFACE (itype), FALSE); 1042 1043 SIGNAL_LOCK (); 1044 signal_id = signal_parse_name (detailed_signal, itype, &detail, force_detail_quark); 1045 SIGNAL_UNLOCK (); 1046 1047 node = signal_id ? LOOKUP_SIGNAL_NODE (signal_id) : NULL; 1048 if (!node || node->destroyed || 1049 (detail && !(node->flags & G_SIGNAL_DETAILED))) 1050 return FALSE; 1051 1052 if (signal_id_p) 1053 *signal_id_p = signal_id; 1054 if (detail_p) 1055 *detail_p = detail; 1056 1057 return TRUE; 1058 } 1059 1060 /** 1061 * g_signal_stop_emission_by_name: 1062 * @instance: the object whose signal handlers you wish to stop. 1063 * @detailed_signal: a string of the form "signal-name::detail". 1064 * 1065 * Stops a signal's current emission. 1066 * 1067 * This is just like g_signal_stop_emission() except it will look up the 1068 * signal id for you. 1069 */ 1070 void 1071 g_signal_stop_emission_by_name (gpointer instance, 1072 const gchar *detailed_signal) 1073 { 1074 guint signal_id; 1075 GQuark detail = 0; 1076 GType itype; 1077 1078 g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance)); 1079 g_return_if_fail (detailed_signal != NULL); 1080 1081 SIGNAL_LOCK (); 1082 itype = G_TYPE_FROM_INSTANCE (instance); 1083 signal_id = signal_parse_name (detailed_signal, itype, &detail, TRUE); 1084 if (signal_id) 1085 { 1086 SignalNode *node = LOOKUP_SIGNAL_NODE (signal_id); 1087 1088 if (detail && !(node->flags & G_SIGNAL_DETAILED)) 1089 g_warning ("%s: signal `%s' does not support details", G_STRLOC, detailed_signal); 1090 else if (!g_type_is_a (itype, node->itype)) 1091 g_warning ("%s: signal `%s' is invalid for instance `%p'", G_STRLOC, detailed_signal, instance); 1092 else 1093 { 1094 Emission *emission_list = node->flags & G_SIGNAL_NO_RECURSE ? g_restart_emissions : g_recursive_emissions; 1095 Emission *emission = emission_find (emission_list, signal_id, detail, instance); 1096 1097 if (emission) 1098 { 1099 if (emission->state == EMISSION_HOOK) 1100 g_warning (G_STRLOC ": emission of signal \"%s\" for instance `%p' cannot be stopped from emission hook", 1101 node->name, instance); 1102 else if (emission->state == EMISSION_RUN) 1103 emission->state = EMISSION_STOP; 1104 } 1105 else 1106 g_warning (G_STRLOC ": no emission of signal \"%s\" to stop for instance `%p'", 1107 node->name, instance); 1108 } 1109 } 1110 else 1111 g_warning ("%s: signal `%s' is invalid for instance `%p'", G_STRLOC, detailed_signal, instance); 1112 SIGNAL_UNLOCK (); 1113 } 1114 1115 /** 1116 * g_signal_lookup: 1117 * @name: the signal's name. 1118 * @itype: the type that the signal operates on. 1119 * 1120 * Given the name of the signal and the type of object it connects to, gets 1121 * the signal's identifying integer. Emitting the signal by number is 1122 * somewhat faster than using the name each time. 1123 * 1124 * Also tries the ancestors of the given type. 1125 * 1126 * See g_signal_new() for details on allowed signal names. 1127 * 1128 * Returns: the signal's identifying number, or 0 if no signal was found. 1129 */ 1130 guint 1131 g_signal_lookup (const gchar *name, 1132 GType itype) 1133 { 1134 guint signal_id; 1135 g_return_val_if_fail (name != NULL, 0); 1136 g_return_val_if_fail (G_TYPE_IS_INSTANTIATABLE (itype) || G_TYPE_IS_INTERFACE (itype), 0); 1137 1138 SIGNAL_LOCK (); 1139 signal_id = signal_id_lookup (g_quark_try_string (name), itype); 1140 SIGNAL_UNLOCK (); 1141 if (!signal_id) 1142 { 1143 /* give elaborate warnings */ 1144 if (!g_type_name (itype)) 1145 g_warning (G_STRLOC ": unable to lookup signal \"%s\" for invalid type id `%"G_GSIZE_FORMAT"'", 1146 name, itype); 1147 else if (!G_TYPE_IS_INSTANTIATABLE (itype)) 1148 g_warning (G_STRLOC ": unable to lookup signal \"%s\" for non instantiatable type `%s'", 1149 name, g_type_name (itype)); 1150 else if (!g_type_class_peek (itype)) 1151 g_warning (G_STRLOC ": unable to lookup signal \"%s\" of unloaded type `%s'", 1152 name, g_type_name (itype)); 1153 } 1154 1155 return signal_id; 1156 } 1157 1158 /** 1159 * g_signal_list_ids: 1160 * @itype: Instance or interface type. 1161 * @n_ids: Location to store the number of signal ids for @itype. 1162 * 1163 * Lists the signals by id that a certain instance or interface type 1164 * created. Further information about the signals can be acquired through 1165 * g_signal_query(). 1166 * 1167 * Returns: Newly allocated array of signal IDs. 1168 */ 1169 guint* 1170 g_signal_list_ids (GType itype, 1171 guint *n_ids) 1172 { 1173 SignalKey *keys; 1174 GArray *result; 1175 guint n_nodes; 1176 guint i; 1177 1178 g_return_val_if_fail (G_TYPE_IS_INSTANTIATABLE (itype) || G_TYPE_IS_INTERFACE (itype), NULL); 1179 g_return_val_if_fail (n_ids != NULL, NULL); 1180 1181 SIGNAL_LOCK (); 1182 keys = g_bsearch_array_get_nth (g_signal_key_bsa, &g_signal_key_bconfig, 0); 1183 n_nodes = g_bsearch_array_get_n_nodes (g_signal_key_bsa); 1184 result = g_array_new (FALSE, FALSE, sizeof (guint)); 1185 1186 for (i = 0; i < n_nodes; i++) 1187 if (keys[i].itype == itype) 1188 { 1189 const gchar *name = g_quark_to_string (keys[i].quark); 1190 1191 /* Signal names with "_" in them are aliases to the same 1192 * name with "-" instead of "_". 1193 */ 1194 if (!strchr (name, '_')) 1195 g_array_append_val (result, keys[i].signal_id); 1196 } 1197 *n_ids = result->len; 1198 SIGNAL_UNLOCK (); 1199 if (!n_nodes) 1200 { 1201 /* give elaborate warnings */ 1202 if (!g_type_name (itype)) 1203 g_warning (G_STRLOC ": unable to list signals for invalid type id `%"G_GSIZE_FORMAT"'", 1204 itype); 1205 else if (!G_TYPE_IS_INSTANTIATABLE (itype) && !G_TYPE_IS_INTERFACE (itype)) 1206 g_warning (G_STRLOC ": unable to list signals of non instantiatable type `%s'", 1207 g_type_name (itype)); 1208 else if (!g_type_class_peek (itype) && !G_TYPE_IS_INTERFACE (itype)) 1209 g_warning (G_STRLOC ": unable to list signals of unloaded type `%s'", 1210 g_type_name (itype)); 1211 } 1212 1213 return (guint*) g_array_free (result, FALSE); 1214 } 1215 1216 /** 1217 * g_signal_name: 1218 * @signal_id: the signal's identifying number. 1219 * 1220 * Given the signal's identifier, finds its name. 1221 * 1222 * Two different signals may have the same name, if they have differing types. 1223 * 1224 * Returns: the signal name, or %NULL if the signal number was invalid. 1225 */ 1226 G_CONST_RETURN gchar* 1227 g_signal_name (guint signal_id) 1228 { 1229 SignalNode *node; 1230 const gchar *name; 1231 1232 SIGNAL_LOCK (); 1233 node = LOOKUP_SIGNAL_NODE (signal_id); 1234 name = node ? node->name : NULL; 1235 SIGNAL_UNLOCK (); 1236 1237 return (char*) name; 1238 } 1239 1240 /** 1241 * g_signal_query: 1242 * @signal_id: The signal id of the signal to query information for. 1243 * @query: A user provided structure that is filled in with constant 1244 * values upon success. 1245 * 1246 * Queries the signal system for in-depth information about a 1247 * specific signal. This function will fill in a user-provided 1248 * structure to hold signal-specific information. If an invalid 1249 * signal id is passed in, the @signal_id member of the #GSignalQuery 1250 * is 0. All members filled into the #GSignalQuery structure should 1251 * be considered constant and have to be left untouched. 1252 */ 1253 void 1254 g_signal_query (guint signal_id, 1255 GSignalQuery *query) 1256 { 1257 SignalNode *node; 1258 1259 g_return_if_fail (query != NULL); 1260 1261 SIGNAL_LOCK (); 1262 node = LOOKUP_SIGNAL_NODE (signal_id); 1263 if (!node || node->destroyed) 1264 query->signal_id = 0; 1265 else 1266 { 1267 query->signal_id = node->signal_id; 1268 query->signal_name = node->name; 1269 query->itype = node->itype; 1270 query->signal_flags = node->flags; 1271 query->return_type = node->return_type; 1272 query->n_params = node->n_params; 1273 query->param_types = node->param_types; 1274 } 1275 SIGNAL_UNLOCK (); 1276 } 1277 1278 /** 1279 * g_signal_new: 1280 * @signal_name: the name for the signal 1281 * @itype: the type this signal pertains to. It will also pertain to 1282 * types which are derived from this type. 1283 * @signal_flags: a combination of #GSignalFlags specifying detail of when 1284 * the default handler is to be invoked. You should at least specify 1285 * %G_SIGNAL_RUN_FIRST or %G_SIGNAL_RUN_LAST. 1286 * @class_offset: The offset of the function pointer in the class structure 1287 * for this type. Used to invoke a class method generically. Pass 0 to 1288 * not associate a class method with this signal. 1289 * @accumulator: the accumulator for this signal; may be %NULL. 1290 * @accu_data: user data for the @accumulator. 1291 * @c_marshaller: the function to translate arrays of parameter values to 1292 * signal emissions into C language callback invocations. 1293 * @return_type: the type of return value, or #G_TYPE_NONE for a signal 1294 * without a return value. 1295 * @n_params: the number of parameter types to follow. 1296 * @...: a list of types, one for each parameter. 1297 * 1298 * Creates a new signal. (This is usually done in the class initializer.) 1299 * 1300 * A signal name consists of segments consisting of ASCII letters and 1301 * digits, separated by either the '-' or '_' character. The first 1302 * character of a signal name must be a letter. Names which violate these 1303 * rules lead to undefined behaviour of the GSignal system. 1304 * 1305 * When registering a signal and looking up a signal, either separator can 1306 * be used, but they cannot be mixed. 1307 * 1308 * Returns: the signal id 1309 */ 1310 guint 1311 g_signal_new (const gchar *signal_name, 1312 GType itype, 1313 GSignalFlags signal_flags, 1314 guint class_offset, 1315 GSignalAccumulator accumulator, 1316 gpointer accu_data, 1317 GSignalCMarshaller c_marshaller, 1318 GType return_type, 1319 guint n_params, 1320 ...) 1321 { 1322 va_list args; 1323 guint signal_id; 1324 1325 g_return_val_if_fail (signal_name != NULL, 0); 1326 1327 va_start (args, n_params); 1328 1329 signal_id = g_signal_new_valist (signal_name, itype, signal_flags, 1330 class_offset ? g_signal_type_cclosure_new (itype, class_offset) : NULL, 1331 accumulator, accu_data, c_marshaller, 1332 return_type, n_params, args); 1333 1334 va_end (args); 1335 1336 /* optimize NOP emissions with NULL class handlers */ 1337 if (signal_id && G_TYPE_IS_INSTANTIATABLE (itype) && return_type == G_TYPE_NONE && 1338 class_offset && class_offset < MAX_TEST_CLASS_OFFSET) 1339 { 1340 SignalNode *node; 1341 1342 SIGNAL_LOCK (); 1343 node = LOOKUP_SIGNAL_NODE (signal_id); 1344 node->test_class_offset = class_offset; 1345 SIGNAL_UNLOCK (); 1346 } 1347 1348 return signal_id; 1349 } 1350 1351 /** 1352 * g_signal_new_class_handler: 1353 * @signal_name: the name for the signal 1354 * @itype: the type this signal pertains to. It will also pertain to 1355 * types which are derived from this type. 1356 * @signal_flags: a combination of #GSignalFlags specifying detail of when 1357 * the default handler is to be invoked. You should at least specify 1358 * %G_SIGNAL_RUN_FIRST or %G_SIGNAL_RUN_LAST. 1359 * @class_handler: a #GCallback which acts as class implementation of 1360 * this signal. Used to invoke a class method generically. Pass %NULL to 1361 * not associate a class method with this signal. 1362 * @accumulator: the accumulator for this signal; may be %NULL. 1363 * @accu_data: user data for the @accumulator. 1364 * @c_marshaller: the function to translate arrays of parameter values to 1365 * signal emissions into C language callback invocations. 1366 * @return_type: the type of return value, or #G_TYPE_NONE for a signal 1367 * without a return value. 1368 * @n_params: the number of parameter types to follow. 1369 * @...: a list of types, one for each parameter. 1370 * 1371 * Creates a new signal. (This is usually done in the class initializer.) 1372 * 1373 * This is a variant of g_signal_new() that takes a C callback instead 1374 * off a class offset for the signal's class handler. This function 1375 * doesn't need a function pointer exposed in the class structure of 1376 * an object definition, instead the function pointer is passed 1377 * directly and can be overriden by derived classes with 1378 * g_signal_override_class_closure() or 1379 * g_signal_override_class_handler()and chained to with 1380 * g_signal_chain_from_overridden() or 1381 * g_signal_chain_from_overridden_handler(). 1382 * 1383 * See g_signal_new() for information about signal names. 1384 * 1385 * Returns: the signal id 1386 * 1387 * Since: 2.18 1388 */ 1389 guint 1390 g_signal_new_class_handler (const gchar *signal_name, 1391 GType itype, 1392 GSignalFlags signal_flags, 1393 GCallback class_handler, 1394 GSignalAccumulator accumulator, 1395 gpointer accu_data, 1396 GSignalCMarshaller c_marshaller, 1397 GType return_type, 1398 guint n_params, 1399 ...) 1400 { 1401 va_list args; 1402 guint signal_id; 1403 1404 g_return_val_if_fail (signal_name != NULL, 0); 1405 1406 va_start (args, n_params); 1407 1408 signal_id = g_signal_new_valist (signal_name, itype, signal_flags, 1409 class_handler ? g_cclosure_new (class_handler, NULL, NULL) : NULL, 1410 accumulator, accu_data, c_marshaller, 1411 return_type, n_params, args); 1412 1413 va_end (args); 1414 1415 return signal_id; 1416 } 1417 1418 static inline ClassClosure* 1419 signal_find_class_closure (SignalNode *node, 1420 GType itype) 1421 { 1422 GBSearchArray *bsa = node->class_closure_bsa; 1423 ClassClosure *cc; 1424 1425 if (bsa) 1426 { 1427 ClassClosure key; 1428 1429 /* cc->instance_type is 0 for default closure */ 1430 1431 key.instance_type = itype; 1432 cc = g_bsearch_array_lookup (bsa, &g_class_closure_bconfig, &key); 1433 while (!cc && key.instance_type) 1434 { 1435 key.instance_type = g_type_parent (key.instance_type); 1436 cc = g_bsearch_array_lookup (bsa, &g_class_closure_bconfig, &key); 1437 } 1438 } 1439 else 1440 cc = NULL; 1441 return cc; 1442 } 1443 1444 static inline GClosure* 1445 signal_lookup_closure (SignalNode *node, 1446 GTypeInstance *instance) 1447 { 1448 ClassClosure *cc; 1449 1450 if (node->class_closure_bsa && g_bsearch_array_get_n_nodes (node->class_closure_bsa) == 1) 1451 { 1452 cc = g_bsearch_array_get_nth (node->class_closure_bsa, &g_class_closure_bconfig, 0); 1453 if (cc && cc->instance_type == 0) /* check for default closure */ 1454 return cc->closure; 1455 } 1456 cc = signal_find_class_closure (node, G_TYPE_FROM_INSTANCE (instance)); 1457 return cc ? cc->closure : NULL; 1458 } 1459 1460 static void 1461 signal_add_class_closure (SignalNode *node, 1462 GType itype, 1463 GClosure *closure) 1464 { 1465 ClassClosure key; 1466 1467 /* can't optimize NOP emissions with overridden class closures */ 1468 node->test_class_offset = 0; 1469 1470 if (!node->class_closure_bsa) 1471 node->class_closure_bsa = g_bsearch_array_create (&g_class_closure_bconfig); 1472 key.instance_type = itype; 1473 key.closure = g_closure_ref (closure); 1474 node->class_closure_bsa = g_bsearch_array_insert (node->class_closure_bsa, 1475 &g_class_closure_bconfig, 1476 &key); 1477 g_closure_sink (closure); 1478 if (node->c_marshaller && closure && G_CLOSURE_NEEDS_MARSHAL (closure)) 1479 g_closure_set_marshal (closure, node->c_marshaller); 1480 } 1481 1482 /** 1483 * g_signal_newv: 1484 * @signal_name: the name for the signal 1485 * @itype: the type this signal pertains to. It will also pertain to 1486 * types which are derived from this type 1487 * @signal_flags: a combination of #GSignalFlags specifying detail of when 1488 * the default handler is to be invoked. You should at least specify 1489 * %G_SIGNAL_RUN_FIRST or %G_SIGNAL_RUN_LAST 1490 * @class_closure: The closure to invoke on signal emission; may be %NULL 1491 * @accumulator: the accumulator for this signal; may be %NULL 1492 * @accu_data: user data for the @accumulator 1493 * @c_marshaller: the function to translate arrays of parameter values to 1494 * signal emissions into C language callback invocations 1495 * @return_type: the type of return value, or #G_TYPE_NONE for a signal 1496 * without a return value 1497 * @n_params: the length of @param_types 1498 * @param_types: an array of types, one for each parameter 1499 * 1500 * Creates a new signal. (This is usually done in the class initializer.) 1501 * 1502 * See g_signal_new() for details on allowed signal names. 1503 * 1504 * Returns: the signal id 1505 */ 1506 guint 1507 g_signal_newv (const gchar *signal_name, 1508 GType itype, 1509 GSignalFlags signal_flags, 1510 GClosure *class_closure, 1511 GSignalAccumulator accumulator, 1512 gpointer accu_data, 1513 GSignalCMarshaller c_marshaller, 1514 GType return_type, 1515 guint n_params, 1516 GType *param_types) 1517 { 1518 gchar *name; 1519 guint signal_id, i; 1520 SignalNode *node; 1521 1522 g_return_val_if_fail (signal_name != NULL, 0); 1523 g_return_val_if_fail (G_TYPE_IS_INSTANTIATABLE (itype) || G_TYPE_IS_INTERFACE (itype), 0); 1524 if (n_params) 1525 g_return_val_if_fail (param_types != NULL, 0); 1526 g_return_val_if_fail ((return_type & G_SIGNAL_TYPE_STATIC_SCOPE) == 0, 0); 1527 if (return_type == (G_TYPE_NONE & ~G_SIGNAL_TYPE_STATIC_SCOPE)) 1528 g_return_val_if_fail (accumulator == NULL, 0); 1529 if (!accumulator) 1530 g_return_val_if_fail (accu_data == NULL, 0); 1531 1532 name = g_strdup (signal_name); 1533 g_strdelimit (name, G_STR_DELIMITERS ":^", '_'); /* FIXME do character checks like for types */ 1534 1535 SIGNAL_LOCK (); 1536 1537 signal_id = signal_id_lookup (g_quark_try_string (name), itype); 1538 node = LOOKUP_SIGNAL_NODE (signal_id); 1539 if (node && !node->destroyed) 1540 { 1541 g_warning (G_STRLOC ": signal \"%s\" already exists in the `%s' %s", 1542 name, 1543 type_debug_name (node->itype), 1544 G_TYPE_IS_INTERFACE (node->itype) ? "interface" : "class ancestry"); 1545 g_free (name); 1546 SIGNAL_UNLOCK (); 1547 return 0; 1548 } 1549 if (node && node->itype != itype) 1550 { 1551 g_warning (G_STRLOC ": signal \"%s\" for type `%s' was previously created for type `%s'", 1552 name, 1553 type_debug_name (itype), 1554 type_debug_name (node->itype)); 1555 g_free (name); 1556 SIGNAL_UNLOCK (); 1557 return 0; 1558 } 1559 for (i = 0; i < n_params; i++) 1560 if (!G_TYPE_IS_VALUE (param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE)) 1561 { 1562 g_warning (G_STRLOC ": parameter %d of type `%s' for signal \"%s::%s\" is not a value type", 1563 i + 1, type_debug_name (param_types[i]), type_debug_name (itype), name); 1564 g_free (name); 1565 SIGNAL_UNLOCK (); 1566 return 0; 1567 } 1568 if (return_type != G_TYPE_NONE && !G_TYPE_IS_VALUE (return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE)) 1569 { 1570 g_warning (G_STRLOC ": return value of type `%s' for signal \"%s::%s\" is not a value type", 1571 type_debug_name (return_type), type_debug_name (itype), name); 1572 g_free (name); 1573 SIGNAL_UNLOCK (); 1574 return 0; 1575 } 1576 if (return_type != G_TYPE_NONE && 1577 (signal_flags & (G_SIGNAL_RUN_FIRST | G_SIGNAL_RUN_LAST | G_SIGNAL_RUN_CLEANUP)) == G_SIGNAL_RUN_FIRST) 1578 { 1579 g_warning (G_STRLOC ": signal \"%s::%s\" has return type `%s' and is only G_SIGNAL_RUN_FIRST", 1580 type_debug_name (itype), name, type_debug_name (return_type)); 1581 g_free (name); 1582 SIGNAL_UNLOCK (); 1583 return 0; 1584 } 1585 1586 /* setup permanent portion of signal node */ 1587 if (!node) 1588 { 1589 SignalKey key; 1590 1591 signal_id = g_n_signal_nodes++; 1592 node = g_new (SignalNode, 1); 1593 node->signal_id = signal_id; 1594 g_signal_nodes = g_renew (SignalNode*, g_signal_nodes, g_n_signal_nodes); 1595 g_signal_nodes[signal_id] = node; 1596 node->itype = itype; 1597 node->name = name; 1598 key.itype = itype; 1599 key.quark = g_quark_from_string (node->name); 1600 key.signal_id = signal_id; 1601 g_signal_key_bsa = g_bsearch_array_insert (g_signal_key_bsa, &g_signal_key_bconfig, &key); 1602 g_strdelimit (name, "_", '-'); 1603 node->name = g_intern_string (name); 1604 key.quark = g_quark_from_string (name); 1605 g_signal_key_bsa = g_bsearch_array_insert (g_signal_key_bsa, &g_signal_key_bconfig, &key); 1606 } 1607 node->destroyed = FALSE; 1608 node->test_class_offset = 0; 1609 1610 /* setup reinitializable portion */ 1611 node->flags = signal_flags & G_SIGNAL_FLAGS_MASK; 1612 node->n_params = n_params; 1613 node->param_types = g_memdup (param_types, sizeof (GType) * n_params); 1614 node->return_type = return_type; 1615 node->class_closure_bsa = NULL; 1616 if (accumulator) 1617 { 1618 node->accumulator = g_new (SignalAccumulator, 1); 1619 node->accumulator->func = accumulator; 1620 node->accumulator->data = accu_data; 1621 } 1622 else 1623 node->accumulator = NULL; 1624 node->c_marshaller = c_marshaller; 1625 node->emission_hooks = NULL; 1626 if (class_closure) 1627 signal_add_class_closure (node, 0, class_closure); 1628 else if (G_TYPE_IS_INSTANTIATABLE (itype) && return_type == G_TYPE_NONE) 1629 { 1630 /* optimize NOP emissions */ 1631 node->test_class_offset = TEST_CLASS_MAGIC; 1632 } 1633 SIGNAL_UNLOCK (); 1634 1635 g_free (name); 1636 1637 return signal_id; 1638 } 1639 1640 /** 1641 * g_signal_new_valist: 1642 * @signal_name: the name for the signal 1643 * @itype: the type this signal pertains to. It will also pertain to 1644 * types which are derived from this type. 1645 * @signal_flags: a combination of #GSignalFlags specifying detail of when 1646 * the default handler is to be invoked. You should at least specify 1647 * %G_SIGNAL_RUN_FIRST or %G_SIGNAL_RUN_LAST. 1648 * @class_closure: The closure to invoke on signal emission; may be %NULL. 1649 * @accumulator: the accumulator for this signal; may be %NULL. 1650 * @accu_data: user data for the @accumulator. 1651 * @c_marshaller: the function to translate arrays of parameter values to 1652 * signal emissions into C language callback invocations. 1653 * @return_type: the type of return value, or #G_TYPE_NONE for a signal 1654 * without a return value. 1655 * @n_params: the number of parameter types in @args. 1656 * @args: va_list of #GType, one for each parameter. 1657 * 1658 * Creates a new signal. (This is usually done in the class initializer.) 1659 * 1660 * See g_signal_new() for details on allowed signal names. 1661 * 1662 * Returns: the signal id 1663 */ 1664 guint 1665 g_signal_new_valist (const gchar *signal_name, 1666 GType itype, 1667 GSignalFlags signal_flags, 1668 GClosure *class_closure, 1669 GSignalAccumulator accumulator, 1670 gpointer accu_data, 1671 GSignalCMarshaller c_marshaller, 1672 GType return_type, 1673 guint n_params, 1674 va_list args) 1675 { 1676 GType *param_types; 1677 guint i; 1678 guint signal_id; 1679 1680 if (n_params > 0) 1681 { 1682 param_types = g_new (GType, n_params); 1683 1684 for (i = 0; i < n_params; i++) 1685 param_types[i] = va_arg (args, GType); 1686 } 1687 else 1688 param_types = NULL; 1689 1690 signal_id = g_signal_newv (signal_name, itype, signal_flags, 1691 class_closure, accumulator, accu_data, c_marshaller, 1692 return_type, n_params, param_types); 1693 g_free (param_types); 1694 1695 return signal_id; 1696 } 1697 1698 static void 1699 signal_destroy_R (SignalNode *signal_node) 1700 { 1701 SignalNode node = *signal_node; 1702 1703 signal_node->destroyed = TRUE; 1704 1705 /* reentrancy caution, zero out real contents first */ 1706 signal_node->test_class_offset = 0; 1707 signal_node->n_params = 0; 1708 signal_node->param_types = NULL; 1709 signal_node->return_type = 0; 1710 signal_node->class_closure_bsa = NULL; 1711 signal_node->accumulator = NULL; 1712 signal_node->c_marshaller = NULL; 1713 signal_node->emission_hooks = NULL; 1714 1715 #ifdef G_ENABLE_DEBUG 1716 /* check current emissions */ 1717 { 1718 Emission *emission; 1719 1720 for (emission = (node.flags & G_SIGNAL_NO_RECURSE) ? g_restart_emissions : g_recursive_emissions; 1721 emission; emission = emission->next) 1722 if (emission->ihint.signal_id == node.signal_id) 1723 g_critical (G_STRLOC ": signal \"%s\" being destroyed is currently in emission (instance `%p')", 1724 node.name, emission->instance); 1725 } 1726 #endif 1727 1728 /* free contents that need to 1729 */ 1730 SIGNAL_UNLOCK (); 1731 g_free (node.param_types); 1732 if (node.class_closure_bsa) 1733 { 1734 guint i; 1735 1736 for (i = 0; i < node.class_closure_bsa->n_nodes; i++) 1737 { 1738 ClassClosure *cc = g_bsearch_array_get_nth (node.class_closure_bsa, &g_class_closure_bconfig, i); 1739 1740 g_closure_unref (cc->closure); 1741 } 1742 g_bsearch_array_free (node.class_closure_bsa, &g_class_closure_bconfig); 1743 } 1744 g_free (node.accumulator); 1745 if (node.emission_hooks) 1746 { 1747 g_hook_list_clear (node.emission_hooks); 1748 g_free (node.emission_hooks); 1749 } 1750 SIGNAL_LOCK (); 1751 } 1752 1753 /** 1754 * g_signal_override_class_closure: 1755 * @signal_id: the signal id 1756 * @instance_type: the instance type on which to override the class closure 1757 * for the signal. 1758 * @class_closure: the closure. 1759 * 1760 * Overrides the class closure (i.e. the default handler) for the given signal 1761 * for emissions on instances of @instance_type. @instance_type must be derived 1762 * from the type to which the signal belongs. 1763 * 1764 * See g_signal_chain_from_overridden() and 1765 * g_signal_chain_from_overridden_handler() for how to chain up to the 1766 * parent class closure from inside the overridden one. 1767 */ 1768 void 1769 g_signal_override_class_closure (guint signal_id, 1770 GType instance_type, 1771 GClosure *class_closure) 1772 { 1773 SignalNode *node; 1774 1775 g_return_if_fail (signal_id > 0); 1776 g_return_if_fail (class_closure != NULL); 1777 1778 SIGNAL_LOCK (); 1779 node = LOOKUP_SIGNAL_NODE (signal_id); 1780 if (!g_type_is_a (instance_type, node->itype)) 1781 g_warning ("%s: type `%s' cannot be overridden for signal id `%u'", G_STRLOC, type_debug_name (instance_type), signal_id); 1782 else 1783 { 1784 ClassClosure *cc = signal_find_class_closure (node, instance_type); 1785 1786 if (cc && cc->instance_type == instance_type) 1787 g_warning ("%s: type `%s' is already overridden for signal id `%u'", G_STRLOC, type_debug_name (instance_type), signal_id); 1788 else 1789 signal_add_class_closure (node, instance_type, class_closure); 1790 } 1791 SIGNAL_UNLOCK (); 1792 } 1793 1794 /** 1795 * g_signal_override_class_handler: 1796 * @signal_name: the name for the signal 1797 * @instance_type: the instance type on which to override the class handler 1798 * for the signal. 1799 * @class_handler: the handler. 1800 * 1801 * Overrides the class closure (i.e. the default handler) for the 1802 * given signal for emissions on instances of @instance_type with 1803 * callabck @class_handler. @instance_type must be derived from the 1804 * type to which the signal belongs. 1805 * 1806 * See g_signal_chain_from_overridden() and 1807 * g_signal_chain_from_overridden_handler() for how to chain up to the 1808 * parent class closure from inside the overridden one. 1809 * 1810 * Since: 2.18 1811 */ 1812 void 1813 g_signal_override_class_handler (const gchar *signal_name, 1814 GType instance_type, 1815 GCallback class_handler) 1816 { 1817 guint signal_id; 1818 1819 g_return_if_fail (signal_name != NULL); 1820 g_return_if_fail (instance_type != G_TYPE_NONE); 1821 g_return_if_fail (class_handler != NULL); 1822 1823 signal_id = g_signal_lookup (signal_name, instance_type); 1824 1825 if (signal_id) 1826 g_signal_override_class_closure (signal_id, instance_type, 1827 g_cclosure_new (class_handler, NULL, NULL)); 1828 else 1829 g_warning ("%s: signal name '%s' is invalid for type id '%"G_GSIZE_FORMAT"'", 1830 G_STRLOC, signal_name, instance_type); 1831 1832 } 1833 1834 /** 1835 * g_signal_chain_from_overridden: 1836 * @instance_and_params: the argument list of the signal emission. The first 1837 * element in the array is a #GValue for the instance the signal is being 1838 * emitted on. The rest are any arguments to be passed to the signal. 1839 * @return_value: Location for the return value. 1840 * 1841 * Calls the original class closure of a signal. This function should only 1842 * be called from an overridden class closure; see 1843 * g_signal_override_class_closure() and 1844 * g_signal_override_class_handler(). 1845 */ 1846 void 1847 g_signal_chain_from_overridden (const GValue *instance_and_params, 1848 GValue *return_value) 1849 { 1850 GType chain_type = 0, restore_type = 0; 1851 Emission *emission = NULL; 1852 GClosure *closure = NULL; 1853 guint n_params = 0; 1854 gpointer instance; 1855 1856 g_return_if_fail (instance_and_params != NULL); 1857 instance = g_value_peek_pointer (instance_and_params); 1858 g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance)); 1859 1860 SIGNAL_LOCK (); 1861 emission = emission_find_innermost (instance); 1862 if (emission) 1863 { 1864 SignalNode *node = LOOKUP_SIGNAL_NODE (emission->ihint.signal_id); 1865 1866 g_assert (node != NULL); /* paranoid */ 1867 1868 /* we should probably do the same parameter checks as g_signal_emit() here. 1869 */ 1870 if (emission->chain_type != G_TYPE_NONE) 1871 { 1872 ClassClosure *cc = signal_find_class_closure (node, emission->chain_type); 1873 1874 g_assert (cc != NULL); /* closure currently in call stack */ 1875 1876 n_params = node->n_params; 1877 restore_type = cc->instance_type; 1878 cc = signal_find_class_closure (node, g_type_parent (cc->instance_type)); 1879 if (cc && cc->instance_type != restore_type) 1880 { 1881 closure = cc->closure; 1882 chain_type = cc->instance_type; 1883 } 1884 } 1885 else 1886 g_warning ("%s: signal id `%u' cannot be chained from current emission stage for instance `%p'", G_STRLOC, node->signal_id, instance); 1887 } 1888 else 1889 g_warning ("%s: no signal is currently being emitted for instance `%p'", G_STRLOC, instance); 1890 1891 if (closure) 1892 { 1893 emission->chain_type = chain_type; 1894 SIGNAL_UNLOCK (); 1895 g_closure_invoke (closure, 1896 return_value, 1897 n_params + 1, 1898 instance_and_params, 1899 &emission->ihint); 1900 SIGNAL_LOCK (); 1901 emission->chain_type = restore_type; 1902 } 1903 SIGNAL_UNLOCK (); 1904 } 1905 1906 /** 1907 * g_signal_chain_from_overridden_handler: 1908 * @instance: the instance the signal is being emitted on. 1909 * @...: parameters to be passed to the parent class closure, followed by a 1910 * location for the return value. If the return type of the signal 1911 * is #G_TYPE_NONE, the return value location can be omitted. 1912 * 1913 * Calls the original class closure of a signal. This function should 1914 * only be called from an overridden class closure; see 1915 * g_signal_override_class_closure() and 1916 * g_signal_override_class_handler(). 1917 * 1918 * Since: 2.18 1919 */ 1920 void 1921 g_signal_chain_from_overridden_handler (gpointer instance, 1922 ...) 1923 { 1924 GType chain_type = 0, restore_type = 0; 1925 Emission *emission = NULL; 1926 GClosure *closure = NULL; 1927 SignalNode *node; 1928 guint n_params = 0; 1929 1930 g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance)); 1931 1932 SIGNAL_LOCK (); 1933 emission = emission_find_innermost (instance); 1934 if (emission) 1935 { 1936 node = LOOKUP_SIGNAL_NODE (emission->ihint.signal_id); 1937 1938 g_assert (node != NULL); /* paranoid */ 1939 1940 /* we should probably do the same parameter checks as g_signal_emit() here. 1941 */ 1942 if (emission->chain_type != G_TYPE_NONE) 1943 { 1944 ClassClosure *cc = signal_find_class_closure (node, emission->chain_type); 1945 1946 g_assert (cc != NULL); /* closure currently in call stack */ 1947 1948 n_params = node->n_params; 1949 restore_type = cc->instance_type; 1950 cc = signal_find_class_closure (node, g_type_parent (cc->instance_type)); 1951 if (cc && cc->instance_type != restore_type) 1952 { 1953 closure = cc->closure; 1954 chain_type = cc->instance_type; 1955 } 1956 } 1957 else 1958 g_warning ("%s: signal id `%u' cannot be chained from current emission stage for instance `%p'", G_STRLOC, node->signal_id, instance); 1959 } 1960 else 1961 g_warning ("%s: no signal is currently being emitted for instance `%p'", G_STRLOC, instance); 1962 1963 if (closure) 1964 { 1965 GValue *instance_and_params; 1966 GType signal_return_type; 1967 GValue *param_values; 1968 va_list var_args; 1969 guint i; 1970 1971 va_start (var_args, instance); 1972 1973 signal_return_type = node->return_type; 1974 instance_and_params = g_slice_alloc (sizeof (GValue) * (n_params + 1)); 1975 param_values = instance_and_params + 1; 1976 1977 for (i = 0; i < node->n_params; i++) 1978 { 1979 gchar *error; 1980 GType ptype = node->param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE; 1981 gboolean static_scope = node->param_types[i] & G_SIGNAL_TYPE_STATIC_SCOPE; 1982 1983 param_values[i].g_type = 0; 1984 SIGNAL_UNLOCK (); 1985 g_value_init (param_values + i, ptype); 1986 G_VALUE_COLLECT (param_values + i, 1987 var_args, 1988 static_scope ? G_VALUE_NOCOPY_CONTENTS : 0, 1989 &error); 1990 if (error) 1991 { 1992 g_warning ("%s: %s", G_STRLOC, error); 1993 g_free (error); 1994 1995 /* we purposely leak the value here, it might not be 1996 * in a sane state if an error condition occoured 1997 */ 1998 while (i--) 1999 g_value_unset (param_values + i); 2000 2001 g_slice_free1 (sizeof (GValue) * (n_params + 1), instance_and_params); 2002 va_end (var_args); 2003 return; 2004 } 2005 SIGNAL_LOCK (); 2006 } 2007 2008 SIGNAL_UNLOCK (); 2009 instance_and_params->g_type = 0; 2010 g_value_init (instance_and_params, G_TYPE_FROM_INSTANCE (instance)); 2011 g_value_set_instance (instance_and_params, instance); 2012 SIGNAL_LOCK (); 2013 2014 emission->chain_type = chain_type; 2015 SIGNAL_UNLOCK (); 2016 2017 if (signal_return_type == G_TYPE_NONE) 2018 { 2019 g_closure_invoke (closure, 2020 NULL, 2021 n_params + 1, 2022 instance_and_params, 2023 &emission->ihint); 2024 } 2025 else 2026 { 2027 GValue return_value = { 0, }; 2028 gchar *error = NULL; 2029 GType rtype = signal_return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE; 2030 gboolean static_scope = signal_return_type & G_SIGNAL_TYPE_STATIC_SCOPE; 2031 2032 g_value_init (&return_value, rtype); 2033 2034 g_closure_invoke (closure, 2035 &return_value, 2036 n_params + 1, 2037 instance_and_params, 2038 &emission->ihint); 2039 2040 G_VALUE_LCOPY (&return_value, 2041 var_args, 2042 static_scope ? G_VALUE_NOCOPY_CONTENTS : 0, 2043 &error); 2044 if (!error) 2045 { 2046 g_value_unset (&return_value); 2047 } 2048 else 2049 { 2050 g_warning ("%s: %s", G_STRLOC, error); 2051 g_free (error); 2052 2053 /* we purposely leak the value here, it might not be 2054 * in a sane state if an error condition occured 2055 */ 2056 } 2057 } 2058 2059 for (i = 0; i < n_params; i++) 2060 g_value_unset (param_values + i); 2061 g_value_unset (instance_and_params); 2062 g_slice_free1 (sizeof (GValue) * (n_params + 1), instance_and_params); 2063 2064 va_end (var_args); 2065 2066 SIGNAL_LOCK (); 2067 emission->chain_type = restore_type; 2068 } 2069 SIGNAL_UNLOCK (); 2070 } 2071 2072 /** 2073 * g_signal_get_invocation_hint: 2074 * @instance: the instance to query 2075 * 2076 * Returns the invocation hint of the innermost signal emission of instance. 2077 * 2078 * Returns: the invocation hint of the innermost signal emission. 2079 */ 2080 GSignalInvocationHint* 2081 g_signal_get_invocation_hint (gpointer instance) 2082 { 2083 Emission *emission = NULL; 2084 2085 g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), NULL); 2086 2087 SIGNAL_LOCK (); 2088 emission = emission_find_innermost (instance); 2089 SIGNAL_UNLOCK (); 2090 2091 return emission ? &emission->ihint : NULL; 2092 } 2093 2094 /** 2095 * g_signal_connect_closure_by_id: 2096 * @instance: the instance to connect to. 2097 * @signal_id: the id of the signal. 2098 * @detail: the detail. 2099 * @closure: the closure to connect. 2100 * @after: whether the handler should be called before or after the 2101 * default handler of the signal. 2102 * 2103 * Connects a closure to a signal for a particular object. 2104 * 2105 * Returns: the handler id 2106 */ 2107 gulong 2108 g_signal_connect_closure_by_id (gpointer instance, 2109 guint signal_id, 2110 GQuark detail, 2111 GClosure *closure, 2112 gboolean after) 2113 { 2114 SignalNode *node; 2115 gulong handler_seq_no = 0; 2116 2117 g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), 0); 2118 g_return_val_if_fail (signal_id > 0, 0); 2119 g_return_val_if_fail (closure != NULL, 0); 2120 2121 SIGNAL_LOCK (); 2122 node = LOOKUP_SIGNAL_NODE (signal_id); 2123 if (node) 2124 { 2125 if (detail && !(node->flags & G_SIGNAL_DETAILED)) 2126 g_warning ("%s: signal id `%u' does not support detail (%u)", G_STRLOC, signal_id, detail); 2127 else if (!g_type_is_a (G_TYPE_FROM_INSTANCE (instance), node->itype)) 2128 g_warning ("%s: signal id `%u' is invalid for instance `%p'", G_STRLOC, signal_id, instance); 2129 else 2130 { 2131 Handler *handler = handler_new (after); 2132 2133 handler_seq_no = handler->sequential_number; 2134 handler->detail = detail; 2135 handler->closure = g_closure_ref (closure); 2136 g_closure_sink (closure); 2137 handler_insert (signal_id, instance, handler); 2138 if (node->c_marshaller && G_CLOSURE_NEEDS_MARSHAL (closure)) 2139 g_closure_set_marshal (closure, node->c_marshaller); 2140 } 2141 } 2142 else 2143 g_warning ("%s: signal id `%u' is invalid for instance `%p'", G_STRLOC, signal_id, instance); 2144 SIGNAL_UNLOCK (); 2145 2146 return handler_seq_no; 2147 } 2148 2149 /** 2150 * g_signal_connect_closure: 2151 * @instance: the instance to connect to. 2152 * @detailed_signal: a string of the form "signal-name::detail". 2153 * @closure: the closure to connect. 2154 * @after: whether the handler should be called before or after the 2155 * default handler of the signal. 2156 * 2157 * Connects a closure to a signal for a particular object. 2158 * 2159 * Returns: the handler id 2160 */ 2161 gulong 2162 g_signal_connect_closure (gpointer instance, 2163 const gchar *detailed_signal, 2164 GClosure *closure, 2165 gboolean after) 2166 { 2167 guint signal_id; 2168 gulong handler_seq_no = 0; 2169 GQuark detail = 0; 2170 GType itype; 2171 2172 g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), 0); 2173 g_return_val_if_fail (detailed_signal != NULL, 0); 2174 g_return_val_if_fail (closure != NULL, 0); 2175 2176 SIGNAL_LOCK (); 2177 itype = G_TYPE_FROM_INSTANCE (instance); 2178 signal_id = signal_parse_name (detailed_signal, itype, &detail, TRUE); 2179 if (signal_id) 2180 { 2181 SignalNode *node = LOOKUP_SIGNAL_NODE (signal_id); 2182 2183 if (detail && !(node->flags & G_SIGNAL_DETAILED)) 2184 g_warning ("%s: signal `%s' does not support details", G_STRLOC, detailed_signal); 2185 else if (!g_type_is_a (itype, node->itype)) 2186 g_warning ("%s: signal `%s' is invalid for instance `%p'", G_STRLOC, detailed_signal, instance); 2187 else 2188 { 2189 Handler *handler = handler_new (after); 2190 2191 handler_seq_no = handler->sequential_number; 2192 handler->detail = detail; 2193 handler->closure = g_closure_ref (closure); 2194 g_closure_sink (closure); 2195 handler_insert (signal_id, instance, handler); 2196 if (node->c_marshaller && G_CLOSURE_NEEDS_MARSHAL (handler->closure)) 2197 g_closure_set_marshal (handler->closure, node->c_marshaller); 2198 } 2199 } 2200 else 2201 g_warning ("%s: signal `%s' is invalid for instance `%p'", G_STRLOC, detailed_signal, instance); 2202 SIGNAL_UNLOCK (); 2203 2204 return handler_seq_no; 2205 } 2206 2207 /** 2208 * g_signal_connect_data: 2209 * @instance: the instance to connect to. 2210 * @detailed_signal: a string of the form "signal-name::detail". 2211 * @c_handler: the #GCallback to connect. 2212 * @data: data to pass to @c_handler calls. 2213 * @destroy_data: a #GClosureNotify for @data. 2214 * @connect_flags: a combination of #GConnectFlags. 2215 * 2216 * Connects a #GCallback function to a signal for a particular object. Similar 2217 * to g_signal_connect(), but allows to provide a #GClosureNotify for the data 2218 * which will be called when the signal handler is disconnected and no longer 2219 * used. Specify @connect_flags if you need <literal>..._after()</literal> or 2220 * <literal>..._swapped()</literal> variants of this function. 2221 * 2222 * Returns: the handler id 2223 */ 2224 gulong 2225 g_signal_connect_data (gpointer instance, 2226 const gchar *detailed_signal, 2227 GCallback c_handler, 2228 gpointer data, 2229 GClosureNotify destroy_data, 2230 GConnectFlags connect_flags) 2231 { 2232 guint signal_id; 2233 gulong handler_seq_no = 0; 2234 GQuark detail = 0; 2235 GType itype; 2236 gboolean swapped, after; 2237 2238 g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), 0); 2239 g_return_val_if_fail (detailed_signal != NULL, 0); 2240 g_return_val_if_fail (c_handler != NULL, 0); 2241 2242 swapped = (connect_flags & G_CONNECT_SWAPPED) != FALSE; 2243 after = (connect_flags & G_CONNECT_AFTER) != FALSE; 2244 2245 SIGNAL_LOCK (); 2246 itype = G_TYPE_FROM_INSTANCE (instance); 2247 signal_id = signal_parse_name (detailed_signal, itype, &detail, TRUE); 2248 if (signal_id) 2249 { 2250 SignalNode *node = LOOKUP_SIGNAL_NODE (signal_id); 2251 2252 if (detail && !(node->flags & G_SIGNAL_DETAILED)) 2253 g_warning ("%s: signal `%s' does not support details", G_STRLOC, detailed_signal); 2254 else if (!g_type_is_a (itype, node->itype)) 2255 g_warning ("%s: signal `%s' is invalid for instance `%p'", G_STRLOC, detailed_signal, instance); 2256 else 2257 { 2258 Handler *handler = handler_new (after); 2259 2260 handler_seq_no = handler->sequential_number; 2261 handler->detail = detail; 2262 handler->closure = g_closure_ref ((swapped ? g_cclosure_new_swap : g_cclosure_new) (c_handler, data, destroy_data)); 2263 g_closure_sink (handler->closure); 2264 handler_insert (signal_id, instance, handler); 2265 if (node->c_marshaller && G_CLOSURE_NEEDS_MARSHAL (handler->closure)) 2266 g_closure_set_marshal (handler->closure, node->c_marshaller); 2267 } 2268 } 2269 else 2270 g_warning ("%s: signal `%s' is invalid for instance `%p'", G_STRLOC, detailed_signal, instance); 2271 SIGNAL_UNLOCK (); 2272 2273 return handler_seq_no; 2274 } 2275 2276 /** 2277 * g_signal_handler_block: 2278 * @instance: The instance to block the signal handler of. 2279 * @handler_id: Handler id of the handler to be blocked. 2280 * 2281 * Blocks a handler of an instance so it will not be called during any 2282 * signal emissions unless it is unblocked again. Thus "blocking" a 2283 * signal handler means to temporarily deactive it, a signal handler 2284 * has to be unblocked exactly the same amount of times it has been 2285 * blocked before to become active again. 2286 * 2287 * The @handler_id has to be a valid signal handler id, connected to a 2288 * signal of @instance. 2289 */ 2290 void 2291 g_signal_handler_block (gpointer instance, 2292 gulong handler_id) 2293 { 2294 Handler *handler; 2295 2296 g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance)); 2297 g_return_if_fail (handler_id > 0); 2298 2299 SIGNAL_LOCK (); 2300 handler = handler_lookup (instance, handler_id, NULL); 2301 if (handler) 2302 { 2303 #ifndef G_DISABLE_CHECKS 2304 if (handler->block_count >= HANDLER_MAX_BLOCK_COUNT - 1) 2305 g_error (G_STRLOC ": handler block_count overflow, %s", REPORT_BUG); 2306 #endif 2307 handler->block_count += 1; 2308 } 2309 else 2310 g_warning ("%s: instance `%p' has no handler with id `%lu'", G_STRLOC, instance, handler_id); 2311 SIGNAL_UNLOCK (); 2312 } 2313 2314 /** 2315 * g_signal_handler_unblock: 2316 * @instance: The instance to unblock the signal handler of. 2317 * @handler_id: Handler id of the handler to be unblocked. 2318 * 2319 * Undoes the effect of a previous g_signal_handler_block() call. A 2320 * blocked handler is skipped during signal emissions and will not be 2321 * invoked, unblocking it (for exactly the amount of times it has been 2322 * blocked before) reverts its "blocked" state, so the handler will be 2323 * recognized by the signal system and is called upon future or 2324 * currently ongoing signal emissions (since the order in which 2325 * handlers are called during signal emissions is deterministic, 2326 * whether the unblocked handler in question is called as part of a 2327 * currently ongoing emission depends on how far that emission has 2328 * proceeded yet). 2329 * 2330 * The @handler_id has to be a valid id of a signal handler that is 2331 * connected to a signal of @instance and is currently blocked. 2332 */ 2333 void 2334 g_signal_handler_unblock (gpointer instance, 2335 gulong handler_id) 2336 { 2337 Handler *handler; 2338 2339 g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance)); 2340 g_return_if_fail (handler_id > 0); 2341 2342 SIGNAL_LOCK (); 2343 handler = handler_lookup (instance, handler_id, NULL); 2344 if (handler) 2345 { 2346 if (handler->block_count) 2347 handler->block_count -= 1; 2348 else 2349 g_warning (G_STRLOC ": handler `%lu' of instance `%p' is not blocked", handler_id, instance); 2350 } 2351 else 2352 g_warning ("%s: instance `%p' has no handler with id `%lu'", G_STRLOC, instance, handler_id); 2353 SIGNAL_UNLOCK (); 2354 } 2355 2356 /** 2357 * g_signal_handler_disconnect: 2358 * @instance: The instance to remove the signal handler from. 2359 * @handler_id: Handler id of the handler to be disconnected. 2360 * 2361 * Disconnects a handler from an instance so it will not be called during 2362 * any future or currently ongoing emissions of the signal it has been 2363 * connected to. The @handler_id becomes invalid and may be reused. 2364 * 2365 * The @handler_id has to be a valid signal handler id, connected to a 2366 * signal of @instance. 2367 */ 2368 void 2369 g_signal_handler_disconnect (gpointer instance, 2370 gulong handler_id) 2371 { 2372 Handler *handler; 2373 guint signal_id; 2374 2375 g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance)); 2376 g_return_if_fail (handler_id > 0); 2377 2378 SIGNAL_LOCK (); 2379 handler = handler_lookup (instance, handler_id, &signal_id); 2380 if (handler) 2381 { 2382 handler->sequential_number = 0; 2383 handler->block_count = 1; 2384 handler_unref_R (signal_id, instance, handler); 2385 } 2386 else 2387 g_warning ("%s: instance `%p' has no handler with id `%lu'", G_STRLOC, instance, handler_id); 2388 SIGNAL_UNLOCK (); 2389 } 2390 2391 /** 2392 * g_signal_handler_is_connected: 2393 * @instance: The instance where a signal handler is sought. 2394 * @handler_id: the handler id. 2395 * 2396 * Returns whether @handler_id is the id of a handler connected to @instance. 2397 * 2398 * Returns: whether @handler_id identifies a handler connected to @instance. 2399 */ 2400 gboolean 2401 g_signal_handler_is_connected (gpointer instance, 2402 gulong handler_id) 2403 { 2404 Handler *handler; 2405 gboolean connected; 2406 2407 g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), FALSE); 2408 2409 SIGNAL_LOCK (); 2410 handler = handler_lookup (instance, handler_id, NULL); 2411 connected = handler != NULL; 2412 SIGNAL_UNLOCK (); 2413 2414 return connected; 2415 } 2416 2417 void 2418 g_signal_handlers_destroy (gpointer instance) 2419 { 2420 GBSearchArray *hlbsa; 2421 2422 g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance)); 2423 2424 SIGNAL_LOCK (); 2425 hlbsa = g_hash_table_lookup (g_handler_list_bsa_ht, instance); 2426 if (hlbsa) 2427 { 2428 guint i; 2429 2430 /* reentrancy caution, delete instance trace first */ 2431 g_hash_table_remove (g_handler_list_bsa_ht, instance); 2432 2433 for (i = 0; i < hlbsa->n_nodes; i++) 2434 { 2435 HandlerList *hlist = g_bsearch_array_get_nth (hlbsa, &g_signal_hlbsa_bconfig, i); 2436 Handler *handler = hlist->handlers; 2437 2438 while (handler) 2439 { 2440 Handler *tmp = handler; 2441 2442 handler = tmp->next; 2443 tmp->block_count = 1; 2444 /* cruel unlink, this works because _all_ handlers vanish */ 2445 tmp->next = NULL; 2446 tmp->prev = tmp; 2447 if (tmp->sequential_number) 2448 { 2449 tmp->sequential_number = 0; 2450 handler_unref_R (0, NULL, tmp); 2451 } 2452 } 2453 } 2454 g_bsearch_array_free (hlbsa, &g_signal_hlbsa_bconfig); 2455 } 2456 SIGNAL_UNLOCK (); 2457 } 2458 2459 /** 2460 * g_signal_handler_find: 2461 * @instance: The instance owning the signal handler to be found. 2462 * @mask: Mask indicating which of @signal_id, @detail, @closure, @func 2463 * and/or @data the handler has to match. 2464 * @signal_id: Signal the handler has to be connected to. 2465 * @detail: Signal detail the handler has to be connected to. 2466 * @closure: The closure the handler will invoke. 2467 * @func: The C closure callback of the handler (useless for non-C closures). 2468 * @data: The closure data of the handler's closure. 2469 * 2470 * Finds the first signal handler that matches certain selection criteria. 2471 * The criteria mask is passed as an OR-ed combination of #GSignalMatchType 2472 * flags, and the criteria values are passed as arguments. 2473 * The match @mask has to be non-0 for successful matches. 2474 * If no handler was found, 0 is returned. 2475 * 2476 * Returns: A valid non-0 signal handler id for a successful match. 2477 */ 2478 gulong 2479 g_signal_handler_find (gpointer instance, 2480 GSignalMatchType mask, 2481 guint signal_id, 2482 GQuark detail, 2483 GClosure *closure, 2484 gpointer func, 2485 gpointer data) 2486 { 2487 gulong handler_seq_no = 0; 2488 2489 g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), 0); 2490 g_return_val_if_fail ((mask & ~G_SIGNAL_MATCH_MASK) == 0, 0); 2491 2492 if (mask & G_SIGNAL_MATCH_MASK) 2493 { 2494 HandlerMatch *mlist; 2495 2496 SIGNAL_LOCK (); 2497 mlist = handlers_find (instance, mask, signal_id, detail, closure, func, data, TRUE); 2498 if (mlist) 2499 { 2500 handler_seq_no = mlist->handler->sequential_number; 2501 handler_match_free1_R (mlist, instance); 2502 } 2503 SIGNAL_UNLOCK (); 2504 } 2505 2506 return handler_seq_no; 2507 } 2508 2509 static guint 2510 signal_handlers_foreach_matched_R (gpointer instance, 2511 GSignalMatchType mask, 2512 guint signal_id, 2513 GQuark detail, 2514 GClosure *closure, 2515 gpointer func, 2516 gpointer data, 2517 void (*callback) (gpointer instance, 2518 gulong handler_seq_no)) 2519 { 2520 HandlerMatch *mlist; 2521 guint n_handlers = 0; 2522 2523 mlist = handlers_find (instance, mask, signal_id, detail, closure, func, data, FALSE); 2524 while (mlist) 2525 { 2526 n_handlers++; 2527 if (mlist->handler->sequential_number) 2528 { 2529 SIGNAL_UNLOCK (); 2530 callback (instance, mlist->handler->sequential_number); 2531 SIGNAL_LOCK (); 2532 } 2533 mlist = handler_match_free1_R (mlist, instance); 2534 } 2535 2536 return n_handlers; 2537 } 2538 2539 /** 2540 * g_signal_handlers_block_matched: 2541 * @instance: The instance to block handlers from. 2542 * @mask: Mask indicating which of @signal_id, @detail, @closure, @func 2543 * and/or @data the handlers have to match. 2544 * @signal_id: Signal the handlers have to be connected to. 2545 * @detail: Signal detail the handlers have to be connected to. 2546 * @closure: The closure the handlers will invoke. 2547 * @func: The C closure callback of the handlers (useless for non-C closures). 2548 * @data: The closure data of the handlers' closures. 2549 * 2550 * Blocks all handlers on an instance that match a certain selection criteria. 2551 * The criteria mask is passed as an OR-ed combination of #GSignalMatchType 2552 * flags, and the criteria values are passed as arguments. 2553 * Passing at least one of the %G_SIGNAL_MATCH_CLOSURE, %G_SIGNAL_MATCH_FUNC 2554 * or %G_SIGNAL_MATCH_DATA match flags is required for successful matches. 2555 * If no handlers were found, 0 is returned, the number of blocked handlers 2556 * otherwise. 2557 * 2558 * Returns: The number of handlers that matched. 2559 */ 2560 guint 2561 g_signal_handlers_block_matched (gpointer instance, 2562 GSignalMatchType mask, 2563 guint signal_id, 2564 GQuark detail, 2565 GClosure *closure, 2566 gpointer func, 2567 gpointer data) 2568 { 2569 guint n_handlers = 0; 2570 2571 g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), 0); 2572 g_return_val_if_fail ((mask & ~G_SIGNAL_MATCH_MASK) == 0, 0); 2573 2574 if (mask & (G_SIGNAL_MATCH_CLOSURE | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA)) 2575 { 2576 SIGNAL_LOCK (); 2577 n_handlers = signal_handlers_foreach_matched_R (instance, mask, signal_id, detail, 2578 closure, func, data, 2579 g_signal_handler_block); 2580 SIGNAL_UNLOCK (); 2581 } 2582 2583 return n_handlers; 2584 } 2585 2586 /** 2587 * g_signal_handlers_unblock_matched: 2588 * @instance: The instance to unblock handlers from. 2589 * @mask: Mask indicating which of @signal_id, @detail, @closure, @func 2590 * and/or @data the handlers have to match. 2591 * @signal_id: Signal the handlers have to be connected to. 2592 * @detail: Signal detail the handlers have to be connected to. 2593 * @closure: The closure the handlers will invoke. 2594 * @func: The C closure callback of the handlers (useless for non-C closures). 2595 * @data: The closure data of the handlers' closures. 2596 * 2597 * Unblocks all handlers on an instance that match a certain selection 2598 * criteria. The criteria mask is passed as an OR-ed combination of 2599 * #GSignalMatchType flags, and the criteria values are passed as arguments. 2600 * Passing at least one of the %G_SIGNAL_MATCH_CLOSURE, %G_SIGNAL_MATCH_FUNC 2601 * or %G_SIGNAL_MATCH_DATA match flags is required for successful matches. 2602 * If no handlers were found, 0 is returned, the number of unblocked handlers 2603 * otherwise. The match criteria should not apply to any handlers that are 2604 * not currently blocked. 2605 * 2606 * Returns: The number of handlers that matched. 2607 */ 2608 guint 2609 g_signal_handlers_unblock_matched (gpointer instance, 2610 GSignalMatchType mask, 2611 guint signal_id, 2612 GQuark detail, 2613 GClosure *closure, 2614 gpointer func, 2615 gpointer data) 2616 { 2617 guint n_handlers = 0; 2618 2619 g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), 0); 2620 g_return_val_if_fail ((mask & ~G_SIGNAL_MATCH_MASK) == 0, 0); 2621 2622 if (mask & (G_SIGNAL_MATCH_CLOSURE | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA)) 2623 { 2624 SIGNAL_LOCK (); 2625 n_handlers = signal_handlers_foreach_matched_R (instance, mask, signal_id, detail, 2626 closure, func, data, 2627 g_signal_handler_unblock); 2628 SIGNAL_UNLOCK (); 2629 } 2630 2631 return n_handlers; 2632 } 2633 2634 /** 2635 * g_signal_handlers_disconnect_matched: 2636 * @instance: The instance to remove handlers from. 2637 * @mask: Mask indicating which of @signal_id, @detail, @closure, @func 2638 * and/or @data the handlers have to match. 2639 * @signal_id: Signal the handlers have to be connected to. 2640 * @detail: Signal detail the handlers have to be connected to. 2641 * @closure: The closure the handlers will invoke. 2642 * @func: The C closure callback of the handlers (useless for non-C closures). 2643 * @data: The closure data of the handlers' closures. 2644 * 2645 * Disconnects all handlers on an instance that match a certain 2646 * selection criteria. The criteria mask is passed as an OR-ed 2647 * combination of #GSignalMatchType flags, and the criteria values are 2648 * passed as arguments. Passing at least one of the 2649 * %G_SIGNAL_MATCH_CLOSURE, %G_SIGNAL_MATCH_FUNC or 2650 * %G_SIGNAL_MATCH_DATA match flags is required for successful 2651 * matches. If no handlers were found, 0 is returned, the number of 2652 * disconnected handlers otherwise. 2653 * 2654 * Returns: The number of handlers that matched. 2655 */ 2656 guint 2657 g_signal_handlers_disconnect_matched (gpointer instance, 2658 GSignalMatchType mask, 2659 guint signal_id, 2660 GQuark detail, 2661 GClosure *closure, 2662 gpointer func, 2663 gpointer data) 2664 { 2665 guint n_handlers = 0; 2666 2667 g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), 0); 2668 g_return_val_if_fail ((mask & ~G_SIGNAL_MATCH_MASK) == 0, 0); 2669 2670 if (mask & (G_SIGNAL_MATCH_CLOSURE | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA)) 2671 { 2672 SIGNAL_LOCK (); 2673 n_handlers = signal_handlers_foreach_matched_R (instance, mask, signal_id, detail, 2674 closure, func, data, 2675 g_signal_handler_disconnect); 2676 SIGNAL_UNLOCK (); 2677 } 2678 2679 return n_handlers; 2680 } 2681 2682 /** 2683 * g_signal_has_handler_pending: 2684 * @instance: the object whose signal handlers are sought. 2685 * @signal_id: the signal id. 2686 * @detail: the detail. 2687 * @may_be_blocked: whether blocked handlers should count as match. 2688 * 2689 * Returns whether there are any handlers connected to @instance for the 2690 * given signal id and detail. 2691 * 2692 * One example of when you might use this is when the arguments to the 2693 * signal are difficult to compute. A class implementor may opt to not 2694 * emit the signal if no one is attached anyway, thus saving the cost 2695 * of building the arguments. 2696 * 2697 * Returns: %TRUE if a handler is connected to the signal, %FALSE 2698 * otherwise. 2699 */ 2700 gboolean 2701 g_signal_has_handler_pending (gpointer instance, 2702 guint signal_id, 2703 GQuark detail, 2704 gboolean may_be_blocked) 2705 { 2706 HandlerMatch *mlist; 2707 gboolean has_pending; 2708 2709 g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), FALSE); 2710 g_return_val_if_fail (signal_id > 0, FALSE); 2711 2712 SIGNAL_LOCK (); 2713 if (detail) 2714 { 2715 SignalNode *node = LOOKUP_SIGNAL_NODE (signal_id); 2716 2717 if (!(node->flags & G_SIGNAL_DETAILED)) 2718 { 2719 g_warning ("%s: signal id `%u' does not support detail (%u)", G_STRLOC, signal_id, detail); 2720 SIGNAL_UNLOCK (); 2721 return FALSE; 2722 } 2723 } 2724 mlist = handlers_find (instance, 2725 (G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_DETAIL | (may_be_blocked ? 0 : G_SIGNAL_MATCH_UNBLOCKED)), 2726 signal_id, detail, NULL, NULL, NULL, TRUE); 2727 if (mlist) 2728 { 2729 has_pending = TRUE; 2730 handler_match_free1_R (mlist, instance); 2731 } 2732 else 2733 has_pending = FALSE; 2734 SIGNAL_UNLOCK (); 2735 2736 return has_pending; 2737 } 2738 2739 static inline gboolean 2740 signal_check_skip_emission (SignalNode *node, 2741 gpointer instance, 2742 GQuark detail) 2743 { 2744 HandlerList *hlist; 2745 2746 /* are we able to check for NULL class handlers? */ 2747 if (!node->test_class_offset) 2748 return FALSE; 2749 2750 /* are there emission hooks pending? */ 2751 if (node->emission_hooks && node->emission_hooks->hooks) 2752 return FALSE; 2753 2754 /* is there a non-NULL class handler? */ 2755 if (node->test_class_offset != TEST_CLASS_MAGIC) 2756 { 2757 GTypeClass *class = G_TYPE_INSTANCE_GET_CLASS (instance, G_TYPE_FROM_INSTANCE (instance), GTypeClass); 2758 2759 if (G_STRUCT_MEMBER (gpointer, class, node->test_class_offset)) 2760 return FALSE; 2761 } 2762 2763 /* are signals being debugged? */ 2764 #ifdef G_ENABLE_DEBUG 2765 IF_DEBUG (SIGNALS, g_trace_instance_signals || g_trap_instance_signals) 2766 return FALSE; 2767 #endif /* G_ENABLE_DEBUG */ 2768 2769 /* is this a no-recurse signal already in emission? */ 2770 if (node->flags & G_SIGNAL_NO_RECURSE && 2771 emission_find (g_restart_emissions, node->signal_id, detail, instance)) 2772 return FALSE; 2773 2774 /* do we have pending handlers? */ 2775 hlist = handler_list_lookup (node->signal_id, instance); 2776 if (hlist && hlist->handlers) 2777 return FALSE; 2778 2779 /* none of the above, no emission required */ 2780 return TRUE; 2781 } 2782 2783 /** 2784 * g_signal_emitv: 2785 * @instance_and_params: argument list for the signal emission. The first 2786 * element in the array is a #GValue for the instance the signal is 2787 * being emitted on. The rest are any arguments to be passed to the 2788 * signal. 2789 * @signal_id: the signal id 2790 * @detail: the detail 2791 * @return_value: Location to store the return value of the signal emission. 2792 * 2793 * Emits a signal. 2794 * 2795 * Note that g_signal_emitv() doesn't change @return_value if no handlers are 2796 * connected, in contrast to g_signal_emit() and g_signal_emit_valist(). 2797 */ 2798 void 2799 g_signal_emitv (const GValue *instance_and_params, 2800 guint signal_id, 2801 GQuark detail, 2802 GValue *return_value) 2803 { 2804 gpointer instance; 2805 SignalNode *node; 2806 #ifdef G_ENABLE_DEBUG 2807 const GValue *param_values; 2808 guint i; 2809 #endif 2810 2811 g_return_if_fail (instance_and_params != NULL); 2812 instance = g_value_peek_pointer (instance_and_params); 2813 g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance)); 2814 g_return_if_fail (signal_id > 0); 2815 2816 #ifdef G_ENABLE_DEBUG 2817 param_values = instance_and_params + 1; 2818 #endif 2819 2820 SIGNAL_LOCK (); 2821 node = LOOKUP_SIGNAL_NODE (signal_id); 2822 if (!node || !g_type_is_a (G_TYPE_FROM_INSTANCE (instance), node->itype)) 2823 { 2824 g_warning ("%s: signal id `%u' is invalid for instance `%p'", G_STRLOC, signal_id, instance); 2825 SIGNAL_UNLOCK (); 2826 return; 2827 } 2828 #ifdef G_ENABLE_DEBUG 2829 if (detail && !(node->flags & G_SIGNAL_DETAILED)) 2830 { 2831 g_warning ("%s: signal id `%u' does not support detail (%u)", G_STRLOC, signal_id, detail); 2832 SIGNAL_UNLOCK (); 2833 return; 2834 } 2835 for (i = 0; i < node->n_params; i++) 2836 if (!G_TYPE_CHECK_VALUE_TYPE (param_values + i, node->param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE)) 2837 { 2838 g_critical ("%s: value for `%s' parameter %u for signal \"%s\" is of type `%s'", 2839 G_STRLOC, 2840 type_debug_name (node->param_types[i]), 2841 i, 2842 node->name, 2843 G_VALUE_TYPE_NAME (param_values + i)); 2844 SIGNAL_UNLOCK (); 2845 return; 2846 } 2847 if (node->return_type != G_TYPE_NONE) 2848 { 2849 if (!return_value) 2850 { 2851 g_critical ("%s: return value `%s' for signal \"%s\" is (NULL)", 2852 G_STRLOC, 2853 type_debug_name (node->return_type), 2854 node->name); 2855 SIGNAL_UNLOCK (); 2856 return; 2857 } 2858 else if (!node->accumulator && !G_TYPE_CHECK_VALUE_TYPE (return_value, node->return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE)) 2859 { 2860 g_critical ("%s: return value `%s' for signal \"%s\" is of type `%s'", 2861 G_STRLOC, 2862 type_debug_name (node->return_type), 2863 node->name, 2864 G_VALUE_TYPE_NAME (return_value)); 2865 SIGNAL_UNLOCK (); 2866 return; 2867 } 2868 } 2869 else 2870 return_value = NULL; 2871 #endif /* G_ENABLE_DEBUG */ 2872 2873 /* optimize NOP emissions */ 2874 if (signal_check_skip_emission (node, instance, detail)) 2875 { 2876 /* nothing to do to emit this signal */ 2877 SIGNAL_UNLOCK (); 2878 /* g_printerr ("omitting emission of \"%s\"\n", node->name); */ 2879 return; 2880 } 2881 2882 SIGNAL_UNLOCK (); 2883 signal_emit_unlocked_R (node, detail, instance, return_value, instance_and_params); 2884 } 2885 2886 /** 2887 * g_signal_emit_valist: 2888 * @instance: the instance the signal is being emitted on. 2889 * @signal_id: the signal id 2890 * @detail: the detail 2891 * @var_args: a list of parameters to be passed to the signal, followed by a 2892 * location for the return value. If the return type of the signal 2893 * is #G_TYPE_NONE, the return value location can be omitted. 2894 * 2895 * Emits a signal. 2896 * 2897 * Note that g_signal_emit_valist() resets the return value to the default 2898 * if no handlers are connected, in contrast to g_signal_emitv(). 2899 */ 2900 void 2901 g_signal_emit_valist (gpointer instance, 2902 guint signal_id, 2903 GQuark detail, 2904 va_list var_args) 2905 { 2906 GValue *instance_and_params; 2907 GType signal_return_type; 2908 GValue *param_values; 2909 SignalNode *node; 2910 guint i, n_params; 2911 2912 g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance)); 2913 g_return_if_fail (signal_id > 0); 2914 2915 SIGNAL_LOCK (); 2916 node = LOOKUP_SIGNAL_NODE (signal_id); 2917 if (!node || !g_type_is_a (G_TYPE_FROM_INSTANCE (instance), node->itype)) 2918 { 2919 g_warning ("%s: signal id `%u' is invalid for instance `%p'", G_STRLOC, signal_id, instance); 2920 SIGNAL_UNLOCK (); 2921 return; 2922 } 2923 #ifndef G_DISABLE_CHECKS 2924 if (detail && !(node->flags & G_SIGNAL_DETAILED)) 2925 { 2926 g_warning ("%s: signal id `%u' does not support detail (%u)", G_STRLOC, signal_id, detail); 2927 SIGNAL_UNLOCK (); 2928 return; 2929 } 2930 #endif /* !G_DISABLE_CHECKS */ 2931 2932 /* optimize NOP emissions */ 2933 if (signal_check_skip_emission (node, instance, detail)) 2934 { 2935 /* nothing to do to emit this signal */ 2936 SIGNAL_UNLOCK (); 2937 /* g_printerr ("omitting emission of \"%s\"\n", node->name); */ 2938 return; 2939 } 2940 2941 n_params = node->n_params; 2942 signal_return_type = node->return_type; 2943 instance_and_params = g_slice_alloc (sizeof (GValue) * (n_params + 1)); 2944 param_values = instance_and_params + 1; 2945 2946 for (i = 0; i < node->n_params; i++) 2947 { 2948 gchar *error; 2949 GType ptype = node->param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE; 2950 gboolean static_scope = node->param_types[i] & G_SIGNAL_TYPE_STATIC_SCOPE; 2951 2952 param_values[i].g_type = 0; 2953 SIGNAL_UNLOCK (); 2954 g_value_init (param_values + i, ptype); 2955 G_VALUE_COLLECT (param_values + i, 2956 var_args, 2957 static_scope ? G_VALUE_NOCOPY_CONTENTS : 0, 2958 &error); 2959 if (error) 2960 { 2961 g_warning ("%s: %s", G_STRLOC, error); 2962 g_free (error); 2963 2964 /* we purposely leak the value here, it might not be 2965 * in a sane state if an error condition occoured 2966 */ 2967 while (i--) 2968 g_value_unset (param_values + i); 2969 2970 g_slice_free1 (sizeof (GValue) * (n_params + 1), instance_and_params); 2971 return; 2972 } 2973 SIGNAL_LOCK (); 2974 } 2975 SIGNAL_UNLOCK (); 2976 instance_and_params->g_type = 0; 2977 g_value_init (instance_and_params, G_TYPE_FROM_INSTANCE (instance)); 2978 g_value_set_instance (instance_and_params, instance); 2979 if (signal_return_type == G_TYPE_NONE) 2980 signal_emit_unlocked_R (node, detail, instance, NULL, instance_and_params); 2981 else 2982 { 2983 GValue return_value = { 0, }; 2984 gchar *error = NULL; 2985 GType rtype = signal_return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE; 2986 gboolean static_scope = signal_return_type & G_SIGNAL_TYPE_STATIC_SCOPE; 2987 2988 g_value_init (&return_value, rtype); 2989 2990 signal_emit_unlocked_R (node, detail, instance, &return_value, instance_and_params); 2991 2992 G_VALUE_LCOPY (&return_value, 2993 var_args, 2994 static_scope ? G_VALUE_NOCOPY_CONTENTS : 0, 2995 &error); 2996 if (!error) 2997 g_value_unset (&return_value); 2998 else 2999 { 3000 g_warning ("%s: %s", G_STRLOC, error); 3001 g_free (error); 3002 3003 /* we purposely leak the value here, it might not be 3004 * in a sane state if an error condition occured 3005 */ 3006 } 3007 } 3008 for (i = 0; i < n_params; i++) 3009 g_value_unset (param_values + i); 3010 g_value_unset (instance_and_params); 3011 g_slice_free1 (sizeof (GValue) * (n_params + 1), instance_and_params); 3012 } 3013 3014 /** 3015 * g_signal_emit: 3016 * @instance: the instance the signal is being emitted on. 3017 * @signal_id: the signal id 3018 * @detail: the detail 3019 * @...: parameters to be passed to the signal, followed by a 3020 * location for the return value. If the return type of the signal 3021 * is #G_TYPE_NONE, the return value location can be omitted. 3022 * 3023 * Emits a signal. 3024 * 3025 * Note that g_signal_emit() resets the return value to the default 3026 * if no handlers are connected, in contrast to g_signal_emitv(). 3027 */ 3028 void 3029 g_signal_emit (gpointer instance, 3030 guint signal_id, 3031 GQuark detail, 3032 ...) 3033 { 3034 va_list var_args; 3035 3036 va_start (var_args, detail); 3037 g_signal_emit_valist (instance, signal_id, detail, var_args); 3038 va_end (var_args); 3039 } 3040 3041 /** 3042 * g_signal_emit_by_name: 3043 * @instance: the instance the signal is being emitted on. 3044 * @detailed_signal: a string of the form "signal-name::detail". 3045 * @...: parameters to be passed to the signal, followed by a 3046 * location for the return value. If the return type of the signal 3047 * is #G_TYPE_NONE, the return value location can be omitted. 3048 * 3049 * Emits a signal. 3050 * 3051 * Note that g_signal_emit_by_name() resets the return value to the default 3052 * if no handlers are connected, in contrast to g_signal_emitv(). 3053 */ 3054 void 3055 g_signal_emit_by_name (gpointer instance, 3056 const gchar *detailed_signal, 3057 ...) 3058 { 3059 GQuark detail = 0; 3060 guint signal_id; 3061 3062 g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance)); 3063 g_return_if_fail (detailed_signal != NULL); 3064 3065 SIGNAL_LOCK (); 3066 signal_id = signal_parse_name (detailed_signal, G_TYPE_FROM_INSTANCE (instance), &detail, TRUE); 3067 SIGNAL_UNLOCK (); 3068 3069 if (signal_id) 3070 { 3071 va_list var_args; 3072 3073 va_start (var_args, detailed_signal); 3074 g_signal_emit_valist (instance, signal_id, detail, var_args); 3075 va_end (var_args); 3076 } 3077 else 3078 g_warning ("%s: signal name `%s' is invalid for instance `%p'", G_STRLOC, detailed_signal, instance); 3079 } 3080 3081 static inline gboolean 3082 accumulate (GSignalInvocationHint *ihint, 3083 GValue *return_accu, 3084 GValue *handler_return, 3085 SignalAccumulator *accumulator) 3086 { 3087 gboolean continue_emission; 3088 3089 if (!accumulator) 3090 return TRUE; 3091 3092 continue_emission = accumulator->func (ihint, return_accu, handler_return, accumulator->data); 3093 g_value_reset (handler_return); 3094 3095 return continue_emission; 3096 } 3097 3098 static gboolean 3099 signal_emit_unlocked_R (SignalNode *node, 3100 GQuark detail, 3101 gpointer instance, 3102 GValue *emission_return, 3103 const GValue *instance_and_params) 3104 { 3105 SignalAccumulator *accumulator; 3106 Emission emission; 3107 GClosure *class_closure; 3108 HandlerList *hlist; 3109 Handler *handler_list = NULL; 3110 GValue *return_accu, accu = { 0, }; 3111 guint signal_id; 3112 gulong max_sequential_handler_number; 3113 gboolean return_value_altered = FALSE; 3114 3115 #ifdef G_ENABLE_DEBUG 3116 IF_DEBUG (SIGNALS, g_trace_instance_signals == instance || g_trap_instance_signals == instance) 3117 { 3118 g_message ("%s::%s(%u) emitted (instance=%p, signal-node=%p)", 3119 g_type_name (G_TYPE_FROM_INSTANCE (instance)), 3120 node->name, detail, 3121 instance, node); 3122 if (g_trap_instance_signals == instance) 3123 G_BREAKPOINT (); 3124 } 3125 #endif /* G_ENABLE_DEBUG */ 3126 3127 SIGNAL_LOCK (); 3128 signal_id = node->signal_id; 3129 if (node->flags & G_SIGNAL_NO_RECURSE) 3130 { 3131 Emission *node = emission_find (g_restart_emissions, signal_id, detail, instance); 3132 3133 if (node) 3134 { 3135 node->state = EMISSION_RESTART; 3136 SIGNAL_UNLOCK (); 3137 return return_value_altered; 3138 } 3139 } 3140 accumulator = node->accumulator; 3141 if (accumulator) 3142 { 3143 SIGNAL_UNLOCK (); 3144 g_value_init (&accu, node->return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE); 3145 return_accu = &accu; 3146 SIGNAL_LOCK (); 3147 } 3148 else 3149 return_accu = emission_return; 3150 emission.instance = instance; 3151 emission.ihint.signal_id = node->signal_id; 3152 emission.ihint.detail = detail; 3153 emission.ihint.run_type = 0; 3154 emission.state = 0; 3155 emission.chain_type = G_TYPE_NONE; 3156 emission_push ((node->flags & G_SIGNAL_NO_RECURSE) ? &g_restart_emissions : &g_recursive_emissions, &emission); 3157 class_closure = signal_lookup_closure (node, instance); 3158 3159 EMIT_RESTART: 3160 3161 if (handler_list) 3162 handler_unref_R (signal_id, instance, handler_list); 3163 max_sequential_handler_number = g_handler_sequential_number; 3164 hlist = handler_list_lookup (signal_id, instance); 3165 handler_list = hlist ? hlist->handlers : NULL; 3166 if (handler_list) 3167 handler_ref (handler_list); 3168 3169 emission.ihint.run_type = G_SIGNAL_RUN_FIRST; 3170 3171 if ((node->flags & G_SIGNAL_RUN_FIRST) && class_closure) 3172 { 3173 emission.state = EMISSION_RUN; 3174 3175 emission.chain_type = G_TYPE_FROM_INSTANCE (instance); 3176 SIGNAL_UNLOCK (); 3177 g_closure_invoke (class_closure, 3178 return_accu, 3179 node->n_params + 1, 3180 instance_and_params, 3181 &emission.ihint); 3182 if (!accumulate (&emission.ihint, emission_return, &accu, accumulator) && 3183 emission.state == EMISSION_RUN) 3184 emission.state = EMISSION_STOP; 3185 SIGNAL_LOCK (); 3186 emission.chain_type = G_TYPE_NONE; 3187 return_value_altered = TRUE; 3188 3189 if (emission.state == EMISSION_STOP) 3190 goto EMIT_CLEANUP; 3191 else if (emission.state == EMISSION_RESTART) 3192 goto EMIT_RESTART; 3193 } 3194 3195 if (node->emission_hooks) 3196 { 3197 gboolean need_destroy, was_in_call, may_recurse = TRUE; 3198 GHook *hook; 3199 3200 emission.state = EMISSION_HOOK; 3201 hook = g_hook_first_valid (node->emission_hooks, may_recurse); 3202 while (hook) 3203 { 3204 SignalHook *signal_hook = SIGNAL_HOOK (hook); 3205 3206 if (!signal_hook->detail || signal_hook->detail == detail) 3207 { 3208 GSignalEmissionHook hook_func = (GSignalEmissionHook) hook->func; 3209 3210 was_in_call = G_HOOK_IN_CALL (hook); 3211 hook->flags |= G_HOOK_FLAG_IN_CALL; 3212 SIGNAL_UNLOCK (); 3213 need_destroy = !hook_func (&emission.ihint, node->n_params + 1, instance_and_params, hook->data); 3214 SIGNAL_LOCK (); 3215 if (!was_in_call) 3216 hook->flags &= ~G_HOOK_FLAG_IN_CALL; 3217 if (need_destroy) 3218 g_hook_destroy_link (node->emission_hooks, hook); 3219 } 3220 hook = g_hook_next_valid (node->emission_hooks, hook, may_recurse); 3221 } 3222 3223 if (emission.state == EMISSION_RESTART) 3224 goto EMIT_RESTART; 3225 } 3226 3227 if (handler_list) 3228 { 3229 Handler *handler = handler_list; 3230 3231 emission.state = EMISSION_RUN; 3232 handler_ref (handler); 3233 do 3234 { 3235 Handler *tmp; 3236 3237 if (handler->after) 3238 { 3239 handler_unref_R (signal_id, instance, handler_list); 3240 handler_list = handler; 3241 break; 3242 } 3243 else if (!handler->block_count && (!handler->detail || handler->detail == detail) && 3244 handler->sequential_number < max_sequential_handler_number) 3245 { 3246 SIGNAL_UNLOCK (); 3247 g_closure_invoke (handler->closure, 3248 return_accu, 3249 node->n_params + 1, 3250 instance_and_params, 3251 &emission.ihint); 3252 if (!accumulate (&emission.ihint, emission_return, &accu, accumulator) && 3253 emission.state == EMISSION_RUN) 3254 emission.state = EMISSION_STOP; 3255 SIGNAL_LOCK (); 3256 return_value_altered = TRUE; 3257 3258 tmp = emission.state == EMISSION_RUN ? handler->next : NULL; 3259 } 3260 else 3261 tmp = handler->next; 3262 3263 if (tmp) 3264 handler_ref (tmp); 3265 handler_unref_R (signal_id, instance, handler_list); 3266 handler_list = handler; 3267 handler = tmp; 3268 } 3269 while (handler); 3270 3271 if (emission.state == EMISSION_STOP) 3272 goto EMIT_CLEANUP; 3273 else if (emission.state == EMISSION_RESTART) 3274 goto EMIT_RESTART; 3275 } 3276 3277 emission.ihint.run_type = G_SIGNAL_RUN_LAST; 3278 3279 if ((node->flags & G_SIGNAL_RUN_LAST) && class_closure) 3280 { 3281 emission.state = EMISSION_RUN; 3282 3283 emission.chain_type = G_TYPE_FROM_INSTANCE (instance); 3284 SIGNAL_UNLOCK (); 3285 g_closure_invoke (class_closure, 3286 return_accu, 3287 node->n_params + 1, 3288 instance_and_params, 3289 &emission.ihint); 3290 if (!accumulate (&emission.ihint, emission_return, &accu, accumulator) && 3291 emission.state == EMISSION_RUN) 3292 emission.state = EMISSION_STOP; 3293 SIGNAL_LOCK (); 3294 emission.chain_type = G_TYPE_NONE; 3295 return_value_altered = TRUE; 3296 3297 if (emission.state == EMISSION_STOP) 3298 goto EMIT_CLEANUP; 3299 else if (emission.state == EMISSION_RESTART) 3300 goto EMIT_RESTART; 3301 } 3302 3303 if (handler_list) 3304 { 3305 Handler *handler = handler_list; 3306 3307 emission.state = EMISSION_RUN; 3308 handler_ref (handler); 3309 do 3310 { 3311 Handler *tmp; 3312 3313 if (handler->after && !handler->block_count && (!handler->detail || handler->detail == detail) && 3314 handler->sequential_number < max_sequential_handler_number) 3315 { 3316 SIGNAL_UNLOCK (); 3317 g_closure_invoke (handler->closure, 3318 return_accu, 3319 node->n_params + 1, 3320 instance_and_params, 3321 &emission.ihint); 3322 if (!accumulate (&emission.ihint, emission_return, &accu, accumulator) && 3323 emission.state == EMISSION_RUN) 3324 emission.state = EMISSION_STOP; 3325 SIGNAL_LOCK (); 3326 return_value_altered = TRUE; 3327 3328 tmp = emission.state == EMISSION_RUN ? handler->next : NULL; 3329 } 3330 else 3331 tmp = handler->next; 3332 3333 if (tmp) 3334 handler_ref (tmp); 3335 handler_unref_R (signal_id, instance, handler); 3336 handler = tmp; 3337 } 3338 while (handler); 3339 3340 if (emission.state == EMISSION_STOP) 3341 goto EMIT_CLEANUP; 3342 else if (emission.state == EMISSION_RESTART) 3343 goto EMIT_RESTART; 3344 } 3345 3346 EMIT_CLEANUP: 3347 3348 emission.ihint.run_type = G_SIGNAL_RUN_CLEANUP; 3349 3350 if ((node->flags & G_SIGNAL_RUN_CLEANUP) && class_closure) 3351 { 3352 gboolean need_unset = FALSE; 3353 3354 emission.state = EMISSION_STOP; 3355 3356 emission.chain_type = G_TYPE_FROM_INSTANCE (instance); 3357 SIGNAL_UNLOCK (); 3358 if (node->return_type != G_TYPE_NONE && !accumulator) 3359 { 3360 g_value_init (&accu, node->return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE); 3361 need_unset = TRUE; 3362 } 3363 g_closure_invoke (class_closure, 3364 node->return_type != G_TYPE_NONE ? &accu : NULL, 3365 node->n_params + 1, 3366 instance_and_params, 3367 &emission.ihint); 3368 if (need_unset) 3369 g_value_unset (&accu); 3370 SIGNAL_LOCK (); 3371 emission.chain_type = G_TYPE_NONE; 3372 3373 if (emission.state == EMISSION_RESTART) 3374 goto EMIT_RESTART; 3375 } 3376 3377 if (handler_list) 3378 handler_unref_R (signal_id, instance, handler_list); 3379 3380 emission_pop ((node->flags & G_SIGNAL_NO_RECURSE) ? &g_restart_emissions : &g_recursive_emissions, &emission); 3381 SIGNAL_UNLOCK (); 3382 if (accumulator) 3383 g_value_unset (&accu); 3384 3385 return return_value_altered; 3386 } 3387 3388 static const gchar* 3389 type_debug_name (GType type) 3390 { 3391 if (type) 3392 { 3393 const char *name = g_type_name (type & ~G_SIGNAL_TYPE_STATIC_SCOPE); 3394 return name ? name : "<unknown>"; 3395 } 3396 else 3397 return "<invalid>"; 3398 } 3399 3400 /** 3401 * g_signal_accumulator_true_handled: 3402 * @ihint: standard #GSignalAccumulator parameter 3403 * @return_accu: standard #GSignalAccumulator parameter 3404 * @handler_return: standard #GSignalAccumulator parameter 3405 * @dummy: standard #GSignalAccumulator parameter 3406 * 3407 * A predefined #GSignalAccumulator for signals that return a 3408 * boolean values. The behavior that this accumulator gives is 3409 * that a return of %TRUE stops the signal emission: no further 3410 * callbacks will be invoked, while a return of %FALSE allows 3411 * the emission to coninue. The idea here is that a %TRUE return 3412 * indicates that the callback <emphasis>handled</emphasis> the signal, 3413 * and no further handling is needed. 3414 * 3415 * Since: 2.4 3416 * 3417 * Returns: standard #GSignalAccumulator result 3418 */ 3419 gboolean 3420 g_signal_accumulator_true_handled (GSignalInvocationHint *ihint, 3421 GValue *return_accu, 3422 const GValue *handler_return, 3423 gpointer dummy) 3424 { 3425 gboolean continue_emission; 3426 gboolean signal_handled; 3427 3428 signal_handled = g_value_get_boolean (handler_return); 3429 g_value_set_boolean (return_accu, signal_handled); 3430 continue_emission = !signal_handled; 3431 3432 return continue_emission; 3433 } 3434 3435 /* --- compile standard marshallers --- */ 3436 #include "gmarshal.c" 3437 3438 #define __G_SIGNAL_C__ 3439 #include "gobjectaliasdef.c" 3440