Coverage Report

Created: 2025-08-28 06:24

/src/glib/gobject/gsignal.c
Line
Count
Source (jump to first uncovered line)
1
/* GObject - GLib Type, Object, Parameter and Signal Library
2
 * Copyright (C) 2000-2001 Red Hat, Inc.
3
 *
4
 * SPDX-License-Identifier: LGPL-2.1-or-later
5
 *
6
 * This library is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU Lesser General Public
8
 * License as published by the Free Software Foundation; either
9
 * version 2.1 of the License, or (at your option) any later version.
10
 *
11
 * This library is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
 * Lesser General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU Lesser General
17
 * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
18
 *
19
 * this code is based on the original GtkSignal implementation
20
 * for the Gtk+ library by Peter Mattis <petm@xcf.berkeley.edu>
21
 */
22
23
/*
24
 * MT safe
25
 */
26
27
#include "config.h"
28
29
#include <signal.h>
30
#include <stdint.h>
31
#include <string.h>
32
33
#include "gsignal.h"
34
#include "gtype-private.h"
35
#include "gbsearcharray.h"
36
#include "gvaluecollector.h"
37
#include "gvaluetypes.h"
38
#include "gobject.h"
39
#include "genums.h"
40
#include "gobject_trace.h"
41
42
43
#define REPORT_BUG      "please report occurrence circumstances to https://gitlab.gnome.org/GNOME/glib/issues/new"
44
45
/* --- typedefs --- */
46
typedef struct _SignalNode   SignalNode;
47
typedef struct _SignalKey    SignalKey;
48
typedef struct _Emission     Emission;
49
typedef struct _Handler      Handler;
50
typedef struct _HandlerList  HandlerList;
51
typedef struct _HandlerMatch HandlerMatch;
52
typedef enum
53
{
54
  EMISSION_STOP,
55
  EMISSION_RUN,
56
  EMISSION_HOOK,
57
  EMISSION_RESTART
58
} EmissionState;
59
60
61
/* --- prototypes --- */
62
static inline guint   signal_id_lookup  (const gchar *name,
63
                                         GType        itype);
64
static        void    signal_destroy_R  (SignalNode  *signal_node);
65
static inline HandlerList*  handler_list_ensure (guint      signal_id,
66
               gpointer   instance);
67
static inline HandlerList*  handler_list_lookup (guint      signal_id,
68
               gpointer   instance);
69
static inline Handler*    handler_new   (guint            signal_id,
70
               gpointer         instance,
71
                                                         gboolean   after);
72
static        void    handler_insert    (guint      signal_id,
73
               gpointer   instance,
74
               Handler   *handler);
75
static        Handler*    handler_lookup    (gpointer   instance,
76
               gulong     handler_id,
77
               GClosure        *closure,
78
               guint     *signal_id_p);
79
static inline HandlerMatch* handler_match_prepend (HandlerMatch  *list,
80
               Handler   *handler,
81
               guint      signal_id);
82
static inline HandlerMatch* handler_match_free1_R (HandlerMatch  *node,
83
               gpointer   instance);
84
static        HandlerMatch* handlers_find   (gpointer   instance,
85
               GSignalMatchType mask,
86
               guint      signal_id,
87
               GQuark     detail,
88
               GClosure  *closure,
89
               gpointer   func,
90
               gpointer   data,
91
               gboolean   one_and_only);
92
static inline void    handler_ref   (Handler   *handler);
93
static inline void    handler_unref_R   (guint      signal_id,
94
               gpointer   instance,
95
               Handler   *handler);
96
static gint     handler_lists_cmp (gconstpointer    node1,
97
               gconstpointer    node2);
98
static inline void    emission_push   (Emission  *emission);
99
static inline void    emission_pop    (Emission  *emission);
100
static inline Emission*   emission_find   (guint      signal_id,
101
               GQuark     detail,
102
               gpointer   instance);
103
static gint     class_closures_cmp  (gconstpointer    node1,
104
               gconstpointer    node2);
105
static gint     signal_key_cmp    (gconstpointer    node1,
106
               gconstpointer    node2);
107
static        gboolean    signal_emit_unlocked_R  (SignalNode  *node,
108
               GQuark     detail,
109
               gpointer   instance,
110
               GValue    *return_value,
111
               const GValue  *instance_and_params);
112
static       void               add_invalid_closure_notify    (Handler         *handler,
113
                     gpointer         instance);
114
static       void               remove_invalid_closure_notify (Handler         *handler,
115
                     gpointer         instance);
116
static       void               invalid_closure_notify  (gpointer         data,
117
               GClosure        *closure);
118
static const gchar *            type_debug_name         (GType            type);
119
static void                     node_check_deprecated   (const SignalNode *node);
120
static void                     node_update_single_va_closure (SignalNode *node);
121
122
123
/* --- structures --- */
124
typedef struct
125
{
126
  GSignalAccumulator func;
127
  gpointer           data;
128
} SignalAccumulator;
129
typedef struct
130
{
131
  GHook hook;
132
  GQuark detail;
133
} SignalHook;
134
0
#define SIGNAL_HOOK(hook) ((SignalHook*) (hook))
135
136
struct _SignalNode
137
{
138
  /* permanent portion */
139
  guint              signal_id;
140
  GType              itype;
141
  const gchar       *name;
142
  guint              destroyed : 1;
143
  
144
  /* reinitializable portion */
145
  guint              flags : 9;
146
  guint              n_params : 8;
147
  guint              single_va_closure_is_valid : 1;
148
  guint              single_va_closure_is_after : 1;
149
  GType       *param_types; /* mangled with G_SIGNAL_TYPE_STATIC_SCOPE flag */
150
  GType        return_type; /* mangled with G_SIGNAL_TYPE_STATIC_SCOPE flag */
151
  GBSearchArray     *class_closure_bsa;
152
  SignalAccumulator *accumulator;
153
  GSignalCMarshaller c_marshaller;
154
  GSignalCVaMarshaller va_marshaller;
155
  GHookList         *emission_hooks;
156
157
  GClosure *single_va_closure;
158
};
159
160
0
#define SINGLE_VA_CLOSURE_EMPTY_MAGIC GINT_TO_POINTER(1)  /* indicates single_va_closure is valid but empty */
161
162
struct _SignalKey
163
{
164
  GType  itype;
165
  GQuark quark;
166
  guint  signal_id;
167
};
168
169
struct _Emission
170
{
171
  Emission             *next;
172
  gpointer              instance;
173
  GSignalInvocationHint ihint;
174
  EmissionState         state;
175
  GType     chain_type;
176
};
177
178
struct _HandlerList
179
{
180
  guint    signal_id;
181
  Handler *handlers;
182
  Handler *tail_before;  /* normal signal handlers are appended here  */
183
  Handler *tail_after;   /* CONNECT_AFTER handlers are appended here  */
184
};
185
186
struct _Handler
187
{
188
  gulong        sequential_number;
189
  Handler      *next;
190
  Handler      *prev;
191
  GQuark  detail;
192
  guint         signal_id;
193
  guint         ref_count;
194
  guint         block_count : 16;
195
0
#define HANDLER_MAX_BLOCK_COUNT (1 << 16)
196
  guint         after : 1;
197
  guint         has_invalid_closure_notify : 1;
198
  GClosure     *closure;
199
  gpointer      instance;
200
};
201
struct _HandlerMatch
202
{
203
  Handler      *handler;
204
  HandlerMatch *next;
205
  guint         signal_id;
206
};
207
208
typedef struct
209
{
210
  GType     instance_type; /* 0 for default closure */
211
  GClosure *closure;
212
} ClassClosure;
213
214
215
/* --- variables --- */
216
static GBSearchArray *g_signal_key_bsa = NULL;
217
static const GBSearchConfig g_signal_key_bconfig = {
218
  sizeof (SignalKey),
219
  signal_key_cmp,
220
  G_BSEARCH_ARRAY_ALIGN_POWER2,
221
};
222
static GBSearchConfig g_signal_hlbsa_bconfig = {
223
  sizeof (HandlerList),
224
  handler_lists_cmp,
225
  0,
226
};
227
static GBSearchConfig g_class_closure_bconfig = {
228
  sizeof (ClassClosure),
229
  class_closures_cmp,
230
  0,
231
};
232
static GHashTable    *g_handler_list_bsa_ht = NULL;
233
static Emission      *g_emissions = NULL;
234
static gulong         g_handler_sequential_number = 1;
235
static GHashTable    *g_handlers = NULL;
236
237
G_LOCK_DEFINE_STATIC (g_signal_mutex);
238
4
#define SIGNAL_LOCK()   G_LOCK (g_signal_mutex)
239
4
#define SIGNAL_UNLOCK()   G_UNLOCK (g_signal_mutex)
240
241
242
/* --- signal nodes --- */
243
static guint          g_n_signal_nodes = 0;
244
static SignalNode   **g_signal_nodes = NULL;
245
246
static inline SignalNode*
247
LOOKUP_SIGNAL_NODE (guint signal_id)
248
0
{
249
0
  if (signal_id < g_n_signal_nodes)
250
0
    return g_signal_nodes[signal_id];
251
0
  else
252
0
    return NULL;
253
0
}
254
255
256
/* --- functions --- */
257
/* @key must have already been validated with is_valid()
258
 * Modifies @key in place. */
259
static void
260
canonicalize_key (gchar *key)
261
0
{
262
0
  gchar *p;
263
264
0
  for (p = key; *p != 0; p++)
265
0
    {
266
0
      gchar c = *p;
267
268
0
      if (c == '_')
269
0
        *p = '-';
270
0
    }
271
0
}
272
273
/* @key must have already been validated with is_valid() */
274
static gboolean
275
is_canonical (const gchar *key)
276
0
{
277
0
  return (strchr (key, '_') == NULL);
278
0
}
279
280
/**
281
 * g_signal_is_valid_name:
282
 * @name: the canonical name of the signal
283
 *
284
 * Validate a signal name. This can be useful for dynamically-generated signals
285
 * which need to be validated at run-time before actually trying to create them.
286
 *
287
 * See [func@GObject.signal_new] for details of the rules for valid names.
288
 * The rules for signal names are the same as those for property names.
289
 *
290
 * Returns: %TRUE if @name is a valid signal name, %FALSE otherwise.
291
 * Since: 2.66
292
 */
293
gboolean
294
g_signal_is_valid_name (const gchar *name)
295
0
{
296
  /* FIXME: We allow this, against our own documentation (the leading `-` is
297
   * invalid), because GTK has historically used this. */
298
0
  if (g_str_equal (name, "-gtk-private-changed"))
299
0
    return TRUE;
300
301
0
  return g_param_spec_is_valid_name (name);
302
0
}
303
304
static inline guint
305
signal_id_lookup (const gchar *name,
306
                  GType  itype)
307
0
{
308
0
  GQuark quark;
309
0
  GType *ifaces, type = itype;
310
0
  SignalKey key;
311
0
  guint n_ifaces;
312
313
0
  quark = g_quark_try_string (name);
314
0
  key.quark = quark;
315
316
  /* try looking up signals for this type and its ancestors */
317
0
  do
318
0
    {
319
0
      SignalKey *signal_key;
320
      
321
0
      key.itype = type;
322
0
      signal_key = g_bsearch_array_lookup (g_signal_key_bsa, &g_signal_key_bconfig, &key);
323
      
324
0
      if (signal_key)
325
0
  return signal_key->signal_id;
326
      
327
0
      type = g_type_parent (type);
328
0
    }
329
0
  while (type);
330
331
  /* no luck, try interfaces it exports */
332
0
  ifaces = g_type_interfaces (itype, &n_ifaces);
333
0
  while (n_ifaces--)
334
0
    {
335
0
      SignalKey *signal_key;
336
337
0
      key.itype = ifaces[n_ifaces];
338
0
      signal_key = g_bsearch_array_lookup (g_signal_key_bsa, &g_signal_key_bconfig, &key);
339
340
0
      if (signal_key)
341
0
  {
342
0
    g_free (ifaces);
343
0
    return signal_key->signal_id;
344
0
  }
345
0
    }
346
0
  g_free (ifaces);
347
348
  /* If the @name is non-canonical, try again. This is the slow path — people
349
   * should use canonical names in their queries if they want performance. */
350
0
  if (!is_canonical (name))
351
0
    {
352
0
      guint signal_id;
353
0
      gchar *name_copy = g_strdup (name);
354
0
      canonicalize_key (name_copy);
355
356
0
      signal_id = signal_id_lookup (name_copy, itype);
357
358
0
      g_free (name_copy);
359
360
0
      return signal_id;
361
0
    }
362
363
0
  return 0;
364
0
}
365
366
static gint
367
class_closures_cmp (gconstpointer node1,
368
        gconstpointer node2)
369
0
{
370
0
  const ClassClosure *c1 = node1, *c2 = node2;
371
  
372
0
  return G_BSEARCH_ARRAY_CMP (c1->instance_type, c2->instance_type);
373
0
}
374
375
static gint
376
handler_lists_cmp (gconstpointer node1,
377
                   gconstpointer node2)
378
0
{
379
0
  const HandlerList *hlist1 = node1, *hlist2 = node2;
380
  
381
0
  return G_BSEARCH_ARRAY_CMP (hlist1->signal_id, hlist2->signal_id);
382
0
}
383
384
static inline HandlerList*
385
handler_list_ensure (guint    signal_id,
386
         gpointer instance)
387
0
{
388
0
  GBSearchArray *hlbsa = g_hash_table_lookup (g_handler_list_bsa_ht, instance);
389
0
  HandlerList key;
390
  
391
0
  key.signal_id = signal_id;
392
0
  key.handlers    = NULL;
393
0
  key.tail_before = NULL;
394
0
  key.tail_after  = NULL;
395
0
  if (!hlbsa)
396
0
    {
397
0
      hlbsa = g_bsearch_array_create (&g_signal_hlbsa_bconfig);
398
0
    }
399
0
  hlbsa = g_bsearch_array_insert (hlbsa, &g_signal_hlbsa_bconfig, &key);
400
0
  g_hash_table_insert (g_handler_list_bsa_ht, instance, hlbsa);
401
0
  return g_bsearch_array_lookup (hlbsa, &g_signal_hlbsa_bconfig, &key);
402
0
}
403
404
static inline HandlerList*
405
handler_list_lookup (guint    signal_id,
406
         gpointer instance)
407
0
{
408
0
  GBSearchArray *hlbsa = g_hash_table_lookup (g_handler_list_bsa_ht, instance);
409
0
  HandlerList key;
410
  
411
0
  key.signal_id = signal_id;
412
  
413
0
  return hlbsa ? g_bsearch_array_lookup (hlbsa, &g_signal_hlbsa_bconfig, &key) : NULL;
414
0
}
415
416
static guint
417
handler_hash (gconstpointer key)
418
0
{
419
0
  return (guint)((Handler*)key)->sequential_number;
420
0
}
421
422
static gboolean
423
handler_equal (gconstpointer a, gconstpointer b)
424
0
{
425
0
  Handler *ha = (Handler *)a;
426
0
  Handler *hb = (Handler *)b;
427
0
  return (ha->sequential_number == hb->sequential_number) &&
428
0
      (ha->instance  == hb->instance);
429
0
}
430
431
static Handler*
432
handler_lookup (gpointer  instance,
433
    gulong    handler_id,
434
    GClosure *closure,
435
    guint    *signal_id_p)
436
0
{
437
0
  GBSearchArray *hlbsa;
438
439
0
  if (handler_id)
440
0
    {
441
0
      Handler key;
442
0
      key.sequential_number = handler_id;
443
0
      key.instance = instance;
444
0
      return g_hash_table_lookup (g_handlers, &key);
445
446
0
    }
447
448
0
  hlbsa = g_hash_table_lookup (g_handler_list_bsa_ht, instance);
449
  
450
0
  if (hlbsa)
451
0
    {
452
0
      guint i;
453
      
454
0
      for (i = 0; i < hlbsa->n_nodes; i++)
455
0
        {
456
0
          HandlerList *hlist = g_bsearch_array_get_nth (hlbsa, &g_signal_hlbsa_bconfig, i);
457
0
          Handler *handler;
458
          
459
0
          for (handler = hlist->handlers; handler; handler = handler->next)
460
0
            if (closure ? (handler->closure == closure) : (handler->sequential_number == handler_id))
461
0
              {
462
0
                if (signal_id_p)
463
0
                  *signal_id_p = hlist->signal_id;
464
465
0
                return handler;
466
0
              }
467
0
        }
468
0
    }
469
  
470
0
  return NULL;
471
0
}
472
473
static inline HandlerMatch*
474
handler_match_prepend (HandlerMatch *list,
475
           Handler      *handler,
476
           guint       signal_id)
477
0
{
478
0
  HandlerMatch *node;
479
  
480
0
  node = g_slice_new (HandlerMatch);
481
0
  node->handler = handler;
482
0
  node->next = list;
483
0
  node->signal_id = signal_id;
484
0
  handler_ref (handler);
485
  
486
0
  return node;
487
0
}
488
static inline HandlerMatch*
489
handler_match_free1_R (HandlerMatch *node,
490
           gpointer      instance)
491
0
{
492
0
  HandlerMatch *next = node->next;
493
  
494
0
  handler_unref_R (node->signal_id, instance, node->handler);
495
0
  g_slice_free (HandlerMatch, node);
496
  
497
0
  return next;
498
0
}
499
500
static HandlerMatch*
501
handlers_find (gpointer         instance,
502
         GSignalMatchType mask,
503
         guint            signal_id,
504
         GQuark           detail,
505
         GClosure        *closure,
506
         gpointer         func,
507
         gpointer         data,
508
         gboolean         one_and_only)
509
0
{
510
0
  HandlerMatch *mlist = NULL;
511
  
512
0
  if (mask & G_SIGNAL_MATCH_ID)
513
0
    {
514
0
      HandlerList *hlist = handler_list_lookup (signal_id, instance);
515
0
      Handler *handler;
516
0
      SignalNode *node = NULL;
517
      
518
0
      if (mask & G_SIGNAL_MATCH_FUNC)
519
0
  {
520
0
    node = LOOKUP_SIGNAL_NODE (signal_id);
521
0
    if (!node || !node->c_marshaller)
522
0
      return NULL;
523
0
  }
524
      
525
0
      mask = ~mask;
526
0
      for (handler = hlist ? hlist->handlers : NULL; handler; handler = handler->next)
527
0
        if (handler->sequential_number &&
528
0
      ((mask & G_SIGNAL_MATCH_DETAIL) || handler->detail == detail) &&
529
0
      ((mask & G_SIGNAL_MATCH_CLOSURE) || handler->closure == closure) &&
530
0
            ((mask & G_SIGNAL_MATCH_DATA) || handler->closure->data == data) &&
531
0
      ((mask & G_SIGNAL_MATCH_UNBLOCKED) || handler->block_count == 0) &&
532
0
      ((mask & G_SIGNAL_MATCH_FUNC) || (handler->closure->marshal == node->c_marshaller &&
533
0
                G_REAL_CLOSURE (handler->closure)->meta_marshal == NULL &&
534
0
                ((GCClosure*) handler->closure)->callback == func)))
535
0
    {
536
0
      mlist = handler_match_prepend (mlist, handler, signal_id);
537
0
      if (one_and_only)
538
0
        return mlist;
539
0
    }
540
0
    }
541
0
  else
542
0
    {
543
0
      GBSearchArray *hlbsa = g_hash_table_lookup (g_handler_list_bsa_ht, instance);
544
      
545
0
      mask = ~mask;
546
0
      if (hlbsa)
547
0
        {
548
0
          guint i;
549
          
550
0
          for (i = 0; i < hlbsa->n_nodes; i++)
551
0
            {
552
0
              HandlerList *hlist = g_bsearch_array_get_nth (hlbsa, &g_signal_hlbsa_bconfig, i);
553
0
        SignalNode *node = NULL;
554
0
              Handler *handler;
555
              
556
0
        if (!(mask & G_SIGNAL_MATCH_FUNC))
557
0
    {
558
0
      node = LOOKUP_SIGNAL_NODE (hlist->signal_id);
559
0
      if (!node->c_marshaller)
560
0
        continue;
561
0
    }
562
        
563
0
              for (handler = hlist->handlers; handler; handler = handler->next)
564
0
    if (handler->sequential_number &&
565
0
        ((mask & G_SIGNAL_MATCH_DETAIL) || handler->detail == detail) &&
566
0
                    ((mask & G_SIGNAL_MATCH_CLOSURE) || handler->closure == closure) &&
567
0
                    ((mask & G_SIGNAL_MATCH_DATA) || handler->closure->data == data) &&
568
0
        ((mask & G_SIGNAL_MATCH_UNBLOCKED) || handler->block_count == 0) &&
569
0
        ((mask & G_SIGNAL_MATCH_FUNC) || (handler->closure->marshal == node->c_marshaller &&
570
0
                  G_REAL_CLOSURE (handler->closure)->meta_marshal == NULL &&
571
0
                  ((GCClosure*) handler->closure)->callback == func)))
572
0
      {
573
0
        mlist = handler_match_prepend (mlist, handler, hlist->signal_id);
574
0
        if (one_and_only)
575
0
          return mlist;
576
0
      }
577
0
            }
578
0
        }
579
0
    }
580
  
581
0
  return mlist;
582
0
}
583
584
static inline Handler*
585
handler_new (guint signal_id, gpointer instance, gboolean after)
586
0
{
587
0
  Handler *handler = g_slice_new (Handler);
588
0
#ifndef G_DISABLE_CHECKS
589
0
  if (g_handler_sequential_number < 1)
590
0
    g_error (G_STRLOC ": handler id overflow, %s", REPORT_BUG);
591
0
#endif
592
  
593
0
  handler->sequential_number = g_handler_sequential_number++;
594
0
  handler->prev = NULL;
595
0
  handler->next = NULL;
596
0
  handler->detail = 0;
597
0
  handler->signal_id = signal_id;
598
0
  handler->instance = instance;
599
0
  handler->ref_count = 1;
600
0
  handler->block_count = 0;
601
0
  handler->after = after != FALSE;
602
0
  handler->closure = NULL;
603
0
  handler->has_invalid_closure_notify = 0;
604
605
0
  g_hash_table_add (g_handlers, handler);
606
  
607
0
  return handler;
608
0
}
609
610
static inline void
611
handler_ref (Handler *handler)
612
0
{
613
0
  g_return_if_fail (handler->ref_count > 0);
614
  
615
0
  handler->ref_count++;
616
0
}
617
618
static inline void
619
handler_unref_R (guint    signal_id,
620
     gpointer instance,
621
     Handler *handler)
