gsignal.c revision f0b9abe801c2e0cccb7930421a81bb77031e3251
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 */ 22f0b9abe801c2e0cccb7930421a81bb77031e3251Tim Janik 23f0b9abe801c2e0cccb7930421a81bb77031e3251Tim Janik/* 24f0b9abe801c2e0cccb7930421a81bb77031e3251Tim Janik * MT safe 25f0b9abe801c2e0cccb7930421a81bb77031e3251Tim Janik */ 26fbe5df779cd39c9587f665118074ac828a805c26Owen Taylor 27ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik#include "gsignal.h" 28ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik#include "gbsearcharray.h" 29e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik#include "gvaluecollector.h" 30f0b9abe801c2e0cccb7930421a81bb77031e3251Tim Janik#include <string.h> 31ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 32ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 33ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik/* pre allocation configurations 34ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik */ 35e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik#define MAX_STACK_VALUES (16) 36ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik#define BSA_PRE_ALLOC (20) 37ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik#define HANDLER_PRE_ALLOC (48) 38ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik#define EMISSION_PRE_ALLOC (16) 39ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 40ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik#define REPORT_BUG "please report occourance circumstances to gtk-devel-list@gnome.org" 41ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 42ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 43ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik/* --- generic allocation --- */ 44782a8e2e7c69c3d98bd69bcfdbb65ded520576f4Tim Janik/* we special case allocations generically by replacing 45ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik * these functions with more speed/memory aware variants 46ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik */ 47782a8e2e7c69c3d98bd69bcfdbb65ded520576f4Tim Janik#ifndef DISABLE_MEM_POOLS 48ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikstatic inline gpointer 49ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikg_generic_node_alloc (GTrashStack **trash_stack_p, 50ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik guint sizeof_node, 51ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik guint nodes_pre_alloc) 52ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 53ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik gpointer node = g_trash_stack_pop (trash_stack_p); 54ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 55ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (!node) 56ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 57ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik guint8 *block; 58ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 59ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik nodes_pre_alloc = MAX (nodes_pre_alloc, 1); 60ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik block = g_malloc (sizeof_node * nodes_pre_alloc); 61ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik while (--nodes_pre_alloc) 62ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 63ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_trash_stack_push (trash_stack_p, block); 64ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik block += sizeof_node; 65ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 66ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node = block; 67ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 68ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 69ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik return node; 70ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 71f0b9abe801c2e0cccb7930421a81bb77031e3251Tim Janik#define g_generic_node_free(trash_stack_p, node) g_trash_stack_push (trash_stack_p, node) 72782a8e2e7c69c3d98bd69bcfdbb65ded520576f4Tim Janik#else /* !DISABLE_MEM_POOLS */ 73f0b9abe801c2e0cccb7930421a81bb77031e3251Tim Janik#define g_generic_node_alloc(t,sizeof_node,p) g_malloc (sizeof_node) 74f0b9abe801c2e0cccb7930421a81bb77031e3251Tim Janik#define g_generic_node_free(t,node) g_free (node) 75782a8e2e7c69c3d98bd69bcfdbb65ded520576f4Tim Janik#endif /* !DISABLE_MEM_POOLS */ 76ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 77ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 78ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik/* --- typedefs --- */ 7983c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janiktypedef struct _SignalNode SignalNode; 8083c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janiktypedef struct _SignalKey SignalKey; 8183c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janiktypedef struct _Emission Emission; 8283c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janiktypedef struct _Handler Handler; 8383c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janiktypedef struct _HandlerList HandlerList; 8483c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janiktypedef struct _HandlerMatch HandlerMatch; 85ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janiktypedef enum 86ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 87ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik EMISSION_STOP, 88ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik EMISSION_RUN, 89ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik EMISSION_HOOK, 90ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik EMISSION_RESTART 91ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} EmissionState; 92ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 93ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 94ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik/* --- prototypes --- */ 9583c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janikstatic inline guint signal_id_lookup (GQuark quark, 9683c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik GType itype); 9783c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janikstatic void signal_destroy_R (SignalNode *signal_node); 9883c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janikstatic inline HandlerList* handler_list_ensure (guint signal_id, 9983c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik gpointer instance); 10083c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janikstatic inline HandlerList* handler_list_lookup (guint signal_id, 10183c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik gpointer instance); 10283c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janikstatic inline Handler* handler_new (gboolean after); 10383c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janikstatic void handler_insert (guint signal_id, 10483c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik gpointer instance, 10583c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik Handler *handler); 10683c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janikstatic Handler* handler_lookup (gpointer instance, 10783c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik guint handler_id, 10883c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik guint *signal_id_p); 10983c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janikstatic inline HandlerMatch* handler_match_prepend (HandlerMatch *list, 11083c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik Handler *handler, 11183c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik guint signal_id); 11283c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janikstatic inline HandlerMatch* handler_match_free1_R (HandlerMatch *node, 11383c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik gpointer instance); 11483c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janikstatic HandlerMatch* handlers_find (gpointer instance, 11583c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik GSignalMatchType mask, 11683c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik guint signal_id, 11783c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik GQuark detail, 11883c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik GClosure *closure, 11983c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik gpointer func, 12083c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik gpointer data, 12183c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik gboolean one_and_only); 12283c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janikstatic inline void handler_ref (Handler *handler); 12383c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janikstatic inline void handler_unref_R (guint signal_id, 12483c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik gpointer instance, 12583c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik Handler *handler); 12683c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janikstatic inline void emission_push (Emission **emission_list_p, 12783c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik guint signal_id, 12883c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik GQuark detail, 12983c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik gpointer instance, 13083c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik EmissionState *state_p); 13183c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janikstatic inline void emission_pop (Emission **emission_list_p, 13283c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik EmissionState *state_p); 13383c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janikstatic inline Emission* emission_find (Emission *emission_list, 13483c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik guint signal_id, 13583c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik GQuark detail, 13683c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik gpointer instance); 137e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janikstatic gboolean signal_emit_R (SignalNode *node, 13883c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik GQuark detail, 13983c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik gpointer instance, 14083c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik GValue *return_value, 14183c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik const GValue *instance_and_params); 142ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 143ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 144ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik/* --- structures --- */ 145ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikstruct _SignalNode 146ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 147ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik /* permanent portion */ 148ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik guint signal_id; 149ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik GType itype; 150ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik gchar *name; 151ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik guint destroyed : 1; 152ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 153ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik /* reinitializable portion */ 154ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik guint flags : 8; 155ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik guint n_params : 8; 156ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik GType *param_types; 157ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik GType return_type; 158ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik GClosure *class_closure; 159ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik GSignalAccumulator accumulator; 160ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik GSignalCMarshaller c_marshaller; 161ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik GHookList *emission_hooks; 162ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik}; 163ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 164ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikstruct _SignalKey 165ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 166ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik GType itype; 167ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik GQuark quark; 168ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik guint signal_id; 169ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik}; 170ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 171ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikstruct _Emission 172ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 173ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik Emission *next; 174ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik guint signal_id; 175830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik GQuark detail; 176ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik gpointer instance; 177ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik EmissionState *state_p; 178ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik}; 179ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 180ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikstruct _HandlerList 181ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 182ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik guint signal_id; 183ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik Handler *handlers; 184ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik}; 185ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikstruct _Handler 186ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 187ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik guint id; 188ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik Handler *next; 189ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik Handler *prev; 190830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik GQuark detail; 191ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik guint ref_count : 16; 192ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik#define HANDLER_MAX_REF_COUNT (1 << 16) 193ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik guint block_count : 12; 194ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik#define HANDLER_MAX_BLOCK_COUNT (1 << 12) 195ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik guint after : 1; 196ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik GClosure *closure; 197ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik}; 19883c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janikstruct _HandlerMatch 19983c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik{ 20083c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik Handler *handler; 20183c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik HandlerMatch *next; 20283c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik union { 20383c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik guint signal_id; 20483c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik gpointer dummy; 20583c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik } d; 20683c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik}; 207ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 208ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 209ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik/* --- variables --- */ 210ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikstatic GBSearchArray g_signal_key_bsa = { NULL, 0, 0, 0, NULL }; 211ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikstatic GHashTable *g_handler_list_bsa_ht = NULL; 212ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikstatic Emission *g_recursive_emissions = NULL; 213ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikstatic Emission *g_restart_emissions = NULL; 214ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikstatic GTrashStack *g_bsa_ts = NULL; 215ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikstatic GTrashStack *g_handler_ts = NULL; 216ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikstatic GTrashStack *g_emission_ts = NULL; 217ee23c09e83d06a0d131ebd234c132f1c3602c019Tim JanikG_LOCK_DEFINE_STATIC (g_signal_mutex); 218ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 219ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 220ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik/* --- signal nodes --- */ 221ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikstatic guint g_n_signal_nodes = 0; 222ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikstatic SignalNode **g_signal_nodes = NULL; 223ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 224ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikstatic inline SignalNode* 225ee23c09e83d06a0d131ebd234c132f1c3602c019Tim JanikLOOKUP_SIGNAL_NODE (register guint signal_id) 226ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 227ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (signal_id < g_n_signal_nodes) 228ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik return g_signal_nodes[signal_id]; 229ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik else 230ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik return NULL; 231ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 232ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 233ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 234ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik/* --- functions --- */ 235ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikstatic inline guint 236ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janiksignal_id_lookup (GQuark quark, 237ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik GType itype) 238ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 239e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik GType *ifaces, type = itype; 240e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik SignalKey key; 241e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik guint n_ifaces; 242e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 243e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik key.quark = quark; 244e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 245e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik /* try looking up signals for this type and its anchestors */ 2468a572c0da1be99527c52f620dc7fd04eb0775bdeTim Janik do 2478a572c0da1be99527c52f620dc7fd04eb0775bdeTim Janik { 248e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik SignalKey *signal_key; 2498a572c0da1be99527c52f620dc7fd04eb0775bdeTim Janik 250e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik key.itype = type; 2518a572c0da1be99527c52f620dc7fd04eb0775bdeTim Janik signal_key = g_bsearch_array_lookup (&g_signal_key_bsa, &key); 2528a572c0da1be99527c52f620dc7fd04eb0775bdeTim Janik 2538a572c0da1be99527c52f620dc7fd04eb0775bdeTim Janik if (signal_key) 2548a572c0da1be99527c52f620dc7fd04eb0775bdeTim Janik return signal_key->signal_id; 2558a572c0da1be99527c52f620dc7fd04eb0775bdeTim Janik 256e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik type = g_type_parent (type); 2578a572c0da1be99527c52f620dc7fd04eb0775bdeTim Janik } 258e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik while (type); 259e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 260e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik /* no luck, try interfaces it exports */ 261e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik ifaces = g_type_interfaces (itype, &n_ifaces); 262e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik while (n_ifaces--) 263e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik { 264e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik SignalKey *signal_key; 265e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 266e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik key.itype = ifaces[n_ifaces]; 267e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik signal_key = g_bsearch_array_lookup (&g_signal_key_bsa, &key); 268e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 269e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik if (signal_key) 270e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik { 271e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_free (ifaces); 272e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik return signal_key->signal_id; 273e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik } 274e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik } 275e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_free (ifaces); 276ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 2778a572c0da1be99527c52f620dc7fd04eb0775bdeTim Janik return 0; 278ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 279ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 280ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikstatic gint 281ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikhandler_lists_cmp (gconstpointer node1, 282ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik gconstpointer node2) 283ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 284ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik const HandlerList *hlist1 = node1, *hlist2 = node2; 285ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 286ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik return G_BSEARCH_ARRAY_CMP (hlist1->signal_id, hlist2->signal_id); 287ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 288ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 289ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikstatic inline HandlerList* 290ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikhandler_list_ensure (guint signal_id, 291ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik gpointer instance) 292ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 293ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik GBSearchArray *hlbsa = g_hash_table_lookup (g_handler_list_bsa_ht, instance); 294ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik HandlerList key; 295ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 296ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (!hlbsa) 297ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 298ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik hlbsa = g_generic_node_alloc (&g_bsa_ts, 299ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik sizeof (GBSearchArray), 300ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik BSA_PRE_ALLOC); 301ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik hlbsa->cmp_func = handler_lists_cmp; 302ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik hlbsa->sizeof_node = sizeof (HandlerList); 303ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik hlbsa->flags = G_BSEARCH_DEFER_SHRINK; 304ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik hlbsa->n_nodes = 0; 305ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik hlbsa->nodes = NULL; 306ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_hash_table_insert (g_handler_list_bsa_ht, instance, hlbsa); 307ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 308ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik key.signal_id = signal_id; 309ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik key.handlers = NULL; 310ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 311ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik return g_bsearch_array_insert (hlbsa, &key, FALSE); 312ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 313ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 314ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikstatic inline HandlerList* 315ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikhandler_list_lookup (guint signal_id, 316ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik gpointer instance) 317ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 318ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik GBSearchArray *hlbsa = g_hash_table_lookup (g_handler_list_bsa_ht, instance); 319ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik HandlerList key; 320ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 321ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik key.signal_id = signal_id; 322ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 323ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik return hlbsa ? g_bsearch_array_lookup (hlbsa, &key) : NULL; 324ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 325ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 326ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikstatic Handler* 327ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikhandler_lookup (gpointer instance, 328ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik guint handler_id, 329ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik guint *signal_id_p) 330ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 331ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik GBSearchArray *hlbsa = g_hash_table_lookup (g_handler_list_bsa_ht, instance); 332ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 333ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (hlbsa) 334ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 335ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik guint i; 336ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 337ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik for (i = 0; i < hlbsa->n_nodes; i++) 338ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 339ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik HandlerList *hlist = g_bsearch_array_get_nth (hlbsa, i); 340ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik Handler *handler; 341ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 342ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik for (handler = hlist->handlers; handler; handler = handler->next) 343ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (handler->id == handler_id) 344ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 345ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (signal_id_p) 346ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik *signal_id_p = hlist->signal_id; 347ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 348ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik return handler; 349ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 350ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 351ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 352ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 353ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik return NULL; 354ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 355ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 35683c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janikstatic inline HandlerMatch* 35783c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janikhandler_match_prepend (HandlerMatch *list, 35883c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik Handler *handler, 35983c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik guint signal_id) 36083c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik{ 36183c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik HandlerMatch *node; 36283c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 36383c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik /* yeah, we could use our own memchunk here, introducing yet more 36483c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik * rarely used cached nodes and extra allocation overhead. 36583c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik * instead, we use GList* nodes, since they are exactly the size 36683c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik * we need and are already cached. g_signal_init() asserts this. 36783c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik */ 36883c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik node = (HandlerMatch*) g_list_alloc (); 36983c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik node->handler = handler; 37083c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik node->next = list; 37183c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik node->d.signal_id = signal_id; 37283c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik handler_ref (handler); 37383c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 37483c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik return node; 37583c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik} 37683c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janikstatic inline HandlerMatch* 37783c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janikhandler_match_free1_R (HandlerMatch *node, 37883c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik gpointer instance) 37983c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik{ 38083c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik HandlerMatch *next = node->next; 38183c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 38283c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik handler_unref_R (node->d.signal_id, instance, node->handler); 38383c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik g_list_free_1 ((GList*) node); 38483c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 38583c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik return next; 38683c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik} 38783c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 38883c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janikstatic HandlerMatch* 38983c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janikhandlers_find (gpointer instance, 39083c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik GSignalMatchType mask, 39183c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik guint signal_id, 39283c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik GQuark detail, 39383c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik GClosure *closure, 39483c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik gpointer func, 39583c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik gpointer data, 39683c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik gboolean one_and_only) 397ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 39883c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik HandlerMatch *mlist = NULL; 39983c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 400ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (mask & G_SIGNAL_MATCH_ID) 401ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 402ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik HandlerList *hlist = handler_list_lookup (signal_id, instance); 403ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik Handler *handler; 404790a7bd3be608d9b12a18711d4400490d96b2a46Elliot Lee SignalNode *node = NULL; 405ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 40655ec7f32a6852dba73abb29e650615b66b065ef9Tim Janik if (mask & G_SIGNAL_MATCH_FUNC) 407ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 408ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node = LOOKUP_SIGNAL_NODE (signal_id); 409ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (!node || !node->c_marshaller) 410ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik return NULL; 411ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 41283c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 413ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik mask = ~mask; 414ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik for (handler = hlist ? hlist->handlers : NULL; handler; handler = handler->next) 41583c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik if (handler->id && 41683c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik ((mask & G_SIGNAL_MATCH_DETAIL) || handler->detail == detail) && 417830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik ((mask & G_SIGNAL_MATCH_CLOSURE) || handler->closure == closure) && 418ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik ((mask & G_SIGNAL_MATCH_DATA) || handler->closure->data == data) && 419830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik ((mask & G_SIGNAL_MATCH_UNBLOCKED) || handler->block_count == 0) && 420ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik ((mask & G_SIGNAL_MATCH_FUNC) || (handler->closure->marshal == node->c_marshaller && 421ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik handler->closure->meta_marshal == 0 && 422ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik ((GCClosure*) handler->closure)->callback == func))) 42383c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik { 42483c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik mlist = handler_match_prepend (mlist, handler, signal_id); 42583c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik if (one_and_only) 42683c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik return mlist; 42783c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik } 428ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 429ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik else 430ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 431ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik GBSearchArray *hlbsa = g_hash_table_lookup (g_handler_list_bsa_ht, instance); 432ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 433ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik mask = ~mask; 434ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (hlbsa) 435ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 436ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik guint i; 437ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 438ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik for (i = 0; i < hlbsa->n_nodes; i++) 439ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 440ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik HandlerList *hlist = g_bsearch_array_get_nth (hlbsa, i); 441790a7bd3be608d9b12a18711d4400490d96b2a46Elliot Lee SignalNode *node = NULL; 442ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik Handler *handler; 443ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 444ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (!(mask & G_SIGNAL_MATCH_FUNC)) 445ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 446ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node = LOOKUP_SIGNAL_NODE (hlist->signal_id); 447ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (!node->c_marshaller) 448ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik continue; 449ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 45083c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 451ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik for (handler = hlist->handlers; handler; handler = handler->next) 45283c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik if (handler->id && 45383c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik ((mask & G_SIGNAL_MATCH_DETAIL) || handler->detail == detail) && 454830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik ((mask & G_SIGNAL_MATCH_CLOSURE) || handler->closure == closure) && 455ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik ((mask & G_SIGNAL_MATCH_DATA) || handler->closure->data == data) && 456830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik ((mask & G_SIGNAL_MATCH_UNBLOCKED) || handler->block_count == 0) && 457ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik ((mask & G_SIGNAL_MATCH_FUNC) || (handler->closure->marshal == node->c_marshaller && 458ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik handler->closure->meta_marshal == 0 && 459ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik ((GCClosure*) handler->closure)->callback == func))) 46083c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik { 461a453526f350a3956a26f71db481bd8b436c65f97Owen Taylor mlist = handler_match_prepend (mlist, handler, hlist->signal_id); 46283c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik if (one_and_only) 46383c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik return mlist; 46483c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik } 465ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 466ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 467ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 468ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 46983c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik return mlist; 470ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 471ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 472ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikstatic inline Handler* 473ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikhandler_new (gboolean after) 474ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 475ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik static guint handler_id = 1; 476ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik Handler *handler = g_generic_node_alloc (&g_handler_ts, 477ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik sizeof (Handler), 478ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik HANDLER_PRE_ALLOC); 479ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik#ifndef G_DISABLE_CHECKS 480ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (handler_id == 0) 481ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_error (G_STRLOC ": handler id overflow, %s", REPORT_BUG); 482ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik#endif 483ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 484ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik handler->id = handler_id++; 485ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik handler->prev = NULL; 486ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik handler->next = NULL; 487830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik handler->detail = 0; 488ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik handler->ref_count = 1; 489ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik handler->block_count = 0; 490ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik handler->after = after != FALSE; 491ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik handler->closure = NULL; 492ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 493ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik return handler; 494ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 495ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 496ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikstatic inline void 497ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikhandler_ref (Handler *handler) 498ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 499ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_return_if_fail (handler->ref_count > 0); 500ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 501ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik#ifndef G_DISABLE_CHECKS 502ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (handler->ref_count >= HANDLER_MAX_REF_COUNT - 1) 503ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_error (G_STRLOC ": handler ref_count overflow, %s", REPORT_BUG); 504ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik#endif 505ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 506ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik handler->ref_count += 1; 507ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 508ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 509ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikstatic inline void 510ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikhandler_unref_R (guint signal_id, 511ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik gpointer instance, 512ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik Handler *handler) 513ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 514ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_return_if_fail (handler->ref_count > 0); 515ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 516ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik handler->ref_count -= 1; 517ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (!handler->ref_count) 518ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 519ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (handler->next) 520ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik handler->next->prev = handler->prev; 52183c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik if (handler->prev) /* watch out for g_signal_handlers_destroy()! */ 522ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik handler->prev->next = handler->next; 523ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik else 524ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 525ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik HandlerList *hlist = handler_list_lookup (signal_id, instance); 526ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 527ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik hlist->handlers = handler->next; 528ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 529ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_UNLOCK (g_signal_mutex); 530ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_closure_unref (handler->closure); 531ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_LOCK (g_signal_mutex); 532ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_generic_node_free (&g_handler_ts, handler); 533ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 534ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 535ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 536ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikstatic void 537ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikhandler_insert (guint signal_id, 538ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik gpointer instance, 539ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik Handler *handler) 540ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 541ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik HandlerList *hlist; 542ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 543e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_assert (handler->prev == NULL && handler->next == NULL); /* paranoid */ 544ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 545ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik hlist = handler_list_ensure (signal_id, instance); 546ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (!hlist->handlers) 547ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik hlist->handlers = handler; 548ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik else if (hlist->handlers->after && !handler->after) 549ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 550ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik handler->next = hlist->handlers; 551ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik hlist->handlers->prev = handler; 552ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik hlist->handlers = handler; 553ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 554ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik else 555ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 556ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik Handler *tmp = hlist->handlers; 557ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 558ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (handler->after) 559ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik while (tmp->next) 560ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik tmp = tmp->next; 561ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik else 562ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik while (tmp->next && !tmp->next->after) 563ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik tmp = tmp->next; 564ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (tmp->next) 565ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik tmp->next->prev = handler; 566ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik handler->next = tmp->next; 567ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik handler->prev = tmp; 568ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik tmp->next = handler; 569ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 570ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 571ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 572ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikstatic inline void 573ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikemission_push (Emission **emission_list_p, 574ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik guint signal_id, 575830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik GQuark detail, 576ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik gpointer instance, 577ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik EmissionState *state_p) 578ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 579ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik Emission *emission = g_generic_node_alloc (&g_emission_ts, 580ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik sizeof (Emission), 581ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik EMISSION_PRE_ALLOC); 582ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik emission->next = *emission_list_p; 583ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik emission->signal_id = signal_id; 584830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik emission->detail = detail; 585ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik emission->instance = instance; 586ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik emission->state_p = state_p; 587ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik *emission_list_p = emission; 588ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 589ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 590ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikstatic inline void 591830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janikemission_pop (Emission **emission_list_p, 592830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik EmissionState *state_p) 593ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 594830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik Emission **loc = emission_list_p, *emission = *loc; 59583c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 596830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik while (emission->state_p != state_p) 597830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik { 598830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik loc = &emission->next; 599830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik emission = *loc; 600830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik } 601830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik *loc = emission->next; 602ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_generic_node_free (&g_emission_ts, emission); 603ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 604ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 605ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikstatic inline Emission* 606ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikemission_find (Emission *emission_list, 607ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik guint signal_id, 608830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik GQuark detail, 609ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik gpointer instance) 610ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 611ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik Emission *emission; 612ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 613ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik for (emission = emission_list; emission; emission = emission->next) 614830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik if (emission->instance == instance && 615830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik emission->signal_id == signal_id && 616830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik emission->detail == detail) 617ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik return emission; 618ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik return NULL; 619ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 620ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 621ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikstatic gint 622ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janiksignal_key_cmp (gconstpointer node1, 623ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik gconstpointer node2) 624ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 625ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik const SignalKey *key1 = node1, *key2 = node2; 626ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 627ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (key1->itype == key2->itype) 628ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik return G_BSEARCH_ARRAY_CMP (key1->quark, key2->quark); 629ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik else 630ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik return G_BSEARCH_ARRAY_CMP (key1->itype, key2->itype); 631ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 632ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 633ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikvoid 634ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikg_signal_init (void) /* sync with gtype.c */ 635ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 636ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_LOCK (g_signal_mutex); 637ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (!g_n_signal_nodes) 638ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 63983c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik /* handler_id_node_prepend() requires this */ 64083c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik g_assert (sizeof (GList) == sizeof (HandlerMatch)); 64183c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 642ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik /* setup signal key array */ 643ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_signal_key_bsa.cmp_func = signal_key_cmp; 644ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_signal_key_bsa.sizeof_node = sizeof (SignalKey); 645782a8e2e7c69c3d98bd69bcfdbb65ded520576f4Tim Janik g_signal_key_bsa.flags = G_BSEARCH_ALIGN_POWER2; /* alloc-only */ 646ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 647ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik /* setup handler list binary searchable array hash table (in german, that'd be one word ;) */ 648ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_handler_list_bsa_ht = g_hash_table_new (g_direct_hash, NULL); 649ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 650ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik /* invalid (0) signal_id */ 651ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_n_signal_nodes = 1; 652ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_signal_nodes = g_renew (SignalNode*, g_signal_nodes, g_n_signal_nodes); 653ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_signal_nodes[0] = NULL; 654ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 655ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_UNLOCK (g_signal_mutex); 656ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 657ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 658ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikvoid 6593cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik_g_signals_destroy (GType itype) 660ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 661ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik guint i; 662ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 663ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_LOCK (g_signal_mutex); 66483c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik for (i = 1; i < g_n_signal_nodes; i++) 665ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 666ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik SignalNode *node = g_signal_nodes[i]; 667ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 668ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (node->itype == itype) 669ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 670ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (node->destroyed) 671ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_warning (G_STRLOC ": signal \"%s\" of type `%s' already destroyed", 672ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node->name, 673ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_type_name (node->itype)); 674ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik else 675cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik signal_destroy_R (node); 676ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 677ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 678ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_UNLOCK (g_signal_mutex); 679ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 680ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 681ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikvoid 682ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikg_signal_stop_emission (gpointer instance, 683830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik guint signal_id, 684830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik GQuark detail) 685ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 686ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik SignalNode *node; 687ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 688ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance)); 689ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_return_if_fail (signal_id > 0); 690ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 691ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_LOCK (g_signal_mutex); 692ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node = LOOKUP_SIGNAL_NODE (signal_id); 693830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik if (node && detail && !(node->flags & G_SIGNAL_DETAILED)) 694830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik { 695830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik g_warning ("%s: signal id `%u' does not support detail (%u)", G_STRLOC, signal_id, detail); 696830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik G_UNLOCK (g_signal_mutex); 697830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik return; 698830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik } 699e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik if (node && g_type_is_a (G_TYPE_FROM_INSTANCE (instance), node->itype)) 700ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 701ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik Emission *emission_list = node->flags & G_SIGNAL_NO_RECURSE ? g_restart_emissions : g_recursive_emissions; 702830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik Emission *emission = emission_find (emission_list, signal_id, detail, instance); 703ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 704ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (emission) 705ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 706ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (*emission->state_p == EMISSION_HOOK) 707ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_warning (G_STRLOC ": emission of signal \"%s\" for instance `%p' cannot be stopped from emission hook", 708ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node->name, instance); 709ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik else if (*emission->state_p == EMISSION_RUN) 710ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik *emission->state_p = EMISSION_STOP; 711ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 712ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik else 713ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_warning (G_STRLOC ": no emission of signal \"%s\" to stop for instance `%p'", 714ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node->name, instance); 715ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 716ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik else 717ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_warning ("%s: signal id `%u' is invalid for instance `%p'", G_STRLOC, signal_id, instance); 718ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_UNLOCK (g_signal_mutex); 719ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 720ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 7213cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janikstatic inline guint 7223cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janiksignal_parse_name (const gchar *name, 7233cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik GType itype, 7243cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik GQuark *detail_p, 7253cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik gboolean force_quark) 7263cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik{ 7273cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik const gchar *colon = strchr (name, ':'); 7283cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik guint signal_id; 7293cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik 7303cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik if (!colon) 7313cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik { 7323cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik signal_id = signal_id_lookup (g_quark_try_string (name), itype); 7333cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik if (signal_id && detail_p) 7343cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik *detail_p = 0; 7353cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik } 7363cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik else if (colon[1] == ':') 7373cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik { 7383cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik gchar buffer[32]; 7393cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik guint l = colon - name; 7403cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik 7413cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik if (l < 32) 7423cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik { 7433cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik memcpy (buffer, name, l); 7443cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik buffer[l] = 0; 7453cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik signal_id = signal_id_lookup (g_quark_try_string (buffer), itype); 7463cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik } 7473cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik else 7483cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik { 7493cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik gchar *signal = g_new (gchar, l + 1); 7503cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik 7513cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik memcpy (signal, name, l); 7523cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik signal[l] = 0; 7533cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik signal_id = signal_id_lookup (g_quark_try_string (signal), itype); 7543cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik g_free (signal); 7553cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik } 7563cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik 7573cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik if (signal_id && detail_p) 7583cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik *detail_p = colon[2] ? (force_quark ? g_quark_from_string : g_quark_try_string) (colon + 2) : 0; 7593cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik } 7603cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik else 7613cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik signal_id = 0; 7623cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik return signal_id; 7633cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik} 7643cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik 7653cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janikgboolean 7663cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janikg_signal_parse_name (const gchar *detailed_signal, 7673cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik GType itype, 7683cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik guint *signal_id_p, 7693cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik GQuark *detail_p, 7703cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik gboolean force_detail_quark) 7713cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik{ 7723cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik GQuark detail = 0; 7733cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik guint signal_id; 77483c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 7753cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik g_return_val_if_fail (detailed_signal != NULL, FALSE); 7763cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik g_return_val_if_fail (G_TYPE_IS_INSTANTIATABLE (itype) || G_TYPE_IS_INTERFACE (itype), FALSE); 77783c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 7783cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik G_LOCK (g_signal_mutex); 7793cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik signal_id = signal_parse_name (detailed_signal, itype, &detail, force_detail_quark); 7803cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik G_UNLOCK (g_signal_mutex); 78183c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 7823cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik if (signal_id) 7833cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik { 7843cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik if (signal_id_p) 7853cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik *signal_id_p = signal_id; 7863cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik if (detail_p) 7873cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik *detail_p = detail; 78883c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 7893cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik return TRUE; 7903cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik } 7913cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik else 7923cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik return FALSE; 7933cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik} 7943cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik 795ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikguint 796ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikg_signal_lookup (const gchar *name, 797ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik GType itype) 798ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 7998a572c0da1be99527c52f620dc7fd04eb0775bdeTim Janik guint signal_id; 8008a572c0da1be99527c52f620dc7fd04eb0775bdeTim Janik 801ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_return_val_if_fail (name != NULL, 0); 802ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_return_val_if_fail (G_TYPE_IS_INSTANTIATABLE (itype) || G_TYPE_IS_INTERFACE (itype), 0); 803ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 804ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_LOCK (g_signal_mutex); 8058a572c0da1be99527c52f620dc7fd04eb0775bdeTim Janik signal_id = signal_id_lookup (g_quark_try_string (name), itype); 806ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_UNLOCK (g_signal_mutex); 807ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 8088a572c0da1be99527c52f620dc7fd04eb0775bdeTim Janik return signal_id; 809ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 810ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 811ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikgchar* 812ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikg_signal_name (guint signal_id) 813ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 814ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik SignalNode *node; 815ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik gchar *name; 81683c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 817ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_LOCK (g_signal_mutex); 818ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node = LOOKUP_SIGNAL_NODE (signal_id); 819ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik name = node ? node->name : NULL; 820ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_UNLOCK (g_signal_mutex); 821ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 822ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik return name; 823ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 824ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 825ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikvoid 826ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikg_signal_query (guint signal_id, 827ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik GSignalQuery *query) 828ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 829ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik SignalNode *node; 83083c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 831ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_return_if_fail (query != NULL); 83283c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 833ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_LOCK (g_signal_mutex); 834ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node = LOOKUP_SIGNAL_NODE (signal_id); 835ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (!node || node->destroyed) 836ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik query->signal_id = 0; 837ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik else 838ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 839ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik query->signal_id = node->signal_id; 840ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik query->signal_name = node->name; 841ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik query->itype = node->itype; 842ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik query->signal_flags = node->flags; 843ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik query->return_type = node->return_type; 844ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik query->n_params = node->n_params; 845ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik query->param_types = node->param_types; 846ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 847ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_UNLOCK (g_signal_mutex); 848ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 849ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 85065c423b458d9fd1338cab0de7951092c09ab1686Tim Janikguint* 85165c423b458d9fd1338cab0de7951092c09ab1686Tim Janikg_signal_list_ids (GType itype, 85265c423b458d9fd1338cab0de7951092c09ab1686Tim Janik guint *n_ids) 853300e3bb247216fee40254822c2fb60a78a8ef21cOwen Taylor{ 854300e3bb247216fee40254822c2fb60a78a8ef21cOwen Taylor SignalKey *keys; 855300e3bb247216fee40254822c2fb60a78a8ef21cOwen Taylor GArray *result; 85665c423b458d9fd1338cab0de7951092c09ab1686Tim Janik guint n_nodes; 85765c423b458d9fd1338cab0de7951092c09ab1686Tim Janik guint i; 85883c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 859300e3bb247216fee40254822c2fb60a78a8ef21cOwen Taylor g_return_val_if_fail (G_TYPE_IS_INSTANTIATABLE (itype) || G_TYPE_IS_INTERFACE (itype), NULL); 86065c423b458d9fd1338cab0de7951092c09ab1686Tim Janik g_return_val_if_fail (n_ids != NULL, NULL); 86183c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 86265c423b458d9fd1338cab0de7951092c09ab1686Tim Janik G_LOCK (g_signal_mutex); 86383c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 864300e3bb247216fee40254822c2fb60a78a8ef21cOwen Taylor keys = g_signal_key_bsa.nodes; 865300e3bb247216fee40254822c2fb60a78a8ef21cOwen Taylor n_nodes = g_signal_key_bsa.n_nodes; 866300e3bb247216fee40254822c2fb60a78a8ef21cOwen Taylor result = g_array_new (FALSE, FALSE, sizeof (guint)); 867300e3bb247216fee40254822c2fb60a78a8ef21cOwen Taylor 868300e3bb247216fee40254822c2fb60a78a8ef21cOwen Taylor for (i = 0; i < n_nodes; i++) 86965c423b458d9fd1338cab0de7951092c09ab1686Tim Janik if (keys[i].itype == itype) 87065c423b458d9fd1338cab0de7951092c09ab1686Tim Janik { 87165c423b458d9fd1338cab0de7951092c09ab1686Tim Janik gchar *name = g_quark_to_string (keys[i].quark); 87283c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 87365c423b458d9fd1338cab0de7951092c09ab1686Tim Janik /* Signal names with "_" in them are aliases to the same 87465c423b458d9fd1338cab0de7951092c09ab1686Tim Janik * name with "-" instead of "_". 87565c423b458d9fd1338cab0de7951092c09ab1686Tim Janik */ 87665c423b458d9fd1338cab0de7951092c09ab1686Tim Janik if (!strchr (name, '_')) 87765c423b458d9fd1338cab0de7951092c09ab1686Tim Janik g_array_append_val (result, keys[i].signal_id); 87865c423b458d9fd1338cab0de7951092c09ab1686Tim Janik } 87983c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 880300e3bb247216fee40254822c2fb60a78a8ef21cOwen Taylor *n_ids = result->len; 88183c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 88265c423b458d9fd1338cab0de7951092c09ab1686Tim Janik G_UNLOCK (g_signal_mutex); 88365c423b458d9fd1338cab0de7951092c09ab1686Tim Janik 884300e3bb247216fee40254822c2fb60a78a8ef21cOwen Taylor return (guint *) g_array_free (result, FALSE); 885300e3bb247216fee40254822c2fb60a78a8ef21cOwen Taylor} 886300e3bb247216fee40254822c2fb60a78a8ef21cOwen Taylor 887ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikguint 888b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Penningtong_signal_new_valist (const gchar *signal_name, 889b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington GType itype, 890b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington GSignalFlags signal_flags, 891b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington GClosure *class_closure, 892b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington GSignalAccumulator accumulator, 893b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington GSignalCMarshaller c_marshaller, 894b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington GType return_type, 895b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington guint n_params, 896b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington va_list args) 897e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik{ 898e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik GType *param_types; 899e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik guint i; 900e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik guint signal_id; 901e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 902e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik if (n_params > 0) 903e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik { 904e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik param_types = g_new (GType, n_params); 905e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 906e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik for (i = 0; i < n_params; i++) 907e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik param_types[i] = va_arg (args, GType); 908e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik } 909e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik else 910e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik param_types = NULL; 911e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 912e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik signal_id = g_signal_newv (signal_name, itype, signal_flags, 913e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik class_closure, accumulator, c_marshaller, 914e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik return_type, n_params, param_types); 915e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_free (param_types); 916e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 917e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik return signal_id; 918e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik} 919e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 920e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janikguint 921b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Penningtong_signal_newc (const gchar *signal_name, 922b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington GType itype, 923b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington GSignalFlags signal_flags, 924b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington guint class_offset, 925b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington GSignalAccumulator accumulator, 926b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington GSignalCMarshaller c_marshaller, 927b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington GType return_type, 928b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington guint n_params, 929b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington ...) 930b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington{ 931b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington va_list args; 932b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington guint signal_id; 933b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington 934b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington g_return_val_if_fail (signal_name != NULL, 0); 935b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington 936b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington va_start (args, n_params); 937b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington 938b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington signal_id = g_signal_new_valist (signal_name, itype, signal_flags, 939b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington g_signal_type_cclosure_new (itype, 940b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington class_offset), 941b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington accumulator, c_marshaller, 942b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington return_type, n_params, args); 943b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington 944b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington va_end (args); 945b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington 946b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington return signal_id; 947b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington} 948b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington 949b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Penningtonguint 950ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikg_signal_newv (const gchar *signal_name, 951ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik GType itype, 952830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik GSignalFlags signal_flags, 953ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik GClosure *class_closure, 954ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik GSignalAccumulator accumulator, 955ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik GSignalCMarshaller c_marshaller, 956ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik GType return_type, 957ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik guint n_params, 958ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik GType *param_types) 959ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 960ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik gchar *name; 961ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik guint signal_id, i; 962ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik SignalNode *node; 963ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 964ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_return_val_if_fail (signal_name != NULL, 0); 965ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_return_val_if_fail (G_TYPE_IS_INSTANTIATABLE (itype) || G_TYPE_IS_INTERFACE (itype), 0); 966ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (n_params) 967ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_return_val_if_fail (param_types != NULL, 0); 968ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (return_type != G_TYPE_NONE) 969ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_return_val_if_fail (accumulator == NULL, 0); 970ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 971ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik name = g_strdup (signal_name); 972ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_strdelimit (name, G_STR_DELIMITERS ":^", '_'); // FIXME do character checks like for types 973ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 974ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_LOCK (g_signal_mutex); 975ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 9768a572c0da1be99527c52f620dc7fd04eb0775bdeTim Janik signal_id = signal_id_lookup (g_quark_try_string (name), itype); 977ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node = LOOKUP_SIGNAL_NODE (signal_id); 978ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (node && !node->destroyed) 979ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 980ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_warning (G_STRLOC ": signal \"%s\" already exists in the `%s' %s", 981ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik name, 982ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_type_name (node->itype), 983ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_TYPE_IS_INTERFACE (node->itype) ? "interface" : "class ancestry"); 984ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_free (name); 985ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_UNLOCK (g_signal_mutex); 986ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik return 0; 987ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 988ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (node && node->itype != itype) 989ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 990ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_warning (G_STRLOC ": signal \"%s\" for type `%s' was previously created for type `%s'", 991ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik name, 992ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_type_name (itype), 993ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_type_name (node->itype)); 994ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_free (name); 995ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_UNLOCK (g_signal_mutex); 996ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik return 0; 997ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 998ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik for (i = 0; i < n_params; i++) 999ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (!G_TYPE_IS_VALUE (param_types[i]) || 1000ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik param_types[i] == G_TYPE_ENUM || param_types[i] == G_TYPE_FLAGS) /* FIXME: kludge */ 1001ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 1002ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_warning (G_STRLOC ": parameter %d of type `%s' for signal \"%s::%s\" is not a value type", 1003ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik i + 1, g_type_name (param_types[i]), g_type_name (itype), name); 1004ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_free (name); 1005ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_UNLOCK (g_signal_mutex); 1006ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik return 0; 1007ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 1008ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (return_type != G_TYPE_NONE && !G_TYPE_IS_VALUE (return_type)) 1009ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 1010ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_warning (G_STRLOC ": return value of type `%s' for signal \"%s::%s\" is not a value type", 1011ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_type_name (param_types[i]), g_type_name (itype), name); 1012ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_free (name); 1013ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_UNLOCK (g_signal_mutex); 1014ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik return 0; 1015ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 1016ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1017ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik /* setup permanent portion of signal node */ 1018ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (!node) 1019ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 1020ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik SignalKey key; 1021ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1022ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik signal_id = g_n_signal_nodes++; 1023ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node = g_new (SignalNode, 1); 1024ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node->signal_id = signal_id; 1025ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_signal_nodes = g_renew (SignalNode*, g_signal_nodes, g_n_signal_nodes); 1026ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_signal_nodes[signal_id] = node; 1027ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node->itype = itype; 1028ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node->name = name; 1029ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik key.itype = itype; 1030ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik key.quark = g_quark_from_string (node->name); 1031ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik key.signal_id = signal_id; 1032ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_bsearch_array_insert (&g_signal_key_bsa, &key, FALSE); 1033ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_strdelimit (node->name, "_", '-'); 1034ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik key.quark = g_quark_from_static_string (node->name); 1035ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_bsearch_array_insert (&g_signal_key_bsa, &key, FALSE); 1036ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 1037ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node->destroyed = FALSE; 1038ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1039ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik /* setup reinitializable portion */ 1040830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik node->flags = signal_flags & G_SIGNAL_FLAGS_MASK; 1041ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node->n_params = n_params; 1042ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node->param_types = g_memdup (param_types, sizeof (GType) * n_params); 1043ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node->return_type = return_type; 1044ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node->class_closure = class_closure ? g_closure_ref (class_closure) : NULL; 1045ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node->accumulator = accumulator; 1046ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node->c_marshaller = c_marshaller; 1047ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node->emission_hooks = NULL; 1048ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (node->c_marshaller && class_closure && G_CLOSURE_NEEDS_MARSHAL (class_closure)) 1049ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_closure_set_marshal (class_closure, node->c_marshaller); 1050ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1051ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_UNLOCK (g_signal_mutex); 1052ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik return signal_id; 1053ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 1054ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1055ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikstatic void 1056ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janiksignal_destroy_R (SignalNode *signal_node) 1057ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 1058ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik SignalNode node = *signal_node; 1059ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1060ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik signal_node->destroyed = TRUE; 1061ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1062ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik /* reentrancy caution, zero out real contents first */ 1063ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik signal_node->n_params = 0; 1064ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik signal_node->param_types = NULL; 1065ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik signal_node->return_type = 0; 1066ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik signal_node->class_closure = NULL; 1067ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik signal_node->accumulator = NULL; 1068ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik signal_node->c_marshaller = NULL; 1069ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik signal_node->emission_hooks = NULL; 1070ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1071782a8e2e7c69c3d98bd69bcfdbb65ded520576f4Tim Janik#ifdef G_ENABLE_DEBUG 1072ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik /* check current emissions */ 1073ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 1074ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik Emission *emission; 1075ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1076ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik for (emission = (node.flags & G_SIGNAL_NO_RECURSE) ? g_restart_emissions : g_recursive_emissions; 1077ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik emission; emission = emission->next) 1078ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (emission->signal_id == node.signal_id) 1079ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_critical (G_STRLOC ": signal \"%s\" being destroyed is currently in emission (instance `%p')", 1080ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node.name, emission->instance); 1081ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 1082ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik#endif 1083ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1084ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik /* free contents that need to 1085ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik */ 1086ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_UNLOCK (g_signal_mutex); 1087ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_free (node.param_types); 1088ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_closure_unref (node.class_closure); 1089ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (node.emission_hooks) 1090ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 1091ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_hook_list_clear (node.emission_hooks); 1092ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_free (node.emission_hooks); 1093ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 1094ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_LOCK (g_signal_mutex); 1095ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 1096ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1097ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikguint 10983cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janikg_signal_connect_closure_by_id (gpointer instance, 10993cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik guint signal_id, 11003cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik GQuark detail, 11013cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik GClosure *closure, 11023cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik gboolean after) 1103ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 1104ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik SignalNode *node; 1105ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik guint handler_id = 0; 1106ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1107ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), 0); 1108ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_return_val_if_fail (signal_id > 0, 0); 1109ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_return_val_if_fail (closure != NULL, 0); 1110ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1111ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_LOCK (g_signal_mutex); 1112ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node = LOOKUP_SIGNAL_NODE (signal_id); 1113e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik if (node) 1114830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik { 1115e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik if (detail && !(node->flags & G_SIGNAL_DETAILED)) 1116e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_warning ("%s: signal id `%u' does not support detail (%u)", G_STRLOC, signal_id, detail); 1117e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik else if (!g_type_is_a (G_TYPE_FROM_INSTANCE (instance), node->itype)) 1118e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_warning ("%s: signal id `%u' is invalid for instance `%p'", G_STRLOC, signal_id, instance); 1119e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik else 1120e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik { 1121e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik Handler *handler = handler_new (after); 1122e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1123e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik handler_id = handler->id; 1124e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik handler->detail = detail; 1125e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik handler->closure = g_closure_ref (closure); 1126e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik handler_insert (signal_id, instance, handler); 1127e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik if (node->c_marshaller && G_CLOSURE_NEEDS_MARSHAL (closure)) 1128e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_closure_set_marshal (closure, node->c_marshaller); 1129e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik } 1130ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 1131ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik else 1132ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_warning ("%s: signal id `%u' is invalid for instance `%p'", G_STRLOC, signal_id, instance); 1133ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_UNLOCK (g_signal_mutex); 1134ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1135ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik return handler_id; 1136ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 1137ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1138e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janikguint 1139e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janikg_signal_connect_closure (gpointer instance, 1140e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik const gchar *detailed_signal, 1141e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik GClosure *closure, 1142e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik gboolean after) 1143e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik{ 1144e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik guint signal_id, handler_id = 0; 1145e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik GQuark detail = 0; 1146e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik GType itype; 1147e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1148e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), 0); 1149e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_return_val_if_fail (detailed_signal != NULL, 0); 1150e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_return_val_if_fail (closure != NULL, 0); 1151e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1152e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik G_LOCK (g_signal_mutex); 1153e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik itype = G_TYPE_FROM_INSTANCE (instance); 1154e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik signal_id = signal_parse_name (detailed_signal, itype, &detail, TRUE); 1155e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik if (signal_id) 1156e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik { 1157e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik SignalNode *node = LOOKUP_SIGNAL_NODE (signal_id); 1158e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1159e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik if (detail && !(node->flags & G_SIGNAL_DETAILED)) 1160e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_warning ("%s: signal `%s' does not support details", G_STRLOC, detailed_signal); 1161e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik else if (!g_type_is_a (itype, node->itype)) 1162e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_warning ("%s: signal `%s' is invalid for instance `%p'", G_STRLOC, detailed_signal, instance); 1163e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik else 1164e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik { 1165e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik Handler *handler = handler_new (after); 1166e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1167e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik handler_id = handler->id; 1168e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik handler->detail = detail; 1169e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik handler->closure = g_closure_ref (closure); 1170e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik handler_insert (signal_id, instance, handler); 1171e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik if (node->c_marshaller && G_CLOSURE_NEEDS_MARSHAL (handler->closure)) 1172e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_closure_set_marshal (handler->closure, node->c_marshaller); 1173e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik } 1174e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik } 1175e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik else 1176e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_warning ("%s: signal `%s' is invalid for instance `%p'", G_STRLOC, detailed_signal, instance); 1177e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik G_UNLOCK (g_signal_mutex); 1178e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1179e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik return handler_id; 1180e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik} 1181e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1182e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janikguint 1183e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janikg_signal_connect_data (gpointer instance, 1184e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik const gchar *detailed_signal, 1185e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik GCallback c_handler, 1186e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik gpointer data, 1187e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik GClosureNotify destroy_data, 1188e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik gboolean swapped, 1189e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik gboolean after) 1190e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik{ 1191e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik guint signal_id, handler_id = 0; 1192e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik GQuark detail = 0; 1193e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik GType itype; 1194e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1195e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), 0); 1196e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_return_val_if_fail (detailed_signal != NULL, 0); 1197e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_return_val_if_fail (c_handler != NULL, 0); 1198e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1199e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik G_LOCK (g_signal_mutex); 1200e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik itype = G_TYPE_FROM_INSTANCE (instance); 1201e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik signal_id = signal_parse_name (detailed_signal, itype, &detail, TRUE); 1202e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik if (signal_id) 1203e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik { 1204e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik SignalNode *node = LOOKUP_SIGNAL_NODE (signal_id); 1205e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1206e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik if (detail && !(node->flags & G_SIGNAL_DETAILED)) 1207e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_warning ("%s: signal `%s' does not support details", G_STRLOC, detailed_signal); 1208e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik else if (!g_type_is_a (itype, node->itype)) 1209e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_warning ("%s: signal `%s' is invalid for instance `%p'", G_STRLOC, detailed_signal, instance); 1210e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik else 1211e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik { 1212e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik Handler *handler = handler_new (after); 1213e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1214e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik handler_id = handler->id; 1215e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik handler->detail = detail; 1216e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik handler->closure = g_closure_ref ((swapped ? g_cclosure_new_swap : g_cclosure_new) (c_handler, data, destroy_data)); 1217e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik handler_insert (signal_id, instance, handler); 1218e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik if (node->c_marshaller && G_CLOSURE_NEEDS_MARSHAL (handler->closure)) 1219e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_closure_set_marshal (handler->closure, node->c_marshaller); 1220e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik } 1221e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik } 1222e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik else 1223e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_warning ("%s: signal `%s' is invalid for instance `%p'", G_STRLOC, detailed_signal, instance); 1224e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik G_UNLOCK (g_signal_mutex); 1225e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1226e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik return handler_id; 1227e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik} 1228e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1229ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikvoid 1230cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janikg_signal_handler_block (gpointer instance, 1231cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik guint handler_id) 1232cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik{ 1233cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik Handler *handler; 1234cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik 1235cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance)); 1236cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik g_return_if_fail (handler_id > 0); 1237cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik 1238cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik G_LOCK (g_signal_mutex); 1239cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik handler = handler_lookup (instance, handler_id, NULL); 1240cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik if (handler) 1241cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik { 1242cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik#ifndef G_DISABLE_CHECKS 1243cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik if (handler->block_count >= HANDLER_MAX_BLOCK_COUNT - 1) 1244cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik g_error (G_STRLOC ": handler block_count overflow, %s", REPORT_BUG); 1245cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik#endif 1246cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik 1247cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik handler->block_count += 1; 1248cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik } 1249cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik else 1250cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik g_warning ("%s: instance `%p' has no handler with id `%u'", G_STRLOC, instance, handler_id); 1251cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik G_UNLOCK (g_signal_mutex); 1252cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik} 1253cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik 1254cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janikvoid 1255cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janikg_signal_handler_unblock (gpointer instance, 1256cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik guint handler_id) 1257cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik{ 1258cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik Handler *handler; 1259cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik 1260cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance)); 1261cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik g_return_if_fail (handler_id > 0); 1262cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik 1263cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik G_LOCK (g_signal_mutex); 1264cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik handler = handler_lookup (instance, handler_id, NULL); 1265cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik if (handler) 1266cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik { 1267cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik if (handler->block_count) 1268cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik handler->block_count -= 1; 1269cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik else 1270cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik g_warning (G_STRLOC ": handler `%u' of instance `%p' is not blocked", handler_id, instance); 1271cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik } 1272cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik else 1273cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik g_warning ("%s: instance `%p' has no handler with id `%u'", G_STRLOC, instance, handler_id); 1274cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik G_UNLOCK (g_signal_mutex); 1275cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik} 1276cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik 1277cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janikvoid 1278ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikg_signal_handler_disconnect (gpointer instance, 1279ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik guint handler_id) 1280ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 1281ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik Handler *handler; 1282ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik guint signal_id; 1283ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1284ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance)); 1285ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_return_if_fail (handler_id > 0); 1286ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1287ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_LOCK (g_signal_mutex); 1288ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik handler = handler_lookup (instance, handler_id, &signal_id); 1289ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (handler) 1290ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 1291ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik handler->id = 0; 1292ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik handler->block_count = 1; 1293ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik handler_unref_R (signal_id, instance, handler); 1294ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 1295ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik else 1296ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_warning ("%s: instance `%p' has no handler with id `%u'", G_STRLOC, instance, handler_id); 1297ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_UNLOCK (g_signal_mutex); 1298ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 1299ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1300ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikvoid 130183c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janikg_signal_handlers_destroy (gpointer instance) 1302ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 1303ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik GBSearchArray *hlbsa; 1304ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1305ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance)); 1306ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1307ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_LOCK (g_signal_mutex); 1308ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik hlbsa = g_hash_table_lookup (g_handler_list_bsa_ht, instance); 1309ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (hlbsa) 1310ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 1311ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik guint i; 1312ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1313ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik /* reentrancy caution, delete instance trace first */ 1314ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_hash_table_remove (g_handler_list_bsa_ht, instance); 131583c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 1316ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik for (i = 0; i < hlbsa->n_nodes; i++) 1317ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 1318ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik HandlerList *hlist = g_bsearch_array_get_nth (hlbsa, i); 1319ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik Handler *handler = hlist->handlers; 1320ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1321ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik while (handler) 1322ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 1323ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik Handler *tmp = handler; 1324ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1325ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik handler = tmp->next; 1326ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik tmp->block_count = 1; 1327ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik /* cruel unlink, this works because _all_ handlers vanish */ 1328ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik tmp->next = NULL; 1329ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik tmp->prev = tmp; 1330ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (tmp->id) 1331ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 1332ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik tmp->id = 0; 1333ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik handler_unref_R (0, NULL, tmp); 1334ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 1335ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 1336ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 1337ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_free (hlbsa->nodes); 1338ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_generic_node_free (&g_bsa_ts, hlbsa); 1339ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 1340ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_UNLOCK (g_signal_mutex); 1341ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 1342ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1343cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janikguint 1344cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janikg_signal_handler_find (gpointer instance, 1345cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik GSignalMatchType mask, 1346cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik guint signal_id, 1347cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik GQuark detail, 1348cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik GClosure *closure, 1349cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik gpointer func, 1350cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik gpointer data) 1351ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 1352cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik guint handler_id = 0; 1353ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1354cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), 0); 1355cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik g_return_val_if_fail ((mask & ~G_SIGNAL_MATCH_MASK) == 0, 0); 135683c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 1357cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik if (mask & G_SIGNAL_MATCH_MASK) 1358ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 135983c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik HandlerMatch *mlist; 136083c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 1361cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik G_LOCK (g_signal_mutex); 136283c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik mlist = handlers_find (instance, mask, signal_id, detail, closure, func, data, TRUE); 136383c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik if (mlist) 136483c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik { 136583c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik handler_id = mlist->handler->id; 136683c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik handler_match_free1_R (mlist, instance); 136783c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik } 1368cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik G_UNLOCK (g_signal_mutex); 1369ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 137083c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 1371cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik return handler_id; 1372ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 1373ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1374cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janikstatic guint 137583c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janiksignal_handlers_foreach_matched_R (gpointer instance, 137683c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik GSignalMatchType mask, 137783c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik guint signal_id, 137883c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik GQuark detail, 137983c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik GClosure *closure, 138083c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik gpointer func, 138183c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik gpointer data, 138283c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik void (*callback) (gpointer instance, 138383c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik guint handler_id)) 1384ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 138583c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik HandlerMatch *mlist; 1386cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik guint n_handlers = 0; 138783c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 138883c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik mlist = handlers_find (instance, mask, signal_id, detail, closure, func, data, FALSE); 138983c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik while (mlist) 1390ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 1391cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik n_handlers++; 1392cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik G_UNLOCK (g_signal_mutex); 139383c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik callback (instance, mlist->handler->id); 1394cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik G_LOCK (g_signal_mutex); 139583c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik mlist = handler_match_free1_R (mlist, instance); 1396ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 139783c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 1398cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik return n_handlers; 1399ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 1400ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1401ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikguint 1402cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janikg_signal_handlers_block_matched (gpointer instance, 1403cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik GSignalMatchType mask, 1404cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik guint signal_id, 1405cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik GQuark detail, 1406cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik GClosure *closure, 1407cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik gpointer func, 1408cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik gpointer data) 1409ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 1410cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik guint n_handlers = 0; 141183c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 1412cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), FALSE); 1413cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik g_return_val_if_fail ((mask & ~G_SIGNAL_MATCH_MASK) == 0, FALSE); 141483c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 1415cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik if (mask & (G_SIGNAL_MATCH_CLOSURE | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA)) 1416cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik { 1417cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik G_LOCK (g_signal_mutex); 141883c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik n_handlers = signal_handlers_foreach_matched_R (instance, mask, signal_id, detail, 141983c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik closure, func, data, 142083c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik g_signal_handler_block); 1421cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik G_UNLOCK (g_signal_mutex); 1422cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik } 142383c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 1424cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik return n_handlers; 1425cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik} 1426cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik 1427cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janikguint 1428cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janikg_signal_handlers_unblock_matched (gpointer instance, 1429cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik GSignalMatchType mask, 1430cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik guint signal_id, 1431cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik GQuark detail, 1432cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik GClosure *closure, 1433cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik gpointer func, 1434cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik gpointer data) 1435cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik{ 1436cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik guint n_handlers = 0; 1437ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1438cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), FALSE); 1439cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik g_return_val_if_fail ((mask & ~G_SIGNAL_MATCH_MASK) == 0, FALSE); 1440ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1441cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik if (mask & (G_SIGNAL_MATCH_CLOSURE | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA)) 1442cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik { 1443cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik G_LOCK (g_signal_mutex); 144483c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik n_handlers = signal_handlers_foreach_matched_R (instance, mask, signal_id, detail, 144583c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik closure, func, data, 144683c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik g_signal_handler_unblock); 1447cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik G_UNLOCK (g_signal_mutex); 1448cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik } 144983c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 1450cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik return n_handlers; 1451cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik} 1452cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik 1453cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janikguint 1454cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janikg_signal_handlers_disconnect_matched (gpointer instance, 1455cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik GSignalMatchType mask, 1456cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik guint signal_id, 1457cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik GQuark detail, 1458cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik GClosure *closure, 1459cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik gpointer func, 1460cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik gpointer data) 1461cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik{ 1462cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik guint n_handlers = 0; 146383c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 1464cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), FALSE); 1465cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik g_return_val_if_fail ((mask & ~G_SIGNAL_MATCH_MASK) == 0, FALSE); 146683c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 1467cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik if (mask & (G_SIGNAL_MATCH_CLOSURE | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA)) 1468cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik { 1469cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik G_LOCK (g_signal_mutex); 147083c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik n_handlers = signal_handlers_foreach_matched_R (instance, mask, signal_id, detail, 147183c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik closure, func, data, 147283c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik g_signal_handler_disconnect); 1473cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik G_UNLOCK (g_signal_mutex); 1474cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik } 147583c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 1476cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik return n_handlers; 1477ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 1478ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1479ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikgboolean 1480cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janikg_signal_has_handler_pending (gpointer instance, 1481cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik guint signal_id, 1482cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik GQuark detail, 1483cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik gboolean may_be_blocked) 1484ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 148583c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik HandlerMatch *mlist; 148683c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik gboolean has_pending; 1487ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1488ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), FALSE); 1489ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_return_val_if_fail (signal_id > 0, FALSE); 1490ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1491ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_LOCK (g_signal_mutex); 1492830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik if (detail) 1493830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik { 1494830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik SignalNode *node = LOOKUP_SIGNAL_NODE (signal_id); 1495830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik 1496830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik if (!(node->flags & G_SIGNAL_DETAILED)) 1497830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik { 1498830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik g_warning ("%s: signal id `%u' does not support detail (%u)", G_STRLOC, signal_id, detail); 1499830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik G_UNLOCK (g_signal_mutex); 1500830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik return FALSE; 1501830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik } 1502830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik } 150383c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik mlist = handlers_find (instance, 150483c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik (G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_DETAIL | (may_be_blocked ? 0 : G_SIGNAL_MATCH_UNBLOCKED)), 150583c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik signal_id, detail, NULL, NULL, NULL, TRUE); 150683c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik if (mlist) 150783c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik { 150883c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik has_pending = TRUE; 150983c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik handler_match_free1_R (mlist, instance); 151083c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik } 151183c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik else 151283c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik has_pending = FALSE; 1513ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_UNLOCK (g_signal_mutex); 1514ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 151583c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik return has_pending; 1516ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 1517ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1518ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikvoid 1519ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikg_signal_emitv (const GValue *instance_and_params, 1520ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik guint signal_id, 1521830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik GQuark detail, 1522ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik GValue *return_value) 1523ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 1524ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik const GValue *param_values; 1525e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik gpointer instance; 1526e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik SignalNode *node; 1527ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik guint i; 1528ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1529ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_return_if_fail (instance_and_params != NULL); 1530ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik instance = g_value_get_as_pointer (instance_and_params); 1531ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance)); 1532ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_return_if_fail (signal_id > 0); 1533e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1534ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik param_values = instance_and_params + 1; 1535ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1536ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_LOCK (g_signal_mutex); 1537ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node = LOOKUP_SIGNAL_NODE (signal_id); 1538e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik if (!node || !g_type_is_a (G_TYPE_FROM_INSTANCE (instance), node->itype)) 1539cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik { 1540cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik g_warning ("%s: signal id `%u' is invalid for instance `%p'", G_STRLOC, signal_id, instance); 1541cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik G_UNLOCK (g_signal_mutex); 1542cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik return; 1543cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik } 1544782a8e2e7c69c3d98bd69bcfdbb65ded520576f4Tim Janik#ifdef G_ENABLE_DEBUG 1545830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik if (detail && !(node->flags & G_SIGNAL_DETAILED)) 1546830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik { 1547830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik g_warning ("%s: signal id `%u' does not support detail (%u)", G_STRLOC, signal_id, detail); 1548830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik G_UNLOCK (g_signal_mutex); 1549830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik return; 1550830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik } 1551ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik for (i = 0; i < node->n_params; i++) 1552ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (!G_VALUE_HOLDS (param_values + i, node->param_types[i])) 1553ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 1554e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_critical ("%s: value for `%s' parameter %u for signal \"%s\" is of type `%s'", 1555e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik G_STRLOC, 1556ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_type_name (node->param_types[i]), 1557ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik i, 1558ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node->name, 1559ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_VALUE_TYPE_NAME (param_values + i)); 1560ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_UNLOCK (g_signal_mutex); 1561ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik return; 1562ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 1563ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (node->return_type != G_TYPE_NONE) 1564ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 1565ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (!return_value) 1566ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 1567e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_critical ("%s: return value `%s' for signal \"%s\" is (NULL)", 1568e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik G_STRLOC, 1569ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_type_name (node->return_type), 1570ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node->name); 1571ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_UNLOCK (g_signal_mutex); 1572ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik return; 1573ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 1574ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik else if (!node->accumulator && !G_VALUE_HOLDS (return_value, node->return_type)) 1575ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 1576e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_critical ("%s: return value `%s' for signal \"%s\" is of type `%s'", 1577e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik G_STRLOC, 1578ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_type_name (node->return_type), 1579ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node->name, 1580ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_VALUE_TYPE_NAME (return_value)); 1581ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_UNLOCK (g_signal_mutex); 1582ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik return; 1583ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 1584ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 1585ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik else 1586ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik return_value = NULL; 1587782a8e2e7c69c3d98bd69bcfdbb65ded520576f4Tim Janik#endif /* G_ENABLE_DEBUG */ 1588e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1589830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik signal_emit_R (node, detail, instance, return_value, instance_and_params); 1590ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_UNLOCK (g_signal_mutex); 1591ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 1592ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1593e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janikvoid 1594e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janikg_signal_emit_valist (gpointer instance, 1595e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik guint signal_id, 1596e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik GQuark detail, 1597e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik va_list var_args) 1598e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik{ 1599e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik GValue *instance_and_params, stack_values[MAX_STACK_VALUES], *free_me = NULL; 1600e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik GValue *param_values; 1601e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik SignalNode *node; 1602e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik guint i; 1603e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1604e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance)); 1605e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_return_if_fail (signal_id > 0); 1606e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1607e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik G_LOCK (g_signal_mutex); 1608e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik node = LOOKUP_SIGNAL_NODE (signal_id); 1609e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik if (!node || !g_type_is_a (G_TYPE_FROM_INSTANCE (instance), node->itype)) 1610e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik { 1611e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_warning ("%s: signal id `%u' is invalid for instance `%p'", G_STRLOC, signal_id, instance); 1612e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik G_UNLOCK (g_signal_mutex); 1613e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik return; 1614e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik } 1615e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik#ifndef G_DISABLE_CHECKS 1616e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik if (detail && !(node->flags & G_SIGNAL_DETAILED)) 1617e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik { 1618e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_warning ("%s: signal id `%u' does not support detail (%u)", G_STRLOC, signal_id, detail); 1619e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik G_UNLOCK (g_signal_mutex); 1620e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik return; 1621e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik } 1622e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik#endif /* !G_DISABLE_CHECKS */ 1623e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1624e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik if (node->n_params < MAX_STACK_VALUES) 1625e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik instance_and_params = stack_values; 1626e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik else 1627e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik { 1628e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik free_me = g_new (GValue, node->n_params + 1); 1629e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik instance_and_params = free_me; 1630e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik } 1631e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik param_values = instance_and_params + 1; 1632e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik for (i = 0; i < node->n_params; i++) 1633e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik { 1634e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik gchar *error; 1635e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1636e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik param_values[i].g_type = 0; 1637e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_value_init (param_values + i, node->param_types[i]); 1638e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik G_VALUE_COLLECT (param_values + i, var_args, &error); 1639e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik if (error) 1640e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik { 1641e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_warning ("%s: %s", G_STRLOC, error); 1642e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_free (error); 1643e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1644e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik /* we purposely leak the value here, it might not be 1645e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik * in a sane state if an error condition occoured 1646e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik */ 1647e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik while (i--) 1648e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_value_unset (param_values + i); 1649e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1650e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik G_UNLOCK (g_signal_mutex); 1651e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_free (free_me); 1652e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik return; 1653e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik } 1654e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik } 1655e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik instance_and_params->g_type = 0; 1656e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_value_init (instance_and_params, node->itype); 1657e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_value_set_instance (instance_and_params, instance); 1658e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik if (node->return_type == G_TYPE_NONE) 1659e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik signal_emit_R (node, detail, instance, NULL, instance_and_params); 1660e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik else 1661e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik { 1662e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik GValue return_value = { 0, }; 1663e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik gchar *error = NULL; 1664e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1665e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_value_init (&return_value, node->return_type); 1666e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik if (signal_emit_R (node, detail, instance, &return_value, instance_and_params)) 1667e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik G_VALUE_LCOPY (&return_value, var_args, &error); 1668e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik if (!error) 1669e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_value_unset (&return_value); 1670e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik else 1671e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik { 1672e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_warning ("%s: %s", G_STRLOC, error); 1673e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_free (error); 1674e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1675e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik /* we purposely leak the value here, it might not be 1676e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik * in a sane state if an error condition occoured 1677e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik */ 1678e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik } 1679e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik } 1680e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik for (i = 0; i < node->n_params; i++) 1681e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_value_unset (param_values + i); 1682e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_value_unset (instance_and_params); 1683e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik if (free_me) 1684e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_free (free_me); 1685e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik G_UNLOCK (g_signal_mutex); 1686e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik} 1687e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1688e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janikvoid 1689e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janikg_signal_emit (gpointer instance, 1690e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik guint signal_id, 1691e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik GQuark detail, 1692e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik ...) 1693e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik{ 1694e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik va_list var_args; 1695e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1696e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik va_start (var_args, detail); 1697e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_signal_emit_valist (instance, signal_id, detail, var_args); 1698e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik va_end (var_args); 1699e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik} 1700e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1701e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janikvoid 1702e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janikg_signal_emit_by_name (gpointer instance, 1703e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik const gchar *detailed_signal, 1704e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik ...) 1705e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik{ 1706e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik GQuark detail = 0; 1707e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik guint signal_id; 1708e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1709e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance)); 1710e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_return_if_fail (detailed_signal != NULL); 1711e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1712e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik G_LOCK (g_signal_mutex); 1713e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik signal_id = signal_parse_name (detailed_signal, G_TYPE_FROM_INSTANCE (instance), &detail, TRUE); 1714e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik G_UNLOCK (g_signal_mutex); 1715e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1716e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik if (signal_id) 1717e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik { 1718e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik va_list var_args; 1719e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1720e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik va_start (var_args, detailed_signal); 1721e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_signal_emit_valist (instance, signal_id, detail, var_args); 1722e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik va_end (var_args); 1723e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik } 1724e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik else 1725e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_warning ("%s: signal name `%s' is invalid for instance `%p'", G_STRLOC, detailed_signal, instance); 1726e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik} 1727e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1728e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janikstatic gboolean 1729ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janiksignal_emit_R (SignalNode *node, 1730830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik GQuark detail, 1731ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik gpointer instance, 1732ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik GValue *return_value, 1733ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik const GValue *instance_and_params) 1734ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 1735ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik EmissionState emission_state = 0; 1736ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik GSignalAccumulator accumulator; 1737830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik GSignalInvocationHint ihint; 1738ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik GClosure *class_closure; 1739ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik HandlerList *hlist; 1740830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik Handler *handler_list = NULL; 1741e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik GValue accu = { 0, }; 1742ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik gboolean accu_used = FALSE; 1743ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik guint signal_id = node->signal_id; 1744e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik gboolean return_value_altered = FALSE; 1745ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1746ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (node->flags & G_SIGNAL_NO_RECURSE) 1747ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 1748830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik Emission *emission = emission_find (g_restart_emissions, signal_id, detail, instance); 1749ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1750ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (emission) 1751ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 1752ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik *emission->state_p = EMISSION_RESTART; 1753e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik return return_value_altered; 1754ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 1755ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 1756830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik ihint.signal_id = node->signal_id; 1757830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik ihint.detail = detail; 1758ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik accumulator = node->accumulator; 1759ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (accumulator) 1760e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_value_init (&accu, node->return_type); 1761ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik emission_push ((node->flags & G_SIGNAL_NO_RECURSE) ? &g_restart_emissions : &g_recursive_emissions, 1762830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik signal_id, detail, instance, &emission_state); 1763ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik class_closure = node->class_closure; 1764ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1765ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik EMIT_RESTART: 1766ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1767830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik if (handler_list) 1768830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik handler_unref_R (signal_id, instance, handler_list); 1769830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik hlist = handler_list_lookup (signal_id, instance); 1770830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik handler_list = hlist ? hlist->handlers : NULL; 1771830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik if (handler_list) 1772830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik handler_ref (handler_list); 1773830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik 1774830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik ihint.run_type = G_SIGNAL_RUN_FIRST; 1775830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik 1776ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if ((node->flags & G_SIGNAL_RUN_FIRST) && class_closure) 1777ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 1778ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik emission_state = EMISSION_RUN; 1779ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1780ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_UNLOCK (g_signal_mutex); 1781ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (accumulator) 1782ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 1783ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (accu_used) 1784ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_value_reset (&accu); 1785ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_closure_invoke (class_closure, 1786ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik &accu, 1787ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node->n_params + 1, 1788830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik instance_and_params, 1789830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik &ihint); 1790830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik if (!accumulator (&ihint, return_value, &accu) && 1791ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik emission_state == EMISSION_RUN) 1792ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik emission_state = EMISSION_STOP; 1793ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik accu_used = TRUE; 1794ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 1795ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik else 1796ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_closure_invoke (class_closure, 1797ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik return_value, 1798ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node->n_params + 1, 1799830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik instance_and_params, 1800830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik &ihint); 1801ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_LOCK (g_signal_mutex); 1802e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik return_value_altered = TRUE; 1803ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1804ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (emission_state == EMISSION_STOP) 1805ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik goto EMIT_CLEANUP; 1806ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik else if (emission_state == EMISSION_RESTART) 1807ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik goto EMIT_RESTART; 1808ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 1809ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1810ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (node->emission_hooks) 1811ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 1812ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik emission_state = EMISSION_HOOK; 1813ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1814ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_UNLOCK (g_signal_mutex); 1815ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_print ("emission_hooks()\n"); 1816ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_LOCK (g_signal_mutex); 1817ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1818ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (emission_state == EMISSION_RESTART) 1819ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik goto EMIT_RESTART; 1820ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 1821ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1822830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik if (handler_list) 1823ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 1824830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik Handler *handler = handler_list; 1825ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1826ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik emission_state = EMISSION_RUN; 1827ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik handler_ref (handler); 1828ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik do 1829ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 1830ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik Handler *tmp; 1831ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1832830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik if (handler->after) 1833830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik { 1834830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik handler_unref_R (signal_id, instance, handler_list); 1835830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik handler_list = handler; 1836830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik break; 1837830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik } 1838830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik else if (!handler->block_count && (!handler->detail || handler->detail == detail)) 1839ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 1840ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_UNLOCK (g_signal_mutex); 1841ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (accumulator) 1842ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 1843ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (accu_used) 1844ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_value_reset (&accu); 1845ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_closure_invoke (handler->closure, 1846ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik &accu, 1847ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node->n_params + 1, 1848830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik instance_and_params, 1849830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik &ihint); 1850830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik if (!accumulator (&ihint, return_value, &accu) && 1851ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik emission_state == EMISSION_RUN) 1852ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik emission_state = EMISSION_STOP; 1853ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik accu_used = TRUE; 1854ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 1855ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik else 1856ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_closure_invoke (handler->closure, 1857ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik return_value, 1858ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node->n_params + 1, 1859830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik instance_and_params, 1860830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik &ihint); 1861ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_LOCK (g_signal_mutex); 1862e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik return_value_altered = TRUE; 1863ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1864ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik tmp = emission_state == EMISSION_RUN ? handler->next : NULL; 1865ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 1866ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik else 1867ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik tmp = handler->next; 1868ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1869ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (tmp) 1870ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik handler_ref (tmp); 1871830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik handler_unref_R (signal_id, instance, handler_list); 1872830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik handler_list = handler; 1873ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik handler = tmp; 1874ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 1875ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik while (handler); 1876ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1877ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (emission_state == EMISSION_STOP) 1878ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik goto EMIT_CLEANUP; 1879ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik else if (emission_state == EMISSION_RESTART) 1880ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik goto EMIT_RESTART; 1881ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 1882ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1883830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik ihint.run_type = G_SIGNAL_RUN_LAST; 1884830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik 1885ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if ((node->flags & G_SIGNAL_RUN_LAST) && class_closure) 1886ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 1887ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik emission_state = EMISSION_RUN; 1888ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1889ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_UNLOCK (g_signal_mutex); 1890ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (accumulator) 1891ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 1892ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (accu_used) 1893ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_value_reset (&accu); 1894ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_closure_invoke (class_closure, 1895ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik &accu, 1896ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node->n_params + 1, 1897830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik instance_and_params, 1898830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik &ihint); 1899830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik if (!accumulator (&ihint, return_value, &accu) && 1900ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik emission_state == EMISSION_RUN) 1901ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik emission_state = EMISSION_STOP; 1902ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik accu_used = TRUE; 1903ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 1904ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik else 1905ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_closure_invoke (class_closure, 1906ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik return_value, 1907ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node->n_params + 1, 1908830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik instance_and_params, 1909830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik &ihint); 1910ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_LOCK (g_signal_mutex); 1911e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik return_value_altered = TRUE; 1912ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1913ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (emission_state == EMISSION_STOP) 1914ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik goto EMIT_CLEANUP; 1915ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik else if (emission_state == EMISSION_RESTART) 1916ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik goto EMIT_RESTART; 1917ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 1918ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1919830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik if (handler_list) 1920ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 1921830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik Handler *handler = handler_list; 1922ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1923ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik emission_state = EMISSION_RUN; 1924ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik handler_ref (handler); 1925ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik do 1926ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 1927ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik Handler *tmp; 1928ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1929830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik if (handler->after && !handler->block_count && (!handler->detail || handler->detail == detail)) 1930ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 1931ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_UNLOCK (g_signal_mutex); 1932ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (accumulator) 1933ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 1934ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (accu_used) 1935ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_value_reset (&accu); 1936ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_closure_invoke (handler->closure, 1937ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik &accu, 1938ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node->n_params + 1, 1939830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik instance_and_params, 1940830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik &ihint); 1941830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik if (!accumulator (&ihint, return_value, &accu) && 1942ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik emission_state == EMISSION_RUN) 1943ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik emission_state = EMISSION_STOP; 1944ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik accu_used = TRUE; 1945ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 1946ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik else 1947ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_closure_invoke (handler->closure, 1948ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik return_value, 1949ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node->n_params + 1, 1950830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik instance_and_params, 1951830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik &ihint); 1952ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_LOCK (g_signal_mutex); 1953e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik return_value_altered = TRUE; 1954ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1955ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik tmp = emission_state == EMISSION_RUN ? handler->next : NULL; 1956ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 1957ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik else 1958ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik tmp = handler->next; 1959ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1960ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (tmp) 1961ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik handler_ref (tmp); 1962ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik handler_unref_R (signal_id, instance, handler); 1963ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik handler = tmp; 1964ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 1965ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik while (handler); 1966ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1967ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (emission_state == EMISSION_STOP) 1968ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik goto EMIT_CLEANUP; 1969ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik else if (emission_state == EMISSION_RESTART) 1970ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik goto EMIT_RESTART; 1971ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 1972ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1973ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik EMIT_CLEANUP: 1974ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1975830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik ihint.run_type = G_SIGNAL_RUN_CLEANUP; 1976830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik 1977ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if ((node->flags & G_SIGNAL_RUN_CLEANUP) && class_closure) 1978ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 1979830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik gboolean need_unset = FALSE; 1980830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik 1981ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik emission_state = EMISSION_STOP; 1982ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1983ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_UNLOCK (g_signal_mutex); 1984ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (node->return_type != G_TYPE_NONE) 1985ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 1986ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (!accumulator) 1987830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik { 1988830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik g_value_init (&accu, node->return_type); 1989830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik need_unset = TRUE; 1990830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik } 1991ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik else if (accu_used) 1992ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_value_reset (&accu); 1993ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 1994ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_closure_invoke (class_closure, 1995ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node->return_type != G_TYPE_NONE ? &accu : NULL, 1996ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node->n_params + 1, 1997830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik instance_and_params, 1998830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik &ihint); 1999830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik if (need_unset) 2000ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_value_unset (&accu); 2001ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_LOCK (g_signal_mutex); 2002830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik 2003ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (emission_state == EMISSION_RESTART) 2004ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik goto EMIT_RESTART; 2005ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 2006ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 2007830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik if (handler_list) 2008830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik handler_unref_R (signal_id, instance, handler_list); 2009ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 2010830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik emission_pop ((node->flags & G_SIGNAL_NO_RECURSE) ? &g_restart_emissions : &g_recursive_emissions, &emission_state); 2011ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (accumulator) 2012e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_value_unset (&accu); 2013e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 2014e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik return return_value_altered; 2015ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 2016e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 2017e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 2018f0b9abe801c2e0cccb7930421a81bb77031e3251Tim Janik/* --- compile standard marshallers --- */ 2019e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik#include "gvaluetypes.h" 2020e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik#include "gmarshal.c" 2021