mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-06-07 13:20:06 +02: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_query
|
||||||
g_signal_list_ids
|
g_signal_list_ids
|
||||||
g_signal_connect_closure
|
g_signal_connect_closure
|
||||||
g_signal_handler_find
|
|
||||||
g_signal_handler_block
|
g_signal_handler_block
|
||||||
g_signal_handler_unblock
|
g_signal_handler_unblock
|
||||||
g_signal_handler_disconnect
|
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_has_handler_pending
|
||||||
g_signal_stop_emission
|
g_signal_stop_emission
|
||||||
g_signal_type_closure_new
|
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.
|
to callbacks during a signal emission.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
@signal_id: The signal id of the signal invoking the callback
|
@signal_id: The signal id of the signal invoking the callback
|
||||||
@detail: The detail passed on for this emission
|
@detail: The detail passed on for this emission
|
||||||
@run_type: The stage the signal emission is currently in, this
|
@run_type: The stage the signal emission is currently in, this
|
||||||
field will contain one of @G_SIGNAL_RUN_FIRST,
|
field will contain one of @G_SIGNAL_RUN_FIRST,
|
||||||
@G_SIGNAL_RUN_LAST or @G_SIGNAL_RUN_CLEANUP.
|
@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.
|
value returned by the last callback.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
@ihint: Signal invokation hint, see @GSignalInvocationHint
|
@ihint: Signal invokation hint, see @GSignalInvocationHint
|
||||||
@return_accu: Accumulator to collect callback return values in, this
|
@return_accu: Accumulator to collect callback return values in, this
|
||||||
is the return value of the current signal emission
|
is the return value of the current signal emission
|
||||||
@return_value: The return value of the most recent callback function
|
@return_value: The return value of the most recent callback function
|
||||||
@Returns: The accumulator function returns whether the signal emission
|
@Returns: The accumulator function returns whether the signal emission
|
||||||
should be aborted. Returning @FALSE means to abort the
|
should be aborted. Returning @FALSE means to abort the
|
||||||
current emission and @TRUE is returned for continuation.
|
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.
|
filled in by the g_signal_query() function.
|
||||||
</para>
|
</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 to be querried was unknown
|
||||||
@signal_name: The signal name
|
@signal_name: The signal name
|
||||||
@itype: The interface/instance type that this signal can be emitted for
|
@itype: The interface/instance type that this signal can be emitted for
|
||||||
@signal_flags: The signal flags as passed in to @g_signal_new()
|
@signal_flags: The signal flags as passed in to @g_signal_new()
|
||||||
@return_type: The return type for user callbacks
|
@return_type: The return type for user callbacks
|
||||||
@n_params: The number of parameters that user callbacks take
|
@n_params: The number of parameters that user callbacks take
|
||||||
@param_types: The individual parameter types for user callbacks, note that the
|
@param_types: The individual parameter types for user callbacks, note that the
|
||||||
effective callback signature is:
|
effective callback signature is:
|
||||||
<msgtext><programlisting>
|
<msgtext><programlisting>
|
||||||
@return_type callback (@gpointer data1,
|
@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.
|
be considered constant and have to be left untouched.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
@signal_id: The signal id of the signal to query information for
|
@signal_id: The signal id of the signal to query information for
|
||||||
@query: A user provided structure that is filled in with constant
|
@query: A user provided structure that is filled in with constant
|
||||||
values upon success.
|
values upon success.
|
||||||
|
|
||||||
|
|
||||||
@ -237,9 +237,9 @@ created. Further information about the signals can be aquired through
|
|||||||
g_signal_query().
|
g_signal_query().
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
@itype: Instance or interface type
|
@itype: Instance or interface type
|
||||||
@n_ids: Location to store the number of signal ids for @itype
|
@n_ids: Location to store the number of signal ids for @itype
|
||||||
@Returns: Newly allocated array of signal ids
|
@Returns: Newly allocated array of signal ids
|
||||||
|
|
||||||
|
|
||||||
<!-- ##### FUNCTION g_signal_connect_closure ##### -->
|
<!-- ##### FUNCTION g_signal_connect_closure ##### -->
|
||||||
@ -255,46 +255,144 @@ g_signal_query().
|
|||||||
@Returns:
|
@Returns:
|
||||||
|
|
||||||
|
|
||||||
<!-- ##### FUNCTION g_signal_handler_find ##### -->
|
|
||||||
<para>
|
|
||||||
|
|
||||||
</para>
|
|
||||||
|
|
||||||
@instance:
|
|
||||||
@mask:
|
|
||||||
@signal_id:
|
|
||||||
@detail:
|
|
||||||
@closure:
|
|
||||||
@func:
|
|
||||||
@data:
|
|
||||||
@Returns:
|
|
||||||
|
|
||||||
|
|
||||||
<!-- ##### FUNCTION g_signal_handler_block ##### -->
|
<!-- ##### FUNCTION g_signal_handler_block ##### -->
|
||||||
<para>
|
<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>
|
</para>
|
||||||
|
|
||||||
@instance:
|
@instance: The instance to block the signal handler of
|
||||||
@handler_id:
|
@handler_id: Handler id of the handler to be blocked
|
||||||
|
|
||||||
|
|
||||||
<!-- ##### FUNCTION g_signal_handler_unblock ##### -->
|
<!-- ##### FUNCTION g_signal_handler_unblock ##### -->
|
||||||
<para>
|
<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>
|
</para>
|
||||||
|
|
||||||
@instance:
|
@instance: The instance to unblock the signal handler of
|
||||||
@handler_id:
|
@handler_id: Handler id of the handler to be unblocked
|
||||||
|
|
||||||
|
|
||||||
<!-- ##### FUNCTION g_signal_handler_disconnect ##### -->
|
<!-- ##### FUNCTION g_signal_handler_disconnect ##### -->
|
||||||
<para>
|
<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>
|
</para>
|
||||||
|
|
||||||
@instance:
|
@instance: The instance to remove the signal handler from
|
||||||
@handler_id:
|
@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 ##### -->
|
<!-- ##### 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>
|
2000-10-30 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
||||||
|
|
||||||
* gvalue.c (exchange_entries_equal), gparam.c (param_spec_equals):
|
* gvalue.c (exchange_entries_equal), gparam.c (param_spec_equals):
|
||||||
|
@ -16,11 +16,12 @@
|
|||||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||||
* Boston, MA 02111-1307, USA.
|
* Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "gobject.h"
|
#include "gobject.h"
|
||||||
|
|
||||||
|
|
||||||
#include "gvaluecollector.h"
|
#include "gvaluecollector.h"
|
||||||
|
#include "gsignal.h"
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
|
||||||
#define DEBUG_OBJECTS
|
#define DEBUG_OBJECTS
|
||||||
@ -162,6 +163,8 @@ g_object_base_class_finalize (GObjectClass *class)
|
|||||||
guint i;
|
guint i;
|
||||||
|
|
||||||
g_message ("finallizing base class of %s", G_OBJECT_CLASS_NAME (class));
|
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++)
|
for (i = 0; i < class->n_param_specs; i++)
|
||||||
{
|
{
|
||||||
@ -292,6 +295,7 @@ g_object_do_shutdown (GObject *object)
|
|||||||
static void
|
static void
|
||||||
g_object_do_finalize (GObject *object)
|
g_object_do_finalize (GObject *object)
|
||||||
{
|
{
|
||||||
|
g_signal_handlers_destroy (object);
|
||||||
g_datalist_clear (&object->qdata);
|
g_datalist_clear (&object->qdata);
|
||||||
|
|
||||||
#ifdef DEBUG_OBJECTS
|
#ifdef DEBUG_OBJECTS
|
||||||
|
@ -344,7 +344,7 @@ handler_find (gpointer instance,
|
|||||||
((mask & G_SIGNAL_MATCH_FUNC) || (handler->closure->marshal == node->c_marshaller &&
|
((mask & G_SIGNAL_MATCH_FUNC) || (handler->closure->marshal == node->c_marshaller &&
|
||||||
handler->closure->meta_marshal == 0 &&
|
handler->closure->meta_marshal == 0 &&
|
||||||
((GCClosure*) handler->closure)->callback == func)))
|
((GCClosure*) handler->closure)->callback == func)))
|
||||||
return handler;
|
return handler;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -376,7 +376,7 @@ handler_find (gpointer instance,
|
|||||||
((mask & G_SIGNAL_MATCH_FUNC) || (handler->closure->marshal == node->c_marshaller &&
|
((mask & G_SIGNAL_MATCH_FUNC) || (handler->closure->marshal == node->c_marshaller &&
|
||||||
handler->closure->meta_marshal == 0 &&
|
handler->closure->meta_marshal == 0 &&
|
||||||
((GCClosure*) handler->closure)->callback == func)))
|
((GCClosure*) handler->closure)->callback == func)))
|
||||||
return handler;
|
return handler;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -571,7 +571,6 @@ void
|
|||||||
g_signals_destroy (GType itype)
|
g_signals_destroy (GType itype)
|
||||||
{
|
{
|
||||||
guint i;
|
guint i;
|
||||||
gboolean found_one = FALSE;
|
|
||||||
|
|
||||||
G_LOCK (g_signal_mutex);
|
G_LOCK (g_signal_mutex);
|
||||||
for (i = 0; i < g_n_signal_nodes; i++)
|
for (i = 0; i < g_n_signal_nodes; i++)
|
||||||
@ -585,15 +584,9 @@ g_signals_destroy (GType itype)
|
|||||||
node->name,
|
node->name,
|
||||||
g_type_name (node->itype));
|
g_type_name (node->itype));
|
||||||
else
|
else
|
||||||
{
|
signal_destroy_R (node);
|
||||||
found_one = TRUE;
|
|
||||||
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);
|
G_UNLOCK (g_signal_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -917,6 +910,54 @@ g_signal_connect_closure (gpointer instance,
|
|||||||
return handler_id;
|
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
|
void
|
||||||
g_signal_handler_disconnect (gpointer instance,
|
g_signal_handler_disconnect (gpointer instance,
|
||||||
guint handler_id)
|
guint handler_id)
|
||||||
@ -983,54 +1024,6 @@ g_signal_handlers_destroy (gpointer instance)
|
|||||||
G_UNLOCK (g_signal_mutex);
|
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
|
guint
|
||||||
g_signal_handler_find (gpointer instance,
|
g_signal_handler_find (gpointer instance,
|
||||||
GSignalMatchType mask,
|
GSignalMatchType mask,
|
||||||
@ -1040,25 +1033,134 @@ g_signal_handler_find (gpointer instance,
|
|||||||
gpointer func,
|
gpointer func,
|
||||||
gpointer data)
|
gpointer data)
|
||||||
{
|
{
|
||||||
Handler *handler = NULL;
|
Handler *handler;
|
||||||
guint handler_id;
|
guint handler_id = 0;
|
||||||
|
|
||||||
g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), 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_return_val_if_fail ((mask & ~G_SIGNAL_MATCH_MASK) == 0, 0);
|
||||||
|
|
||||||
G_LOCK (g_signal_mutex);
|
if (mask & G_SIGNAL_MATCH_MASK)
|
||||||
handler = handler_find (instance, mask, signal_id, detail, closure, func, data);
|
{
|
||||||
handler_id = handler ? handler->id : 0;
|
G_LOCK (g_signal_mutex);
|
||||||
G_UNLOCK (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;
|
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
|
gboolean
|
||||||
g_signal_handler_pending (gpointer instance,
|
g_signal_has_handler_pending (gpointer instance,
|
||||||
guint signal_id,
|
guint signal_id,
|
||||||
GQuark detail,
|
GQuark detail,
|
||||||
gboolean may_be_blocked)
|
gboolean may_be_blocked)
|
||||||
{
|
{
|
||||||
Handler *handler = NULL;
|
Handler *handler = NULL;
|
||||||
|
|
||||||
@ -1108,7 +1210,11 @@ g_signal_emitv (const GValue *instance_and_params,
|
|||||||
node = LOOKUP_SIGNAL_NODE (signal_id);
|
node = LOOKUP_SIGNAL_NODE (signal_id);
|
||||||
#ifndef G_DISABLE_CHECKS
|
#ifndef G_DISABLE_CHECKS
|
||||||
if (!node || !g_type_conforms_to (G_TYPE_FROM_INSTANCE (instance), node->itype))
|
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))
|
if (detail && !(node->flags & G_SIGNAL_DETAILED))
|
||||||
{
|
{
|
||||||
g_warning ("%s: signal id `%u' does not support detail (%u)", G_STRLOC, signal_id, detail);
|
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,
|
* This library is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* 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.
|
* Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General
|
* You should have received a copy of the GNU Lesser General
|
||||||
@ -31,9 +31,9 @@ extern "C" {
|
|||||||
|
|
||||||
|
|
||||||
/* --- typedefs --- */
|
/* --- typedefs --- */
|
||||||
typedef struct _GSignalQuery GSignalQuery;
|
typedef struct _GSignalQuery GSignalQuery;
|
||||||
typedef struct _GSignalInvocationHint GSignalInvocationHint;
|
typedef struct _GSignalInvocationHint GSignalInvocationHint;
|
||||||
typedef GClosureMarshal GSignalCMarshaller;
|
typedef GClosureMarshal GSignalCMarshaller;
|
||||||
typedef gboolean (*GSignalEmissionHook) (GSignalInvocationHint *ihint,
|
typedef gboolean (*GSignalEmissionHook) (GSignalInvocationHint *ihint,
|
||||||
guint n_param_values,
|
guint n_param_values,
|
||||||
const GValue *param_values);
|
const GValue *param_values);
|
||||||
@ -52,7 +52,7 @@ typedef enum
|
|||||||
G_SIGNAL_DETAILED = 1 << 4,
|
G_SIGNAL_DETAILED = 1 << 4,
|
||||||
G_SIGNAL_ACTION = 1 << 5,
|
G_SIGNAL_ACTION = 1 << 5,
|
||||||
G_SIGNAL_NO_HOOKS = 1 << 6
|
G_SIGNAL_NO_HOOKS = 1 << 6
|
||||||
#define G_SIGNAL_FLAGS_MASK 0x7f
|
#define G_SIGNAL_FLAGS_MASK 0x7f
|
||||||
} GSignalFlags;
|
} GSignalFlags;
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
@ -62,7 +62,7 @@ typedef enum
|
|||||||
G_SIGNAL_MATCH_FUNC = 1 << 3,
|
G_SIGNAL_MATCH_FUNC = 1 << 3,
|
||||||
G_SIGNAL_MATCH_DATA = 1 << 4,
|
G_SIGNAL_MATCH_DATA = 1 << 4,
|
||||||
G_SIGNAL_MATCH_UNBLOCKED = 1 << 5
|
G_SIGNAL_MATCH_UNBLOCKED = 1 << 5
|
||||||
#define G_SIGNAL_MATCH_MASK 0x3f
|
#define G_SIGNAL_MATCH_MASK 0x3f
|
||||||
} GSignalMatchType;
|
} GSignalMatchType;
|
||||||
|
|
||||||
|
|
||||||
@ -86,64 +86,86 @@ struct _GSignalQuery
|
|||||||
|
|
||||||
|
|
||||||
/* --- signals --- */
|
/* --- signals --- */
|
||||||
guint g_signal_newv (const gchar *signal_name,
|
guint g_signal_newv (const gchar *signal_name,
|
||||||
GType itype,
|
GType itype,
|
||||||
GSignalFlags signal_flags,
|
GSignalFlags signal_flags,
|
||||||
GClosure *class_closure,
|
GClosure *class_closure,
|
||||||
GSignalAccumulator accumulator,
|
GSignalAccumulator accumulator,
|
||||||
GSignalCMarshaller c_marshaller,
|
GSignalCMarshaller c_marshaller,
|
||||||
GType return_type,
|
GType return_type,
|
||||||
guint n_params,
|
guint n_params,
|
||||||
GType *param_types);
|
GType *param_types);
|
||||||
void g_signal_emitv (const GValue *instance_and_params,
|
void g_signal_emitv (const GValue *instance_and_params,
|
||||||
guint signal_id,
|
guint signal_id,
|
||||||
GQuark detail,
|
GQuark detail,
|
||||||
GValue *return_value);
|
GValue *return_value);
|
||||||
guint g_signal_lookup (const gchar *name,
|
guint g_signal_lookup (const gchar *name,
|
||||||
GType itype);
|
GType itype);
|
||||||
gchar* g_signal_name (guint signal_id);
|
gchar* g_signal_name (guint signal_id);
|
||||||
void g_signal_query (guint signal_id,
|
void g_signal_query (guint signal_id,
|
||||||
GSignalQuery *query);
|
GSignalQuery *query);
|
||||||
guint* g_signal_list_ids (GType itype,
|
guint* g_signal_list_ids (GType itype,
|
||||||
guint *n_ids);
|
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);
|
|
||||||
|
|
||||||
|
|
||||||
/* --- signal emissions --- */
|
/* --- signal emissions --- */
|
||||||
void g_signal_stop_emission (gpointer instance,
|
void g_signal_stop_emission (gpointer instance,
|
||||||
guint signal_id,
|
guint signal_id,
|
||||||
GQuark detail);
|
GQuark detail);
|
||||||
guint g_signal_add_emission_hook_full (guint signal_id,
|
guint g_signal_add_emission_hook_full (guint signal_id,
|
||||||
GClosure *closure);
|
GClosure *closure);
|
||||||
void g_signal_remove_emission_hook (guint signal_id,
|
void g_signal_remove_emission_hook (guint signal_id,
|
||||||
guint hook_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 >*/
|
/*< private >*/
|
||||||
void g_signal_handlers_destroy (gpointer instance);
|
void g_signal_handlers_destroy (gpointer instance);
|
||||||
void g_signals_destroy (GType itype);
|
void g_signals_destroy (GType itype);
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
Loading…
x
Reference in New Issue
Block a user