622
0
{
623
0
  g_return_if_fail (handler->ref_count > 0);
624
625
0
  handler->ref_count--;
626
627
0
  if (G_UNLIKELY (handler->ref_count == 0))
628
0
    {
629
0
      HandlerList *hlist = NULL;
630
631
0
      if (handler->next)
632
0
        handler->next->prev = handler->prev;
633
0
      if (handler->prev)    /* watch out for g_signal_handlers_destroy()! */
634
0
        handler->prev->next = handler->next;
635
0
      else
636
0
        {
637
0
          hlist = handler_list_lookup (signal_id, instance);
638
0
          g_assert (hlist != NULL);
639
0
          hlist->handlers = handler->next;
640
0
        }
641
642
0
      if (instance)
643
0
        {
644
          /*  check if we are removing the handler pointed to by tail_before  */
645
0
          if (!handler->after && (!handler->next || handler->next->after))
646
0
            {
647
0
              if (!hlist)
648
0
                hlist = handler_list_lookup (signal_id, instance);
649
0
              if (hlist)
650
0
                {
651
0
                  g_assert (hlist->tail_before == handler); /* paranoid */
652
0
                  hlist->tail_before = handler->prev;
653
0
                }
654
0
            }
655
656
          /*  check if we are removing the handler pointed to by tail_after  */
657
0
          if (!handler->next)
658
0
            {
659
0
              if (!hlist)
660
0
                hlist = handler_list_lookup (signal_id, instance);
661
0
              if (hlist)
662
0
                {
663
0
                  g_assert (hlist->tail_after == handler); /* paranoid */
664
0
                  hlist->tail_after = handler->prev;
665
0
                }
666
0
            }
667
0
        }
668
669
0
      SIGNAL_UNLOCK ();
670
0
      g_closure_unref (handler->closure);
671
0
      SIGNAL_LOCK ();
672
0
      g_slice_free (Handler, handler);
673
0
    }
674
0
}
675
676
static void
677
handler_insert (guint    signal_id,
678
    gpointer instance,
679
    Handler  *handler)
680
0
{
681
0
  HandlerList *hlist;
682
  
683
0
  g_assert (handler->prev == NULL && handler->next == NULL); /* paranoid */
684
685
0
  hlist = handler_list_ensure (signal_id, instance);
686
0
  if (!hlist->handlers)
687
0
    {
688
0
      hlist->handlers = handler;
689
0
      if (!handler->after)
690
0
        hlist->tail_before = handler;
691
0
    }
692
0
  else if (handler->after)
693
0
    {
694
0
      handler->prev = hlist->tail_after;
695
0
      hlist->tail_after->next = handler;
696
0
    }
697
0
  else
698
0
    {
699
0
      if (hlist->tail_before)
700
0
        {
701
0
          handler->next = hlist->tail_before->next;
702
0
          if (handler->next)
703
0
            handler->next->prev = handler;
704
0
          handler->prev = hlist->tail_before;
705
0
          hlist->tail_before->next = handler;
706
0
        }
707
0
      else /* insert !after handler into a list of only after handlers */
708
0
        {
709
0
          handler->next = hlist->handlers;
710
0
          if (handler->next)
711
0
            handler->next->prev = handler;
712
0
          hlist->handlers = handler;
713
0
        }
714
0
      hlist->tail_before = handler;
715
0
    }
716
717
0
  if (!handler->next)
718
0
    hlist->tail_after = handler;
719
0
}
720
721
static void
722
node_update_single_va_closure (SignalNode *node)
723
0
{
724
0
  GClosure *closure = NULL;
725
0
  gboolean is_after = FALSE;
726
727
  /* Fast path single-handler without boxing the arguments in GValues */
728
0
  if (G_TYPE_IS_OBJECT (node->itype) &&
729
0
      (node->flags & (G_SIGNAL_MUST_COLLECT)) == 0 &&
730
0
      (node->emission_hooks == NULL || node->emission_hooks->hooks == NULL))
731
0
    {
732
0
      GSignalFlags run_type;
733
0
      ClassClosure * cc; 
734
0
      GBSearchArray *bsa = node->class_closure_bsa;
735
736
0
      if (bsa == NULL || bsa->n_nodes == 0)
737
0
  closure = SINGLE_VA_CLOSURE_EMPTY_MAGIC;
738
0
      else if (bsa->n_nodes == 1)
739
0
  {
740
    /* Look for default class closure (can't support non-default as it
741
       chains up using GValues */
742
0
    cc = g_bsearch_array_get_nth (bsa, &g_class_closure_bconfig, 0);
743
0
    if (cc->instance_type == 0)
744
0
      {
745
0
        run_type = node->flags & (G_SIGNAL_RUN_FIRST|G_SIGNAL_RUN_LAST|G_SIGNAL_RUN_CLEANUP);
746
        /* Only support *one* of run-first or run-last, not multiple or cleanup */
747
0
        if (run_type == G_SIGNAL_RUN_FIRST ||
748
0
      run_type == G_SIGNAL_RUN_LAST)
749
0
    {
750
0
      closure = cc->closure;
751
0
      is_after = (run_type == G_SIGNAL_RUN_LAST);
752
0
    }
753
0
      }
754
0
  }
755
0
    }
756
757
0
  node->single_va_closure_is_valid = TRUE;
758
0
  node->single_va_closure = closure;
759
0
  node->single_va_closure_is_after = (guint) is_after;
760
0
}
761
762
static inline void
763
emission_push (Emission  *emission)
764
0
{
765
0
  emission->next = g_emissions;
766
0
  g_emissions = emission;
767
0
}
768
769
static inline void
770
emission_pop (Emission  *emission)
771
0
{
772
0
  Emission *node, *last = NULL;
773
774
0
  for (node = g_emissions; node; last = node, node = last->next)
775
0
    if (node == emission)
776
0
      {
777
0
  if (last)
778
0
    last->next = node->next;
779
0
  else
780
0
    g_emissions = node->next;
781
0
  return;
782
0
      }
783
0
  g_assert_not_reached ();
784
0
}
785
786
static inline Emission*
787
emission_find (guint     signal_id,
788
         GQuark    detail,
789
         gpointer  instance)
790
0
{
791
0
  Emission *emission;
792
  
793
0
  for (emission = g_emissions; emission; emission = emission->next)
794
0
    if (emission->instance == instance &&
795
0
  emission->ihint.signal_id == signal_id &&
796
0
  emission->ihint.detail == detail)
797
0
      return emission;
798
0
  return NULL;
799
0
}
800
801
static inline Emission*
802
emission_find_innermost (gpointer instance)
803
0
{
804
0
  Emission *emission;
805
  
806
0
  for (emission = g_emissions; emission; emission = emission->next)
807
0
    if (emission->instance == instance)
808
0
      return emission;
809
810
0
  return NULL;
811
0
}
812
813
static gint
814
signal_key_cmp (gconstpointer node1,
815
                gconstpointer node2)
816
0
{
817
0
  const SignalKey *key1 = node1, *key2 = node2;
818
  
819
0
  if (key1->itype == key2->itype)
820
0
    return G_BSEARCH_ARRAY_CMP (key1->quark, key2->quark);
821
0
  else
822
0
    return G_BSEARCH_ARRAY_CMP (key1->itype, key2->itype);
823
0
}
824
825
void
826
_g_signal_init (void)
827
4
{
828
4
  SIGNAL_LOCK ();
829
4
  if (!g_n_signal_nodes)
830
4
    {
831
      /* setup handler list binary searchable array hash table (in german, that'd be one word ;) */
832
4
      g_handler_list_bsa_ht = g_hash_table_new (g_direct_hash, NULL);
833
4
      g_signal_key_bsa = g_bsearch_array_create (&g_signal_key_bconfig);
834
      
835
      /* invalid (0) signal_id */
836
4
      g_n_signal_nodes = 1;
837
4
      g_signal_nodes = g_renew (SignalNode*, g_signal_nodes, g_n_signal_nodes);
838
4
      g_signal_nodes[0] = NULL;
839
4
      g_handlers = g_hash_table_new (handler_hash, handler_equal);
840
4
    }
841
4
  SIGNAL_UNLOCK ();
842
4
}
843
844
void
845
_g_signals_destroy (GType itype)
846
0
{
847
0
  guint i;
848
  
849
0
  SIGNAL_LOCK ();
850
0
  for (i = 1; i < g_n_signal_nodes; i++)
851
0
    {
852
0
      SignalNode *node = g_signal_nodes[i];
853
      
854
0
      if (node->itype == itype)
855
0
        {
856
0
          if (node->destroyed)
857
0
            g_critical (G_STRLOC ": signal \"%s\" of type '%s' already destroyed",
858
0
                        node->name,
859
0
                        type_debug_name (node->itype));
860
0
          else
861
0
      signal_destroy_R (node);
862
0
        }
863
0
    }
864
0
  SIGNAL_UNLOCK ();
865
0
}
866
867
/**
868
 * g_signal_stop_emission:
869
 * @instance: (type GObject.Object): the object whose signal handlers you wish to stop.
870
 * @signal_id: the signal identifier, as returned by g_signal_lookup().
871
 * @detail: the detail which the signal was emitted with.
872
 *
873
 * Stops a signal's current emission.
874
 *
875
 * This will prevent the default method from running, if the signal was
876
 * %G_SIGNAL_RUN_LAST and you connected normally (i.e. without the "after"
877
 * flag).
878
 *
879
 * Prints a warning if used on a signal which isn't being emitted.
880
 */
881
void
882
g_signal_stop_emission (gpointer instance,
883
                        guint    signal_id,
884
      GQuark   detail)
885
0
{
886
0
  SignalNode *node;
887
  
888
0
  g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance));
889
0
  g_return_if_fail (signal_id > 0);
890
  
891
0
  SIGNAL_LOCK ();
892
0
  node = LOOKUP_SIGNAL_NODE (signal_id);
893
0
  if (node && detail && !(node->flags & G_SIGNAL_DETAILED))
894
0
    {
895
0
      g_critical ("%s: signal id '%u' does not support detail (%u)", G_STRLOC, signal_id, detail);
896
0
      SIGNAL_UNLOCK ();
897
0
      return;
898
0
    }
899
0
  if (node && g_type_is_a (G_TYPE_FROM_INSTANCE (instance), node->itype))
900
0
    {
901
0
      Emission *emission = emission_find (signal_id, detail, instance);
902
      
903
0
      if (emission)
904
0
        {
905
0
          if (emission->state == EMISSION_HOOK)
906
0
            g_critical (G_STRLOC ": emission of signal \"%s\" for instance '%p' cannot be stopped from emission hook",
907
0
                        node->name, instance);
908
0
          else if (emission->state == EMISSION_RUN)
909
0
            emission->state = EMISSION_STOP;
910
0
        }
911
0
      else
912
0
        g_critical (G_STRLOC ": no emission of signal \"%s\" to stop for instance '%p'",
913
0
                    node->name, instance);
914
0
    }
915
0
  else
916
0
    g_critical ("%s: signal id '%u' is invalid for instance '%p'", G_STRLOC, signal_id, instance);
917
0
  SIGNAL_UNLOCK ();
918
0
}
919
920
static void
921
signal_finalize_hook (GHookList *hook_list,
922
          GHook     *hook)
923
0
{
924
0
  GDestroyNotify destroy = hook->destroy;
925
926
0
  if (destroy)
927
0
    {
928
0
      hook->destroy = NULL;
929
0
      SIGNAL_UNLOCK ();
930
0
      destroy (hook->data);
931
0
      SIGNAL_LOCK ();
932
0
    }
933
0
}
934
935
/**
936
 * g_signal_add_emission_hook:
937
 * @signal_id: the signal identifier, as returned by g_signal_lookup().
938
 * @detail: the detail on which to call the hook.
939
 * @hook_func: (not nullable): a #GSignalEmissionHook function.
940
 * @hook_data: (nullable) (closure hook_func): user data for @hook_func.
941
 * @data_destroy: (nullable) (destroy hook_data): a #GDestroyNotify for @hook_data.
942
 *
943
 * Adds an emission hook for a signal, which will get called for any emission
944
 * of that signal, independent of the instance. This is possible only
945
 * for signals which don't have %G_SIGNAL_NO_HOOKS flag set.
946
 *
947
 * Returns: the hook id, for later use with g_signal_remove_emission_hook().
948
 */
949
gulong
950
g_signal_add_emission_hook (guint               signal_id,
951
          GQuark              detail,
952
          GSignalEmissionHook hook_func,
953
          gpointer            hook_data,
954
          GDestroyNotify      data_destroy)
955
0
{
956
0
  static gulong seq_hook_id = 1;
957
0
  SignalNode *node;
958
0
  GHook *hook;
959
0
  SignalHook *signal_hook;
960
961
0
  g_return_val_if_fail (signal_id > 0, 0);
962
0
  g_return_val_if_fail (hook_func != NULL, 0);
963
964
0
  SIGNAL_LOCK ();
965
0
  node = LOOKUP_SIGNAL_NODE (signal_id);
966
0
  if (!node || node->destroyed)
967
0
    {
968
0
      g_critical ("%s: invalid signal id '%u'", G_STRLOC, signal_id);
969
0
      SIGNAL_UNLOCK ();
970
0
      return 0;
971
0
    }
972
0
  if (node->flags & G_SIGNAL_NO_HOOKS) 
973
0
    {
974
0
      g_critical ("%s: signal id '%u' does not support emission hooks (G_SIGNAL_NO_HOOKS flag set)", G_STRLOC, signal_id);
975
0
      SIGNAL_UNLOCK ();
976
0
      return 0;
977
0
    }
978
0
  if (detail && !(node->flags & G_SIGNAL_DETAILED))
979
0
    {
980
0
      g_critical ("%s: signal id '%u' does not support detail (%u)", G_STRLOC, signal_id, detail);
981
0
      SIGNAL_UNLOCK ();
982
0
      return 0;
983
0
    }
984
0
    node->single_va_closure_is_valid = FALSE;
985
0
  if (!node->emission_hooks)
986
0
    {
987
0
      node->emission_hooks = g_new (GHookList, 1);
988
0
      g_hook_list_init (node->emission_hooks, sizeof (SignalHook));
989
0
      node->emission_hooks->finalize_hook = signal_finalize_hook;
990
0
    }
991
992
0
  node_check_deprecated (node);
993
994
0
  hook = g_hook_alloc (node->emission_hooks);
995
0
  hook->data = hook_data;
996
0
  hook->func = (gpointer) hook_func;
997
0
  hook->destroy = data_destroy;
998
0
  signal_hook = SIGNAL_HOOK (hook);
999
0
  signal_hook->detail = detail;
1000
0
  node->emission_hooks->seq_id = seq_hook_id;
1001
0
  g_hook_append (node->emission_hooks, hook);
1002
0
  seq_hook_id = node->emission_hooks->seq_id;
1003
1004
0
  SIGNAL_UNLOCK ();
1005
1006
0
  return hook->hook_id;
1007
0
}
1008
1009
/**
1010
 * g_signal_remove_emission_hook:
1011
 * @signal_id: the id of the signal
1012
 * @hook_id: the id of the emission hook, as returned by
1013
 *  g_signal_add_emission_hook()
1014
 *
1015
 * Deletes an emission hook.
1016
 */
1017
void
1018
g_signal_remove_emission_hook (guint  signal_id,
1019
             gulong hook_id)
1020
0
{
1021
0
  SignalNode *node;
1022
1023
0
  g_return_if_fail (signal_id > 0);
1024
0
  g_return_if_fail (hook_id > 0);
1025
1026
0
  SIGNAL_LOCK ();
1027
0
  node = LOOKUP_SIGNAL_NODE (signal_id);
1028
0
  if (!node || node->destroyed)
1029
0
    {
1030
0
      g_critical ("%s: invalid signal id '%u'", G_STRLOC, signal_id);
1031
0
      goto out;
1032
0
    }
1033
0
  else if (!node->emission_hooks || !g_hook_destroy (node->emission_hooks, hook_id))
1034
0
    g_critical ("%s: signal \"%s\" had no hook (%lu) to remove", G_STRLOC, node->name, hook_id);
1035
1036
0
  node->single_va_closure_is_valid = FALSE;
1037
1038
0
 out:
1039
0
  SIGNAL_UNLOCK ();
1040
0
}
1041
1042
static inline guint
1043
signal_parse_name (const gchar *name,
1044
       GType        itype,
1045
       GQuark      *detail_p,
1046
       gboolean     force_quark)
1047
0
{
1048
0
  const gchar *colon = strchr (name, ':');
1049
0
  guint signal_id;
1050
  
1051
0
  if (!colon)
1052
0
    {
1053
0
      signal_id = signal_id_lookup (name, itype);
1054
0
      if (signal_id && detail_p)
1055
0
  *detail_p = 0;
1056
0
    }
1057
0
  else if (colon[1] == ':')
1058
0
    {
1059
0
      gchar buffer[32];
1060
0
      size_t l = (size_t) (colon - name);
1061
      
1062
0
      if (colon[2] == '\0')
1063
0
        return 0;
1064
1065
0
      if (l < 32)
1066
0
  {
1067
0
    memcpy (buffer, name, l);
1068
0
    buffer[l] = 0;
1069
0
    signal_id = signal_id_lookup (buffer, itype);
1070
0
  }
1071
0
      else
1072
0
  {
1073
0
    gchar *signal = g_new (gchar, l + 1);
1074
    
1075
0
    memcpy (signal, name, l);
1076
0
    signal[l] = 0;
1077
0
    signal_id = signal_id_lookup (signal, itype);
1078
0
    g_free (signal);
1079
0
  }
1080
      
1081
0
      if (signal_id && detail_p)
1082
0
        *detail_p = (force_quark ? g_quark_from_string : g_quark_try_string) (colon + 2);
1083
0
    }
1084
0
  else
1085
0
    signal_id = 0;
1086
0
  return signal_id;
1087
0
}
1088
1089
/**
1090
 * g_signal_parse_name:
1091
 * @detailed_signal: a string of the form "signal-name::detail".
1092
 * @itype: The interface/instance type that introduced "signal-name".
1093
 * @signal_id_p: (out): Location to store the signal id.
1094
 * @detail_p: (out): Location to store the detail quark.
1095
 * @force_detail_quark: %TRUE forces creation of a #GQuark for the detail.
1096
 *
1097
 * Internal function to parse a signal name into its @signal_id
1098
 * and @detail quark.
1099
 *
1100
 * Returns: Whether the signal name could successfully be parsed and @signal_id_p and @detail_p contain valid return values.
1101
 */
1102
gboolean
1103
g_signal_parse_name (const gchar *detailed_signal,
1104
         GType        itype,
1105
         guint       *signal_id_p,
1106
         GQuark      *detail_p,
1107
         gboolean   force_detail_quark)
1108
0
{
1109
0
  SignalNode *node;
1110
0
  GQuark detail = 0;
1111
0
  guint signal_id;
1112
  
1113
0
  g_return_val_if_fail (detailed_signal != NULL, FALSE);
1114
0
  g_return_val_if_fail (G_TYPE_IS_INSTANTIATABLE (itype) || G_TYPE_IS_INTERFACE (itype), FALSE);
1115
  
1116
0
  SIGNAL_LOCK ();
1117
0
  signal_id = signal_parse_name (detailed_signal, itype, &detail, force_detail_quark);
1118
1119
0
  node = signal_id ? LOOKUP_SIGNAL_NODE (signal_id) : NULL;
1120
1121
0
  if (!node || node->destroyed ||
1122
0
      (detail && !(node->flags & G_SIGNAL_DETAILED)))
1123
0
    {
1124
0
      SIGNAL_UNLOCK ();
1125
0
      return FALSE;
1126
0
    }
1127
1128
0
  SIGNAL_UNLOCK ();
1129
1130
0
  if (signal_id_p)
1131
0
    *signal_id_p = signal_id;
1132
0
  if (detail_p)
1133
0
    *detail_p = detail;
1134
  
1135
0
  return TRUE;
1136
0
}
1137
1138
/**
1139
 * g_signal_stop_emission_by_name:
1140
 * @instance: (type GObject.Object): the object whose signal handlers you wish to stop.
1141
 * @detailed_signal: a string of the form "signal-name::detail".
1142
 *
1143
 * Stops a signal's current emission.
1144
 *
1145
 * This is just like g_signal_stop_emission() except it will look up the
1146
 * signal id for you.
1147
 */
1148
void
1149
g_signal_stop_emission_by_name (gpointer     instance,
1150
        const gchar *detailed_signal)
1151
0
{
1152
0
  guint signal_id;
1153
0
  GQuark detail = 0;
1154
0
  GType itype;
1155
  
1156
0
  g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance));
1157
0
  g_return_if_fail (detailed_signal != NULL);
1158
  
1159
0
  SIGNAL_LOCK ();
1160
0
  itype = G_TYPE_FROM_INSTANCE (instance);
1161
0
  signal_id = signal_parse_name (detailed_signal, itype, &detail, TRUE);
1162
0
  if (signal_id)
