Add g_signal_connect define to make porting from gtk_signal_connect easy.
[platform/upstream/glib.git] / gobject / gsignal.c
1 /* GObject - GLib Type, Object, Parameter and Signal Library
2  * Copyright (C) 2000 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        <string.h> 
31
32
33 /* pre allocation configurations
34  */
35 #define MAX_STACK_VALUES        (16)
36 #define BSA_PRE_ALLOC           (20)
37 #define HANDLER_PRE_ALLOC       (48)
38 #define EMISSION_PRE_ALLOC      (16)
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                                                          guint            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 inline void              emission_push           (Emission       **emission_list_p,
132                                                          guint            signal_id,
133                                                          GQuark           detail,
134                                                          gpointer         instance,
135                                                          EmissionState   *state_p);
136 static inline void              emission_pop            (Emission       **emission_list_p,
137                                                          EmissionState   *state_p);
138 static inline Emission*         emission_find           (Emission        *emission_list,
139                                                          guint            signal_id,
140                                                          GQuark           detail,
141                                                          gpointer         instance);
142 static        gboolean          signal_emit_R           (SignalNode      *node,
143                                                          GQuark           detail,
144                                                          gpointer         instance,
145                                                          GValue          *return_value,
146                                                          const GValue    *instance_and_params);
147
148
149 /* --- structures --- */
150 struct _SignalNode
151 {
152   /* permanent portion */
153   guint              signal_id;
154   GType              itype;
155   gchar             *name;
156   guint              destroyed : 1;
157   
158   /* reinitializable portion */
159   guint              flags : 8;
160   guint              n_params : 8;
161   GType             *param_types; /* mangled with G_SIGNAL_TYPE_STATIC_SCOPE flag */
162   GType              return_type; /* mangled with G_SIGNAL_TYPE_STATIC_SCOPE flag */
163   GClosure          *class_closure;
164   GSignalAccumulator accumulator;
165   GSignalCMarshaller c_marshaller;
166   GHookList         *emission_hooks;
167 };
168
169 struct _SignalKey
170 {
171   GType  itype;
172   GQuark quark;
173   guint  signal_id;
174 };
175
176 struct _Emission
177 {
178   Emission      *next;
179   guint          signal_id;
180   GQuark         detail;
181   gpointer       instance;
182   EmissionState *state_p;
183 };
184
185 struct _HandlerList
186 {
187   guint    signal_id;
188   Handler *handlers;
189 };
190 struct _Handler
191 {
192   guint         id;
193   Handler      *next;
194   Handler      *prev;
195   GQuark        detail;
196   guint         ref_count : 16;
197 #define HANDLER_MAX_REF_COUNT   (1 << 16)
198   guint         block_count : 12;
199 #define HANDLER_MAX_BLOCK_COUNT (1 << 12)
200   guint         after : 1;
201   GClosure     *closure;
202 };
203 struct _HandlerMatch
204 {
205   Handler      *handler;
206   HandlerMatch *next;
207   union {
208     guint       signal_id;
209     gpointer    dummy;
210   } d;
211 };
212
213
214 /* --- variables --- */
215 static GBSearchArray  g_signal_key_bsa = { NULL, 0, 0, 0, NULL };
216 static GHashTable    *g_handler_list_bsa_ht = NULL;
217 static Emission      *g_recursive_emissions = NULL;
218 static Emission      *g_restart_emissions = NULL;
219 static GTrashStack   *g_bsa_ts = NULL;
220 static GTrashStack   *g_handler_ts = NULL;
221 static GTrashStack   *g_emission_ts = NULL;
222 G_LOCK_DEFINE_STATIC (g_signal_mutex);
223
224
225 /* --- signal nodes --- */
226 static guint          g_n_signal_nodes = 0;
227 static SignalNode   **g_signal_nodes = NULL;
228
229 static inline SignalNode*
230 LOOKUP_SIGNAL_NODE (register guint signal_id)
231 {
232   if (signal_id < g_n_signal_nodes)
233     return g_signal_nodes[signal_id];
234   else
235     return NULL;
236 }
237
238
239 /* --- functions --- */
240 static inline guint
241 signal_id_lookup (GQuark quark,
242                   GType  itype)
243 {
244   GType *ifaces, type = itype;
245   SignalKey key;
246   guint n_ifaces;
247
248   key.quark = quark;
249
250   /* try looking up signals for this type and its anchestors */
251   do
252     {
253       SignalKey *signal_key;
254       
255       key.itype = type;
256       signal_key = g_bsearch_array_lookup (&g_signal_key_bsa, &key);
257       
258       if (signal_key)
259         return signal_key->signal_id;
260       
261       type = g_type_parent (type);
262     }
263   while (type);
264
265   /* no luck, try interfaces it exports */
266   ifaces = g_type_interfaces (itype, &n_ifaces);
267   while (n_ifaces--)
268     {
269       SignalKey *signal_key;
270
271       key.itype = ifaces[n_ifaces];
272       signal_key = g_bsearch_array_lookup (&g_signal_key_bsa, &key);
273
274       if (signal_key)
275         {
276           g_free (ifaces);
277           return signal_key->signal_id;
278         }
279     }
280   g_free (ifaces);
281   
282   return 0;
283 }
284
285 static gint
286 handler_lists_cmp (gconstpointer node1,
287                    gconstpointer node2)
288 {
289   const HandlerList *hlist1 = node1, *hlist2 = node2;
290   
291   return G_BSEARCH_ARRAY_CMP (hlist1->signal_id, hlist2->signal_id);
292 }
293
294 static inline HandlerList*
295 handler_list_ensure (guint    signal_id,
296                      gpointer instance)
297 {
298   GBSearchArray *hlbsa = g_hash_table_lookup (g_handler_list_bsa_ht, instance);
299   HandlerList key;
300   
301   if (!hlbsa)
302     {
303       hlbsa = g_generic_node_alloc (&g_bsa_ts,
304                                     sizeof (GBSearchArray),
305                                     BSA_PRE_ALLOC);
306       hlbsa->cmp_func = handler_lists_cmp;
307       hlbsa->sizeof_node = sizeof (HandlerList);
308       hlbsa->flags = G_BSEARCH_DEFER_SHRINK;
309       hlbsa->n_nodes = 0;
310       hlbsa->nodes = NULL;
311       g_hash_table_insert (g_handler_list_bsa_ht, instance, hlbsa);
312     }
313   key.signal_id = signal_id;
314   key.handlers = NULL;
315   
316   return g_bsearch_array_insert (hlbsa, &key, FALSE);
317 }
318
319 static inline HandlerList*
320 handler_list_lookup (guint    signal_id,
321                      gpointer instance)
322 {
323   GBSearchArray *hlbsa = g_hash_table_lookup (g_handler_list_bsa_ht, instance);
324   HandlerList key;
325   
326   key.signal_id = signal_id;
327   
328   return hlbsa ? g_bsearch_array_lookup (hlbsa, &key) : NULL;
329 }
330
331 static Handler*
332 handler_lookup (gpointer instance,
333                 guint    handler_id,
334                 guint   *signal_id_p)
335 {
336   GBSearchArray *hlbsa = g_hash_table_lookup (g_handler_list_bsa_ht, instance);
337   
338   if (hlbsa)
339     {
340       guint i;
341       
342       for (i = 0; i < hlbsa->n_nodes; i++)
343         {
344           HandlerList *hlist = g_bsearch_array_get_nth (hlbsa, i);
345           Handler *handler;
346           
347           for (handler = hlist->handlers; handler; handler = handler->next)
348             if (handler->id == handler_id)
349               {
350                 if (signal_id_p)
351                   *signal_id_p = hlist->signal_id;
352                 
353                 return handler;
354               }
355         }
356     }
357   
358   return NULL;
359 }
360
361 static inline HandlerMatch*
362 handler_match_prepend (HandlerMatch *list,
363                        Handler      *handler,
364                        guint         signal_id)
365 {
366   HandlerMatch *node;
367   
368   /* yeah, we could use our own memchunk here, introducing yet more
369    * rarely used cached nodes and extra allocation overhead.
370    * instead, we use GList* nodes, since they are exactly the size
371    * we need and are already cached. g_signal_init() asserts this.
372    */
373   node = (HandlerMatch*) g_list_alloc ();
374   node->handler = handler;
375   node->next = list;
376   node->d.signal_id = signal_id;
377   handler_ref (handler);
378   
379   return node;
380 }
381 static inline HandlerMatch*
382 handler_match_free1_R (HandlerMatch *node,
383                        gpointer      instance)
384 {
385   HandlerMatch *next = node->next;
386   
387   handler_unref_R (node->d.signal_id, instance, node->handler);
388   g_list_free_1 ((GList*) node);
389   
390   return next;
391 }
392
393 static HandlerMatch*
394 handlers_find (gpointer         instance,
395                GSignalMatchType mask,
396                guint            signal_id,
397                GQuark           detail,
398                GClosure        *closure,
399                gpointer         func,
400                gpointer         data,
401                gboolean         one_and_only)
402 {
403   HandlerMatch *mlist = NULL;
404   
405   if (mask & G_SIGNAL_MATCH_ID)
406     {
407       HandlerList *hlist = handler_list_lookup (signal_id, instance);
408       Handler *handler;
409       SignalNode *node = NULL;
410       
411       if (mask & G_SIGNAL_MATCH_FUNC)
412         {
413           node = LOOKUP_SIGNAL_NODE (signal_id);
414           if (!node || !node->c_marshaller)
415             return NULL;
416         }
417       
418       mask = ~mask;
419       for (handler = hlist ? hlist->handlers : NULL; handler; handler = handler->next)
420         if (handler->id &&
421             ((mask & G_SIGNAL_MATCH_DETAIL) || handler->detail == detail) &&
422             ((mask & G_SIGNAL_MATCH_CLOSURE) || handler->closure == closure) &&
423             ((mask & G_SIGNAL_MATCH_DATA) || handler->closure->data == data) &&
424             ((mask & G_SIGNAL_MATCH_UNBLOCKED) || handler->block_count == 0) &&
425             ((mask & G_SIGNAL_MATCH_FUNC) || (handler->closure->marshal == node->c_marshaller &&
426                                               handler->closure->meta_marshal == 0 &&
427                                               ((GCClosure*) handler->closure)->callback == func)))
428           {
429             mlist = handler_match_prepend (mlist, handler, signal_id);
430             if (one_and_only)
431               return mlist;
432           }
433     }
434   else
435     {
436       GBSearchArray *hlbsa = g_hash_table_lookup (g_handler_list_bsa_ht, instance);
437       
438       mask = ~mask;
439       if (hlbsa)
440         {
441           guint i;
442           
443           for (i = 0; i < hlbsa->n_nodes; i++)
444             {
445               HandlerList *hlist = g_bsearch_array_get_nth (hlbsa, i);
446               SignalNode *node = NULL;
447               Handler *handler;
448               
449               if (!(mask & G_SIGNAL_MATCH_FUNC))
450                 {
451                   node = LOOKUP_SIGNAL_NODE (hlist->signal_id);
452                   if (!node->c_marshaller)
453                     continue;
454                 }
455               
456               for (handler = hlist->handlers; handler; handler = handler->next)
457                 if (handler->id &&
458                     ((mask & G_SIGNAL_MATCH_DETAIL) || handler->detail == detail) &&
459                     ((mask & G_SIGNAL_MATCH_CLOSURE) || handler->closure == closure) &&
460                     ((mask & G_SIGNAL_MATCH_DATA) || handler->closure->data == data) &&
461                     ((mask & G_SIGNAL_MATCH_UNBLOCKED) || handler->block_count == 0) &&
462                     ((mask & G_SIGNAL_MATCH_FUNC) || (handler->closure->marshal == node->c_marshaller &&
463                                                       handler->closure->meta_marshal == 0 &&
464                                                       ((GCClosure*) handler->closure)->callback == func)))
465                   {
466                     mlist = handler_match_prepend (mlist, handler, hlist->signal_id);
467                     if (one_and_only)
468                       return mlist;
469                   }
470             }
471         }
472     }
473   
474   return mlist;
475 }
476
477 static inline Handler*
478 handler_new (gboolean after)
479 {
480   static guint handler_id = 1;
481   Handler *handler = g_generic_node_alloc (&g_handler_ts,
482                                            sizeof (Handler),
483                                            HANDLER_PRE_ALLOC);
484 #ifndef G_DISABLE_CHECKS
485   if (handler_id == 0)
486     g_error (G_STRLOC ": handler id overflow, %s", REPORT_BUG);
487 #endif
488   
489   handler->id = handler_id++;
490   handler->prev = NULL;
491   handler->next = NULL;
492   handler->detail = 0;
493   handler->ref_count = 1;
494   handler->block_count = 0;
495   handler->after = after != FALSE;
496   handler->closure = NULL;
497   
498   return handler;
499 }
500
501 static inline void
502 handler_ref (Handler *handler)
503 {
504   g_return_if_fail (handler->ref_count > 0);
505   
506 #ifndef G_DISABLE_CHECKS
507   if (handler->ref_count >= HANDLER_MAX_REF_COUNT - 1)
508     g_error (G_STRLOC ": handler ref_count overflow, %s", REPORT_BUG);
509 #endif
510   
511   handler->ref_count += 1;
512 }
513
514 static inline void
515 handler_unref_R (guint    signal_id,
516                  gpointer instance,
517                  Handler *handler)
518 {
519   g_return_if_fail (handler->ref_count > 0);
520   
521   handler->ref_count -= 1;
522   if (!handler->ref_count)
523     {
524       if (handler->next)
525         handler->next->prev = handler->prev;
526       if (handler->prev)        /* watch out for g_signal_handlers_destroy()! */
527         handler->prev->next = handler->next;
528       else
529         {
530           HandlerList *hlist = handler_list_lookup (signal_id, instance);
531           
532           hlist->handlers = handler->next;
533         }
534       G_UNLOCK (g_signal_mutex);
535       g_closure_unref (handler->closure);
536       G_LOCK (g_signal_mutex);
537       g_generic_node_free (&g_handler_ts, handler);
538     }
539 }
540
541 static void
542 handler_insert (guint    signal_id,
543                 gpointer instance,
544                 Handler  *handler)
545 {
546   HandlerList *hlist;
547   
548   g_assert (handler->prev == NULL && handler->next == NULL); /* paranoid */
549   
550   hlist = handler_list_ensure (signal_id, instance);
551   if (!hlist->handlers)
552     hlist->handlers = handler;
553   else if (hlist->handlers->after && !handler->after)
554     {
555       handler->next = hlist->handlers;
556       hlist->handlers->prev = handler;
557       hlist->handlers = handler;
558     }
559   else
560     {
561       Handler *tmp = hlist->handlers;
562       
563       if (handler->after)
564         while (tmp->next)
565           tmp = tmp->next;
566       else
567         while (tmp->next && !tmp->next->after)
568           tmp = tmp->next;
569       if (tmp->next)
570         tmp->next->prev = handler;
571       handler->next = tmp->next;
572       handler->prev = tmp;
573       tmp->next = handler;
574     }
575 }
576
577 static inline void
578 emission_push (Emission     **emission_list_p,
579                guint          signal_id,
580                GQuark         detail,
581                gpointer       instance,
582                EmissionState *state_p)
583 {
584   Emission *emission = g_generic_node_alloc (&g_emission_ts,
585                                              sizeof (Emission),
586                                              EMISSION_PRE_ALLOC);
587   emission->next = *emission_list_p;
588   emission->signal_id = signal_id;
589   emission->detail = detail;
590   emission->instance = instance;
591   emission->state_p = state_p;
592   *emission_list_p = emission;
593 }
594
595 static inline void
596 emission_pop (Emission     **emission_list_p,
597               EmissionState *state_p)
598 {
599   Emission **loc = emission_list_p, *emission = *loc;
600   
601   while (emission->state_p != state_p)
602     {
603       loc = &emission->next;
604       emission = *loc;
605     }
606   *loc = emission->next;
607   g_generic_node_free (&g_emission_ts, emission);
608 }
609
610 static inline Emission*
611 emission_find (Emission *emission_list,
612                guint     signal_id,
613                GQuark    detail,
614                gpointer  instance)
615 {
616   Emission *emission;
617   
618   for (emission = emission_list; emission; emission = emission->next)
619     if (emission->instance == instance &&
620         emission->signal_id == signal_id &&
621         emission->detail == detail)
622       return emission;
623   return NULL;
624 }
625
626 static gint
627 signal_key_cmp (gconstpointer node1,
628                 gconstpointer node2)
629 {
630   const SignalKey *key1 = node1, *key2 = node2;
631   
632   if (key1->itype == key2->itype)
633     return G_BSEARCH_ARRAY_CMP (key1->quark, key2->quark);
634   else
635     return G_BSEARCH_ARRAY_CMP (key1->itype, key2->itype);
636 }
637
638 void
639 g_signal_init (void) /* sync with gtype.c */
640 {
641   G_LOCK (g_signal_mutex);
642   if (!g_n_signal_nodes)
643     {
644       /* handler_id_node_prepend() requires this */
645       g_assert (sizeof (GList) == sizeof (HandlerMatch));
646       
647       /* setup signal key array */
648       g_signal_key_bsa.cmp_func = signal_key_cmp;
649       g_signal_key_bsa.sizeof_node = sizeof (SignalKey);
650       g_signal_key_bsa.flags = G_BSEARCH_ALIGN_POWER2; /* alloc-only */
651       
652       /* setup handler list binary searchable array hash table (in german, that'd be one word ;) */
653       g_handler_list_bsa_ht = g_hash_table_new (g_direct_hash, NULL);
654       
655       /* invalid (0) signal_id */
656       g_n_signal_nodes = 1;
657       g_signal_nodes = g_renew (SignalNode*, g_signal_nodes, g_n_signal_nodes);
658       g_signal_nodes[0] = NULL;
659     }
660   G_UNLOCK (g_signal_mutex);
661 }
662
663 void
664 _g_signals_destroy (GType itype)
665 {
666   guint i;
667   
668   G_LOCK (g_signal_mutex);
669   for (i = 1; i < g_n_signal_nodes; i++)
670     {
671       SignalNode *node = g_signal_nodes[i];
672       
673       if (node->itype == itype)
674         {
675           if (node->destroyed)
676             g_warning (G_STRLOC ": signal \"%s\" of type `%s' already destroyed",
677                        node->name,
678                        g_type_name (node->itype));
679           else
680             signal_destroy_R (node);
681         }
682     }
683   G_UNLOCK (g_signal_mutex);
684 }
685
686 void
687 g_signal_stop_emission (gpointer instance,
688                         guint    signal_id,
689                         GQuark   detail)
690 {
691   SignalNode *node;
692   
693   g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance));
694   g_return_if_fail (signal_id > 0);
695   
696   G_LOCK (g_signal_mutex);
697   node = LOOKUP_SIGNAL_NODE (signal_id);
698   if (node && detail && !(node->flags & G_SIGNAL_DETAILED))
699     {
700       g_warning ("%s: signal id `%u' does not support detail (%u)", G_STRLOC, signal_id, detail);
701       G_UNLOCK (g_signal_mutex);
702       return;
703     }
704   if (node && g_type_is_a (G_TYPE_FROM_INSTANCE (instance), node->itype))
705     {
706       Emission *emission_list = node->flags & G_SIGNAL_NO_RECURSE ? g_restart_emissions : g_recursive_emissions;
707       Emission *emission = emission_find (emission_list, signal_id, detail, instance);
708       
709       if (emission)
710         {
711           if (*emission->state_p == EMISSION_HOOK)
712             g_warning (G_STRLOC ": emission of signal \"%s\" for instance `%p' cannot be stopped from emission hook",
713                        node->name, instance);
714           else if (*emission->state_p == EMISSION_RUN)
715             *emission->state_p = EMISSION_STOP;
716         }
717       else
718         g_warning (G_STRLOC ": no emission of signal \"%s\" to stop for instance `%p'",
719                    node->name, instance);
720     }
721   else
722     g_warning ("%s: signal id `%u' is invalid for instance `%p'", G_STRLOC, signal_id, instance);
723   G_UNLOCK (g_signal_mutex);
724 }
725
726 static inline guint
727 signal_parse_name (const gchar *name,
728                    GType        itype,
729                    GQuark      *detail_p,
730                    gboolean     force_quark)
731 {
732   const gchar *colon = strchr (name, ':');
733   guint signal_id;
734   
735   if (!colon)
736     {
737       signal_id = signal_id_lookup (g_quark_try_string (name), itype);
738       if (signal_id && detail_p)
739         *detail_p = 0;
740     }
741   else if (colon[1] == ':')
742     {
743       gchar buffer[32];
744       guint l = colon - name;
745       
746       if (l < 32)
747         {
748           memcpy (buffer, name, l);
749           buffer[l] = 0;
750           signal_id = signal_id_lookup (g_quark_try_string (buffer), itype);
751         }
752       else
753         {
754           gchar *signal = g_new (gchar, l + 1);
755           
756           memcpy (signal, name, l);
757           signal[l] = 0;
758           signal_id = signal_id_lookup (g_quark_try_string (signal), itype);
759           g_free (signal);
760         }
761       
762       if (signal_id && detail_p)
763         *detail_p = colon[2] ? (force_quark ? g_quark_from_string : g_quark_try_string) (colon + 2) : 0;
764     }
765   else
766     signal_id = 0;
767   return signal_id;
768 }
769
770 gboolean
771 g_signal_parse_name (const gchar *detailed_signal,
772                      GType        itype,
773                      guint       *signal_id_p,
774                      GQuark      *detail_p,
775                      gboolean     force_detail_quark)
776 {
777   GQuark detail = 0;
778   guint signal_id;
779   
780   g_return_val_if_fail (detailed_signal != NULL, FALSE);
781   g_return_val_if_fail (G_TYPE_IS_INSTANTIATABLE (itype) || G_TYPE_IS_INTERFACE (itype), FALSE);
782   
783   G_LOCK (g_signal_mutex);
784   signal_id = signal_parse_name (detailed_signal, itype, &detail, force_detail_quark);
785   G_UNLOCK (g_signal_mutex);
786   
787   if (signal_id)
788     {
789       if (signal_id_p)
790         *signal_id_p = signal_id;
791       if (detail_p)
792         *detail_p = detail;
793       
794       return TRUE;
795     }
796   else
797     return FALSE;
798 }
799
800 guint
801 g_signal_lookup (const gchar *name,
802                  GType        itype)
803 {
804   guint signal_id;
805   
806   g_return_val_if_fail (name != NULL, 0);
807   g_return_val_if_fail (G_TYPE_IS_INSTANTIATABLE (itype) || G_TYPE_IS_INTERFACE (itype), 0);
808   
809   G_LOCK (g_signal_mutex);
810   signal_id = signal_id_lookup (g_quark_try_string (name), itype);
811   G_UNLOCK (g_signal_mutex);
812   
813   return signal_id;
814 }
815
816 G_CONST_RETURN gchar*
817 g_signal_name (guint signal_id)
818 {
819   SignalNode *node;
820   gchar *name;
821   
822   G_LOCK (g_signal_mutex);
823   node = LOOKUP_SIGNAL_NODE (signal_id);
824   name = node ? node->name : NULL;
825   G_UNLOCK (g_signal_mutex);
826   
827   return name;
828 }
829
830 void
831 g_signal_query (guint         signal_id,
832                 GSignalQuery *query)
833 {
834   SignalNode *node;
835   
836   g_return_if_fail (query != NULL);
837   
838   G_LOCK (g_signal_mutex);
839   node = LOOKUP_SIGNAL_NODE (signal_id);
840   if (!node || node->destroyed)
841     query->signal_id = 0;
842   else
843     {
844       query->signal_id = node->signal_id;
845       query->signal_name = node->name;
846       query->itype = node->itype;
847       query->signal_flags = node->flags;
848       query->return_type = node->return_type;
849       query->n_params = node->n_params;
850       query->param_types = node->param_types;
851     }
852   G_UNLOCK (g_signal_mutex);
853 }
854
855 guint*
856 g_signal_list_ids (GType  itype,
857                    guint *n_ids)
858 {
859   SignalKey *keys;
860   GArray *result;
861   guint n_nodes;
862   guint i;
863   
864   g_return_val_if_fail (G_TYPE_IS_INSTANTIATABLE (itype) || G_TYPE_IS_INTERFACE (itype), NULL);
865   g_return_val_if_fail (n_ids != NULL, NULL);
866   
867   G_LOCK (g_signal_mutex);
868   
869   keys = g_signal_key_bsa.nodes;
870   n_nodes  = g_signal_key_bsa.n_nodes;
871   result = g_array_new (FALSE, FALSE, sizeof (guint));
872   
873   for (i = 0; i < n_nodes; i++)
874     if (keys[i].itype == itype)
875       {
876         const gchar *name = g_quark_to_string (keys[i].quark);
877         
878         /* Signal names with "_" in them are aliases to the same
879          * name with "-" instead of "_".
880          */
881         if (!strchr (name, '_'))
882           g_array_append_val (result, keys[i].signal_id);
883       }
884   
885   *n_ids = result->len;
886   
887   G_UNLOCK (g_signal_mutex);
888   
889   return (guint *) g_array_free (result, FALSE);
890 }
891
892 guint
893 g_signal_new_valist (const gchar       *signal_name,
894                      GType              itype,
895                      GSignalFlags       signal_flags,
896                      GClosure          *class_closure,
897                      GSignalAccumulator accumulator,
898                      GSignalCMarshaller c_marshaller,
899                      GType              return_type,
900                      guint              n_params,
901                      va_list            args)
902 {
903   GType *param_types;
904   guint i;
905   guint signal_id;
906
907   if (n_params > 0)
908     {
909       param_types = g_new (GType, n_params);
910
911       for (i = 0; i < n_params; i++)
912         param_types[i] = va_arg (args, GType);
913     }
914   else
915     param_types = NULL;
916
917   signal_id = g_signal_newv (signal_name, itype, signal_flags,
918                              class_closure, accumulator, c_marshaller,
919                              return_type, n_params, param_types);
920   g_free (param_types);
921
922   return signal_id;
923 }
924
925 guint
926 g_signal_newc (const gchar       *signal_name,
927                GType              itype,
928                GSignalFlags       signal_flags,
929                guint              class_offset,
930                GSignalAccumulator accumulator,
931                GSignalCMarshaller c_marshaller,
932                GType              return_type,
933                guint              n_params,
934                ...)
935 {
936   va_list args;
937   guint signal_id;
938
939   g_return_val_if_fail (signal_name != NULL, 0);
940   
941   va_start (args, n_params);
942
943   signal_id = g_signal_new_valist (signal_name, itype, signal_flags,
944                                    g_signal_type_cclosure_new (itype, class_offset),
945                                    accumulator, c_marshaller,
946                                    return_type, n_params, args);
947
948   va_end (args);
949  
950   return signal_id;
951 }
952
953 guint
954 g_signal_newv (const gchar       *signal_name,
955                GType              itype,
956                GSignalFlags       signal_flags,
957                GClosure          *class_closure,
958                GSignalAccumulator accumulator,
959                GSignalCMarshaller c_marshaller,
960                GType              return_type,
961                guint              n_params,
962                GType             *param_types)
963 {
964   gchar *name;
965   guint signal_id, i;
966   SignalNode *node;
967   
968   g_return_val_if_fail (signal_name != NULL, 0);
969   g_return_val_if_fail (G_TYPE_IS_INSTANTIATABLE (itype) || G_TYPE_IS_INTERFACE (itype), 0);
970   if (n_params)
971     g_return_val_if_fail (param_types != NULL, 0);
972   if (return_type != G_TYPE_NONE)
973     g_return_val_if_fail (accumulator == NULL, 0);
974   
975   name = g_strdup (signal_name);
976   g_strdelimit (name, G_STR_DELIMITERS ":^", '_');  // FIXME do character checks like for types
977   
978   G_LOCK (g_signal_mutex);
979   
980   signal_id = signal_id_lookup (g_quark_try_string (name), itype);
981   node = LOOKUP_SIGNAL_NODE (signal_id);
982   if (node && !node->destroyed)
983     {
984       g_warning (G_STRLOC ": signal \"%s\" already exists in the `%s' %s",
985                  name,
986                  g_type_name (node->itype),
987                  G_TYPE_IS_INTERFACE (node->itype) ? "interface" : "class ancestry");
988       g_free (name);
989       G_UNLOCK (g_signal_mutex);
990       return 0;
991     }
992   if (node && node->itype != itype)
993     {
994       g_warning (G_STRLOC ": signal \"%s\" for type `%s' was previously created for type `%s'",
995                  name,
996                  g_type_name (itype),
997                  g_type_name (node->itype));
998       g_free (name);
999       G_UNLOCK (g_signal_mutex);
1000       return 0;
1001     }
1002   for (i = 0; i < n_params; i++)
1003     if (!G_TYPE_IS_VALUE (param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE) ||
1004         (param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE) == G_TYPE_ENUM ||
1005         (param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE) == G_TYPE_FLAGS) /* FIXME: kludge */
1006       {
1007         g_warning (G_STRLOC ": parameter %d of type `%s' for signal \"%s::%s\" is not a value type",
1008                    i + 1, g_type_name (param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE), g_type_name (itype), name);
1009         g_free (name);
1010         G_UNLOCK (g_signal_mutex);
1011         return 0;
1012       }
1013   if (return_type != G_TYPE_NONE && !G_TYPE_IS_VALUE (return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE))
1014     {
1015       g_warning (G_STRLOC ": return value of type `%s' for signal \"%s::%s\" is not a value type",
1016                  g_type_name (return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE), g_type_name (itype), name);
1017       g_free (name);
1018       G_UNLOCK (g_signal_mutex);
1019       return 0;
1020     }
1021   
1022   /* setup permanent portion of signal node */
1023   if (!node)
1024     {
1025       SignalKey key;
1026       
1027       signal_id = g_n_signal_nodes++;
1028       node = g_new (SignalNode, 1);
1029       node->signal_id = signal_id;
1030       g_signal_nodes = g_renew (SignalNode*, g_signal_nodes, g_n_signal_nodes);
1031       g_signal_nodes[signal_id] = node;
1032       node->itype = itype;
1033       node->name = name;
1034       key.itype = itype;
1035       key.quark = g_quark_from_string (node->name);
1036       key.signal_id = signal_id;
1037       g_bsearch_array_insert (&g_signal_key_bsa, &key, FALSE);
1038       g_strdelimit (node->name, "_", '-');
1039       key.quark = g_quark_from_static_string (node->name);
1040       g_bsearch_array_insert (&g_signal_key_bsa, &key, FALSE);
1041     }
1042   node->destroyed = FALSE;
1043   
1044   /* setup reinitializable portion */
1045   node->flags = signal_flags & G_SIGNAL_FLAGS_MASK;
1046   node->n_params = n_params;
1047   node->param_types = g_memdup (param_types, sizeof (GType) * n_params);
1048   node->return_type = return_type;
1049   node->class_closure = class_closure ? g_closure_ref (class_closure) : NULL;
1050   if (class_closure)
1051     g_closure_sink (class_closure);
1052   node->accumulator = accumulator;
1053   node->c_marshaller = c_marshaller;
1054   node->emission_hooks = NULL;
1055   if (node->c_marshaller && class_closure && G_CLOSURE_NEEDS_MARSHAL (class_closure))
1056     g_closure_set_marshal (class_closure, node->c_marshaller);
1057   
1058   G_UNLOCK (g_signal_mutex);
1059   return signal_id;
1060 }
1061
1062 static void
1063 signal_destroy_R (SignalNode *signal_node)
1064 {
1065   SignalNode node = *signal_node;
1066   
1067   signal_node->destroyed = TRUE;
1068   
1069   /* reentrancy caution, zero out real contents first */
1070   signal_node->n_params = 0;
1071   signal_node->param_types = NULL;
1072   signal_node->return_type = 0;
1073   signal_node->class_closure = NULL;
1074   signal_node->accumulator = NULL;
1075   signal_node->c_marshaller = NULL;
1076   signal_node->emission_hooks = NULL;
1077   
1078 #ifdef  G_ENABLE_DEBUG
1079   /* check current emissions */
1080   {
1081     Emission *emission;
1082     
1083     for (emission = (node.flags & G_SIGNAL_NO_RECURSE) ? g_restart_emissions : g_recursive_emissions;
1084          emission; emission = emission->next)
1085       if (emission->signal_id == node.signal_id)
1086         g_critical (G_STRLOC ": signal \"%s\" being destroyed is currently in emission (instance `%p')",
1087                     node.name, emission->instance);
1088   }
1089 #endif
1090   
1091   /* free contents that need to
1092    */
1093   G_UNLOCK (g_signal_mutex);
1094   g_free (node.param_types);
1095   g_closure_unref (node.class_closure);
1096   if (node.emission_hooks)
1097     {
1098       g_hook_list_clear (node.emission_hooks);
1099       g_free (node.emission_hooks);
1100     }
1101   G_LOCK (g_signal_mutex);
1102 }
1103
1104 guint
1105 g_signal_connect_closure_by_id (gpointer  instance,
1106                                 guint     signal_id,
1107                                 GQuark    detail,
1108                                 GClosure *closure,
1109                                 gboolean  after)
1110 {
1111   SignalNode *node;
1112   guint handler_id = 0;
1113   
1114   g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), 0);
1115   g_return_val_if_fail (signal_id > 0, 0);
1116   g_return_val_if_fail (closure != NULL, 0);
1117   
1118   G_LOCK (g_signal_mutex);
1119   node = LOOKUP_SIGNAL_NODE (signal_id);
1120   if (node)
1121     {
1122       if (detail && !(node->flags & G_SIGNAL_DETAILED))
1123         g_warning ("%s: signal id `%u' does not support detail (%u)", G_STRLOC, signal_id, detail);
1124       else if (!g_type_is_a (G_TYPE_FROM_INSTANCE (instance), node->itype))
1125         g_warning ("%s: signal id `%u' is invalid for instance `%p'", G_STRLOC, signal_id, instance);
1126       else
1127         {
1128           Handler *handler = handler_new (after);
1129           
1130           handler_id = handler->id;
1131           handler->detail = detail;
1132           handler->closure = g_closure_ref (closure);
1133           g_closure_sink (closure);
1134           handler_insert (signal_id, instance, handler);
1135           if (node->c_marshaller && G_CLOSURE_NEEDS_MARSHAL (closure))
1136             g_closure_set_marshal (closure, node->c_marshaller);
1137         }
1138     }
1139   else
1140     g_warning ("%s: signal id `%u' is invalid for instance `%p'", G_STRLOC, signal_id, instance);
1141   G_UNLOCK (g_signal_mutex);
1142   
1143   return handler_id;
1144 }
1145
1146 guint
1147 g_signal_connect_closure (gpointer     instance,
1148                           const gchar *detailed_signal,
1149                           GClosure    *closure,
1150                           gboolean     after)
1151 {
1152   guint signal_id, handler_id = 0;
1153   GQuark detail = 0;
1154   GType itype;
1155
1156   g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), 0);
1157   g_return_val_if_fail (detailed_signal != NULL, 0);
1158   g_return_val_if_fail (closure != NULL, 0);
1159
1160   G_LOCK (g_signal_mutex);
1161   itype = G_TYPE_FROM_INSTANCE (instance);
1162   signal_id = signal_parse_name (detailed_signal, itype, &detail, TRUE);
1163   if (signal_id)
1164     {
1165       SignalNode *node = LOOKUP_SIGNAL_NODE (signal_id);
1166
1167       if (detail && !(node->flags & G_SIGNAL_DETAILED))
1168         g_warning ("%s: signal `%s' does not support details", G_STRLOC, detailed_signal);
1169       else if (!g_type_is_a (itype, node->itype))
1170         g_warning ("%s: signal `%s' is invalid for instance `%p'", G_STRLOC, detailed_signal, instance);
1171       else
1172         {
1173           Handler *handler = handler_new (after);
1174
1175           handler_id = handler->id;
1176           handler->detail = detail;
1177           handler->closure = g_closure_ref (closure);
1178           g_closure_sink (closure);
1179           handler_insert (signal_id, instance, handler);
1180           if (node->c_marshaller && G_CLOSURE_NEEDS_MARSHAL (handler->closure))
1181             g_closure_set_marshal (handler->closure, node->c_marshaller);
1182         }
1183     }
1184   else
1185     g_warning ("%s: signal `%s' is invalid for instance `%p'", G_STRLOC, detailed_signal, instance);
1186   G_UNLOCK (g_signal_mutex);
1187
1188   return handler_id;
1189 }
1190
1191 guint
1192 g_signal_connect_data (gpointer       instance,
1193                        const gchar   *detailed_signal,
1194                        GCallback      c_handler,
1195                        gpointer       data,
1196                        GClosureNotify destroy_data,
1197                        gboolean       swapped,
1198                        gboolean       after)
1199 {
1200   guint signal_id, handler_id = 0;
1201   GQuark detail = 0;
1202   GType itype;
1203
1204   g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), 0);
1205   g_return_val_if_fail (detailed_signal != NULL, 0);
1206   g_return_val_if_fail (c_handler != NULL, 0);
1207
1208   G_LOCK (g_signal_mutex);
1209   itype = G_TYPE_FROM_INSTANCE (instance);
1210   signal_id = signal_parse_name (detailed_signal, itype, &detail, TRUE);
1211   if (signal_id)
1212     {
1213       SignalNode *node = LOOKUP_SIGNAL_NODE (signal_id);
1214
1215       if (detail && !(node->flags & G_SIGNAL_DETAILED))
1216         g_warning ("%s: signal `%s' does not support details", G_STRLOC, detailed_signal);
1217       else if (!g_type_is_a (itype, node->itype))
1218         g_warning ("%s: signal `%s' is invalid for instance `%p'", G_STRLOC, detailed_signal, instance);
1219       else
1220         {
1221           Handler *handler = handler_new (after);
1222
1223           handler_id = handler->id;
1224           handler->detail = detail;
1225           handler->closure = g_closure_ref ((swapped ? g_cclosure_new_swap : g_cclosure_new) (c_handler, data, destroy_data));
1226           g_closure_sink (handler->closure);
1227           handler_insert (signal_id, instance, handler);
1228           if (node->c_marshaller && G_CLOSURE_NEEDS_MARSHAL (handler->closure))
1229             g_closure_set_marshal (handler->closure, node->c_marshaller);
1230         }
1231     }
1232   else
1233     g_warning ("%s: signal `%s' is invalid for instance `%p'", G_STRLOC, detailed_signal, instance);
1234   G_UNLOCK (g_signal_mutex);
1235
1236   return handler_id;
1237 }
1238
1239 void
1240 g_signal_handler_block (gpointer instance,
1241                         guint    handler_id)
1242 {
1243   Handler *handler;
1244   
1245   g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance));
1246   g_return_if_fail (handler_id > 0);
1247   
1248   G_LOCK (g_signal_mutex);
1249   handler = handler_lookup (instance, handler_id, NULL);
1250   if (handler)
1251     {
1252 #ifndef G_DISABLE_CHECKS
1253       if (handler->block_count >= HANDLER_MAX_BLOCK_COUNT - 1)
1254         g_error (G_STRLOC ": handler block_count overflow, %s", REPORT_BUG);
1255 #endif
1256       
1257       handler->block_count += 1;
1258     }
1259   else
1260     g_warning ("%s: instance `%p' has no handler with id `%u'", G_STRLOC, instance, handler_id);
1261   G_UNLOCK (g_signal_mutex);
1262 }
1263
1264 void
1265 g_signal_handler_unblock (gpointer instance,
1266                           guint    handler_id)
1267 {
1268   Handler *handler;
1269   
1270   g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance));
1271   g_return_if_fail (handler_id > 0);
1272   
1273   G_LOCK (g_signal_mutex);
1274   handler = handler_lookup (instance, handler_id, NULL);
1275   if (handler)
1276     {
1277       if (handler->block_count)
1278         handler->block_count -= 1;
1279       else
1280         g_warning (G_STRLOC ": handler `%u' of instance `%p' is not blocked", handler_id, instance);
1281     }
1282   else
1283     g_warning ("%s: instance `%p' has no handler with id `%u'", G_STRLOC, instance, handler_id);
1284   G_UNLOCK (g_signal_mutex);
1285 }
1286
1287 void
1288 g_signal_handler_disconnect (gpointer instance,
1289                              guint    handler_id)
1290 {
1291   Handler *handler;
1292   guint signal_id;
1293   
1294   g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance));
1295   g_return_if_fail (handler_id > 0);
1296   
1297   G_LOCK (g_signal_mutex);
1298   handler = handler_lookup (instance, handler_id, &signal_id);
1299   if (handler)
1300     {
1301       handler->id = 0;
1302       handler->block_count = 1;
1303       handler_unref_R (signal_id, instance, handler);
1304     }
1305   else
1306     g_warning ("%s: instance `%p' has no handler with id `%u'", G_STRLOC, instance, handler_id);
1307   G_UNLOCK (g_signal_mutex);
1308 }
1309
1310 void
1311 g_signal_handlers_destroy (gpointer instance)
1312 {
1313   GBSearchArray *hlbsa;
1314   
1315   g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance));
1316   
1317   G_LOCK (g_signal_mutex);
1318   hlbsa = g_hash_table_lookup (g_handler_list_bsa_ht, instance);
1319   if (hlbsa)
1320     {
1321       guint i;
1322       
1323       /* reentrancy caution, delete instance trace first */
1324       g_hash_table_remove (g_handler_list_bsa_ht, instance);
1325       
1326       for (i = 0; i < hlbsa->n_nodes; i++)
1327         {
1328           HandlerList *hlist = g_bsearch_array_get_nth (hlbsa, i);
1329           Handler *handler = hlist->handlers;
1330           
1331           while (handler)
1332             {
1333               Handler *tmp = handler;
1334               
1335               handler = tmp->next;
1336               tmp->block_count = 1;
1337               /* cruel unlink, this works because _all_ handlers vanish */
1338               tmp->next = NULL;
1339               tmp->prev = tmp;
1340               if (tmp->id)
1341                 {
1342                   tmp->id = 0;
1343                   handler_unref_R (0, NULL, tmp);
1344                 }
1345             }
1346         }
1347       g_free (hlbsa->nodes);
1348       g_generic_node_free (&g_bsa_ts, hlbsa);
1349     }
1350   G_UNLOCK (g_signal_mutex);
1351 }
1352
1353 guint
1354 g_signal_handler_find (gpointer         instance,
1355                        GSignalMatchType mask,
1356                        guint            signal_id,
1357                        GQuark           detail,
1358                        GClosure        *closure,
1359                        gpointer         func,
1360                        gpointer         data)
1361 {
1362   guint handler_id = 0;
1363   
1364   g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), 0);
1365   g_return_val_if_fail ((mask & ~G_SIGNAL_MATCH_MASK) == 0, 0);
1366   
1367   if (mask & G_SIGNAL_MATCH_MASK)
1368     {
1369       HandlerMatch *mlist;
1370       
1371       G_LOCK (g_signal_mutex);
1372       mlist = handlers_find (instance, mask, signal_id, detail, closure, func, data, TRUE);
1373       if (mlist)
1374         {
1375           handler_id = mlist->handler->id;
1376           handler_match_free1_R (mlist, instance);
1377         }
1378       G_UNLOCK (g_signal_mutex);
1379     }
1380   
1381   return handler_id;
1382 }
1383
1384 static guint
1385 signal_handlers_foreach_matched_R (gpointer         instance,
1386                                    GSignalMatchType mask,
1387                                    guint            signal_id,
1388                                    GQuark           detail,
1389                                    GClosure        *closure,
1390                                    gpointer         func,
1391                                    gpointer         data,
1392                                    void           (*callback) (gpointer instance,
1393                                                                guint    handler_id))
1394 {
1395   HandlerMatch *mlist;
1396   guint n_handlers = 0;
1397   
1398   mlist = handlers_find (instance, mask, signal_id, detail, closure, func, data, FALSE);
1399   while (mlist)
1400     {
1401       n_handlers++;
1402       G_UNLOCK (g_signal_mutex);
1403       callback (instance, mlist->handler->id);
1404       G_LOCK (g_signal_mutex);
1405       mlist = handler_match_free1_R (mlist, instance);
1406     }
1407   
1408   return n_handlers;
1409 }
1410
1411 guint
1412 g_signal_handlers_block_matched (gpointer         instance,
1413                                  GSignalMatchType mask,
1414                                  guint            signal_id,
1415                                  GQuark           detail,
1416                                  GClosure        *closure,
1417                                  gpointer         func,
1418                                  gpointer         data)
1419 {
1420   guint n_handlers = 0;
1421   
1422   g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), FALSE);
1423   g_return_val_if_fail ((mask & ~G_SIGNAL_MATCH_MASK) == 0, FALSE);
1424   
1425   if (mask & (G_SIGNAL_MATCH_CLOSURE | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA))
1426     {
1427       G_LOCK (g_signal_mutex);
1428       n_handlers = signal_handlers_foreach_matched_R (instance, mask, signal_id, detail,
1429                                                       closure, func, data,
1430                                                       g_signal_handler_block);
1431       G_UNLOCK (g_signal_mutex);
1432     }
1433   
1434   return n_handlers;
1435 }
1436
1437 guint
1438 g_signal_handlers_unblock_matched (gpointer         instance,
1439                                    GSignalMatchType mask,
1440                                    guint            signal_id,
1441                                    GQuark           detail,
1442                                    GClosure        *closure,
1443                                    gpointer         func,
1444                                    gpointer         data)
1445 {
1446   guint n_handlers = 0;
1447   
1448   g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), FALSE);
1449   g_return_val_if_fail ((mask & ~G_SIGNAL_MATCH_MASK) == 0, FALSE);
1450   
1451   if (mask & (G_SIGNAL_MATCH_CLOSURE | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA))
1452     {
1453       G_LOCK (g_signal_mutex);
1454       n_handlers = signal_handlers_foreach_matched_R (instance, mask, signal_id, detail,
1455                                                       closure, func, data,
1456                                                       g_signal_handler_unblock);
1457       G_UNLOCK (g_signal_mutex);
1458     }
1459   
1460   return n_handlers;
1461 }
1462
1463 guint
1464 g_signal_handlers_disconnect_matched (gpointer         instance,
1465                                       GSignalMatchType mask,
1466                                       guint            signal_id,
1467                                       GQuark           detail,
1468                                       GClosure        *closure,
1469                                       gpointer         func,
1470                                       gpointer         data)
1471 {
1472   guint n_handlers = 0;
1473   
1474   g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), FALSE);
1475   g_return_val_if_fail ((mask & ~G_SIGNAL_MATCH_MASK) == 0, FALSE);
1476   
1477   if (mask & (G_SIGNAL_MATCH_CLOSURE | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA))
1478     {
1479       G_LOCK (g_signal_mutex);
1480       n_handlers = signal_handlers_foreach_matched_R (instance, mask, signal_id, detail,
1481                                                       closure, func, data,
1482                                                       g_signal_handler_disconnect);
1483       G_UNLOCK (g_signal_mutex);
1484     }
1485   
1486   return n_handlers;
1487 }
1488
1489 gboolean
1490 g_signal_has_handler_pending (gpointer instance,
1491                               guint    signal_id,
1492                               GQuark   detail,
1493                               gboolean may_be_blocked)
1494 {
1495   HandlerMatch *mlist;
1496   gboolean has_pending;
1497   
1498   g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), FALSE);
1499   g_return_val_if_fail (signal_id > 0, FALSE);
1500   
1501   G_LOCK (g_signal_mutex);
1502   if (detail)
1503     {
1504       SignalNode *node = LOOKUP_SIGNAL_NODE (signal_id);
1505       
1506       if (!(node->flags & G_SIGNAL_DETAILED))
1507         {
1508           g_warning ("%s: signal id `%u' does not support detail (%u)", G_STRLOC, signal_id, detail);
1509           G_UNLOCK (g_signal_mutex);
1510           return FALSE;
1511         }
1512     }
1513   mlist = handlers_find (instance,
1514                          (G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_DETAIL | (may_be_blocked ? 0 : G_SIGNAL_MATCH_UNBLOCKED)),
1515                          signal_id, detail, NULL, NULL, NULL, TRUE);
1516   if (mlist)
1517     {
1518       has_pending = TRUE;
1519       handler_match_free1_R (mlist, instance);
1520     }
1521   else
1522     has_pending = FALSE;
1523   G_UNLOCK (g_signal_mutex);
1524   
1525   return has_pending;
1526 }
1527
1528 void
1529 g_signal_emitv (const GValue *instance_and_params,
1530                 guint         signal_id,
1531                 GQuark        detail,
1532                 GValue       *return_value)
1533 {
1534   const GValue *param_values;
1535   gpointer instance;
1536   SignalNode *node;
1537   guint i;
1538   
1539   g_return_if_fail (instance_and_params != NULL);
1540   instance = g_value_get_as_pointer (instance_and_params);
1541   g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance));
1542   g_return_if_fail (signal_id > 0);
1543
1544   param_values = instance_and_params + 1;
1545   
1546   G_LOCK (g_signal_mutex);
1547   node = LOOKUP_SIGNAL_NODE (signal_id);
1548   if (!node || !g_type_is_a (G_TYPE_FROM_INSTANCE (instance), node->itype))
1549     {
1550       g_warning ("%s: signal id `%u' is invalid for instance `%p'", G_STRLOC, signal_id, instance);
1551       G_UNLOCK (g_signal_mutex);
1552       return;
1553     }
1554 #ifdef G_ENABLE_DEBUG
1555   if (detail && !(node->flags & G_SIGNAL_DETAILED))
1556     {
1557       g_warning ("%s: signal id `%u' does not support detail (%u)", G_STRLOC, signal_id, detail);
1558       G_UNLOCK (g_signal_mutex);
1559       return;
1560     }
1561   for (i = 0; i < node->n_params; i++)
1562     if (!G_VALUE_HOLDS (param_values + i, node->param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE))
1563       {
1564         g_critical ("%s: value for `%s' parameter %u for signal \"%s\" is of type `%s'",
1565                     G_STRLOC,
1566                     g_type_name (node->param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE),
1567                     i,
1568                     node->name,
1569                     G_VALUE_TYPE_NAME (param_values + i));
1570         G_UNLOCK (g_signal_mutex);
1571         return;
1572       }
1573   if (node->return_type != G_TYPE_NONE)
1574     {
1575       if (!return_value)
1576         {
1577           g_critical ("%s: return value `%s' for signal \"%s\" is (NULL)",
1578                       G_STRLOC,
1579                       g_type_name (node->return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE),
1580                       node->name);
1581           G_UNLOCK (g_signal_mutex);
1582           return;
1583         }
1584       else if (!node->accumulator && !G_VALUE_HOLDS (return_value, node->return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE))
1585         {
1586           g_critical ("%s: return value `%s' for signal \"%s\" is of type `%s'",
1587                       G_STRLOC,
1588                       g_type_name (node->return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE),
1589                       node->name,
1590                       G_VALUE_TYPE_NAME (return_value));
1591           G_UNLOCK (g_signal_mutex);
1592           return;
1593         }
1594     }
1595   else
1596     return_value = NULL;
1597 #endif  /* G_ENABLE_DEBUG */
1598
1599   signal_emit_R (node, detail, instance, return_value, instance_and_params);
1600   G_UNLOCK (g_signal_mutex);
1601 }
1602
1603 void
1604 g_signal_emit_valist (gpointer instance,
1605                       guint    signal_id,
1606                       GQuark   detail,
1607                       va_list  var_args)
1608 {
1609   GValue *instance_and_params, stack_values[MAX_STACK_VALUES], *free_me = NULL;
1610   GValue *param_values;
1611   SignalNode *node;
1612   guint i;
1613
1614   g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance));
1615   g_return_if_fail (signal_id > 0);
1616
1617   G_LOCK (g_signal_mutex);
1618   node = LOOKUP_SIGNAL_NODE (signal_id);
1619   if (!node || !g_type_is_a (G_TYPE_FROM_INSTANCE (instance), node->itype))
1620     {
1621       g_warning ("%s: signal id `%u' is invalid for instance `%p'", G_STRLOC, signal_id, instance);
1622       G_UNLOCK (g_signal_mutex);
1623       return;
1624     }
1625 #ifndef G_DISABLE_CHECKS
1626   if (detail && !(node->flags & G_SIGNAL_DETAILED))
1627     {
1628       g_warning ("%s: signal id `%u' does not support detail (%u)", G_STRLOC, signal_id, detail);
1629       G_UNLOCK (g_signal_mutex);
1630       return;
1631     }
1632 #endif  /* !G_DISABLE_CHECKS */
1633
1634   if (node->n_params < MAX_STACK_VALUES)
1635     instance_and_params = stack_values;
1636   else
1637     {
1638       free_me = g_new (GValue, node->n_params + 1);
1639       instance_and_params = free_me;
1640     }
1641   param_values = instance_and_params + 1;
1642   for (i = 0; i < node->n_params; i++)
1643     {
1644       gchar *error;
1645
1646       param_values[i].g_type = 0;
1647       g_value_init (param_values + i, node->param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE);
1648       G_VALUE_COLLECT (param_values + i,
1649                        var_args,
1650                        node->param_types[i] & G_SIGNAL_TYPE_STATIC_SCOPE ? G_VALUE_NOCOPY_CONTENTS : 0,
1651                        &error);
1652       if (error)
1653         {
1654           g_warning ("%s: %s", G_STRLOC, error);
1655           g_free (error);
1656
1657           /* we purposely leak the value here, it might not be
1658            * in a sane state if an error condition occoured
1659            */
1660           while (i--)
1661             g_value_unset (param_values + i);
1662
1663           G_UNLOCK (g_signal_mutex);
1664           g_free (free_me);
1665           return;
1666         }
1667     }
1668   instance_and_params->g_type = 0;
1669   g_value_init (instance_and_params, G_TYPE_FROM_INSTANCE (instance));
1670   g_value_set_instance (instance_and_params, instance);
1671   if (node->return_type == G_TYPE_NONE)
1672     signal_emit_R (node, detail, instance, NULL, instance_and_params);
1673   else
1674     {
1675       GValue return_value = { 0, };
1676       gchar *error = NULL;
1677
1678       g_value_init (&return_value, node->return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE);
1679       if (signal_emit_R (node, detail, instance, &return_value, instance_and_params))
1680         G_VALUE_LCOPY (&return_value,
1681                        var_args,
1682                        node->return_type & G_SIGNAL_TYPE_STATIC_SCOPE ? G_VALUE_NOCOPY_CONTENTS : 0,
1683                        &error);
1684       if (!error)
1685         g_value_unset (&return_value);
1686       else
1687         {
1688           g_warning ("%s: %s", G_STRLOC, error);
1689           g_free (error);
1690
1691           /* we purposely leak the value here, it might not be
1692            * in a sane state if an error condition occoured
1693            */
1694         }
1695     }
1696   for (i = 0; i < node->n_params; i++)
1697     g_value_unset (param_values + i);
1698   g_value_unset (instance_and_params);
1699   if (free_me)
1700     g_free (free_me);
1701   G_UNLOCK (g_signal_mutex);
1702 }
1703
1704 void
1705 g_signal_emit (gpointer instance,
1706                guint    signal_id,
1707                GQuark   detail,
1708                ...)
1709 {
1710   va_list var_args;
1711
1712   va_start (var_args, detail);
1713   g_signal_emit_valist (instance, signal_id, detail, var_args);
1714   va_end (var_args);
1715 }
1716
1717 void
1718 g_signal_emit_by_name (gpointer     instance,
1719                        const gchar *detailed_signal,
1720                        ...)
1721 {
1722   GQuark detail = 0;
1723   guint signal_id;
1724
1725   g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance));
1726   g_return_if_fail (detailed_signal != NULL);
1727
1728   G_LOCK (g_signal_mutex);
1729   signal_id = signal_parse_name (detailed_signal, G_TYPE_FROM_INSTANCE (instance), &detail, TRUE);
1730   G_UNLOCK (g_signal_mutex);
1731
1732   if (signal_id)
1733     {
1734       va_list var_args;
1735
1736       va_start (var_args, detailed_signal);
1737       g_signal_emit_valist (instance, signal_id, detail, var_args);
1738       va_end (var_args);
1739     }
1740   else
1741     g_warning ("%s: signal name `%s' is invalid for instance `%p'", G_STRLOC, detailed_signal, instance);
1742 }
1743
1744 static gboolean
1745 signal_emit_R (SignalNode   *node,
1746                GQuark        detail,
1747                gpointer      instance,
1748                GValue       *return_value,
1749                const GValue *instance_and_params)
1750 {
1751   EmissionState emission_state = 0;
1752   GSignalAccumulator accumulator;
1753   GSignalInvocationHint ihint;
1754   GClosure *class_closure;
1755   HandlerList *hlist;
1756   Handler *handler_list = NULL;
1757   GValue accu = { 0, };
1758   gboolean accu_used = FALSE;
1759   guint signal_id = node->signal_id;
1760   gboolean return_value_altered = FALSE;
1761   
1762 #ifdef  G_ENABLE_DEBUG
1763   IF_DEBUG (SIGNALS, g_trace_instance_signals == instance || g_trap_instance_signals == instance)
1764     {
1765       g_message ("%s::%s(%u) emitted (instance=%p signal-node=%p)\n",
1766                  g_type_name (G_TYPE_FROM_INSTANCE (instance)),
1767                  node->name, detail,
1768                  instance, node);
1769       if (g_trap_instance_signals == instance)
1770         G_BREAKPOINT ();
1771     }
1772 #endif  /* G_ENABLE_DEBUG */
1773   
1774   if (node->flags & G_SIGNAL_NO_RECURSE)
1775     {
1776       Emission *emission = emission_find (g_restart_emissions, signal_id, detail, instance);
1777       
1778       if (emission)
1779         {
1780           *emission->state_p = EMISSION_RESTART;
1781           return return_value_altered;
1782         }
1783     }
1784   ihint.signal_id = node->signal_id;
1785   ihint.detail = detail;
1786   accumulator = node->accumulator;
1787   if (accumulator)
1788     g_value_init (&accu, node->return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE);
1789   emission_push ((node->flags & G_SIGNAL_NO_RECURSE) ? &g_restart_emissions : &g_recursive_emissions,
1790                  signal_id, detail, instance, &emission_state);
1791   class_closure = node->class_closure;
1792   
1793  EMIT_RESTART:
1794   
1795   if (handler_list)
1796     handler_unref_R (signal_id, instance, handler_list);
1797   hlist = handler_list_lookup (signal_id, instance);
1798   handler_list = hlist ? hlist->handlers : NULL;
1799   if (handler_list)
1800     handler_ref (handler_list);
1801   
1802   ihint.run_type = G_SIGNAL_RUN_FIRST;
1803   
1804   if ((node->flags & G_SIGNAL_RUN_FIRST) && class_closure)
1805     {
1806       emission_state = EMISSION_RUN;
1807       
1808       G_UNLOCK (g_signal_mutex);
1809       if (accumulator)
1810         {
1811           if (accu_used)
1812             g_value_reset (&accu);
1813           g_closure_invoke (class_closure,
1814                             &accu,
1815                             node->n_params + 1,
1816                             instance_and_params,
1817                             &ihint);
1818           if (!accumulator (&ihint, return_value, &accu) &&
1819               emission_state == EMISSION_RUN)
1820             emission_state = EMISSION_STOP;
1821           accu_used = TRUE;
1822         }
1823       else
1824         g_closure_invoke (class_closure,
1825                           return_value,
1826                           node->n_params + 1,
1827                           instance_and_params,
1828                           &ihint);
1829       G_LOCK (g_signal_mutex);
1830       return_value_altered = TRUE;
1831       
1832       if (emission_state == EMISSION_STOP)
1833         goto EMIT_CLEANUP;
1834       else if (emission_state == EMISSION_RESTART)
1835         goto EMIT_RESTART;
1836     }
1837   
1838   if (node->emission_hooks)
1839     {
1840       emission_state = EMISSION_HOOK;
1841       
1842       G_UNLOCK (g_signal_mutex);
1843       g_print ("emission_hooks()\n");
1844       G_LOCK (g_signal_mutex);
1845       
1846       if (emission_state == EMISSION_RESTART)
1847         goto EMIT_RESTART;
1848     }
1849   
1850   if (handler_list)
1851     {
1852       Handler *handler = handler_list;
1853       
1854       emission_state = EMISSION_RUN;
1855       handler_ref (handler);
1856       do
1857         {
1858           Handler *tmp;
1859           
1860           if (handler->after)
1861             {
1862               handler_unref_R (signal_id, instance, handler_list);
1863               handler_list = handler;
1864               break;
1865             }
1866           else if (!handler->block_count && (!handler->detail || handler->detail == detail))
1867             {
1868               G_UNLOCK (g_signal_mutex);
1869               if (accumulator)
1870                 {
1871                   if (accu_used)
1872                     g_value_reset (&accu);
1873                   g_closure_invoke (handler->closure,
1874                                     &accu,
1875                                     node->n_params + 1,
1876                                     instance_and_params,
1877                                     &ihint);
1878                   if (!accumulator (&ihint, return_value, &accu) &&
1879                       emission_state == EMISSION_RUN)
1880                     emission_state = EMISSION_STOP;
1881                   accu_used = TRUE;
1882                 }
1883               else
1884                 g_closure_invoke (handler->closure,
1885                                   return_value,
1886                                   node->n_params + 1,
1887                                   instance_and_params,
1888                                   &ihint);
1889               G_LOCK (g_signal_mutex);
1890               return_value_altered = TRUE;
1891               
1892               tmp = emission_state == EMISSION_RUN ? handler->next : NULL;
1893             }
1894           else
1895             tmp = handler->next;
1896           
1897           if (tmp)
1898             handler_ref (tmp);
1899           handler_unref_R (signal_id, instance, handler_list);
1900           handler_list = handler;
1901           handler = tmp;
1902         }
1903       while (handler);
1904       
1905       if (emission_state == EMISSION_STOP)
1906         goto EMIT_CLEANUP;
1907       else if (emission_state == EMISSION_RESTART)
1908         goto EMIT_RESTART;
1909     }
1910   
1911   ihint.run_type = G_SIGNAL_RUN_LAST;
1912   
1913   if ((node->flags & G_SIGNAL_RUN_LAST) && class_closure)
1914     {
1915       emission_state = EMISSION_RUN;
1916       
1917       G_UNLOCK (g_signal_mutex);
1918       if (accumulator)
1919         {
1920           if (accu_used)
1921             g_value_reset (&accu);
1922           g_closure_invoke (class_closure,
1923                             &accu,
1924                             node->n_params + 1,
1925                             instance_and_params,
1926                             &ihint);
1927           if (!accumulator (&ihint, return_value, &accu) &&
1928               emission_state == EMISSION_RUN)
1929             emission_state = EMISSION_STOP;
1930           accu_used = TRUE;
1931         }
1932       else
1933         g_closure_invoke (class_closure,
1934                           return_value,
1935                           node->n_params + 1,
1936                           instance_and_params,
1937                           &ihint);
1938       G_LOCK (g_signal_mutex);
1939       return_value_altered = TRUE;
1940       
1941       if (emission_state == EMISSION_STOP)
1942         goto EMIT_CLEANUP;
1943       else if (emission_state == EMISSION_RESTART)
1944         goto EMIT_RESTART;
1945     }
1946   
1947   if (handler_list)
1948     {
1949       Handler *handler = handler_list;
1950       
1951       emission_state = EMISSION_RUN;
1952       handler_ref (handler);
1953       do
1954         {
1955           Handler *tmp;
1956           
1957           if (handler->after && !handler->block_count && (!handler->detail || handler->detail == detail))
1958             {
1959               G_UNLOCK (g_signal_mutex);
1960               if (accumulator)
1961                 {
1962                   if (accu_used)
1963                     g_value_reset (&accu);
1964                   g_closure_invoke (handler->closure,
1965                                     &accu,
1966                                     node->n_params + 1,
1967                                     instance_and_params,
1968                                     &ihint);
1969                   if (!accumulator (&ihint, return_value, &accu) &&
1970                       emission_state == EMISSION_RUN)
1971                     emission_state = EMISSION_STOP;
1972                   accu_used = TRUE;
1973                 }
1974               else
1975                 g_closure_invoke (handler->closure,
1976                                   return_value,
1977                                   node->n_params + 1,
1978                                   instance_and_params,
1979                                   &ihint);
1980               G_LOCK (g_signal_mutex);
1981               return_value_altered = TRUE;
1982               
1983               tmp = emission_state == EMISSION_RUN ? handler->next : NULL;
1984             }
1985           else
1986             tmp = handler->next;
1987           
1988           if (tmp)
1989             handler_ref (tmp);
1990           handler_unref_R (signal_id, instance, handler);
1991           handler = tmp;
1992         }
1993       while (handler);
1994       
1995       if (emission_state == EMISSION_STOP)
1996         goto EMIT_CLEANUP;
1997       else if (emission_state == EMISSION_RESTART)
1998         goto EMIT_RESTART;
1999     }
2000   
2001  EMIT_CLEANUP:
2002   
2003   ihint.run_type = G_SIGNAL_RUN_CLEANUP;
2004   
2005   if ((node->flags & G_SIGNAL_RUN_CLEANUP) && class_closure)
2006     {
2007       gboolean need_unset = FALSE;
2008       
2009       emission_state = EMISSION_STOP;
2010       
2011       G_UNLOCK (g_signal_mutex);
2012       if (node->return_type != G_TYPE_NONE)
2013         {
2014           if (!accumulator)
2015             {
2016               g_value_init (&accu, node->return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE);
2017               need_unset = TRUE;
2018             }
2019           else if (accu_used)
2020             g_value_reset (&accu);
2021         }
2022       g_closure_invoke (class_closure,
2023                         node->return_type != G_TYPE_NONE ? &accu : NULL,
2024                         node->n_params + 1,
2025                         instance_and_params,
2026                         &ihint);
2027       if (need_unset)
2028         g_value_unset (&accu);
2029       G_LOCK (g_signal_mutex);
2030       
2031       if (emission_state == EMISSION_RESTART)
2032         goto EMIT_RESTART;
2033     }
2034   
2035   if (handler_list)
2036     handler_unref_R (signal_id, instance, handler_list);
2037   
2038   emission_pop ((node->flags & G_SIGNAL_NO_RECURSE) ? &g_restart_emissions : &g_recursive_emissions, &emission_state);
2039   if (accumulator)
2040     g_value_unset (&accu);
2041
2042   return return_value_altered;
2043 }
2044
2045
2046 /* --- compile standard marshallers --- */
2047 #include        "gvaluetypes.h"
2048 #include        "gmarshal.c"