gsignal.c revision 782a8e2e7c69c3d98bd69bcfdbb65ded520576f4
1ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik/* GObject - GLib Type, Object, Parameter and Signal Library 2ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik * Copyright (C) 2000 Red Hat, Inc. 3ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik * 4ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik * This library is free software; you can redistribute it and/or 5ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik * modify it under the terms of the GNU Lesser General Public 6ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik * License as published by the Free Software Foundation; either 7ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik * version 2 of the License, or (at your option) any later version. 8ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik * 9ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik * This library is distributed in the hope that it will be useful, 10ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik * but WITHOUT ANY WARRANTY; without even the implied warranty of 11ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik * Lesser General Public License for more details. 13ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik * 14ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik * You should have received a copy of the GNU Lesser General 15ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik * Public License along with this library; if not, write to the 16ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik * Free Software Foundation, Inc., 59 Temple Place, Suite 330, 17ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik * Boston, MA 02111-1307, USA. 18ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik * 19ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik * this code is based on the original GtkSignal implementation 20ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik * for the Gtk+ library by Peter Mattis <petm@xcf.berkeley.edu> 21ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik */ 22fbe5df779cd39c9587f665118074ac828a805c26Owen Taylor#include <string.h> 23fbe5df779cd39c9587f665118074ac828a805c26Owen Taylor 24ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik#include "gsignal.h" 25ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik#include "gbsearcharray.h" 26e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik#include "gvaluecollector.h" 27ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 28ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 29ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik/* pre allocation configurations 30ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik */ 31e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik#define MAX_STACK_VALUES (16) 32ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik#define BSA_PRE_ALLOC (20) 33ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik#define HANDLER_PRE_ALLOC (48) 34ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik#define EMISSION_PRE_ALLOC (16) 35ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 36ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik#define REPORT_BUG "please report occourance circumstances to gtk-devel-list@gnome.org" 37ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 38ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 39ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik/* --- generic allocation --- */ 40782a8e2e7c69c3d98bd69bcfdbb65ded520576f4Tim Janik/* we special case allocations generically by replacing 41ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik * these functions with more speed/memory aware variants 42ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik */ 43782a8e2e7c69c3d98bd69bcfdbb65ded520576f4Tim Janik#ifndef DISABLE_MEM_POOLS 44ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikstatic inline gpointer 45ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikg_generic_node_alloc (GTrashStack **trash_stack_p, 46ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik guint sizeof_node, 47ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik guint nodes_pre_alloc) 48ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 49ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik gpointer node = g_trash_stack_pop (trash_stack_p); 50ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 51ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (!node) 52ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 53ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik guint8 *block; 54ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 55ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik nodes_pre_alloc = MAX (nodes_pre_alloc, 1); 56ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik block = g_malloc (sizeof_node * nodes_pre_alloc); 57ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik while (--nodes_pre_alloc) 58ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 59ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_trash_stack_push (trash_stack_p, block); 60ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik block += sizeof_node; 61ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 62ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node = block; 63ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 64ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 65ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik return node; 66ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 67ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikstatic inline void 68ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikg_generic_node_free (GTrashStack **trash_stack_p, 69ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik gpointer node) 70ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 71ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_trash_stack_push (trash_stack_p, node); 72ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 73782a8e2e7c69c3d98bd69bcfdbb65ded520576f4Tim Janik#else /* !DISABLE_MEM_POOLS */ 74782a8e2e7c69c3d98bd69bcfdbb65ded520576f4Tim Janikstatic inline gpointer 75782a8e2e7c69c3d98bd69bcfdbb65ded520576f4Tim Janikg_generic_node_alloc (GTrashStack **trash_stack_p, 76782a8e2e7c69c3d98bd69bcfdbb65ded520576f4Tim Janik guint sizeof_node, 77782a8e2e7c69c3d98bd69bcfdbb65ded520576f4Tim Janik guint nodes_pre_alloc) 78782a8e2e7c69c3d98bd69bcfdbb65ded520576f4Tim Janik{ 79782a8e2e7c69c3d98bd69bcfdbb65ded520576f4Tim Janik return g_malloc (sizeof_node); 80782a8e2e7c69c3d98bd69bcfdbb65ded520576f4Tim Janik} 81782a8e2e7c69c3d98bd69bcfdbb65ded520576f4Tim Janikstatic inline void 82782a8e2e7c69c3d98bd69bcfdbb65ded520576f4Tim Janikg_generic_node_free (GTrashStack **trash_stack_p, 83782a8e2e7c69c3d98bd69bcfdbb65ded520576f4Tim Janik gpointer node) 84782a8e2e7c69c3d98bd69bcfdbb65ded520576f4Tim Janik{ 85782a8e2e7c69c3d98bd69bcfdbb65ded520576f4Tim Janik g_free (node); 86782a8e2e7c69c3d98bd69bcfdbb65ded520576f4Tim Janik} 87782a8e2e7c69c3d98bd69bcfdbb65ded520576f4Tim Janik#endif /* !DISABLE_MEM_POOLS */ 88ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 89ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 90ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik/* --- typedefs --- */ 9183c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janiktypedef struct _SignalNode SignalNode; 9283c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janiktypedef struct _SignalKey SignalKey; 9383c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janiktypedef struct _Emission Emission; 9483c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janiktypedef struct _Handler Handler; 9583c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janiktypedef struct _HandlerList HandlerList; 9683c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janiktypedef struct _HandlerMatch HandlerMatch; 97ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janiktypedef enum 98ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 99ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik EMISSION_STOP, 100ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik EMISSION_RUN, 101ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik EMISSION_HOOK, 102ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik EMISSION_RESTART 103ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} EmissionState; 104ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 105ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 106ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik/* --- prototypes --- */ 10783c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janikstatic inline guint signal_id_lookup (GQuark quark, 10883c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik GType itype); 10983c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janikstatic void signal_destroy_R (SignalNode *signal_node); 11083c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janikstatic inline HandlerList* handler_list_ensure (guint signal_id, 11183c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik gpointer instance); 11283c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janikstatic inline HandlerList* handler_list_lookup (guint signal_id, 11383c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik gpointer instance); 11483c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janikstatic inline Handler* handler_new (gboolean after); 11583c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janikstatic void handler_insert (guint signal_id, 11683c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik gpointer instance, 11783c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik Handler *handler); 11883c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janikstatic Handler* handler_lookup (gpointer instance, 11983c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik guint handler_id, 12083c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik guint *signal_id_p); 12183c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janikstatic inline HandlerMatch* handler_match_prepend (HandlerMatch *list, 12283c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik Handler *handler, 12383c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik guint signal_id); 12483c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janikstatic inline HandlerMatch* handler_match_free1_R (HandlerMatch *node, 12583c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik gpointer instance); 12683c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janikstatic HandlerMatch* handlers_find (gpointer instance, 12783c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik GSignalMatchType mask, 12883c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik guint signal_id, 12983c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik GQuark detail, 13083c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik GClosure *closure, 13183c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik gpointer func, 13283c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik gpointer data, 13383c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik gboolean one_and_only); 13483c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janikstatic inline void handler_ref (Handler *handler); 13583c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janikstatic inline void handler_unref_R (guint signal_id, 13683c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik gpointer instance, 13783c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik Handler *handler); 13883c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janikstatic inline void emission_push (Emission **emission_list_p, 13983c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik guint signal_id, 14083c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik GQuark detail, 14183c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik gpointer instance, 14283c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik EmissionState *state_p); 14383c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janikstatic inline void emission_pop (Emission **emission_list_p, 14483c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik EmissionState *state_p); 14583c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janikstatic inline Emission* emission_find (Emission *emission_list, 14683c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik guint signal_id, 14783c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik GQuark detail, 14883c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik gpointer instance); 149e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janikstatic gboolean signal_emit_R (SignalNode *node, 15083c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik GQuark detail, 15183c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik gpointer instance, 15283c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik GValue *return_value, 15383c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik const GValue *instance_and_params); 154ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 155ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 156ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik/* --- structures --- */ 157ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikstruct _SignalNode 158ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 159ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik /* permanent portion */ 160ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik guint signal_id; 161ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik GType itype; 162ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik gchar *name; 163ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik guint destroyed : 1; 164ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 165ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik /* reinitializable portion */ 166ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik guint flags : 8; 167ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik guint n_params : 8; 168ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik GType *param_types; 169ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik GType return_type; 170ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik GClosure *class_closure; 171ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik GSignalAccumulator accumulator; 172ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik GSignalCMarshaller c_marshaller; 173ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik GHookList *emission_hooks; 174ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik}; 175ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 176ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikstruct _SignalKey 177ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 178ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik GType itype; 179ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik GQuark quark; 180ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik guint signal_id; 181ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik}; 182ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 183ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikstruct _Emission 184ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 185ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik Emission *next; 186ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik guint signal_id; 187830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik GQuark detail; 188ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik gpointer instance; 189ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik EmissionState *state_p; 190ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik}; 191ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 192ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikstruct _HandlerList 193ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 194ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik guint signal_id; 195ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik Handler *handlers; 196ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik}; 197ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikstruct _Handler 198ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 199ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik guint id; 200ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik Handler *next; 201ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik Handler *prev; 202830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik GQuark detail; 203ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik guint ref_count : 16; 204ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik#define HANDLER_MAX_REF_COUNT (1 << 16) 205ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik guint block_count : 12; 206ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik#define HANDLER_MAX_BLOCK_COUNT (1 << 12) 207ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik guint after : 1; 208ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik GClosure *closure; 209ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik}; 21083c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janikstruct _HandlerMatch 21183c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik{ 21283c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik Handler *handler; 21383c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik HandlerMatch *next; 21483c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik union { 21583c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik guint signal_id; 21683c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik gpointer dummy; 21783c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik } d; 21883c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik}; 219ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 220ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 221ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik/* --- variables --- */ 222ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikstatic GBSearchArray g_signal_key_bsa = { NULL, 0, 0, 0, NULL }; 223ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikstatic GHashTable *g_handler_list_bsa_ht = NULL; 224ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikstatic Emission *g_recursive_emissions = NULL; 225ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikstatic Emission *g_restart_emissions = NULL; 226ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikstatic GTrashStack *g_bsa_ts = NULL; 227ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikstatic GTrashStack *g_handler_ts = NULL; 228ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikstatic GTrashStack *g_emission_ts = NULL; 229ee23c09e83d06a0d131ebd234c132f1c3602c019Tim JanikG_LOCK_DEFINE_STATIC (g_signal_mutex); 230ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 231ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 232ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik/* --- signal nodes --- */ 233ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikstatic guint g_n_signal_nodes = 0; 234ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikstatic SignalNode **g_signal_nodes = NULL; 235ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 236ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikstatic inline SignalNode* 237ee23c09e83d06a0d131ebd234c132f1c3602c019Tim JanikLOOKUP_SIGNAL_NODE (register guint signal_id) 238ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 239ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (signal_id < g_n_signal_nodes) 240ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik return g_signal_nodes[signal_id]; 241ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik else 242ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik return NULL; 243ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 244ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 245ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 246ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik/* --- functions --- */ 247ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikstatic inline guint 248ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janiksignal_id_lookup (GQuark quark, 249ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik GType itype) 250ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 251e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik GType *ifaces, type = itype; 252e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik SignalKey key; 253e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik guint n_ifaces; 254e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 255e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik key.quark = quark; 256e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 257e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik /* try looking up signals for this type and its anchestors */ 2588a572c0da1be99527c52f620dc7fd04eb0775bdeTim Janik do 2598a572c0da1be99527c52f620dc7fd04eb0775bdeTim Janik { 260e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik SignalKey *signal_key; 2618a572c0da1be99527c52f620dc7fd04eb0775bdeTim Janik 262e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik key.itype = type; 2638a572c0da1be99527c52f620dc7fd04eb0775bdeTim Janik signal_key = g_bsearch_array_lookup (&g_signal_key_bsa, &key); 2648a572c0da1be99527c52f620dc7fd04eb0775bdeTim Janik 2658a572c0da1be99527c52f620dc7fd04eb0775bdeTim Janik if (signal_key) 2668a572c0da1be99527c52f620dc7fd04eb0775bdeTim Janik return signal_key->signal_id; 2678a572c0da1be99527c52f620dc7fd04eb0775bdeTim Janik 268e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik type = g_type_parent (type); 2698a572c0da1be99527c52f620dc7fd04eb0775bdeTim Janik } 270e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik while (type); 271e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 272e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik /* no luck, try interfaces it exports */ 273e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik ifaces = g_type_interfaces (itype, &n_ifaces); 274e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik while (n_ifaces--) 275e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik { 276e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik SignalKey *signal_key; 277e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 278e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik key.itype = ifaces[n_ifaces]; 279e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik signal_key = g_bsearch_array_lookup (&g_signal_key_bsa, &key); 280e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 281e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik if (signal_key) 282e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik { 283e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_free (ifaces); 284e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik return signal_key->signal_id; 285e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik } 286e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik } 287e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_free (ifaces); 288ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 2898a572c0da1be99527c52f620dc7fd04eb0775bdeTim Janik return 0; 290ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 291ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 292ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikstatic gint 293ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikhandler_lists_cmp (gconstpointer node1, 294ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik gconstpointer node2) 295ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 296ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik const HandlerList *hlist1 = node1, *hlist2 = node2; 297ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 298ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik return G_BSEARCH_ARRAY_CMP (hlist1->signal_id, hlist2->signal_id); 299ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 300ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 301ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikstatic inline HandlerList* 302ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikhandler_list_ensure (guint signal_id, 303ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik gpointer instance) 304ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 305ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik GBSearchArray *hlbsa = g_hash_table_lookup (g_handler_list_bsa_ht, instance); 306ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik HandlerList key; 307ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 308ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (!hlbsa) 309ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 310ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik hlbsa = g_generic_node_alloc (&g_bsa_ts, 311ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik sizeof (GBSearchArray), 312ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik BSA_PRE_ALLOC); 313ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik hlbsa->cmp_func = handler_lists_cmp; 314ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik hlbsa->sizeof_node = sizeof (HandlerList); 315ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik hlbsa->flags = G_BSEARCH_DEFER_SHRINK; 316ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik hlbsa->n_nodes = 0; 317ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik hlbsa->nodes = NULL; 318ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_hash_table_insert (g_handler_list_bsa_ht, instance, hlbsa); 319ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 320ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik key.signal_id = signal_id; 321ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik key.handlers = NULL; 322ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 323ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik return g_bsearch_array_insert (hlbsa, &key, FALSE); 324ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 325ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 326ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikstatic inline HandlerList* 327ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikhandler_list_lookup (guint signal_id, 328ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik gpointer instance) 329ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 330ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik GBSearchArray *hlbsa = g_hash_table_lookup (g_handler_list_bsa_ht, instance); 331ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik HandlerList key; 332ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 333ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik key.signal_id = signal_id; 334ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 335ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik return hlbsa ? g_bsearch_array_lookup (hlbsa, &key) : NULL; 336ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 337ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 338ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikstatic Handler* 339ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikhandler_lookup (gpointer instance, 340ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik guint handler_id, 341ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik guint *signal_id_p) 342ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 343ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik GBSearchArray *hlbsa = g_hash_table_lookup (g_handler_list_bsa_ht, instance); 344ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 345ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (hlbsa) 346ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 347ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik guint i; 348ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 349ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik for (i = 0; i < hlbsa->n_nodes; i++) 350ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 351ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik HandlerList *hlist = g_bsearch_array_get_nth (hlbsa, i); 352ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik Handler *handler; 353ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 354ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik for (handler = hlist->handlers; handler; handler = handler->next) 355ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (handler->id == handler_id) 356ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 357ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (signal_id_p) 358ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik *signal_id_p = hlist->signal_id; 359ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 360ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik return handler; 361ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 362ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 363ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 364ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 365ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik return NULL; 366ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 367ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 36883c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janikstatic inline HandlerMatch* 36983c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janikhandler_match_prepend (HandlerMatch *list, 37083c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik Handler *handler, 37183c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik guint signal_id) 37283c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik{ 37383c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik HandlerMatch *node; 37483c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 37583c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik /* yeah, we could use our own memchunk here, introducing yet more 37683c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik * rarely used cached nodes and extra allocation overhead. 37783c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik * instead, we use GList* nodes, since they are exactly the size 37883c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik * we need and are already cached. g_signal_init() asserts this. 37983c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik */ 38083c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik node = (HandlerMatch*) g_list_alloc (); 38183c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik node->handler = handler; 38283c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik node->next = list; 38383c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik node->d.signal_id = signal_id; 38483c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik handler_ref (handler); 38583c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 38683c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik return node; 38783c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik} 38883c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janikstatic inline HandlerMatch* 38983c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janikhandler_match_free1_R (HandlerMatch *node, 39083c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik gpointer instance) 39183c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik{ 39283c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik HandlerMatch *next = node->next; 39383c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 39483c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik handler_unref_R (node->d.signal_id, instance, node->handler); 39583c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik g_list_free_1 ((GList*) node); 39683c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 39783c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik return next; 39883c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik} 39983c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 40083c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janikstatic HandlerMatch* 40183c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janikhandlers_find (gpointer instance, 40283c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik GSignalMatchType mask, 40383c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik guint signal_id, 40483c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik GQuark detail, 40583c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik GClosure *closure, 40683c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik gpointer func, 40783c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik gpointer data, 40883c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik gboolean one_and_only) 409ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 41083c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik HandlerMatch *mlist = NULL; 41183c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 412ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (mask & G_SIGNAL_MATCH_ID) 413ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 414ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik HandlerList *hlist = handler_list_lookup (signal_id, instance); 415ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik Handler *handler; 416790a7bd3be608d9b12a18711d4400490d96b2a46Elliot Lee SignalNode *node = NULL; 417ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 41855ec7f32a6852dba73abb29e650615b66b065ef9Tim Janik if (mask & G_SIGNAL_MATCH_FUNC) 419ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 420ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node = LOOKUP_SIGNAL_NODE (signal_id); 421ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (!node || !node->c_marshaller) 422ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik return NULL; 423ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 42483c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 425ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik mask = ~mask; 426ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik for (handler = hlist ? hlist->handlers : NULL; handler; handler = handler->next) 42783c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik if (handler->id && 42883c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik ((mask & G_SIGNAL_MATCH_DETAIL) || handler->detail == detail) && 429830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik ((mask & G_SIGNAL_MATCH_CLOSURE) || handler->closure == closure) && 430ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik ((mask & G_SIGNAL_MATCH_DATA) || handler->closure->data == data) && 431830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik ((mask & G_SIGNAL_MATCH_UNBLOCKED) || handler->block_count == 0) && 432ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik ((mask & G_SIGNAL_MATCH_FUNC) || (handler->closure->marshal == node->c_marshaller && 433ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik handler->closure->meta_marshal == 0 && 434ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik ((GCClosure*) handler->closure)->callback == func))) 43583c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik { 43683c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik mlist = handler_match_prepend (mlist, handler, signal_id); 43783c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik if (one_and_only) 43883c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik return mlist; 43983c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik } 440ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 441ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik else 442ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 443ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik GBSearchArray *hlbsa = g_hash_table_lookup (g_handler_list_bsa_ht, instance); 444ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 445ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik mask = ~mask; 446ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (hlbsa) 447ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 448ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik guint i; 449ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 450ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik for (i = 0; i < hlbsa->n_nodes; i++) 451ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 452ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik HandlerList *hlist = g_bsearch_array_get_nth (hlbsa, i); 453790a7bd3be608d9b12a18711d4400490d96b2a46Elliot Lee SignalNode *node = NULL; 454ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik Handler *handler; 455ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 456ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (!(mask & G_SIGNAL_MATCH_FUNC)) 457ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 458ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node = LOOKUP_SIGNAL_NODE (hlist->signal_id); 459ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (!node->c_marshaller) 460ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik continue; 461ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 46283c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 463ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik for (handler = hlist->handlers; handler; handler = handler->next) 46483c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik if (handler->id && 46583c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik ((mask & G_SIGNAL_MATCH_DETAIL) || handler->detail == detail) && 466830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik ((mask & G_SIGNAL_MATCH_CLOSURE) || handler->closure == closure) && 467ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik ((mask & G_SIGNAL_MATCH_DATA) || handler->closure->data == data) && 468830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik ((mask & G_SIGNAL_MATCH_UNBLOCKED) || handler->block_count == 0) && 469ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik ((mask & G_SIGNAL_MATCH_FUNC) || (handler->closure->marshal == node->c_marshaller && 470ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik handler->closure->meta_marshal == 0 && 471ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik ((GCClosure*) handler->closure)->callback == func))) 47283c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik { 473a453526f350a3956a26f71db481bd8b436c65f97Owen Taylor mlist = handler_match_prepend (mlist, handler, hlist->signal_id); 47483c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik if (one_and_only) 47583c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik return mlist; 47683c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik } 477ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 478ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 479ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 480ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 48183c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik return mlist; 482ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 483ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 484ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikstatic inline Handler* 485ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikhandler_new (gboolean after) 486ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 487ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik static guint handler_id = 1; 488ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik Handler *handler = g_generic_node_alloc (&g_handler_ts, 489ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik sizeof (Handler), 490ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik HANDLER_PRE_ALLOC); 491ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik#ifndef G_DISABLE_CHECKS 492ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (handler_id == 0) 493ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_error (G_STRLOC ": handler id overflow, %s", REPORT_BUG); 494ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik#endif 495ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 496ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik handler->id = handler_id++; 497ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik handler->prev = NULL; 498ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik handler->next = NULL; 499830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik handler->detail = 0; 500ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik handler->ref_count = 1; 501ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik handler->block_count = 0; 502ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik handler->after = after != FALSE; 503ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik handler->closure = NULL; 504ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 505ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik return handler; 506ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 507ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 508ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikstatic inline void 509ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikhandler_ref (Handler *handler) 510ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 511ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_return_if_fail (handler->ref_count > 0); 512ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 513ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik#ifndef G_DISABLE_CHECKS 514ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (handler->ref_count >= HANDLER_MAX_REF_COUNT - 1) 515ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_error (G_STRLOC ": handler ref_count overflow, %s", REPORT_BUG); 516ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik#endif 517ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 518ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik handler->ref_count += 1; 519ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 520ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 521ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikstatic inline void 522ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikhandler_unref_R (guint signal_id, 523ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik gpointer instance, 524ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik Handler *handler) 525ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 526ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_return_if_fail (handler->ref_count > 0); 527ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 528ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik handler->ref_count -= 1; 529ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (!handler->ref_count) 530ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 531ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (handler->next) 532ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik handler->next->prev = handler->prev; 53383c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik if (handler->prev) /* watch out for g_signal_handlers_destroy()! */ 534ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik handler->prev->next = handler->next; 535ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik else 536ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 537ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik HandlerList *hlist = handler_list_lookup (signal_id, instance); 538ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 539ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik hlist->handlers = handler->next; 540ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 541ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_UNLOCK (g_signal_mutex); 542ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_closure_unref (handler->closure); 543ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_LOCK (g_signal_mutex); 544ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_generic_node_free (&g_handler_ts, handler); 545ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 546ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 547ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 548ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikstatic void 549ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikhandler_insert (guint signal_id, 550ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik gpointer instance, 551ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik Handler *handler) 552ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 553ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik HandlerList *hlist; 554ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 555e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_assert (handler->prev == NULL && handler->next == NULL); /* paranoid */ 556ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 557ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik hlist = handler_list_ensure (signal_id, instance); 558ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (!hlist->handlers) 559ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik hlist->handlers = handler; 560ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik else if (hlist->handlers->after && !handler->after) 561ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 562ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik handler->next = hlist->handlers; 563ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik hlist->handlers->prev = handler; 564ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik hlist->handlers = handler; 565ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 566ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik else 567ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 568ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik Handler *tmp = hlist->handlers; 569ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 570ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (handler->after) 571ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik while (tmp->next) 572ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik tmp = tmp->next; 573ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik else 574ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik while (tmp->next && !tmp->next->after) 575ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik tmp = tmp->next; 576ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (tmp->next) 577ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik tmp->next->prev = handler; 578ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik handler->next = tmp->next; 579ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik handler->prev = tmp; 580ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik tmp->next = handler; 581ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 582ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 583ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 584ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikstatic inline void 585ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikemission_push (Emission **emission_list_p, 586ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik guint signal_id, 587830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik GQuark detail, 588ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik gpointer instance, 589ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik EmissionState *state_p) 590ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 591ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik Emission *emission = g_generic_node_alloc (&g_emission_ts, 592ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik sizeof (Emission), 593ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik EMISSION_PRE_ALLOC); 594ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik emission->next = *emission_list_p; 595ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik emission->signal_id = signal_id; 596830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik emission->detail = detail; 597ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik emission->instance = instance; 598ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik emission->state_p = state_p; 599ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik *emission_list_p = emission; 600ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 601ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 602ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikstatic inline void 603830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janikemission_pop (Emission **emission_list_p, 604830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik EmissionState *state_p) 605ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 606830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik Emission **loc = emission_list_p, *emission = *loc; 60783c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 608830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik while (emission->state_p != state_p) 609830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik { 610830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik loc = &emission->next; 611830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik emission = *loc; 612830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik } 613830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik *loc = emission->next; 614ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_generic_node_free (&g_emission_ts, emission); 615ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 616ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 617ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikstatic inline Emission* 618ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikemission_find (Emission *emission_list, 619ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik guint signal_id, 620830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik GQuark detail, 621ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik gpointer instance) 622ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 623ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik Emission *emission; 624ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 625ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik for (emission = emission_list; emission; emission = emission->next) 626830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik if (emission->instance == instance && 627830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik emission->signal_id == signal_id && 628830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik emission->detail == detail) 629ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik return emission; 630ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik return NULL; 631ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 632ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 633ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikstatic gint 634ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janiksignal_key_cmp (gconstpointer node1, 635ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik gconstpointer node2) 636ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 637ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik const SignalKey *key1 = node1, *key2 = node2; 638ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 639ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (key1->itype == key2->itype) 640ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik return G_BSEARCH_ARRAY_CMP (key1->quark, key2->quark); 641ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik else 642ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik return G_BSEARCH_ARRAY_CMP (key1->itype, key2->itype); 643ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 644ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 645ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikvoid 646ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikg_signal_init (void) /* sync with gtype.c */ 647ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 648ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_LOCK (g_signal_mutex); 649ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (!g_n_signal_nodes) 650ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 65183c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik /* handler_id_node_prepend() requires this */ 65283c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik g_assert (sizeof (GList) == sizeof (HandlerMatch)); 65383c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 654ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik /* setup signal key array */ 655ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_signal_key_bsa.cmp_func = signal_key_cmp; 656ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_signal_key_bsa.sizeof_node = sizeof (SignalKey); 657782a8e2e7c69c3d98bd69bcfdbb65ded520576f4Tim Janik g_signal_key_bsa.flags = G_BSEARCH_ALIGN_POWER2; /* alloc-only */ 658ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 659ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik /* setup handler list binary searchable array hash table (in german, that'd be one word ;) */ 660ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_handler_list_bsa_ht = g_hash_table_new (g_direct_hash, NULL); 661ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 662ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik /* invalid (0) signal_id */ 663ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_n_signal_nodes = 1; 664ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_signal_nodes = g_renew (SignalNode*, g_signal_nodes, g_n_signal_nodes); 665ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_signal_nodes[0] = NULL; 666ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 667ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_UNLOCK (g_signal_mutex); 668ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 669ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 670ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikvoid 6713cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik_g_signals_destroy (GType itype) 672ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 673ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik guint i; 674ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 675ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_LOCK (g_signal_mutex); 67683c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik for (i = 1; i < g_n_signal_nodes; i++) 677ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 678ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik SignalNode *node = g_signal_nodes[i]; 679ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 680ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (node->itype == itype) 681ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 682ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (node->destroyed) 683ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_warning (G_STRLOC ": signal \"%s\" of type `%s' already destroyed", 684ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node->name, 685ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_type_name (node->itype)); 686ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik else 687cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik signal_destroy_R (node); 688ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 689ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 690ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_UNLOCK (g_signal_mutex); 691ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 692ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 693ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikvoid 694ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikg_signal_stop_emission (gpointer instance, 695830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik guint signal_id, 696830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik GQuark detail) 697ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 698ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik SignalNode *node; 699ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 700ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance)); 701ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_return_if_fail (signal_id > 0); 702ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 703ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_LOCK (g_signal_mutex); 704ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node = LOOKUP_SIGNAL_NODE (signal_id); 705830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik if (node && detail && !(node->flags & G_SIGNAL_DETAILED)) 706830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik { 707830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik g_warning ("%s: signal id `%u' does not support detail (%u)", G_STRLOC, signal_id, detail); 708830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik G_UNLOCK (g_signal_mutex); 709830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik return; 710830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik } 711e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik if (node && g_type_is_a (G_TYPE_FROM_INSTANCE (instance), node->itype)) 712ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 713ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik Emission *emission_list = node->flags & G_SIGNAL_NO_RECURSE ? g_restart_emissions : g_recursive_emissions; 714830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik Emission *emission = emission_find (emission_list, signal_id, detail, instance); 715ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 716ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (emission) 717ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 718ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (*emission->state_p == EMISSION_HOOK) 719ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_warning (G_STRLOC ": emission of signal \"%s\" for instance `%p' cannot be stopped from emission hook", 720ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node->name, instance); 721ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik else if (*emission->state_p == EMISSION_RUN) 722ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik *emission->state_p = EMISSION_STOP; 723ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 724ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik else 725ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_warning (G_STRLOC ": no emission of signal \"%s\" to stop for instance `%p'", 726ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node->name, instance); 727ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 728ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik else 729ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_warning ("%s: signal id `%u' is invalid for instance `%p'", G_STRLOC, signal_id, instance); 730ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_UNLOCK (g_signal_mutex); 731ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 732ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 7333cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janikstatic inline guint 7343cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janiksignal_parse_name (const gchar *name, 7353cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik GType itype, 7363cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik GQuark *detail_p, 7373cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik gboolean force_quark) 7383cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik{ 7393cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik const gchar *colon = strchr (name, ':'); 7403cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik guint signal_id; 7413cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik 7423cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik if (!colon) 7433cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik { 7443cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik signal_id = signal_id_lookup (g_quark_try_string (name), itype); 7453cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik if (signal_id && detail_p) 7463cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik *detail_p = 0; 7473cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik } 7483cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik else if (colon[1] == ':') 7493cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik { 7503cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik gchar buffer[32]; 7513cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik guint l = colon - name; 7523cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik 7533cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik if (l < 32) 7543cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik { 7553cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik memcpy (buffer, name, l); 7563cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik buffer[l] = 0; 7573cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik signal_id = signal_id_lookup (g_quark_try_string (buffer), itype); 7583cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik } 7593cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik else 7603cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik { 7613cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik gchar *signal = g_new (gchar, l + 1); 7623cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik 7633cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik memcpy (signal, name, l); 7643cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik signal[l] = 0; 7653cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik signal_id = signal_id_lookup (g_quark_try_string (signal), itype); 7663cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik g_free (signal); 7673cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik } 7683cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik 7693cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik if (signal_id && detail_p) 7703cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik *detail_p = colon[2] ? (force_quark ? g_quark_from_string : g_quark_try_string) (colon + 2) : 0; 7713cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik } 7723cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik else 7733cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik signal_id = 0; 7743cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik return signal_id; 7753cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik} 7763cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik 7773cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janikgboolean 7783cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janikg_signal_parse_name (const gchar *detailed_signal, 7793cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik GType itype, 7803cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik guint *signal_id_p, 7813cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik GQuark *detail_p, 7823cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik gboolean force_detail_quark) 7833cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik{ 7843cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik GQuark detail = 0; 7853cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik guint signal_id; 78683c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 7873cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik g_return_val_if_fail (detailed_signal != NULL, FALSE); 7883cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik g_return_val_if_fail (G_TYPE_IS_INSTANTIATABLE (itype) || G_TYPE_IS_INTERFACE (itype), FALSE); 78983c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 7903cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik G_LOCK (g_signal_mutex); 7913cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik signal_id = signal_parse_name (detailed_signal, itype, &detail, force_detail_quark); 7923cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik G_UNLOCK (g_signal_mutex); 79383c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 7943cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik if (signal_id) 7953cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik { 7963cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik if (signal_id_p) 7973cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik *signal_id_p = signal_id; 7983cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik if (detail_p) 7993cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik *detail_p = detail; 80083c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 8013cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik return TRUE; 8023cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik } 8033cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik else 8043cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik return FALSE; 8053cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik} 8063cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik 807ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikguint 808ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikg_signal_lookup (const gchar *name, 809ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik GType itype) 810ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 8118a572c0da1be99527c52f620dc7fd04eb0775bdeTim Janik guint signal_id; 8128a572c0da1be99527c52f620dc7fd04eb0775bdeTim Janik 813ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_return_val_if_fail (name != NULL, 0); 814ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_return_val_if_fail (G_TYPE_IS_INSTANTIATABLE (itype) || G_TYPE_IS_INTERFACE (itype), 0); 815ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 816ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_LOCK (g_signal_mutex); 8178a572c0da1be99527c52f620dc7fd04eb0775bdeTim Janik signal_id = signal_id_lookup (g_quark_try_string (name), itype); 818ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_UNLOCK (g_signal_mutex); 819ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 8208a572c0da1be99527c52f620dc7fd04eb0775bdeTim Janik return signal_id; 821ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 822ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 823ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikgchar* 824ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikg_signal_name (guint signal_id) 825ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 826ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik SignalNode *node; 827ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik gchar *name; 82883c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 829ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_LOCK (g_signal_mutex); 830ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node = LOOKUP_SIGNAL_NODE (signal_id); 831ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik name = node ? node->name : NULL; 832ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_UNLOCK (g_signal_mutex); 833ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 834ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik return name; 835ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 836ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 837ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikvoid 838ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikg_signal_query (guint signal_id, 839ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik GSignalQuery *query) 840ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 841ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik SignalNode *node; 84283c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 843ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_return_if_fail (query != NULL); 84483c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 845ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_LOCK (g_signal_mutex); 846ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node = LOOKUP_SIGNAL_NODE (signal_id); 847ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (!node || node->destroyed) 848ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik query->signal_id = 0; 849ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik else 850ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 851ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik query->signal_id = node->signal_id; 852ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik query->signal_name = node->name; 853ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik query->itype = node->itype; 854ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik query->signal_flags = node->flags; 855ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik query->return_type = node->return_type; 856ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik query->n_params = node->n_params; 857ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik query->param_types = node->param_types; 858ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 859ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_UNLOCK (g_signal_mutex); 860ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 861ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 86265c423b458d9fd1338cab0de7951092c09ab1686Tim Janikguint* 86365c423b458d9fd1338cab0de7951092c09ab1686Tim Janikg_signal_list_ids (GType itype, 86465c423b458d9fd1338cab0de7951092c09ab1686Tim Janik guint *n_ids) 865300e3bb247216fee40254822c2fb60a78a8ef21cOwen Taylor{ 866300e3bb247216fee40254822c2fb60a78a8ef21cOwen Taylor SignalKey *keys; 867300e3bb247216fee40254822c2fb60a78a8ef21cOwen Taylor GArray *result; 86865c423b458d9fd1338cab0de7951092c09ab1686Tim Janik guint n_nodes; 86965c423b458d9fd1338cab0de7951092c09ab1686Tim Janik guint i; 87083c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 871300e3bb247216fee40254822c2fb60a78a8ef21cOwen Taylor g_return_val_if_fail (G_TYPE_IS_INSTANTIATABLE (itype) || G_TYPE_IS_INTERFACE (itype), NULL); 87265c423b458d9fd1338cab0de7951092c09ab1686Tim Janik g_return_val_if_fail (n_ids != NULL, NULL); 87383c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 87465c423b458d9fd1338cab0de7951092c09ab1686Tim Janik G_LOCK (g_signal_mutex); 87583c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 876300e3bb247216fee40254822c2fb60a78a8ef21cOwen Taylor keys = g_signal_key_bsa.nodes; 877300e3bb247216fee40254822c2fb60a78a8ef21cOwen Taylor n_nodes = g_signal_key_bsa.n_nodes; 878300e3bb247216fee40254822c2fb60a78a8ef21cOwen Taylor result = g_array_new (FALSE, FALSE, sizeof (guint)); 879300e3bb247216fee40254822c2fb60a78a8ef21cOwen Taylor 880300e3bb247216fee40254822c2fb60a78a8ef21cOwen Taylor for (i = 0; i < n_nodes; i++) 88165c423b458d9fd1338cab0de7951092c09ab1686Tim Janik if (keys[i].itype == itype) 88265c423b458d9fd1338cab0de7951092c09ab1686Tim Janik { 88365c423b458d9fd1338cab0de7951092c09ab1686Tim Janik gchar *name = g_quark_to_string (keys[i].quark); 88483c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 88565c423b458d9fd1338cab0de7951092c09ab1686Tim Janik /* Signal names with "_" in them are aliases to the same 88665c423b458d9fd1338cab0de7951092c09ab1686Tim Janik * name with "-" instead of "_". 88765c423b458d9fd1338cab0de7951092c09ab1686Tim Janik */ 88865c423b458d9fd1338cab0de7951092c09ab1686Tim Janik if (!strchr (name, '_')) 88965c423b458d9fd1338cab0de7951092c09ab1686Tim Janik g_array_append_val (result, keys[i].signal_id); 89065c423b458d9fd1338cab0de7951092c09ab1686Tim Janik } 89183c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 892300e3bb247216fee40254822c2fb60a78a8ef21cOwen Taylor *n_ids = result->len; 89383c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 89465c423b458d9fd1338cab0de7951092c09ab1686Tim Janik G_UNLOCK (g_signal_mutex); 89565c423b458d9fd1338cab0de7951092c09ab1686Tim Janik 896300e3bb247216fee40254822c2fb60a78a8ef21cOwen Taylor return (guint *) g_array_free (result, FALSE); 897300e3bb247216fee40254822c2fb60a78a8ef21cOwen Taylor} 898300e3bb247216fee40254822c2fb60a78a8ef21cOwen Taylor 899ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikguint 900b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Penningtong_signal_new_valist (const gchar *signal_name, 901b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington GType itype, 902b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington GSignalFlags signal_flags, 903b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington GClosure *class_closure, 904b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington GSignalAccumulator accumulator, 905b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington GSignalCMarshaller c_marshaller, 906b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington GType return_type, 907b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington guint n_params, 908b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington va_list args) 909e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik{ 910e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik GType *param_types; 911e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik guint i; 912e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik guint signal_id; 913e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 914e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik if (n_params > 0) 915e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik { 916e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik param_types = g_new (GType, n_params); 917e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 918e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik for (i = 0; i < n_params; i++) 919e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik param_types[i] = va_arg (args, GType); 920e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik } 921e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik else 922e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik param_types = NULL; 923e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 924e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik signal_id = g_signal_newv (signal_name, itype, signal_flags, 925e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik class_closure, accumulator, c_marshaller, 926e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik return_type, n_params, param_types); 927e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_free (param_types); 928e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 929e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik return signal_id; 930e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik} 931e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 932e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janikguint 933b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Penningtong_signal_newc (const gchar *signal_name, 934b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington GType itype, 935b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington GSignalFlags signal_flags, 936b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington guint class_offset, 937b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington GSignalAccumulator accumulator, 938b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington GSignalCMarshaller c_marshaller, 939b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington GType return_type, 940b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington guint n_params, 941b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington ...) 942b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington{ 943b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington va_list args; 944b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington guint signal_id; 945b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington 946b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington g_return_val_if_fail (signal_name != NULL, 0); 947b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington 948b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington va_start (args, n_params); 949b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington 950b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington signal_id = g_signal_new_valist (signal_name, itype, signal_flags, 951b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington g_signal_type_cclosure_new (itype, 952b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington class_offset), 953b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington accumulator, c_marshaller, 954b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington return_type, n_params, args); 955b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington 956b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington va_end (args); 957b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington 958b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington return signal_id; 959b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington} 960b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington 961b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Penningtonguint 962ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikg_signal_newv (const gchar *signal_name, 963ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik GType itype, 964830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik GSignalFlags signal_flags, 965ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik GClosure *class_closure, 966ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik GSignalAccumulator accumulator, 967ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik GSignalCMarshaller c_marshaller, 968ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik GType return_type, 969ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik guint n_params, 970ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik GType *param_types) 971ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 972ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik gchar *name; 973ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik guint signal_id, i; 974ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik SignalNode *node; 975ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 976ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_return_val_if_fail (signal_name != NULL, 0); 977ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_return_val_if_fail (G_TYPE_IS_INSTANTIATABLE (itype) || G_TYPE_IS_INTERFACE (itype), 0); 978ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (n_params) 979ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_return_val_if_fail (param_types != NULL, 0); 980ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (return_type != G_TYPE_NONE) 981ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_return_val_if_fail (accumulator == NULL, 0); 982ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 983ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik name = g_strdup (signal_name); 984ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_strdelimit (name, G_STR_DELIMITERS ":^", '_'); // FIXME do character checks like for types 985ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 986ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_LOCK (g_signal_mutex); 987ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 9888a572c0da1be99527c52f620dc7fd04eb0775bdeTim Janik signal_id = signal_id_lookup (g_quark_try_string (name), itype); 989ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node = LOOKUP_SIGNAL_NODE (signal_id); 990ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (node && !node->destroyed) 991ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 992ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_warning (G_STRLOC ": signal \"%s\" already exists in the `%s' %s", 993ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik name, 994ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_type_name (node->itype), 995ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_TYPE_IS_INTERFACE (node->itype) ? "interface" : "class ancestry"); 996ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_free (name); 997ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_UNLOCK (g_signal_mutex); 998ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik return 0; 999ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 1000ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (node && node->itype != itype) 1001ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 1002ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_warning (G_STRLOC ": signal \"%s\" for type `%s' was previously created for type `%s'", 1003ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik name, 1004ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_type_name (itype), 1005ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_type_name (node->itype)); 1006ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_free (name); 1007ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_UNLOCK (g_signal_mutex); 1008ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik return 0; 1009ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 1010ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik for (i = 0; i < n_params; i++) 1011ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (!G_TYPE_IS_VALUE (param_types[i]) || 1012ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik param_types[i] == G_TYPE_ENUM || param_types[i] == G_TYPE_FLAGS) /* FIXME: kludge */ 1013ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 1014ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_warning (G_STRLOC ": parameter %d of type `%s' for signal \"%s::%s\" is not a value type", 1015ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik i + 1, g_type_name (param_types[i]), g_type_name (itype), name); 1016ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_free (name); 1017ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_UNLOCK (g_signal_mutex); 1018ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik return 0; 1019ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 1020ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (return_type != G_TYPE_NONE && !G_TYPE_IS_VALUE (return_type)) 1021ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 1022ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_warning (G_STRLOC ": return value of type `%s' for signal \"%s::%s\" is not a value type", 1023ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_type_name (param_types[i]), g_type_name (itype), name); 1024ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_free (name); 1025ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_UNLOCK (g_signal_mutex); 1026ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik return 0; 1027ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 1028ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1029ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik /* setup permanent portion of signal node */ 1030ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (!node) 1031ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 1032ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik SignalKey key; 1033ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1034ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik signal_id = g_n_signal_nodes++; 1035ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node = g_new (SignalNode, 1); 1036ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node->signal_id = signal_id; 1037ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_signal_nodes = g_renew (SignalNode*, g_signal_nodes, g_n_signal_nodes); 1038ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_signal_nodes[signal_id] = node; 1039ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node->itype = itype; 1040ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node->name = name; 1041ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik key.itype = itype; 1042ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik key.quark = g_quark_from_string (node->name); 1043ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik key.signal_id = signal_id; 1044ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_bsearch_array_insert (&g_signal_key_bsa, &key, FALSE); 1045ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_strdelimit (node->name, "_", '-'); 1046ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik key.quark = g_quark_from_static_string (node->name); 1047ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_bsearch_array_insert (&g_signal_key_bsa, &key, FALSE); 1048ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 1049ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node->destroyed = FALSE; 1050ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1051ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik /* setup reinitializable portion */ 1052830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik node->flags = signal_flags & G_SIGNAL_FLAGS_MASK; 1053ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node->n_params = n_params; 1054ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node->param_types = g_memdup (param_types, sizeof (GType) * n_params); 1055ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node->return_type = return_type; 1056ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node->class_closure = class_closure ? g_closure_ref (class_closure) : NULL; 1057ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node->accumulator = accumulator; 1058ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node->c_marshaller = c_marshaller; 1059ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node->emission_hooks = NULL; 1060ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (node->c_marshaller && class_closure && G_CLOSURE_NEEDS_MARSHAL (class_closure)) 1061ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_closure_set_marshal (class_closure, node->c_marshaller); 1062ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1063ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_UNLOCK (g_signal_mutex); 1064ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik return signal_id; 1065ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 1066ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1067ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikstatic void 1068ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janiksignal_destroy_R (SignalNode *signal_node) 1069ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 1070ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik SignalNode node = *signal_node; 1071ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1072ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik signal_node->destroyed = TRUE; 1073ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1074ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik /* reentrancy caution, zero out real contents first */ 1075ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik signal_node->n_params = 0; 1076ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik signal_node->param_types = NULL; 1077ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik signal_node->return_type = 0; 1078ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik signal_node->class_closure = NULL; 1079ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik signal_node->accumulator = NULL; 1080ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik signal_node->c_marshaller = NULL; 1081ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik signal_node->emission_hooks = NULL; 1082ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1083782a8e2e7c69c3d98bd69bcfdbb65ded520576f4Tim Janik#ifdef G_ENABLE_DEBUG 1084ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik /* check current emissions */ 1085ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 1086ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik Emission *emission; 1087ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1088ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik for (emission = (node.flags & G_SIGNAL_NO_RECURSE) ? g_restart_emissions : g_recursive_emissions; 1089ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik emission; emission = emission->next) 1090ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (emission->signal_id == node.signal_id) 1091ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_critical (G_STRLOC ": signal \"%s\" being destroyed is currently in emission (instance `%p')", 1092ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node.name, emission->instance); 1093ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 1094ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik#endif 1095ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1096ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik /* free contents that need to 1097ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik */ 1098ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_UNLOCK (g_signal_mutex); 1099ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_free (node.param_types); 1100ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_closure_unref (node.class_closure); 1101ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (node.emission_hooks) 1102ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 1103ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_hook_list_clear (node.emission_hooks); 1104ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_free (node.emission_hooks); 1105ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 1106ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_LOCK (g_signal_mutex); 1107ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 1108ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1109ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikguint 11103cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janikg_signal_connect_closure_by_id (gpointer instance, 11113cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik guint signal_id, 11123cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik GQuark detail, 11133cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik GClosure *closure, 11143cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik gboolean after) 1115ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 1116ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik SignalNode *node; 1117ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik guint handler_id = 0; 1118ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1119ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), 0); 1120ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_return_val_if_fail (signal_id > 0, 0); 1121ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_return_val_if_fail (closure != NULL, 0); 1122ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1123ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_LOCK (g_signal_mutex); 1124ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node = LOOKUP_SIGNAL_NODE (signal_id); 1125e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik if (node) 1126830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik { 1127e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik if (detail && !(node->flags & G_SIGNAL_DETAILED)) 1128e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_warning ("%s: signal id `%u' does not support detail (%u)", G_STRLOC, signal_id, detail); 1129e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik else if (!g_type_is_a (G_TYPE_FROM_INSTANCE (instance), node->itype)) 1130e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_warning ("%s: signal id `%u' is invalid for instance `%p'", G_STRLOC, signal_id, instance); 1131e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik else 1132e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik { 1133e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik Handler *handler = handler_new (after); 1134e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1135e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik handler_id = handler->id; 1136e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik handler->detail = detail; 1137e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik handler->closure = g_closure_ref (closure); 1138e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik handler_insert (signal_id, instance, handler); 1139e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik if (node->c_marshaller && G_CLOSURE_NEEDS_MARSHAL (closure)) 1140e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_closure_set_marshal (closure, node->c_marshaller); 1141e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik } 1142ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 1143ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik else 1144ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_warning ("%s: signal id `%u' is invalid for instance `%p'", G_STRLOC, signal_id, instance); 1145ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_UNLOCK (g_signal_mutex); 1146ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1147ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik return handler_id; 1148ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 1149ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1150e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janikguint 1151e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janikg_signal_connect_closure (gpointer instance, 1152e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik const gchar *detailed_signal, 1153e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik GClosure *closure, 1154e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik gboolean after) 1155e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik{ 1156e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik guint signal_id, handler_id = 0; 1157e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik GQuark detail = 0; 1158e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik GType itype; 1159e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1160e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), 0); 1161e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_return_val_if_fail (detailed_signal != NULL, 0); 1162e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_return_val_if_fail (closure != NULL, 0); 1163e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1164e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik G_LOCK (g_signal_mutex); 1165e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik itype = G_TYPE_FROM_INSTANCE (instance); 1166e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik signal_id = signal_parse_name (detailed_signal, itype, &detail, TRUE); 1167e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik if (signal_id) 1168e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik { 1169e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik SignalNode *node = LOOKUP_SIGNAL_NODE (signal_id); 1170e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1171e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik if (detail && !(node->flags & G_SIGNAL_DETAILED)) 1172e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_warning ("%s: signal `%s' does not support details", G_STRLOC, detailed_signal); 1173e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik else if (!g_type_is_a (itype, node->itype)) 1174e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_warning ("%s: signal `%s' is invalid for instance `%p'", G_STRLOC, detailed_signal, instance); 1175e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik else 1176e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik { 1177e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik Handler *handler = handler_new (after); 1178e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1179e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik handler_id = handler->id; 1180e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik handler->detail = detail; 1181e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik handler->closure = g_closure_ref (closure); 1182e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik handler_insert (signal_id, instance, handler); 1183e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik if (node->c_marshaller && G_CLOSURE_NEEDS_MARSHAL (handler->closure)) 1184e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_closure_set_marshal (handler->closure, node->c_marshaller); 1185e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik } 1186e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik } 1187e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik else 1188e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_warning ("%s: signal `%s' is invalid for instance `%p'", G_STRLOC, detailed_signal, instance); 1189e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik G_UNLOCK (g_signal_mutex); 1190e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1191e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik return handler_id; 1192e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik} 1193e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1194e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janikguint 1195e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janikg_signal_connect_data (gpointer instance, 1196e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik const gchar *detailed_signal, 1197e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik GCallback c_handler, 1198e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik gpointer data, 1199e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik GClosureNotify destroy_data, 1200e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik gboolean swapped, 1201e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik gboolean after) 1202e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik{ 1203e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik guint signal_id, handler_id = 0; 1204e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik GQuark detail = 0; 1205e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik GType itype; 1206e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1207e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), 0); 1208e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_return_val_if_fail (detailed_signal != NULL, 0); 1209e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_return_val_if_fail (c_handler != NULL, 0); 1210e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1211e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik G_LOCK (g_signal_mutex); 1212e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik itype = G_TYPE_FROM_INSTANCE (instance); 1213e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik signal_id = signal_parse_name (detailed_signal, itype, &detail, TRUE); 1214e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik if (signal_id) 1215e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik { 1216e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik SignalNode *node = LOOKUP_SIGNAL_NODE (signal_id); 1217e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1218e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik if (detail && !(node->flags & G_SIGNAL_DETAILED)) 1219e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_warning ("%s: signal `%s' does not support details", G_STRLOC, detailed_signal); 1220e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik else if (!g_type_is_a (itype, node->itype)) 1221e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_warning ("%s: signal `%s' is invalid for instance `%p'", G_STRLOC, detailed_signal, instance); 1222e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik else 1223e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik { 1224e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik Handler *handler = handler_new (after); 1225e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1226e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik handler_id = handler->id; 1227e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik handler->detail = detail; 1228e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik handler->closure = g_closure_ref ((swapped ? g_cclosure_new_swap : g_cclosure_new) (c_handler, data, destroy_data)); 1229e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik handler_insert (signal_id, instance, handler); 1230e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik if (node->c_marshaller && G_CLOSURE_NEEDS_MARSHAL (handler->closure)) 1231e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_closure_set_marshal (handler->closure, node->c_marshaller); 1232e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik } 1233e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik } 1234e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik else 1235e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_warning ("%s: signal `%s' is invalid for instance `%p'", G_STRLOC, detailed_signal, instance); 1236e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik G_UNLOCK (g_signal_mutex); 1237e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1238e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik return handler_id; 1239e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik} 1240e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1241ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikvoid 1242cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janikg_signal_handler_block (gpointer instance, 1243cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik guint handler_id) 1244cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik{ 1245cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik Handler *handler; 1246cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik 1247cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance)); 1248cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik g_return_if_fail (handler_id > 0); 1249cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik 1250cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik G_LOCK (g_signal_mutex); 1251cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik handler = handler_lookup (instance, handler_id, NULL); 1252cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik if (handler) 1253cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik { 1254cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik#ifndef G_DISABLE_CHECKS 1255cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik if (handler->block_count >= HANDLER_MAX_BLOCK_COUNT - 1) 1256cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik g_error (G_STRLOC ": handler block_count overflow, %s", REPORT_BUG); 1257cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik#endif 1258cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik 1259cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik handler->block_count += 1; 1260cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik } 1261cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik else 1262cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik g_warning ("%s: instance `%p' has no handler with id `%u'", G_STRLOC, instance, handler_id); 1263cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik G_UNLOCK (g_signal_mutex); 1264cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik} 1265cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik 1266cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janikvoid 1267cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janikg_signal_handler_unblock (gpointer instance, 1268cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik guint handler_id) 1269cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik{ 1270cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik Handler *handler; 1271cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik 1272cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance)); 1273cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik g_return_if_fail (handler_id > 0); 1274cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik 1275cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik G_LOCK (g_signal_mutex); 1276cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik handler = handler_lookup (instance, handler_id, NULL); 1277cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik if (handler) 1278cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik { 1279cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik if (handler->block_count) 1280cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik handler->block_count -= 1; 1281cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik else 1282cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik g_warning (G_STRLOC ": handler `%u' of instance `%p' is not blocked", handler_id, instance); 1283cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik } 1284cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik else 1285cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik g_warning ("%s: instance `%p' has no handler with id `%u'", G_STRLOC, instance, handler_id); 1286cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik G_UNLOCK (g_signal_mutex); 1287cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik} 1288cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik 1289cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janikvoid 1290ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikg_signal_handler_disconnect (gpointer instance, 1291ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik guint handler_id) 1292ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 1293ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik Handler *handler; 1294ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik guint signal_id; 1295ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1296ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance)); 1297ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_return_if_fail (handler_id > 0); 1298ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1299ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_LOCK (g_signal_mutex); 1300ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik handler = handler_lookup (instance, handler_id, &signal_id); 1301ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (handler) 1302ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 1303ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik handler->id = 0; 1304ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik handler->block_count = 1; 1305ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik handler_unref_R (signal_id, instance, handler); 1306ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 1307ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik else 1308ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_warning ("%s: instance `%p' has no handler with id `%u'", G_STRLOC, instance, handler_id); 1309ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_UNLOCK (g_signal_mutex); 1310ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 1311ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1312ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikvoid 131383c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janikg_signal_handlers_destroy (gpointer instance) 1314ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 1315ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik GBSearchArray *hlbsa; 1316ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1317ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance)); 1318ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1319ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_LOCK (g_signal_mutex); 1320ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik hlbsa = g_hash_table_lookup (g_handler_list_bsa_ht, instance); 1321ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (hlbsa) 1322ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 1323ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik guint i; 1324ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1325ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik /* reentrancy caution, delete instance trace first */ 1326ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_hash_table_remove (g_handler_list_bsa_ht, instance); 132783c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 1328ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik for (i = 0; i < hlbsa->n_nodes; i++) 1329ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 1330ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik HandlerList *hlist = g_bsearch_array_get_nth (hlbsa, i); 1331ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik Handler *handler = hlist->handlers; 1332ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1333ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik while (handler) 1334ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 1335ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik Handler *tmp = handler; 1336ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1337ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik handler = tmp->next; 1338ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik tmp->block_count = 1; 1339ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik /* cruel unlink, this works because _all_ handlers vanish */ 1340ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik tmp->next = NULL; 1341ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik tmp->prev = tmp; 1342ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (tmp->id) 1343ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 1344ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik tmp->id = 0; 1345ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik handler_unref_R (0, NULL, tmp); 1346ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 1347ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 1348ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 1349ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_free (hlbsa->nodes); 1350ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_generic_node_free (&g_bsa_ts, hlbsa); 1351ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 1352ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_UNLOCK (g_signal_mutex); 1353ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 1354ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1355cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janikguint 1356cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janikg_signal_handler_find (gpointer instance, 1357cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik GSignalMatchType mask, 1358cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik guint signal_id, 1359cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik GQuark detail, 1360cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik GClosure *closure, 1361cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik gpointer func, 1362cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik gpointer data) 1363ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 1364cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik guint handler_id = 0; 1365ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1366cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), 0); 1367cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik g_return_val_if_fail ((mask & ~G_SIGNAL_MATCH_MASK) == 0, 0); 136883c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 1369cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik if (mask & G_SIGNAL_MATCH_MASK) 1370ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 137183c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik HandlerMatch *mlist; 137283c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 1373cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik G_LOCK (g_signal_mutex); 137483c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik mlist = handlers_find (instance, mask, signal_id, detail, closure, func, data, TRUE); 137583c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik if (mlist) 137683c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik { 137783c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik handler_id = mlist->handler->id; 137883c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik handler_match_free1_R (mlist, instance); 137983c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik } 1380cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik G_UNLOCK (g_signal_mutex); 1381ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 138283c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 1383cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik return handler_id; 1384ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 1385ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1386cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janikstatic guint 138783c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janiksignal_handlers_foreach_matched_R (gpointer instance, 138883c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik GSignalMatchType mask, 138983c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik guint signal_id, 139083c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik GQuark detail, 139183c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik GClosure *closure, 139283c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik gpointer func, 139383c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik gpointer data, 139483c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik void (*callback) (gpointer instance, 139583c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik guint handler_id)) 1396ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 139783c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik HandlerMatch *mlist; 1398cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik guint n_handlers = 0; 139983c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 140083c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik mlist = handlers_find (instance, mask, signal_id, detail, closure, func, data, FALSE); 140183c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik while (mlist) 1402ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 1403cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik n_handlers++; 1404cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik G_UNLOCK (g_signal_mutex); 140583c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik callback (instance, mlist->handler->id); 1406cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik G_LOCK (g_signal_mutex); 140783c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik mlist = handler_match_free1_R (mlist, instance); 1408ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 140983c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 1410cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik return n_handlers; 1411ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 1412ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1413ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikguint 1414cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janikg_signal_handlers_block_matched (gpointer instance, 1415cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik GSignalMatchType mask, 1416cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik guint signal_id, 1417cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik GQuark detail, 1418cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik GClosure *closure, 1419cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik gpointer func, 1420cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik gpointer data) 1421ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 1422cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik guint n_handlers = 0; 142383c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 1424cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), FALSE); 1425cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik g_return_val_if_fail ((mask & ~G_SIGNAL_MATCH_MASK) == 0, FALSE); 142683c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 1427cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik if (mask & (G_SIGNAL_MATCH_CLOSURE | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA)) 1428cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik { 1429cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik G_LOCK (g_signal_mutex); 143083c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik n_handlers = signal_handlers_foreach_matched_R (instance, mask, signal_id, detail, 143183c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik closure, func, data, 143283c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik g_signal_handler_block); 1433cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik G_UNLOCK (g_signal_mutex); 1434cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik } 143583c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 1436cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik return n_handlers; 1437cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik} 1438cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik 1439cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janikguint 1440cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janikg_signal_handlers_unblock_matched (gpointer instance, 1441cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik GSignalMatchType mask, 1442cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik guint signal_id, 1443cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik GQuark detail, 1444cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik GClosure *closure, 1445cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik gpointer func, 1446cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik gpointer data) 1447cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik{ 1448cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik guint n_handlers = 0; 1449ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1450cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), FALSE); 1451cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik g_return_val_if_fail ((mask & ~G_SIGNAL_MATCH_MASK) == 0, FALSE); 1452ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1453cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik if (mask & (G_SIGNAL_MATCH_CLOSURE | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA)) 1454cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik { 1455cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik G_LOCK (g_signal_mutex); 145683c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik n_handlers = signal_handlers_foreach_matched_R (instance, mask, signal_id, detail, 145783c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik closure, func, data, 145883c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik g_signal_handler_unblock); 1459cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik G_UNLOCK (g_signal_mutex); 1460cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik } 146183c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 1462cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik return n_handlers; 1463cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik} 1464cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik 1465cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janikguint 1466cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janikg_signal_handlers_disconnect_matched (gpointer instance, 1467cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik GSignalMatchType mask, 1468cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik guint signal_id, 1469cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik GQuark detail, 1470cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik GClosure *closure, 1471cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik gpointer func, 1472cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik gpointer data) 1473cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik{ 1474cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik guint n_handlers = 0; 147583c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 1476cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), FALSE); 1477cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik g_return_val_if_fail ((mask & ~G_SIGNAL_MATCH_MASK) == 0, FALSE); 147883c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 1479cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik if (mask & (G_SIGNAL_MATCH_CLOSURE | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA)) 1480cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik { 1481cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik G_LOCK (g_signal_mutex); 148283c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik n_handlers = signal_handlers_foreach_matched_R (instance, mask, signal_id, detail, 148383c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik closure, func, data, 148483c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik g_signal_handler_disconnect); 1485cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik G_UNLOCK (g_signal_mutex); 1486cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik } 148783c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 1488cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik return n_handlers; 1489ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 1490ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1491ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikgboolean 1492cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janikg_signal_has_handler_pending (gpointer instance, 1493cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik guint signal_id, 1494cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik GQuark detail, 1495cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik gboolean may_be_blocked) 1496ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 149783c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik HandlerMatch *mlist; 149883c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik gboolean has_pending; 1499ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1500ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), FALSE); 1501ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_return_val_if_fail (signal_id > 0, FALSE); 1502ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1503ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_LOCK (g_signal_mutex); 1504830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik if (detail) 1505830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik { 1506830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik SignalNode *node = LOOKUP_SIGNAL_NODE (signal_id); 1507830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik 1508830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik if (!(node->flags & G_SIGNAL_DETAILED)) 1509830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik { 1510830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik g_warning ("%s: signal id `%u' does not support detail (%u)", G_STRLOC, signal_id, detail); 1511830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik G_UNLOCK (g_signal_mutex); 1512830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik return FALSE; 1513830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik } 1514830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik } 151583c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik mlist = handlers_find (instance, 151683c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik (G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_DETAIL | (may_be_blocked ? 0 : G_SIGNAL_MATCH_UNBLOCKED)), 151783c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik signal_id, detail, NULL, NULL, NULL, TRUE); 151883c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik if (mlist) 151983c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik { 152083c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik has_pending = TRUE; 152183c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik handler_match_free1_R (mlist, instance); 152283c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik } 152383c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik else 152483c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik has_pending = FALSE; 1525ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_UNLOCK (g_signal_mutex); 1526ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 152783c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik return has_pending; 1528ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 1529ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1530ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikvoid 1531ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikg_signal_emitv (const GValue *instance_and_params, 1532ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik guint signal_id, 1533830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik GQuark detail, 1534ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik GValue *return_value) 1535ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 1536ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik const GValue *param_values; 1537e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik gpointer instance; 1538e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik SignalNode *node; 1539ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik guint i; 1540ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1541ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_return_if_fail (instance_and_params != NULL); 1542ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik instance = g_value_get_as_pointer (instance_and_params); 1543ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance)); 1544ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_return_if_fail (signal_id > 0); 1545e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1546ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik param_values = instance_and_params + 1; 1547ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1548ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_LOCK (g_signal_mutex); 1549ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node = LOOKUP_SIGNAL_NODE (signal_id); 1550e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik if (!node || !g_type_is_a (G_TYPE_FROM_INSTANCE (instance), node->itype)) 1551cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik { 1552cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik g_warning ("%s: signal id `%u' is invalid for instance `%p'", G_STRLOC, signal_id, instance); 1553cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik G_UNLOCK (g_signal_mutex); 1554cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik return; 1555cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik } 1556782a8e2e7c69c3d98bd69bcfdbb65ded520576f4Tim Janik#ifdef G_ENABLE_DEBUG 1557830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik if (detail && !(node->flags & G_SIGNAL_DETAILED)) 1558830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik { 1559830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik g_warning ("%s: signal id `%u' does not support detail (%u)", G_STRLOC, signal_id, detail); 1560830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik G_UNLOCK (g_signal_mutex); 1561830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik return; 1562830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik } 1563ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik for (i = 0; i < node->n_params; i++) 1564ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (!G_VALUE_HOLDS (param_values + i, node->param_types[i])) 1565ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 1566e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_critical ("%s: value for `%s' parameter %u for signal \"%s\" is of type `%s'", 1567e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik G_STRLOC, 1568ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_type_name (node->param_types[i]), 1569ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik i, 1570ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node->name, 1571ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_VALUE_TYPE_NAME (param_values + i)); 1572ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_UNLOCK (g_signal_mutex); 1573ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik return; 1574ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 1575ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (node->return_type != G_TYPE_NONE) 1576ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 1577ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (!return_value) 1578ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 1579e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_critical ("%s: return value `%s' for signal \"%s\" is (NULL)", 1580e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik G_STRLOC, 1581ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_type_name (node->return_type), 1582ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node->name); 1583ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_UNLOCK (g_signal_mutex); 1584ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik return; 1585ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 1586ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik else if (!node->accumulator && !G_VALUE_HOLDS (return_value, node->return_type)) 1587ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 1588e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_critical ("%s: return value `%s' for signal \"%s\" is of type `%s'", 1589e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik G_STRLOC, 1590ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_type_name (node->return_type), 1591ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node->name, 1592ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_VALUE_TYPE_NAME (return_value)); 1593ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_UNLOCK (g_signal_mutex); 1594ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik return; 1595ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 1596ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 1597ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik else 1598ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik return_value = NULL; 1599782a8e2e7c69c3d98bd69bcfdbb65ded520576f4Tim Janik#endif /* G_ENABLE_DEBUG */ 1600e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1601830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik signal_emit_R (node, detail, instance, return_value, instance_and_params); 1602ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_UNLOCK (g_signal_mutex); 1603ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 1604ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1605e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janikvoid 1606e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janikg_signal_emit_valist (gpointer instance, 1607e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik guint signal_id, 1608e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik GQuark detail, 1609e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik va_list var_args) 1610e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik{ 1611e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik GValue *instance_and_params, stack_values[MAX_STACK_VALUES], *free_me = NULL; 1612e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik GValue *param_values; 1613e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik SignalNode *node; 1614e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik guint i; 1615e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1616e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance)); 1617e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_return_if_fail (signal_id > 0); 1618e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1619e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik G_LOCK (g_signal_mutex); 1620e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik node = LOOKUP_SIGNAL_NODE (signal_id); 1621e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik if (!node || !g_type_is_a (G_TYPE_FROM_INSTANCE (instance), node->itype)) 1622e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik { 1623e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_warning ("%s: signal id `%u' is invalid for instance `%p'", G_STRLOC, signal_id, instance); 1624e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik G_UNLOCK (g_signal_mutex); 1625e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik return; 1626e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik } 1627e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik#ifndef G_DISABLE_CHECKS 1628e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik if (detail && !(node->flags & G_SIGNAL_DETAILED)) 1629e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik { 1630e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_warning ("%s: signal id `%u' does not support detail (%u)", G_STRLOC, signal_id, detail); 1631e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik G_UNLOCK (g_signal_mutex); 1632e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik return; 1633e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik } 1634e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik#endif /* !G_DISABLE_CHECKS */ 1635e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1636e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik if (node->n_params < MAX_STACK_VALUES) 1637e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik instance_and_params = stack_values; 1638e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik else 1639e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik { 1640e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik free_me = g_new (GValue, node->n_params + 1); 1641e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik instance_and_params = free_me; 1642e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik } 1643e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik param_values = instance_and_params + 1; 1644e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik for (i = 0; i < node->n_params; i++) 1645e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik { 1646e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik gchar *error; 1647e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1648e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik param_values[i].g_type = 0; 1649e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_value_init (param_values + i, node->param_types[i]); 1650e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik G_VALUE_COLLECT (param_values + i, var_args, &error); 1651e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik if (error) 1652e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik { 1653e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_warning ("%s: %s", G_STRLOC, error); 1654e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_free (error); 1655e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1656e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik /* we purposely leak the value here, it might not be 1657e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik * in a sane state if an error condition occoured 1658e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik */ 1659e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik while (i--) 1660e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_value_unset (param_values + i); 1661e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1662e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik G_UNLOCK (g_signal_mutex); 1663e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_free (free_me); 1664e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik return; 1665e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik } 1666e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik } 1667e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik instance_and_params->g_type = 0; 1668e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_value_init (instance_and_params, node->itype); 1669e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_value_set_instance (instance_and_params, instance); 1670e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik if (node->return_type == G_TYPE_NONE) 1671e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik signal_emit_R (node, detail, instance, NULL, instance_and_params); 1672e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik else 1673e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik { 1674e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik GValue return_value = { 0, }; 1675e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik gchar *error = NULL; 1676e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1677e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_value_init (&return_value, node->return_type); 1678e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik if (signal_emit_R (node, detail, instance, &return_value, instance_and_params)) 1679e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik G_VALUE_LCOPY (&return_value, var_args, &error); 1680e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik if (!error) 1681e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_value_unset (&return_value); 1682e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik else 1683e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik { 1684e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_warning ("%s: %s", G_STRLOC, error); 1685e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_free (error); 1686e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1687e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik /* we purposely leak the value here, it might not be 1688e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik * in a sane state if an error condition occoured 1689e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik */ 1690e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik } 1691e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik } 1692e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik for (i = 0; i < node->n_params; i++) 1693e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_value_unset (param_values + i); 1694e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_value_unset (instance_and_params); 1695e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik if (free_me) 1696e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_free (free_me); 1697e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik G_UNLOCK (g_signal_mutex); 1698e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik} 1699e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1700e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janikvoid 1701e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janikg_signal_emit (gpointer instance, 1702e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik guint signal_id, 1703e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik GQuark detail, 1704e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik ...) 1705e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik{ 1706e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik va_list var_args; 1707e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1708e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik va_start (var_args, detail); 1709e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_signal_emit_valist (instance, signal_id, detail, var_args); 1710e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik va_end (var_args); 1711e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik} 1712e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1713e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janikvoid 1714e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janikg_signal_emit_by_name (gpointer instance, 1715e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik const gchar *detailed_signal, 1716e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik ...) 1717e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik{ 1718e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik GQuark detail = 0; 1719e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik guint signal_id; 1720e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1721e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance)); 1722e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_return_if_fail (detailed_signal != NULL); 1723e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1724e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik G_LOCK (g_signal_mutex); 1725e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik signal_id = signal_parse_name (detailed_signal, G_TYPE_FROM_INSTANCE (instance), &detail, TRUE); 1726e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik G_UNLOCK (g_signal_mutex); 1727e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1728e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik if (signal_id) 1729e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik { 1730e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik va_list var_args; 1731e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1732e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik va_start (var_args, detailed_signal); 1733e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_signal_emit_valist (instance, signal_id, detail, var_args); 1734e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik va_end (var_args); 1735e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik } 1736e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik else 1737e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_warning ("%s: signal name `%s' is invalid for instance `%p'", G_STRLOC, detailed_signal, instance); 1738e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik} 1739e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1740e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janikstatic gboolean 1741ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janiksignal_emit_R (SignalNode *node, 1742830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik GQuark detail, 1743ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik gpointer instance, 1744ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik GValue *return_value, 1745ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik const GValue *instance_and_params) 1746ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 1747ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik EmissionState emission_state = 0; 1748ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik GSignalAccumulator accumulator; 1749830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik GSignalInvocationHint ihint; 1750ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik GClosure *class_closure; 1751ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik HandlerList *hlist; 1752830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik Handler *handler_list = NULL; 1753e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik GValue accu = { 0, }; 1754ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik gboolean accu_used = FALSE; 1755ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik guint signal_id = node->signal_id; 1756e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik gboolean return_value_altered = FALSE; 1757ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1758ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (node->flags & G_SIGNAL_NO_RECURSE) 1759ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 1760830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik Emission *emission = emission_find (g_restart_emissions, signal_id, detail, instance); 1761ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1762ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (emission) 1763ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 1764ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik *emission->state_p = EMISSION_RESTART; 1765e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik return return_value_altered; 1766ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 1767ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 1768830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik ihint.signal_id = node->signal_id; 1769830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik ihint.detail = detail; 1770ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik accumulator = node->accumulator; 1771ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (accumulator) 1772e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_value_init (&accu, node->return_type); 1773ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik emission_push ((node->flags & G_SIGNAL_NO_RECURSE) ? &g_restart_emissions : &g_recursive_emissions, 1774830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik signal_id, detail, instance, &emission_state); 1775ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik class_closure = node->class_closure; 1776ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1777ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik EMIT_RESTART: 1778ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1779830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik if (handler_list) 1780830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik handler_unref_R (signal_id, instance, handler_list); 1781830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik hlist = handler_list_lookup (signal_id, instance); 1782830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik handler_list = hlist ? hlist->handlers : NULL; 1783830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik if (handler_list) 1784830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik handler_ref (handler_list); 1785830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik 1786830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik ihint.run_type = G_SIGNAL_RUN_FIRST; 1787830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik 1788ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if ((node->flags & G_SIGNAL_RUN_FIRST) && class_closure) 1789ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 1790ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik emission_state = EMISSION_RUN; 1791ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1792ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_UNLOCK (g_signal_mutex); 1793ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (accumulator) 1794ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 1795ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (accu_used) 1796ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_value_reset (&accu); 1797ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_closure_invoke (class_closure, 1798ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik &accu, 1799ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node->n_params + 1, 1800830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik instance_and_params, 1801830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik &ihint); 1802830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik if (!accumulator (&ihint, return_value, &accu) && 1803ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik emission_state == EMISSION_RUN) 1804ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik emission_state = EMISSION_STOP; 1805ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik accu_used = TRUE; 1806ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 1807ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik else 1808ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_closure_invoke (class_closure, 1809ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik return_value, 1810ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node->n_params + 1, 1811830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik instance_and_params, 1812830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik &ihint); 1813ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_LOCK (g_signal_mutex); 1814e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik return_value_altered = TRUE; 1815ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1816ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (emission_state == EMISSION_STOP) 1817ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik goto EMIT_CLEANUP; 1818ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik else if (emission_state == EMISSION_RESTART) 1819ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik goto EMIT_RESTART; 1820ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 1821ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1822ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (node->emission_hooks) 1823ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 1824ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik emission_state = EMISSION_HOOK; 1825ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1826ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_UNLOCK (g_signal_mutex); 1827ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_print ("emission_hooks()\n"); 1828ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_LOCK (g_signal_mutex); 1829ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1830ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (emission_state == EMISSION_RESTART) 1831ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik goto EMIT_RESTART; 1832ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 1833ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1834830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik if (handler_list) 1835ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 1836830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik Handler *handler = handler_list; 1837ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1838ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik emission_state = EMISSION_RUN; 1839ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik handler_ref (handler); 1840ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik do 1841ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 1842ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik Handler *tmp; 1843ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1844830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik if (handler->after) 1845830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik { 1846830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik handler_unref_R (signal_id, instance, handler_list); 1847830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik handler_list = handler; 1848830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik break; 1849830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik } 1850830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik else if (!handler->block_count && (!handler->detail || handler->detail == detail)) 1851ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 1852ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_UNLOCK (g_signal_mutex); 1853ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (accumulator) 1854ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 1855ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (accu_used) 1856ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_value_reset (&accu); 1857ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_closure_invoke (handler->closure, 1858ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik &accu, 1859ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node->n_params + 1, 1860830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik instance_and_params, 1861830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik &ihint); 1862830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik if (!accumulator (&ihint, return_value, &accu) && 1863ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik emission_state == EMISSION_RUN) 1864ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik emission_state = EMISSION_STOP; 1865ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik accu_used = TRUE; 1866ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 1867ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik else 1868ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_closure_invoke (handler->closure, 1869ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik return_value, 1870ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node->n_params + 1, 1871830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik instance_and_params, 1872830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik &ihint); 1873ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_LOCK (g_signal_mutex); 1874e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik return_value_altered = TRUE; 1875ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1876ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik tmp = emission_state == EMISSION_RUN ? handler->next : NULL; 1877ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 1878ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik else 1879ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik tmp = handler->next; 1880ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1881ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (tmp) 1882ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik handler_ref (tmp); 1883830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik handler_unref_R (signal_id, instance, handler_list); 1884830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik handler_list = handler; 1885ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik handler = tmp; 1886ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 1887ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik while (handler); 1888ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1889ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (emission_state == EMISSION_STOP) 1890ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik goto EMIT_CLEANUP; 1891ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik else if (emission_state == EMISSION_RESTART) 1892ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik goto EMIT_RESTART; 1893ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 1894ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1895830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik ihint.run_type = G_SIGNAL_RUN_LAST; 1896830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik 1897ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if ((node->flags & G_SIGNAL_RUN_LAST) && class_closure) 1898ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 1899ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik emission_state = EMISSION_RUN; 1900ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1901ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_UNLOCK (g_signal_mutex); 1902ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (accumulator) 1903ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 1904ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (accu_used) 1905ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_value_reset (&accu); 1906ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_closure_invoke (class_closure, 1907ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik &accu, 1908ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node->n_params + 1, 1909830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik instance_and_params, 1910830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik &ihint); 1911830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik if (!accumulator (&ihint, return_value, &accu) && 1912ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik emission_state == EMISSION_RUN) 1913ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik emission_state = EMISSION_STOP; 1914ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik accu_used = TRUE; 1915ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 1916ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik else 1917ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_closure_invoke (class_closure, 1918ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik return_value, 1919ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node->n_params + 1, 1920830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik instance_and_params, 1921830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik &ihint); 1922ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_LOCK (g_signal_mutex); 1923e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik return_value_altered = TRUE; 1924ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1925ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (emission_state == EMISSION_STOP) 1926ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik goto EMIT_CLEANUP; 1927ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik else if (emission_state == EMISSION_RESTART) 1928ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik goto EMIT_RESTART; 1929ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 1930ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1931830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik if (handler_list) 1932ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 1933830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik Handler *handler = handler_list; 1934ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1935ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik emission_state = EMISSION_RUN; 1936ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik handler_ref (handler); 1937ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik do 1938ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 1939ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik Handler *tmp; 1940ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1941830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik if (handler->after && !handler->block_count && (!handler->detail || handler->detail == detail)) 1942ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 1943ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_UNLOCK (g_signal_mutex); 1944ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (accumulator) 1945ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 1946ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (accu_used) 1947ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_value_reset (&accu); 1948ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_closure_invoke (handler->closure, 1949ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik &accu, 1950ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node->n_params + 1, 1951830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik instance_and_params, 1952830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik &ihint); 1953830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik if (!accumulator (&ihint, return_value, &accu) && 1954ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik emission_state == EMISSION_RUN) 1955ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik emission_state = EMISSION_STOP; 1956ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik accu_used = TRUE; 1957ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 1958ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik else 1959ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_closure_invoke (handler->closure, 1960ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik return_value, 1961ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node->n_params + 1, 1962830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik instance_and_params, 1963830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik &ihint); 1964ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_LOCK (g_signal_mutex); 1965e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik return_value_altered = TRUE; 1966ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1967ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik tmp = emission_state == EMISSION_RUN ? handler->next : NULL; 1968ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 1969ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik else 1970ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik tmp = handler->next; 1971ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1972ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (tmp) 1973ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik handler_ref (tmp); 1974ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik handler_unref_R (signal_id, instance, handler); 1975ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik handler = tmp; 1976ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 1977ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik while (handler); 1978ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1979ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (emission_state == EMISSION_STOP) 1980ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik goto EMIT_CLEANUP; 1981ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik else if (emission_state == EMISSION_RESTART) 1982ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik goto EMIT_RESTART; 1983ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 1984ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1985ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik EMIT_CLEANUP: 1986ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1987830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik ihint.run_type = G_SIGNAL_RUN_CLEANUP; 1988830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik 1989ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if ((node->flags & G_SIGNAL_RUN_CLEANUP) && class_closure) 1990ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 1991830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik gboolean need_unset = FALSE; 1992830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik 1993ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik emission_state = EMISSION_STOP; 1994ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1995ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_UNLOCK (g_signal_mutex); 1996ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (node->return_type != G_TYPE_NONE) 1997ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 1998ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (!accumulator) 1999830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik { 2000830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik g_value_init (&accu, node->return_type); 2001830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik need_unset = TRUE; 2002830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik } 2003ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik else if (accu_used) 2004ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_value_reset (&accu); 2005ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 2006ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_closure_invoke (class_closure, 2007ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node->return_type != G_TYPE_NONE ? &accu : NULL, 2008ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node->n_params + 1, 2009830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik instance_and_params, 2010830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik &ihint); 2011830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik if (need_unset) 2012ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_value_unset (&accu); 2013ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_LOCK (g_signal_mutex); 2014830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik 2015ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (emission_state == EMISSION_RESTART) 2016ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik goto EMIT_RESTART; 2017ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 2018ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 2019830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik if (handler_list) 2020830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik handler_unref_R (signal_id, instance, handler_list); 2021ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 2022830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik emission_pop ((node->flags & G_SIGNAL_NO_RECURSE) ? &g_restart_emissions : &g_recursive_emissions, &emission_state); 2023ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (accumulator) 2024e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_value_unset (&accu); 2025e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 2026e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik return return_value_altered; 2027ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 2028e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 2029e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 2030e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik/* compile standard marshallers */ 2031e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik#include "gvaluetypes.h" 2032e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik#include "gmarshal.c" 2033