1163
0
    {
1164
0
      SignalNode *node = LOOKUP_SIGNAL_NODE (signal_id);
1165
      
1166
0
      if (detail && !(node->flags & G_SIGNAL_DETAILED))
1167
0
  g_critical ("%s: signal '%s' does not support details", G_STRLOC, detailed_signal);
1168
0
      else if (!g_type_is_a (itype, node->itype))
1169
0
        g_critical ("%s: signal '%s' is invalid for instance '%p' of type '%s'",
1170
0
                    G_STRLOC, detailed_signal, instance, g_type_name (itype));
1171
0
      else
1172
0
  {
1173
0
    Emission *emission = emission_find (signal_id, detail, instance);
1174
    
1175
0
    if (emission)
1176
0
      {
1177
0
        if (emission->state == EMISSION_HOOK)
1178
0
    g_critical (G_STRLOC ": emission of signal \"%s\" for instance '%p' cannot be stopped from emission hook",
1179
0
          node->name, instance);
1180
0
        else if (emission->state == EMISSION_RUN)
1181
0
    emission->state = EMISSION_STOP;
1182
0
      }
1183
0
    else
1184
0
      g_critical (G_STRLOC ": no emission of signal \"%s\" to stop for instance '%p'",
1185
0
            node->name, instance);
1186
0
  }
1187
0
    }
1188
0
  else
1189
0
    g_critical ("%s: signal '%s' is invalid for instance '%p' of type '%s'",
1190
0
                G_STRLOC, detailed_signal, instance, g_type_name (itype));
1191
0
  SIGNAL_UNLOCK ();
1192
0
}
1193
1194
/**
1195
 * g_signal_lookup:
1196
 * @name: the signal's name.
1197
 * @itype: the type that the signal operates on.
1198
 *
1199
 * Given the name of the signal and the type of object it connects to, gets
1200
 * the signal's identifying integer. Emitting the signal by number is
1201
 * somewhat faster than using the name each time.
1202
 *
1203
 * Also tries the ancestors of the given type.
1204
 *
1205
 * The type class passed as @itype must already have been instantiated (for
1206
 * example, using g_type_class_ref()) for this function to work, as signals are
1207
 * always installed during class initialization.
1208
 *
1209
 * See g_signal_new() for details on allowed signal names.
1210
 *
1211
 * Returns: the signal's identifying number, or 0 if no signal was found.
1212
 */
1213
guint
1214
g_signal_lookup (const gchar *name,
1215
                 GType        itype)
1216
0
{
1217
0
  guint signal_id;
1218
0
  g_return_val_if_fail (name != NULL, 0);
1219
0
  g_return_val_if_fail (G_TYPE_IS_INSTANTIATABLE (itype) || G_TYPE_IS_INTERFACE (itype), 0);
1220
  
1221
0
  SIGNAL_LOCK ();
1222
0
  signal_id = signal_id_lookup (name, itype);
1223
0
  SIGNAL_UNLOCK ();
1224
0
  if (!signal_id)
1225
0
    {
1226
      /* give elaborate warnings */
1227
0
      if (!g_type_name (itype))
1228
0
  g_critical (G_STRLOC ": unable to look up signal \"%s\" for invalid type id '%"G_GUINTPTR_FORMAT"'",
1229
0
        name, (guintptr) itype);
1230
0
      else if (!g_signal_is_valid_name (name))
1231
0
        g_critical (G_STRLOC ": unable to look up invalid signal name \"%s\" on type '%s'",
1232
0
                    name, g_type_name (itype));
1233
0
    }
1234
  
1235
0
  return signal_id;
1236
0
}
1237
1238
/**
1239
 * g_signal_list_ids:
1240
 * @itype: Instance or interface type.
1241
 * @n_ids: Location to store the number of signal ids for @itype.
1242
 *
1243
 * Lists the signals by id that a certain instance or interface type
1244
 * created. Further information about the signals can be acquired through
1245
 * g_signal_query().
1246
 *
1247
 * Returns: (array length=n_ids) (transfer full): Newly allocated array of signal IDs.
1248
 */
1249
guint*
1250
g_signal_list_ids (GType  itype,
1251
       guint *n_ids)
1252
0
{
1253
0
  SignalKey *keys;
1254
0
  GArray *result;
1255
0
  guint n_nodes;
1256
0
  guint i;
1257
  
1258
0
  g_return_val_if_fail (G_TYPE_IS_INSTANTIATABLE (itype) || G_TYPE_IS_INTERFACE (itype), NULL);
1259
0
  g_return_val_if_fail (n_ids != NULL, NULL);
1260
  
1261
0
  SIGNAL_LOCK ();
1262
0
  keys = g_bsearch_array_get_nth (g_signal_key_bsa, &g_signal_key_bconfig, 0);
1263
0
  n_nodes = g_bsearch_array_get_n_nodes (g_signal_key_bsa);
1264
0
  result = g_array_new (FALSE, FALSE, sizeof (guint));
1265
  
1266
0
  for (i = 0; i < n_nodes; i++)
1267
0
    if (keys[i].itype == itype)
1268
0
      {
1269
0
        g_array_append_val (result, keys[i].signal_id);
1270
0
      }
1271
0
  *n_ids = result->len;
1272
0
  SIGNAL_UNLOCK ();
1273
0
  if (!n_nodes)
1274
0
    {
1275
      /* give elaborate warnings */
1276
0
      if (!g_type_name (itype))
1277
0
  g_critical (G_STRLOC ": unable to list signals for invalid type id '%"G_GUINTPTR_FORMAT"'",
1278
0
        (guintptr) itype);
1279
0
      else if (!G_TYPE_IS_INSTANTIATABLE (itype) && !G_TYPE_IS_INTERFACE (itype))
1280
0
  g_critical (G_STRLOC ": unable to list signals of non instantiatable type '%s'",
1281
0
        g_type_name (itype));
1282
0
      else if (!g_type_class_peek (itype) && !G_TYPE_IS_INTERFACE (itype))
1283
0
  g_critical (G_STRLOC ": unable to list signals of unloaded type '%s'",
1284
0
        g_type_name (itype));
1285
0
    }
1286
  
1287
0
  return (guint*) g_array_free (result, FALSE);
1288
0
}
1289
1290
/**
1291
 * g_signal_name:
1292
 * @signal_id: the signal's identifying number.
1293
 *
1294
 * Given the signal's identifier, finds its name.
1295
 *
1296
 * Two different signals may have the same name, if they have differing types.
1297
 *
1298
 * Returns: (nullable): the signal name, or %NULL if the signal number was invalid.
1299
 */
1300
const gchar *
1301
g_signal_name (guint signal_id)
1302
0
{
1303
0
  SignalNode *node;
1304
0
  const gchar *name;
1305
  
1306
0
  SIGNAL_LOCK ();
1307
0
  node = LOOKUP_SIGNAL_NODE (signal_id);
1308
0
  name = node ? node->name : NULL;
1309
0
  SIGNAL_UNLOCK ();
1310
  
1311
0
  return (char*) name;
1312
0
}
1313
1314
/**
1315
 * g_signal_query:
1316
 * @signal_id: The signal id of the signal to query information for.
1317
 * @query: (out caller-allocates) (not optional): A user provided structure that is
1318
 *  filled in with constant values upon success.
1319
 *
1320
 * Queries the signal system for in-depth information about a
1321
 * specific signal. This function will fill in a user-provided
1322
 * structure to hold signal-specific information. If an invalid
1323
 * signal id is passed in, the @signal_id member of the #GSignalQuery
1324
 * is 0. All members filled into the #GSignalQuery structure should
1325
 * be considered constant and have to be left untouched.
1326
 */
1327
void
1328
g_signal_query (guint         signal_id,
1329
    GSignalQuery *query)
1330
0
{
1331
0
  SignalNode *node;
1332
  
1333
0
  g_return_if_fail (query != NULL);
1334
  
1335
0
  SIGNAL_LOCK ();
1336
0
  node = LOOKUP_SIGNAL_NODE (signal_id);
1337
0
  if (!node || node->destroyed)
1338
0
    query->signal_id = 0;
1339
0
  else
1340
0
    {
1341
0
      query->signal_id = node->signal_id;
1342
0
      query->signal_name = node->name;
1343
0
      query->itype = node->itype;
1344
0
      query->signal_flags = node->flags;
1345
0
      query->return_type = node->return_type;
1346
0
      query->n_params = node->n_params;
1347
0
      query->param_types = node->param_types;
1348
0
    }
1349
0
  SIGNAL_UNLOCK ();
1350
0
}
1351
1352
/**
1353
 * g_signal_new:
1354
 * @signal_name: the name for the signal
1355
 * @itype: the type this signal pertains to. It will also pertain to
1356
 *  types which are derived from this type.
1357
 * @signal_flags: a combination of #GSignalFlags specifying detail of when
1358
 *  the default handler is to be invoked. You should at least specify
1359
 *  %G_SIGNAL_RUN_FIRST or %G_SIGNAL_RUN_LAST.
1360
 * @class_offset: The offset of the function pointer in the class structure
1361
 *  for this type. Used to invoke a class method generically. Pass 0 to
1362
 *  not associate a class method slot with this signal.
1363
 * @accumulator: (nullable) (scope forever): the accumulator for this signal; may be %NULL.
1364
 * @accu_data: (nullable) (closure accumulator): user data for the @accumulator.
1365
 * @c_marshaller: (nullable): the function to translate arrays of parameter
1366
 *  values to signal emissions into C language callback invocations or %NULL.
1367
 * @return_type: the type of return value, or %G_TYPE_NONE for a signal
1368
 *  without a return value.
1369
 * @n_params: the number of parameter types to follow.
1370
 * @...: a list of types, one for each parameter.
1371
 *
1372
 * Creates a new signal. (This is usually done in the class initializer.)
1373
 *
1374
 * A signal name consists of segments consisting of ASCII letters and
1375
 * digits, separated by either the `-` or `_` character. The first
1376
 * character of a signal name must be a letter. Names which violate these
1377
 * rules lead to undefined behaviour. These are the same rules as for property
1378
 * naming (see g_param_spec_internal()).
1379
 *
1380
 * When registering a signal and looking up a signal, either separator can
1381
 * be used, but they cannot be mixed. Using `-` is considerably more efficient.
1382
 * Using `_` is discouraged.
1383
 *
1384
 * If 0 is used for @class_offset subclasses cannot override the class handler
1385
 * in their class_init method by doing super_class->signal_handler = my_signal_handler.
1386
 * Instead they will have to use g_signal_override_class_handler().
1387
 *
1388
 * If @c_marshaller is %NULL, g_cclosure_marshal_generic() will be used as
1389
 * the marshaller for this signal. In some simple cases, g_signal_new()
1390
 * will use a more optimized c_marshaller and va_marshaller for the signal
1391
 * instead of g_cclosure_marshal_generic().
1392
 *
1393
 * If @c_marshaller is non-%NULL, you need to also specify a va_marshaller
1394
 * using g_signal_set_va_marshaller() or the generic va_marshaller will
1395
 * be used.
1396
 *
1397
 * Returns: the signal id
1398
 */
1399
guint
1400
g_signal_new (const gchar  *signal_name,
1401
        GType     itype,
1402
        GSignalFlags    signal_flags,
1403
        guint               class_offset,
1404
        GSignalAccumulator  accumulator,
1405
        gpointer      accu_data,
1406
        GSignalCMarshaller  c_marshaller,
1407
        GType     return_type,
1408
        guint     n_params,
1409
        ...)
1410
0
{
1411
0
  va_list args;
1412
0
  guint signal_id;
1413
1414
0
  g_return_val_if_fail (signal_name != NULL, 0);
1415
  
1416
0
  va_start (args, n_params);
1417
1418
0
  signal_id = g_signal_new_valist (signal_name, itype, signal_flags,
1419
0
                                   class_offset ? g_signal_type_cclosure_new (itype, class_offset) : NULL,
1420
0
           accumulator, accu_data, c_marshaller,
1421
0
                                   return_type, n_params, args);
1422
1423
0
  va_end (args);
1424
1425
0
  return signal_id;
1426
0
}
1427
1428
/**
1429
 * g_signal_new_class_handler:
1430
 * @signal_name: the name for the signal
1431
 * @itype: the type this signal pertains to. It will also pertain to
1432
 *  types which are derived from this type.
1433
 * @signal_flags: a combination of #GSignalFlags specifying detail of when
1434
 *  the default handler is to be invoked. You should at least specify
1435
 *  %G_SIGNAL_RUN_FIRST or %G_SIGNAL_RUN_LAST.
1436
 * @class_handler: (nullable) (scope forever): a #GCallback which acts as class implementation of
1437
 *  this signal. Used to invoke a class method generically. Pass %NULL to
1438
 *  not associate a class method with this signal.
1439
 * @accumulator: (nullable) (scope forever): the accumulator for this signal; may be %NULL.
1440
 * @accu_data: (nullable) (closure accumulator): user data for the @accumulator.
1441
 * @c_marshaller: (nullable): the function to translate arrays of parameter
1442
 *  values to signal emissions into C language callback invocations or %NULL.
1443
 * @return_type: the type of return value, or %G_TYPE_NONE for a signal
1444
 *  without a return value.
1445
 * @n_params: the number of parameter types to follow.
1446
 * @...: a list of types, one for each parameter.
1447
 *
1448
 * Creates a new signal. (This is usually done in the class initializer.)
1449
 *
1450
 * This is a variant of g_signal_new() that takes a C callback instead
1451
 * of a class offset for the signal's class handler. This function
1452
 * doesn't need a function pointer exposed in the class structure of
1453
 * an object definition, instead the function pointer is passed
1454
 * directly and can be overridden by derived classes with
1455
 * g_signal_override_class_closure() or
1456
 * g_signal_override_class_handler() and chained to with
1457
 * g_signal_chain_from_overridden() or
1458
 * g_signal_chain_from_overridden_handler().
1459
 *
1460
 * See g_signal_new() for information about signal names.
1461
 *
1462
 * If c_marshaller is %NULL, g_cclosure_marshal_generic() will be used as
1463
 * the marshaller for this signal.
1464
 *
1465
 * Returns: the signal id
1466
 *
1467
 * Since: 2.18
1468
 */
1469
guint
1470
g_signal_new_class_handler (const gchar        *signal_name,
1471
                            GType               itype,
1472
                            GSignalFlags        signal_flags,
1473
                            GCallback           class_handler,
1474
                            GSignalAccumulator  accumulator,
1475
                            gpointer            accu_data,
1476
                            GSignalCMarshaller  c_marshaller,
1477
                            GType               return_type,
1478
                            guint               n_params,
1479
                            ...)
1480
0
{
1481
0
  va_list args;
1482
0
  guint signal_id;
1483
1484
0
  g_return_val_if_fail (signal_name != NULL, 0);
1485
1486
0
  va_start (args, n_params);
1487
1488
0
  signal_id = g_signal_new_valist (signal_name, itype, signal_flags,
1489
0
                                   class_handler ? g_cclosure_new (class_handler, NULL, NULL) : NULL,
1490
0
                                   accumulator, accu_data, c_marshaller,
1491
0
                                   return_type, n_params, args);
1492
1493
0
  va_end (args);
1494
1495
0
  return signal_id;
1496
0
}
1497
1498
static inline ClassClosure*
1499
signal_find_class_closure (SignalNode *node,
1500
         GType       itype)
1501
0
{
1502
0
  GBSearchArray *bsa = node->class_closure_bsa;
1503
0
  ClassClosure *cc;
1504
1505
0
  if (bsa)
1506
0
    {
1507
0
      ClassClosure key;
1508
1509
      /* cc->instance_type is 0 for default closure */
1510
1511
0
      if (g_bsearch_array_get_n_nodes (bsa) == 1)
1512
0
        {
1513
0
          cc = g_bsearch_array_get_nth (bsa, &g_class_closure_bconfig, 0);
1514
0
          if (cc && cc->instance_type == 0) /* check for default closure */
1515
0
            return cc;
1516
0
        }
1517
1518
0
      key.instance_type = itype;
1519
0
      cc = g_bsearch_array_lookup (bsa, &g_class_closure_bconfig, &key);
1520
0
      while (!cc && key.instance_type)
1521
0
  {
1522
0
    key.instance_type = g_type_parent (key.instance_type);
1523
0
    cc = g_bsearch_array_lookup (bsa, &g_class_closure_bconfig, &key);
1524
0
  }
1525
0
    }
1526
0
  else
1527
0
    cc = NULL;
1528
0
  return cc;
1529
0
}
1530
1531
static inline GClosure*
1532
signal_lookup_closure (SignalNode    *node,
1533
           GTypeInstance *instance)
1534
0
{
1535
0
  ClassClosure *cc;
1536
1537
0
  cc = signal_find_class_closure (node, G_TYPE_FROM_INSTANCE (instance));
1538
0
  return cc ? cc->closure : NULL;
1539
0
}
1540
1541
static void
1542
signal_add_class_closure (SignalNode *node,
1543
        GType       itype,
1544
        GClosure   *closure)
1545
0
{
1546
0
  ClassClosure key;
1547
1548
0
  node->single_va_closure_is_valid = FALSE;
1549
1550
0
  if (!node->class_closure_bsa)
1551
0
    node->class_closure_bsa = g_bsearch_array_create (&g_class_closure_bconfig);
1552
0
  key.instance_type = itype;
1553
0
  key.closure = g_closure_ref (closure);
1554
0
  node->class_closure_bsa = g_bsearch_array_insert (node->class_closure_bsa,
1555
0
                &g_class_closure_bconfig,
1556
0
                &key);
1557
0
  g_closure_sink (closure);
1558
0
  if (node->c_marshaller && closure && G_CLOSURE_NEEDS_MARSHAL (closure))
1559
0
    {
1560
0
      g_closure_set_marshal (closure, node->c_marshaller);
1561
0
      if (node->va_marshaller)
1562
0
  _g_closure_set_va_marshal (closure, node->va_marshaller);
1563
0
    }
1564
0
}
1565
1566
/**
1567
 * g_signal_newv:
1568
 * @signal_name: the name for the signal
1569
 * @itype: the type this signal pertains to. It will also pertain to
1570
 *     types which are derived from this type
1571
 * @signal_flags: a combination of #GSignalFlags specifying detail of when
1572
 *     the default handler is to be invoked. You should at least specify
1573
 *     %G_SIGNAL_RUN_FIRST or %G_SIGNAL_RUN_LAST
1574
 * @class_closure: (nullable): The closure to invoke on signal emission;
1575
 *     may be %NULL
1576
 * @accumulator: (nullable) (scope forever): the accumulator for this signal; may be %NULL
1577
 * @accu_data: (nullable) (closure accumulator): user data for the @accumulator
1578
 * @c_marshaller: (nullable): the function to translate arrays of
1579
 *     parameter values to signal emissions into C language callback
1580
 *     invocations or %NULL
1581
 * @return_type: the type of return value, or %G_TYPE_NONE for a signal
1582
 *     without a return value
1583
 * @n_params: the length of @param_types
1584
 * @param_types: (array length=n_params) (nullable): an array of types, one for
1585
 *     each parameter (may be %NULL if @n_params is zero)
1586
 *
1587
 * Creates a new signal. (This is usually done in the class initializer.)
1588
 *
1589
 * See g_signal_new() for details on allowed signal names.
1590
 *
1591
 * If c_marshaller is %NULL, g_cclosure_marshal_generic() will be used as
1592
 * the marshaller for this signal.
1593
 *
1594
 * Returns: the signal id
1595
 */
1596
guint
1597
g_signal_newv (const gchar       *signal_name,
1598
               GType              itype,
1599
               GSignalFlags       signal_flags,
1600
               GClosure          *class_closure,
1601
               GSignalAccumulator accumulator,
1602
         gpointer     accu_data,
1603
               GSignalCMarshaller c_marshaller,
1604
               GType      return_type,
1605
               guint              n_params,
1606
               GType     *param_types)
