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