gsignal.c revision 72df5e6cabe02f155ff767650cdaf10046c26e0e
1ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik/* GObject - GLib Type, Object, Parameter and Signal Library 237e4b8c87e8b0574a806a6f1d2284e4ab45341b3Tim Janik * Copyright (C) 2000-2001 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" 30617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik#include "gvaluetypes.h" 31617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik#include "gboxed.h" 32f0b9abe801c2e0cccb7930421a81bb77031e3251Tim Janik#include <string.h> 33ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 34ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 35ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik/* pre allocation configurations 36ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik */ 37e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik#define MAX_STACK_VALUES (16) 38ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik#define HANDLER_PRE_ALLOC (48) 39ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik#define EMISSION_PRE_ALLOC (16) 40ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 41ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik#define REPORT_BUG "please report occourance circumstances to gtk-devel-list@gnome.org" 4222357542e9cb017e2dfeee0004d6a22ed8897468Tim Janik#ifdef G_ENABLE_DEBUG 4322357542e9cb017e2dfeee0004d6a22ed8897468Tim Janik#define IF_DEBUG(debug_type, cond) if ((_g_type_debug_flags & G_TYPE_DEBUG_ ## debug_type) || cond) 4422357542e9cb017e2dfeee0004d6a22ed8897468Tim Janikstatic volatile gpointer *g_trace_instance_signals = NULL; 4522357542e9cb017e2dfeee0004d6a22ed8897468Tim Janikstatic volatile gpointer *g_trap_instance_signals = NULL; 4622357542e9cb017e2dfeee0004d6a22ed8897468Tim Janik#endif /* G_ENABLE_DEBUG */ 47ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 48ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 49ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik/* --- generic allocation --- */ 50782a8e2e7c69c3d98bd69bcfdbb65ded520576f4Tim Janik/* we special case allocations generically by replacing 51ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik * these functions with more speed/memory aware variants 52ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik */ 53782a8e2e7c69c3d98bd69bcfdbb65ded520576f4Tim Janik#ifndef DISABLE_MEM_POOLS 54ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikstatic inline gpointer 55ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikg_generic_node_alloc (GTrashStack **trash_stack_p, 56ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik guint sizeof_node, 57ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik guint nodes_pre_alloc) 58ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 59ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik gpointer node = g_trash_stack_pop (trash_stack_p); 60ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 61ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (!node) 62ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 63ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik guint8 *block; 64ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 65ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik nodes_pre_alloc = MAX (nodes_pre_alloc, 1); 66ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik block = g_malloc (sizeof_node * nodes_pre_alloc); 67ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik while (--nodes_pre_alloc) 68ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 69ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_trash_stack_push (trash_stack_p, block); 70ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik block += sizeof_node; 71ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 72ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node = block; 73ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 74ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 75ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik return node; 76ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 77f0b9abe801c2e0cccb7930421a81bb77031e3251Tim Janik#define g_generic_node_free(trash_stack_p, node) g_trash_stack_push (trash_stack_p, node) 78782a8e2e7c69c3d98bd69bcfdbb65ded520576f4Tim Janik#else /* !DISABLE_MEM_POOLS */ 79f0b9abe801c2e0cccb7930421a81bb77031e3251Tim Janik#define g_generic_node_alloc(t,sizeof_node,p) g_malloc (sizeof_node) 80f0b9abe801c2e0cccb7930421a81bb77031e3251Tim Janik#define g_generic_node_free(t,node) g_free (node) 81782a8e2e7c69c3d98bd69bcfdbb65ded520576f4Tim Janik#endif /* !DISABLE_MEM_POOLS */ 82ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 83ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 84ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik/* --- typedefs --- */ 8583c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janiktypedef struct _SignalNode SignalNode; 8683c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janiktypedef struct _SignalKey SignalKey; 8783c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janiktypedef struct _Emission Emission; 8883c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janiktypedef struct _Handler Handler; 8983c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janiktypedef struct _HandlerList HandlerList; 9083c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janiktypedef struct _HandlerMatch HandlerMatch; 91ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janiktypedef enum 92ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 93ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik EMISSION_STOP, 94ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik EMISSION_RUN, 95ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik EMISSION_HOOK, 96ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik EMISSION_RESTART 97ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} EmissionState; 98ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 99ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 100ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik/* --- prototypes --- */ 10183c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janikstatic inline guint signal_id_lookup (GQuark quark, 10283c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik GType itype); 10383c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janikstatic void signal_destroy_R (SignalNode *signal_node); 10483c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janikstatic inline HandlerList* handler_list_ensure (guint signal_id, 10583c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik gpointer instance); 10683c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janikstatic inline HandlerList* handler_list_lookup (guint signal_id, 10783c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik gpointer instance); 10883c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janikstatic inline Handler* handler_new (gboolean after); 10983c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janikstatic void handler_insert (guint signal_id, 11083c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik gpointer instance, 11183c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik Handler *handler); 11283c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janikstatic Handler* handler_lookup (gpointer instance, 113abc5cbbe3e1f6e6bdc40d94741713e9efb6d580dTim Janik gulong handler_id, 11483c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik guint *signal_id_p); 11583c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janikstatic inline HandlerMatch* handler_match_prepend (HandlerMatch *list, 11683c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik Handler *handler, 11783c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik guint signal_id); 11883c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janikstatic inline HandlerMatch* handler_match_free1_R (HandlerMatch *node, 11983c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik gpointer instance); 12083c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janikstatic HandlerMatch* handlers_find (gpointer instance, 12183c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik GSignalMatchType mask, 12283c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik guint signal_id, 12383c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik GQuark detail, 12483c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik GClosure *closure, 12583c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik gpointer func, 12683c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik gpointer data, 12783c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik gboolean one_and_only); 12883c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janikstatic inline void handler_ref (Handler *handler); 12983c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janikstatic inline void handler_unref_R (guint signal_id, 13083c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik gpointer instance, 13183c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik Handler *handler); 13283c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janikstatic inline void emission_push (Emission **emission_list_p, 13383c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik guint signal_id, 13483c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik GQuark detail, 13583c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik gpointer instance, 13683c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik EmissionState *state_p); 13783c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janikstatic inline void emission_pop (Emission **emission_list_p, 13883c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik EmissionState *state_p); 13983c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janikstatic inline Emission* emission_find (Emission *emission_list, 14083c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik guint signal_id, 14183c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik GQuark detail, 14283c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik gpointer instance); 14345fb71949a0c0e27fe8d0948b345334f61a5c924Tim Janikstatic gint signal_key_cmp (gconstpointer node1, 14445fb71949a0c0e27fe8d0948b345334f61a5c924Tim Janik gconstpointer node2); 145e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janikstatic gboolean signal_emit_R (SignalNode *node, 14683c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik GQuark detail, 14783c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik gpointer instance, 14883c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik GValue *return_value, 14983c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik const GValue *instance_and_params); 150ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 151ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 152ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik/* --- structures --- */ 153617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janiktypedef struct 154617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik{ 155617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik GSignalAccumulator func; 156617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik gpointer data; 157617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik} SignalAccumulator; 1589490f8d7e435d60b76d5fca12ba6332a5f058fa5Tim Janiktypedef struct 1599490f8d7e435d60b76d5fca12ba6332a5f058fa5Tim Janik{ 1609490f8d7e435d60b76d5fca12ba6332a5f058fa5Tim Janik GHook hook; 1619490f8d7e435d60b76d5fca12ba6332a5f058fa5Tim Janik GQuark detail; 1629490f8d7e435d60b76d5fca12ba6332a5f058fa5Tim Janik} SignalHook; 1639490f8d7e435d60b76d5fca12ba6332a5f058fa5Tim Janik#define SIGNAL_HOOK(hook) ((SignalHook*) (hook)) 1649490f8d7e435d60b76d5fca12ba6332a5f058fa5Tim Janik 165ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikstruct _SignalNode 166ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 167ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik /* permanent portion */ 168ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik guint signal_id; 169ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik GType itype; 170ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik gchar *name; 171ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik guint destroyed : 1; 172ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 173ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik /* reinitializable portion */ 174ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik guint flags : 8; 175ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik guint n_params : 8; 176bbc5a3adac7d6d5dbdcf956d7d185e9910c3034bTim Janik GType *param_types; /* mangled with G_SIGNAL_TYPE_STATIC_SCOPE flag */ 177bbc5a3adac7d6d5dbdcf956d7d185e9910c3034bTim Janik GType return_type; /* mangled with G_SIGNAL_TYPE_STATIC_SCOPE flag */ 178ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik GClosure *class_closure; 179617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik SignalAccumulator *accumulator; 180ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik GSignalCMarshaller c_marshaller; 181ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik GHookList *emission_hooks; 182ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik}; 183ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 184ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikstruct _SignalKey 185ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 186ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik GType itype; 187ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik GQuark quark; 188ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik guint signal_id; 189ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik}; 190ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 191ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikstruct _Emission 192ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 193ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik Emission *next; 194ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik guint signal_id; 195830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik GQuark detail; 196ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik gpointer instance; 197ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik EmissionState *state_p; 198ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik}; 199ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 200ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikstruct _HandlerList 201ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 202ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik guint signal_id; 203ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik Handler *handlers; 204ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik}; 205ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikstruct _Handler 206ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 207abc5cbbe3e1f6e6bdc40d94741713e9efb6d580dTim Janik gulong sequential_number; 208ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik Handler *next; 209ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik Handler *prev; 210830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik GQuark detail; 211ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik guint ref_count : 16; 212ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik#define HANDLER_MAX_REF_COUNT (1 << 16) 213ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik guint block_count : 12; 214ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik#define HANDLER_MAX_BLOCK_COUNT (1 << 12) 215ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik guint after : 1; 216ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik GClosure *closure; 217ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik}; 21883c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janikstruct _HandlerMatch 21983c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik{ 22083c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik Handler *handler; 22183c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik HandlerMatch *next; 22283c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik union { 22383c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik guint signal_id; 22483c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik gpointer dummy; 22583c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik } d; 22683c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik}; 227ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 228ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 229ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik/* --- variables --- */ 23045fb71949a0c0e27fe8d0948b345334f61a5c924Tim Janikstatic GBSearchArray g_signal_key_bsa = G_STATIC_BSEARCH_ARRAY_INIT (sizeof (SignalKey), 23145fb71949a0c0e27fe8d0948b345334f61a5c924Tim Janik signal_key_cmp, 23245fb71949a0c0e27fe8d0948b345334f61a5c924Tim Janik G_BSEARCH_ARRAY_ALIGN_POWER2); 233ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikstatic GHashTable *g_handler_list_bsa_ht = NULL; 234ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikstatic Emission *g_recursive_emissions = NULL; 235ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikstatic Emission *g_restart_emissions = NULL; 236ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikstatic GTrashStack *g_handler_ts = NULL; 237ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikstatic GTrashStack *g_emission_ts = NULL; 238abc5cbbe3e1f6e6bdc40d94741713e9efb6d580dTim Janikstatic gulong g_handler_sequential_number = 1; 239ee23c09e83d06a0d131ebd234c132f1c3602c019Tim JanikG_LOCK_DEFINE_STATIC (g_signal_mutex); 240ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 241ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 242ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik/* --- signal nodes --- */ 243ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikstatic guint g_n_signal_nodes = 0; 244ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikstatic SignalNode **g_signal_nodes = NULL; 245ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 246ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikstatic inline SignalNode* 247ee23c09e83d06a0d131ebd234c132f1c3602c019Tim JanikLOOKUP_SIGNAL_NODE (register guint signal_id) 248ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 249ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (signal_id < g_n_signal_nodes) 250ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik return g_signal_nodes[signal_id]; 251ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik else 252ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik return NULL; 253ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 254ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 255ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 256ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik/* --- functions --- */ 257ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikstatic inline guint 258ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janiksignal_id_lookup (GQuark quark, 259ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik GType itype) 260ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 261e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik GType *ifaces, type = itype; 262e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik SignalKey key; 263e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik guint n_ifaces; 264e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 265e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik key.quark = quark; 266e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 267e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik /* try looking up signals for this type and its anchestors */ 2688a572c0da1be99527c52f620dc7fd04eb0775bdeTim Janik do 2698a572c0da1be99527c52f620dc7fd04eb0775bdeTim Janik { 270e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik SignalKey *signal_key; 2718a572c0da1be99527c52f620dc7fd04eb0775bdeTim Janik 272e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik key.itype = type; 2738a572c0da1be99527c52f620dc7fd04eb0775bdeTim Janik signal_key = g_bsearch_array_lookup (&g_signal_key_bsa, &key); 2748a572c0da1be99527c52f620dc7fd04eb0775bdeTim Janik 2758a572c0da1be99527c52f620dc7fd04eb0775bdeTim Janik if (signal_key) 2768a572c0da1be99527c52f620dc7fd04eb0775bdeTim Janik return signal_key->signal_id; 2778a572c0da1be99527c52f620dc7fd04eb0775bdeTim Janik 278e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik type = g_type_parent (type); 2798a572c0da1be99527c52f620dc7fd04eb0775bdeTim Janik } 280e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik while (type); 281e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 282e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik /* no luck, try interfaces it exports */ 283e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik ifaces = g_type_interfaces (itype, &n_ifaces); 284e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik while (n_ifaces--) 285e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik { 286e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik SignalKey *signal_key; 287e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 288e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik key.itype = ifaces[n_ifaces]; 289e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik signal_key = g_bsearch_array_lookup (&g_signal_key_bsa, &key); 290e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 291e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik if (signal_key) 292e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik { 293e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_free (ifaces); 294e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik return signal_key->signal_id; 295e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik } 296e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik } 297e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_free (ifaces); 298ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 2998a572c0da1be99527c52f620dc7fd04eb0775bdeTim Janik return 0; 300ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 301ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 302ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikstatic gint 303ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikhandler_lists_cmp (gconstpointer node1, 304ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik gconstpointer node2) 305ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 306ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik const HandlerList *hlist1 = node1, *hlist2 = node2; 307ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 308ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik return G_BSEARCH_ARRAY_CMP (hlist1->signal_id, hlist2->signal_id); 309ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 310ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 311ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikstatic inline HandlerList* 312ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikhandler_list_ensure (guint signal_id, 313ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik gpointer instance) 314ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 315ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik GBSearchArray *hlbsa = g_hash_table_lookup (g_handler_list_bsa_ht, instance); 316ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik HandlerList key; 317ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 318ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (!hlbsa) 319ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 32045fb71949a0c0e27fe8d0948b345334f61a5c924Tim Janik hlbsa = g_bsearch_array_new (sizeof (HandlerList), handler_lists_cmp, G_BSEARCH_ARRAY_DEFER_SHRINK); 321ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_hash_table_insert (g_handler_list_bsa_ht, instance, hlbsa); 322ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 323ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik key.signal_id = signal_id; 324ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik key.handlers = NULL; 325ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 326ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik return g_bsearch_array_insert (hlbsa, &key, FALSE); 327ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 328ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 329ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikstatic inline HandlerList* 330ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikhandler_list_lookup (guint signal_id, 331ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik gpointer instance) 332ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 333ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik GBSearchArray *hlbsa = g_hash_table_lookup (g_handler_list_bsa_ht, instance); 334ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik HandlerList key; 335ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 336ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik key.signal_id = signal_id; 337ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 338ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik return hlbsa ? g_bsearch_array_lookup (hlbsa, &key) : NULL; 339ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 340ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 341ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikstatic Handler* 342ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikhandler_lookup (gpointer instance, 343abc5cbbe3e1f6e6bdc40d94741713e9efb6d580dTim Janik gulong handler_id, 344ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik guint *signal_id_p) 345ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 346ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik GBSearchArray *hlbsa = g_hash_table_lookup (g_handler_list_bsa_ht, instance); 347ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 348ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (hlbsa) 349ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 350ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik guint i; 351ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 352ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik for (i = 0; i < hlbsa->n_nodes; i++) 353ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 354ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik HandlerList *hlist = g_bsearch_array_get_nth (hlbsa, i); 355ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik Handler *handler; 356ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 357ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik for (handler = hlist->handlers; handler; handler = handler->next) 358abc5cbbe3e1f6e6bdc40d94741713e9efb6d580dTim Janik if (handler->sequential_number == handler_id) 359ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 360ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (signal_id_p) 361ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik *signal_id_p = hlist->signal_id; 362ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 363ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik return handler; 364ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 365ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 366ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 367ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 368ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik return NULL; 369ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 370ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 37183c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janikstatic inline HandlerMatch* 37283c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janikhandler_match_prepend (HandlerMatch *list, 37383c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik Handler *handler, 37483c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik guint signal_id) 37583c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik{ 37683c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik HandlerMatch *node; 37783c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 37883c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik /* yeah, we could use our own memchunk here, introducing yet more 37983c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik * rarely used cached nodes and extra allocation overhead. 38083c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik * instead, we use GList* nodes, since they are exactly the size 38183c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik * we need and are already cached. g_signal_init() asserts this. 38283c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik */ 38383c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik node = (HandlerMatch*) g_list_alloc (); 38483c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik node->handler = handler; 38583c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik node->next = list; 38683c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik node->d.signal_id = signal_id; 38783c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik handler_ref (handler); 38883c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 38983c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik return node; 39083c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik} 39183c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janikstatic inline HandlerMatch* 39283c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janikhandler_match_free1_R (HandlerMatch *node, 39383c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik gpointer instance) 39483c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik{ 39583c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik HandlerMatch *next = node->next; 39683c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 39783c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik handler_unref_R (node->d.signal_id, instance, node->handler); 39883c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik g_list_free_1 ((GList*) node); 39983c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 40083c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik return next; 40183c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik} 40283c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 40383c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janikstatic HandlerMatch* 40483c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janikhandlers_find (gpointer instance, 40583c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik GSignalMatchType mask, 40683c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik guint signal_id, 40783c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik GQuark detail, 40883c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik GClosure *closure, 40983c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik gpointer func, 41083c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik gpointer data, 41183c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik gboolean one_and_only) 412ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 41383c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik HandlerMatch *mlist = NULL; 41483c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 415ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (mask & G_SIGNAL_MATCH_ID) 416ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 417ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik HandlerList *hlist = handler_list_lookup (signal_id, instance); 418ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik Handler *handler; 419790a7bd3be608d9b12a18711d4400490d96b2a46Elliot Lee SignalNode *node = NULL; 420ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 42155ec7f32a6852dba73abb29e650615b66b065ef9Tim Janik if (mask & G_SIGNAL_MATCH_FUNC) 422ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 423ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node = LOOKUP_SIGNAL_NODE (signal_id); 424ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (!node || !node->c_marshaller) 425ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik return NULL; 426ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 42783c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 428ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik mask = ~mask; 429ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik for (handler = hlist ? hlist->handlers : NULL; handler; handler = handler->next) 430abc5cbbe3e1f6e6bdc40d94741713e9efb6d580dTim Janik if (handler->sequential_number && 43183c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik ((mask & G_SIGNAL_MATCH_DETAIL) || handler->detail == detail) && 432830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik ((mask & G_SIGNAL_MATCH_CLOSURE) || handler->closure == closure) && 433ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik ((mask & G_SIGNAL_MATCH_DATA) || handler->closure->data == data) && 434830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik ((mask & G_SIGNAL_MATCH_UNBLOCKED) || handler->block_count == 0) && 435ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik ((mask & G_SIGNAL_MATCH_FUNC) || (handler->closure->marshal == node->c_marshaller && 436ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik handler->closure->meta_marshal == 0 && 437ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik ((GCClosure*) handler->closure)->callback == func))) 43883c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik { 43983c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik mlist = handler_match_prepend (mlist, handler, signal_id); 44083c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik if (one_and_only) 44183c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik return mlist; 44283c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik } 443ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 444ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik else 445ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 446ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik GBSearchArray *hlbsa = g_hash_table_lookup (g_handler_list_bsa_ht, instance); 447ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 448ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik mask = ~mask; 449ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (hlbsa) 450ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 451ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik guint i; 452ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 453ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik for (i = 0; i < hlbsa->n_nodes; i++) 454ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 455ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik HandlerList *hlist = g_bsearch_array_get_nth (hlbsa, i); 456790a7bd3be608d9b12a18711d4400490d96b2a46Elliot Lee SignalNode *node = NULL; 457ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik Handler *handler; 458ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 459ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (!(mask & G_SIGNAL_MATCH_FUNC)) 460ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 461ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node = LOOKUP_SIGNAL_NODE (hlist->signal_id); 462ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (!node->c_marshaller) 463ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik continue; 464ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 46583c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 466ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik for (handler = hlist->handlers; handler; handler = handler->next) 467abc5cbbe3e1f6e6bdc40d94741713e9efb6d580dTim Janik if (handler->sequential_number && 46883c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik ((mask & G_SIGNAL_MATCH_DETAIL) || handler->detail == detail) && 469830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik ((mask & G_SIGNAL_MATCH_CLOSURE) || handler->closure == closure) && 470ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik ((mask & G_SIGNAL_MATCH_DATA) || handler->closure->data == data) && 471830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik ((mask & G_SIGNAL_MATCH_UNBLOCKED) || handler->block_count == 0) && 472ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik ((mask & G_SIGNAL_MATCH_FUNC) || (handler->closure->marshal == node->c_marshaller && 473ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik handler->closure->meta_marshal == 0 && 474ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik ((GCClosure*) handler->closure)->callback == func))) 47583c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik { 476a453526f350a3956a26f71db481bd8b436c65f97Owen Taylor mlist = handler_match_prepend (mlist, handler, hlist->signal_id); 47783c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik if (one_and_only) 47883c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik return mlist; 47983c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik } 480ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 481ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 482ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 483ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 48483c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik return mlist; 485ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 486ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 487ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikstatic inline Handler* 488ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikhandler_new (gboolean after) 489ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 490ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik Handler *handler = g_generic_node_alloc (&g_handler_ts, 491ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik sizeof (Handler), 492ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik HANDLER_PRE_ALLOC); 493ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik#ifndef G_DISABLE_CHECKS 494abc5cbbe3e1f6e6bdc40d94741713e9efb6d580dTim Janik if (g_handler_sequential_number < 1) 495ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_error (G_STRLOC ": handler id overflow, %s", REPORT_BUG); 496ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik#endif 497ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 498abc5cbbe3e1f6e6bdc40d94741713e9efb6d580dTim Janik handler->sequential_number = g_handler_sequential_number++; 499ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik handler->prev = NULL; 500ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik handler->next = NULL; 501830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik handler->detail = 0; 502ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik handler->ref_count = 1; 503ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik handler->block_count = 0; 504ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik handler->after = after != FALSE; 505ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik handler->closure = NULL; 506ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 507ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik return handler; 508ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 509ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 510ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikstatic inline void 511ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikhandler_ref (Handler *handler) 512ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 513ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_return_if_fail (handler->ref_count > 0); 514ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 515ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik#ifndef G_DISABLE_CHECKS 516ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (handler->ref_count >= HANDLER_MAX_REF_COUNT - 1) 517ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_error (G_STRLOC ": handler ref_count overflow, %s", REPORT_BUG); 518ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik#endif 519ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 520ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik handler->ref_count += 1; 521ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 522ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 523ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikstatic inline void 524ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikhandler_unref_R (guint signal_id, 525ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik gpointer instance, 526ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik Handler *handler) 527ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 528ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_return_if_fail (handler->ref_count > 0); 529ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 530ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik handler->ref_count -= 1; 531ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (!handler->ref_count) 532ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 533ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (handler->next) 534ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik handler->next->prev = handler->prev; 53583c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik if (handler->prev) /* watch out for g_signal_handlers_destroy()! */ 536ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik handler->prev->next = handler->next; 537ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik else 538ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 539ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik HandlerList *hlist = handler_list_lookup (signal_id, instance); 540ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 541ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik hlist->handlers = handler->next; 542ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 543ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_UNLOCK (g_signal_mutex); 544ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_closure_unref (handler->closure); 545ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_LOCK (g_signal_mutex); 546ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_generic_node_free (&g_handler_ts, handler); 547ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 548ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 549ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 550ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikstatic void 551ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikhandler_insert (guint signal_id, 552ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik gpointer instance, 553ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik Handler *handler) 554ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 555ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik HandlerList *hlist; 556ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 557e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_assert (handler->prev == NULL && handler->next == NULL); /* paranoid */ 558ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 559ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik hlist = handler_list_ensure (signal_id, instance); 560ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (!hlist->handlers) 561ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik hlist->handlers = handler; 562ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik else if (hlist->handlers->after && !handler->after) 563ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 564ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik handler->next = hlist->handlers; 565ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik hlist->handlers->prev = handler; 566ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik hlist->handlers = handler; 567ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 568ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik else 569ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 570ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik Handler *tmp = hlist->handlers; 571ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 572ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (handler->after) 573ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik while (tmp->next) 574ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik tmp = tmp->next; 575ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik else 576ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik while (tmp->next && !tmp->next->after) 577ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik tmp = tmp->next; 578ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (tmp->next) 579ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik tmp->next->prev = handler; 580ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik handler->next = tmp->next; 581ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik handler->prev = tmp; 582ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik tmp->next = handler; 583ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 584ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 585ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 586ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikstatic inline void 587ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikemission_push (Emission **emission_list_p, 588ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik guint signal_id, 589830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik GQuark detail, 590ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik gpointer instance, 591ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik EmissionState *state_p) 592ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 593ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik Emission *emission = g_generic_node_alloc (&g_emission_ts, 594ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik sizeof (Emission), 595ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik EMISSION_PRE_ALLOC); 596ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik emission->next = *emission_list_p; 597ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik emission->signal_id = signal_id; 598830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik emission->detail = detail; 599ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik emission->instance = instance; 600ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik emission->state_p = state_p; 601ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik *emission_list_p = emission; 602ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 603ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 604ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikstatic inline void 605830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janikemission_pop (Emission **emission_list_p, 606830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik EmissionState *state_p) 607ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 608830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik Emission **loc = emission_list_p, *emission = *loc; 60983c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 610830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik while (emission->state_p != state_p) 611830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik { 612830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik loc = &emission->next; 613830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik emission = *loc; 614830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik } 615830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik *loc = emission->next; 616ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_generic_node_free (&g_emission_ts, emission); 617ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 618ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 619ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikstatic inline Emission* 620ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikemission_find (Emission *emission_list, 621ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik guint signal_id, 622830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik GQuark detail, 623ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik gpointer instance) 624ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 625ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik Emission *emission; 626ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 627ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik for (emission = emission_list; emission; emission = emission->next) 628830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik if (emission->instance == instance && 629830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik emission->signal_id == signal_id && 630830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik emission->detail == detail) 631ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik return emission; 632ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik return NULL; 633ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 634ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 635ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikstatic gint 636ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janiksignal_key_cmp (gconstpointer node1, 637ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik gconstpointer node2) 638ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 639ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik const SignalKey *key1 = node1, *key2 = node2; 640ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 641ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (key1->itype == key2->itype) 642ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik return G_BSEARCH_ARRAY_CMP (key1->quark, key2->quark); 643ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik else 644ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik return G_BSEARCH_ARRAY_CMP (key1->itype, key2->itype); 645ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 646ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 647ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikvoid 648ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikg_signal_init (void) /* sync with gtype.c */ 649ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 650ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_LOCK (g_signal_mutex); 651ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (!g_n_signal_nodes) 652ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 65383c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik /* handler_id_node_prepend() requires this */ 65483c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik g_assert (sizeof (GList) == sizeof (HandlerMatch)); 65583c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 656ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik /* setup handler list binary searchable array hash table (in german, that'd be one word ;) */ 657ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_handler_list_bsa_ht = g_hash_table_new (g_direct_hash, NULL); 658ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 659ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik /* invalid (0) signal_id */ 660ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_n_signal_nodes = 1; 661ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_signal_nodes = g_renew (SignalNode*, g_signal_nodes, g_n_signal_nodes); 662ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_signal_nodes[0] = NULL; 663ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 664ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_UNLOCK (g_signal_mutex); 665ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 666ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 667ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikvoid 6683cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik_g_signals_destroy (GType itype) 669ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 670ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik guint i; 671ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 672ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_LOCK (g_signal_mutex); 67383c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik for (i = 1; i < g_n_signal_nodes; i++) 674ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 675ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik SignalNode *node = g_signal_nodes[i]; 676ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 677ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (node->itype == itype) 678ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 679ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (node->destroyed) 680ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_warning (G_STRLOC ": signal \"%s\" of type `%s' already destroyed", 681ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node->name, 682ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_type_name (node->itype)); 683ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik else 684cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik signal_destroy_R (node); 685ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 686ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 687ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_UNLOCK (g_signal_mutex); 688ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 689ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 690ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikvoid 691ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikg_signal_stop_emission (gpointer instance, 692830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik guint signal_id, 693830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik GQuark detail) 694ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 695ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik SignalNode *node; 696ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 697ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance)); 698ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_return_if_fail (signal_id > 0); 699ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 700ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_LOCK (g_signal_mutex); 701ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node = LOOKUP_SIGNAL_NODE (signal_id); 702830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik if (node && detail && !(node->flags & G_SIGNAL_DETAILED)) 703830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik { 704830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik g_warning ("%s: signal id `%u' does not support detail (%u)", G_STRLOC, signal_id, detail); 705830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik G_UNLOCK (g_signal_mutex); 706830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik return; 707830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik } 708e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik if (node && g_type_is_a (G_TYPE_FROM_INSTANCE (instance), node->itype)) 709ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 710ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik Emission *emission_list = node->flags & G_SIGNAL_NO_RECURSE ? g_restart_emissions : g_recursive_emissions; 711830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik Emission *emission = emission_find (emission_list, signal_id, detail, instance); 712ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 713ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (emission) 714ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 715ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (*emission->state_p == EMISSION_HOOK) 716ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_warning (G_STRLOC ": emission of signal \"%s\" for instance `%p' cannot be stopped from emission hook", 717ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node->name, instance); 718ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik else if (*emission->state_p == EMISSION_RUN) 719ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik *emission->state_p = EMISSION_STOP; 720ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 721ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik else 722ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_warning (G_STRLOC ": no emission of signal \"%s\" to stop for instance `%p'", 723ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node->name, instance); 724ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 725ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik else 726ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_warning ("%s: signal id `%u' is invalid for instance `%p'", G_STRLOC, signal_id, instance); 727ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_UNLOCK (g_signal_mutex); 728ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 729ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 730617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janikstatic void 731617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janiksignal_finalize_hook (GHookList *hook_list, 732617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik GHook *hook) 733617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik{ 734617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik GDestroyNotify destroy = hook->destroy; 735617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik 736617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik if (destroy) 737617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik { 738617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik hook->destroy = NULL; 739617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik G_UNLOCK (g_signal_mutex); 740617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik destroy (hook->data); 741617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik G_LOCK (g_signal_mutex); 742617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik } 743617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik} 744617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik 745abc5cbbe3e1f6e6bdc40d94741713e9efb6d580dTim Janikgulong 746617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janikg_signal_add_emission_hook (guint signal_id, 747617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik GQuark detail, 748617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik GSignalEmissionHook hook_func, 749617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik gpointer hook_data, 750617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik GDestroyNotify data_destroy) 751617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik{ 752abc5cbbe3e1f6e6bdc40d94741713e9efb6d580dTim Janik static gulong seq_hook_id = 1; 753617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik SignalNode *node; 754617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik GHook *hook; 7559490f8d7e435d60b76d5fca12ba6332a5f058fa5Tim Janik SignalHook *signal_hook; 756617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik 757617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik g_return_val_if_fail (signal_id > 0, 0); 758617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik g_return_val_if_fail (hook_func != NULL, 0); 759617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik 760617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik G_LOCK (g_signal_mutex); 761617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik node = LOOKUP_SIGNAL_NODE (signal_id); 762617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik if (!node || node->destroyed || (node->flags & G_SIGNAL_NO_HOOKS)) 763617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik { 764617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik g_warning ("%s: invalid signal id `%u'", G_STRLOC, signal_id); 765617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik G_UNLOCK (g_signal_mutex); 766617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik return 0; 767617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik } 768617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik if (detail && !(node->flags & G_SIGNAL_DETAILED)) 769617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik { 770617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik g_warning ("%s: signal id `%u' does not support detail (%u)", G_STRLOC, signal_id, detail); 771617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik G_UNLOCK (g_signal_mutex); 772617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik return 0; 773617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik } 774617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik if (!node->emission_hooks) 775617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik { 776617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik node->emission_hooks = g_new (GHookList, 1); 7779490f8d7e435d60b76d5fca12ba6332a5f058fa5Tim Janik g_hook_list_init (node->emission_hooks, sizeof (SignalHook)); 778617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik node->emission_hooks->finalize_hook = signal_finalize_hook; 779617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik } 780617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik hook = g_hook_alloc (node->emission_hooks); 781617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik hook->data = hook_data; 782617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik hook->func = hook_func; 783617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik hook->destroy = data_destroy; 7849490f8d7e435d60b76d5fca12ba6332a5f058fa5Tim Janik signal_hook = SIGNAL_HOOK (hook); 7859490f8d7e435d60b76d5fca12ba6332a5f058fa5Tim Janik signal_hook->detail = detail; 786617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik node->emission_hooks->seq_id = seq_hook_id; 787617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik g_hook_append (node->emission_hooks, hook); 788617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik seq_hook_id = node->emission_hooks->seq_id; 789617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik G_UNLOCK (g_signal_mutex); 790617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik 791617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik return hook->hook_id; 792617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik} 793617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik 794617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janikvoid 795abc5cbbe3e1f6e6bdc40d94741713e9efb6d580dTim Janikg_signal_remove_emission_hook (guint signal_id, 796abc5cbbe3e1f6e6bdc40d94741713e9efb6d580dTim Janik gulong hook_id) 797617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik{ 798617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik SignalNode *node; 799617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik 800617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik g_return_if_fail (signal_id > 0); 801617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik g_return_if_fail (hook_id > 0); 802617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik 803617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik G_LOCK (g_signal_mutex); 804617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik node = LOOKUP_SIGNAL_NODE (signal_id); 805617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik if (!node || node->destroyed) 806617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik g_warning ("%s: invalid signal id `%u'", G_STRLOC, signal_id); 807617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik else if (!node->emission_hooks || !g_hook_destroy (node->emission_hooks, hook_id)) 808abc5cbbe3e1f6e6bdc40d94741713e9efb6d580dTim Janik g_warning ("%s: signal \"%s\" had no hook (%lu) to remove", G_STRLOC, node->name, hook_id); 809617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik G_UNLOCK (g_signal_mutex); 810617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik} 811617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik 8123cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janikstatic inline guint 8133cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janiksignal_parse_name (const gchar *name, 8143cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik GType itype, 8153cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik GQuark *detail_p, 8163cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik gboolean force_quark) 8173cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik{ 8183cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik const gchar *colon = strchr (name, ':'); 8193cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik guint signal_id; 8203cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik 8213cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik if (!colon) 8223cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik { 8233cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik signal_id = signal_id_lookup (g_quark_try_string (name), itype); 8243cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik if (signal_id && detail_p) 8253cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik *detail_p = 0; 8263cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik } 8273cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik else if (colon[1] == ':') 8283cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik { 8293cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik gchar buffer[32]; 8303cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik guint l = colon - name; 8313cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik 8323cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik if (l < 32) 8333cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik { 8343cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik memcpy (buffer, name, l); 8353cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik buffer[l] = 0; 8363cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik signal_id = signal_id_lookup (g_quark_try_string (buffer), itype); 8373cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik } 8383cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik else 8393cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik { 8403cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik gchar *signal = g_new (gchar, l + 1); 8413cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik 8423cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik memcpy (signal, name, l); 8433cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik signal[l] = 0; 8443cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik signal_id = signal_id_lookup (g_quark_try_string (signal), itype); 8453cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik g_free (signal); 8463cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik } 8473cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik 8483cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik if (signal_id && detail_p) 8493cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik *detail_p = colon[2] ? (force_quark ? g_quark_from_string : g_quark_try_string) (colon + 2) : 0; 8503cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik } 8513cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik else 8523cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik signal_id = 0; 8533cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik return signal_id; 8543cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik} 8553cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik 8563cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janikgboolean 8573cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janikg_signal_parse_name (const gchar *detailed_signal, 8583cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik GType itype, 8593cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik guint *signal_id_p, 8603cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik GQuark *detail_p, 8613cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik gboolean force_detail_quark) 8623cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik{ 86337e4b8c87e8b0574a806a6f1d2284e4ab45341b3Tim Janik SignalNode *node; 8643cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik GQuark detail = 0; 8653cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik guint signal_id; 86683c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 8673cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik g_return_val_if_fail (detailed_signal != NULL, FALSE); 8683cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik g_return_val_if_fail (G_TYPE_IS_INSTANTIATABLE (itype) || G_TYPE_IS_INTERFACE (itype), FALSE); 86983c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 8703cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik G_LOCK (g_signal_mutex); 8713cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik signal_id = signal_parse_name (detailed_signal, itype, &detail, force_detail_quark); 8723cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik G_UNLOCK (g_signal_mutex); 87337e4b8c87e8b0574a806a6f1d2284e4ab45341b3Tim Janik 87437e4b8c87e8b0574a806a6f1d2284e4ab45341b3Tim Janik node = signal_id ? LOOKUP_SIGNAL_NODE (signal_id) : NULL; 87537e4b8c87e8b0574a806a6f1d2284e4ab45341b3Tim Janik if (!node || node->destroyed || 87637e4b8c87e8b0574a806a6f1d2284e4ab45341b3Tim Janik (detail && !(node->flags & G_SIGNAL_DETAILED))) 8773cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik return FALSE; 87837e4b8c87e8b0574a806a6f1d2284e4ab45341b3Tim Janik 87937e4b8c87e8b0574a806a6f1d2284e4ab45341b3Tim Janik if (signal_id_p) 88037e4b8c87e8b0574a806a6f1d2284e4ab45341b3Tim Janik *signal_id_p = signal_id; 88137e4b8c87e8b0574a806a6f1d2284e4ab45341b3Tim Janik if (detail_p) 88237e4b8c87e8b0574a806a6f1d2284e4ab45341b3Tim Janik *detail_p = detail; 88337e4b8c87e8b0574a806a6f1d2284e4ab45341b3Tim Janik 88437e4b8c87e8b0574a806a6f1d2284e4ab45341b3Tim Janik return TRUE; 8853cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik} 8863cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik 887ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikguint 888ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikg_signal_lookup (const gchar *name, 889ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik GType itype) 890ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 8918a572c0da1be99527c52f620dc7fd04eb0775bdeTim Janik guint signal_id; 8928a572c0da1be99527c52f620dc7fd04eb0775bdeTim Janik 893ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_return_val_if_fail (name != NULL, 0); 894ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_return_val_if_fail (G_TYPE_IS_INSTANTIATABLE (itype) || G_TYPE_IS_INTERFACE (itype), 0); 895ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 896ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_LOCK (g_signal_mutex); 8978a572c0da1be99527c52f620dc7fd04eb0775bdeTim Janik signal_id = signal_id_lookup (g_quark_try_string (name), itype); 898ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_UNLOCK (g_signal_mutex); 899ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 9008a572c0da1be99527c52f620dc7fd04eb0775bdeTim Janik return signal_id; 901ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 902ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 9031c391cc69846713b0406545146ea232efc5f34e2Havoc PenningtonG_CONST_RETURN gchar* 904ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikg_signal_name (guint signal_id) 905ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 906ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik SignalNode *node; 907ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik gchar *name; 90883c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 909ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_LOCK (g_signal_mutex); 910ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node = LOOKUP_SIGNAL_NODE (signal_id); 911ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik name = node ? node->name : NULL; 912ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_UNLOCK (g_signal_mutex); 913ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 914ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik return name; 915ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 916ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 917ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikvoid 918ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikg_signal_query (guint signal_id, 919ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik GSignalQuery *query) 920ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 921ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik SignalNode *node; 92283c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 923ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_return_if_fail (query != NULL); 92483c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 925ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_LOCK (g_signal_mutex); 926ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node = LOOKUP_SIGNAL_NODE (signal_id); 927ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (!node || node->destroyed) 928ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik query->signal_id = 0; 929ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik else 930ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 931ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik query->signal_id = node->signal_id; 932ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik query->signal_name = node->name; 933ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik query->itype = node->itype; 934ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik query->signal_flags = node->flags; 935ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik query->return_type = node->return_type; 936ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik query->n_params = node->n_params; 937ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik query->param_types = node->param_types; 938ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 939ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_UNLOCK (g_signal_mutex); 940ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 941ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 94265c423b458d9fd1338cab0de7951092c09ab1686Tim Janikguint* 94365c423b458d9fd1338cab0de7951092c09ab1686Tim Janikg_signal_list_ids (GType itype, 94465c423b458d9fd1338cab0de7951092c09ab1686Tim Janik guint *n_ids) 945300e3bb247216fee40254822c2fb60a78a8ef21cOwen Taylor{ 946300e3bb247216fee40254822c2fb60a78a8ef21cOwen Taylor SignalKey *keys; 947300e3bb247216fee40254822c2fb60a78a8ef21cOwen Taylor GArray *result; 94865c423b458d9fd1338cab0de7951092c09ab1686Tim Janik guint n_nodes; 94965c423b458d9fd1338cab0de7951092c09ab1686Tim Janik guint i; 95083c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 951300e3bb247216fee40254822c2fb60a78a8ef21cOwen Taylor g_return_val_if_fail (G_TYPE_IS_INSTANTIATABLE (itype) || G_TYPE_IS_INTERFACE (itype), NULL); 95265c423b458d9fd1338cab0de7951092c09ab1686Tim Janik g_return_val_if_fail (n_ids != NULL, NULL); 95383c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 95465c423b458d9fd1338cab0de7951092c09ab1686Tim Janik G_LOCK (g_signal_mutex); 95583c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 956300e3bb247216fee40254822c2fb60a78a8ef21cOwen Taylor keys = g_signal_key_bsa.nodes; 957300e3bb247216fee40254822c2fb60a78a8ef21cOwen Taylor n_nodes = g_signal_key_bsa.n_nodes; 958300e3bb247216fee40254822c2fb60a78a8ef21cOwen Taylor result = g_array_new (FALSE, FALSE, sizeof (guint)); 959300e3bb247216fee40254822c2fb60a78a8ef21cOwen Taylor 960300e3bb247216fee40254822c2fb60a78a8ef21cOwen Taylor for (i = 0; i < n_nodes; i++) 96165c423b458d9fd1338cab0de7951092c09ab1686Tim Janik if (keys[i].itype == itype) 96265c423b458d9fd1338cab0de7951092c09ab1686Tim Janik { 9631c391cc69846713b0406545146ea232efc5f34e2Havoc Pennington const gchar *name = g_quark_to_string (keys[i].quark); 96483c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 96565c423b458d9fd1338cab0de7951092c09ab1686Tim Janik /* Signal names with "_" in them are aliases to the same 96665c423b458d9fd1338cab0de7951092c09ab1686Tim Janik * name with "-" instead of "_". 96765c423b458d9fd1338cab0de7951092c09ab1686Tim Janik */ 96865c423b458d9fd1338cab0de7951092c09ab1686Tim Janik if (!strchr (name, '_')) 96965c423b458d9fd1338cab0de7951092c09ab1686Tim Janik g_array_append_val (result, keys[i].signal_id); 97065c423b458d9fd1338cab0de7951092c09ab1686Tim Janik } 97183c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 972300e3bb247216fee40254822c2fb60a78a8ef21cOwen Taylor *n_ids = result->len; 97383c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 97465c423b458d9fd1338cab0de7951092c09ab1686Tim Janik G_UNLOCK (g_signal_mutex); 97565c423b458d9fd1338cab0de7951092c09ab1686Tim Janik 97645fb71949a0c0e27fe8d0948b345334f61a5c924Tim Janik return (guint*) g_array_free (result, FALSE); 977300e3bb247216fee40254822c2fb60a78a8ef21cOwen Taylor} 978300e3bb247216fee40254822c2fb60a78a8ef21cOwen Taylor 979ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikguint 980b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Penningtong_signal_new_valist (const gchar *signal_name, 981b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington GType itype, 982b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington GSignalFlags signal_flags, 983b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington GClosure *class_closure, 984b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington GSignalAccumulator accumulator, 985617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik gpointer accu_data, 986b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington GSignalCMarshaller c_marshaller, 987b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington GType return_type, 988b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington guint n_params, 989b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington va_list args) 990e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik{ 991e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik GType *param_types; 992e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik guint i; 993e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik guint signal_id; 994e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 995e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik if (n_params > 0) 996e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik { 997e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik param_types = g_new (GType, n_params); 998e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 999e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik for (i = 0; i < n_params; i++) 1000e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik param_types[i] = va_arg (args, GType); 1001e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik } 1002e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik else 1003e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik param_types = NULL; 1004e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1005e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik signal_id = g_signal_newv (signal_name, itype, signal_flags, 1006617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik class_closure, accumulator, accu_data, c_marshaller, 1007e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik return_type, n_params, param_types); 1008e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_free (param_types); 1009e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1010e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik return signal_id; 1011e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik} 1012e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1013e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janikguint 1014b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Penningtong_signal_newc (const gchar *signal_name, 1015b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington GType itype, 1016b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington GSignalFlags signal_flags, 1017b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington guint class_offset, 1018617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik GSignalAccumulator accumulator, 1019617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik gpointer accu_data, 1020b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington GSignalCMarshaller c_marshaller, 1021b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington GType return_type, 1022b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington guint n_params, 1023b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington ...) 1024b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington{ 1025b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington va_list args; 1026b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington guint signal_id; 1027b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington 1028b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington g_return_val_if_fail (signal_name != NULL, 0); 1029b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington 1030b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington va_start (args, n_params); 1031b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington 1032b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington signal_id = g_signal_new_valist (signal_name, itype, signal_flags, 103343b692c8eb49a82657d9cb09a222dc66f2cc0199Tim Janik class_offset ? g_signal_type_cclosure_new (itype, class_offset) : NULL, 1034617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik accumulator, accu_data, c_marshaller, 1035b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington return_type, n_params, args); 1036b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington 1037b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington va_end (args); 1038b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington 1039b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington return signal_id; 1040b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington} 1041b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Pennington 1042b3c410dee1b3d3e72ad1e76c7dc597a07482137dHavoc Penningtonguint 1043ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikg_signal_newv (const gchar *signal_name, 1044ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik GType itype, 1045830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik GSignalFlags signal_flags, 1046ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik GClosure *class_closure, 1047ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik GSignalAccumulator accumulator, 1048617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik gpointer accu_data, 1049ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik GSignalCMarshaller c_marshaller, 1050ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik GType return_type, 1051ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik guint n_params, 1052ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik GType *param_types) 1053ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 1054ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik gchar *name; 1055ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik guint signal_id, i; 1056ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik SignalNode *node; 1057ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1058ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_return_val_if_fail (signal_name != NULL, 0); 1059ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_return_val_if_fail (G_TYPE_IS_INSTANTIATABLE (itype) || G_TYPE_IS_INTERFACE (itype), 0); 1060ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (n_params) 1061ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_return_val_if_fail (param_types != NULL, 0); 106243b692c8eb49a82657d9cb09a222dc66f2cc0199Tim Janik g_return_val_if_fail ((return_type & G_SIGNAL_TYPE_STATIC_SCOPE) == 0, 0); 1063617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik if (return_type == (G_TYPE_NONE & ~G_SIGNAL_TYPE_STATIC_SCOPE)) 1064ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_return_val_if_fail (accumulator == NULL, 0); 1065617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik if (!accumulator) 1066617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik g_return_val_if_fail (accu_data == NULL, 0); 1067617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik 1068ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik name = g_strdup (signal_name); 10699abb30720036dfd464a142555aae7cce5e85c3d6Owen Taylor g_strdelimit (name, G_STR_DELIMITERS ":^", '_'); /* FIXME do character checks like for types */ 1070ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1071ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_LOCK (g_signal_mutex); 1072ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 10738a572c0da1be99527c52f620dc7fd04eb0775bdeTim Janik signal_id = signal_id_lookup (g_quark_try_string (name), itype); 1074ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node = LOOKUP_SIGNAL_NODE (signal_id); 1075ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (node && !node->destroyed) 1076ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 1077ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_warning (G_STRLOC ": signal \"%s\" already exists in the `%s' %s", 1078ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik name, 1079ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_type_name (node->itype), 1080ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_TYPE_IS_INTERFACE (node->itype) ? "interface" : "class ancestry"); 1081ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_free (name); 1082ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_UNLOCK (g_signal_mutex); 1083ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik return 0; 1084ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 1085ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (node && node->itype != itype) 1086ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 1087ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_warning (G_STRLOC ": signal \"%s\" for type `%s' was previously created for type `%s'", 1088ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik name, 1089ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_type_name (itype), 1090ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_type_name (node->itype)); 1091ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_free (name); 1092ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_UNLOCK (g_signal_mutex); 1093ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik return 0; 1094ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 1095ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik for (i = 0; i < n_params; i++) 109637e4b8c87e8b0574a806a6f1d2284e4ab45341b3Tim Janik if (!G_TYPE_IS_VALUE (param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE)) 1097ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 1098ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_warning (G_STRLOC ": parameter %d of type `%s' for signal \"%s::%s\" is not a value type", 1099bbc5a3adac7d6d5dbdcf956d7d185e9910c3034bTim Janik i + 1, g_type_name (param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE), g_type_name (itype), name); 1100ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_free (name); 1101ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_UNLOCK (g_signal_mutex); 1102ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik return 0; 1103ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 1104bbc5a3adac7d6d5dbdcf956d7d185e9910c3034bTim Janik if (return_type != G_TYPE_NONE && !G_TYPE_IS_VALUE (return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE)) 1105ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 1106ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_warning (G_STRLOC ": return value of type `%s' for signal \"%s::%s\" is not a value type", 1107bbc5a3adac7d6d5dbdcf956d7d185e9910c3034bTim Janik g_type_name (return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE), g_type_name (itype), name); 1108ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_free (name); 1109ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_UNLOCK (g_signal_mutex); 1110ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik return 0; 1111ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 1112b7d54841ee594eebfec33d6dc32596eef32acbfdTim Janik if (return_type != G_TYPE_NONE && 1113b7d54841ee594eebfec33d6dc32596eef32acbfdTim Janik (signal_flags & (G_SIGNAL_RUN_FIRST | G_SIGNAL_RUN_LAST | G_SIGNAL_RUN_CLEANUP)) == G_SIGNAL_RUN_FIRST) 1114b7d54841ee594eebfec33d6dc32596eef32acbfdTim Janik { 1115b7d54841ee594eebfec33d6dc32596eef32acbfdTim Janik g_warning (G_STRLOC ": signal \"%s::%s\" has return type `%s' and is only G_SIGNAL_RUN_FIRST", 1116b7d54841ee594eebfec33d6dc32596eef32acbfdTim Janik g_type_name (itype), name, 1117b7d54841ee594eebfec33d6dc32596eef32acbfdTim Janik g_type_name (return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE)); 1118b7d54841ee594eebfec33d6dc32596eef32acbfdTim Janik g_free (name); 1119b7d54841ee594eebfec33d6dc32596eef32acbfdTim Janik G_UNLOCK (g_signal_mutex); 1120b7d54841ee594eebfec33d6dc32596eef32acbfdTim Janik return 0; 1121b7d54841ee594eebfec33d6dc32596eef32acbfdTim Janik } 1122ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1123ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik /* setup permanent portion of signal node */ 1124ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (!node) 1125ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 1126ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik SignalKey key; 1127ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1128ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik signal_id = g_n_signal_nodes++; 1129ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node = g_new (SignalNode, 1); 1130ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node->signal_id = signal_id; 1131ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_signal_nodes = g_renew (SignalNode*, g_signal_nodes, g_n_signal_nodes); 1132ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_signal_nodes[signal_id] = node; 1133ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node->itype = itype; 1134ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node->name = name; 1135ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik key.itype = itype; 1136ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik key.quark = g_quark_from_string (node->name); 1137ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik key.signal_id = signal_id; 1138ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_bsearch_array_insert (&g_signal_key_bsa, &key, FALSE); 1139ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_strdelimit (node->name, "_", '-'); 1140ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik key.quark = g_quark_from_static_string (node->name); 1141ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_bsearch_array_insert (&g_signal_key_bsa, &key, FALSE); 1142ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 1143ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node->destroyed = FALSE; 1144ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1145ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik /* setup reinitializable portion */ 1146830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik node->flags = signal_flags & G_SIGNAL_FLAGS_MASK; 1147ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node->n_params = n_params; 1148ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node->param_types = g_memdup (param_types, sizeof (GType) * n_params); 1149ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node->return_type = return_type; 1150ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node->class_closure = class_closure ? g_closure_ref (class_closure) : NULL; 115112a0d19c11c29e3d4b7a5f02a07576309e2787a6Tim Janik if (class_closure) 115212a0d19c11c29e3d4b7a5f02a07576309e2787a6Tim Janik g_closure_sink (class_closure); 1153617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik if (accumulator) 1154617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik { 1155617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik node->accumulator = g_new (SignalAccumulator, 1); 1156617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik node->accumulator->func = accumulator; 1157617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik node->accumulator->data = accu_data; 1158617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik } 1159617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik else 1160617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik node->accumulator = NULL; 1161ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node->c_marshaller = c_marshaller; 1162ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node->emission_hooks = NULL; 1163ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (node->c_marshaller && class_closure && G_CLOSURE_NEEDS_MARSHAL (class_closure)) 1164ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_closure_set_marshal (class_closure, node->c_marshaller); 1165ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_UNLOCK (g_signal_mutex); 1166ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik return signal_id; 1167ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 1168ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1169ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikstatic void 1170ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janiksignal_destroy_R (SignalNode *signal_node) 1171ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 1172ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik SignalNode node = *signal_node; 1173ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1174ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik signal_node->destroyed = TRUE; 1175ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1176ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik /* reentrancy caution, zero out real contents first */ 1177ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik signal_node->n_params = 0; 1178ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik signal_node->param_types = NULL; 1179ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik signal_node->return_type = 0; 1180ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik signal_node->class_closure = NULL; 1181ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik signal_node->accumulator = NULL; 1182ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik signal_node->c_marshaller = NULL; 1183ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik signal_node->emission_hooks = NULL; 1184ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1185782a8e2e7c69c3d98bd69bcfdbb65ded520576f4Tim Janik#ifdef G_ENABLE_DEBUG 1186ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik /* check current emissions */ 1187ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 1188ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik Emission *emission; 1189ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1190ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik for (emission = (node.flags & G_SIGNAL_NO_RECURSE) ? g_restart_emissions : g_recursive_emissions; 1191ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik emission; emission = emission->next) 1192ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (emission->signal_id == node.signal_id) 1193ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_critical (G_STRLOC ": signal \"%s\" being destroyed is currently in emission (instance `%p')", 1194ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node.name, emission->instance); 1195ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 1196ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik#endif 1197ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1198ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik /* free contents that need to 1199ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik */ 1200ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_UNLOCK (g_signal_mutex); 1201ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_free (node.param_types); 1202ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_closure_unref (node.class_closure); 1203617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik g_free (node.accumulator); 1204ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (node.emission_hooks) 1205ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 1206ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_hook_list_clear (node.emission_hooks); 1207ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_free (node.emission_hooks); 1208ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 1209ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_LOCK (g_signal_mutex); 1210ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 1211ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1212abc5cbbe3e1f6e6bdc40d94741713e9efb6d580dTim Janikgulong 12133cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janikg_signal_connect_closure_by_id (gpointer instance, 12143cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik guint signal_id, 12153cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik GQuark detail, 12163cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik GClosure *closure, 12173cc60a9ab1df2dcf393a15b8a66e0602817646bdTim Janik gboolean after) 1218ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 1219ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik SignalNode *node; 1220abc5cbbe3e1f6e6bdc40d94741713e9efb6d580dTim Janik gulong handler_seq_no = 0; 1221ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1222ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), 0); 1223ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_return_val_if_fail (signal_id > 0, 0); 1224ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_return_val_if_fail (closure != NULL, 0); 1225ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1226ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_LOCK (g_signal_mutex); 1227ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node = LOOKUP_SIGNAL_NODE (signal_id); 1228e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik if (node) 1229830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik { 1230e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik if (detail && !(node->flags & G_SIGNAL_DETAILED)) 1231e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_warning ("%s: signal id `%u' does not support detail (%u)", G_STRLOC, signal_id, detail); 1232e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik else if (!g_type_is_a (G_TYPE_FROM_INSTANCE (instance), node->itype)) 1233e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_warning ("%s: signal id `%u' is invalid for instance `%p'", G_STRLOC, signal_id, instance); 1234e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik else 1235e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik { 1236e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik Handler *handler = handler_new (after); 1237e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1238abc5cbbe3e1f6e6bdc40d94741713e9efb6d580dTim Janik handler_seq_no = handler->sequential_number; 1239e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik handler->detail = detail; 1240e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik handler->closure = g_closure_ref (closure); 124112a0d19c11c29e3d4b7a5f02a07576309e2787a6Tim Janik g_closure_sink (closure); 1242e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik handler_insert (signal_id, instance, handler); 1243e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik if (node->c_marshaller && G_CLOSURE_NEEDS_MARSHAL (closure)) 1244e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_closure_set_marshal (closure, node->c_marshaller); 1245e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik } 1246ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 1247ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik else 1248ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_warning ("%s: signal id `%u' is invalid for instance `%p'", G_STRLOC, signal_id, instance); 1249ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_UNLOCK (g_signal_mutex); 1250ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1251abc5cbbe3e1f6e6bdc40d94741713e9efb6d580dTim Janik return handler_seq_no; 1252ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 1253ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1254abc5cbbe3e1f6e6bdc40d94741713e9efb6d580dTim Janikgulong 1255e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janikg_signal_connect_closure (gpointer instance, 1256e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik const gchar *detailed_signal, 1257e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik GClosure *closure, 1258e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik gboolean after) 1259e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik{ 1260abc5cbbe3e1f6e6bdc40d94741713e9efb6d580dTim Janik guint signal_id; 1261abc5cbbe3e1f6e6bdc40d94741713e9efb6d580dTim Janik gulong handler_seq_no = 0; 1262e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik GQuark detail = 0; 1263e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik GType itype; 1264e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1265e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), 0); 1266e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_return_val_if_fail (detailed_signal != NULL, 0); 1267e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_return_val_if_fail (closure != NULL, 0); 1268e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1269e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik G_LOCK (g_signal_mutex); 1270e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik itype = G_TYPE_FROM_INSTANCE (instance); 1271e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik signal_id = signal_parse_name (detailed_signal, itype, &detail, TRUE); 1272e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik if (signal_id) 1273e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik { 1274e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik SignalNode *node = LOOKUP_SIGNAL_NODE (signal_id); 1275e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1276e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik if (detail && !(node->flags & G_SIGNAL_DETAILED)) 1277e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_warning ("%s: signal `%s' does not support details", G_STRLOC, detailed_signal); 1278e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik else if (!g_type_is_a (itype, node->itype)) 1279e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_warning ("%s: signal `%s' is invalid for instance `%p'", G_STRLOC, detailed_signal, instance); 1280e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik else 1281e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik { 1282e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik Handler *handler = handler_new (after); 1283e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1284abc5cbbe3e1f6e6bdc40d94741713e9efb6d580dTim Janik handler_seq_no = handler->sequential_number; 1285e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik handler->detail = detail; 1286e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik handler->closure = g_closure_ref (closure); 128712a0d19c11c29e3d4b7a5f02a07576309e2787a6Tim Janik g_closure_sink (closure); 1288e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik handler_insert (signal_id, instance, handler); 1289e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik if (node->c_marshaller && G_CLOSURE_NEEDS_MARSHAL (handler->closure)) 1290e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_closure_set_marshal (handler->closure, node->c_marshaller); 1291e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik } 1292e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik } 1293e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik else 1294e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_warning ("%s: signal `%s' is invalid for instance `%p'", G_STRLOC, detailed_signal, instance); 1295e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik G_UNLOCK (g_signal_mutex); 1296e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1297abc5cbbe3e1f6e6bdc40d94741713e9efb6d580dTim Janik return handler_seq_no; 1298e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik} 1299e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1300abc5cbbe3e1f6e6bdc40d94741713e9efb6d580dTim Janikgulong 1301e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janikg_signal_connect_data (gpointer instance, 1302e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik const gchar *detailed_signal, 1303e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik GCallback c_handler, 1304e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik gpointer data, 1305e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik GClosureNotify destroy_data, 1306e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik gboolean swapped, 1307e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik gboolean after) 1308e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik{ 1309abc5cbbe3e1f6e6bdc40d94741713e9efb6d580dTim Janik guint signal_id; 1310abc5cbbe3e1f6e6bdc40d94741713e9efb6d580dTim Janik gulong handler_seq_no = 0; 1311e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik GQuark detail = 0; 1312e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik GType itype; 1313e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1314e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), 0); 1315e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_return_val_if_fail (detailed_signal != NULL, 0); 1316e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_return_val_if_fail (c_handler != NULL, 0); 1317e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1318e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik G_LOCK (g_signal_mutex); 1319e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik itype = G_TYPE_FROM_INSTANCE (instance); 1320e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik signal_id = signal_parse_name (detailed_signal, itype, &detail, TRUE); 1321e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik if (signal_id) 1322e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik { 1323e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik SignalNode *node = LOOKUP_SIGNAL_NODE (signal_id); 1324e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1325e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik if (detail && !(node->flags & G_SIGNAL_DETAILED)) 1326e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_warning ("%s: signal `%s' does not support details", G_STRLOC, detailed_signal); 1327e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik else if (!g_type_is_a (itype, node->itype)) 1328e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_warning ("%s: signal `%s' is invalid for instance `%p'", G_STRLOC, detailed_signal, instance); 1329e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik else 1330e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik { 1331e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik Handler *handler = handler_new (after); 1332e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1333abc5cbbe3e1f6e6bdc40d94741713e9efb6d580dTim Janik handler_seq_no = handler->sequential_number; 1334e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik handler->detail = detail; 1335e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik handler->closure = g_closure_ref ((swapped ? g_cclosure_new_swap : g_cclosure_new) (c_handler, data, destroy_data)); 133612a0d19c11c29e3d4b7a5f02a07576309e2787a6Tim Janik g_closure_sink (handler->closure); 1337e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik handler_insert (signal_id, instance, handler); 1338e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik if (node->c_marshaller && G_CLOSURE_NEEDS_MARSHAL (handler->closure)) 1339e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_closure_set_marshal (handler->closure, node->c_marshaller); 1340e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik } 1341e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik } 1342e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik else 1343e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_warning ("%s: signal `%s' is invalid for instance `%p'", G_STRLOC, detailed_signal, instance); 1344e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik G_UNLOCK (g_signal_mutex); 1345e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1346abc5cbbe3e1f6e6bdc40d94741713e9efb6d580dTim Janik return handler_seq_no; 1347e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik} 1348e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1349ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikvoid 1350cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janikg_signal_handler_block (gpointer instance, 1351abc5cbbe3e1f6e6bdc40d94741713e9efb6d580dTim Janik gulong handler_id) 1352cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik{ 1353cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik Handler *handler; 1354cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik 1355cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance)); 1356cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik g_return_if_fail (handler_id > 0); 1357cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik 1358cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik G_LOCK (g_signal_mutex); 1359cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik handler = handler_lookup (instance, handler_id, NULL); 1360cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik if (handler) 1361cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik { 1362cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik#ifndef G_DISABLE_CHECKS 1363cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik if (handler->block_count >= HANDLER_MAX_BLOCK_COUNT - 1) 1364cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik g_error (G_STRLOC ": handler block_count overflow, %s", REPORT_BUG); 1365cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik#endif 1366cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik handler->block_count += 1; 1367cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik } 1368cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik else 1369abc5cbbe3e1f6e6bdc40d94741713e9efb6d580dTim Janik g_warning ("%s: instance `%p' has no handler with id `%lu'", G_STRLOC, instance, handler_id); 1370cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik G_UNLOCK (g_signal_mutex); 1371cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik} 1372cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik 1373cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janikvoid 1374cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janikg_signal_handler_unblock (gpointer instance, 1375abc5cbbe3e1f6e6bdc40d94741713e9efb6d580dTim Janik gulong handler_id) 1376cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik{ 1377cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik Handler *handler; 1378cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik 1379cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance)); 1380cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik g_return_if_fail (handler_id > 0); 1381cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik 1382cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik G_LOCK (g_signal_mutex); 1383cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik handler = handler_lookup (instance, handler_id, NULL); 1384cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik if (handler) 1385cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik { 1386cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik if (handler->block_count) 1387cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik handler->block_count -= 1; 1388cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik else 1389abc5cbbe3e1f6e6bdc40d94741713e9efb6d580dTim Janik g_warning (G_STRLOC ": handler `%lu' of instance `%p' is not blocked", handler_id, instance); 1390cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik } 1391cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik else 1392abc5cbbe3e1f6e6bdc40d94741713e9efb6d580dTim Janik g_warning ("%s: instance `%p' has no handler with id `%lu'", G_STRLOC, instance, handler_id); 1393cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik G_UNLOCK (g_signal_mutex); 1394cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik} 1395cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik 1396cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janikvoid 1397ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikg_signal_handler_disconnect (gpointer instance, 1398abc5cbbe3e1f6e6bdc40d94741713e9efb6d580dTim Janik gulong handler_id) 1399ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 1400ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik Handler *handler; 1401ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik guint signal_id; 1402ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1403ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance)); 1404ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_return_if_fail (handler_id > 0); 1405ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1406ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_LOCK (g_signal_mutex); 1407ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik handler = handler_lookup (instance, handler_id, &signal_id); 1408ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (handler) 1409ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 1410abc5cbbe3e1f6e6bdc40d94741713e9efb6d580dTim Janik handler->sequential_number = 0; 1411ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik handler->block_count = 1; 1412ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik handler_unref_R (signal_id, instance, handler); 1413ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 1414ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik else 1415abc5cbbe3e1f6e6bdc40d94741713e9efb6d580dTim Janik g_warning ("%s: instance `%p' has no handler with id `%lu'", G_STRLOC, instance, handler_id); 1416ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_UNLOCK (g_signal_mutex); 1417ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 1418ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 141972df5e6cabe02f155ff767650cdaf10046c26e0eTim Janikgboolean 142072df5e6cabe02f155ff767650cdaf10046c26e0eTim Janikg_signal_handler_is_connected (gpointer instance, 142172df5e6cabe02f155ff767650cdaf10046c26e0eTim Janik gulong handler_id) 142272df5e6cabe02f155ff767650cdaf10046c26e0eTim Janik{ 142372df5e6cabe02f155ff767650cdaf10046c26e0eTim Janik Handler *handler; 142472df5e6cabe02f155ff767650cdaf10046c26e0eTim Janik gboolean connected; 142572df5e6cabe02f155ff767650cdaf10046c26e0eTim Janik 142672df5e6cabe02f155ff767650cdaf10046c26e0eTim Janik g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), FALSE); 142772df5e6cabe02f155ff767650cdaf10046c26e0eTim Janik g_return_val_if_fail (handler_id > 0, FALSE); 142872df5e6cabe02f155ff767650cdaf10046c26e0eTim Janik 142972df5e6cabe02f155ff767650cdaf10046c26e0eTim Janik G_LOCK (g_signal_mutex); 143072df5e6cabe02f155ff767650cdaf10046c26e0eTim Janik handler = handler_lookup (instance, handler_id, NULL); 143172df5e6cabe02f155ff767650cdaf10046c26e0eTim Janik connected = handler != NULL; 143272df5e6cabe02f155ff767650cdaf10046c26e0eTim Janik G_UNLOCK (g_signal_mutex); 143372df5e6cabe02f155ff767650cdaf10046c26e0eTim Janik 143472df5e6cabe02f155ff767650cdaf10046c26e0eTim Janik return connected; 143572df5e6cabe02f155ff767650cdaf10046c26e0eTim Janik} 143672df5e6cabe02f155ff767650cdaf10046c26e0eTim Janik 1437ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikvoid 143883c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janikg_signal_handlers_destroy (gpointer instance) 1439ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 1440ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik GBSearchArray *hlbsa; 1441ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1442ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance)); 1443ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1444ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_LOCK (g_signal_mutex); 1445ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik hlbsa = g_hash_table_lookup (g_handler_list_bsa_ht, instance); 1446ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (hlbsa) 1447ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 1448ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik guint i; 1449ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1450ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik /* reentrancy caution, delete instance trace first */ 1451ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_hash_table_remove (g_handler_list_bsa_ht, instance); 145283c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 1453ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik for (i = 0; i < hlbsa->n_nodes; i++) 1454ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 1455ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik HandlerList *hlist = g_bsearch_array_get_nth (hlbsa, i); 1456ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik Handler *handler = hlist->handlers; 1457ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1458ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik while (handler) 1459ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 1460ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik Handler *tmp = handler; 1461ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1462ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik handler = tmp->next; 1463ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik tmp->block_count = 1; 1464ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik /* cruel unlink, this works because _all_ handlers vanish */ 1465ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik tmp->next = NULL; 1466ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik tmp->prev = tmp; 1467abc5cbbe3e1f6e6bdc40d94741713e9efb6d580dTim Janik if (tmp->sequential_number) 1468ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 1469abc5cbbe3e1f6e6bdc40d94741713e9efb6d580dTim Janik tmp->sequential_number = 0; 1470ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik handler_unref_R (0, NULL, tmp); 1471ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 1472ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 1473ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 147445fb71949a0c0e27fe8d0948b345334f61a5c924Tim Janik g_bsearch_array_destroy (hlbsa); 1475ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 1476ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_UNLOCK (g_signal_mutex); 1477ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 1478ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1479abc5cbbe3e1f6e6bdc40d94741713e9efb6d580dTim Janikgulong 1480cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janikg_signal_handler_find (gpointer instance, 1481cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik GSignalMatchType mask, 1482cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik guint signal_id, 1483cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik GQuark detail, 1484cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik GClosure *closure, 1485cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik gpointer func, 1486cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik gpointer data) 1487ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 1488abc5cbbe3e1f6e6bdc40d94741713e9efb6d580dTim Janik gulong handler_seq_no = 0; 1489ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1490cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), 0); 1491cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik g_return_val_if_fail ((mask & ~G_SIGNAL_MATCH_MASK) == 0, 0); 149283c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 1493cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik if (mask & G_SIGNAL_MATCH_MASK) 1494ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 149583c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik HandlerMatch *mlist; 149683c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 1497cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik G_LOCK (g_signal_mutex); 149883c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik mlist = handlers_find (instance, mask, signal_id, detail, closure, func, data, TRUE); 149983c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik if (mlist) 150083c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik { 1501abc5cbbe3e1f6e6bdc40d94741713e9efb6d580dTim Janik handler_seq_no = mlist->handler->sequential_number; 150283c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik handler_match_free1_R (mlist, instance); 150383c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik } 1504cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik G_UNLOCK (g_signal_mutex); 1505ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 150683c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 1507abc5cbbe3e1f6e6bdc40d94741713e9efb6d580dTim Janik return handler_seq_no; 1508ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 1509ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1510cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janikstatic guint 151183c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janiksignal_handlers_foreach_matched_R (gpointer instance, 151283c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik GSignalMatchType mask, 151383c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik guint signal_id, 151483c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik GQuark detail, 151583c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik GClosure *closure, 151683c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik gpointer func, 151783c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik gpointer data, 151883c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik void (*callback) (gpointer instance, 1519abc5cbbe3e1f6e6bdc40d94741713e9efb6d580dTim Janik gulong handler_seq_no)) 1520ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 152183c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik HandlerMatch *mlist; 1522cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik guint n_handlers = 0; 152383c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 152483c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik mlist = handlers_find (instance, mask, signal_id, detail, closure, func, data, FALSE); 152583c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik while (mlist) 1526ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 1527cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik n_handlers++; 1528abc5cbbe3e1f6e6bdc40d94741713e9efb6d580dTim Janik if (mlist->handler->sequential_number) 1529abc5cbbe3e1f6e6bdc40d94741713e9efb6d580dTim Janik { 1530abc5cbbe3e1f6e6bdc40d94741713e9efb6d580dTim Janik G_UNLOCK (g_signal_mutex); 1531abc5cbbe3e1f6e6bdc40d94741713e9efb6d580dTim Janik callback (instance, mlist->handler->sequential_number); 1532abc5cbbe3e1f6e6bdc40d94741713e9efb6d580dTim Janik G_LOCK (g_signal_mutex); 1533abc5cbbe3e1f6e6bdc40d94741713e9efb6d580dTim Janik } 153483c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik mlist = handler_match_free1_R (mlist, instance); 1535ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 153683c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 1537cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik return n_handlers; 1538ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 1539ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1540ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikguint 1541cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janikg_signal_handlers_block_matched (gpointer instance, 1542cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik GSignalMatchType mask, 1543cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik guint signal_id, 1544cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik GQuark detail, 1545cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik GClosure *closure, 1546cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik gpointer func, 1547cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik gpointer data) 1548ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 1549cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik guint n_handlers = 0; 155083c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 1551cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), FALSE); 1552cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik g_return_val_if_fail ((mask & ~G_SIGNAL_MATCH_MASK) == 0, FALSE); 155383c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 1554cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik if (mask & (G_SIGNAL_MATCH_CLOSURE | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA)) 1555cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik { 1556cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik G_LOCK (g_signal_mutex); 155783c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik n_handlers = signal_handlers_foreach_matched_R (instance, mask, signal_id, detail, 155883c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik closure, func, data, 155983c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik g_signal_handler_block); 1560cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik G_UNLOCK (g_signal_mutex); 1561cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik } 156283c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 1563cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik return n_handlers; 1564cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik} 1565cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik 1566cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janikguint 1567cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janikg_signal_handlers_unblock_matched (gpointer instance, 1568cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik GSignalMatchType mask, 1569cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik guint signal_id, 1570cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik GQuark detail, 1571cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik GClosure *closure, 1572cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik gpointer func, 1573cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik gpointer data) 1574cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik{ 1575cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik guint n_handlers = 0; 1576ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1577cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), FALSE); 1578cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik g_return_val_if_fail ((mask & ~G_SIGNAL_MATCH_MASK) == 0, FALSE); 1579ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1580cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik if (mask & (G_SIGNAL_MATCH_CLOSURE | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA)) 1581cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik { 1582cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik G_LOCK (g_signal_mutex); 158383c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik n_handlers = signal_handlers_foreach_matched_R (instance, mask, signal_id, detail, 158483c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik closure, func, data, 158583c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik g_signal_handler_unblock); 1586cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik G_UNLOCK (g_signal_mutex); 1587cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik } 158883c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 1589cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik return n_handlers; 1590cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik} 1591cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik 1592cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janikguint 1593cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janikg_signal_handlers_disconnect_matched (gpointer instance, 1594cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik GSignalMatchType mask, 1595cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik guint signal_id, 1596cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik GQuark detail, 1597cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik GClosure *closure, 1598cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik gpointer func, 1599cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik gpointer data) 1600cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik{ 1601cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik guint n_handlers = 0; 160283c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 1603cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), FALSE); 1604cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik g_return_val_if_fail ((mask & ~G_SIGNAL_MATCH_MASK) == 0, FALSE); 160583c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 1606cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik if (mask & (G_SIGNAL_MATCH_CLOSURE | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA)) 1607cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik { 1608cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik G_LOCK (g_signal_mutex); 160983c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik n_handlers = signal_handlers_foreach_matched_R (instance, mask, signal_id, detail, 161083c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik closure, func, data, 161183c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik g_signal_handler_disconnect); 1612cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik G_UNLOCK (g_signal_mutex); 1613cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik } 161483c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik 1615cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik return n_handlers; 1616ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 1617ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1618ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikgboolean 1619cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janikg_signal_has_handler_pending (gpointer instance, 1620cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik guint signal_id, 1621cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik GQuark detail, 1622cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik gboolean may_be_blocked) 1623ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 162483c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik HandlerMatch *mlist; 162583c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik gboolean has_pending; 1626ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1627ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), FALSE); 1628ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_return_val_if_fail (signal_id > 0, FALSE); 1629ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1630ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_LOCK (g_signal_mutex); 1631830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik if (detail) 1632830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik { 1633830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik SignalNode *node = LOOKUP_SIGNAL_NODE (signal_id); 1634830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik 1635830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik if (!(node->flags & G_SIGNAL_DETAILED)) 1636830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik { 1637830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik g_warning ("%s: signal id `%u' does not support detail (%u)", G_STRLOC, signal_id, detail); 1638830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik G_UNLOCK (g_signal_mutex); 1639830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik return FALSE; 1640830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik } 1641830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik } 164283c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik mlist = handlers_find (instance, 164383c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik (G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_DETAIL | (may_be_blocked ? 0 : G_SIGNAL_MATCH_UNBLOCKED)), 164483c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik signal_id, detail, NULL, NULL, NULL, TRUE); 164583c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik if (mlist) 164683c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik { 164783c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik has_pending = TRUE; 164883c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik handler_match_free1_R (mlist, instance); 164983c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik } 165083c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik else 165183c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik has_pending = FALSE; 1652ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_UNLOCK (g_signal_mutex); 1653ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 165483c45024e3d3a56ac17eb08dcddae048005bbb71Tim Janik return has_pending; 1655ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 1656ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1657ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikvoid 1658ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janikg_signal_emitv (const GValue *instance_and_params, 1659ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik guint signal_id, 1660830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik GQuark detail, 1661ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik GValue *return_value) 1662ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 1663ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik const GValue *param_values; 1664e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik gpointer instance; 1665e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik SignalNode *node; 1666ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik guint i; 1667ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1668ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_return_if_fail (instance_and_params != NULL); 166937e4b8c87e8b0574a806a6f1d2284e4ab45341b3Tim Janik instance = g_value_peek_pointer (instance_and_params); 1670ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance)); 1671ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_return_if_fail (signal_id > 0); 1672e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1673ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik param_values = instance_and_params + 1; 1674ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1675ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_LOCK (g_signal_mutex); 1676ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node = LOOKUP_SIGNAL_NODE (signal_id); 1677e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik if (!node || !g_type_is_a (G_TYPE_FROM_INSTANCE (instance), node->itype)) 1678cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik { 1679cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik g_warning ("%s: signal id `%u' is invalid for instance `%p'", G_STRLOC, signal_id, instance); 1680cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik G_UNLOCK (g_signal_mutex); 1681cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik return; 1682cfe0780d3ea8a5a9bdd3497926437cde42298086Tim Janik } 1683782a8e2e7c69c3d98bd69bcfdbb65ded520576f4Tim Janik#ifdef G_ENABLE_DEBUG 1684830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik if (detail && !(node->flags & G_SIGNAL_DETAILED)) 1685830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik { 1686830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik g_warning ("%s: signal id `%u' does not support detail (%u)", G_STRLOC, signal_id, detail); 1687830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik G_UNLOCK (g_signal_mutex); 1688830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik return; 1689830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik } 1690ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik for (i = 0; i < node->n_params; i++) 169137e4b8c87e8b0574a806a6f1d2284e4ab45341b3Tim Janik if (!G_TYPE_CHECK_VALUE_TYPE (param_values + i, node->param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE)) 1692ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 1693e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_critical ("%s: value for `%s' parameter %u for signal \"%s\" is of type `%s'", 1694e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik G_STRLOC, 1695bbc5a3adac7d6d5dbdcf956d7d185e9910c3034bTim Janik g_type_name (node->param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE), 1696ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik i, 1697ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node->name, 1698ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_VALUE_TYPE_NAME (param_values + i)); 1699ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_UNLOCK (g_signal_mutex); 1700ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik return; 1701ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 1702ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (node->return_type != G_TYPE_NONE) 1703ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 1704ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (!return_value) 1705ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 1706e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_critical ("%s: return value `%s' for signal \"%s\" is (NULL)", 1707e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik G_STRLOC, 1708bbc5a3adac7d6d5dbdcf956d7d185e9910c3034bTim Janik g_type_name (node->return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE), 1709ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node->name); 1710ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_UNLOCK (g_signal_mutex); 1711ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik return; 1712ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 171337e4b8c87e8b0574a806a6f1d2284e4ab45341b3Tim Janik else if (!node->accumulator && !G_TYPE_CHECK_VALUE_TYPE (return_value, node->return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE)) 1714ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 1715e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_critical ("%s: return value `%s' for signal \"%s\" is of type `%s'", 1716e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik G_STRLOC, 1717bbc5a3adac7d6d5dbdcf956d7d185e9910c3034bTim Janik g_type_name (node->return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE), 1718ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node->name, 1719ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_VALUE_TYPE_NAME (return_value)); 1720ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_UNLOCK (g_signal_mutex); 1721ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik return; 1722ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 1723ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 1724ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik else 1725ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik return_value = NULL; 1726782a8e2e7c69c3d98bd69bcfdbb65ded520576f4Tim Janik#endif /* G_ENABLE_DEBUG */ 1727e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1728830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik signal_emit_R (node, detail, instance, return_value, instance_and_params); 1729ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_UNLOCK (g_signal_mutex); 1730ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 1731ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1732e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janikvoid 1733e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janikg_signal_emit_valist (gpointer instance, 1734e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik guint signal_id, 1735e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik GQuark detail, 1736e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik va_list var_args) 1737e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik{ 1738e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik GValue *instance_and_params, stack_values[MAX_STACK_VALUES], *free_me = NULL; 1739e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik GValue *param_values; 1740e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik SignalNode *node; 1741e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik guint i; 1742e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1743e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance)); 1744e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_return_if_fail (signal_id > 0); 1745e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1746e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik G_LOCK (g_signal_mutex); 1747e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik node = LOOKUP_SIGNAL_NODE (signal_id); 1748e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik if (!node || !g_type_is_a (G_TYPE_FROM_INSTANCE (instance), node->itype)) 1749e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik { 1750e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_warning ("%s: signal id `%u' is invalid for instance `%p'", G_STRLOC, signal_id, instance); 1751e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik G_UNLOCK (g_signal_mutex); 1752e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik return; 1753e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik } 1754e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik#ifndef G_DISABLE_CHECKS 1755e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik if (detail && !(node->flags & G_SIGNAL_DETAILED)) 1756e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik { 1757e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_warning ("%s: signal id `%u' does not support detail (%u)", G_STRLOC, signal_id, detail); 1758e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik G_UNLOCK (g_signal_mutex); 1759e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik return; 1760e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik } 1761e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik#endif /* !G_DISABLE_CHECKS */ 1762e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1763e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik if (node->n_params < MAX_STACK_VALUES) 1764e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik instance_and_params = stack_values; 1765e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik else 1766e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik { 1767e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik free_me = g_new (GValue, node->n_params + 1); 1768e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik instance_and_params = free_me; 1769e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik } 1770e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik param_values = instance_and_params + 1; 1771e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik for (i = 0; i < node->n_params; i++) 1772e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik { 1773e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik gchar *error; 1774e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1775e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik param_values[i].g_type = 0; 1776bbc5a3adac7d6d5dbdcf956d7d185e9910c3034bTim Janik g_value_init (param_values + i, node->param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE); 1777bbc5a3adac7d6d5dbdcf956d7d185e9910c3034bTim Janik G_VALUE_COLLECT (param_values + i, 1778bbc5a3adac7d6d5dbdcf956d7d185e9910c3034bTim Janik var_args, 1779bbc5a3adac7d6d5dbdcf956d7d185e9910c3034bTim Janik node->param_types[i] & G_SIGNAL_TYPE_STATIC_SCOPE ? G_VALUE_NOCOPY_CONTENTS : 0, 1780bbc5a3adac7d6d5dbdcf956d7d185e9910c3034bTim Janik &error); 1781e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik if (error) 1782e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik { 1783e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_warning ("%s: %s", G_STRLOC, error); 1784e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_free (error); 1785e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1786e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik /* we purposely leak the value here, it might not be 1787e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik * in a sane state if an error condition occoured 1788e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik */ 1789e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik while (i--) 1790e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_value_unset (param_values + i); 1791e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1792e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik G_UNLOCK (g_signal_mutex); 1793e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_free (free_me); 1794e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik return; 1795e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik } 1796e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik } 1797e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik instance_and_params->g_type = 0; 1798f3ec41e8d22b5fa99b93ea753acb0de873732e94Jonathan Blandford g_value_init (instance_and_params, G_TYPE_FROM_INSTANCE (instance)); 1799e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_value_set_instance (instance_and_params, instance); 1800e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik if (node->return_type == G_TYPE_NONE) 1801e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik signal_emit_R (node, detail, instance, NULL, instance_and_params); 1802e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik else 1803e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik { 1804e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik GValue return_value = { 0, }; 1805e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik gchar *error = NULL; 1806e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1807bbc5a3adac7d6d5dbdcf956d7d185e9910c3034bTim Janik g_value_init (&return_value, node->return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE); 1808743f49cec9f4696c9eba32966d6ac78cd96c586dTim Janik signal_emit_R (node, detail, instance, &return_value, instance_and_params); 1809743f49cec9f4696c9eba32966d6ac78cd96c586dTim Janik G_VALUE_LCOPY (&return_value, 1810743f49cec9f4696c9eba32966d6ac78cd96c586dTim Janik var_args, 1811743f49cec9f4696c9eba32966d6ac78cd96c586dTim Janik node->return_type & G_SIGNAL_TYPE_STATIC_SCOPE ? G_VALUE_NOCOPY_CONTENTS : 0, 1812743f49cec9f4696c9eba32966d6ac78cd96c586dTim Janik &error); 1813e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik if (!error) 1814e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_value_unset (&return_value); 1815e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik else 1816e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik { 1817e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_warning ("%s: %s", G_STRLOC, error); 1818e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_free (error); 1819e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1820e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik /* we purposely leak the value here, it might not be 1821e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik * in a sane state if an error condition occoured 1822e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik */ 1823e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik } 1824e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik } 1825e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik for (i = 0; i < node->n_params; i++) 1826e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_value_unset (param_values + i); 1827e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_value_unset (instance_and_params); 1828e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik if (free_me) 1829e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_free (free_me); 1830e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik G_UNLOCK (g_signal_mutex); 1831e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik} 1832e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1833e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janikvoid 1834e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janikg_signal_emit (gpointer instance, 1835e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik guint signal_id, 1836e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik GQuark detail, 1837e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik ...) 1838e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik{ 1839e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik va_list var_args; 1840e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1841e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik va_start (var_args, detail); 1842e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_signal_emit_valist (instance, signal_id, detail, var_args); 1843e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik va_end (var_args); 1844e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik} 1845e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1846e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janikvoid 1847e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janikg_signal_emit_by_name (gpointer instance, 1848e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik const gchar *detailed_signal, 1849e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik ...) 1850e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik{ 1851e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik GQuark detail = 0; 1852e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik guint signal_id; 1853e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1854e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance)); 1855e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_return_if_fail (detailed_signal != NULL); 1856e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1857e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik G_LOCK (g_signal_mutex); 1858e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik signal_id = signal_parse_name (detailed_signal, G_TYPE_FROM_INSTANCE (instance), &detail, TRUE); 1859e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik G_UNLOCK (g_signal_mutex); 1860e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1861e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik if (signal_id) 1862e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik { 1863e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik va_list var_args; 1864e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1865e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik va_start (var_args, detailed_signal); 1866e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_signal_emit_valist (instance, signal_id, detail, var_args); 1867e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik va_end (var_args); 1868e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik } 1869e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik else 1870e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_warning ("%s: signal name `%s' is invalid for instance `%p'", G_STRLOC, detailed_signal, instance); 1871e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik} 1872e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 1873617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janikstatic inline gboolean 1874617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janikaccumulate (GSignalInvocationHint *ihint, 1875617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik GValue *return_accu, 1876617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik GValue *handler_return, 1877617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik SignalAccumulator *accumulator) 1878617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik{ 1879617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik gboolean continue_emission; 1880617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik 1881617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik if (!accumulator) 1882617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik return TRUE; 1883617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik 1884617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik continue_emission = accumulator->func (ihint, return_accu, handler_return, accumulator->data); 1885617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik g_value_reset (handler_return); 1886617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik 1887617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik return continue_emission; 1888617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik} 1889617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik 1890e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janikstatic gboolean 1891ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janiksignal_emit_R (SignalNode *node, 1892830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik GQuark detail, 1893ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik gpointer instance, 1894617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik GValue *emission_return, 1895ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik const GValue *instance_and_params) 1896ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik{ 1897ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik EmissionState emission_state = 0; 1898617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik SignalAccumulator *accumulator; 1899830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik GSignalInvocationHint ihint; 1900ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik GClosure *class_closure; 1901ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik HandlerList *hlist; 1902830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik Handler *handler_list = NULL; 1903617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik GValue *return_accu, accu = { 0, }; 1904ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik guint signal_id = node->signal_id; 1905abc5cbbe3e1f6e6bdc40d94741713e9efb6d580dTim Janik gulong max_sequential_handler_number; 1906e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik gboolean return_value_altered = FALSE; 1907ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 190822357542e9cb017e2dfeee0004d6a22ed8897468Tim Janik#ifdef G_ENABLE_DEBUG 190922357542e9cb017e2dfeee0004d6a22ed8897468Tim Janik IF_DEBUG (SIGNALS, g_trace_instance_signals == instance || g_trap_instance_signals == instance) 191022357542e9cb017e2dfeee0004d6a22ed8897468Tim Janik { 191143b692c8eb49a82657d9cb09a222dc66f2cc0199Tim Janik g_message ("%s::%s(%u) emitted (instance=%p, signal-node=%p)", 191222357542e9cb017e2dfeee0004d6a22ed8897468Tim Janik g_type_name (G_TYPE_FROM_INSTANCE (instance)), 191322357542e9cb017e2dfeee0004d6a22ed8897468Tim Janik node->name, detail, 191422357542e9cb017e2dfeee0004d6a22ed8897468Tim Janik instance, node); 191522357542e9cb017e2dfeee0004d6a22ed8897468Tim Janik if (g_trap_instance_signals == instance) 191622357542e9cb017e2dfeee0004d6a22ed8897468Tim Janik G_BREAKPOINT (); 191722357542e9cb017e2dfeee0004d6a22ed8897468Tim Janik } 191822357542e9cb017e2dfeee0004d6a22ed8897468Tim Janik#endif /* G_ENABLE_DEBUG */ 191922357542e9cb017e2dfeee0004d6a22ed8897468Tim Janik 1920ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (node->flags & G_SIGNAL_NO_RECURSE) 1921ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 1922830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik Emission *emission = emission_find (g_restart_emissions, signal_id, detail, instance); 1923ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1924ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (emission) 1925ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 1926ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik *emission->state_p = EMISSION_RESTART; 1927e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik return return_value_altered; 1928ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 1929ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 1930830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik ihint.signal_id = node->signal_id; 1931830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik ihint.detail = detail; 1932ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik accumulator = node->accumulator; 1933ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (accumulator) 1934617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik { 1935617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik g_value_init (&accu, node->return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE); 1936617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik return_accu = &accu; 1937617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik } 1938617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik else 1939617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik return_accu = emission_return; 1940ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik emission_push ((node->flags & G_SIGNAL_NO_RECURSE) ? &g_restart_emissions : &g_recursive_emissions, 1941830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik signal_id, detail, instance, &emission_state); 1942ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik class_closure = node->class_closure; 1943ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1944ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik EMIT_RESTART: 1945ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1946830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik if (handler_list) 1947830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik handler_unref_R (signal_id, instance, handler_list); 1948abc5cbbe3e1f6e6bdc40d94741713e9efb6d580dTim Janik max_sequential_handler_number = g_handler_sequential_number; 1949830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik hlist = handler_list_lookup (signal_id, instance); 1950830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik handler_list = hlist ? hlist->handlers : NULL; 1951830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik if (handler_list) 1952830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik handler_ref (handler_list); 1953830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik 1954830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik ihint.run_type = G_SIGNAL_RUN_FIRST; 1955830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik 1956ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if ((node->flags & G_SIGNAL_RUN_FIRST) && class_closure) 1957ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 1958ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik emission_state = EMISSION_RUN; 1959ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1960ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_UNLOCK (g_signal_mutex); 1961617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik g_closure_invoke (class_closure, 1962617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik return_accu, 1963617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik node->n_params + 1, 1964617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik instance_and_params, 1965617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik &ihint); 1966617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik if (!accumulate (&ihint, emission_return, &accu, accumulator) && 1967617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik emission_state == EMISSION_RUN) 1968617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik emission_state = EMISSION_STOP; 1969ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_LOCK (g_signal_mutex); 1970e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik return_value_altered = TRUE; 1971ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1972ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (emission_state == EMISSION_STOP) 1973ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik goto EMIT_CLEANUP; 1974ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik else if (emission_state == EMISSION_RESTART) 1975ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik goto EMIT_RESTART; 1976ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 1977ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 1978ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (node->emission_hooks) 1979ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 1980617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik gboolean need_destroy, was_in_call, may_recurse = TRUE; 1981617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik GHook *hook; 19829490f8d7e435d60b76d5fca12ba6332a5f058fa5Tim Janik 1983617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik emission_state = EMISSION_HOOK; 1984617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik hook = g_hook_first_valid (node->emission_hooks, may_recurse); 1985617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik while (hook) 1986617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik { 19879490f8d7e435d60b76d5fca12ba6332a5f058fa5Tim Janik SignalHook *signal_hook = SIGNAL_HOOK (hook); 1988617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik 19899490f8d7e435d60b76d5fca12ba6332a5f058fa5Tim Janik if (!signal_hook->detail || signal_hook->detail == detail) 1990617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik { 1991617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik GSignalEmissionHook hook_func = hook->func; 1992617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik 1993617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik was_in_call = G_HOOK_IN_CALL (hook); 1994617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik hook->flags |= G_HOOK_FLAG_IN_CALL; 1995617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik G_UNLOCK (g_signal_mutex); 1996617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik need_destroy = !hook_func (&ihint, node->n_params + 1, instance_and_params, hook->data); 1997617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik G_LOCK (g_signal_mutex); 1998617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik if (!was_in_call) 1999617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik hook->flags &= ~G_HOOK_FLAG_IN_CALL; 2000617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik if (need_destroy) 2001617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik g_hook_destroy_link (node->emission_hooks, hook); 2002617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik } 2003617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik hook = g_hook_next_valid (node->emission_hooks, hook, may_recurse); 2004617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik } 2005ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 2006ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (emission_state == EMISSION_RESTART) 2007ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik goto EMIT_RESTART; 2008ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 2009ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 2010830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik if (handler_list) 2011ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 2012830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik Handler *handler = handler_list; 2013ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 2014ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik emission_state = EMISSION_RUN; 2015ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik handler_ref (handler); 2016ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik do 2017ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 2018ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik Handler *tmp; 2019ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 2020830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik if (handler->after) 2021830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik { 2022830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik handler_unref_R (signal_id, instance, handler_list); 2023830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik handler_list = handler; 2024830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik break; 2025830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik } 2026abc5cbbe3e1f6e6bdc40d94741713e9efb6d580dTim Janik else if (!handler->block_count && (!handler->detail || handler->detail == detail) && 2027abc5cbbe3e1f6e6bdc40d94741713e9efb6d580dTim Janik handler->sequential_number < max_sequential_handler_number) 2028ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 2029ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_UNLOCK (g_signal_mutex); 2030617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik g_closure_invoke (handler->closure, 2031617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik return_accu, 2032617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik node->n_params + 1, 2033617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik instance_and_params, 2034617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik &ihint); 2035617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik if (!accumulate (&ihint, emission_return, &accu, accumulator) && 2036617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik emission_state == EMISSION_RUN) 2037617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik emission_state = EMISSION_STOP; 2038ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_LOCK (g_signal_mutex); 2039e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik return_value_altered = TRUE; 2040ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 2041ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik tmp = emission_state == EMISSION_RUN ? handler->next : NULL; 2042ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 2043ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik else 2044ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik tmp = handler->next; 2045ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 2046ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (tmp) 2047ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik handler_ref (tmp); 2048830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik handler_unref_R (signal_id, instance, handler_list); 2049830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik handler_list = handler; 2050ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik handler = tmp; 2051ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 2052ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik while (handler); 2053ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 2054ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (emission_state == EMISSION_STOP) 2055ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik goto EMIT_CLEANUP; 2056ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik else if (emission_state == EMISSION_RESTART) 2057ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik goto EMIT_RESTART; 2058ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 2059ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 2060830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik ihint.run_type = G_SIGNAL_RUN_LAST; 2061830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik 2062ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if ((node->flags & G_SIGNAL_RUN_LAST) && class_closure) 2063ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 2064ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik emission_state = EMISSION_RUN; 2065ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 2066ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_UNLOCK (g_signal_mutex); 2067617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik g_closure_invoke (class_closure, 2068617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik return_accu, 2069617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik node->n_params + 1, 2070617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik instance_and_params, 2071617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik &ihint); 2072617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik if (!accumulate (&ihint, emission_return, &accu, accumulator) && 2073617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik emission_state == EMISSION_RUN) 2074617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik emission_state = EMISSION_STOP; 2075ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_LOCK (g_signal_mutex); 2076e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik return_value_altered = TRUE; 2077ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 2078ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (emission_state == EMISSION_STOP) 2079ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik goto EMIT_CLEANUP; 2080ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik else if (emission_state == EMISSION_RESTART) 2081ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik goto EMIT_RESTART; 2082ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 2083ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 2084830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik if (handler_list) 2085ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 2086830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik Handler *handler = handler_list; 2087ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 2088ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik emission_state = EMISSION_RUN; 2089ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik handler_ref (handler); 2090ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik do 2091ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 2092ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik Handler *tmp; 2093ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 2094abc5cbbe3e1f6e6bdc40d94741713e9efb6d580dTim Janik if (handler->after && !handler->block_count && (!handler->detail || handler->detail == detail) && 2095abc5cbbe3e1f6e6bdc40d94741713e9efb6d580dTim Janik handler->sequential_number < max_sequential_handler_number) 2096ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 2097ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_UNLOCK (g_signal_mutex); 2098617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik g_closure_invoke (handler->closure, 2099617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik return_accu, 2100617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik node->n_params + 1, 2101617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik instance_and_params, 2102617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik &ihint); 2103617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik if (!accumulate (&ihint, emission_return, &accu, accumulator) && 2104617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik emission_state == EMISSION_RUN) 2105617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik emission_state = EMISSION_STOP; 2106ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_LOCK (g_signal_mutex); 2107e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik return_value_altered = TRUE; 2108ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 2109ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik tmp = emission_state == EMISSION_RUN ? handler->next : NULL; 2110ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 2111ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik else 2112ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik tmp = handler->next; 2113ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 2114ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (tmp) 2115ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik handler_ref (tmp); 2116ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik handler_unref_R (signal_id, instance, handler); 2117ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik handler = tmp; 2118ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 2119ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik while (handler); 2120ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 2121ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (emission_state == EMISSION_STOP) 2122ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik goto EMIT_CLEANUP; 2123ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik else if (emission_state == EMISSION_RESTART) 2124ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik goto EMIT_RESTART; 2125ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 2126ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 2127ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik EMIT_CLEANUP: 2128ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 2129830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik ihint.run_type = G_SIGNAL_RUN_CLEANUP; 2130830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik 2131ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if ((node->flags & G_SIGNAL_RUN_CLEANUP) && class_closure) 2132ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 2133830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik gboolean need_unset = FALSE; 2134830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik 2135ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik emission_state = EMISSION_STOP; 2136ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 2137ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_UNLOCK (g_signal_mutex); 2138617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik if (node->return_type != G_TYPE_NONE && !accumulator) 2139ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik { 2140617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik g_value_init (&accu, node->return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE); 2141617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik need_unset = TRUE; 2142ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 2143ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_closure_invoke (class_closure, 2144ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node->return_type != G_TYPE_NONE ? &accu : NULL, 2145ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik node->n_params + 1, 2146830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik instance_and_params, 2147830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik &ihint); 2148830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik if (need_unset) 2149ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik g_value_unset (&accu); 2150ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik G_LOCK (g_signal_mutex); 2151830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik 2152ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (emission_state == EMISSION_RESTART) 2153ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik goto EMIT_RESTART; 2154ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik } 2155ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 2156830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik if (handler_list) 2157830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik handler_unref_R (signal_id, instance, handler_list); 2158ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik 2159830d808c5ce0d94524807d4777a4c8257efcbf8aTim Janik emission_pop ((node->flags & G_SIGNAL_NO_RECURSE) ? &g_restart_emissions : &g_recursive_emissions, &emission_state); 2160ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik if (accumulator) 2161e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik g_value_unset (&accu); 2162617332234d4426ed0941ec1e2cb9f0736bd796c3Tim Janik 2163e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik return return_value_altered; 2164ee23c09e83d06a0d131ebd234c132f1c3602c019Tim Janik} 2165e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 2166e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik 2167f0b9abe801c2e0cccb7930421a81bb77031e3251Tim Janik/* --- compile standard marshallers --- */ 216837e4b8c87e8b0574a806a6f1d2284e4ab45341b3Tim Janik#include "gobject.h" 216937e4b8c87e8b0574a806a6f1d2284e4ab45341b3Tim Janik#include "genums.h" 2170e773d7dba66cf51c7d6ad7d1973ab3635e986e2eTim Janik#include "gmarshal.c" 2171