1607
0
{
1608
0
  const gchar *name;
1609
0
  gchar *signal_name_copy = NULL;
1610
0
  guint signal_id, i;
1611
0
  SignalNode *node;
1612
0
  GSignalCMarshaller builtin_c_marshaller;
1613
0
  GSignalCVaMarshaller builtin_va_marshaller;
1614
0
  GSignalCVaMarshaller va_marshaller;
1615
  
1616
0
  g_return_val_if_fail (signal_name != NULL, 0);
1617
0
  g_return_val_if_fail (g_signal_is_valid_name (signal_name), 0);
1618
0
  g_return_val_if_fail (G_TYPE_IS_INSTANTIATABLE (itype) || G_TYPE_IS_INTERFACE (itype), 0);
1619
0
  if (n_params)
1620
0
    g_return_val_if_fail (param_types != NULL, 0);
1621
0
  g_return_val_if_fail ((return_type & G_SIGNAL_TYPE_STATIC_SCOPE) == 0, 0);
1622
0
  if (return_type == (G_TYPE_NONE & ~G_SIGNAL_TYPE_STATIC_SCOPE))
1623
0
    g_return_val_if_fail (accumulator == NULL, 0);
1624
0
  if (!accumulator)
1625
0
    g_return_val_if_fail (accu_data == NULL, 0);
1626
0
  g_return_val_if_fail ((signal_flags & G_SIGNAL_ACCUMULATOR_FIRST_RUN) == 0, 0);
1627
1628
0
  if (!is_canonical (signal_name))
1629
0
    {
1630
0
      signal_name_copy = g_strdup (signal_name);
1631
0
      canonicalize_key (signal_name_copy);
1632
0
      name = signal_name_copy;
1633
0
    }
1634
0
  else
1635
0
    {
1636
0
      name = signal_name;
1637
0
    }
1638
  
1639
0
  SIGNAL_LOCK ();
1640
  
1641
0
  signal_id = signal_id_lookup (name, itype);
1642
0
  node = LOOKUP_SIGNAL_NODE (signal_id);
1643
0
  if (node && !node->destroyed)
1644
0
    {
1645
0
      g_critical (G_STRLOC ": signal \"%s\" already exists in the '%s' %s",
1646
0
                  name,
1647
0
                  type_debug_name (node->itype),
1648
0
                  G_TYPE_IS_INTERFACE (node->itype) ? "interface" : "class ancestry");
1649
0
      g_free (signal_name_copy);
1650
0
      SIGNAL_UNLOCK ();
1651
0
      return 0;
1652
0
    }
1653
0
  if (node && node->itype != itype)
1654
0
    {
1655
0
      g_critical (G_STRLOC ": signal \"%s\" for type '%s' was previously created for type '%s'",
1656
0
                  name,
1657
0
                  type_debug_name (itype),
1658
0
                  type_debug_name (node->itype));
1659
0
      g_free (signal_name_copy);
1660
0
      SIGNAL_UNLOCK ();
1661
0
      return 0;
1662
0
    }
1663
0
  for (i = 0; i < n_params; i++)
1664
0
    if (!G_TYPE_IS_VALUE (param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE))
1665
0
      {
1666
0
  g_critical (G_STRLOC ": parameter %d of type '%s' for signal \"%s::%s\" is not a value type",
1667
0
        i + 1, type_debug_name (param_types[i]), type_debug_name (itype), name);
1668
0
  g_free (signal_name_copy);
1669
0
  SIGNAL_UNLOCK ();
1670
0
  return 0;
1671
0
      }
1672
0
  if (return_type != G_TYPE_NONE && !G_TYPE_IS_VALUE (return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE))
1673
0
    {
1674
0
      g_critical (G_STRLOC ": return value of type '%s' for signal \"%s::%s\" is not a value type",
1675
0
      type_debug_name (return_type), type_debug_name (itype), name);
1676
0
      g_free (signal_name_copy);
1677
0
      SIGNAL_UNLOCK ();
1678
0
      return 0;
1679
0
    }
1680
  
1681
  /* setup permanent portion of signal node */
1682
0
  if (!node)
1683
0
    {
1684
0
      SignalKey key;
1685
      
1686
0
      signal_id = g_n_signal_nodes++;
1687
0
      node = g_new (SignalNode, 1);
1688
0
      node->signal_id = signal_id;
1689
0
      g_signal_nodes = g_renew (SignalNode*, g_signal_nodes, g_n_signal_nodes);
1690
0
      g_signal_nodes[signal_id] = node;
1691
0
      node->itype = itype;
1692
0
      key.itype = itype;
1693
0
      key.signal_id = signal_id;
1694
0
      node->name = g_intern_string (name);
1695
0
      key.quark = g_quark_from_string (name);
1696
0
      g_signal_key_bsa = g_bsearch_array_insert (g_signal_key_bsa, &g_signal_key_bconfig, &key);
1697
1698
0
      TRACE (GOBJECT_SIGNAL_NEW (signal_id, name, (uintmax_t) itype));
1699
0
    }
1700
0
  node->destroyed = FALSE;
1701
1702
  /* setup reinitializable portion */
1703
0
  node->single_va_closure_is_valid = FALSE;
1704
0
  node->flags = signal_flags & G_SIGNAL_FLAGS_MASK;
1705
0
  node->n_params = n_params;
1706
0
  node->param_types = g_memdup2 (param_types, sizeof (GType) * n_params);
1707
0
  node->return_type = return_type;
1708
0
  node->class_closure_bsa = NULL;
1709
0
  if (accumulator)
1710
0
    {
1711
0
      node->accumulator = g_new (SignalAccumulator, 1);
1712
0
      node->accumulator->func = accumulator;
1713
0
      node->accumulator->data = accu_data;
1714
0
    }
1715
0
  else
1716
0
    node->accumulator = NULL;
1717
1718
0
  builtin_c_marshaller = NULL;
1719
0
  builtin_va_marshaller = NULL;
1720
1721
  /* Pick up built-in va marshallers for standard types, and
1722
     instead of generic marshaller if no marshaller specified */
1723
0
  if (n_params == 0 && return_type == G_TYPE_NONE)
1724
0
    {
1725
0
      builtin_c_marshaller = g_cclosure_marshal_VOID__VOID;
1726
0
      builtin_va_marshaller = g_cclosure_marshal_VOID__VOIDv;
1727
0
    }
1728
0
  else if (n_params == 1 && return_type == G_TYPE_NONE)
1729
0
    {
1730
0
#define ADD_CHECK(__type__) \
1731
0
      else if (g_type_is_a (param_types[0] & ~G_SIGNAL_TYPE_STATIC_SCOPE, G_TYPE_ ##__type__))         \
1732
0
  {                                                                \
1733
0
    builtin_c_marshaller = g_cclosure_marshal_VOID__ ## __type__;  \
1734
0
    builtin_va_marshaller = g_cclosure_marshal_VOID__ ## __type__ ##v;     \
1735
0
  }
1736
1737
0
      if (0) {}
1738
0
      ADD_CHECK (BOOLEAN)
1739
0
      ADD_CHECK (CHAR)
1740
0
      ADD_CHECK (UCHAR)
1741
0
      ADD_CHECK (INT)
1742
0
      ADD_CHECK (UINT)
1743
0
      ADD_CHECK (LONG)
1744
0
      ADD_CHECK (ULONG)
1745
0
      ADD_CHECK (ENUM)
1746
0
      ADD_CHECK (FLAGS)
1747
0
      ADD_CHECK (FLOAT)
1748
0
      ADD_CHECK (DOUBLE)
1749
0
      ADD_CHECK (STRING)
1750
0
      ADD_CHECK (PARAM)
1751
0
      ADD_CHECK (BOXED)
1752
0
      ADD_CHECK (POINTER)
1753
0
      ADD_CHECK (OBJECT)
1754
0
      ADD_CHECK (VARIANT)
1755
0
    }
1756
1757
0
  if (c_marshaller == NULL)
1758
0
    {
1759
0
      if (builtin_c_marshaller)
1760
0
        {
1761
0
    c_marshaller = builtin_c_marshaller;
1762
0
          va_marshaller = builtin_va_marshaller;
1763
0
        }
1764
0
      else
1765
0
  {
1766
0
    c_marshaller = g_cclosure_marshal_generic;
1767
0
    va_marshaller = g_cclosure_marshal_generic_va;
1768
0
  }
1769
0
    }
1770
0
  else
1771
0
    va_marshaller = NULL;
1772
1773
0
  node->c_marshaller = c_marshaller;
1774
0
  node->va_marshaller = va_marshaller;
1775
0
  node->emission_hooks = NULL;
1776
0
  if (class_closure)
1777
0
    signal_add_class_closure (node, 0, class_closure);
1778
1779
0
  SIGNAL_UNLOCK ();
1780
1781
0
  g_free (signal_name_copy);
1782
1783
0
  return signal_id;
1784
0
}
1785
1786
/**
1787
 * g_signal_set_va_marshaller:
1788
 * @signal_id: the signal id
1789
 * @instance_type: the instance type on which to set the marshaller.
1790
 * @va_marshaller: the marshaller to set.
1791
 *
1792
 * Change the #GSignalCVaMarshaller used for a given signal.  This is a
1793
 * specialised form of the marshaller that can often be used for the
1794
 * common case of a single connected signal handler and avoids the
1795
 * overhead of #GValue.  Its use is optional.
1796
 *
1797
 * Since: 2.32
1798
 */
1799
void
1800
g_signal_set_va_marshaller (guint              signal_id,
1801
          GType              instance_type,
1802
          GSignalCVaMarshaller va_marshaller)
1803
0
{
1804
0
  SignalNode *node;
1805
  
1806
0
  g_return_if_fail (signal_id > 0);
1807
0
  g_return_if_fail (va_marshaller != NULL);
1808
  
1809
0
  SIGNAL_LOCK ();
1810
0
  node = LOOKUP_SIGNAL_NODE (signal_id);
1811
0
  if (node)
1812
0
    {
1813
0
      node->va_marshaller = va_marshaller;
1814
0
      if (node->class_closure_bsa)
1815
0
  {
1816
0
    ClassClosure *cc = g_bsearch_array_get_nth (node->class_closure_bsa, &g_class_closure_bconfig, 0);
1817
0
    if (cc->closure->marshal == node->c_marshaller)
1818
0
      _g_closure_set_va_marshal (cc->closure, va_marshaller);
1819
0
  }
1820
1821
0
      node->single_va_closure_is_valid = FALSE;
1822
0
    }
1823
1824
0
  SIGNAL_UNLOCK ();
1825
0
}
1826
1827
1828
/**
1829
 * g_signal_new_valist:
1830
 * @signal_name: the name for the signal
1831
 * @itype: the type this signal pertains to. It will also pertain to
1832
 *  types which are derived from this type.
1833
 * @signal_flags: a combination of #GSignalFlags specifying detail of when
1834
 *  the default handler is to be invoked. You should at least specify
1835
 *  %G_SIGNAL_RUN_FIRST or %G_SIGNAL_RUN_LAST.
1836
 * @class_closure: (nullable): The closure to invoke on signal emission; may be %NULL.
1837
 * @accumulator: (nullable) (scope forever): the accumulator for this signal; may be %NULL.
1838
 * @accu_data: (nullable) (closure accumulator): user data for the @accumulator.
1839
 * @c_marshaller: (nullable): the function to translate arrays of parameter
1840
 *  values to signal emissions into C language callback invocations or %NULL.
1841
 * @return_type: the type of return value, or %G_TYPE_NONE for a signal
1842
 *  without a return value.
1843
 * @n_params: the number of parameter types in @args.
1844
 * @args: va_list of #GType, one for each parameter.
1845
 *
1846
 * Creates a new signal. (This is usually done in the class initializer.)
1847
 *
1848
 * See g_signal_new() for details on allowed signal names.
1849
 *
1850
 * If c_marshaller is %NULL, g_cclosure_marshal_generic() will be used as
1851
 * the marshaller for this signal.
1852
 *
1853
 * Returns: the signal id
1854
 */
1855
guint
1856
g_signal_new_valist (const gchar       *signal_name,
1857
                     GType              itype,
1858
                     GSignalFlags       signal_flags,
1859
                     GClosure          *class_closure,
1860
                     GSignalAccumulator accumulator,
1861
                     gpointer           accu_data,
1862
                     GSignalCMarshaller c_marshaller,
1863
                     GType              return_type,
1864
                     guint              n_params,
1865
                     va_list            args)
1866
0
{
1867
  /* Somewhat arbitrarily reserve 200 bytes. That should cover the majority
1868
   * of cases where n_params is small and still be small enough for what we
1869
   * want to put on the stack. */
1870
0
  GType param_types_stack[200 / sizeof (GType)];
1871
0
  GType *param_types_heap = NULL;
1872
0
  GType *param_types;
1873
0
  guint i;
1874
0
  guint signal_id;
1875
1876
0
  param_types = param_types_stack;
1877
0
  if (n_params > 0)
1878
0
    {
1879
0
      if (G_UNLIKELY (n_params > G_N_ELEMENTS (param_types_stack)))
1880
0
        {
1881
0
          param_types_heap = g_new (GType, n_params);
1882
0
          param_types = param_types_heap;
1883
0
        }
1884
1885
0
      for (i = 0; i < n_params; i++)
1886
0
        param_types[i] = va_arg (args, GType);
1887
0
    }
1888
1889
0
  signal_id = g_signal_newv (signal_name, itype, signal_flags,
1890
0
                             class_closure, accumulator, accu_data, c_marshaller,
1891
0
                             return_type, n_params, param_types);
1892
0
  g_free (param_types_heap);
1893
1894
0
  return signal_id;
1895
0
}
1896
1897
static void
1898
signal_destroy_R (SignalNode *signal_node)
1899
0
{
1900
0
  SignalNode node = *signal_node;
1901
1902
0
  signal_node->destroyed = TRUE;
1903
  
1904
  /* reentrancy caution, zero out real contents first */
1905
0
  signal_node->single_va_closure_is_valid = FALSE;
1906
0
  signal_node->n_params = 0;
1907
0
  signal_node->param_types = NULL;
1908
0
  signal_node->return_type = 0;
1909
0
  signal_node->class_closure_bsa = NULL;
1910
0
  signal_node->accumulator = NULL;
1911
0
  signal_node->c_marshaller = NULL;
1912
0
  signal_node->va_marshaller = NULL;
1913
0
  signal_node->emission_hooks = NULL;
1914
  
1915
0
#ifdef  G_ENABLE_DEBUG
1916
  /* check current emissions */
1917
0
  {
1918
0
    Emission *emission;
1919
    
1920
0
    for (emission = g_emissions; emission; emission = emission->next)
1921
0
      if (emission->ihint.signal_id == node.signal_id)
1922
0
        g_critical (G_STRLOC ": signal \"%s\" being destroyed is currently in emission (instance '%p')",
1923
0
                    node.name, emission->instance);
1924
0
  }
1925
0
#endif
1926
  
1927
  /* free contents that need to
1928
   */
1929
0
  SIGNAL_UNLOCK ();
1930
0
  g_free (node.param_types);
1931
0
  if (node.class_closure_bsa)
1932
0
    {
1933
0
      guint i;
1934
1935
0
      for (i = 0; i < node.class_closure_bsa->n_nodes; i++)
1936
0
  {
1937
0
    ClassClosure *cc = g_bsearch_array_get_nth (node.class_closure_bsa, &g_class_closure_bconfig, i);
1938
1939
0
    g_closure_unref (cc->closure);
1940
0
  }
1941
0
      g_bsearch_array_free (node.class_closure_bsa, &g_class_closure_bconfig);
1942
0
    }
1943
0
  g_free (node.accumulator);
1944
0
  if (node.emission_hooks)
1945
0
    {
1946
0
      g_hook_list_clear (node.emission_hooks);
1947
0
      g_free (node.emission_hooks);
1948
0
    }
1949
0
  SIGNAL_LOCK ();
1950
0
}
1951
1952
/**
1953
 * g_signal_override_class_closure:
1954
 * @signal_id: the signal id
1955
 * @instance_type: the instance type on which to override the class closure
1956
 *  for the signal.
1957
 * @class_closure: the closure.
1958
 *
1959
 * Overrides the class closure (i.e. the default handler) for the given signal
1960
 * for emissions on instances of @instance_type. @instance_type must be derived
1961
 * from the type to which the signal belongs.
1962
 *
1963
 * See g_signal_chain_from_overridden() and
1964
 * g_signal_chain_from_overridden_handler() for how to chain up to the
1965
 * parent class closure from inside the overridden one.
1966
 */
1967
void
1968
g_signal_override_class_closure (guint     signal_id,
1969
         GType     instance_type,
1970
         GClosure *class_closure)
1971
0
{
1972
0
  SignalNode *node;
1973
  
1974
0
  g_return_if_fail (signal_id > 0);
1975
0
  g_return_if_fail (class_closure != NULL);
1976
  
1977
0
  SIGNAL_LOCK ();
1978
0
  node = LOOKUP_SIGNAL_NODE (signal_id);
1979
0
  node_check_deprecated (node);
1980
0
  if (!g_type_is_a (instance_type, node->itype))
1981
0
    g_critical ("%s: type '%s' cannot be overridden for signal id '%u'", G_STRLOC, type_debug_name (instance_type), signal_id);
1982
0
  else
1983
0
    {
1984
0
      ClassClosure *cc = signal_find_class_closure (node, instance_type);
1985
      
1986
0
      if (cc && cc->instance_type == instance_type)
1987
0
  g_critical ("%s: type '%s' is already overridden for signal id '%u'", G_STRLOC, type_debug_name (instance_type), signal_id);
1988
0
      else
1989
0
  signal_add_class_closure (node, instance_type, class_closure);
1990
0
    }
1991
0
  SIGNAL_UNLOCK ();
1992
0
}
1993
1994
/**
1995
 * g_signal_override_class_handler:
1996
 * @signal_name: the name for the signal
1997
 * @instance_type: the instance type on which to override the class handler
1998
 *  for the signal.
1999
 * @class_handler: (scope forever): the handler.
2000
 *
2001
 * Overrides the class closure (i.e. the default handler) for the
2002
 * given signal for emissions on instances of @instance_type with
2003
 * callback @class_handler. @instance_type must be derived from the
2004
 * type to which the signal belongs.
2005
 *
2006
 * See g_signal_chain_from_overridden() and
2007
 * g_signal_chain_from_overridden_handler() for how to chain up to the
2008
 * parent class closure from inside the overridden one.
2009
 *
2010
 * Since: 2.18
2011
 */
2012
void
2013
g_signal_override_class_handler (const gchar *signal_name,
2014
         GType        instance_type,
2015
         GCallback    class_handler)
2016
0
{
2017
0
  guint signal_id;
2018
2019
0
  g_return_if_fail (signal_name != NULL);
2020
0
  g_return_if_fail (instance_type != G_TYPE_NONE);
2021
0
  g_return_if_fail (class_handler != NULL);
2022
2023
0
  signal_id = g_signal_lookup (signal_name, instance_type);
2024
2025
0
  if (signal_id)
2026
0
    g_signal_override_class_closure (signal_id, instance_type,
2027
0
                                     g_cclosure_new (class_handler, NULL, NULL));
2028
0
  else
2029
0
    g_critical ("%s: signal name '%s' is invalid for type id '%"G_GUINTPTR_FORMAT"'",
2030
0
                G_STRLOC, signal_name, (guintptr) instance_type);
2031
2032
0
}
2033
2034
/**
2035
 * g_signal_chain_from_overridden:
2036
 * @instance_and_params: (array): the argument list of the signal emission.
2037
 *  The first element in the array is a #GValue for the instance the signal
2038
 *  is being emitted on. The rest are any arguments to be passed to the signal.
2039
 * @return_value: Location for the return value.
2040
 *
2041
 * Calls the original class closure of a signal. This function should only
2042
 * be called from an overridden class closure; see
2043
 * g_signal_override_class_closure() and
2044
 * g_signal_override_class_handler().
2045
 */
2046
void
2047
g_signal_chain_from_overridden (const GValue *instance_and_params,
2048
        GValue       *return_value)
2049
0
{
2050
0
  GType chain_type = 0, restore_type = 0;
2051
0
  Emission *emission = NULL;
2052
0
  GClosure *closure = NULL;
2053
0
  guint n_params = 0;
2054
0
  gpointer instance;
2055
  
2056
0
  g_return_if_fail (instance_and_params != NULL);
2057
0
  instance = g_value_peek_pointer (instance_and_params);
2058
0
  g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance));
2059
  
2060
0
  SIGNAL_LOCK ();
2061
0
  emission = emission_find_innermost (instance);
2062
0
  if (emission)
2063
0
    {
2064
0
      SignalNode *node = LOOKUP_SIGNAL_NODE (emission->ihint.signal_id);
2065
      
2066
0
      g_assert (node != NULL);  /* paranoid */
2067
      
2068
      /* we should probably do the same parameter checks as g_signal_emit() here.
2069
       */
2070
0
      if (emission->chain_type != G_TYPE_NONE)
2071
0
  {
2072
0
    ClassClosure *cc = signal_find_class_closure (node, emission->chain_type);
2073
    
2074
0
    g_assert (cc != NULL);  /* closure currently in call stack */
2075
2076
0
    n_params = node->n_params;
2077
0
    restore_type = cc->instance_type;
2078
0
    cc = signal_find_class_closure (node, g_type_parent (cc->instance_type));
2079
0
    if (cc && cc->instance_type != restore_type)
2080
0
      {
2081
0
        closure = cc->closure;
2082
0
        chain_type = cc->instance_type;
2083
0
      }
2084
0
  }
2085
0
      else
2086
0
  g_critical ("%s: signal id '%u' cannot be chained from current emission stage for instance '%p'", G_STRLOC, node->signal_id, instance);
2087
0
    }
2088
0
  else
2089
0
    g_critical ("%s: no signal is currently being emitted for instance '%p'", G_STRLOC, instance);
2090
2091
0
  if (closure)
2092
0
    {
2093
0
      emission->chain_type = chain_type;
2094
0
      SIGNAL_UNLOCK ();
2095
0
      g_closure_invoke (closure,
2096
0
      return_value,
2097
0
      n_params + 1,
2098
0
      instance_and_params,
2099
0
      &emission->ihint);
2100
0
      SIGNAL_LOCK ();
2101
0
      emission->chain_type = restore_type;
2102
0
    }
2103
0
  SIGNAL_UNLOCK ();
2104
0
}
2105
2106
/**
2107
 * g_signal_chain_from_overridden_handler: (skip)
2108
 * @instance: (type GObject.TypeInstance): the instance the signal is being
2109
 *    emitted on.
2110
 * @...: parameters to be passed to the parent class closure, followed by a
2111
 *  location for the return value. If the return type of the signal
2112
 *  is %G_TYPE_NONE, the return value location can be omitted.
2113
 *
2114
 * Calls the original class closure of a signal. This function should
2115
 * only be called from an overridden class closure; see
2116
 * g_signal_override_class_closure() and
2117
 * g_signal_override_class_handler().
2118
 *
2119
 * Since: 2.18
2120
 */
2121
void
2122
g_signal_chain_from_overridden_handler (gpointer instance,
2123
                                        ...)
2124
0
{
2125
0
  GType chain_type = 0, restore_type = 0;
2126
0
  Emission *emission = NULL;
2127
0
  GClosure *closure = NULL;
2128
0
  SignalNode *node = NULL;
2129
0
  guint n_params = 0;
2130
2131
0
  g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance));
2132
2133
0
  SIGNAL_LOCK ();
2134
0
  emission = emission_find_innermost (instance);
2135
0
  if (emission)
