mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-02-20 17:22:11 +01:00
destruction cleanup. there's one ->finalize_hook member in the hooklist
Thu Mar 8 16:23:34 2001 Tim Janik <timj@gtk.org> * ghook.[hc]: destruction cleanup. there's one ->finalize_hook member in the hooklist now that gets called when a hook should be destroyed, that's it. that function is guarranteed to be called only when all ref_counts to the hook vanished, thus also when the hook is not in call. Thu Mar 8 16:35:48 2001 Tim Janik <timj@gtk.org> * gparamspecs.[hc]: s/g_param_spec_string_c/g_param_spec_stringc/. * gsignal.[hc]: fixed accumulator invocation, implemented emission hooks. and no, neither of these callbacks are called via a closure, language bindings can wrap the accumulator and emission hook interface, they already get parameters marshalled into a GValue array. (g_signal_connect): removed this function as its C specific, doesn't cover the swapped argument, is too close to its broken original gtk_signal_connect() and creates demand for _swapped, _after and _swapped_after variants <brrr>. (g_signal_connectc): convenience macro to connect a C handler func with data, like the old g_signal_connect() plus swapped argument. * gtype.h: * gboxed.c: added G_TYPE_VALUE boxed type.
This commit is contained in:
parent
c811ed93d3
commit
617332234d
@ -1,3 +1,12 @@
|
|||||||
|
Thu Mar 8 16:23:34 2001 Tim Janik <timj@gtk.org>
|
||||||
|
|
||||||
|
* ghook.[hc]: destruction cleanup. there's one
|
||||||
|
->finalize_hook member in the hooklist now that gets
|
||||||
|
called when a hook should be destroyed, that's it.
|
||||||
|
that function is guarranteed to be called only when
|
||||||
|
all ref_counts to the hook vanished, thus also when
|
||||||
|
the hook is not in call.
|
||||||
|
|
||||||
2001-03-08 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
2001-03-08 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
||||||
|
|
||||||
* configure.in (FLAG_DOES_NOT_WORK): Fix typo and thus bug #51862.
|
* configure.in (FLAG_DOES_NOT_WORK): Fix typo and thus bug #51862.
|
||||||
|
@ -1,3 +1,12 @@
|
|||||||
|
Thu Mar 8 16:23:34 2001 Tim Janik <timj@gtk.org>
|
||||||
|
|
||||||
|
* ghook.[hc]: destruction cleanup. there's one
|
||||||
|
->finalize_hook member in the hooklist now that gets
|
||||||
|
called when a hook should be destroyed, that's it.
|
||||||
|
that function is guarranteed to be called only when
|
||||||
|
all ref_counts to the hook vanished, thus also when
|
||||||
|
the hook is not in call.
|
||||||
|
|
||||||
2001-03-08 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
2001-03-08 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
||||||
|
|
||||||
* configure.in (FLAG_DOES_NOT_WORK): Fix typo and thus bug #51862.
|
* configure.in (FLAG_DOES_NOT_WORK): Fix typo and thus bug #51862.
|
||||||
|
@ -1,3 +1,12 @@
|
|||||||
|
Thu Mar 8 16:23:34 2001 Tim Janik <timj@gtk.org>
|
||||||
|
|
||||||
|
* ghook.[hc]: destruction cleanup. there's one
|
||||||
|
->finalize_hook member in the hooklist now that gets
|
||||||
|
called when a hook should be destroyed, that's it.
|
||||||
|
that function is guarranteed to be called only when
|
||||||
|
all ref_counts to the hook vanished, thus also when
|
||||||
|
the hook is not in call.
|
||||||
|
|
||||||
2001-03-08 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
2001-03-08 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
||||||
|
|
||||||
* configure.in (FLAG_DOES_NOT_WORK): Fix typo and thus bug #51862.
|
* configure.in (FLAG_DOES_NOT_WORK): Fix typo and thus bug #51862.
|
||||||
|
@ -1,3 +1,12 @@
|
|||||||
|
Thu Mar 8 16:23:34 2001 Tim Janik <timj@gtk.org>
|
||||||
|
|
||||||
|
* ghook.[hc]: destruction cleanup. there's one
|
||||||
|
->finalize_hook member in the hooklist now that gets
|
||||||
|
called when a hook should be destroyed, that's it.
|
||||||
|
that function is guarranteed to be called only when
|
||||||
|
all ref_counts to the hook vanished, thus also when
|
||||||
|
the hook is not in call.
|
||||||
|
|
||||||
2001-03-08 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
2001-03-08 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
||||||
|
|
||||||
* configure.in (FLAG_DOES_NOT_WORK): Fix typo and thus bug #51862.
|
* configure.in (FLAG_DOES_NOT_WORK): Fix typo and thus bug #51862.
|
||||||
|
@ -1,3 +1,12 @@
|
|||||||
|
Thu Mar 8 16:23:34 2001 Tim Janik <timj@gtk.org>
|
||||||
|
|
||||||
|
* ghook.[hc]: destruction cleanup. there's one
|
||||||
|
->finalize_hook member in the hooklist now that gets
|
||||||
|
called when a hook should be destroyed, that's it.
|
||||||
|
that function is guarranteed to be called only when
|
||||||
|
all ref_counts to the hook vanished, thus also when
|
||||||
|
the hook is not in call.
|
||||||
|
|
||||||
2001-03-08 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
2001-03-08 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
||||||
|
|
||||||
* configure.in (FLAG_DOES_NOT_WORK): Fix typo and thus bug #51862.
|
* configure.in (FLAG_DOES_NOT_WORK): Fix typo and thus bug #51862.
|
||||||
|
@ -1,3 +1,12 @@
|
|||||||
|
Thu Mar 8 16:23:34 2001 Tim Janik <timj@gtk.org>
|
||||||
|
|
||||||
|
* ghook.[hc]: destruction cleanup. there's one
|
||||||
|
->finalize_hook member in the hooklist now that gets
|
||||||
|
called when a hook should be destroyed, that's it.
|
||||||
|
that function is guarranteed to be called only when
|
||||||
|
all ref_counts to the hook vanished, thus also when
|
||||||
|
the hook is not in call.
|
||||||
|
|
||||||
2001-03-08 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
2001-03-08 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
||||||
|
|
||||||
* configure.in (FLAG_DOES_NOT_WORK): Fix typo and thus bug #51862.
|
* configure.in (FLAG_DOES_NOT_WORK): Fix typo and thus bug #51862.
|
||||||
|
@ -1,3 +1,12 @@
|
|||||||
|
Thu Mar 8 16:23:34 2001 Tim Janik <timj@gtk.org>
|
||||||
|
|
||||||
|
* ghook.[hc]: destruction cleanup. there's one
|
||||||
|
->finalize_hook member in the hooklist now that gets
|
||||||
|
called when a hook should be destroyed, that's it.
|
||||||
|
that function is guarranteed to be called only when
|
||||||
|
all ref_counts to the hook vanished, thus also when
|
||||||
|
the hook is not in call.
|
||||||
|
|
||||||
2001-03-08 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
2001-03-08 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
||||||
|
|
||||||
* configure.in (FLAG_DOES_NOT_WORK): Fix typo and thus bug #51862.
|
* configure.in (FLAG_DOES_NOT_WORK): Fix typo and thus bug #51862.
|
||||||
|
@ -1,3 +1,12 @@
|
|||||||
|
Thu Mar 8 16:23:34 2001 Tim Janik <timj@gtk.org>
|
||||||
|
|
||||||
|
* ghook.[hc]: destruction cleanup. there's one
|
||||||
|
->finalize_hook member in the hooklist now that gets
|
||||||
|
called when a hook should be destroyed, that's it.
|
||||||
|
that function is guarranteed to be called only when
|
||||||
|
all ref_counts to the hook vanished, thus also when
|
||||||
|
the hook is not in call.
|
||||||
|
|
||||||
2001-03-08 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
2001-03-08 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
||||||
|
|
||||||
* configure.in (FLAG_DOES_NOT_WORK): Fix typo and thus bug #51862.
|
* configure.in (FLAG_DOES_NOT_WORK): Fix typo and thus bug #51862.
|
||||||
|
@ -17,6 +17,20 @@
|
|||||||
@s2:
|
@s2:
|
||||||
@Returns:
|
@Returns:
|
||||||
|
|
||||||
|
<!-- ##### USER_FUNCTION GHookFreeFunc ##### -->
|
||||||
|
<para>
|
||||||
|
|
||||||
|
</para>
|
||||||
|
|
||||||
|
@hook_list:
|
||||||
|
@hook:
|
||||||
|
|
||||||
|
<!-- ##### MACRO G_HOOK_DEFERRED_DESTROY ##### -->
|
||||||
|
<para>
|
||||||
|
|
||||||
|
</para>
|
||||||
|
|
||||||
|
|
||||||
<!-- ##### MACRO access ##### -->
|
<!-- ##### MACRO access ##### -->
|
||||||
<para>
|
<para>
|
||||||
|
|
||||||
|
@ -68,8 +68,7 @@ and the list of hook functions can be invoked.
|
|||||||
@is_setup:
|
@is_setup:
|
||||||
@hooks:
|
@hooks:
|
||||||
@hook_memchunk:
|
@hook_memchunk:
|
||||||
@hook_free:
|
@finalize_hook:
|
||||||
@hook_destroy:
|
|
||||||
|
|
||||||
<!-- ##### STRUCT GHook ##### -->
|
<!-- ##### STRUCT GHook ##### -->
|
||||||
<para>
|
<para>
|
||||||
@ -153,6 +152,8 @@ and the list of hook functions can be invoked.
|
|||||||
</para>
|
</para>
|
||||||
|
|
||||||
@hook:
|
@hook:
|
||||||
|
@marshal_data:
|
||||||
|
<!-- # Unused Parameters # -->
|
||||||
@data:
|
@data:
|
||||||
|
|
||||||
|
|
||||||
@ -162,24 +163,10 @@ and the list of hook functions can be invoked.
|
|||||||
</para>
|
</para>
|
||||||
|
|
||||||
@hook:
|
@hook:
|
||||||
@data:
|
@marshal_data:
|
||||||
@Returns:
|
@Returns:
|
||||||
|
<!-- # Unused Parameters # -->
|
||||||
|
@data:
|
||||||
<!-- ##### USER_FUNCTION GHookFreeFunc ##### -->
|
|
||||||
<para>
|
|
||||||
|
|
||||||
</para>
|
|
||||||
|
|
||||||
@hook_list:
|
|
||||||
@hook:
|
|
||||||
|
|
||||||
|
|
||||||
<!-- ##### MACRO G_HOOK_DEFERRED_DESTROY ##### -->
|
|
||||||
<para>
|
|
||||||
|
|
||||||
</para>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!-- ##### FUNCTION g_hook_list_init ##### -->
|
<!-- ##### FUNCTION g_hook_list_init ##### -->
|
||||||
@ -222,6 +209,8 @@ thread) can be called. If set to FALSE, these are skipped.
|
|||||||
@hook_list: a #GHookList.
|
@hook_list: a #GHookList.
|
||||||
@may_recurse:
|
@may_recurse:
|
||||||
@marshaller:
|
@marshaller:
|
||||||
|
@marshal_data:
|
||||||
|
<!-- # Unused Parameters # -->
|
||||||
@data:
|
@data:
|
||||||
|
|
||||||
|
|
||||||
@ -233,6 +222,8 @@ thread) can be called. If set to FALSE, these are skipped.
|
|||||||
@hook_list: a #GHookList.
|
@hook_list: a #GHookList.
|
||||||
@may_recurse:
|
@may_recurse:
|
||||||
@marshaller:
|
@marshaller:
|
||||||
|
@marshal_data:
|
||||||
|
<!-- # Unused Parameters # -->
|
||||||
@data:
|
@data:
|
||||||
|
|
||||||
|
|
||||||
|
@ -66,6 +66,7 @@ only one statement is expected by the compiler.
|
|||||||
Portable way to copy <type>va_list</type> variables.
|
Portable way to copy <type>va_list</type> variables.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
<!-- # Unused Parameters # -->
|
||||||
@ap1: the <type>va_list</type> variable to place a copy of @ap2 in.
|
@ap1: the <type>va_list</type> variable to place a copy of @ap2 in.
|
||||||
@ap2: a <type>va_list</type>.
|
@ap2: a <type>va_list</type>.
|
||||||
|
|
||||||
|
@ -1,3 +1,24 @@
|
|||||||
|
<!-- ##### FUNCTION g_param_spec_string_c ##### -->
|
||||||
|
<para>
|
||||||
|
|
||||||
|
</para>
|
||||||
|
|
||||||
|
@name:
|
||||||
|
@nick:
|
||||||
|
@blurb:
|
||||||
|
@default_value:
|
||||||
|
@flags:
|
||||||
|
@Returns:
|
||||||
|
|
||||||
|
<!-- ##### FUNCTION g_signal_add_emission_hook_full ##### -->
|
||||||
|
<para>
|
||||||
|
|
||||||
|
</para>
|
||||||
|
|
||||||
|
@signal_id:
|
||||||
|
@closure:
|
||||||
|
@Returns:
|
||||||
|
|
||||||
<!-- ##### FUNCTION g_type_value_is_a ##### -->
|
<!-- ##### FUNCTION g_type_value_is_a ##### -->
|
||||||
<para>
|
<para>
|
||||||
Determines if @value is a #GValue whose type conforms to @type.
|
Determines if @value is a #GValue whose type conforms to @type.
|
||||||
|
@ -96,10 +96,13 @@ value returned by the last callback.
|
|||||||
@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.
|
@handler_return:
|
||||||
|
@data:
|
||||||
@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.
|
||||||
|
<!-- # Unused Parameters # -->
|
||||||
|
@return_value: The return value of the most recent callback function.
|
||||||
|
|
||||||
|
|
||||||
<!-- ##### TYPEDEF GSignalCMarshaller ##### -->
|
<!-- ##### TYPEDEF GSignalCMarshaller ##### -->
|
||||||
@ -120,6 +123,7 @@ signal system.
|
|||||||
@ihint:
|
@ihint:
|
||||||
@n_param_values:
|
@n_param_values:
|
||||||
@param_values:
|
@param_values:
|
||||||
|
@data:
|
||||||
@Returns:
|
@Returns:
|
||||||
<!-- # Unused Parameters # -->
|
<!-- # Unused Parameters # -->
|
||||||
@signal_id:
|
@signal_id:
|
||||||
@ -213,6 +217,7 @@ filled in by the g_signal_query() function.
|
|||||||
@signal_flags:
|
@signal_flags:
|
||||||
@class_offset:
|
@class_offset:
|
||||||
@accumulator:
|
@accumulator:
|
||||||
|
@accu_data:
|
||||||
@c_marshaller:
|
@c_marshaller:
|
||||||
@return_type:
|
@return_type:
|
||||||
@n_params:
|
@n_params:
|
||||||
@ -230,6 +235,7 @@ filled in by the g_signal_query() function.
|
|||||||
@signal_flags:
|
@signal_flags:
|
||||||
@class_closure:
|
@class_closure:
|
||||||
@accumulator:
|
@accumulator:
|
||||||
|
@accu_data:
|
||||||
@c_marshaller:
|
@c_marshaller:
|
||||||
@return_type:
|
@return_type:
|
||||||
@n_params:
|
@n_params:
|
||||||
@ -247,6 +253,7 @@ filled in by the g_signal_query() function.
|
|||||||
@signal_flags:
|
@signal_flags:
|
||||||
@class_closure:
|
@class_closure:
|
||||||
@accumulator:
|
@accumulator:
|
||||||
|
@accu_data:
|
||||||
@c_marshaller:
|
@c_marshaller:
|
||||||
@return_type:
|
@return_type:
|
||||||
@n_params:
|
@n_params:
|
||||||
@ -563,16 +570,6 @@ otherwise.
|
|||||||
@detail:
|
@detail:
|
||||||
|
|
||||||
|
|
||||||
<!-- ##### FUNCTION g_signal_add_emission_hook_full ##### -->
|
|
||||||
<para>
|
|
||||||
|
|
||||||
</para>
|
|
||||||
|
|
||||||
@signal_id:
|
|
||||||
@closure:
|
|
||||||
@Returns:
|
|
||||||
|
|
||||||
|
|
||||||
<!-- ##### FUNCTION g_signal_remove_emission_hook ##### -->
|
<!-- ##### FUNCTION g_signal_remove_emission_hook ##### -->
|
||||||
<para>
|
<para>
|
||||||
|
|
||||||
|
@ -593,19 +593,6 @@ Standard Parameter Types
|
|||||||
@Returns:
|
@Returns:
|
||||||
|
|
||||||
|
|
||||||
<!-- ##### FUNCTION g_param_spec_string_c ##### -->
|
|
||||||
<para>
|
|
||||||
|
|
||||||
</para>
|
|
||||||
|
|
||||||
@name:
|
|
||||||
@nick:
|
|
||||||
@blurb:
|
|
||||||
@default_value:
|
|
||||||
@flags:
|
|
||||||
@Returns:
|
|
||||||
|
|
||||||
|
|
||||||
<!-- ##### FUNCTION g_param_spec_boxed ##### -->
|
<!-- ##### FUNCTION g_param_spec_boxed ##### -->
|
||||||
<para>
|
<para>
|
||||||
|
|
||||||
|
@ -201,6 +201,7 @@ The predefined identifiers of the reserved fundamental types.
|
|||||||
@G_TYPE_RESERVED_BSE_LAST: Last fundamental type ID reserved for BSE.
|
@G_TYPE_RESERVED_BSE_LAST: Last fundamental type ID reserved for BSE.
|
||||||
@G_TYPE_RESERVED_LAST_FUNDAMENTAL: Last reserved fundamental type ID.
|
@G_TYPE_RESERVED_LAST_FUNDAMENTAL: Last reserved fundamental type ID.
|
||||||
@G_TYPE_CLOSURE:
|
@G_TYPE_CLOSURE:
|
||||||
|
@G_TYPE_VALUE:
|
||||||
@G_TYPE_VALUE_ARRAY:
|
@G_TYPE_VALUE_ARRAY:
|
||||||
@G_TYPE_PARAM_CHAR: Identifier for the "#GParamSpecChar" type.
|
@G_TYPE_PARAM_CHAR: Identifier for the "#GParamSpecChar" type.
|
||||||
@G_TYPE_PARAM_UCHAR: Identifier for the "#GParamSpecUChar" type.
|
@G_TYPE_PARAM_UCHAR: Identifier for the "#GParamSpecUChar" type.
|
||||||
|
40
ghook.c
40
ghook.c
@ -39,12 +39,26 @@
|
|||||||
|
|
||||||
|
|
||||||
/* --- functions --- */
|
/* --- functions --- */
|
||||||
|
static void
|
||||||
|
default_finalize_hook (GHookList *hook_list,
|
||||||
|
GHook *hook)
|
||||||
|
{
|
||||||
|
GDestroyNotify destroy = hook->destroy;
|
||||||
|
|
||||||
|
if (destroy)
|
||||||
|
{
|
||||||
|
hook->destroy = NULL;
|
||||||
|
destroy (hook->data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
g_hook_list_init (GHookList *hook_list,
|
g_hook_list_init (GHookList *hook_list,
|
||||||
guint hook_size)
|
guint hook_size)
|
||||||
{
|
{
|
||||||
g_return_if_fail (hook_list != NULL);
|
g_return_if_fail (hook_list != NULL);
|
||||||
g_return_if_fail (hook_size >= sizeof (GHook));
|
g_return_if_fail (hook_size >= sizeof (GHook));
|
||||||
|
g_return_if_fail (hook_size < 65536);
|
||||||
|
|
||||||
hook_list->seq_id = 1;
|
hook_list->seq_id = 1;
|
||||||
hook_list->hook_size = hook_size;
|
hook_list->hook_size = hook_size;
|
||||||
@ -54,8 +68,7 @@ g_hook_list_init (GHookList *hook_list,
|
|||||||
hook_size,
|
hook_size,
|
||||||
hook_size * G_HOOKS_PREALLOC,
|
hook_size * G_HOOKS_PREALLOC,
|
||||||
G_ALLOC_AND_FREE);
|
G_ALLOC_AND_FREE);
|
||||||
hook_list->hook_free = NULL;
|
hook_list->finalize_hook = default_finalize_hook;
|
||||||
hook_list->hook_destroy = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -87,6 +100,8 @@ g_hook_list_clear (GHookList *hook_list)
|
|||||||
hook = tmp;
|
hook = tmp;
|
||||||
}
|
}
|
||||||
while (hook);
|
while (hook);
|
||||||
|
if (hook_list->hook_memchunk)
|
||||||
|
g_warning (G_STRLOC ": failed to clear hooklist, unconsolidated references on hooks left");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,10 +134,9 @@ g_hook_free (GHookList *hook_list,
|
|||||||
g_return_if_fail (hook_list->is_setup);
|
g_return_if_fail (hook_list->is_setup);
|
||||||
g_return_if_fail (hook != NULL);
|
g_return_if_fail (hook != NULL);
|
||||||
g_return_if_fail (G_HOOK_IS_UNLINKED (hook));
|
g_return_if_fail (G_HOOK_IS_UNLINKED (hook));
|
||||||
|
g_return_if_fail (!G_HOOK_IN_CALL (hook));
|
||||||
|
|
||||||
if (hook_list->hook_free)
|
hook_list->finalize_hook (hook_list, hook);
|
||||||
hook_list->hook_free (hook_list, hook);
|
|
||||||
|
|
||||||
g_chunk_free (hook, hook_list->hook_memchunk);
|
g_chunk_free (hook, hook_list->hook_memchunk);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,22 +147,10 @@ g_hook_destroy_link (GHookList *hook_list,
|
|||||||
g_return_if_fail (hook_list != NULL);
|
g_return_if_fail (hook_list != NULL);
|
||||||
g_return_if_fail (hook != NULL);
|
g_return_if_fail (hook != NULL);
|
||||||
|
|
||||||
|
hook->flags &= ~G_HOOK_FLAG_ACTIVE;
|
||||||
if (hook->hook_id)
|
if (hook->hook_id)
|
||||||
{
|
{
|
||||||
hook->hook_id = 0;
|
hook->hook_id = 0;
|
||||||
hook->flags &= ~G_HOOK_FLAG_ACTIVE;
|
|
||||||
if (hook_list->hook_destroy)
|
|
||||||
{
|
|
||||||
if (hook_list->hook_destroy != G_HOOK_DEFERRED_DESTROY)
|
|
||||||
hook_list->hook_destroy (hook_list, hook);
|
|
||||||
}
|
|
||||||
else if (hook->destroy)
|
|
||||||
{
|
|
||||||
hook->destroy (hook->data);
|
|
||||||
hook->data = NULL;
|
|
||||||
hook->func = NULL;
|
|
||||||
hook->destroy = NULL;
|
|
||||||
}
|
|
||||||
g_hook_unref (hook_list, hook); /* counterpart to g_hook_insert_before */
|
g_hook_unref (hook_list, hook); /* counterpart to g_hook_insert_before */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -244,7 +246,7 @@ g_hook_insert_before (GHookList *hook_list,
|
|||||||
g_return_if_fail (hook_list->is_setup);
|
g_return_if_fail (hook_list->is_setup);
|
||||||
g_return_if_fail (hook != NULL);
|
g_return_if_fail (hook != NULL);
|
||||||
g_return_if_fail (G_HOOK_IS_UNLINKED (hook));
|
g_return_if_fail (G_HOOK_IS_UNLINKED (hook));
|
||||||
g_return_if_fail (hook->func != NULL);
|
g_return_if_fail (hook->ref_count == 0);
|
||||||
|
|
||||||
hook->hook_id = hook_list->seq_id++;
|
hook->hook_id = hook_list->seq_id++;
|
||||||
hook->ref_count = 1; /* counterpart to g_hook_destroy_link */
|
hook->ref_count = 1; /* counterpart to g_hook_destroy_link */
|
||||||
|
70
ghook.h
70
ghook.h
@ -31,6 +31,8 @@
|
|||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
|
||||||
|
/* --- typedefs --- */
|
||||||
typedef struct _GHook GHook;
|
typedef struct _GHook GHook;
|
||||||
typedef struct _GHookList GHookList;
|
typedef struct _GHookList GHookList;
|
||||||
|
|
||||||
@ -39,37 +41,32 @@ typedef gint (*GHookCompareFunc) (GHook *new_hook,
|
|||||||
typedef gboolean (*GHookFindFunc) (GHook *hook,
|
typedef gboolean (*GHookFindFunc) (GHook *hook,
|
||||||
gpointer data);
|
gpointer data);
|
||||||
typedef void (*GHookMarshaller) (GHook *hook,
|
typedef void (*GHookMarshaller) (GHook *hook,
|
||||||
gpointer data);
|
gpointer marshal_data);
|
||||||
typedef gboolean (*GHookCheckMarshaller) (GHook *hook,
|
typedef gboolean (*GHookCheckMarshaller) (GHook *hook,
|
||||||
gpointer data);
|
gpointer marshal_data);
|
||||||
typedef void (*GHookFunc) (gpointer data);
|
typedef void (*GHookFunc) (gpointer data);
|
||||||
typedef gboolean (*GHookCheckFunc) (gpointer data);
|
typedef gboolean (*GHookCheckFunc) (gpointer data);
|
||||||
typedef void (*GHookFreeFunc) (GHookList *hook_list,
|
typedef void (*GHookFinalizeFunc) (GHookList *hook_list,
|
||||||
GHook *hook);
|
GHook *hook);
|
||||||
|
|
||||||
/* Callback maintenance functions
|
|
||||||
*/
|
|
||||||
#define G_HOOK_FLAG_USER_SHIFT (4)
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
G_HOOK_FLAG_ACTIVE = 1 << 0,
|
G_HOOK_FLAG_ACTIVE = 1 << 0,
|
||||||
G_HOOK_FLAG_IN_CALL = 1 << 1,
|
G_HOOK_FLAG_IN_CALL = 1 << 1,
|
||||||
G_HOOK_FLAG_MASK = 0x0f
|
G_HOOK_FLAG_MASK = 0x0f
|
||||||
} GHookFlagMask;
|
} GHookFlagMask;
|
||||||
|
#define G_HOOK_FLAG_USER_SHIFT (4)
|
||||||
|
|
||||||
#define G_HOOK_DEFERRED_DESTROY ((GHookFreeFunc) 0x01)
|
|
||||||
|
|
||||||
|
/* --- structures --- */
|
||||||
struct _GHookList
|
struct _GHookList
|
||||||
{
|
{
|
||||||
guint seq_id;
|
guint seq_id;
|
||||||
guint hook_size;
|
guint hook_size : 16;
|
||||||
guint is_setup : 1;
|
guint is_setup : 1;
|
||||||
GHook *hooks;
|
GHook *hooks;
|
||||||
GMemChunk *hook_memchunk;
|
GMemChunk *hook_memchunk;
|
||||||
GHookFreeFunc hook_free; /* virtual function */
|
GHookFinalizeFunc finalize_hook;
|
||||||
GHookFreeFunc hook_destroy; /* virtual function */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GHook
|
struct _GHook
|
||||||
{
|
{
|
||||||
gpointer data;
|
gpointer data;
|
||||||
@ -82,17 +79,25 @@ struct _GHook
|
|||||||
GDestroyNotify destroy;
|
GDestroyNotify destroy;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define G_HOOK_ACTIVE(hook) ((((GHook*) hook)->flags & \
|
|
||||||
G_HOOK_FLAG_ACTIVE) != 0)
|
|
||||||
#define G_HOOK_IN_CALL(hook) ((((GHook*) hook)->flags & \
|
|
||||||
G_HOOK_FLAG_IN_CALL) != 0)
|
|
||||||
#define G_HOOK_IS_VALID(hook) (((GHook*) hook)->hook_id != 0 && \
|
|
||||||
G_HOOK_ACTIVE (hook))
|
|
||||||
#define G_HOOK_IS_UNLINKED(hook) (((GHook*) hook)->next == NULL && \
|
|
||||||
((GHook*) hook)->prev == NULL && \
|
|
||||||
((GHook*) hook)->hook_id == 0 && \
|
|
||||||
((GHook*) hook)->ref_count == 0)
|
|
||||||
|
|
||||||
|
/* --- macros --- */
|
||||||
|
#define G_HOOK(hook) ((GHook*) (hook))
|
||||||
|
#define G_HOOK_FLAGS(hook) (G_HOOK (hook)->flags)
|
||||||
|
#define G_HOOK_ACTIVE(hook) ((G_HOOK_FLAGS (hook) & \
|
||||||
|
G_HOOK_FLAG_ACTIVE) != 0)
|
||||||
|
#define G_HOOK_IN_CALL(hook) ((G_HOOK_FLAGS (hook) & \
|
||||||
|
G_HOOK_FLAG_IN_CALL) != 0)
|
||||||
|
#define G_HOOK_IS_VALID(hook) (G_HOOK (hook)->hook_id != 0 && \
|
||||||
|
(G_HOOK_FLAGS (hook) & \
|
||||||
|
G_HOOK_FLAG_ACTIVE))
|
||||||
|
#define G_HOOK_IS_UNLINKED(hook) (G_HOOK (hook)->next == NULL && \
|
||||||
|
G_HOOK (hook)->prev == NULL && \
|
||||||
|
G_HOOK (hook)->hook_id == 0 && \
|
||||||
|
G_HOOK (hook)->ref_count == 0)
|
||||||
|
|
||||||
|
|
||||||
|
/* --- prototypes --- */
|
||||||
|
/* callback mainenance functions */
|
||||||
void g_hook_list_init (GHookList *hook_list,
|
void g_hook_list_init (GHookList *hook_list,
|
||||||
guint hook_size);
|
guint hook_size);
|
||||||
void g_hook_list_clear (GHookList *hook_list);
|
void g_hook_list_clear (GHookList *hook_list);
|
||||||
@ -140,15 +145,12 @@ GHook* g_hook_first_valid (GHookList *hook_list,
|
|||||||
GHook* g_hook_next_valid (GHookList *hook_list,
|
GHook* g_hook_next_valid (GHookList *hook_list,
|
||||||
GHook *hook,
|
GHook *hook,
|
||||||
gboolean may_be_in_call);
|
gboolean may_be_in_call);
|
||||||
|
|
||||||
/* GHookCompareFunc implementation to insert hooks sorted by their id */
|
/* GHookCompareFunc implementation to insert hooks sorted by their id */
|
||||||
gint g_hook_compare_ids (GHook *new_hook,
|
gint g_hook_compare_ids (GHook *new_hook,
|
||||||
GHook *sibling);
|
GHook *sibling);
|
||||||
|
|
||||||
/* convenience macros */
|
/* convenience macros */
|
||||||
#define g_hook_append( hook_list, hook ) \
|
#define g_hook_append( hook_list, hook ) \
|
||||||
g_hook_insert_before ((hook_list), NULL, (hook))
|
g_hook_insert_before ((hook_list), NULL, (hook))
|
||||||
|
|
||||||
/* invoke all valid hooks with the (*GHookFunc) signature.
|
/* invoke all valid hooks with the (*GHookFunc) signature.
|
||||||
*/
|
*/
|
||||||
void g_hook_list_invoke (GHookList *hook_list,
|
void g_hook_list_invoke (GHookList *hook_list,
|
||||||
@ -163,11 +165,11 @@ void g_hook_list_invoke_check (GHookList *hook_list,
|
|||||||
void g_hook_list_marshal (GHookList *hook_list,
|
void g_hook_list_marshal (GHookList *hook_list,
|
||||||
gboolean may_recurse,
|
gboolean may_recurse,
|
||||||
GHookMarshaller marshaller,
|
GHookMarshaller marshaller,
|
||||||
gpointer data);
|
gpointer marshal_data);
|
||||||
void g_hook_list_marshal_check (GHookList *hook_list,
|
void g_hook_list_marshal_check (GHookList *hook_list,
|
||||||
gboolean may_recurse,
|
gboolean may_recurse,
|
||||||
GHookCheckMarshaller marshaller,
|
GHookCheckMarshaller marshaller,
|
||||||
gpointer data);
|
gpointer marshal_data);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
|
40
glib/ghook.c
40
glib/ghook.c
@ -39,12 +39,26 @@
|
|||||||
|
|
||||||
|
|
||||||
/* --- functions --- */
|
/* --- functions --- */
|
||||||
|
static void
|
||||||
|
default_finalize_hook (GHookList *hook_list,
|
||||||
|
GHook *hook)
|
||||||
|
{
|
||||||
|
GDestroyNotify destroy = hook->destroy;
|
||||||
|
|
||||||
|
if (destroy)
|
||||||
|
{
|
||||||
|
hook->destroy = NULL;
|
||||||
|
destroy (hook->data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
g_hook_list_init (GHookList *hook_list,
|
g_hook_list_init (GHookList *hook_list,
|
||||||
guint hook_size)
|
guint hook_size)
|
||||||
{
|
{
|
||||||
g_return_if_fail (hook_list != NULL);
|
g_return_if_fail (hook_list != NULL);
|
||||||
g_return_if_fail (hook_size >= sizeof (GHook));
|
g_return_if_fail (hook_size >= sizeof (GHook));
|
||||||
|
g_return_if_fail (hook_size < 65536);
|
||||||
|
|
||||||
hook_list->seq_id = 1;
|
hook_list->seq_id = 1;
|
||||||
hook_list->hook_size = hook_size;
|
hook_list->hook_size = hook_size;
|
||||||
@ -54,8 +68,7 @@ g_hook_list_init (GHookList *hook_list,
|
|||||||
hook_size,
|
hook_size,
|
||||||
hook_size * G_HOOKS_PREALLOC,
|
hook_size * G_HOOKS_PREALLOC,
|
||||||
G_ALLOC_AND_FREE);
|
G_ALLOC_AND_FREE);
|
||||||
hook_list->hook_free = NULL;
|
hook_list->finalize_hook = default_finalize_hook;
|
||||||
hook_list->hook_destroy = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -87,6 +100,8 @@ g_hook_list_clear (GHookList *hook_list)
|
|||||||
hook = tmp;
|
hook = tmp;
|
||||||
}
|
}
|
||||||
while (hook);
|
while (hook);
|
||||||
|
if (hook_list->hook_memchunk)
|
||||||
|
g_warning (G_STRLOC ": failed to clear hooklist, unconsolidated references on hooks left");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,10 +134,9 @@ g_hook_free (GHookList *hook_list,
|
|||||||
g_return_if_fail (hook_list->is_setup);
|
g_return_if_fail (hook_list->is_setup);
|
||||||
g_return_if_fail (hook != NULL);
|
g_return_if_fail (hook != NULL);
|
||||||
g_return_if_fail (G_HOOK_IS_UNLINKED (hook));
|
g_return_if_fail (G_HOOK_IS_UNLINKED (hook));
|
||||||
|
g_return_if_fail (!G_HOOK_IN_CALL (hook));
|
||||||
|
|
||||||
if (hook_list->hook_free)
|
hook_list->finalize_hook (hook_list, hook);
|
||||||
hook_list->hook_free (hook_list, hook);
|
|
||||||
|
|
||||||
g_chunk_free (hook, hook_list->hook_memchunk);
|
g_chunk_free (hook, hook_list->hook_memchunk);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,22 +147,10 @@ g_hook_destroy_link (GHookList *hook_list,
|
|||||||
g_return_if_fail (hook_list != NULL);
|
g_return_if_fail (hook_list != NULL);
|
||||||
g_return_if_fail (hook != NULL);
|
g_return_if_fail (hook != NULL);
|
||||||
|
|
||||||
|
hook->flags &= ~G_HOOK_FLAG_ACTIVE;
|
||||||
if (hook->hook_id)
|
if (hook->hook_id)
|
||||||
{
|
{
|
||||||
hook->hook_id = 0;
|
hook->hook_id = 0;
|
||||||
hook->flags &= ~G_HOOK_FLAG_ACTIVE;
|
|
||||||
if (hook_list->hook_destroy)
|
|
||||||
{
|
|
||||||
if (hook_list->hook_destroy != G_HOOK_DEFERRED_DESTROY)
|
|
||||||
hook_list->hook_destroy (hook_list, hook);
|
|
||||||
}
|
|
||||||
else if (hook->destroy)
|
|
||||||
{
|
|
||||||
hook->destroy (hook->data);
|
|
||||||
hook->data = NULL;
|
|
||||||
hook->func = NULL;
|
|
||||||
hook->destroy = NULL;
|
|
||||||
}
|
|
||||||
g_hook_unref (hook_list, hook); /* counterpart to g_hook_insert_before */
|
g_hook_unref (hook_list, hook); /* counterpart to g_hook_insert_before */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -244,7 +246,7 @@ g_hook_insert_before (GHookList *hook_list,
|
|||||||
g_return_if_fail (hook_list->is_setup);
|
g_return_if_fail (hook_list->is_setup);
|
||||||
g_return_if_fail (hook != NULL);
|
g_return_if_fail (hook != NULL);
|
||||||
g_return_if_fail (G_HOOK_IS_UNLINKED (hook));
|
g_return_if_fail (G_HOOK_IS_UNLINKED (hook));
|
||||||
g_return_if_fail (hook->func != NULL);
|
g_return_if_fail (hook->ref_count == 0);
|
||||||
|
|
||||||
hook->hook_id = hook_list->seq_id++;
|
hook->hook_id = hook_list->seq_id++;
|
||||||
hook->ref_count = 1; /* counterpart to g_hook_destroy_link */
|
hook->ref_count = 1; /* counterpart to g_hook_destroy_link */
|
||||||
|
70
glib/ghook.h
70
glib/ghook.h
@ -31,6 +31,8 @@
|
|||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
|
||||||
|
/* --- typedefs --- */
|
||||||
typedef struct _GHook GHook;
|
typedef struct _GHook GHook;
|
||||||
typedef struct _GHookList GHookList;
|
typedef struct _GHookList GHookList;
|
||||||
|
|
||||||
@ -39,37 +41,32 @@ typedef gint (*GHookCompareFunc) (GHook *new_hook,
|
|||||||
typedef gboolean (*GHookFindFunc) (GHook *hook,
|
typedef gboolean (*GHookFindFunc) (GHook *hook,
|
||||||
gpointer data);
|
gpointer data);
|
||||||
typedef void (*GHookMarshaller) (GHook *hook,
|
typedef void (*GHookMarshaller) (GHook *hook,
|
||||||
gpointer data);
|
gpointer marshal_data);
|
||||||
typedef gboolean (*GHookCheckMarshaller) (GHook *hook,
|
typedef gboolean (*GHookCheckMarshaller) (GHook *hook,
|
||||||
gpointer data);
|
gpointer marshal_data);
|
||||||
typedef void (*GHookFunc) (gpointer data);
|
typedef void (*GHookFunc) (gpointer data);
|
||||||
typedef gboolean (*GHookCheckFunc) (gpointer data);
|
typedef gboolean (*GHookCheckFunc) (gpointer data);
|
||||||
typedef void (*GHookFreeFunc) (GHookList *hook_list,
|
typedef void (*GHookFinalizeFunc) (GHookList *hook_list,
|
||||||
GHook *hook);
|
GHook *hook);
|
||||||
|
|
||||||
/* Callback maintenance functions
|
|
||||||
*/
|
|
||||||
#define G_HOOK_FLAG_USER_SHIFT (4)
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
G_HOOK_FLAG_ACTIVE = 1 << 0,
|
G_HOOK_FLAG_ACTIVE = 1 << 0,
|
||||||
G_HOOK_FLAG_IN_CALL = 1 << 1,
|
G_HOOK_FLAG_IN_CALL = 1 << 1,
|
||||||
G_HOOK_FLAG_MASK = 0x0f
|
G_HOOK_FLAG_MASK = 0x0f
|
||||||
} GHookFlagMask;
|
} GHookFlagMask;
|
||||||
|
#define G_HOOK_FLAG_USER_SHIFT (4)
|
||||||
|
|
||||||
#define G_HOOK_DEFERRED_DESTROY ((GHookFreeFunc) 0x01)
|
|
||||||
|
|
||||||
|
/* --- structures --- */
|
||||||
struct _GHookList
|
struct _GHookList
|
||||||
{
|
{
|
||||||
guint seq_id;
|
guint seq_id;
|
||||||
guint hook_size;
|
guint hook_size : 16;
|
||||||
guint is_setup : 1;
|
guint is_setup : 1;
|
||||||
GHook *hooks;
|
GHook *hooks;
|
||||||
GMemChunk *hook_memchunk;
|
GMemChunk *hook_memchunk;
|
||||||
GHookFreeFunc hook_free; /* virtual function */
|
GHookFinalizeFunc finalize_hook;
|
||||||
GHookFreeFunc hook_destroy; /* virtual function */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GHook
|
struct _GHook
|
||||||
{
|
{
|
||||||
gpointer data;
|
gpointer data;
|
||||||
@ -82,17 +79,25 @@ struct _GHook
|
|||||||
GDestroyNotify destroy;
|
GDestroyNotify destroy;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define G_HOOK_ACTIVE(hook) ((((GHook*) hook)->flags & \
|
|
||||||
G_HOOK_FLAG_ACTIVE) != 0)
|
|
||||||
#define G_HOOK_IN_CALL(hook) ((((GHook*) hook)->flags & \
|
|
||||||
G_HOOK_FLAG_IN_CALL) != 0)
|
|
||||||
#define G_HOOK_IS_VALID(hook) (((GHook*) hook)->hook_id != 0 && \
|
|
||||||
G_HOOK_ACTIVE (hook))
|
|
||||||
#define G_HOOK_IS_UNLINKED(hook) (((GHook*) hook)->next == NULL && \
|
|
||||||
((GHook*) hook)->prev == NULL && \
|
|
||||||
((GHook*) hook)->hook_id == 0 && \
|
|
||||||
((GHook*) hook)->ref_count == 0)
|
|
||||||
|
|
||||||
|
/* --- macros --- */
|
||||||
|
#define G_HOOK(hook) ((GHook*) (hook))
|
||||||
|
#define G_HOOK_FLAGS(hook) (G_HOOK (hook)->flags)
|
||||||
|
#define G_HOOK_ACTIVE(hook) ((G_HOOK_FLAGS (hook) & \
|
||||||
|
G_HOOK_FLAG_ACTIVE) != 0)
|
||||||
|
#define G_HOOK_IN_CALL(hook) ((G_HOOK_FLAGS (hook) & \
|
||||||
|
G_HOOK_FLAG_IN_CALL) != 0)
|
||||||
|
#define G_HOOK_IS_VALID(hook) (G_HOOK (hook)->hook_id != 0 && \
|
||||||
|
(G_HOOK_FLAGS (hook) & \
|
||||||
|
G_HOOK_FLAG_ACTIVE))
|
||||||
|
#define G_HOOK_IS_UNLINKED(hook) (G_HOOK (hook)->next == NULL && \
|
||||||
|
G_HOOK (hook)->prev == NULL && \
|
||||||
|
G_HOOK (hook)->hook_id == 0 && \
|
||||||
|
G_HOOK (hook)->ref_count == 0)
|
||||||
|
|
||||||
|
|
||||||
|
/* --- prototypes --- */
|
||||||
|
/* callback mainenance functions */
|
||||||
void g_hook_list_init (GHookList *hook_list,
|
void g_hook_list_init (GHookList *hook_list,
|
||||||
guint hook_size);
|
guint hook_size);
|
||||||
void g_hook_list_clear (GHookList *hook_list);
|
void g_hook_list_clear (GHookList *hook_list);
|
||||||
@ -140,15 +145,12 @@ GHook* g_hook_first_valid (GHookList *hook_list,
|
|||||||
GHook* g_hook_next_valid (GHookList *hook_list,
|
GHook* g_hook_next_valid (GHookList *hook_list,
|
||||||
GHook *hook,
|
GHook *hook,
|
||||||
gboolean may_be_in_call);
|
gboolean may_be_in_call);
|
||||||
|
|
||||||
/* GHookCompareFunc implementation to insert hooks sorted by their id */
|
/* GHookCompareFunc implementation to insert hooks sorted by their id */
|
||||||
gint g_hook_compare_ids (GHook *new_hook,
|
gint g_hook_compare_ids (GHook *new_hook,
|
||||||
GHook *sibling);
|
GHook *sibling);
|
||||||
|
|
||||||
/* convenience macros */
|
/* convenience macros */
|
||||||
#define g_hook_append( hook_list, hook ) \
|
#define g_hook_append( hook_list, hook ) \
|
||||||
g_hook_insert_before ((hook_list), NULL, (hook))
|
g_hook_insert_before ((hook_list), NULL, (hook))
|
||||||
|
|
||||||
/* invoke all valid hooks with the (*GHookFunc) signature.
|
/* invoke all valid hooks with the (*GHookFunc) signature.
|
||||||
*/
|
*/
|
||||||
void g_hook_list_invoke (GHookList *hook_list,
|
void g_hook_list_invoke (GHookList *hook_list,
|
||||||
@ -163,11 +165,11 @@ void g_hook_list_invoke_check (GHookList *hook_list,
|
|||||||
void g_hook_list_marshal (GHookList *hook_list,
|
void g_hook_list_marshal (GHookList *hook_list,
|
||||||
gboolean may_recurse,
|
gboolean may_recurse,
|
||||||
GHookMarshaller marshaller,
|
GHookMarshaller marshaller,
|
||||||
gpointer data);
|
gpointer marshal_data);
|
||||||
void g_hook_list_marshal_check (GHookList *hook_list,
|
void g_hook_list_marshal_check (GHookList *hook_list,
|
||||||
gboolean may_recurse,
|
gboolean may_recurse,
|
||||||
GHookCheckMarshaller marshaller,
|
GHookCheckMarshaller marshaller,
|
||||||
gpointer data);
|
gpointer marshal_data);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
|
@ -1,3 +1,22 @@
|
|||||||
|
Thu Mar 8 16:35:48 2001 Tim Janik <timj@gtk.org>
|
||||||
|
|
||||||
|
* gparamspecs.[hc]: s/g_param_spec_string_c/g_param_spec_stringc/.
|
||||||
|
|
||||||
|
* gsignal.[hc]: fixed accumulator invocation, implemented emission
|
||||||
|
hooks. and no, neither of these callbacks are called via a closure,
|
||||||
|
language bindings can wrap the accumulator and emission hook
|
||||||
|
interface, they already get parameters marshalled into a GValue array.
|
||||||
|
(g_signal_connect): removed this function as its C specific, doesn't
|
||||||
|
cover the swapped argument, is too close to its broken original
|
||||||
|
gtk_signal_connect() and creates demand for _swapped, _after and
|
||||||
|
_swapped_after variants <brrr>.
|
||||||
|
(g_signal_connectc): convenience macro to connect a C handler
|
||||||
|
func with data, like the old g_signal_connect() plus swapped
|
||||||
|
argument.
|
||||||
|
|
||||||
|
* gtype.h:
|
||||||
|
* gboxed.c: added G_TYPE_VALUE boxed type.
|
||||||
|
|
||||||
Wed Mar 7 19:02:51 2001 Tim Janik <timj@gtk.org>
|
Wed Mar 7 19:02:51 2001 Tim Janik <timj@gtk.org>
|
||||||
|
|
||||||
* gtype.c (type_node_add_iface_entry_W): catch when adding an interface
|
* gtype.c (type_node_add_iface_entry_W): catch when adding an interface
|
||||||
|
@ -64,6 +64,30 @@ value_meminit (GValue *value,
|
|||||||
memset (value->data, 0, sizeof (value->data));
|
memset (value->data, 0, sizeof (value->data));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gpointer
|
||||||
|
value_copy (gpointer boxed)
|
||||||
|
{
|
||||||
|
const GValue *src_value = boxed;
|
||||||
|
GValue *dest_value = g_new0 (GValue, 1);
|
||||||
|
|
||||||
|
if (G_VALUE_TYPE (src_value))
|
||||||
|
{
|
||||||
|
g_value_init (dest_value, G_VALUE_TYPE (src_value));
|
||||||
|
g_value_copy (src_value, dest_value);
|
||||||
|
}
|
||||||
|
return dest_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
value_free (gpointer boxed)
|
||||||
|
{
|
||||||
|
GValue *value = boxed;
|
||||||
|
|
||||||
|
if (G_VALUE_TYPE (value))
|
||||||
|
g_value_unset (value);
|
||||||
|
g_free (value);
|
||||||
|
}
|
||||||
|
|
||||||
static gpointer
|
static gpointer
|
||||||
value_array_init (void)
|
value_array_init (void)
|
||||||
{
|
{
|
||||||
@ -103,6 +127,15 @@ g_boxed_type_init (void) /* sync with gtype.c */
|
|||||||
TRUE);
|
TRUE);
|
||||||
g_assert (type == G_TYPE_CLOSURE);
|
g_assert (type == G_TYPE_CLOSURE);
|
||||||
|
|
||||||
|
/* boxed: G_TYPE_VALUE
|
||||||
|
*/
|
||||||
|
type = g_boxed_type_register_static ("GValue",
|
||||||
|
(GBoxedInitFunc) NULL,
|
||||||
|
value_copy,
|
||||||
|
value_free,
|
||||||
|
FALSE);
|
||||||
|
g_assert (type == G_TYPE_VALUE);
|
||||||
|
|
||||||
/* boxed: G_TYPE_VALUE_ARRAY
|
/* boxed: G_TYPE_VALUE_ARRAY
|
||||||
*/
|
*/
|
||||||
type = g_boxed_type_register_static ("GValueArray",
|
type = g_boxed_type_register_static ("GValueArray",
|
||||||
|
@ -271,8 +271,8 @@ g_object_do_class_init (GObjectClass *class)
|
|||||||
G_TYPE_FROM_CLASS (class),
|
G_TYPE_FROM_CLASS (class),
|
||||||
G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE,
|
G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE,
|
||||||
G_STRUCT_OFFSET (GObjectClass, properties_changed),
|
G_STRUCT_OFFSET (GObjectClass, properties_changed),
|
||||||
NULL, /* accumulator */
|
NULL, NULL,
|
||||||
g_cclosure_marshal_VOID__UINT_POINTER,
|
g_cclosure_marshal_VOID__UINT_POINTER,
|
||||||
G_TYPE_NONE,
|
G_TYPE_NONE,
|
||||||
2, G_TYPE_UINT, G_TYPE_POINTER);
|
2, G_TYPE_UINT, G_TYPE_POINTER);
|
||||||
gobject_signals[NOTIFY] =
|
gobject_signals[NOTIFY] =
|
||||||
@ -280,7 +280,7 @@ g_object_do_class_init (GObjectClass *class)
|
|||||||
G_TYPE_FROM_CLASS (class),
|
G_TYPE_FROM_CLASS (class),
|
||||||
G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE | G_SIGNAL_DETAILED | G_SIGNAL_NO_HOOKS,
|
G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE | G_SIGNAL_DETAILED | G_SIGNAL_NO_HOOKS,
|
||||||
G_STRUCT_OFFSET (GObjectClass, notify),
|
G_STRUCT_OFFSET (GObjectClass, notify),
|
||||||
NULL, /* accumulator */
|
NULL, NULL,
|
||||||
g_cclosure_marshal_VOID__PARAM,
|
g_cclosure_marshal_VOID__PARAM,
|
||||||
G_TYPE_NONE,
|
G_TYPE_NONE,
|
||||||
1, G_TYPE_PARAM);
|
1, G_TYPE_PARAM);
|
||||||
|
@ -1453,11 +1453,11 @@ g_param_spec_string (const gchar *name,
|
|||||||
}
|
}
|
||||||
|
|
||||||
GParamSpec*
|
GParamSpec*
|
||||||
g_param_spec_string_c (const gchar *name,
|
g_param_spec_stringc (const gchar *name,
|
||||||
const gchar *nick,
|
const gchar *nick,
|
||||||
const gchar *blurb,
|
const gchar *blurb,
|
||||||
const gchar *default_value,
|
const gchar *default_value,
|
||||||
GParamFlags flags)
|
GParamFlags flags)
|
||||||
{
|
{
|
||||||
GParamSpecString *sspec = g_param_spec_internal (G_TYPE_PARAM_STRING,
|
GParamSpecString *sspec = g_param_spec_internal (G_TYPE_PARAM_STRING,
|
||||||
name,
|
name,
|
||||||
|
@ -295,7 +295,7 @@ GParamSpec* g_param_spec_string (const gchar *name,
|
|||||||
const gchar *blurb,
|
const gchar *blurb,
|
||||||
const gchar *default_value,
|
const gchar *default_value,
|
||||||
GParamFlags flags);
|
GParamFlags flags);
|
||||||
GParamSpec* g_param_spec_string_c (const gchar *name,
|
GParamSpec* g_param_spec_stringc (const gchar *name,
|
||||||
const gchar *nick,
|
const gchar *nick,
|
||||||
const gchar *blurb,
|
const gchar *blurb,
|
||||||
const gchar *default_value,
|
const gchar *default_value,
|
||||||
|
@ -27,6 +27,8 @@
|
|||||||
#include "gsignal.h"
|
#include "gsignal.h"
|
||||||
#include "gbsearcharray.h"
|
#include "gbsearcharray.h"
|
||||||
#include "gvaluecollector.h"
|
#include "gvaluecollector.h"
|
||||||
|
#include "gvaluetypes.h"
|
||||||
|
#include "gboxed.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
|
||||||
@ -147,6 +149,11 @@ static gboolean signal_emit_R (SignalNode *node,
|
|||||||
|
|
||||||
|
|
||||||
/* --- structures --- */
|
/* --- structures --- */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
GSignalAccumulator func;
|
||||||
|
gpointer data;
|
||||||
|
} SignalAccumulator;
|
||||||
struct _SignalNode
|
struct _SignalNode
|
||||||
{
|
{
|
||||||
/* permanent portion */
|
/* permanent portion */
|
||||||
@ -161,7 +168,7 @@ struct _SignalNode
|
|||||||
GType *param_types; /* mangled with G_SIGNAL_TYPE_STATIC_SCOPE flag */
|
GType *param_types; /* mangled with G_SIGNAL_TYPE_STATIC_SCOPE flag */
|
||||||
GType return_type; /* mangled with G_SIGNAL_TYPE_STATIC_SCOPE flag */
|
GType return_type; /* mangled with G_SIGNAL_TYPE_STATIC_SCOPE flag */
|
||||||
GClosure *class_closure;
|
GClosure *class_closure;
|
||||||
GSignalAccumulator accumulator;
|
SignalAccumulator *accumulator;
|
||||||
GSignalCMarshaller c_marshaller;
|
GSignalCMarshaller c_marshaller;
|
||||||
GHookList *emission_hooks;
|
GHookList *emission_hooks;
|
||||||
};
|
};
|
||||||
@ -723,6 +730,85 @@ g_signal_stop_emission (gpointer instance,
|
|||||||
G_UNLOCK (g_signal_mutex);
|
G_UNLOCK (g_signal_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
signal_finalize_hook (GHookList *hook_list,
|
||||||
|
GHook *hook)
|
||||||
|
{
|
||||||
|
GDestroyNotify destroy = hook->destroy;
|
||||||
|
|
||||||
|
if (destroy)
|
||||||
|
{
|
||||||
|
hook->destroy = NULL;
|
||||||
|
G_UNLOCK (g_signal_mutex);
|
||||||
|
destroy (hook->data);
|
||||||
|
G_LOCK (g_signal_mutex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
guint
|
||||||
|
g_signal_add_emission_hook (guint signal_id,
|
||||||
|
GQuark detail,
|
||||||
|
GSignalEmissionHook hook_func,
|
||||||
|
gpointer hook_data,
|
||||||
|
GDestroyNotify data_destroy)
|
||||||
|
{
|
||||||
|
static guint seq_hook_id = 1;
|
||||||
|
SignalNode *node;
|
||||||
|
GHook *hook;
|
||||||
|
|
||||||
|
g_return_val_if_fail (signal_id > 0, 0);
|
||||||
|
g_return_val_if_fail (hook_func != NULL, 0);
|
||||||
|
|
||||||
|
G_LOCK (g_signal_mutex);
|
||||||
|
node = LOOKUP_SIGNAL_NODE (signal_id);
|
||||||
|
if (!node || node->destroyed || (node->flags & G_SIGNAL_NO_HOOKS))
|
||||||
|
{
|
||||||
|
g_warning ("%s: invalid signal id `%u'", G_STRLOC, signal_id);
|
||||||
|
G_UNLOCK (g_signal_mutex);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (detail && !(node->flags & G_SIGNAL_DETAILED))
|
||||||
|
{
|
||||||
|
g_warning ("%s: signal id `%u' does not support detail (%u)", G_STRLOC, signal_id, detail);
|
||||||
|
G_UNLOCK (g_signal_mutex);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (!node->emission_hooks)
|
||||||
|
{
|
||||||
|
node->emission_hooks = g_new (GHookList, 1);
|
||||||
|
g_hook_list_init (node->emission_hooks, sizeof (GHook));
|
||||||
|
node->emission_hooks->finalize_hook = signal_finalize_hook;
|
||||||
|
}
|
||||||
|
hook = g_hook_alloc (node->emission_hooks);
|
||||||
|
hook->data = hook_data;
|
||||||
|
hook->func = hook_func;
|
||||||
|
hook->destroy = data_destroy;
|
||||||
|
node->emission_hooks->seq_id = seq_hook_id;
|
||||||
|
g_hook_append (node->emission_hooks, hook);
|
||||||
|
seq_hook_id = node->emission_hooks->seq_id;
|
||||||
|
G_UNLOCK (g_signal_mutex);
|
||||||
|
|
||||||
|
return hook->hook_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
g_signal_remove_emission_hook (guint signal_id,
|
||||||
|
guint hook_id)
|
||||||
|
{
|
||||||
|
SignalNode *node;
|
||||||
|
|
||||||
|
g_return_if_fail (signal_id > 0);
|
||||||
|
g_return_if_fail (hook_id > 0);
|
||||||
|
|
||||||
|
G_LOCK (g_signal_mutex);
|
||||||
|
node = LOOKUP_SIGNAL_NODE (signal_id);
|
||||||
|
if (!node || node->destroyed)
|
||||||
|
g_warning ("%s: invalid signal id `%u'", G_STRLOC, signal_id);
|
||||||
|
else if (!node->emission_hooks || !g_hook_destroy (node->emission_hooks, hook_id))
|
||||||
|
g_warning ("%s: signal \"%s\" had no hook (%u) to remove", G_STRLOC, node->name, hook_id);
|
||||||
|
G_UNLOCK (g_signal_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
static inline guint
|
static inline guint
|
||||||
signal_parse_name (const gchar *name,
|
signal_parse_name (const gchar *name,
|
||||||
GType itype,
|
GType itype,
|
||||||
@ -896,6 +982,7 @@ g_signal_new_valist (const gchar *signal_name,
|
|||||||
GSignalFlags signal_flags,
|
GSignalFlags signal_flags,
|
||||||
GClosure *class_closure,
|
GClosure *class_closure,
|
||||||
GSignalAccumulator accumulator,
|
GSignalAccumulator accumulator,
|
||||||
|
gpointer accu_data,
|
||||||
GSignalCMarshaller c_marshaller,
|
GSignalCMarshaller c_marshaller,
|
||||||
GType return_type,
|
GType return_type,
|
||||||
guint n_params,
|
guint n_params,
|
||||||
@ -916,7 +1003,7 @@ g_signal_new_valist (const gchar *signal_name,
|
|||||||
param_types = NULL;
|
param_types = NULL;
|
||||||
|
|
||||||
signal_id = g_signal_newv (signal_name, itype, signal_flags,
|
signal_id = g_signal_newv (signal_name, itype, signal_flags,
|
||||||
class_closure, accumulator, c_marshaller,
|
class_closure, accumulator, accu_data, c_marshaller,
|
||||||
return_type, n_params, param_types);
|
return_type, n_params, param_types);
|
||||||
g_free (param_types);
|
g_free (param_types);
|
||||||
|
|
||||||
@ -928,7 +1015,8 @@ g_signal_newc (const gchar *signal_name,
|
|||||||
GType itype,
|
GType itype,
|
||||||
GSignalFlags signal_flags,
|
GSignalFlags signal_flags,
|
||||||
guint class_offset,
|
guint class_offset,
|
||||||
GSignalAccumulator accumulator,
|
GSignalAccumulator accumulator,
|
||||||
|
gpointer accu_data,
|
||||||
GSignalCMarshaller c_marshaller,
|
GSignalCMarshaller c_marshaller,
|
||||||
GType return_type,
|
GType return_type,
|
||||||
guint n_params,
|
guint n_params,
|
||||||
@ -943,7 +1031,7 @@ g_signal_newc (const gchar *signal_name,
|
|||||||
|
|
||||||
signal_id = g_signal_new_valist (signal_name, itype, signal_flags,
|
signal_id = g_signal_new_valist (signal_name, itype, signal_flags,
|
||||||
g_signal_type_cclosure_new (itype, class_offset),
|
g_signal_type_cclosure_new (itype, class_offset),
|
||||||
accumulator, c_marshaller,
|
accumulator, accu_data, c_marshaller,
|
||||||
return_type, n_params, args);
|
return_type, n_params, args);
|
||||||
|
|
||||||
va_end (args);
|
va_end (args);
|
||||||
@ -957,6 +1045,7 @@ g_signal_newv (const gchar *signal_name,
|
|||||||
GSignalFlags signal_flags,
|
GSignalFlags signal_flags,
|
||||||
GClosure *class_closure,
|
GClosure *class_closure,
|
||||||
GSignalAccumulator accumulator,
|
GSignalAccumulator accumulator,
|
||||||
|
gpointer accu_data,
|
||||||
GSignalCMarshaller c_marshaller,
|
GSignalCMarshaller c_marshaller,
|
||||||
GType return_type,
|
GType return_type,
|
||||||
guint n_params,
|
guint n_params,
|
||||||
@ -970,8 +1059,10 @@ g_signal_newv (const gchar *signal_name,
|
|||||||
g_return_val_if_fail (G_TYPE_IS_INSTANTIATABLE (itype) || G_TYPE_IS_INTERFACE (itype), 0);
|
g_return_val_if_fail (G_TYPE_IS_INSTANTIATABLE (itype) || G_TYPE_IS_INTERFACE (itype), 0);
|
||||||
if (n_params)
|
if (n_params)
|
||||||
g_return_val_if_fail (param_types != NULL, 0);
|
g_return_val_if_fail (param_types != NULL, 0);
|
||||||
if (return_type != G_TYPE_NONE)
|
if (return_type == (G_TYPE_NONE & ~G_SIGNAL_TYPE_STATIC_SCOPE))
|
||||||
g_return_val_if_fail (accumulator == NULL, 0);
|
g_return_val_if_fail (accumulator == NULL, 0);
|
||||||
|
if (!accumulator)
|
||||||
|
g_return_val_if_fail (accu_data == NULL, 0);
|
||||||
|
|
||||||
name = g_strdup (signal_name);
|
name = g_strdup (signal_name);
|
||||||
g_strdelimit (name, G_STR_DELIMITERS ":^", '_'); // FIXME do character checks like for types
|
g_strdelimit (name, G_STR_DELIMITERS ":^", '_'); // FIXME do character checks like for types
|
||||||
@ -1048,12 +1139,18 @@ g_signal_newv (const gchar *signal_name,
|
|||||||
node->class_closure = class_closure ? g_closure_ref (class_closure) : NULL;
|
node->class_closure = class_closure ? g_closure_ref (class_closure) : NULL;
|
||||||
if (class_closure)
|
if (class_closure)
|
||||||
g_closure_sink (class_closure);
|
g_closure_sink (class_closure);
|
||||||
node->accumulator = accumulator;
|
if (accumulator)
|
||||||
|
{
|
||||||
|
node->accumulator = g_new (SignalAccumulator, 1);
|
||||||
|
node->accumulator->func = accumulator;
|
||||||
|
node->accumulator->data = accu_data;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
node->accumulator = NULL;
|
||||||
node->c_marshaller = c_marshaller;
|
node->c_marshaller = c_marshaller;
|
||||||
node->emission_hooks = NULL;
|
node->emission_hooks = NULL;
|
||||||
if (node->c_marshaller && class_closure && G_CLOSURE_NEEDS_MARSHAL (class_closure))
|
if (node->c_marshaller && class_closure && G_CLOSURE_NEEDS_MARSHAL (class_closure))
|
||||||
g_closure_set_marshal (class_closure, node->c_marshaller);
|
g_closure_set_marshal (class_closure, node->c_marshaller);
|
||||||
|
|
||||||
G_UNLOCK (g_signal_mutex);
|
G_UNLOCK (g_signal_mutex);
|
||||||
return signal_id;
|
return signal_id;
|
||||||
}
|
}
|
||||||
@ -1092,6 +1189,7 @@ signal_destroy_R (SignalNode *signal_node)
|
|||||||
G_UNLOCK (g_signal_mutex);
|
G_UNLOCK (g_signal_mutex);
|
||||||
g_free (node.param_types);
|
g_free (node.param_types);
|
||||||
g_closure_unref (node.class_closure);
|
g_closure_unref (node.class_closure);
|
||||||
|
g_free (node.accumulator);
|
||||||
if (node.emission_hooks)
|
if (node.emission_hooks)
|
||||||
{
|
{
|
||||||
g_hook_list_clear (node.emission_hooks);
|
g_hook_list_clear (node.emission_hooks);
|
||||||
@ -1740,21 +1838,37 @@ g_signal_emit_by_name (gpointer instance,
|
|||||||
g_warning ("%s: signal name `%s' is invalid for instance `%p'", G_STRLOC, detailed_signal, instance);
|
g_warning ("%s: signal name `%s' is invalid for instance `%p'", G_STRLOC, detailed_signal, instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline gboolean
|
||||||
|
accumulate (GSignalInvocationHint *ihint,
|
||||||
|
GValue *return_accu,
|
||||||
|
GValue *handler_return,
|
||||||
|
SignalAccumulator *accumulator)
|
||||||
|
{
|
||||||
|
gboolean continue_emission;
|
||||||
|
|
||||||
|
if (!accumulator)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
continue_emission = accumulator->func (ihint, return_accu, handler_return, accumulator->data);
|
||||||
|
g_value_reset (handler_return);
|
||||||
|
|
||||||
|
return continue_emission;
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
signal_emit_R (SignalNode *node,
|
signal_emit_R (SignalNode *node,
|
||||||
GQuark detail,
|
GQuark detail,
|
||||||
gpointer instance,
|
gpointer instance,
|
||||||
GValue *return_value,
|
GValue *emission_return,
|
||||||
const GValue *instance_and_params)
|
const GValue *instance_and_params)
|
||||||
{
|
{
|
||||||
EmissionState emission_state = 0;
|
EmissionState emission_state = 0;
|
||||||
GSignalAccumulator accumulator;
|
SignalAccumulator *accumulator;
|
||||||
GSignalInvocationHint ihint;
|
GSignalInvocationHint ihint;
|
||||||
GClosure *class_closure;
|
GClosure *class_closure;
|
||||||
HandlerList *hlist;
|
HandlerList *hlist;
|
||||||
Handler *handler_list = NULL;
|
Handler *handler_list = NULL;
|
||||||
GValue accu = { 0, };
|
GValue *return_accu, accu = { 0, };
|
||||||
gboolean accu_used = FALSE;
|
|
||||||
guint signal_id = node->signal_id;
|
guint signal_id = node->signal_id;
|
||||||
gboolean return_value_altered = FALSE;
|
gboolean return_value_altered = FALSE;
|
||||||
|
|
||||||
@ -1784,7 +1898,12 @@ signal_emit_R (SignalNode *node,
|
|||||||
ihint.detail = detail;
|
ihint.detail = detail;
|
||||||
accumulator = node->accumulator;
|
accumulator = node->accumulator;
|
||||||
if (accumulator)
|
if (accumulator)
|
||||||
g_value_init (&accu, node->return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE);
|
{
|
||||||
|
g_value_init (&accu, node->return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE);
|
||||||
|
return_accu = &accu;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return_accu = emission_return;
|
||||||
emission_push ((node->flags & G_SIGNAL_NO_RECURSE) ? &g_restart_emissions : &g_recursive_emissions,
|
emission_push ((node->flags & G_SIGNAL_NO_RECURSE) ? &g_restart_emissions : &g_recursive_emissions,
|
||||||
signal_id, detail, instance, &emission_state);
|
signal_id, detail, instance, &emission_state);
|
||||||
class_closure = node->class_closure;
|
class_closure = node->class_closure;
|
||||||
@ -1805,26 +1924,14 @@ signal_emit_R (SignalNode *node,
|
|||||||
emission_state = EMISSION_RUN;
|
emission_state = EMISSION_RUN;
|
||||||
|
|
||||||
G_UNLOCK (g_signal_mutex);
|
G_UNLOCK (g_signal_mutex);
|
||||||
if (accumulator)
|
g_closure_invoke (class_closure,
|
||||||
{
|
return_accu,
|
||||||
if (accu_used)
|
node->n_params + 1,
|
||||||
g_value_reset (&accu);
|
instance_and_params,
|
||||||
g_closure_invoke (class_closure,
|
&ihint);
|
||||||
&accu,
|
if (!accumulate (&ihint, emission_return, &accu, accumulator) &&
|
||||||
node->n_params + 1,
|
emission_state == EMISSION_RUN)
|
||||||
instance_and_params,
|
emission_state = EMISSION_STOP;
|
||||||
&ihint);
|
|
||||||
if (!accumulator (&ihint, return_value, &accu) &&
|
|
||||||
emission_state == EMISSION_RUN)
|
|
||||||
emission_state = EMISSION_STOP;
|
|
||||||
accu_used = TRUE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
g_closure_invoke (class_closure,
|
|
||||||
return_value,
|
|
||||||
node->n_params + 1,
|
|
||||||
instance_and_params,
|
|
||||||
&ihint);
|
|
||||||
G_LOCK (g_signal_mutex);
|
G_LOCK (g_signal_mutex);
|
||||||
return_value_altered = TRUE;
|
return_value_altered = TRUE;
|
||||||
|
|
||||||
@ -1836,11 +1943,31 @@ signal_emit_R (SignalNode *node,
|
|||||||
|
|
||||||
if (node->emission_hooks)
|
if (node->emission_hooks)
|
||||||
{
|
{
|
||||||
emission_state = EMISSION_HOOK;
|
gboolean need_destroy, was_in_call, may_recurse = TRUE;
|
||||||
|
GHook *hook;
|
||||||
|
|
||||||
G_UNLOCK (g_signal_mutex);
|
emission_state = EMISSION_HOOK;
|
||||||
g_print ("emission_hooks()\n");
|
hook = g_hook_first_valid (node->emission_hooks, may_recurse);
|
||||||
G_LOCK (g_signal_mutex);
|
while (hook)
|
||||||
|
{
|
||||||
|
GQuark hook_detail = GPOINTER_TO_UINT (hook->func);
|
||||||
|
|
||||||
|
if (!hook_detail || hook_detail == detail)
|
||||||
|
{
|
||||||
|
GSignalEmissionHook hook_func = hook->func;
|
||||||
|
|
||||||
|
was_in_call = G_HOOK_IN_CALL (hook);
|
||||||
|
hook->flags |= G_HOOK_FLAG_IN_CALL;
|
||||||
|
G_UNLOCK (g_signal_mutex);
|
||||||
|
need_destroy = !hook_func (&ihint, node->n_params + 1, instance_and_params, hook->data);
|
||||||
|
G_LOCK (g_signal_mutex);
|
||||||
|
if (!was_in_call)
|
||||||
|
hook->flags &= ~G_HOOK_FLAG_IN_CALL;
|
||||||
|
if (need_destroy)
|
||||||
|
g_hook_destroy_link (node->emission_hooks, hook);
|
||||||
|
}
|
||||||
|
hook = g_hook_next_valid (node->emission_hooks, hook, may_recurse);
|
||||||
|
}
|
||||||
|
|
||||||
if (emission_state == EMISSION_RESTART)
|
if (emission_state == EMISSION_RESTART)
|
||||||
goto EMIT_RESTART;
|
goto EMIT_RESTART;
|
||||||
@ -1865,26 +1992,14 @@ signal_emit_R (SignalNode *node,
|
|||||||
else if (!handler->block_count && (!handler->detail || handler->detail == detail))
|
else if (!handler->block_count && (!handler->detail || handler->detail == detail))
|
||||||
{
|
{
|
||||||
G_UNLOCK (g_signal_mutex);
|
G_UNLOCK (g_signal_mutex);
|
||||||
if (accumulator)
|
g_closure_invoke (handler->closure,
|
||||||
{
|
return_accu,
|
||||||
if (accu_used)
|
node->n_params + 1,
|
||||||
g_value_reset (&accu);
|
instance_and_params,
|
||||||
g_closure_invoke (handler->closure,
|
&ihint);
|
||||||
&accu,
|
if (!accumulate (&ihint, emission_return, &accu, accumulator) &&
|
||||||
node->n_params + 1,
|
emission_state == EMISSION_RUN)
|
||||||
instance_and_params,
|
emission_state = EMISSION_STOP;
|
||||||
&ihint);
|
|
||||||
if (!accumulator (&ihint, return_value, &accu) &&
|
|
||||||
emission_state == EMISSION_RUN)
|
|
||||||
emission_state = EMISSION_STOP;
|
|
||||||
accu_used = TRUE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
g_closure_invoke (handler->closure,
|
|
||||||
return_value,
|
|
||||||
node->n_params + 1,
|
|
||||||
instance_and_params,
|
|
||||||
&ihint);
|
|
||||||
G_LOCK (g_signal_mutex);
|
G_LOCK (g_signal_mutex);
|
||||||
return_value_altered = TRUE;
|
return_value_altered = TRUE;
|
||||||
|
|
||||||
@ -1914,26 +2029,14 @@ signal_emit_R (SignalNode *node,
|
|||||||
emission_state = EMISSION_RUN;
|
emission_state = EMISSION_RUN;
|
||||||
|
|
||||||
G_UNLOCK (g_signal_mutex);
|
G_UNLOCK (g_signal_mutex);
|
||||||
if (accumulator)
|
g_closure_invoke (class_closure,
|
||||||
{
|
return_accu,
|
||||||
if (accu_used)
|
node->n_params + 1,
|
||||||
g_value_reset (&accu);
|
instance_and_params,
|
||||||
g_closure_invoke (class_closure,
|
&ihint);
|
||||||
&accu,
|
if (!accumulate (&ihint, emission_return, &accu, accumulator) &&
|
||||||
node->n_params + 1,
|
emission_state == EMISSION_RUN)
|
||||||
instance_and_params,
|
emission_state = EMISSION_STOP;
|
||||||
&ihint);
|
|
||||||
if (!accumulator (&ihint, return_value, &accu) &&
|
|
||||||
emission_state == EMISSION_RUN)
|
|
||||||
emission_state = EMISSION_STOP;
|
|
||||||
accu_used = TRUE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
g_closure_invoke (class_closure,
|
|
||||||
return_value,
|
|
||||||
node->n_params + 1,
|
|
||||||
instance_and_params,
|
|
||||||
&ihint);
|
|
||||||
G_LOCK (g_signal_mutex);
|
G_LOCK (g_signal_mutex);
|
||||||
return_value_altered = TRUE;
|
return_value_altered = TRUE;
|
||||||
|
|
||||||
@ -1956,26 +2059,14 @@ signal_emit_R (SignalNode *node,
|
|||||||
if (handler->after && !handler->block_count && (!handler->detail || handler->detail == detail))
|
if (handler->after && !handler->block_count && (!handler->detail || handler->detail == detail))
|
||||||
{
|
{
|
||||||
G_UNLOCK (g_signal_mutex);
|
G_UNLOCK (g_signal_mutex);
|
||||||
if (accumulator)
|
g_closure_invoke (handler->closure,
|
||||||
{
|
return_accu,
|
||||||
if (accu_used)
|
node->n_params + 1,
|
||||||
g_value_reset (&accu);
|
instance_and_params,
|
||||||
g_closure_invoke (handler->closure,
|
&ihint);
|
||||||
&accu,
|
if (!accumulate (&ihint, emission_return, &accu, accumulator) &&
|
||||||
node->n_params + 1,
|
emission_state == EMISSION_RUN)
|
||||||
instance_and_params,
|
emission_state = EMISSION_STOP;
|
||||||
&ihint);
|
|
||||||
if (!accumulator (&ihint, return_value, &accu) &&
|
|
||||||
emission_state == EMISSION_RUN)
|
|
||||||
emission_state = EMISSION_STOP;
|
|
||||||
accu_used = TRUE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
g_closure_invoke (handler->closure,
|
|
||||||
return_value,
|
|
||||||
node->n_params + 1,
|
|
||||||
instance_and_params,
|
|
||||||
&ihint);
|
|
||||||
G_LOCK (g_signal_mutex);
|
G_LOCK (g_signal_mutex);
|
||||||
return_value_altered = TRUE;
|
return_value_altered = TRUE;
|
||||||
|
|
||||||
@ -2008,15 +2099,10 @@ signal_emit_R (SignalNode *node,
|
|||||||
emission_state = EMISSION_STOP;
|
emission_state = EMISSION_STOP;
|
||||||
|
|
||||||
G_UNLOCK (g_signal_mutex);
|
G_UNLOCK (g_signal_mutex);
|
||||||
if (node->return_type != G_TYPE_NONE)
|
if (node->return_type != G_TYPE_NONE && !accumulator)
|
||||||
{
|
{
|
||||||
if (!accumulator)
|
g_value_init (&accu, node->return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE);
|
||||||
{
|
need_unset = TRUE;
|
||||||
g_value_init (&accu, node->return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE);
|
|
||||||
need_unset = TRUE;
|
|
||||||
}
|
|
||||||
else if (accu_used)
|
|
||||||
g_value_reset (&accu);
|
|
||||||
}
|
}
|
||||||
g_closure_invoke (class_closure,
|
g_closure_invoke (class_closure,
|
||||||
node->return_type != G_TYPE_NONE ? &accu : NULL,
|
node->return_type != G_TYPE_NONE ? &accu : NULL,
|
||||||
@ -2043,8 +2129,6 @@ signal_emit_R (SignalNode *node,
|
|||||||
|
|
||||||
|
|
||||||
/* --- compile standard marshallers --- */
|
/* --- compile standard marshallers --- */
|
||||||
#include "gvaluetypes.h"
|
|
||||||
#include "gobject.h"
|
#include "gobject.h"
|
||||||
#include "genums.h"
|
#include "genums.h"
|
||||||
#include "gboxed.h"
|
|
||||||
#include "gmarshal.c"
|
#include "gmarshal.c"
|
||||||
|
@ -37,10 +37,12 @@ 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,
|
||||||
|
gpointer data);
|
||||||
typedef gboolean (*GSignalAccumulator) (GSignalInvocationHint *ihint,
|
typedef gboolean (*GSignalAccumulator) (GSignalInvocationHint *ihint,
|
||||||
GValue *return_accu,
|
GValue *return_accu,
|
||||||
const GValue *return_value);
|
const GValue *handler_return,
|
||||||
|
gpointer data);
|
||||||
|
|
||||||
|
|
||||||
/* --- run & match types --- */
|
/* --- run & match types --- */
|
||||||
@ -92,7 +94,8 @@ 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,
|
||||||
|
gpointer accu_data,
|
||||||
GSignalCMarshaller c_marshaller,
|
GSignalCMarshaller c_marshaller,
|
||||||
GType return_type,
|
GType return_type,
|
||||||
guint n_params,
|
guint n_params,
|
||||||
@ -101,7 +104,8 @@ guint g_signal_new_valist (const gchar *signal_name,
|
|||||||
GType itype,
|
GType itype,
|
||||||
GSignalFlags signal_flags,
|
GSignalFlags signal_flags,
|
||||||
GClosure *class_closure,
|
GClosure *class_closure,
|
||||||
GSignalAccumulator accumulator,
|
GSignalAccumulator accumulator,
|
||||||
|
gpointer accu_data,
|
||||||
GSignalCMarshaller c_marshaller,
|
GSignalCMarshaller c_marshaller,
|
||||||
GType return_type,
|
GType return_type,
|
||||||
guint n_params,
|
guint n_params,
|
||||||
@ -110,7 +114,8 @@ guint g_signal_newc (const gchar *signal_name,
|
|||||||
GType itype,
|
GType itype,
|
||||||
GSignalFlags signal_flags,
|
GSignalFlags signal_flags,
|
||||||
guint class_offset,
|
guint class_offset,
|
||||||
GSignalAccumulator accumulator,
|
GSignalAccumulator accumulator,
|
||||||
|
gpointer accu_data,
|
||||||
GSignalCMarshaller c_marshaller,
|
GSignalCMarshaller c_marshaller,
|
||||||
GType return_type,
|
GType return_type,
|
||||||
guint n_params,
|
guint n_params,
|
||||||
@ -137,16 +142,24 @@ 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);
|
||||||
|
gboolean g_signal_parse_name (const gchar *detailed_signal,
|
||||||
|
GType itype,
|
||||||
|
guint *signal_id_p,
|
||||||
|
GQuark *detail_p,
|
||||||
|
gboolean force_detail_quark);
|
||||||
|
|
||||||
|
|
||||||
/* --- 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 (guint signal_id,
|
||||||
GClosure *closure);
|
GQuark quark,
|
||||||
void g_signal_remove_emission_hook (guint signal_id,
|
GSignalEmissionHook hook_func,
|
||||||
guint hook_id);
|
gpointer hook_data,
|
||||||
|
GDestroyNotify data_destroy);
|
||||||
|
void g_signal_remove_emission_hook (guint signal_id,
|
||||||
|
guint hook_id);
|
||||||
|
|
||||||
|
|
||||||
/* --- signal handlers --- */
|
/* --- signal handlers --- */
|
||||||
@ -154,8 +167,6 @@ gboolean 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);
|
||||||
#define g_signal_connect(instance, detailed_signal, c_handler, data) \
|
|
||||||
g_signal_connect_data (instance, detailed_signal, c_handler, data, NULL, FALSE, FALSE)
|
|
||||||
guint g_signal_connect_closure_by_id (gpointer instance,
|
guint g_signal_connect_closure_by_id (gpointer instance,
|
||||||
guint signal_id,
|
guint signal_id,
|
||||||
GQuark detail,
|
GQuark detail,
|
||||||
@ -206,13 +217,12 @@ guint g_signal_handlers_disconnect_matched (gpointer instance,
|
|||||||
GClosure *closure,
|
GClosure *closure,
|
||||||
gpointer func,
|
gpointer func,
|
||||||
gpointer data);
|
gpointer data);
|
||||||
gboolean g_signal_parse_name (const gchar *detailed_signal,
|
|
||||||
GType itype,
|
|
||||||
guint *signal_id_p,
|
|
||||||
GQuark *detail_p,
|
|
||||||
gboolean force_detail_quark);
|
|
||||||
|
|
||||||
|
|
||||||
|
/* --- convenience --- */
|
||||||
|
#define g_signal_connectc(instance, detailed_signal, c_handler, data, swapped) \
|
||||||
|
g_signal_connect_data ((instance), (detailed_signal), (c_handler), (data), NULL, (swapped), FALSE)
|
||||||
|
|
||||||
/*< 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);
|
||||||
|
@ -73,7 +73,8 @@ typedef enum /*< skip >*/
|
|||||||
|
|
||||||
/* derived type ids */
|
/* derived type ids */
|
||||||
G_TYPE_CLOSURE = G_TYPE_DERIVE_ID (G_TYPE_BOXED, 1),
|
G_TYPE_CLOSURE = G_TYPE_DERIVE_ID (G_TYPE_BOXED, 1),
|
||||||
G_TYPE_VALUE_ARRAY = G_TYPE_DERIVE_ID (G_TYPE_BOXED, 2),
|
G_TYPE_VALUE = G_TYPE_DERIVE_ID (G_TYPE_BOXED, 2),
|
||||||
|
G_TYPE_VALUE_ARRAY = G_TYPE_DERIVE_ID (G_TYPE_BOXED, 3),
|
||||||
G_TYPE_PARAM_CHAR = G_TYPE_DERIVE_ID (G_TYPE_PARAM, 1),
|
G_TYPE_PARAM_CHAR = G_TYPE_DERIVE_ID (G_TYPE_PARAM, 1),
|
||||||
G_TYPE_PARAM_UCHAR = G_TYPE_DERIVE_ID (G_TYPE_PARAM, 2),
|
G_TYPE_PARAM_UCHAR = G_TYPE_DERIVE_ID (G_TYPE_PARAM, 2),
|
||||||
G_TYPE_PARAM_BOOLEAN = G_TYPE_DERIVE_ID (G_TYPE_PARAM, 3),
|
G_TYPE_PARAM_BOOLEAN = G_TYPE_DERIVE_ID (G_TYPE_PARAM, 3),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user