mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-12-25 23:16:14 +01:00
destroy all signals that the finalized obejct type introduced.
Wed Nov 1 03:36:54 2000 Tim Janik <timj@gtk.org> * 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.
This commit is contained in:
parent
b6eb9a2e7d
commit
cfe0780d3e
@ -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
|
||||
|
@ -76,9 +76,9 @@ The @GSignalInvocationHint structure is used to pass on additional information
|
||||
to callbacks during a signal emission.
|
||||
</para>
|
||||
|
||||
@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.
|
||||
</para>
|
||||
|
||||
@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.
|
||||
</para>
|
||||
|
||||
@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:
|
||||
<msgtext><programlisting>
|
||||
@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.
|
||||
</para>
|
||||
|
||||
@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().
|
||||
</para>
|
||||
|
||||
@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
|
||||
|
||||
|
||||
<!-- ##### FUNCTION g_signal_connect_closure ##### -->
|
||||
@ -255,46 +255,144 @@ g_signal_query().
|
||||
@Returns:
|
||||
|
||||
|
||||
<!-- ##### FUNCTION g_signal_handler_find ##### -->
|
||||
<para>
|
||||
|
||||
</para>
|
||||
|
||||
@instance:
|
||||
@mask:
|
||||
@signal_id:
|
||||
@detail:
|
||||
@closure:
|
||||
@func:
|
||||
@data:
|
||||
@Returns:
|
||||
|
||||
|
||||
<!-- ##### FUNCTION g_signal_handler_block ##### -->
|
||||
<para>
|
||||
|
||||
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.
|
||||
</para>
|
||||
|
||||
@instance:
|
||||
@handler_id:
|
||||
|
||||
@instance: The instance to block the signal handler of
|
||||
@handler_id: Handler id of the handler to be blocked
|
||||
|
||||
<!-- ##### FUNCTION g_signal_handler_unblock ##### -->
|
||||
<para>
|
||||
|
||||
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.
|
||||
</para>
|
||||
|
||||
@instance:
|
||||
@handler_id:
|
||||
@instance: The instance to unblock the signal handler of
|
||||
@handler_id: Handler id of the handler to be unblocked
|
||||
|
||||
|
||||
<!-- ##### FUNCTION g_signal_handler_disconnect ##### -->
|
||||
<para>
|
||||
|
||||
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.
|
||||
</para>
|
||||
|
||||
@instance:
|
||||
@handler_id:
|
||||
@instance: The instance to remove the signal handler from
|
||||
@handler_id: Handler id of the handler to be disconnected
|
||||
|
||||
|
||||
<!-- ##### FUNCTION g_signal_handler_find ##### -->
|
||||
<para>
|
||||
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.
|
||||
</para>
|
||||
|
||||
@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
|
||||
|
||||
|
||||
<!-- ##### FUNCTION g_signal_handlers_block_matched ##### -->
|
||||
<para>
|
||||
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.
|
||||
</para>
|
||||
|
||||
@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
|
||||
|
||||
|
||||
<!-- ##### FUNCTION g_signal_handlers_unblock_matched ##### -->
|
||||
<para>
|
||||
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.
|
||||
</para>
|
||||
|
||||
@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
|
||||
|
||||
|
||||
<!-- ##### FUNCTION g_signal_handlers_disconnect_matched ##### -->
|
||||
<para>
|
||||
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.
|
||||
</para>
|
||||
|
||||
@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
|
||||
|
||||
|
||||
<!-- ##### FUNCTION g_signal_has_handler_pending ##### -->
|
||||
|
@ -1,3 +1,21 @@
|
||||
Wed Nov 1 03:36:54 2000 Tim Janik <timj@gtk.org>
|
||||
|
||||
* 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 <wilhelmi@ira.uka.de>
|
||||
|
||||
* gvalue.c (exchange_entries_equal), gparam.c (param_spec_equals):
|
||||
|
@ -16,11 +16,12 @@
|
||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "gobject.h"
|
||||
|
||||
|
||||
#include "gvaluecollector.h"
|
||||
#include "gsignal.h"
|
||||
#include <string.h>
|
||||
|
||||
|
||||
#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
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user