2136
0
    {
2137
0
      node = LOOKUP_SIGNAL_NODE (emission->ihint.signal_id);
2138
2139
0
      g_assert (node != NULL);  /* paranoid */
2140
2141
      /* we should probably do the same parameter checks as g_signal_emit() here.
2142
       */
2143
0
      if (emission->chain_type != G_TYPE_NONE)
2144
0
  {
2145
0
    ClassClosure *cc = signal_find_class_closure (node, emission->chain_type);
2146
2147
0
    g_assert (cc != NULL);  /* closure currently in call stack */
2148
2149
0
    n_params = node->n_params;
2150
0
    restore_type = cc->instance_type;
2151
0
    cc = signal_find_class_closure (node, g_type_parent (cc->instance_type));
2152
0
    if (cc && cc->instance_type != restore_type)
2153
0
      {
2154
0
        closure = cc->closure;
2155
0
        chain_type = cc->instance_type;
2156
0
      }
2157
0
  }
2158
0
      else
2159
0
  g_critical ("%s: signal id '%u' cannot be chained from current emission stage for instance '%p'", G_STRLOC, node->signal_id, instance);
2160
0
    }
2161
0
  else
2162
0
    g_critical ("%s: no signal is currently being emitted for instance '%p'", G_STRLOC, instance);
2163
2164
0
  if (closure)
2165
0
    {
2166
0
      GValue *instance_and_params;
2167
0
      GType signal_return_type;
2168
0
      GValue *param_values;
2169
0
      va_list var_args;
2170
0
      guint i;
2171
2172
0
      va_start (var_args, instance);
2173
2174
0
      signal_return_type = node->return_type;
2175
0
      instance_and_params = g_newa0 (GValue, n_params + 1);
2176
0
      param_values = instance_and_params + 1;
2177
2178
0
      for (i = 0; i < node->n_params; i++)
2179
0
        {
2180
0
          gchar *error;
2181
0
          GType ptype = node->param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE;
2182
0
          gboolean static_scope = node->param_types[i] & G_SIGNAL_TYPE_STATIC_SCOPE;
2183
2184
0
          SIGNAL_UNLOCK ();
2185
0
          G_VALUE_COLLECT_INIT (param_values + i, ptype,
2186
0
        var_args,
2187
0
        static_scope ? G_VALUE_NOCOPY_CONTENTS : 0,
2188
0
        &error);
2189
0
          if (error)
2190
0
            {
2191
0
              g_critical ("%s: %s", G_STRLOC, error);
2192
0
              g_free (error);
2193
2194
              /* we purposely leak the value here, it might not be
2195
               * in a correct state if an error condition occurred
2196
               */
2197
0
              while (i--)
2198
0
                g_value_unset (param_values + i);
2199
2200
0
              va_end (var_args);
2201
0
              return;
2202
0
            }
2203
0
          SIGNAL_LOCK ();
2204
0
        }
2205
2206
0
      SIGNAL_UNLOCK ();
2207
0
      g_value_init_from_instance (instance_and_params, instance);
2208
0
      SIGNAL_LOCK ();
2209
2210
0
      emission->chain_type = chain_type;
2211
0
      SIGNAL_UNLOCK ();
2212
2213
0
      if (signal_return_type == G_TYPE_NONE)
2214
0
        {
2215
0
          g_closure_invoke (closure,
2216
0
                            NULL,
2217
0
                            n_params + 1,
2218
0
                            instance_and_params,
2219
0
                            &emission->ihint);
2220
0
        }
2221
0
      else
2222
0
        {
2223
0
          GValue return_value = G_VALUE_INIT;
2224
0
          gchar *error = NULL;
2225
0
          GType rtype = signal_return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE;
2226
0
          gboolean static_scope = signal_return_type & G_SIGNAL_TYPE_STATIC_SCOPE;
2227
2228
0
          g_value_init (&return_value, rtype);
2229
2230
0
          g_closure_invoke (closure,
2231
0
                            &return_value,
2232
0
                            n_params + 1,
2233
0
                            instance_and_params,
2234
0
                            &emission->ihint);
2235
2236
0
          G_VALUE_LCOPY (&return_value,
2237
0
                         var_args,
2238
0
                         static_scope ? G_VALUE_NOCOPY_CONTENTS : 0,
2239
0
                         &error);
2240
0
          if (!error)
2241
0
            {
2242
0
              g_value_unset (&return_value);
2243
0
            }
2244
0
          else
2245
0
            {
2246
0
              g_critical ("%s: %s", G_STRLOC, error);
2247
0
              g_free (error);
2248
2249
              /* we purposely leak the value here, it might not be
2250
               * in a correct state if an error condition occurred
2251
               */
2252
0
            }
2253
0
        }
2254
2255
0
      for (i = 0; i < n_params; i++)
2256
0
        g_value_unset (param_values + i);
2257
0
      g_value_unset (instance_and_params);
2258
2259
0
      va_end (var_args);
2260
2261
0
      SIGNAL_LOCK ();
2262
0
      emission->chain_type = restore_type;
2263
0
    }
2264
0
  SIGNAL_UNLOCK ();
2265
0
}
2266
2267
/**
2268
 * g_signal_get_invocation_hint:
2269
 * @instance: (type GObject.Object): the instance to query
2270
 *
2271
 * Returns the invocation hint of the innermost signal emission of instance.
2272
 *
2273
 * Returns: (transfer none) (nullable): the invocation hint of the innermost
2274
 *     signal emission, or %NULL if not found.
2275
 */
2276
GSignalInvocationHint*
2277
g_signal_get_invocation_hint (gpointer instance)
2278
0
{
2279
0
  Emission *emission = NULL;
2280
  
2281
0
  g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), NULL);
2282
2283
0
  SIGNAL_LOCK ();
2284
0
  emission = emission_find_innermost (instance);
2285
0
  SIGNAL_UNLOCK ();
2286
  
2287
0
  return emission ? &emission->ihint : NULL;
2288
0
}
2289
2290
/**
2291
 * g_signal_connect_closure_by_id:
2292
 * @instance: (type GObject.Object): the instance to connect to.
2293
 * @signal_id: the id of the signal.
2294
 * @detail: the detail.
2295
 * @closure: (not nullable): the closure to connect.
2296
 * @after: whether the handler should be called before or after the
2297
 *  default handler of the signal.
2298
 *
2299
 * Connects a closure to a signal for a particular object.
2300
 *
2301
 * If @closure is a floating reference (see g_closure_sink()), this function
2302
 * takes ownership of @closure.
2303
 *
2304
 * This function cannot fail. If the given signal name doesn’t exist,
2305
 * a critical warning is emitted. No validation is performed on the
2306
 * ‘detail’ string when specified in @detailed_signal, other than a
2307
 * non-empty check.
2308
 *
2309
 * Refer to the [signals documentation](signals.html) for more
2310
 * details.
2311
 *
2312
 * Returns: the handler ID (always greater than 0)
2313
 */
2314
gulong
2315
g_signal_connect_closure_by_id (gpointer  instance,
2316
        guint     signal_id,
2317
        GQuark    detail,
2318
        GClosure *closure,
2319
        gboolean  after)
2320
0
{
2321
0
  SignalNode *node;
2322
0
  gulong handler_seq_no = 0;
2323
  
2324
0
  g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), 0);
2325
0
  g_return_val_if_fail (signal_id > 0, 0);
2326
0
  g_return_val_if_fail (closure != NULL, 0);
2327
  
2328
0
  SIGNAL_LOCK ();
2329
0
  node = LOOKUP_SIGNAL_NODE (signal_id);
2330
0
  if (node)
2331
0
    {
2332
0
      if (detail && !(node->flags & G_SIGNAL_DETAILED))
2333
0
  g_critical ("%s: signal id '%u' does not support detail (%u)", G_STRLOC, signal_id, detail);
2334
0
      else if (!g_type_is_a (G_TYPE_FROM_INSTANCE (instance), node->itype))
2335
0
  g_critical ("%s: signal id '%u' is invalid for instance '%p'", G_STRLOC, signal_id, instance);
2336
0
      else
2337
0
  {
2338
0
    Handler *handler = handler_new (signal_id, instance, after);
2339
2340
0
          if (G_TYPE_IS_OBJECT (node->itype))
2341
0
            _g_object_set_has_signal_handler ((GObject *) instance, signal_id);
2342
2343
0
          handler_seq_no = handler->sequential_number;
2344
0
    handler->detail = detail;
2345
0
    handler->closure = g_closure_ref (closure);
2346
0
    g_closure_sink (closure);
2347
0
    add_invalid_closure_notify (handler, instance);
2348
0
    handler_insert (signal_id, instance, handler);
2349
0
    if (node->c_marshaller && G_CLOSURE_NEEDS_MARSHAL (closure))
2350
0
      {
2351
0
        g_closure_set_marshal (closure, node->c_marshaller);
2352
0
        if (node->va_marshaller)
2353
0
    _g_closure_set_va_marshal (closure, node->va_marshaller);
2354
0
      }
2355
0
  }
2356
0
    }
2357
0
  else
2358
0
    g_critical ("%s: signal id '%u' is invalid for instance '%p'", G_STRLOC, signal_id, instance);
2359
0
  SIGNAL_UNLOCK ();
2360
  
2361
0
  return handler_seq_no;
2362
0
}
2363
2364
/**
2365
 * g_signal_connect_closure:
2366
 * @instance: (type GObject.Object): the instance to connect to.
2367
 * @detailed_signal: a string of the form "signal-name::detail".
2368
 * @closure: (not nullable): the closure to connect.
2369
 * @after: whether the handler should be called before or after the
2370
 *  default handler of the signal.
2371
 *
2372
 * Connects a closure to a signal for a particular object.
2373
 *
2374
 * If @closure is a floating reference (see g_closure_sink()), this function
2375
 * takes ownership of @closure.
2376
 *
2377
 * This function cannot fail. If the given signal name doesn’t exist,
2378
 * a critical warning is emitted. No validation is performed on the
2379
 * ‘detail’ string when specified in @detailed_signal, other than a
2380
 * non-empty check.
2381
 *
2382
 * Refer to the [signals documentation](signals.html) for more
2383
 * details.
2384
 *
2385
 * Returns: the handler ID (always greater than 0)
2386
 */
2387
gulong
2388
g_signal_connect_closure (gpointer     instance,
2389
        const gchar *detailed_signal,
2390
        GClosure    *closure,
2391
        gboolean     after)
2392
0
{
2393
0
  guint signal_id;
2394
0
  gulong handler_seq_no = 0;
2395
0
  GQuark detail = 0;
2396
0
  GType itype;
2397
2398
0
  g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), 0);
2399
0
  g_return_val_if_fail (detailed_signal != NULL, 0);
2400
0
  g_return_val_if_fail (closure != NULL, 0);
2401
2402
0
  SIGNAL_LOCK ();
2403
0
  itype = G_TYPE_FROM_INSTANCE (instance);
2404
0
  signal_id = signal_parse_name (detailed_signal, itype, &detail, TRUE);
2405
0
  if (signal_id)
2406
0
    {
2407
0
      SignalNode *node = LOOKUP_SIGNAL_NODE (signal_id);
2408
2409
0
      if (detail && !(node->flags & G_SIGNAL_DETAILED))
2410
0
  g_critical ("%s: signal '%s' does not support details", G_STRLOC, detailed_signal);
2411
0
      else if (!g_type_is_a (itype, node->itype))
2412
0
        g_critical ("%s: signal '%s' is invalid for instance '%p' of type '%s'",
2413
0
                    G_STRLOC, detailed_signal, instance, g_type_name (itype));
2414
0
      else
2415
0
  {
2416
0
    Handler *handler = handler_new (signal_id, instance, after);
2417
2418
0
          if (G_TYPE_IS_OBJECT (node->itype))
2419
0
            _g_object_set_has_signal_handler ((GObject *) instance, signal_id);
2420
2421
0
          handler_seq_no = handler->sequential_number;
2422
0
    handler->detail = detail;
2423
0
    handler->closure = g_closure_ref (closure);
2424
0
    g_closure_sink (closure);
2425
0
    add_invalid_closure_notify (handler, instance);
2426
0
    handler_insert (signal_id, instance, handler);
2427
0
    if (node->c_marshaller && G_CLOSURE_NEEDS_MARSHAL (handler->closure))
2428
0
      {
2429
0
        g_closure_set_marshal (handler->closure, node->c_marshaller);
2430
0
        if (node->va_marshaller)
2431
0
    _g_closure_set_va_marshal (handler->closure, node->va_marshaller);
2432
0
      }
2433
0
  }
2434
0
    }
2435
0
  else
2436
0
    g_critical ("%s: signal '%s' is invalid for instance '%p' of type '%s'",
2437
0
                G_STRLOC, detailed_signal, instance, g_type_name (itype));
2438
0
  SIGNAL_UNLOCK ();
2439
2440
0
  return handler_seq_no;
2441
0
}
2442
2443
static void
2444
node_check_deprecated (const SignalNode *node)
2445
0
{
2446
0
  static const gchar * g_enable_diagnostic = NULL;
2447
2448
0
  if (G_UNLIKELY (!g_enable_diagnostic))
2449
0
    {
2450
0
      g_enable_diagnostic = g_getenv ("G_ENABLE_DIAGNOSTIC");
2451
0
      if (!g_enable_diagnostic)
2452
0
        g_enable_diagnostic = "0";
2453
0
    }
2454
2455
0
  if (g_enable_diagnostic[0] == '1')
2456
0
    {
2457
0
      if (node->flags & G_SIGNAL_DEPRECATED)
2458
0
        {
2459
0
          g_warning ("The signal %s::%s is deprecated and shouldn't be used "
2460
0
                     "anymore. It will be removed in a future version.",
2461
0
                     type_debug_name (node->itype), node->name);
2462
0
        }
2463
0
    }
2464
0
}
2465
2466
/**
2467
 * g_signal_connect_data:
2468
 * @instance: (type GObject.Object): the instance to connect to.
2469
 * @detailed_signal: a string of the form "signal-name::detail".
2470
 * @c_handler: (not nullable): the #GCallback to connect.
2471
 * @data: (nullable) (closure c_handler): data to pass to @c_handler calls.
2472
 * @destroy_data: (nullable) (destroy data): a #GClosureNotify for @data.
2473
 * @connect_flags: a combination of #GConnectFlags.
2474
 *
2475
 * Connects a #GCallback function to a signal for a particular object. Similar
2476
 * to g_signal_connect(), but allows to provide a #GClosureNotify for the data
2477
 * which will be called when the signal handler is disconnected and no longer
2478
 * used. Specify @connect_flags if you need `..._after()` or
2479
 * `..._swapped()` variants of this function.
2480
 *
2481
 * This function cannot fail. If the given signal name doesn’t exist,
2482
 * a critical warning is emitted. No validation is performed on the
2483
 * ‘detail’ string when specified in @detailed_signal, other than a
2484
 * non-empty check.
2485
 *
2486
 * Refer to the [signals documentation](signals.html) for more
2487
 * details.
2488
 *
2489
 * Returns: the handler ID (always greater than 0)
2490
 */
2491
gulong
2492
g_signal_connect_data (gpointer       instance,
2493
           const gchar   *detailed_signal,
2494
           GCallback      c_handler,
2495
           gpointer       data,
2496
           GClosureNotify destroy_data,
2497
           GConnectFlags  connect_flags)
2498
0
{
2499
0
  guint signal_id;
2500
0
  gulong handler_seq_no = 0;
2501
0
  GQuark detail = 0;
2502
0
  GType itype;
2503
0
  gboolean swapped, after;
2504
  
2505
0
  g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), 0);
2506
0
  g_return_val_if_fail (detailed_signal != NULL, 0);
2507
0
  g_return_val_if_fail (c_handler != NULL, 0);
2508
2509
0
  swapped = (connect_flags & G_CONNECT_SWAPPED) != FALSE;
2510
0
  after = (connect_flags & G_CONNECT_AFTER) != FALSE;
2511
2512
0
  SIGNAL_LOCK ();
2513
0
  itype = G_TYPE_FROM_INSTANCE (instance);
2514
0
  signal_id = signal_parse_name (detailed_signal, itype, &detail, TRUE);
2515
0
  if (signal_id)
2516
0
    {
2517
0
      SignalNode *node = LOOKUP_SIGNAL_NODE (signal_id);
2518
2519
0
      node_check_deprecated (node);
2520
2521
0
      if (detail && !(node->flags & G_SIGNAL_DETAILED))
2522
0
  g_critical ("%s: signal '%s' does not support details", G_STRLOC, detailed_signal);
2523
0
      else if (!g_type_is_a (itype, node->itype))
2524
0
        g_critical ("%s: signal '%s' is invalid for instance '%p' of type '%s'",
2525
0
                    G_STRLOC, detailed_signal, instance, g_type_name (itype));
2526
0
      else
2527
0
  {
2528
0
    Handler *handler = handler_new (signal_id, instance, after);
2529
2530
0
          if (G_TYPE_IS_OBJECT (node->itype))
2531
0
            _g_object_set_has_signal_handler ((GObject *) instance, signal_id);
2532
2533
0
    handler_seq_no = handler->sequential_number;
2534
0
    handler->detail = detail;
2535
0
    handler->closure = g_closure_ref ((swapped ? g_cclosure_new_swap : g_cclosure_new) (c_handler, data, destroy_data));
2536
0
    g_closure_sink (handler->closure);
2537
0
    handler_insert (signal_id, instance, handler);
2538
0
    if (node->c_marshaller && G_CLOSURE_NEEDS_MARSHAL (handler->closure))
2539
0
      {
2540
0
        g_closure_set_marshal (handler->closure, node->c_marshaller);
2541
0
        if (node->va_marshaller)
2542
0
    _g_closure_set_va_marshal (handler->closure, node->va_marshaller);
2543
0
      }
2544
0
        }
2545
0
    }
2546
0
  else
2547
0
    g_critical ("%s: signal '%s' is invalid for instance '%p' of type '%s'",
2548
0
                G_STRLOC, detailed_signal, instance, g_type_name (itype));
2549
0
  SIGNAL_UNLOCK ();
2550
2551
0
  return handler_seq_no;
2552
0
}
2553
2554
static void
2555
signal_handler_block_unlocked (gpointer instance,
2556
                               gulong   handler_id);
2557
2558
/**
2559
 * g_signal_handler_block:
2560
 * @instance: (type GObject.Object): The instance to block the signal handler of.
2561
 * @handler_id: Handler id of the handler to be blocked.
2562
 *
2563
 * Blocks a handler of an instance so it will not be called during any
2564
 * signal emissions unless it is unblocked again. Thus "blocking" a
2565
 * signal handler means to temporarily deactivate it, a signal handler
2566
 * has to be unblocked exactly the same amount of times it has been
2567
 * blocked before to become active again.
2568
 *
2569
 * The @handler_id has to be a valid signal handler id, connected to a
2570
 * signal of @instance.
2571
 */
2572
void
2573
g_signal_handler_block (gpointer instance,
2574
                        gulong   handler_id)
2575
0
{
2576
0
  g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance));
2577
0
  g_return_if_fail (handler_id > 0);
2578
  
2579
0
  SIGNAL_LOCK ();
2580
0
  signal_handler_block_unlocked (instance, handler_id);
2581
0
  SIGNAL_UNLOCK ();
2582
0
}
2583
2584
static void
2585
signal_handler_block_unlocked (gpointer instance,
2586
                               gulong   handler_id)
2587
0
{
2588
0
  Handler *handler;
2589
2590
0
  handler = handler_lookup (instance, handler_id, NULL, NULL);
2591
0
  if (handler)
2592
0
    {
2593
0
#ifndef G_DISABLE_CHECKS
2594
0
      if (handler->block_count >= HANDLER_MAX_BLOCK_COUNT - 1)
2595
0
        g_error (G_STRLOC ": handler block_count overflow, %s", REPORT_BUG);
2596
0
#endif
2597
0
      handler->block_count += 1;
2598
0
    }
2599
0
  else
2600
0
    g_critical ("%s: instance '%p' has no handler with id '%lu'", G_STRLOC, instance, handler_id);
2601
0
}
2602
2603
static void
2604
signal_handler_unblock_unlocked (gpointer instance,
2605
                                 gulong   handler_id);
2606
2607
/**
2608
 * g_signal_handler_unblock:
2609
 * @instance: (type GObject.Object): The instance to unblock the signal handler of.
2610
 * @handler_id: Handler id of the handler to be unblocked.
2611
 *
2612
 * Undoes the effect of a previous g_signal_handler_block() call.  A
2613
 * blocked handler is skipped during signal emissions and will not be
2614
 * invoked, unblocking it (for exactly the amount of times it has been
2615
 * blocked before) reverts its "blocked" state, so the handler will be
2616
 * recognized by the signal system and is called upon future or
2617
 * currently ongoing signal emissions (since the order in which
2618
 * handlers are called during signal emissions is deterministic,
2619
 * whether the unblocked handler in question is called as part of a
2620
 * currently ongoing emission depends on how far that emission has
2621
 * proceeded yet).
2622
 *
2623
 * The @handler_id has to be a valid id of a signal handler that is
2624
 * connected to a signal of @instance and is currently blocked.
2625
 */
2626
void
2627
g_signal_handler_unblock (gpointer instance,
2628
                          gulong   handler_id)
2629
0
{
2630
0
  g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance));
2631
0
  g_return_if_fail (handler_id > 0);
2632
  
2633
0
  SIGNAL_LOCK ();
2634
0
  signal_handler_unblock_unlocked (instance, handler_id);
2635
0
  SIGNAL_UNLOCK ();
2636
0
}
2637
2638
static void
2639
signal_handler_unblock_unlocked (gpointer instance,
2640
                                 gulong   handler_id)
2641
0
{
2642
0
  Handler *handler;
2643
2644
0
  handler = handler_lookup (instance, handler_id, NULL, NULL);
2645
0
  if (handler)
2646
0
    {
2647
0
      if (handler->block_count)
2648
0
        handler->block_count -= 1;
2649
0
      else
2650
0
        g_critical (G_STRLOC ": handler '%lu' of instance '%p' is not blocked", handler_id, instance);
2651
0
    }
2652
0
  else
2653
0
    g_critical ("%s: instance '%p' has no handler with id '%lu'", G_STRLOC, instance, handler_id);
2654
0
}
2655
2656
static void
2657
signal_handler_disconnect_unlocked (gpointer instance,
2658
                                    gulong   handler_id);
