From cfe0780d3ea8a5a9bdd3497926437cde42298086 Mon Sep 17 00:00:00 2001 From: Tim Janik Date: Wed, 1 Nov 2000 03:03:04 +0000 Subject: [PATCH] destroy all signals that the finalized obejct type introduced. Wed Nov 1 03:36:54 2000 Tim Janik * gobject.c (g_object_base_class_finalize): destroy all signals that the finalized obejct type introduced. * gsignal.c (g_signals_destroy): don't require itype to have signals. * gobject.c (g_object_do_finalize): make sure all signal handlers are destroyed. * gsignal.[hc]: (g_signal_handler_find): only match on non-0 masks. (g_signal_handlers_block_matched): (g_signal_handlers_unblock_matched): (g_signal_handlers_disconnect_matched): new functions to block/unblock or disconnect handlers in groups. --- docs/reference/gobject/gobject-sections.txt | 5 +- docs/reference/gobject/tmpl/signals.sgml | 186 +++++++++++---- gobject/ChangeLog | 18 ++ gobject/gobject.c | 10 +- gobject/gsignal.c | 248 ++++++++++++++------ gobject/gsignal.h | 142 ++++++----- 6 files changed, 430 insertions(+), 179 deletions(-) diff --git a/docs/reference/gobject/gobject-sections.txt b/docs/reference/gobject/gobject-sections.txt index 8f352b49d..8046cd623 100644 --- a/docs/reference/gobject/gobject-sections.txt +++ b/docs/reference/gobject/gobject-sections.txt @@ -337,10 +337,13 @@ g_signal_name g_signal_query g_signal_list_ids g_signal_connect_closure -g_signal_handler_find g_signal_handler_block g_signal_handler_unblock g_signal_handler_disconnect +g_signal_handler_find +g_signal_handlers_block_matched +g_signal_handlers_unblock_matched +g_signal_handlers_disconnect_matched g_signal_has_handler_pending g_signal_stop_emission g_signal_type_closure_new diff --git a/docs/reference/gobject/tmpl/signals.sgml b/docs/reference/gobject/tmpl/signals.sgml index 265d16513..5f3c35118 100644 --- a/docs/reference/gobject/tmpl/signals.sgml +++ b/docs/reference/gobject/tmpl/signals.sgml @@ -76,9 +76,9 @@ The @GSignalInvocationHint structure is used to pass on additional information to callbacks during a signal emission. -@signal_id: The signal id of the signal invoking the callback -@detail: The detail passed on for this emission -@run_type: The stage the signal emission is currently in, this +@signal_id: The signal id of the signal invoking the callback +@detail: The detail passed on for this emission +@run_type: The stage the signal emission is currently in, this field will contain one of @G_SIGNAL_RUN_FIRST, @G_SIGNAL_RUN_LAST or @G_SIGNAL_RUN_CLEANUP. @@ -92,11 +92,11 @@ values is perfomed. The return value of signal emissions is then the value returned by the last callback. -@ihint: Signal invokation hint, see @GSignalInvocationHint -@return_accu: Accumulator to collect callback return values in, this +@ihint: Signal invokation hint, see @GSignalInvocationHint +@return_accu: Accumulator to collect callback return values in, this is the return value of the current signal emission -@return_value: The return value of the most recent callback function -@Returns: The accumulator function returns whether the signal emission +@return_value: The return value of the most recent callback function +@Returns: The accumulator function returns whether the signal emission should be aborted. Returning @FALSE means to abort the current emission and @TRUE is returned for continuation. @@ -153,14 +153,14 @@ A structure holding in-depth information for a specific signal. It is filled in by the g_signal_query() function. -@signal_id: The signal id of the signal being querried, or 0 if the +@signal_id: The signal id of the signal being querried, or 0 if the signal to be querried was unknown -@signal_name: The signal name -@itype: The interface/instance type that this signal can be emitted for -@signal_flags: The signal flags as passed in to @g_signal_new() -@return_type: The return type for user callbacks -@n_params: The number of parameters that user callbacks take -@param_types: The individual parameter types for user callbacks, note that the +@signal_name: The signal name +@itype: The interface/instance type that this signal can be emitted for +@signal_flags: The signal flags as passed in to @g_signal_new() +@return_type: The return type for user callbacks +@n_params: The number of parameters that user callbacks take +@param_types: The individual parameter types for user callbacks, note that the effective callback signature is: @return_type callback (@gpointer data1, @@ -225,8 +225,8 @@ is 0. All members filled into the @GSignalQuery structure should be considered constant and have to be left untouched. -@signal_id: The signal id of the signal to query information for -@query: A user provided structure that is filled in with constant +@signal_id: The signal id of the signal to query information for +@query: A user provided structure that is filled in with constant values upon success. @@ -237,9 +237,9 @@ created. Further information about the signals can be aquired through g_signal_query(). -@itype: Instance or interface type -@n_ids: Location to store the number of signal ids for @itype -@Returns: Newly allocated array of signal ids +@itype: Instance or interface type +@n_ids: Location to store the number of signal ids for @itype +@Returns: Newly allocated array of signal ids @@ -255,46 +255,144 @@ g_signal_query(). @Returns: - - - - - -@instance: -@mask: -@signal_id: -@detail: -@closure: -@func: -@data: -@Returns: - - - +g_signal_handler_block() blocks a handler of an +instance so it will not be called during any signal emissions +unless it is unblocked again. Thus "blocking" a signal handler +means to temporarily deactive it, a signal handler has to be +unblocked exactly the same amount of times it has been blocked +before to become active again. +The @handler_id passed into g_signal_handler_block() has +to be a valid signal handler id, connected to a signal of +@instance. -@instance: -@handler_id: - +@instance: The instance to block the signal handler of +@handler_id: Handler id of the handler to be blocked - +g_signal_handler_unblock() undoes the effect of a previous +g_signal_handler_block() call. A blocked handler is skipped +during signal emissions and will not be invoked, unblocking +it (for exactly the amount of times it has been blocked before) +reverts its "blocked" state, so the handler will be recognized +by the signal system and is called upon future or currently +ongoing signal emissions (since the order in which handlers are +called during signal emissions is deterministic, whether the +unblocked handler in question is called as part of a currently +ongoing emission depends on how far that emission has proceeded +yet). +The @handler_id passed into g_signal_handler_unblock() has +to be a valid id of a signal handler that is connected to a +signal of @instance and is currently blocked. -@instance: -@handler_id: +@instance: The instance to unblock the signal handler of +@handler_id: Handler id of the handler to be unblocked - +g_signal_handler_disconnect() disconnects a handler from an +instance so it will not be called during any future or currently +ongoing emissions of the signal it has been connected to. +The @handler_id becomes invalid and may be reused. +The @handler_id passed into g_signal_handler_disconnect() has +to be a valid signal handler id, connected to a signal of +@instance. -@instance: -@handler_id: +@instance: The instance to remove the signal handler from +@handler_id: Handler id of the handler to be disconnected + + + + +Find the first signal handler that matches certain selection criteria. +The criteria mask is passed as an OR-ed combination of #GSignalMatchType +flags, and the criteria values are passed as arguments. +The match @mask has to be non-0 for successfull matches. +If no handler was found, 0 is returned. + + +@instance: The instance owning the signal handler to be found +@mask: Mask indicating which of @signal_id, @detail, + @closure, @func and/or @data the handler has to match +@signal_id: Signal the handler has to be connected to +@detail: Signal detail the handler has to be connected to +@closure: The closure the handler will invoke +@func: The C closure callback of the handler (useless for non-C closures) +@data: The closure data of the handler's closure +@Returns: A valid non-0 signal handler id for a successfull match + + + + +This function blocks all handlers on an instance that match a certain +selection criteria. The criteria mask is passed as an OR-ed combination of +#GSignalMatchType flags, and the criteria values are passed as arguments. +Passing at least one of the %G_SIGNAL_MATCH_CLOSURE, %G_SIGNAL_MATCH_FUNC +or %G_SIGNAL_MATCH_DATA match flags is required for successfull matches. +If no handlers were found, 0 is returned, the number of blocked handlers +otherwise. + + +@instance: The instance to block handlers from +@mask: Mask indicating which of @signal_id, @detail, + @closure, @func and/or @data the handlers have to match +@signal_id: Signal the handlers have to be connected to +@detail: Signal detail the handlers have to be connected to +@closure: The closure the handlers will invoke +@func: The C closure callback of the handlers (useless for non-C closures) +@data: The closure data of the handlers' closures +@Returns: The amount of handlers that got blocked + + + + +This function unblocks all handlers on an instance that match a certain +selection criteria. The criteria mask is passed as an OR-ed combination of +#GSignalMatchType flags, and the criteria values are passed as arguments. +Passing at least one of the %G_SIGNAL_MATCH_CLOSURE, %G_SIGNAL_MATCH_FUNC +or %G_SIGNAL_MATCH_DATA match flags is required for successfull matches. +If no handlers were found, 0 is returned, the number of unblocked handlers +otherwise. The match criteria should not apply to any handlers that are +not currently blocked. + + +@instance: The instance to unblock handlers from +@mask: Mask indicating which of @signal_id, @detail, + @closure, @func and/or @data the handlers have to match +@signal_id: Signal the handlers have to be connected to +@detail: Signal detail the handlers have to be connected to +@closure: The closure the handlers will invoke +@func: The C closure callback of the handlers (useless for non-C closures) +@data: The closure data of the handlers' closures +@Returns: The amount of handlers that got unblocked + + + + +This function disconnects all handlers on an instance that match a certain +selection criteria. The criteria mask is passed as an OR-ed combination of +#GSignalMatchType flags, and the criteria values are passed as arguments. +Passing at least one of the %G_SIGNAL_MATCH_CLOSURE, %G_SIGNAL_MATCH_FUNC +or %G_SIGNAL_MATCH_DATA match flags is required for successfull matches. +If no handlers were found, 0 is returned, the number of disconnected handlers +otherwise. + + +@instance: The instance to remove handlers from +@mask: Mask indicating which of @signal_id, @detail, + @closure, @func and/or @data the handlers have to match +@signal_id: Signal the handlers have to be connected to +@detail: Signal detail the handlers have to be connected to +@closure: The closure the handlers will invoke +@func: The C closure callback of the handlers (useless for non-C closures) +@data: The closure data of the handlers' closures +@Returns: The amount of handlers that got disconnected diff --git a/gobject/ChangeLog b/gobject/ChangeLog index 312b46158..85e21cc50 100644 --- a/gobject/ChangeLog +++ b/gobject/ChangeLog @@ -1,3 +1,21 @@ +Wed Nov 1 03:36:54 2000 Tim Janik + + * gobject.c (g_object_base_class_finalize): destroy all signals that + the finalized obejct type introduced. + + * gsignal.c (g_signals_destroy): don't require itype to have + signals. + + * gobject.c (g_object_do_finalize): make sure all signal handlers + are destroyed. + + * gsignal.[hc]: + (g_signal_handler_find): only match on non-0 masks. + (g_signal_handlers_block_matched): + (g_signal_handlers_unblock_matched): + (g_signal_handlers_disconnect_matched): new functions to block/unblock + or disconnect handlers in groups. + 2000-10-30 Sebastian Wilhelmi * gvalue.c (exchange_entries_equal), gparam.c (param_spec_equals): diff --git a/gobject/gobject.c b/gobject/gobject.c index f50f346ea..5aa99d8bc 100644 --- a/gobject/gobject.c +++ b/gobject/gobject.c @@ -16,11 +16,12 @@ * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ - -#include - #include "gobject.h" + + #include "gvaluecollector.h" +#include "gsignal.h" +#include #define DEBUG_OBJECTS @@ -162,6 +163,8 @@ g_object_base_class_finalize (GObjectClass *class) guint i; g_message ("finallizing base class of %s", G_OBJECT_CLASS_NAME (class)); + + g_signals_destroy (G_OBJECT_CLASS_TYPE (class)); for (i = 0; i < class->n_param_specs; i++) { @@ -292,6 +295,7 @@ g_object_do_shutdown (GObject *object) static void g_object_do_finalize (GObject *object) { + g_signal_handlers_destroy (object); g_datalist_clear (&object->qdata); #ifdef DEBUG_OBJECTS diff --git a/gobject/gsignal.c b/gobject/gsignal.c index 26f317658..35fe060a6 100644 --- a/gobject/gsignal.c +++ b/gobject/gsignal.c @@ -344,7 +344,7 @@ handler_find (gpointer instance, ((mask & G_SIGNAL_MATCH_FUNC) || (handler->closure->marshal == node->c_marshaller && handler->closure->meta_marshal == 0 && ((GCClosure*) handler->closure)->callback == func))) - return handler; + return handler; } else { @@ -376,7 +376,7 @@ handler_find (gpointer instance, ((mask & G_SIGNAL_MATCH_FUNC) || (handler->closure->marshal == node->c_marshaller && handler->closure->meta_marshal == 0 && ((GCClosure*) handler->closure)->callback == func))) - return handler; + return handler; } } } @@ -571,7 +571,6 @@ void g_signals_destroy (GType itype) { guint i; - gboolean found_one = FALSE; G_LOCK (g_signal_mutex); for (i = 0; i < g_n_signal_nodes; i++) @@ -585,15 +584,9 @@ g_signals_destroy (GType itype) node->name, g_type_name (node->itype)); else - { - found_one = TRUE; - signal_destroy_R (node); - } + signal_destroy_R (node); } } - if (!found_one) - g_warning (G_STRLOC ": type `%s' has no signals that could be destroyed", - g_type_name (itype)); G_UNLOCK (g_signal_mutex); } @@ -917,6 +910,54 @@ g_signal_connect_closure (gpointer instance, return handler_id; } +void +g_signal_handler_block (gpointer instance, + guint handler_id) +{ + Handler *handler; + + g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance)); + g_return_if_fail (handler_id > 0); + + G_LOCK (g_signal_mutex); + handler = handler_lookup (instance, handler_id, NULL); + if (handler) + { +#ifndef G_DISABLE_CHECKS + if (handler->block_count >= HANDLER_MAX_BLOCK_COUNT - 1) + g_error (G_STRLOC ": handler block_count overflow, %s", REPORT_BUG); +#endif + + handler->block_count += 1; + } + else + g_warning ("%s: instance `%p' has no handler with id `%u'", G_STRLOC, instance, handler_id); + G_UNLOCK (g_signal_mutex); +} + +void +g_signal_handler_unblock (gpointer instance, + guint handler_id) +{ + Handler *handler; + + g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance)); + g_return_if_fail (handler_id > 0); + + G_LOCK (g_signal_mutex); + handler = handler_lookup (instance, handler_id, NULL); + if (handler) + { + if (handler->block_count) + handler->block_count -= 1; + else + g_warning (G_STRLOC ": handler `%u' of instance `%p' is not blocked", handler_id, instance); + } + else + g_warning ("%s: instance `%p' has no handler with id `%u'", G_STRLOC, instance, handler_id); + G_UNLOCK (g_signal_mutex); +} + void g_signal_handler_disconnect (gpointer instance, guint handler_id) @@ -983,54 +1024,6 @@ g_signal_handlers_destroy (gpointer instance) G_UNLOCK (g_signal_mutex); } -void -g_signal_handler_block (gpointer instance, - guint handler_id) -{ - Handler *handler; - - g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance)); - g_return_if_fail (handler_id > 0); - - G_LOCK (g_signal_mutex); - handler = handler_lookup (instance, handler_id, NULL); - if (handler) - { -#ifndef G_DISABLE_CHECKS - if (handler->block_count >= HANDLER_MAX_BLOCK_COUNT - 1) - g_error (G_STRLOC ": handler block_count overflow, %s", REPORT_BUG); -#endif - - handler->block_count += 1; - } - else - g_warning ("%s: instance `%p' has no handler with id `%u'", G_STRLOC, instance, handler_id); - G_UNLOCK (g_signal_mutex); -} - -void -g_signal_handler_unblock (gpointer instance, - guint handler_id) -{ - Handler *handler; - - g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance)); - g_return_if_fail (handler_id > 0); - - G_LOCK (g_signal_mutex); - handler = handler_lookup (instance, handler_id, NULL); - if (handler) - { - if (handler->block_count) - handler->block_count -= 1; - else - g_warning (G_STRLOC ": handler `%u' of instance `%p' is not blocked", handler_id, instance); - } - else - g_warning ("%s: instance `%p' has no handler with id `%u'", G_STRLOC, instance, handler_id); - G_UNLOCK (g_signal_mutex); -} - guint g_signal_handler_find (gpointer instance, GSignalMatchType mask, @@ -1040,25 +1033,134 @@ g_signal_handler_find (gpointer instance, gpointer func, gpointer data) { - Handler *handler = NULL; - guint handler_id; + Handler *handler; + guint handler_id = 0; g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), 0); g_return_val_if_fail ((mask & ~G_SIGNAL_MATCH_MASK) == 0, 0); - - G_LOCK (g_signal_mutex); - handler = handler_find (instance, mask, signal_id, detail, closure, func, data); - handler_id = handler ? handler->id : 0; - G_UNLOCK (g_signal_mutex); - + + if (mask & G_SIGNAL_MATCH_MASK) + { + G_LOCK (g_signal_mutex); + handler = handler_find (instance, mask, signal_id, detail, closure, func, data); + handler_id = handler ? handler->id : 0; + G_UNLOCK (g_signal_mutex); + } + return handler_id; } +static guint +signal_handlers_foreach_matched (gpointer instance, + GSignalMatchType mask, + guint signal_id, + GQuark detail, + GClosure *closure, + gpointer func, + gpointer data, + void (*callback) (gpointer instance, + guint handler_id)) +{ + Handler *handler; + guint n_handlers = 0; + + handler = handler_find (instance, mask, signal_id, detail, closure, func, data); + while (handler && handler->id) + { + n_handlers++; + G_UNLOCK (g_signal_mutex); + callback (instance, handler->id); + G_LOCK (g_signal_mutex); + /* need constant relookups due to callback */ + handler = handler_find (instance, mask, signal_id, detail, closure, func, data); + } + + return n_handlers; +} + +guint +g_signal_handlers_block_matched (gpointer instance, + GSignalMatchType mask, + guint signal_id, + GQuark detail, + GClosure *closure, + gpointer func, + gpointer data) +{ + guint n_handlers = 0; + + g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), FALSE); + g_return_val_if_fail ((mask & ~G_SIGNAL_MATCH_MASK) == 0, FALSE); + + if (mask & (G_SIGNAL_MATCH_CLOSURE | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA)) + { + G_LOCK (g_signal_mutex); + n_handlers = signal_handlers_foreach_matched (instance, mask, signal_id, detail, + closure, func, data, + g_signal_handler_block); + G_UNLOCK (g_signal_mutex); + } + + return n_handlers; +} + +guint +g_signal_handlers_unblock_matched (gpointer instance, + GSignalMatchType mask, + guint signal_id, + GQuark detail, + GClosure *closure, + gpointer func, + gpointer data) +{ + guint n_handlers = 0; + + g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), FALSE); + g_return_val_if_fail ((mask & ~G_SIGNAL_MATCH_MASK) == 0, FALSE); + + if (mask & (G_SIGNAL_MATCH_CLOSURE | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA)) + { + G_LOCK (g_signal_mutex); + n_handlers = signal_handlers_foreach_matched (instance, mask, signal_id, detail, + closure, func, data, + g_signal_handler_unblock); + G_UNLOCK (g_signal_mutex); + } + + return n_handlers; +} + +guint +g_signal_handlers_disconnect_matched (gpointer instance, + GSignalMatchType mask, + guint signal_id, + GQuark detail, + GClosure *closure, + gpointer func, + gpointer data) +{ + guint n_handlers = 0; + + g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), FALSE); + g_return_val_if_fail ((mask & ~G_SIGNAL_MATCH_MASK) == 0, FALSE); + + if (mask & (G_SIGNAL_MATCH_CLOSURE | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA)) + { + G_LOCK (g_signal_mutex); + n_handlers = signal_handlers_foreach_matched (instance, mask, signal_id, detail, + closure, func, data, + g_signal_handler_disconnect); + G_UNLOCK (g_signal_mutex); + } + + return n_handlers; +} + gboolean -g_signal_handler_pending (gpointer instance, - guint signal_id, - GQuark detail, - gboolean may_be_blocked) +g_signal_has_handler_pending (gpointer instance, + guint signal_id, + GQuark detail, + gboolean may_be_blocked) { Handler *handler = NULL; @@ -1108,7 +1210,11 @@ g_signal_emitv (const GValue *instance_and_params, node = LOOKUP_SIGNAL_NODE (signal_id); #ifndef G_DISABLE_CHECKS if (!node || !g_type_conforms_to (G_TYPE_FROM_INSTANCE (instance), node->itype)) - g_warning ("%s: signal id `%u' is invalid for instance `%p'", G_STRLOC, signal_id, instance); + { + g_warning ("%s: signal id `%u' is invalid for instance `%p'", G_STRLOC, signal_id, instance); + G_UNLOCK (g_signal_mutex); + return; + } if (detail && !(node->flags & G_SIGNAL_DETAILED)) { g_warning ("%s: signal id `%u' does not support detail (%u)", G_STRLOC, signal_id, detail); diff --git a/gobject/gsignal.h b/gobject/gsignal.h index f6db74563..92e5a4814 100644 --- a/gobject/gsignal.h +++ b/gobject/gsignal.h @@ -8,7 +8,7 @@ * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General @@ -31,9 +31,9 @@ extern "C" { /* --- typedefs --- */ -typedef struct _GSignalQuery GSignalQuery; -typedef struct _GSignalInvocationHint GSignalInvocationHint; -typedef GClosureMarshal GSignalCMarshaller; +typedef struct _GSignalQuery GSignalQuery; +typedef struct _GSignalInvocationHint GSignalInvocationHint; +typedef GClosureMarshal GSignalCMarshaller; typedef gboolean (*GSignalEmissionHook) (GSignalInvocationHint *ihint, guint n_param_values, const GValue *param_values); @@ -52,7 +52,7 @@ typedef enum G_SIGNAL_DETAILED = 1 << 4, G_SIGNAL_ACTION = 1 << 5, G_SIGNAL_NO_HOOKS = 1 << 6 -#define G_SIGNAL_FLAGS_MASK 0x7f +#define G_SIGNAL_FLAGS_MASK 0x7f } GSignalFlags; typedef enum { @@ -62,7 +62,7 @@ typedef enum G_SIGNAL_MATCH_FUNC = 1 << 3, G_SIGNAL_MATCH_DATA = 1 << 4, G_SIGNAL_MATCH_UNBLOCKED = 1 << 5 -#define G_SIGNAL_MATCH_MASK 0x3f +#define G_SIGNAL_MATCH_MASK 0x3f } GSignalMatchType; @@ -86,64 +86,86 @@ struct _GSignalQuery /* --- signals --- */ -guint g_signal_newv (const gchar *signal_name, - GType itype, - GSignalFlags signal_flags, - GClosure *class_closure, - GSignalAccumulator accumulator, - GSignalCMarshaller c_marshaller, - GType return_type, - guint n_params, - GType *param_types); -void g_signal_emitv (const GValue *instance_and_params, - guint signal_id, - GQuark detail, - GValue *return_value); -guint g_signal_lookup (const gchar *name, - GType itype); -gchar* g_signal_name (guint signal_id); -void g_signal_query (guint signal_id, - GSignalQuery *query); -guint* g_signal_list_ids (GType itype, - guint *n_ids); - -/* --- signal handlers --- */ -guint g_signal_connect_closure (gpointer instance, - guint signal_id, - GQuark detail, - GClosure *closure, - gboolean after); -void g_signal_handler_disconnect (gpointer instance, - guint handler_id); -void g_signal_handler_block (gpointer instance, - guint handler_id); -void g_signal_handler_unblock (gpointer instance, - guint handler_id); -guint g_signal_handler_find (gpointer instance, - GSignalMatchType mask, - guint signal_id, - GQuark detail, - GClosure *closure, - gpointer func, - gpointer data); -gboolean g_signal_has_handler_pending (gpointer instance, - guint signal_id, - GQuark detail, - gboolean may_be_blocked); - +guint g_signal_newv (const gchar *signal_name, + GType itype, + GSignalFlags signal_flags, + GClosure *class_closure, + GSignalAccumulator accumulator, + GSignalCMarshaller c_marshaller, + GType return_type, + guint n_params, + GType *param_types); +void g_signal_emitv (const GValue *instance_and_params, + guint signal_id, + GQuark detail, + GValue *return_value); +guint g_signal_lookup (const gchar *name, + GType itype); +gchar* g_signal_name (guint signal_id); +void g_signal_query (guint signal_id, + GSignalQuery *query); +guint* g_signal_list_ids (GType itype, + guint *n_ids); /* --- signal emissions --- */ -void g_signal_stop_emission (gpointer instance, - guint signal_id, - GQuark detail); -guint g_signal_add_emission_hook_full (guint signal_id, - GClosure *closure); -void g_signal_remove_emission_hook (guint signal_id, - guint hook_id); +void g_signal_stop_emission (gpointer instance, + guint signal_id, + GQuark detail); +guint g_signal_add_emission_hook_full (guint signal_id, + GClosure *closure); +void g_signal_remove_emission_hook (guint signal_id, + guint hook_id); + + +/* --- signal handlers --- */ +gboolean g_signal_has_handler_pending (gpointer instance, + guint signal_id, + GQuark detail, + gboolean may_be_blocked); +guint g_signal_connect_closure (gpointer instance, + guint signal_id, + GQuark detail, + GClosure *closure, + gboolean after); +void g_signal_handler_block (gpointer instance, + guint handler_id); +void g_signal_handler_unblock (gpointer instance, + guint handler_id); +void g_signal_handler_disconnect (gpointer instance, + guint handler_id); +guint g_signal_handler_find (gpointer instance, + GSignalMatchType mask, + guint signal_id, + GQuark detail, + GClosure *closure, + gpointer func, + gpointer data); +guint g_signal_handlers_block_matched (gpointer instance, + GSignalMatchType mask, + guint signal_id, + GQuark detail, + GClosure *closure, + gpointer func, + gpointer data); +guint g_signal_handlers_unblock_matched (gpointer instance, + GSignalMatchType mask, + guint signal_id, + GQuark detail, + GClosure *closure, + gpointer func, + gpointer data); +guint g_signal_handlers_disconnect_matched (gpointer instance, + GSignalMatchType mask, + guint signal_id, + GQuark detail, + GClosure *closure, + gpointer func, + gpointer data); + /*< private >*/ -void g_signal_handlers_destroy (gpointer instance); -void g_signals_destroy (GType itype); +void g_signal_handlers_destroy (gpointer instance); +void g_signals_destroy (GType itype); #ifdef __cplusplus