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