2659
2660
/**
2661
 * g_signal_handler_disconnect:
2662
 * @instance: (type GObject.Object): The instance to remove the signal handler from.
2663
 * @handler_id: Handler id of the handler to be disconnected.
2664
 *
2665
 * Disconnects a handler from an instance so it will not be called during
2666
 * any future or currently ongoing emissions of the signal it has been
2667
 * connected to. The @handler_id becomes invalid and may be reused.
2668
 *
2669
 * The @handler_id has to be a valid signal handler id, connected to a
2670
 * signal of @instance.
2671
 */
2672
void
2673
g_signal_handler_disconnect (gpointer instance,
2674
                             gulong   handler_id)
2675
0
{
2676
0
  g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance));
2677
0
  g_return_if_fail (handler_id > 0);
2678
  
2679
0
  SIGNAL_LOCK ();
2680
0
  signal_handler_disconnect_unlocked (instance, handler_id);
2681
0
  SIGNAL_UNLOCK ();
2682
0
}
2683
2684
static void
2685
signal_handler_disconnect_unlocked (gpointer instance,
2686
                                    gulong   handler_id)
2687
0
{
2688
0
  Handler *handler;
2689
2690
0
  handler = handler_lookup (instance, handler_id, 0, 0);
2691
0
  if (handler)
2692
0
    {
2693
0
      g_hash_table_remove (g_handlers, handler);
2694
0
      handler->sequential_number = 0;
2695
0
      handler->block_count = 1;
2696
0
      remove_invalid_closure_notify (handler, instance);
2697
0
      handler_unref_R (handler->signal_id, instance, handler);
2698
0
    }
2699
0
  else
2700
0
    g_critical ("%s: instance '%p' has no handler with id '%lu'", G_STRLOC, instance, handler_id);
2701
0
}
2702
2703
/**
2704
 * g_signal_handler_is_connected:
2705
 * @instance: (type GObject.Object): The instance where a signal handler is sought.
2706
 * @handler_id: the handler ID.
2707
 *
2708
 * Returns whether @handler_id is the ID of a handler connected to @instance.
2709
 *
2710
 * Returns: whether @handler_id identifies a handler connected to @instance.
2711
 */
2712
gboolean
2713
g_signal_handler_is_connected (gpointer instance,
2714
             gulong   handler_id)
2715
0
{
2716
0
  Handler *handler;
2717
0
  gboolean connected;
2718
2719
0
  g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), FALSE);
2720
2721
0
  SIGNAL_LOCK ();
2722
0
  handler = handler_lookup (instance, handler_id, NULL, NULL);
2723
0
  connected = handler != NULL;
2724
0
  SIGNAL_UNLOCK ();
2725
2726
0
  return connected;
2727
0
}
2728
2729
/**
2730
 * g_signal_handlers_destroy:
2731
 * @instance: (type GObject.Object): The instance whose signal handlers are destroyed
2732
 *
2733
 * Destroy all signal handlers of a type instance. This function is
2734
 * an implementation detail of the #GObject dispose implementation,
2735
 * and should not be used outside of the type system.
2736
 */
2737
void
2738
g_signal_handlers_destroy (gpointer instance)
2739
0
{
2740
0
  GBSearchArray *hlbsa;
2741
  
2742
0
  g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance));
2743
  
2744
0
  SIGNAL_LOCK ();
2745
0
  hlbsa = g_hash_table_lookup (g_handler_list_bsa_ht, instance);
2746
0
  if (hlbsa)
2747
0
    {
2748
0
      guint i;
2749
      
2750
      /* reentrancy caution, delete instance trace first */
2751
0
      g_hash_table_remove (g_handler_list_bsa_ht, instance);
2752
      
2753
0
      for (i = 0; i < hlbsa->n_nodes; i++)
2754
0
        {
2755
0
          HandlerList *hlist = g_bsearch_array_get_nth (hlbsa, &g_signal_hlbsa_bconfig, i);
2756
0
          Handler *handler = hlist->handlers;
2757
    
2758
0
          while (handler)
2759
0
            {
2760
0
              Handler *tmp = handler;
2761
        
2762
0
              handler = tmp->next;
2763
0
              tmp->block_count = 1;
2764
              /* cruel unlink, this works because _all_ handlers vanish */
2765
0
              tmp->next = NULL;
2766
0
              tmp->prev = tmp;
2767
0
              if (tmp->sequential_number)
2768
0
    {
2769
0
                  g_hash_table_remove (g_handlers, tmp);
2770
0
      remove_invalid_closure_notify (tmp, instance);
2771
0
      tmp->sequential_number = 0;
2772
0
      handler_unref_R (0, NULL, tmp);
2773
0
    }
2774
0
            }
2775
0
        }
2776
0
      g_bsearch_array_free (hlbsa, &g_signal_hlbsa_bconfig);
2777
0
    }
2778
0
  SIGNAL_UNLOCK ();
2779
0
}
2780
2781
/**
2782
 * g_signal_handler_find:
2783
 * @instance: (type GObject.Object): The instance owning the signal handler to be found.
2784
 * @mask: Mask indicating which of @signal_id, @detail, @closure, @func
2785
 *  and/or @data the handler has to match.
2786
 * @signal_id: Signal the handler has to be connected to.
2787
 * @detail: Signal detail the handler has to be connected to.
2788
 * @closure: (nullable): The closure the handler will invoke.
2789
 * @func: The C closure callback of the handler (useless for non-C closures).
2790
 * @data: (nullable) (closure closure): The closure data of the handler's closure.
2791
 *
2792
 * Finds the first signal handler that matches certain selection criteria.
2793
 * The criteria mask is passed as an OR-ed combination of #GSignalMatchType
2794
 * flags, and the criteria values are passed as arguments.
2795
 * The match @mask has to be non-0 for successful matches.
2796
 * If no handler was found, 0 is returned.
2797
 *
2798
 * Returns: A valid non-0 signal handler id for a successful match.
2799
 */
2800
gulong
2801
g_signal_handler_find (gpointer         instance,
2802
                       GSignalMatchType mask,
2803
                       guint            signal_id,
2804
           GQuark   detail,
2805
                       GClosure        *closure,
2806
                       gpointer         func,
2807
                       gpointer         data)
2808
0
{
2809
0
  gulong handler_seq_no = 0;
2810
  
2811
0
  g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), 0);
2812
0
  g_return_val_if_fail ((mask & (unsigned) ~G_SIGNAL_MATCH_MASK) == 0, 0);
2813
  
2814
0
  if (mask & G_SIGNAL_MATCH_MASK)
2815
0
    {
2816
0
      HandlerMatch *mlist;
2817
      
2818
0
      SIGNAL_LOCK ();
2819
0
      mlist = handlers_find (instance, mask, signal_id, detail, closure, func, data, TRUE);
2820
0
      if (mlist)
2821
0
  {
2822
0
    handler_seq_no = mlist->handler->sequential_number;
2823
0
    handler_match_free1_R (mlist, instance);
2824
0
  }
2825
0
      SIGNAL_UNLOCK ();
2826
0
    }
2827
  
2828
0
  return handler_seq_no;
2829
0
}
2830
2831
typedef void (*CallbackHandlerFunc) (gpointer instance, gulong handler_seq_no);
2832
2833
static guint
2834
signal_handlers_foreach_matched_unlocked_R (gpointer             instance,
2835
                                            GSignalMatchType     mask,
2836
                                            guint                signal_id,
2837
                                            GQuark               detail,
2838
                                            GClosure            *closure,
2839
                                            gpointer             func,
2840
                                            gpointer             data,
2841
                                            CallbackHandlerFunc  callback)
2842
0
{
2843
0
  HandlerMatch *mlist;
2844
0
  guint n_handlers = 0;
2845
2846
0
  mlist = handlers_find (instance, mask, signal_id, detail, closure, func, data, FALSE);
2847
0
  while (mlist)
2848
0
    {
2849
0
      n_handlers++;
2850
0
      if (mlist->handler->sequential_number)
2851
0
        callback (instance, mlist->handler->sequential_number);
2852
2853
0
      mlist = handler_match_free1_R (mlist, instance);
2854
0
    }
2855
2856
0
  return n_handlers;
2857
0
}
2858
2859
/**
2860
 * g_signal_handlers_block_matched:
2861
 * @instance: (type GObject.Object): The instance to block handlers from.
2862
 * @mask: Mask indicating which of @signal_id, @detail, @closure, @func
2863
 *  and/or @data the handlers have to match.
2864
 * @signal_id: Signal the handlers have to be connected to.
2865
 * @detail: Signal detail the handlers have to be connected to.
2866
 * @closure: (nullable): The closure the handlers will invoke.
2867
 * @func: The C closure callback of the handlers (useless for non-C closures).
2868
 * @data: (nullable) (closure closure): The closure data of the handlers' closures.
2869
 *
2870
 * Blocks all handlers on an instance that match a certain selection criteria.
2871
 *
2872
 * The criteria mask is passed as a combination of #GSignalMatchType flags, and
2873
 * the criteria values are passed as arguments. A handler must match on all
2874
 * flags set in @mask to be blocked (i.e. the match is conjunctive).
2875
 *
2876
 * Passing at least one of the %G_SIGNAL_MATCH_ID, %G_SIGNAL_MATCH_CLOSURE,
2877
 * %G_SIGNAL_MATCH_FUNC
2878
 * or %G_SIGNAL_MATCH_DATA match flags is required for successful matches.
2879
 * If no handlers were found, 0 is returned, the number of blocked handlers
2880
 * otherwise.
2881
 *
2882
 * Support for %G_SIGNAL_MATCH_ID was added in GLib 2.78.
2883
 *
2884
 * Returns: The number of handlers that matched.
2885
 */
2886
guint
2887
g_signal_handlers_block_matched (gpointer         instance,
2888
         GSignalMatchType mask,
2889
         guint            signal_id,
2890
         GQuark           detail,
2891
         GClosure        *closure,
2892
         gpointer         func,
2893
         gpointer         data)
2894
0
{
2895
0
  guint n_handlers = 0;
2896
  
2897
0
  g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), 0);
2898
0
  g_return_val_if_fail ((mask & (unsigned) ~G_SIGNAL_MATCH_MASK) == 0, 0);
2899
  
2900
0
  if (mask & (G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_CLOSURE | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA))
2901
0
    {
2902
0
      SIGNAL_LOCK ();
2903
0
      n_handlers =
2904
0
        signal_handlers_foreach_matched_unlocked_R (instance, mask, signal_id, detail,
2905
0
                                                    closure, func, data,
2906
0
                                                    signal_handler_block_unlocked);
2907
0
      SIGNAL_UNLOCK ();
2908
0
    }
2909
  
2910
0
  return n_handlers;
2911
0
}
2912
2913
/**
2914
 * g_signal_handlers_unblock_matched:
2915
 * @instance: (type GObject.Object): The instance to unblock handlers from.
2916
 * @mask: Mask indicating which of @signal_id, @detail, @closure, @func
2917
 *  and/or @data the handlers have to match.
2918
 * @signal_id: Signal the handlers have to be connected to.
2919
 * @detail: Signal detail the handlers have to be connected to.
2920
 * @closure: (nullable): The closure the handlers will invoke.
2921
 * @func: The C closure callback of the handlers (useless for non-C closures).
2922
 * @data: (nullable) (closure closure): The closure data of the handlers' closures.
2923
 *
2924
 * Unblocks all handlers on an instance that match a certain selection
2925
 * criteria.
2926
 *
2927
 * The criteria mask is passed as a combination of #GSignalMatchType flags, and
2928
 * the criteria values are passed as arguments. A handler must match on all
2929
 * flags set in @mask to be unblocked (i.e. the match is conjunctive).
2930
 *
2931
 * Passing at least one of the %G_SIGNAL_MATCH_ID, %G_SIGNAL_MATCH_CLOSURE,
2932
 * %G_SIGNAL_MATCH_FUNC
2933
 * or %G_SIGNAL_MATCH_DATA match flags is required for successful matches.
2934
 * If no handlers were found, 0 is returned, the number of unblocked handlers
2935
 * otherwise. The match criteria should not apply to any handlers that are
2936
 * not currently blocked.
2937
 *
2938
 * Support for %G_SIGNAL_MATCH_ID was added in GLib 2.78.
2939
 *
2940
 * Returns: The number of handlers that matched.
2941
 */
2942
guint
2943
g_signal_handlers_unblock_matched (gpointer         instance,
2944
           GSignalMatchType mask,
2945
           guint            signal_id,
2946
           GQuark           detail,
2947
           GClosure        *closure,
2948
           gpointer         func,
2949
           gpointer         data)
2950
0
{
2951
0
  guint n_handlers = 0;
2952
  
2953
0
  g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), 0);
2954
0
  g_return_val_if_fail ((mask & (unsigned) ~G_SIGNAL_MATCH_MASK) == 0, 0);
2955
  
2956
0
  if (mask & (G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_CLOSURE | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA))
2957
0
    {
2958
0
      SIGNAL_LOCK ();
2959
0
      n_handlers =
2960
0
        signal_handlers_foreach_matched_unlocked_R (instance, mask, signal_id, detail,
2961
0
                                                    closure, func, data,
2962
0
                                                    signal_handler_unblock_unlocked);
2963
0
      SIGNAL_UNLOCK ();
2964
0
    }
2965
  
2966
0
  return n_handlers;
2967
0
}
2968
2969
/**
2970
 * g_signal_handlers_disconnect_matched:
2971
 * @instance: (type GObject.Object): The instance to remove handlers from.
2972
 * @mask: Mask indicating which of @signal_id, @detail, @closure, @func
2973
 *  and/or @data the handlers have to match.
2974
 * @signal_id: Signal the handlers have to be connected to.
2975
 * @detail: Signal detail the handlers have to be connected to.
2976
 * @closure: (nullable): The closure the handlers will invoke.
2977
 * @func: The C closure callback of the handlers (useless for non-C closures).
2978
 * @data: (nullable) (closure closure): The closure data of the handlers' closures.
2979
 *
2980
 * Disconnects all handlers on an instance that match a certain
2981
 * selection criteria.
2982
 *
2983
 * The criteria mask is passed as a combination of #GSignalMatchType flags, and
2984
 * the criteria values are passed as arguments. A handler must match on all
2985
 * flags set in @mask to be disconnected (i.e. the match is conjunctive).
2986
 *
2987
 * Passing at least one of the %G_SIGNAL_MATCH_ID, %G_SIGNAL_MATCH_CLOSURE,
2988
 * %G_SIGNAL_MATCH_FUNC or
2989
 * %G_SIGNAL_MATCH_DATA match flags is required for successful
2990
 * matches.  If no handlers were found, 0 is returned, the number of
2991
 * disconnected handlers otherwise.
2992
 *
2993
 * Support for %G_SIGNAL_MATCH_ID was added in GLib 2.78.
2994
 *
2995
 * Returns: The number of handlers that matched.
2996
 */
2997
guint
2998
g_signal_handlers_disconnect_matched (gpointer         instance,
2999
              GSignalMatchType mask,
3000
              guint            signal_id,
3001
              GQuark           detail,
3002
              GClosure        *closure,
3003
              gpointer         func,
3004
              gpointer         data)
3005
0
{
3006
0
  guint n_handlers = 0;
3007
  
3008
0
  g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), 0);
3009
0
  g_return_val_if_fail ((mask & (unsigned) ~G_SIGNAL_MATCH_MASK) == 0, 0);
3010
  
3011
0
  if (mask & (G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_CLOSURE | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA))
3012
0
    {
3013
0
      SIGNAL_LOCK ();
3014
0
      n_handlers =
3015
0
        signal_handlers_foreach_matched_unlocked_R (instance, mask, signal_id, detail,
3016
0
                                                    closure, func, data,
3017
0
                                                    signal_handler_disconnect_unlocked);
3018
0
      SIGNAL_UNLOCK ();
3019
0
    }
3020
  
3021
0
  return n_handlers;
3022
0
}
3023
3024
/**
3025
 * g_signal_has_handler_pending:
3026
 * @instance: (type GObject.Object): the object whose signal handlers are sought.
3027
 * @signal_id: the signal id.
3028
 * @detail: the detail.
3029
 * @may_be_blocked: whether blocked handlers should count as match.
3030
 *
3031
 * Returns whether there are any handlers connected to @instance for the
3032
 * given signal id and detail.
3033
 *
3034
 * If @detail is 0 then it will only match handlers that were connected
3035
 * without detail.  If @detail is non-zero then it will match handlers
3036
 * connected both without detail and with the given detail.  This is
3037
 * consistent with how a signal emitted with @detail would be delivered
3038
 * to those handlers.
3039
 *
3040
 * Since 2.46 this also checks for a non-default class closure being
3041
 * installed, as this is basically always what you want.
3042
 *
3043
 * One example of when you might use this is when the arguments to the
3044
 * signal are difficult to compute. A class implementor may opt to not
3045
 * emit the signal if no one is attached anyway, thus saving the cost
3046
 * of building the arguments.
3047
 *
3048
 * Returns: %TRUE if a handler is connected to the signal, %FALSE
3049
 *          otherwise.
3050
 */
3051
gboolean
3052
g_signal_has_handler_pending (gpointer instance,
3053
            guint    signal_id,
3054
            GQuark   detail,
3055
            gboolean may_be_blocked)
3056
0
{
3057
0
  HandlerMatch *mlist;
3058
0
  gboolean has_pending;
3059
0
  SignalNode *node;
3060
  
3061
0
  g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), FALSE);
3062
0
  g_return_val_if_fail (signal_id > 0, FALSE);
3063
  
3064
0
  SIGNAL_LOCK ();
3065
3066
0
  node = LOOKUP_SIGNAL_NODE (signal_id);
3067
0
  if (detail)
3068
0
    {
3069
0
      if (!(node->flags & G_SIGNAL_DETAILED))
3070
0
  {
3071
0
    g_critical ("%s: signal id '%u' does not support detail (%u)", G_STRLOC, signal_id, detail);
3072
0
    SIGNAL_UNLOCK ();
3073
0
    return FALSE;
3074
0
  }
3075
0
    }
3076
0
  mlist = handlers_find (instance,
3077
0
       (G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_DETAIL | (may_be_blocked ? 0 : G_SIGNAL_MATCH_UNBLOCKED)),
3078
0
       signal_id, detail, NULL, NULL, NULL, TRUE);
3079
0
  if (mlist)
3080
0
    {
3081
0
      has_pending = TRUE;
3082
0
      handler_match_free1_R (mlist, instance);
3083
0
    }
3084
0
  else
3085
0
    {
3086
0
      ClassClosure *class_closure = signal_find_class_closure (node, G_TYPE_FROM_INSTANCE (instance));
3087
0
      if (class_closure != NULL && class_closure->instance_type != 0)
3088
0
        has_pending = TRUE;
3089
0
      else
3090
0
        has_pending = FALSE;
3091
0
    }
3092
0
  SIGNAL_UNLOCK ();
3093
3094
0
  return has_pending;
3095
0
}
3096
3097
static void
3098
signal_emitv_unlocked (const GValue *instance_and_params,
3099
                       guint         signal_id,
3100
                       GQuark        detail,
3101
                       GValue       *return_value);
3102
3103
/**
3104
 * g_signal_emitv:
3105
 * @instance_and_params: (array): argument list for the signal emission.
3106
 *  The first element in the array is a #GValue for the instance the signal
3107
 *  is being emitted on. The rest are any arguments to be passed to the signal.
3108
 * @signal_id: the signal id
3109
 * @detail: the detail
3110
 * @return_value: (inout) (optional): Location to
3111
 * store the return value of the signal emission. This must be provided if the
3112
 * specified signal returns a value, but may be ignored otherwise.
3113
 *
3114
 * Emits a signal. Signal emission is done synchronously.
3115
 * The method will only return control after all handlers are called or signal emission was stopped.
3116
 *
3117
 * Note that g_signal_emitv() doesn't change @return_value if no handlers are
3118
 * connected, in contrast to g_signal_emit() and g_signal_emit_valist().
3119
 */
3120
void
3121
g_signal_emitv (const GValue *instance_and_params,
3122
    guint         signal_id,
3123
    GQuark        detail,
3124
    GValue       *return_value)
3125
0
{
3126
0
  SIGNAL_LOCK ();
3127
0
  signal_emitv_unlocked (instance_and_params, signal_id, detail, return_value);
3128
0
  SIGNAL_UNLOCK ();
3129
0
}
3130
3131
static void
3132
signal_emitv_unlocked (const GValue *instance_and_params,
3133
                       guint         signal_id,
3134
                       GQuark        detail,
3135
                       GValue       *return_value)
3136
0
{
3137
0
  gpointer instance;
3138
0
  SignalNode *node;
3139
0
#ifdef G_ENABLE_DEBUG
3140
0
  const GValue *param_values;
3141
0
  guint i;
3142
0
#endif
3143
  
3144
0
  g_return_if_fail (instance_and_params != NULL);
3145
0
  instance = g_value_peek_pointer (instance_and_params);
3146
0
  g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance));
3147
0
  g_return_if_fail (signal_id > 0);
3148
3149
0
#ifdef G_ENABLE_DEBUG
3150
0
  param_values = instance_and_params + 1;
3151
0
#endif
3152
3153
0
  node = LOOKUP_SIGNAL_NODE (signal_id);
3154
0
  if (!node || !g_type_is_a (G_TYPE_FROM_INSTANCE (instance), node->itype))
3155
0
    {
3156
0
      g_critical ("%s: signal id '%u' is invalid for instance '%p'", G_STRLOC, signal_id, instance);
3157
0
      return;
3158
0
    }
3159
0
#ifdef G_ENABLE_DEBUG
3160
0
  if (detail && !(node->flags & G_SIGNAL_DETAILED))
3161
0
    {
3162
0
      g_critical ("%s: signal id '%u' does not support detail (%u)", G_STRLOC, signal_id, detail);
3163
0
      return;
3164
0
    }
3165
0
  for (i = 0; i < node->n_params; i++)
3166
0
    if (!G_TYPE_CHECK_VALUE_TYPE (param_values + i, node->param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE))
3167
0
      {
3168
0
  g_critical ("%s: value for '%s' parameter %u for signal \"%s\" is of type '%s'",
3169
0
        G_STRLOC,
3170
0
        type_debug_name (node->param_types[i]),
3171
0
        i,
3172
0
        node->name,
3173
0
        G_VALUE_TYPE_NAME (param_values + i));
3174
0
  return;
3175
0
      }
3176
0
  if (node->return_type != G_TYPE_NONE)
3177
0
    {
3178
0
      if (!return_value)
3179
0
  {
3180
0
    g_critical ("%s: return value '%s' for signal \"%s\" is (NULL)",
3181
0
          G_STRLOC,
3182
0
          type_debug_name (node->return_type),
3183
0
          node->name);
3184
0
    return;
3185
0
  }
3186
0
      else if (!node->accumulator && !G_TYPE_CHECK_VALUE_TYPE (return_value, node->return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE))
3187
0
  {
3188
0
    g_critical ("%s: return value '%s' for signal \"%s\" is of type '%s'",
3189
0
          G_STRLOC,
3190
0
          type_debug_name (node->return_type),
3191
0
          node->name,
3192
0
          G_VALUE_TYPE_NAME (return_value));
3193
0
    return;
3194
0
  }
3195
0
    }
3196
0
  else
3197
0
    return_value = NULL;
3198
0
#endif  /* G_ENABLE_DEBUG */
3199
3200
  /* optimize NOP emissions */
3201
0
  if (!node->single_va_closure_is_valid)
3202
0
    node_update_single_va_closure (node);
3203
3204
0
  if (node->single_va_closure != NULL &&
3205
0
      (node->single_va_closure == SINGLE_VA_CLOSURE_EMPTY_MAGIC ||
3206
0
       _g_closure_is_void (node->single_va_closure, instance)))
3207
0
    {
3208
0
      HandlerList* hlist;
3209
3210
      /* single_va_closure is only true for GObjects, so fast path if no handler ever connected to the signal */
3211
0
      if (_g_object_has_signal_handler ((GObject *)instance))
3212
0
        hlist = handler_list_lookup (node->signal_id, instance);
3213
0
      else
3214
0
        hlist = NULL;
3215
3216
0
      if (hlist == NULL || hlist->handlers == NULL)
3217
0
  {
3218
    /* nothing to do to emit this signal */
3219
    /* g_printerr ("omitting emission of \"%s\"\n", node->name); */
3220
0
    return;
3221
0
  }
3222
0
    }
3223
3224
  /* Pass a stable node pointer, whose address can't change even if the
3225
   * g_signal_nodes array gets reallocated. */
3226
0
  SignalNode node_copy = *node;
3227
0
  signal_emit_unlocked_R (&node_copy, detail, instance, return_value, instance_and_params);
3228
0
}
3229
3230
static inline gboolean
3231
accumulate (GSignalInvocationHint *ihint,
3232
      GValue                *return_accu,
3233
      GValue            *handler_return,
3234
      SignalAccumulator     *accumulator)
3235
0
{
3236
0
  gboolean continue_emission;
3237
3238
0
  if (!accumulator)
3239
0
    return TRUE;
3240
3241
0
  continue_emission = accumulator->func (ihint, return_accu, handler_return, accumulator->data);
3242
0
  g_value_reset (handler_return);
3243
3244
0
  ihint->run_type &= (unsigned) ~G_SIGNAL_ACCUMULATOR_FIRST_RUN;
3245
3246
0
  return continue_emission;
3247
0
}
3248
3249
static gboolean
3250
signal_emit_valist_unlocked (gpointer instance,
3251
                             guint    signal_id,
3252
                             GQuark   detail,
3253
                             va_list  var_args);
3254
3255
/**
3256
 * g_signal_emit_valist: (skip)
3257
 * @instance: (type GObject.TypeInstance): the instance the signal is being
3258
 *    emitted on.
3259
 * @signal_id: the signal id
3260
 * @detail: the detail
3261
 * @var_args: a list of parameters to be passed to the signal, followed by a
3262
 *  location for the return value. If the return type of the signal
3263
 *  is %G_TYPE_NONE, the return value location can be omitted.
3264
 *
3265
 * Emits a signal. Signal emission is done synchronously.
3266
 * The method will only return control after all handlers are called or signal emission was stopped.
3267
 *
3268
 * Note that g_signal_emit_valist() resets the return value to the default
3269
 * if no handlers are connected, in contrast to g_signal_emitv().
3270
 */
3271
void
3272
g_signal_emit_valist (gpointer instance,
3273
          guint    signal_id,
3274
          GQuark   detail,
3275
          va_list  var_args)
3276
0
{
3277
0
  SIGNAL_LOCK ();
3278
0
  if (signal_emit_valist_unlocked (instance, signal_id, detail, var_args))
3279
0
    SIGNAL_UNLOCK ();
3280
0
}
3281
3282
/*<private>
3283
 * signal_emit_valist_unlocked:
3284
 * @instance: The instance to emit from
3285
 * @signal_id: Signal id to emit
3286
 * @detail: Signal detail
3287
 * @var_args: Call arguments
3288
 *
3289
 * Returns: %TRUE if the signal mutex has been left locked
3290
 */
3291
static gboolean
3292
signal_emit_valist_unlocked (gpointer instance,
3293
                             guint    signal_id,
3294
                             GQuark   detail,
3295
                             va_list  var_args)
3296
0
{
3297
0
  GValue *instance_and_params;
3298
0
  GValue *param_values;
3299
0
  SignalNode *node;
3300
0
  guint i;
3301
3302
0
  g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), TRUE);
3303
0
  g_return_val_if_fail (signal_id > 0, TRUE);
3304
3305
0
  node = LOOKUP_SIGNAL_NODE (signal_id);
3306
0
  if (!node || !g_type_is_a (G_TYPE_FROM_INSTANCE (instance), node->itype))
3307
0
    {
3308
0
      g_critical ("%s: signal id '%u' is invalid for instance '%p'", G_STRLOC, signal_id, instance);
3309
0
      return TRUE;
3310
0
    }
3311
0
#ifndef G_DISABLE_CHECKS
3312
0
  if (detail && !(node->flags & G_SIGNAL_DETAILED))
3313
0
    {
3314
0
      g_critical ("%s: signal id '%u' does not support detail (%u)", G_STRLOC, signal_id, detail);
3315
0
      return TRUE;
3316
0
    }
3317
0
#endif  /* !G_DISABLE_CHECKS */
3318
3319
0
  if (!node->single_va_closure_is_valid)
3320
0
    node_update_single_va_closure (node);
3321
3322
  /* There's no need to deep copy this, because a SignalNode instance won't
3323
   * ever be destroyed, given that _g_signals_destroy() is not called in any
3324
   * real program, however the SignalNode pointer could change, so just store
3325
   * the struct contents references, so that we won't try to deference a
3326
   * potentially invalid (or changed) pointer;
3327
   */
3328
0
  SignalNode node_copy = *node;
3329
3330
0
  if (node->single_va_closure != NULL)
3331
0
    {
3332
0
      HandlerList* hlist;
3333
0
      Handler *fastpath_handler = NULL;
3334
0
      Handler *l;
3335
0
      GClosure *closure = NULL;
3336
0
      gboolean fastpath = TRUE;
3337
0
      GSignalFlags run_type = G_SIGNAL_RUN_FIRST;
3338
3339
0
      if (node->single_va_closure != SINGLE_VA_CLOSURE_EMPTY_MAGIC &&
3340
0
    !_g_closure_is_void (node->single_va_closure, instance))
3341
0
  {
3342
0
    if (_g_closure_supports_invoke_va (node->single_va_closure))
3343
0
      {
3344
0
        closure = node->single_va_closure;
3345
0
        if (node->single_va_closure_is_after)
3346
0
    run_type = G_SIGNAL_RUN_LAST;
3347
0
        else
3348
0
    run_type = G_SIGNAL_RUN_FIRST;
3349
0
      }
3350
0
    else
3351
0
      fastpath = FALSE;
3352
0
  }
3353
3354
      /* single_va_closure is only true for GObjects, so fast path if no handler ever connected to the signal */
3355
0
      if (_g_object_has_signal_handler ((GObject *)instance))
3356
0
        hlist = handler_list_lookup (node->signal_id, instance);
3357
0
      else
3358
0
        hlist = NULL;
3359
3360
0
      for (l = hlist ? hlist->handlers : NULL; fastpath && l != NULL; l = l->next)
3361
0
  {
3362
0
    if (!l->block_count &&
3363
0
        (!l->detail || l->detail == detail))
3364
0
      {
3365
0
        if (closure != NULL || !_g_closure_supports_invoke_va (l->closure))
3366
0
    {
3367
0
      fastpath = FALSE;
3368
0
      break;
3369
0
    }
3370
0
        else
3371
0
    {
3372
0
                  fastpath_handler = l;
3373
0
      closure = l->closure;
3374
0
      if (l->after)
3375
0
        run_type = G_SIGNAL_RUN_LAST;
3376
0
      else
3377
0
        run_type = G_SIGNAL_RUN_FIRST;
3378
0
    }
3379
0
      }
3380
0
  }
3381
3382
0
      if (fastpath && closure == NULL && node_copy.return_type == G_TYPE_NONE)
3383
0
        return TRUE;
3384
3385
      /* Don't allow no-recurse emission as we might have to restart, which means
3386
   we will run multiple handlers and thus must ref all arguments */
3387
0
      if (closure != NULL && (node_copy.flags & (G_SIGNAL_NO_RECURSE)) != 0)
3388
0
  fastpath = FALSE;
3389
      
3390
0
      if (fastpath)
3391
0
  {
3392
0
    Emission emission;
3393
0
    GValue *return_accu, accu = G_VALUE_INIT;
3394
0
    GType instance_type = G_TYPE_FROM_INSTANCE (instance);
3395
0
    GValue emission_return = G_VALUE_INIT;
3396
0
          GType rtype = node_copy.return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE;
3397
0
    gboolean static_scope = node_copy.return_type & G_SIGNAL_TYPE_STATIC_SCOPE;
3398
3399
0
    if (rtype == G_TYPE_NONE)
3400
0
      return_accu = NULL;
3401
0
    else if (node_copy.accumulator)
3402
0
      return_accu = &accu;
3403
0
    else
3404
0
      return_accu = &emission_return;
3405
3406
0
    emission.instance = instance;
3407
0
    emission.ihint.signal_id = signal_id;
3408
0
    emission.ihint.detail = detail;
3409
0
    emission.ihint.run_type = run_type | G_SIGNAL_ACCUMULATOR_FIRST_RUN;
3410
0
    emission.state = EMISSION_RUN;
3411
0
    emission.chain_type = instance_type;
3412
0
    emission_push (&emission);
3413
3414
0
          if (fastpath_handler)
3415
0
            handler_ref (fastpath_handler);
3416
3417
0
    if (closure != NULL)
3418
0
      {
3419
0
              TRACE (GOBJECT_SIGNAL_EMIT (signal_id, detail, instance, (uintmax_t) instance_type));
3420
3421
0
              SIGNAL_UNLOCK ();
3422
3423
0
              if (rtype != G_TYPE_NONE)
3424
0
                g_value_init (&emission_return, rtype);
3425
3426
0
              if (node_copy.accumulator)
3427
0
                g_value_init (&accu, rtype);
3428
3429
              /*
3430
               * Coverity doesn’t understand the paired ref/unref here and seems
3431
               * to ignore the ref, thus reports every call to g_signal_emit()
3432
               * as causing a double-free. That’s incorrect, but I can’t get a
3433
               * model file to work for avoiding the false positives, so instead
3434
               * comment out the ref/unref when doing static analysis.
3435
               */
3436
0
#ifndef __COVERITY__
3437
0
        g_object_ref (instance);
3438
0
#endif
3439
0
        _g_closure_invoke_va (closure,
3440
0
            return_accu,
3441
0
            instance,
3442
0
            var_args,
3443
0
                                    node_copy.n_params,
3444
0
                                    node_copy.param_types);
3445
0
        accumulate (&emission.ihint, &emission_return, &accu, node_copy.accumulator);
3446
3447
0
              if (node_copy.accumulator)
3448
0
                g_value_unset (&accu);
3449
3450
0
              SIGNAL_LOCK ();
3451
0
            }
3452
3453
0
    emission.chain_type = G_TYPE_NONE;
3454
0
    emission_pop (&emission);
3455
3456
0
          if (fastpath_handler)
3457
0
            handler_unref_R (signal_id, instance, fastpath_handler);
3458
3459
0
          SIGNAL_UNLOCK ();
3460
3461
0
    if (rtype != G_TYPE_NONE)
3462
0
      {
3463
0
        gchar *error = NULL;
3464
0
              for (i = 0; i < node_copy.n_params; i++)
3465
0
    {
3466
0
                  GType ptype = node_copy.param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE;
3467
0
      G_VALUE_COLLECT_SKIP (ptype, var_args);
3468
0
    }
3469
3470
0
              if (closure == NULL)
3471
0
                g_value_init (&emission_return, rtype);
3472
3473
0
        G_VALUE_LCOPY (&emission_return,
3474
0
           var_args,
3475
0
           static_scope ? G_VALUE_NOCOPY_CONTENTS : 0,
3476
0
           &error);
3477
0
        if (!error)
3478
0
    g_value_unset (&emission_return);
3479
0
        else
3480
0
    {
3481
0
      g_critical ("%s: %s", G_STRLOC, error);
3482
0
      g_free (error);
3483
      /* we purposely leak the value here, it might not be
3484
       * in a correct state if an error condition occurred
3485
       */
3486
0
    }
3487
0
      }
3488
3489
0
          TRACE (GOBJECT_SIGNAL_EMIT_END (signal_id, detail, instance, (uintmax_t) instance_type));
3490
3491
          /* See comment above paired ref above */
3492
0
#ifndef __COVERITY__
3493
0
          if (closure != NULL)
3494
0
            g_object_unref (instance);
3495
0
#endif
3496
3497
0
    return FALSE;
3498
0
  }
3499
0
    }
3500
3501
0
  SIGNAL_UNLOCK ();
3502
3503
0
  instance_and_params = g_newa0 (GValue, node_copy.n_params + 1);
3504
0
  param_values = instance_and_params + 1;
3505
3506
0
  for (i = 0; i < node_copy.n_params; i++)
3507
0
    {
3508
0
      gchar *error;
3509
0
      GType ptype = node_copy.param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE;
3510
0
      gboolean static_scope = node_copy.param_types[i] & G_SIGNAL_TYPE_STATIC_SCOPE;
3511
3512
0
      G_VALUE_COLLECT_INIT (param_values + i, ptype,
3513
0
          var_args,
3514
0
          static_scope ? G_VALUE_NOCOPY_CONTENTS : 0,
3515
0
          &error);
3516
0
      if (error)
3517
0
  {
3518
0
    g_critical ("%s: %s", G_STRLOC, error);
3519
0
    g_free (error);
3520
3521
    /* we purposely leak the value here, it might not be
3522
     * in a correct state if an error condition occurred
3523
     */
3524
0
    while (i--)
3525
0
      g_value_unset (param_values + i);
3526
3527
0
          return FALSE;
3528
0
  }
3529
0
    }
3530
3531
0
  g_value_init_from_instance (instance_and_params, instance);
3532
0
  if (node_copy.return_type == G_TYPE_NONE)
3533
0
    {
3534
0
      SIGNAL_LOCK ();
3535
0
      signal_emit_unlocked_R (&node_copy, detail, instance, NULL, instance_and_params);
3536
0
      SIGNAL_UNLOCK ();
3537
0
    }
3538
0
  else
3539
0
    {
3540
0
      GValue return_value = G_VALUE_INIT;
3541
0
      gchar *error = NULL;
3542
0
      GType rtype = node_copy.return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE;
3543
0
      gboolean static_scope = node_copy.return_type & G_SIGNAL_TYPE_STATIC_SCOPE;
3544
      
3545
0
      g_value_init (&return_value, rtype);
3546
3547
0
      SIGNAL_LOCK ();
3548
0
      signal_emit_unlocked_R (&node_copy, detail, instance, &return_value, instance_and_params);
3549
0
      SIGNAL_UNLOCK ();
3550
3551
0
      G_VALUE_LCOPY (&return_value,
3552
0
         var_args,
3553
0
         static_scope ? G_VALUE_NOCOPY_CONTENTS : 0,
3554
0
         &error);
3555
0
      if (!error)
3556
0
  g_value_unset (&return_value);
3557
0
      else
3558
0
  {
3559
0
    g_critical ("%s: %s", G_STRLOC, error);
3560
0
    g_free (error);
3561
    
3562
    /* we purposely leak the value here, it might not be
3563
     * in a correct state if an error condition occurred
3564
     */
3565
0
  }
3566
0
    }
3567
0
  for (i = 0; i < node_copy.n_params; i++)
3568
0
    g_value_unset (param_values + i);
3569
0
  g_value_unset (instance_and_params);
3570
3571
0
  return FALSE;
3572
0
}
3573
3574
/**
3575
 * g_signal_emit:
3576
 * @instance: (type GObject.Object): the instance the signal is being emitted on.
3577
 * @signal_id: the signal id
3578
 * @detail: the detail
3579
 * @...: parameters to be passed to the signal, followed by a
3580
 *  location for the return value. If the return type of the signal
3581
 *  is %G_TYPE_NONE, the return value location can be omitted.
3582
 *
3583
 * Emits a signal. Signal emission is done synchronously.
3584
 * The method will only return control after all handlers are called or signal emission was stopped.
3585
 *
3586
 * Note that g_signal_emit() resets the return value to the default
3587
 * if no handlers are connected, in contrast to g_signal_emitv().
3588
 */
3589
void
3590
g_signal_emit (gpointer instance,
3591
         guint    signal_id,
3592
         GQuark   detail,
3593
         ...)
3594
0
{
3595
0
  va_list var_args;
3596
3597
0
  va_start (var_args, detail);
3598
0
  g_signal_emit_valist (instance, signal_id, detail, var_args);
3599
0
  va_end (var_args);
3600
0
}
3601
3602
/**
3603
 * g_signal_emit_by_name:
3604
 * @instance: (type GObject.Object): the instance the signal is being emitted on.
3605
 * @detailed_signal: a string of the form "signal-name::detail".
3606
 * @...: parameters to be passed to the signal, followed by a
3607
 *  location for the return value. If the return type of the signal
3608
 *  is %G_TYPE_NONE, the return value location can be omitted. The
3609
 *  number of parameters to pass to this function is defined when creating the signal.
3610
 *
3611
 * Emits a signal. Signal emission is done synchronously.
3612
 * The method will only return control after all handlers are called or signal emission was stopped.
3613
 *
3614
 * Note that g_signal_emit_by_name() resets the return value to the default
3615
 * if no handlers are connected, in contrast to g_signal_emitv().
3616
 */
3617
void
3618
g_signal_emit_by_name (gpointer     instance,
3619
           const gchar *detailed_signal,
3620
           ...)
3621
0
{
3622
0
  GQuark detail = 0;
3623
0
  guint signal_id;
3624
0
  GType itype;
3625
3626
0
  g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance));
3627
0
  g_return_if_fail (detailed_signal != NULL);
3628
3629
0
  itype = G_TYPE_FROM_INSTANCE (instance);
3630
3631
0
  SIGNAL_LOCK ();
3632
0
  signal_id = signal_parse_name (detailed_signal, itype, &detail, TRUE);
3633
3634
0
  if (signal_id)
3635
0
    {
3636
0
      va_list var_args;
3637
3638
0
      va_start (var_args, detailed_signal);
3639
0
      if (signal_emit_valist_unlocked (instance, signal_id, detail, var_args))
3640
0
        SIGNAL_UNLOCK ();
3641
0
      va_end (var_args);
3642
0
    }
3643
0
  else
3644
0
    {
3645
0
      SIGNAL_UNLOCK ();
3646
3647
0
      g_critical ("%s: signal name '%s' is invalid for instance '%p' of type '%s'",
3648
0
                  G_STRLOC, detailed_signal, instance, g_type_name (itype));
3649
0
    }
3650
0
}
3651
3652
G_ALWAYS_INLINE static inline GValue *
3653
maybe_init_accumulator_unlocked (SignalNode *node,
3654
                                 GValue     *emission_return,
3655
                                 GValue     *accumulator_value)
3656
0
{
3657
0
  if (node->accumulator)
3658
0
    {
3659
0
      if (accumulator_value->g_type)
3660
0
        return accumulator_value;
3661
3662
0
      g_value_init (accumulator_value,
3663
0
                    node->return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE);
3664
0
      return accumulator_value;
3665
0
    }
3666
3667
0
  return emission_return;
3668
0
}
3669
3670
static gboolean
3671
signal_emit_unlocked_R (SignalNode   *node,
3672
      GQuark        detail,
3673
      gpointer      instance,
3674
      GValue       *emission_return,
3675
      const GValue *instance_and_params)
3676
0
{
3677
0
  SignalAccumulator *accumulator;
3678
0
  Emission emission;
3679
0
  GClosure *class_closure;
3680
0
  HandlerList *hlist;
3681
0
  Handler *handler_list = NULL;
3682
0
  GValue *return_accu, accu = G_VALUE_INIT;
3683
0
  guint signal_id;
3684
0
  gulong max_sequential_handler_number;
3685
0
  gboolean return_value_altered = FALSE;
3686
0
  guint n_params;
3687
3688
0
  TRACE(GOBJECT_SIGNAL_EMIT(node->signal_id, detail, instance, G_TYPE_FROM_INSTANCE (instance)));
3689
3690
  /* We expect this function to be called with a stable SignalNode pointer
3691
   * that cannot change location, so accessing its stable members should
3692
   * always work even after a lock/unlock.
3693
   */
3694
0
  signal_id = node->signal_id;
3695
0
  n_params = node->n_params + 1;
3696
3697
0
  if (node->flags & G_SIGNAL_NO_RECURSE)
3698
0
    {
3699
0
      Emission *emission_node = emission_find (signal_id, detail, instance);
3700
3701
0
      if (emission_node)
3702
0
        {
3703
0
          emission_node->state = EMISSION_RESTART;
3704
0
          return return_value_altered;
3705
0
        }
3706
0
    }
3707
0
  accumulator = node->accumulator;
3708
0
  emission.instance = instance;
3709
0
  emission.ihint.signal_id = node->signal_id;
3710
0
  emission.ihint.detail = detail;
3711
0
  emission.ihint.run_type = 0;
3712
0
  emission.state = 0;
3713
0
  emission.chain_type = G_TYPE_NONE;
3714
0
  emission_push (&emission);
3715
0
  class_closure = signal_lookup_closure (node, instance);
3716
  
3717
0
 EMIT_RESTART:
3718
  
3719
0
  if (handler_list)
3720
0
    handler_unref_R (signal_id, instance, handler_list);
3721
0
  max_sequential_handler_number = g_handler_sequential_number;
3722
0
  hlist = handler_list_lookup (signal_id, instance);
3723
0
  handler_list = hlist ? hlist->handlers : NULL;
3724
0
  if (handler_list)
3725
0
    handler_ref (handler_list);
3726
  
3727
0
  emission.ihint.run_type = G_SIGNAL_RUN_FIRST | G_SIGNAL_ACCUMULATOR_FIRST_RUN;
3728
  
3729
0
  if ((node->flags & G_SIGNAL_RUN_FIRST) && class_closure)
3730
0
    {
3731
0
      emission.state = EMISSION_RUN;
3732
3733
0
      emission.chain_type = G_TYPE_FROM_INSTANCE (instance);
3734
0
      SIGNAL_UNLOCK ();
3735
0
      return_accu = maybe_init_accumulator_unlocked (node, emission_return, &accu);
3736
0
      g_closure_invoke (class_closure,
3737
0
      return_accu,
3738
0
                        n_params,
3739
0
      instance_and_params,
3740
0
      &emission.ihint);
3741
0
      if (!accumulate (&emission.ihint, emission_return, &accu, accumulator) &&
3742
0
    emission.state == EMISSION_RUN)
3743
0
  emission.state = EMISSION_STOP;
3744
0
      SIGNAL_LOCK ();
3745
0
      emission.chain_type = G_TYPE_NONE;
3746
0
      return_value_altered = TRUE;
3747
      
3748
0
      if (emission.state == EMISSION_STOP)
3749
0
  goto EMIT_CLEANUP;
3750
0
      else if (emission.state == EMISSION_RESTART)
3751
0
  goto EMIT_RESTART;
3752
0
    }
3753
3754
0
  if (node->emission_hooks)
3755
0
    {
3756
0
      GHook *hook;
3757
0
      GHook *static_emission_hooks[3];
3758
0
      size_t n_emission_hooks = 0;
3759
0
      const gboolean may_recurse = TRUE;
3760
0
      guint i;
3761
3762
0
      emission.state = EMISSION_HOOK;
3763
3764
      /* Quick check to determine whether any hooks match this emission,
3765
       * before committing to the more complex work of calling those hooks.
3766
       * We save a few of them into a static array, to try to avoid further
3767
       * allocations.
3768
       */
3769
0
      hook = g_hook_first_valid (node->emission_hooks, may_recurse);
3770
0
      while (hook)
3771
0
  {
3772
0
    SignalHook *signal_hook = SIGNAL_HOOK (hook);
3773
3774
0
    if (!signal_hook->detail || signal_hook->detail == detail)
3775
0
            {
3776
0
              if (n_emission_hooks < G_N_ELEMENTS (static_emission_hooks))
3777
0
                {
3778
0
                  static_emission_hooks[n_emission_hooks] =
3779
0
                    g_hook_ref (node->emission_hooks, hook);
3780
0
                }
3781
3782
0
              n_emission_hooks += 1;
3783
0
            }
3784
3785
0
    hook = g_hook_next_valid (node->emission_hooks, hook, may_recurse);
3786
0
  }
3787
3788
      /* Re-iterate back through the matching hooks and copy them into
3789
       * an array which won’t change when we unlock to call the
3790
       * user-provided hook functions.
3791
       * These functions may change hook configuration for this signal,
3792
       * add / remove signal handlers, etc.
3793
       */
3794
0
      if G_UNLIKELY (n_emission_hooks > 0)
3795
0
        {
3796
0
          guint8 static_hook_returns[G_N_ELEMENTS (static_emission_hooks)];
3797
0
          GHook **emission_hooks = NULL;
3798
0
          guint8 *hook_returns = NULL;
3799
3800
0
          if G_LIKELY (n_emission_hooks <= G_N_ELEMENTS (static_emission_hooks))
3801
0
            {
3802
0
              emission_hooks = static_emission_hooks;
3803
0
              hook_returns = static_hook_returns;
3804
0
            }
3805
0
          else
3806
0
            {
3807
0
              emission_hooks = g_newa (GHook *, n_emission_hooks);
3808
0
              hook_returns = g_newa (guint8, n_emission_hooks);
3809
3810
              /* We can't just memcpy the ones we have in the static array,
3811
               * to the alloca()'d one because otherwise we'd get an invalid
3812
               * ID assertion during unref
3813
               */
3814
0
              i = 0;
3815
0
              for (hook = g_hook_first_valid (node->emission_hooks, may_recurse);
3816
0
                   hook != NULL;
3817
0
                   hook = g_hook_next_valid (node->emission_hooks, hook, may_recurse))
3818
0
                {
3819
0
                  SignalHook *signal_hook = SIGNAL_HOOK (hook);
3820
3821
0
                  if (!signal_hook->detail || signal_hook->detail == detail)
3822
0
                    {
3823
0
                       if (i < G_N_ELEMENTS (static_emission_hooks))
3824
0
                         {
3825
0
                            emission_hooks[i] = g_steal_pointer (&static_emission_hooks[i]);
3826
0
                            g_assert (emission_hooks[i] == hook);
3827
0
                         }
3828
0
                       else
3829
0
                         {
3830
0
                            emission_hooks[i] = g_hook_ref (node->emission_hooks, hook);
3831
0
                         }
3832
3833
0
                      i += 1;
3834
0
                    }
3835
0
                }
3836
3837
0
               g_assert (i == n_emission_hooks);
3838
0
            }
3839
3840
0
            SIGNAL_UNLOCK ();
3841
3842
0
            for (i = 0; i < n_emission_hooks; ++i)
3843
0
              {
3844
0
                GSignalEmissionHook hook_func;
3845
0
                gboolean need_destroy;
3846
0
                guint old_flags;
3847
3848
0
                hook = emission_hooks[i];
3849
0
                hook_func = (GSignalEmissionHook) hook->func;
3850
3851
0
                old_flags = g_atomic_int_or (&hook->flags, G_HOOK_FLAG_IN_CALL);
3852
0
                need_destroy = !hook_func (&emission.ihint, n_params,
3853
0
                                           instance_and_params, hook->data);
3854
3855
0
                if (!(old_flags & G_HOOK_FLAG_IN_CALL))
3856
0
                  {
3857
0
                    g_atomic_int_compare_and_exchange ((gint *) &hook->flags,
3858
0
                                                       (gint) old_flags | G_HOOK_FLAG_IN_CALL,
3859
0
                                                       (gint) old_flags);
3860
0
                  }
3861
3862
0
                hook_returns[i] = !!need_destroy;
3863
0
              }
3864
3865
0
            SIGNAL_LOCK ();
3866
3867
0
            for (i = 0; i < n_emission_hooks; i++)
3868
0
              {
3869
0
                hook = emission_hooks[i];
3870
3871
0
                g_hook_unref (node->emission_hooks, hook);
3872
3873
0
                if (hook_returns[i])
3874
0
                  g_hook_destroy_link (node->emission_hooks, hook);
3875
0
              }
3876
0
  }
3877
3878
0
      if (emission.state == EMISSION_RESTART)
3879
0
  goto EMIT_RESTART;
3880
0
    }
3881
  
3882
0
  if (handler_list)
3883
0
    {
3884
0
      Handler *handler = handler_list;
3885
      
3886
0
      emission.state = EMISSION_RUN;
3887
0
      handler_ref (handler);
3888
0
      do
3889
0
  {
3890
0
    Handler *tmp;
3891
    
3892
0
    if (handler->after)
3893
0
      {
3894
0
        handler_unref_R (signal_id, instance, handler_list);
3895
0
        handler_list = handler;
3896
0
        break;
3897
0
      }
3898
0
    else if (!handler->block_count && (!handler->detail || handler->detail == detail) &&
3899
0
       handler->sequential_number < max_sequential_handler_number)
3900
0
      {
3901
0
        SIGNAL_UNLOCK ();
3902
0
        return_accu = maybe_init_accumulator_unlocked (node, emission_return, &accu);
3903
0
        g_closure_invoke (handler->closure,
3904
0
        return_accu,
3905
0
                                n_params,
3906
0
        instance_and_params,
3907
0
        &emission.ihint);
3908
0
        if (!accumulate (&emission.ihint, emission_return, &accu, accumulator) &&
3909
0
      emission.state == EMISSION_RUN)
3910
0
    emission.state = EMISSION_STOP;
3911
0
        SIGNAL_LOCK ();
3912
0
        return_value_altered = TRUE;
3913
        
3914
0
        tmp = emission.state == EMISSION_RUN ? handler->next : NULL;
3915
0
      }
3916
0
    else
3917
0
      tmp = handler->next;
3918
    
3919
0
    if (tmp)
3920
0
      handler_ref (tmp);
3921
0
    handler_unref_R (signal_id, instance, handler_list);
3922
0
    handler_list = handler;
3923
0
    handler = tmp;
3924
0
  }
3925
0
      while (handler);
3926
      
3927
0
      if (emission.state == EMISSION_STOP)
3928
0
  goto EMIT_CLEANUP;
3929
0
      else if (emission.state == EMISSION_RESTART)
3930
0
  goto EMIT_RESTART;
3931
0
    }
3932
  
3933
0
  emission.ihint.run_type &= (unsigned) ~G_SIGNAL_RUN_FIRST;
3934
0
  emission.ihint.run_type |= G_SIGNAL_RUN_LAST;
3935
  
3936
0
  if ((node->flags & G_SIGNAL_RUN_LAST) && class_closure)
3937
0
    {
3938
0
      emission.state = EMISSION_RUN;
3939
      
3940
0
      emission.chain_type = G_TYPE_FROM_INSTANCE (instance);
3941
0
      SIGNAL_UNLOCK ();
3942
0
      return_accu = maybe_init_accumulator_unlocked (node, emission_return, &accu);
3943
0
      g_closure_invoke (class_closure,
3944
0
      return_accu,
3945
0
                        n_params,
3946
0
      instance_and_params,
3947
0
      &emission.ihint);
3948
0
      if (!accumulate (&emission.ihint, emission_return, &accu, accumulator) &&
3949
0
    emission.state == EMISSION_RUN)
3950
0
  emission.state = EMISSION_STOP;
3951
0
      SIGNAL_LOCK ();
3952
0
      emission.chain_type = G_TYPE_NONE;
3953
0
      return_value_altered = TRUE;
3954
      
3955
0
      if (emission.state == EMISSION_STOP)
3956
0
  goto EMIT_CLEANUP;
3957
0
      else if (emission.state == EMISSION_RESTART)
3958
0
  goto EMIT_RESTART;
3959
0
    }
3960
  
3961
0
  if (handler_list)
3962
0
    {
3963
0
      Handler *handler = handler_list;
3964
      
3965
0
      emission.state = EMISSION_RUN;
3966
0
      handler_ref (handler);
3967
0
      do
3968
0
  {
3969
0
    Handler *tmp;
3970
    
3971
0
    if (handler->after && !handler->block_count && (!handler->detail || handler->detail == detail) &&
3972
0
        handler->sequential_number < max_sequential_handler_number)
3973
0
      {
3974
0
        SIGNAL_UNLOCK ();
3975
0
        return_accu = maybe_init_accumulator_unlocked (node, emission_return, &accu);
3976
0
        g_closure_invoke (handler->closure,
3977
0
        return_accu,
3978
0
                                n_params,
3979
0
        instance_and_params,
3980
0
        &emission.ihint);
3981
0
        if (!accumulate (&emission.ihint, emission_return, &accu, accumulator) &&
3982
0
      emission.state == EMISSION_RUN)
3983
0
    emission.state = EMISSION_STOP;
3984
0
        SIGNAL_LOCK ();
3985
0
        return_value_altered = TRUE;
3986
        
3987
0
        tmp = emission.state == EMISSION_RUN ? handler->next : NULL;
3988
0
      }
3989
0
    else
3990
0
      tmp = handler->next;
3991
    
3992
0
    if (tmp)
3993
0
      handler_ref (tmp);
3994
0
    handler_unref_R (signal_id, instance, handler);
3995
0
    handler = tmp;
3996
0
  }
3997
0
      while (handler);
3998
      
3999
0
      if (emission.state == EMISSION_STOP)
4000
0
  goto EMIT_CLEANUP;
4001
0
      else if (emission.state == EMISSION_RESTART)
4002
0
  goto EMIT_RESTART;
4003
0
    }
4004
  
4005
0
 EMIT_CLEANUP:
4006
  
4007
0
  emission.ihint.run_type &= (unsigned) ~G_SIGNAL_RUN_LAST;
4008
0
  emission.ihint.run_type |= G_SIGNAL_RUN_CLEANUP;
4009
  
4010
0
  if ((node->flags & G_SIGNAL_RUN_CLEANUP) && class_closure)
4011
0
    {
4012
0
      gboolean need_unset = FALSE;
4013
      
4014
0
      emission.state = EMISSION_STOP;
4015
      
4016
0
      emission.chain_type = G_TYPE_FROM_INSTANCE (instance);
4017
0
      SIGNAL_UNLOCK ();
4018
0
      if (node->return_type != G_TYPE_NONE && !accumulator)
4019
0
  {
4020
0
    g_value_init (&accu, node->return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE);
4021
0
    need_unset = TRUE;
4022
0
  }
4023
0
      g_closure_invoke (class_closure,
4024
0
      node->return_type != G_TYPE_NONE ? &accu : NULL,
4025
0
                        n_params,
4026
0
      instance_and_params,
4027
0
      &emission.ihint);
4028
0
      if (!accumulate (&emission.ihint, emission_return, &accu, accumulator) &&
4029
0
          emission.state == EMISSION_RUN)
4030
0
        emission.state = EMISSION_STOP;
4031
0
      if (need_unset)
4032
0
  g_value_unset (&accu);
4033
0
      SIGNAL_LOCK ();
4034
0
      return_value_altered = TRUE;
4035
4036
0
      emission.chain_type = G_TYPE_NONE;
4037
      
4038
0
      if (emission.state == EMISSION_RESTART)
4039
0
  goto EMIT_RESTART;
4040
0
    }
4041
  
4042
0
  if (handler_list)
4043
0
    handler_unref_R (signal_id, instance, handler_list);
4044
  
4045
0
  emission_pop (&emission);
4046
0
  if (accumulator)
4047
0
    g_value_unset (&accu);
4048
4049
0
  TRACE(GOBJECT_SIGNAL_EMIT_END(node->signal_id, detail, instance, G_TYPE_FROM_INSTANCE (instance)));
4050
4051
0
  return return_value_altered;
4052
0
}
4053
4054
static void
4055
add_invalid_closure_notify (Handler  *handler,
4056
          gpointer  instance)
4057
0
{
4058
0
  g_closure_add_invalidate_notifier (handler->closure, instance, invalid_closure_notify);
4059
0
  handler->has_invalid_closure_notify = 1;
4060
0
}
4061
4062
static void
4063
remove_invalid_closure_notify (Handler  *handler,
4064
             gpointer  instance)
4065
0
{
4066
0
  if (handler->has_invalid_closure_notify)
4067
0
    {
4068
0
      g_closure_remove_invalidate_notifier (handler->closure, instance, invalid_closure_notify);
4069
0
      handler->has_invalid_closure_notify = 0;
4070
0
    }
4071
0
}
4072
4073
static void
4074
invalid_closure_notify (gpointer  instance,
4075
            GClosure *closure)
4076
0
{
4077
0
  Handler *handler;
4078
0
  guint signal_id;
4079
4080
0
  SIGNAL_LOCK ();
4081
4082
0
  handler = handler_lookup (instance, 0, closure, &signal_id);
4083
  /* See https://bugzilla.gnome.org/show_bug.cgi?id=730296 for discussion about this... */
4084
0
  g_assert (handler != NULL);
4085
0
  g_assert (handler->closure == closure);
4086
4087
0
  g_hash_table_remove (g_handlers, handler);
4088
0
  handler->sequential_number = 0;
4089
0
  handler->block_count = 1;
4090
0
  handler_unref_R (signal_id, instance, handler);
4091
4092
0
  SIGNAL_UNLOCK ();
4093
0
}
4094
4095
static const gchar*
4096
type_debug_name (GType type)
4097
0
{
4098
0
  if (type)
4099
0
    {
4100
0
      const char *name = g_type_name (type & ~G_SIGNAL_TYPE_STATIC_SCOPE);
4101
0
      return name ? name : "<unknown>";
4102
0
    }
4103
0
  else
4104
0
    return "<invalid>";
4105
0
}
4106
4107
/**
4108
 * g_signal_accumulator_true_handled:
4109
 * @ihint: standard #GSignalAccumulator parameter
4110
 * @return_accu: standard #GSignalAccumulator parameter
4111
 * @handler_return: standard #GSignalAccumulator parameter
4112
 * @dummy: standard #GSignalAccumulator parameter
4113
 *
4114
 * A predefined #GSignalAccumulator for signals that return a
4115
 * boolean values. The behavior that this accumulator gives is
4116
 * that a return of %TRUE stops the signal emission: no further
4117
 * callbacks will be invoked, while a return of %FALSE allows
4118
 * the emission to continue. The idea here is that a %TRUE return
4119
 * indicates that the callback handled the signal, and no further
4120
 * handling is needed.
4121
 *
4122
 * Since: 2.4
4123
 *
4124
 * Returns: standard #GSignalAccumulator result
4125
 */
4126
gboolean
4127
g_signal_accumulator_true_handled (GSignalInvocationHint *ihint,
4128
           GValue                *return_accu,
4129
           const GValue          *handler_return,
4130
           gpointer               dummy)
4131
0
{
4132
0
  gboolean continue_emission;
4133
0
  gboolean signal_handled;
4134
  
4135
0
  signal_handled = g_value_get_boolean (handler_return);
4136
0
  g_value_set_boolean (return_accu, signal_handled);
4137
0
  continue_emission = !signal_handled;
4138
  
4139
0
  return continue_emission;
4140
0
}
4141
4142
/**
4143
 * g_signal_accumulator_first_wins:
4144
 * @ihint: standard #GSignalAccumulator parameter
4145
 * @return_accu: standard #GSignalAccumulator parameter
4146
 * @handler_return: standard #GSignalAccumulator parameter
4147
 * @dummy: standard #GSignalAccumulator parameter
4148
 *
4149
 * A predefined #GSignalAccumulator for signals intended to be used as a
4150
 * hook for application code to provide a particular value.  Usually
4151
 * only one such value is desired and multiple handlers for the same
4152
 * signal don't make much sense (except for the case of the default
4153
 * handler defined in the class structure, in which case you will
4154
 * usually want the signal connection to override the class handler).
4155
 *
4156
 * This accumulator will use the return value from the first signal
4157
 * handler that is run as the return value for the signal and not run
4158
 * any further handlers (ie: the first handler "wins").
4159
 *
4160
 * Returns: standard #GSignalAccumulator result
4161
 *
4162
 * Since: 2.28
4163
 **/
4164
gboolean
4165
g_signal_accumulator_first_wins (GSignalInvocationHint *ihint,
4166
                                 GValue                *return_accu,
4167
                                 const GValue          *handler_return,
4168
                                 gpointer               dummy)
4169
0
{
4170
0
  g_value_copy (handler_return, return_accu);
4171
0
  return FALSE;
4172
0
}
4173
4174
/**
4175
 * g_clear_signal_handler:
4176
 * @handler_id_ptr: A pointer to a handler ID (of type #gulong) of the handler to be disconnected.
4177
 * @instance: (type GObject.Object): The instance to remove the signal handler from.
4178
 *   This pointer may be %NULL or invalid, if the handler ID is zero.
4179
 *
4180
 * Disconnects a handler from @instance so it will not be called during
4181
 * any future or currently ongoing emissions of the signal it has been
4182
 * connected to. The @handler_id_ptr is then set to zero, which is never a valid handler ID value (see g_signal_connect()).
4183
 *
4184
 * If the handler ID is 0 then this function does nothing.
4185
 *
4186
 * There is also a macro version of this function so that the code
4187
 * will be inlined.
4188
 *
4189
 * Since: 2.62
4190
 */
4191
void
4192
(g_clear_signal_handler) (gulong   *handler_id_ptr,
4193
                          gpointer  instance)
4194
0
{
4195
0
  g_return_if_fail (handler_id_ptr != NULL);
4196
4197
#ifndef g_clear_signal_handler
4198
#error g_clear_signal_handler() macro is not defined
4199
#endif
4200
4201
0
  g_clear_signal_handler (handler_id_ptr, instance);
4202
0
}