mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-12-25 15:06:14 +01:00
publically define GSignalInvocationHint structure that gets passed in to
Fri Oct 27 16:33:41 2000 Tim Janik <timj@gtk.org> * gsignal.[hc]: publically define GSignalInvocationHint structure that gets passed in to closure invocations. added signal details. renamed GSignalType to GSignalFlags to comply with conventions. quite some cleanups and minor fixes. avoid uneccessary handler list walks upon invokation of after handlers. relookup handler list for restarted emissions. preliminary abort normal handler invokation if after handler is encountered. * glib-genmarshal.c: * gclosure.[hc]: moved invocation_hint to the end of the g_closure_invoke() arguments as sugegsted by kenelson. also made it a gpointer to be more generic. the invocation_hint is a caller specific thing that can be used to pass additional data in to closure invocations as documented with the caller invoking the closure.
This commit is contained in:
parent
e6dfecacc0
commit
830d808c5c
@ -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>.
|
||||||
|
|
||||||
|
@ -141,17 +141,6 @@ path it returns NULL.
|
|||||||
@Returns: a pointer into @file_name after the root component.
|
@Returns: a pointer into @file_name after the root component.
|
||||||
|
|
||||||
|
|
||||||
<!-- ##### FUNCTION g_path_get_dirname ##### -->
|
|
||||||
<para>
|
|
||||||
Gets the directory components of a file name. If the file name has no
|
|
||||||
directory components "." is returned. The returned string should be
|
|
||||||
freed when no longer needed.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
@file_name: the name of the file.
|
|
||||||
@Returns: the directory components of the file.
|
|
||||||
|
|
||||||
|
|
||||||
<!-- ##### FUNCTION g_path_get_basename ##### -->
|
<!-- ##### FUNCTION g_path_get_basename ##### -->
|
||||||
<para>
|
<para>
|
||||||
Gets the name of the file without any leading directory components.
|
Gets the name of the file without any leading directory components.
|
||||||
@ -170,6 +159,17 @@ into the argument.
|
|||||||
@Returns: the name of the file without any leading directory components.
|
@Returns: the name of the file without any leading directory components.
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ##### FUNCTION g_path_get_dirname ##### -->
|
||||||
|
<para>
|
||||||
|
Gets the directory components of a file name. If the file name has no
|
||||||
|
directory components "." is returned. The returned string should be
|
||||||
|
freed when no longer needed.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
@file_name: the name of the file.
|
||||||
|
@Returns: the directory components of the file.
|
||||||
|
|
||||||
|
|
||||||
<!-- ##### FUNCTION g_filename_to_utf8 ##### -->
|
<!-- ##### FUNCTION g_filename_to_utf8 ##### -->
|
||||||
<para>
|
<para>
|
||||||
|
|
||||||
|
@ -1,3 +1,21 @@
|
|||||||
|
Fri Oct 27 16:33:41 2000 Tim Janik <timj@gtk.org>
|
||||||
|
|
||||||
|
* gsignal.[hc]: publically define GSignalInvocationHint structure
|
||||||
|
that gets passed in to closure invocations. added signal details.
|
||||||
|
renamed GSignalType to GSignalFlags to comply with conventions.
|
||||||
|
quite some cleanups and minor fixes. avoid uneccessary handler list
|
||||||
|
walks upon invokation of after handlers. relookup handler list for
|
||||||
|
restarted emissions. preliminary abort normal handler invokation if
|
||||||
|
after handler is encountered.
|
||||||
|
|
||||||
|
* glib-genmarshal.c:
|
||||||
|
* gclosure.[hc]: moved invocation_hint to the end of the
|
||||||
|
g_closure_invoke() arguments as sugegsted by kenelson.
|
||||||
|
also made it a gpointer to be more generic. the invocation_hint
|
||||||
|
is a caller specific thing that can be used to pass additional
|
||||||
|
data in to closure invocations as documented with the caller
|
||||||
|
invoking the closure.
|
||||||
|
|
||||||
Fri Oct 27 05:35:14 2000 Tim Janik <timj@gtk.org>
|
Fri Oct 27 05:35:14 2000 Tim Janik <timj@gtk.org>
|
||||||
|
|
||||||
* gobject.c (g_object_watch_closure): fixed realloc bug, reported
|
* gobject.c (g_object_watch_closure): fixed realloc bug, reported
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#include "gclosure.h"
|
#include "gclosure.h"
|
||||||
|
|
||||||
#include "gvalue.h"
|
#include "gvalue.h"
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
|
||||||
/* FIXME: need caching allocators
|
/* FIXME: need caching allocators
|
||||||
@ -387,10 +388,10 @@ g_closure_remove_fnotify (GClosure *closure,
|
|||||||
|
|
||||||
void
|
void
|
||||||
g_closure_invoke (GClosure *closure,
|
g_closure_invoke (GClosure *closure,
|
||||||
guint invocation_hint,
|
|
||||||
GValue /*out*/ *return_value,
|
GValue /*out*/ *return_value,
|
||||||
guint n_param_values,
|
guint n_param_values,
|
||||||
const GValue *param_values)
|
const GValue *param_values,
|
||||||
|
gpointer invocation_hint)
|
||||||
{
|
{
|
||||||
g_return_if_fail (closure != NULL);
|
g_return_if_fail (closure != NULL);
|
||||||
g_return_if_fail (closure->marshal || closure->meta_marshal);
|
g_return_if_fail (closure->marshal || closure->meta_marshal);
|
||||||
@ -415,9 +416,10 @@ g_closure_invoke (GClosure *closure,
|
|||||||
}
|
}
|
||||||
if (!in_marshal)
|
if (!in_marshal)
|
||||||
closure_invoke_notifiers (closure, PRE_NOTIFY);
|
closure_invoke_notifiers (closure, PRE_NOTIFY);
|
||||||
marshal (closure, invocation_hint,
|
marshal (closure,
|
||||||
return_value,
|
return_value,
|
||||||
n_param_values, param_values,
|
n_param_values, param_values,
|
||||||
|
invocation_hint,
|
||||||
marshal_data);
|
marshal_data);
|
||||||
if (!in_marshal)
|
if (!in_marshal)
|
||||||
closure_invoke_notifiers (closure, POST_NOTIFY);
|
closure_invoke_notifiers (closure, POST_NOTIFY);
|
||||||
@ -477,10 +479,10 @@ g_cclosure_new_swap (GCallback callback_func,
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
g_type_class_meta_marshal (GClosure *closure,
|
g_type_class_meta_marshal (GClosure *closure,
|
||||||
guint invocation_hint,
|
|
||||||
GValue /*out*/ *return_value,
|
GValue /*out*/ *return_value,
|
||||||
guint n_param_values,
|
guint n_param_values,
|
||||||
const GValue *param_values,
|
const GValue *param_values,
|
||||||
|
gpointer invocation_hint,
|
||||||
gpointer marshal_data)
|
gpointer marshal_data)
|
||||||
{
|
{
|
||||||
GTypeClass *class;
|
GTypeClass *class;
|
||||||
@ -491,16 +493,19 @@ g_type_class_meta_marshal (GClosure *closure,
|
|||||||
class = G_TYPE_INSTANCE_GET_CLASS (g_value_get_as_pointer (param_values + 0), itype, GTypeClass);
|
class = G_TYPE_INSTANCE_GET_CLASS (g_value_get_as_pointer (param_values + 0), itype, GTypeClass);
|
||||||
callback = G_STRUCT_MEMBER (gpointer, class, offset);
|
callback = G_STRUCT_MEMBER (gpointer, class, offset);
|
||||||
if (callback)
|
if (callback)
|
||||||
closure->marshal (closure, invocation_hint, return_value,
|
closure->marshal (closure,
|
||||||
n_param_values, param_values, callback);
|
return_value,
|
||||||
|
n_param_values, param_values,
|
||||||
|
invocation_hint,
|
||||||
|
callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
g_type_iface_meta_marshal (GClosure *closure,
|
g_type_iface_meta_marshal (GClosure *closure,
|
||||||
guint invocation_hint,
|
|
||||||
GValue /*out*/ *return_value,
|
GValue /*out*/ *return_value,
|
||||||
guint n_param_values,
|
guint n_param_values,
|
||||||
const GValue *param_values,
|
const GValue *param_values,
|
||||||
|
gpointer invocation_hint,
|
||||||
gpointer marshal_data)
|
gpointer marshal_data)
|
||||||
{
|
{
|
||||||
GTypeClass *class;
|
GTypeClass *class;
|
||||||
@ -511,8 +516,11 @@ g_type_iface_meta_marshal (GClosure *closure,
|
|||||||
class = G_TYPE_INSTANCE_GET_INTERFACE (g_value_get_as_pointer (param_values + 0), itype, GTypeClass);
|
class = G_TYPE_INSTANCE_GET_INTERFACE (g_value_get_as_pointer (param_values + 0), itype, GTypeClass);
|
||||||
callback = G_STRUCT_MEMBER (gpointer, class, offset);
|
callback = G_STRUCT_MEMBER (gpointer, class, offset);
|
||||||
if (callback)
|
if (callback)
|
||||||
closure->marshal (closure, invocation_hint, return_value,
|
closure->marshal (closure,
|
||||||
n_param_values, param_values, callback);
|
return_value,
|
||||||
|
n_param_values, param_values,
|
||||||
|
invocation_hint,
|
||||||
|
callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
GClosure*
|
GClosure*
|
||||||
|
@ -41,10 +41,10 @@ typedef gpointer GCallback;
|
|||||||
typedef void (*GClosureNotify) (gpointer data,
|
typedef void (*GClosureNotify) (gpointer data,
|
||||||
GClosure *closure);
|
GClosure *closure);
|
||||||
typedef void (*GClosureMarshal) (GClosure *closure,
|
typedef void (*GClosureMarshal) (GClosure *closure,
|
||||||
guint invocation_hint,
|
|
||||||
GValue *return_value,
|
GValue *return_value,
|
||||||
guint n_param_values,
|
guint n_param_values,
|
||||||
const GValue *param_values,
|
const GValue *param_values,
|
||||||
|
gpointer invocation_hint,
|
||||||
gpointer marshal_data);
|
gpointer marshal_data);
|
||||||
typedef struct _GCClosure GCClosure;
|
typedef struct _GCClosure GCClosure;
|
||||||
|
|
||||||
@ -69,10 +69,10 @@ struct _GClosure
|
|||||||
/*< public >*/ guint is_invalid : 1;
|
/*< public >*/ guint is_invalid : 1;
|
||||||
|
|
||||||
/*< private >*/ void (*marshal) (GClosure *closure,
|
/*< private >*/ void (*marshal) (GClosure *closure,
|
||||||
guint invocation_hint,
|
|
||||||
GValue /*out*/ *return_value,
|
GValue /*out*/ *return_value,
|
||||||
guint n_param_values,
|
guint n_param_values,
|
||||||
const GValue *param_values,
|
const GValue *param_values,
|
||||||
|
gpointer invocation_hint,
|
||||||
gpointer marshal_data);
|
gpointer marshal_data);
|
||||||
/*< protected >*/ gpointer data;
|
/*< protected >*/ gpointer data;
|
||||||
|
|
||||||
@ -139,10 +139,10 @@ void g_closure_set_meta_marshal (GClosure *closure,
|
|||||||
GClosureMarshal meta_marshal);
|
GClosureMarshal meta_marshal);
|
||||||
void g_closure_invalidate (GClosure *closure);
|
void g_closure_invalidate (GClosure *closure);
|
||||||
void g_closure_invoke (GClosure *closure,
|
void g_closure_invoke (GClosure *closure,
|
||||||
guint invocation_hint,
|
|
||||||
GValue /*out*/ *return_value,
|
GValue /*out*/ *return_value,
|
||||||
guint n_param_values,
|
guint n_param_values,
|
||||||
const GValue *param_values);
|
const GValue *param_values,
|
||||||
|
gpointer invocation_hint);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -248,10 +248,10 @@ generate_marshal (const gchar *signame,
|
|||||||
ind = fprintf (fout, "extern void ");
|
ind = fprintf (fout, "extern void ");
|
||||||
ind += fprintf (fout, "%s_%s (", marshaller_prefix, signame);
|
ind += fprintf (fout, "%s_%s (", marshaller_prefix, signame);
|
||||||
fprintf (fout, "GClosure *closure,\n");
|
fprintf (fout, "GClosure *closure,\n");
|
||||||
fprintf (fout, "%sguint invocation_hint,\n", indent (ind));
|
|
||||||
fprintf (fout, "%sGValue *return_value,\n", indent (ind));
|
fprintf (fout, "%sGValue *return_value,\n", indent (ind));
|
||||||
fprintf (fout, "%sguint n_param_values,\n", indent (ind));
|
fprintf (fout, "%sguint n_param_values,\n", indent (ind));
|
||||||
fprintf (fout, "%sconst GValue *param_values,\n", indent (ind));
|
fprintf (fout, "%sconst GValue *param_values,\n", indent (ind));
|
||||||
|
fprintf (fout, "%sgpointer invocation_hint,\n", indent (ind));
|
||||||
fprintf (fout, "%sgpointer marshal_data);\n", indent (ind));
|
fprintf (fout, "%sgpointer marshal_data);\n", indent (ind));
|
||||||
}
|
}
|
||||||
if (gen_cbody)
|
if (gen_cbody)
|
||||||
@ -260,10 +260,10 @@ generate_marshal (const gchar *signame,
|
|||||||
fprintf (fout, "void\n");
|
fprintf (fout, "void\n");
|
||||||
ind = fprintf (fout, "%s_%s (", marshaller_prefix, signame);
|
ind = fprintf (fout, "%s_%s (", marshaller_prefix, signame);
|
||||||
fprintf (fout, "GClosure *closure,\n");
|
fprintf (fout, "GClosure *closure,\n");
|
||||||
fprintf (fout, "%sguint invocation_hint,\n", indent (ind));
|
|
||||||
fprintf (fout, "%sGValue *return_value,\n", indent (ind));
|
fprintf (fout, "%sGValue *return_value,\n", indent (ind));
|
||||||
fprintf (fout, "%sguint n_param_values,\n", indent (ind));
|
fprintf (fout, "%sguint n_param_values,\n", indent (ind));
|
||||||
fprintf (fout, "%sconst GValue *param_values,\n", indent (ind));
|
fprintf (fout, "%sconst GValue *param_values,\n", indent (ind));
|
||||||
|
fprintf (fout, "%sgpointer invocation_hint,\n", indent (ind));
|
||||||
fprintf (fout, "%sgpointer marshal_data)\n", indent (ind));
|
fprintf (fout, "%sgpointer marshal_data)\n", indent (ind));
|
||||||
fprintf (fout, "{\n");
|
fprintf (fout, "{\n");
|
||||||
|
|
||||||
|
@ -103,6 +103,7 @@ static Handler* handler_lookup (gpointer instance
|
|||||||
static Handler* handler_find (gpointer instance,
|
static Handler* handler_find (gpointer instance,
|
||||||
GSignalMatchType mask,
|
GSignalMatchType mask,
|
||||||
guint signal_id,
|
guint signal_id,
|
||||||
|
GQuark detail,
|
||||||
GClosure *closure,
|
GClosure *closure,
|
||||||
gpointer func,
|
gpointer func,
|
||||||
gpointer data);
|
gpointer data);
|
||||||
@ -112,13 +113,17 @@ static inline void handler_unref_R (guint signal_i
|
|||||||
Handler *handler);
|
Handler *handler);
|
||||||
static inline void emission_push (Emission **emission_list_p,
|
static inline void emission_push (Emission **emission_list_p,
|
||||||
guint signal_id,
|
guint signal_id,
|
||||||
|
GQuark detail,
|
||||||
gpointer instance,
|
gpointer instance,
|
||||||
EmissionState *state_p);
|
EmissionState *state_p);
|
||||||
static inline void emission_pop (Emission **emission_list_p);
|
static inline void emission_pop (Emission **emission_list_p,
|
||||||
|
EmissionState *state_p);
|
||||||
static inline Emission* emission_find (Emission *emission_list,
|
static inline Emission* emission_find (Emission *emission_list,
|
||||||
guint signal_id,
|
guint signal_id,
|
||||||
|
GQuark detail,
|
||||||
gpointer instance);
|
gpointer instance);
|
||||||
static void signal_emit_R (SignalNode *node,
|
static void signal_emit_R (SignalNode *node,
|
||||||
|
GQuark detail,
|
||||||
gpointer instance,
|
gpointer instance,
|
||||||
GValue *return_value,
|
GValue *return_value,
|
||||||
const GValue *instance_and_params);
|
const GValue *instance_and_params);
|
||||||
@ -155,6 +160,7 @@ struct _Emission
|
|||||||
{
|
{
|
||||||
Emission *next;
|
Emission *next;
|
||||||
guint signal_id;
|
guint signal_id;
|
||||||
|
GQuark detail;
|
||||||
gpointer instance;
|
gpointer instance;
|
||||||
EmissionState *state_p;
|
EmissionState *state_p;
|
||||||
};
|
};
|
||||||
@ -170,6 +176,7 @@ struct _Handler
|
|||||||
guint id;
|
guint id;
|
||||||
Handler *next;
|
Handler *next;
|
||||||
Handler *prev;
|
Handler *prev;
|
||||||
|
GQuark detail;
|
||||||
guint ref_count : 16;
|
guint ref_count : 16;
|
||||||
#define HANDLER_MAX_REF_COUNT (1 << 16)
|
#define HANDLER_MAX_REF_COUNT (1 << 16)
|
||||||
guint block_count : 12;
|
guint block_count : 12;
|
||||||
@ -308,6 +315,7 @@ static Handler*
|
|||||||
handler_find (gpointer instance,
|
handler_find (gpointer instance,
|
||||||
GSignalMatchType mask,
|
GSignalMatchType mask,
|
||||||
guint signal_id,
|
guint signal_id,
|
||||||
|
GQuark detail,
|
||||||
GClosure *closure,
|
GClosure *closure,
|
||||||
gpointer func,
|
gpointer func,
|
||||||
gpointer data)
|
gpointer data)
|
||||||
@ -327,9 +335,10 @@ handler_find (gpointer instance,
|
|||||||
|
|
||||||
mask = ~mask;
|
mask = ~mask;
|
||||||
for (handler = hlist ? hlist->handlers : NULL; handler; handler = handler->next)
|
for (handler = hlist ? hlist->handlers : NULL; handler; handler = handler->next)
|
||||||
if (((mask & G_SIGNAL_MATCH_CLOSURE) || handler->closure == closure) &&
|
if (((mask & G_SIGNAL_MATCH_DETAIL) || handler->detail == detail) &&
|
||||||
((mask & G_SIGNAL_MATCH_UNBLOCKED) || handler->block_count == 0) &&
|
((mask & G_SIGNAL_MATCH_CLOSURE) || handler->closure == closure) &&
|
||||||
((mask & G_SIGNAL_MATCH_DATA) || handler->closure->data == data) &&
|
((mask & G_SIGNAL_MATCH_DATA) || handler->closure->data == data) &&
|
||||||
|
((mask & G_SIGNAL_MATCH_UNBLOCKED) || handler->block_count == 0) &&
|
||||||
((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)))
|
||||||
@ -358,9 +367,10 @@ handler_find (gpointer instance,
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (handler = hlist->handlers; handler; handler = handler->next)
|
for (handler = hlist->handlers; handler; handler = handler->next)
|
||||||
if (((mask & G_SIGNAL_MATCH_CLOSURE) || handler->closure == closure) &&
|
if (((mask & G_SIGNAL_MATCH_DETAIL) || handler->detail == detail) &&
|
||||||
((mask & G_SIGNAL_MATCH_UNBLOCKED) || handler->block_count == 0) &&
|
((mask & G_SIGNAL_MATCH_CLOSURE) || handler->closure == closure) &&
|
||||||
((mask & G_SIGNAL_MATCH_DATA) || handler->closure->data == data) &&
|
((mask & G_SIGNAL_MATCH_DATA) || handler->closure->data == data) &&
|
||||||
|
((mask & G_SIGNAL_MATCH_UNBLOCKED) || handler->block_count == 0) &&
|
||||||
((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)))
|
||||||
@ -387,6 +397,7 @@ handler_new (gboolean after)
|
|||||||
handler->id = handler_id++;
|
handler->id = handler_id++;
|
||||||
handler->prev = NULL;
|
handler->prev = NULL;
|
||||||
handler->next = NULL;
|
handler->next = NULL;
|
||||||
|
handler->detail = 0;
|
||||||
handler->ref_count = 1;
|
handler->ref_count = 1;
|
||||||
handler->block_count = 0;
|
handler->block_count = 0;
|
||||||
handler->after = after != FALSE;
|
handler->after = after != FALSE;
|
||||||
@ -474,6 +485,7 @@ handler_insert (guint signal_id,
|
|||||||
static inline void
|
static inline void
|
||||||
emission_push (Emission **emission_list_p,
|
emission_push (Emission **emission_list_p,
|
||||||
guint signal_id,
|
guint signal_id,
|
||||||
|
GQuark detail,
|
||||||
gpointer instance,
|
gpointer instance,
|
||||||
EmissionState *state_p)
|
EmissionState *state_p)
|
||||||
{
|
{
|
||||||
@ -482,29 +494,39 @@ emission_push (Emission **emission_list_p,
|
|||||||
EMISSION_PRE_ALLOC);
|
EMISSION_PRE_ALLOC);
|
||||||
emission->next = *emission_list_p;
|
emission->next = *emission_list_p;
|
||||||
emission->signal_id = signal_id;
|
emission->signal_id = signal_id;
|
||||||
|
emission->detail = detail;
|
||||||
emission->instance = instance;
|
emission->instance = instance;
|
||||||
emission->state_p = state_p;
|
emission->state_p = state_p;
|
||||||
*emission_list_p = emission;
|
*emission_list_p = emission;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
emission_pop (Emission **emission_list_p)
|
emission_pop (Emission **emission_list_p,
|
||||||
|
EmissionState *state_p)
|
||||||
{
|
{
|
||||||
Emission *emission = *emission_list_p;
|
Emission **loc = emission_list_p, *emission = *loc;
|
||||||
|
|
||||||
*emission_list_p = emission->next;
|
while (emission->state_p != state_p)
|
||||||
|
{
|
||||||
|
loc = &emission->next;
|
||||||
|
emission = *loc;
|
||||||
|
}
|
||||||
|
*loc = emission->next;
|
||||||
g_generic_node_free (&g_emission_ts, emission);
|
g_generic_node_free (&g_emission_ts, emission);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline Emission*
|
static inline Emission*
|
||||||
emission_find (Emission *emission_list,
|
emission_find (Emission *emission_list,
|
||||||
guint signal_id,
|
guint signal_id,
|
||||||
|
GQuark detail,
|
||||||
gpointer instance)
|
gpointer instance)
|
||||||
{
|
{
|
||||||
Emission *emission;
|
Emission *emission;
|
||||||
|
|
||||||
for (emission = emission_list; emission; emission = emission->next)
|
for (emission = emission_list; emission; emission = emission->next)
|
||||||
if (emission->instance == instance && emission->signal_id == signal_id)
|
if (emission->instance == instance &&
|
||||||
|
emission->signal_id == signal_id &&
|
||||||
|
emission->detail == detail)
|
||||||
return emission;
|
return emission;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -575,7 +597,8 @@ g_signals_destroy (GType itype)
|
|||||||
|
|
||||||
void
|
void
|
||||||
g_signal_stop_emission (gpointer instance,
|
g_signal_stop_emission (gpointer instance,
|
||||||
guint signal_id)
|
guint signal_id,
|
||||||
|
GQuark detail)
|
||||||
{
|
{
|
||||||
SignalNode *node;
|
SignalNode *node;
|
||||||
|
|
||||||
@ -584,10 +607,16 @@ g_signal_stop_emission (gpointer instance,
|
|||||||
|
|
||||||
G_LOCK (g_signal_mutex);
|
G_LOCK (g_signal_mutex);
|
||||||
node = LOOKUP_SIGNAL_NODE (signal_id);
|
node = LOOKUP_SIGNAL_NODE (signal_id);
|
||||||
|
if (node && 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;
|
||||||
|
}
|
||||||
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))
|
||||||
{
|
{
|
||||||
Emission *emission_list = node->flags & G_SIGNAL_NO_RECURSE ? g_restart_emissions : g_recursive_emissions;
|
Emission *emission_list = node->flags & G_SIGNAL_NO_RECURSE ? g_restart_emissions : g_recursive_emissions;
|
||||||
Emission *emission = emission_find (emission_list, signal_id, instance);
|
Emission *emission = emission_find (emission_list, signal_id, detail, instance);
|
||||||
|
|
||||||
if (emission)
|
if (emission)
|
||||||
{
|
{
|
||||||
@ -664,7 +693,7 @@ g_signal_query (guint signal_id,
|
|||||||
guint
|
guint
|
||||||
g_signal_newv (const gchar *signal_name,
|
g_signal_newv (const gchar *signal_name,
|
||||||
GType itype,
|
GType itype,
|
||||||
GSignalType signal_flags,
|
GSignalFlags signal_flags,
|
||||||
GClosure *class_closure,
|
GClosure *class_closure,
|
||||||
GSignalAccumulator accumulator,
|
GSignalAccumulator accumulator,
|
||||||
GSignalCMarshaller c_marshaller,
|
GSignalCMarshaller c_marshaller,
|
||||||
@ -752,12 +781,7 @@ g_signal_newv (const gchar *signal_name,
|
|||||||
node->destroyed = FALSE;
|
node->destroyed = FALSE;
|
||||||
|
|
||||||
/* setup reinitializable portion */
|
/* setup reinitializable portion */
|
||||||
node->flags = signal_flags & (G_SIGNAL_RUN_FIRST |
|
node->flags = signal_flags & G_SIGNAL_FLAGS_MASK;
|
||||||
G_SIGNAL_RUN_LAST |
|
|
||||||
G_SIGNAL_RUN_CLEANUP |
|
|
||||||
G_SIGNAL_NO_RECURSE |
|
|
||||||
G_SIGNAL_ACTION |
|
|
||||||
G_SIGNAL_NO_HOOKS);
|
|
||||||
node->n_params = n_params;
|
node->n_params = n_params;
|
||||||
node->param_types = g_memdup (param_types, sizeof (GType) * n_params);
|
node->param_types = g_memdup (param_types, sizeof (GType) * n_params);
|
||||||
node->return_type = return_type;
|
node->return_type = return_type;
|
||||||
@ -817,6 +841,7 @@ signal_destroy_R (SignalNode *signal_node)
|
|||||||
guint
|
guint
|
||||||
g_signal_connect_closure (gpointer instance,
|
g_signal_connect_closure (gpointer instance,
|
||||||
guint signal_id,
|
guint signal_id,
|
||||||
|
GQuark detail,
|
||||||
GClosure *closure,
|
GClosure *closure,
|
||||||
gboolean after)
|
gboolean after)
|
||||||
{
|
{
|
||||||
@ -829,11 +854,18 @@ g_signal_connect_closure (gpointer instance,
|
|||||||
|
|
||||||
G_LOCK (g_signal_mutex);
|
G_LOCK (g_signal_mutex);
|
||||||
node = LOOKUP_SIGNAL_NODE (signal_id);
|
node = LOOKUP_SIGNAL_NODE (signal_id);
|
||||||
|
if (node && 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 && g_type_conforms_to (G_TYPE_FROM_INSTANCE (instance), node->itype))
|
if (node && g_type_conforms_to (G_TYPE_FROM_INSTANCE (instance), node->itype))
|
||||||
{
|
{
|
||||||
Handler *handler = handler_new (after);
|
Handler *handler = handler_new (after);
|
||||||
|
|
||||||
handler_id = handler->id;
|
handler_id = handler->id;
|
||||||
|
handler->detail = detail;
|
||||||
handler->closure = g_closure_ref (closure);
|
handler->closure = g_closure_ref (closure);
|
||||||
handler_insert (signal_id, instance, handler);
|
handler_insert (signal_id, instance, handler);
|
||||||
if (node->c_marshaller && G_CLOSURE_NEEDS_MARSHAL (closure))
|
if (node->c_marshaller && G_CLOSURE_NEEDS_MARSHAL (closure))
|
||||||
@ -964,6 +996,7 @@ guint
|
|||||||
g_signal_handler_find (gpointer instance,
|
g_signal_handler_find (gpointer instance,
|
||||||
GSignalMatchType mask,
|
GSignalMatchType mask,
|
||||||
guint signal_id,
|
guint signal_id,
|
||||||
|
GQuark detail,
|
||||||
GClosure *closure,
|
GClosure *closure,
|
||||||
gpointer func,
|
gpointer func,
|
||||||
gpointer data)
|
gpointer data)
|
||||||
@ -972,9 +1005,10 @@ g_signal_handler_find (gpointer instance,
|
|||||||
guint handler_id;
|
guint handler_id;
|
||||||
|
|
||||||
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_LOCK (g_signal_mutex);
|
G_LOCK (g_signal_mutex);
|
||||||
handler = handler_find (instance, mask, signal_id, closure, func, data);
|
handler = handler_find (instance, mask, signal_id, detail, closure, func, data);
|
||||||
handler_id = handler ? handler->id : 0;
|
handler_id = handler ? handler->id : 0;
|
||||||
G_UNLOCK (g_signal_mutex);
|
G_UNLOCK (g_signal_mutex);
|
||||||
|
|
||||||
@ -984,6 +1018,7 @@ g_signal_handler_find (gpointer instance,
|
|||||||
gboolean
|
gboolean
|
||||||
g_signal_handler_pending (gpointer instance,
|
g_signal_handler_pending (gpointer instance,
|
||||||
guint signal_id,
|
guint signal_id,
|
||||||
|
GQuark detail,
|
||||||
gboolean may_be_blocked)
|
gboolean may_be_blocked)
|
||||||
{
|
{
|
||||||
Handler *handler = NULL;
|
Handler *handler = NULL;
|
||||||
@ -992,11 +1027,21 @@ g_signal_handler_pending (gpointer instance,
|
|||||||
g_return_val_if_fail (signal_id > 0, FALSE);
|
g_return_val_if_fail (signal_id > 0, FALSE);
|
||||||
|
|
||||||
G_LOCK (g_signal_mutex);
|
G_LOCK (g_signal_mutex);
|
||||||
handler = handler_find (instance, G_SIGNAL_MATCH_ID, signal_id, NULL, NULL, NULL);
|
if (detail)
|
||||||
if (!may_be_blocked)
|
{
|
||||||
for (; handler; handler = handler->next)
|
SignalNode *node = LOOKUP_SIGNAL_NODE (signal_id);
|
||||||
if (!handler->block_count)
|
|
||||||
break;
|
if (!(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 FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
handler = handler_find (instance,
|
||||||
|
(G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_DETAIL |
|
||||||
|
(may_be_blocked ? 0 : G_SIGNAL_MATCH_UNBLOCKED)),
|
||||||
|
signal_id, detail, NULL, NULL, NULL);
|
||||||
G_UNLOCK (g_signal_mutex);
|
G_UNLOCK (g_signal_mutex);
|
||||||
|
|
||||||
return handler != NULL;
|
return handler != NULL;
|
||||||
@ -1005,6 +1050,7 @@ g_signal_handler_pending (gpointer instance,
|
|||||||
void
|
void
|
||||||
g_signal_emitv (const GValue *instance_and_params,
|
g_signal_emitv (const GValue *instance_and_params,
|
||||||
guint signal_id,
|
guint signal_id,
|
||||||
|
GQuark detail,
|
||||||
GValue *return_value)
|
GValue *return_value)
|
||||||
{
|
{
|
||||||
SignalNode *node;
|
SignalNode *node;
|
||||||
@ -1024,6 +1070,12 @@ g_signal_emitv (const GValue *instance_and_params,
|
|||||||
#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);
|
||||||
|
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;
|
||||||
|
}
|
||||||
for (i = 0; i < node->n_params; i++)
|
for (i = 0; i < node->n_params; i++)
|
||||||
if (!G_VALUE_HOLDS (param_values + i, node->param_types[i]))
|
if (!G_VALUE_HOLDS (param_values + i, node->param_types[i]))
|
||||||
{
|
{
|
||||||
@ -1059,29 +1111,31 @@ g_signal_emitv (const GValue *instance_and_params,
|
|||||||
return_value = NULL;
|
return_value = NULL;
|
||||||
#endif /* !G_DISABLE_CHECKS */
|
#endif /* !G_DISABLE_CHECKS */
|
||||||
|
|
||||||
signal_emit_R (node, instance, return_value, instance_and_params);
|
signal_emit_R (node, detail, instance, return_value, instance_and_params);
|
||||||
|
|
||||||
G_UNLOCK (g_signal_mutex);
|
G_UNLOCK (g_signal_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
signal_emit_R (SignalNode *node,
|
signal_emit_R (SignalNode *node,
|
||||||
|
GQuark detail,
|
||||||
gpointer instance,
|
gpointer instance,
|
||||||
GValue *return_value,
|
GValue *return_value,
|
||||||
const GValue *instance_and_params)
|
const GValue *instance_and_params)
|
||||||
{
|
{
|
||||||
EmissionState emission_state = 0;
|
EmissionState emission_state = 0;
|
||||||
GSignalAccumulator accumulator;
|
GSignalAccumulator accumulator;
|
||||||
|
GSignalInvocationHint ihint;
|
||||||
GClosure *class_closure;
|
GClosure *class_closure;
|
||||||
HandlerList *hlist;
|
HandlerList *hlist;
|
||||||
Handler *handlers;
|
Handler *handler_list = NULL;
|
||||||
GValue accu;
|
GValue accu;
|
||||||
gboolean accu_used = FALSE;
|
gboolean accu_used = FALSE;
|
||||||
guint signal_id = node->signal_id;
|
guint signal_id = node->signal_id;
|
||||||
|
|
||||||
if (node->flags & G_SIGNAL_NO_RECURSE)
|
if (node->flags & G_SIGNAL_NO_RECURSE)
|
||||||
{
|
{
|
||||||
Emission *emission = emission_find (g_restart_emissions, signal_id, instance);
|
Emission *emission = emission_find (g_restart_emissions, signal_id, detail, instance);
|
||||||
|
|
||||||
if (emission)
|
if (emission)
|
||||||
{
|
{
|
||||||
@ -1089,6 +1143,8 @@ signal_emit_R (SignalNode *node,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ihint.signal_id = node->signal_id;
|
||||||
|
ihint.detail = detail;
|
||||||
accumulator = node->accumulator;
|
accumulator = node->accumulator;
|
||||||
if (accumulator)
|
if (accumulator)
|
||||||
{
|
{
|
||||||
@ -1097,15 +1153,20 @@ signal_emit_R (SignalNode *node,
|
|||||||
G_LOCK (g_signal_mutex);
|
G_LOCK (g_signal_mutex);
|
||||||
}
|
}
|
||||||
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, instance, &emission_state);
|
signal_id, detail, instance, &emission_state);
|
||||||
class_closure = node->class_closure;
|
class_closure = node->class_closure;
|
||||||
hlist = handler_list_lookup (signal_id, instance);
|
|
||||||
handlers = hlist ? hlist->handlers : NULL;
|
|
||||||
if (handlers)
|
|
||||||
handler_ref (handlers);
|
|
||||||
|
|
||||||
EMIT_RESTART:
|
EMIT_RESTART:
|
||||||
|
|
||||||
|
if (handler_list)
|
||||||
|
handler_unref_R (signal_id, instance, handler_list);
|
||||||
|
hlist = handler_list_lookup (signal_id, instance);
|
||||||
|
handler_list = hlist ? hlist->handlers : NULL;
|
||||||
|
if (handler_list)
|
||||||
|
handler_ref (handler_list);
|
||||||
|
|
||||||
|
ihint.run_type = G_SIGNAL_RUN_FIRST;
|
||||||
|
|
||||||
if ((node->flags & G_SIGNAL_RUN_FIRST) && class_closure)
|
if ((node->flags & G_SIGNAL_RUN_FIRST) && class_closure)
|
||||||
{
|
{
|
||||||
emission_state = EMISSION_RUN;
|
emission_state = EMISSION_RUN;
|
||||||
@ -1116,21 +1177,21 @@ signal_emit_R (SignalNode *node,
|
|||||||
if (accu_used)
|
if (accu_used)
|
||||||
g_value_reset (&accu);
|
g_value_reset (&accu);
|
||||||
g_closure_invoke (class_closure,
|
g_closure_invoke (class_closure,
|
||||||
(signal_id << 8) | G_SIGNAL_RUN_FIRST,
|
|
||||||
&accu,
|
&accu,
|
||||||
node->n_params + 1,
|
node->n_params + 1,
|
||||||
instance_and_params);
|
instance_and_params,
|
||||||
if (!accumulator (signal_id, return_value, &accu) &&
|
&ihint);
|
||||||
|
if (!accumulator (&ihint, return_value, &accu) &&
|
||||||
emission_state == EMISSION_RUN)
|
emission_state == EMISSION_RUN)
|
||||||
emission_state = EMISSION_STOP;
|
emission_state = EMISSION_STOP;
|
||||||
accu_used = TRUE;
|
accu_used = TRUE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
g_closure_invoke (class_closure,
|
g_closure_invoke (class_closure,
|
||||||
(signal_id << 8) | G_SIGNAL_RUN_FIRST,
|
|
||||||
return_value,
|
return_value,
|
||||||
node->n_params + 1,
|
node->n_params + 1,
|
||||||
instance_and_params);
|
instance_and_params,
|
||||||
|
&ihint);
|
||||||
G_LOCK (g_signal_mutex);
|
G_LOCK (g_signal_mutex);
|
||||||
|
|
||||||
if (emission_state == EMISSION_STOP)
|
if (emission_state == EMISSION_STOP)
|
||||||
@ -1151,18 +1212,23 @@ signal_emit_R (SignalNode *node,
|
|||||||
goto EMIT_RESTART;
|
goto EMIT_RESTART;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (handlers)
|
if (handler_list)
|
||||||
{
|
{
|
||||||
Handler *handler = handlers;
|
Handler *handler = handler_list;
|
||||||
|
|
||||||
emission_state = EMISSION_RUN;
|
emission_state = EMISSION_RUN;
|
||||||
|
|
||||||
handler_ref (handler);
|
handler_ref (handler);
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
Handler *tmp;
|
Handler *tmp;
|
||||||
|
|
||||||
if (!handler->after && !handler->block_count)
|
if (handler->after)
|
||||||
|
{
|
||||||
|
handler_unref_R (signal_id, instance, handler_list);
|
||||||
|
handler_list = handler;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (!handler->block_count && (!handler->detail || handler->detail == detail))
|
||||||
{
|
{
|
||||||
G_UNLOCK (g_signal_mutex);
|
G_UNLOCK (g_signal_mutex);
|
||||||
if (accumulator)
|
if (accumulator)
|
||||||
@ -1170,21 +1236,21 @@ signal_emit_R (SignalNode *node,
|
|||||||
if (accu_used)
|
if (accu_used)
|
||||||
g_value_reset (&accu);
|
g_value_reset (&accu);
|
||||||
g_closure_invoke (handler->closure,
|
g_closure_invoke (handler->closure,
|
||||||
(signal_id << 8) | G_SIGNAL_RUN_FIRST,
|
|
||||||
&accu,
|
&accu,
|
||||||
node->n_params + 1,
|
node->n_params + 1,
|
||||||
instance_and_params);
|
instance_and_params,
|
||||||
if (!accumulator (signal_id, return_value, &accu) &&
|
&ihint);
|
||||||
|
if (!accumulator (&ihint, return_value, &accu) &&
|
||||||
emission_state == EMISSION_RUN)
|
emission_state == EMISSION_RUN)
|
||||||
emission_state = EMISSION_STOP;
|
emission_state = EMISSION_STOP;
|
||||||
accu_used = TRUE;
|
accu_used = TRUE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
g_closure_invoke (handler->closure,
|
g_closure_invoke (handler->closure,
|
||||||
(signal_id << 8) | G_SIGNAL_RUN_FIRST,
|
|
||||||
return_value,
|
return_value,
|
||||||
node->n_params + 1,
|
node->n_params + 1,
|
||||||
instance_and_params);
|
instance_and_params,
|
||||||
|
&ihint);
|
||||||
G_LOCK (g_signal_mutex);
|
G_LOCK (g_signal_mutex);
|
||||||
|
|
||||||
tmp = emission_state == EMISSION_RUN ? handler->next : NULL;
|
tmp = emission_state == EMISSION_RUN ? handler->next : NULL;
|
||||||
@ -1194,7 +1260,8 @@ signal_emit_R (SignalNode *node,
|
|||||||
|
|
||||||
if (tmp)
|
if (tmp)
|
||||||
handler_ref (tmp);
|
handler_ref (tmp);
|
||||||
handler_unref_R (signal_id, instance, handler);
|
handler_unref_R (signal_id, instance, handler_list);
|
||||||
|
handler_list = handler;
|
||||||
handler = tmp;
|
handler = tmp;
|
||||||
}
|
}
|
||||||
while (handler);
|
while (handler);
|
||||||
@ -1205,6 +1272,8 @@ signal_emit_R (SignalNode *node,
|
|||||||
goto EMIT_RESTART;
|
goto EMIT_RESTART;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ihint.run_type = G_SIGNAL_RUN_LAST;
|
||||||
|
|
||||||
if ((node->flags & G_SIGNAL_RUN_LAST) && class_closure)
|
if ((node->flags & G_SIGNAL_RUN_LAST) && class_closure)
|
||||||
{
|
{
|
||||||
emission_state = EMISSION_RUN;
|
emission_state = EMISSION_RUN;
|
||||||
@ -1215,21 +1284,21 @@ signal_emit_R (SignalNode *node,
|
|||||||
if (accu_used)
|
if (accu_used)
|
||||||
g_value_reset (&accu);
|
g_value_reset (&accu);
|
||||||
g_closure_invoke (class_closure,
|
g_closure_invoke (class_closure,
|
||||||
(signal_id << 8) | G_SIGNAL_RUN_LAST,
|
|
||||||
&accu,
|
&accu,
|
||||||
node->n_params + 1,
|
node->n_params + 1,
|
||||||
instance_and_params);
|
instance_and_params,
|
||||||
if (!accumulator (signal_id, return_value, &accu) &&
|
&ihint);
|
||||||
|
if (!accumulator (&ihint, return_value, &accu) &&
|
||||||
emission_state == EMISSION_RUN)
|
emission_state == EMISSION_RUN)
|
||||||
emission_state = EMISSION_STOP;
|
emission_state = EMISSION_STOP;
|
||||||
accu_used = TRUE;
|
accu_used = TRUE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
g_closure_invoke (class_closure,
|
g_closure_invoke (class_closure,
|
||||||
(signal_id << 8) | G_SIGNAL_RUN_LAST,
|
|
||||||
return_value,
|
return_value,
|
||||||
node->n_params + 1,
|
node->n_params + 1,
|
||||||
instance_and_params);
|
instance_and_params,
|
||||||
|
&ihint);
|
||||||
G_LOCK (g_signal_mutex);
|
G_LOCK (g_signal_mutex);
|
||||||
|
|
||||||
if (emission_state == EMISSION_STOP)
|
if (emission_state == EMISSION_STOP)
|
||||||
@ -1238,18 +1307,17 @@ signal_emit_R (SignalNode *node,
|
|||||||
goto EMIT_RESTART;
|
goto EMIT_RESTART;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (handlers)
|
if (handler_list)
|
||||||
{
|
{
|
||||||
Handler *handler = handlers;
|
Handler *handler = handler_list;
|
||||||
|
|
||||||
emission_state = EMISSION_RUN;
|
emission_state = EMISSION_RUN;
|
||||||
|
|
||||||
handler_ref (handler);
|
handler_ref (handler);
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
Handler *tmp;
|
Handler *tmp;
|
||||||
|
|
||||||
if (handler->after && !handler->block_count)
|
if (handler->after && !handler->block_count && (!handler->detail || handler->detail == detail))
|
||||||
{
|
{
|
||||||
G_UNLOCK (g_signal_mutex);
|
G_UNLOCK (g_signal_mutex);
|
||||||
if (accumulator)
|
if (accumulator)
|
||||||
@ -1257,21 +1325,21 @@ signal_emit_R (SignalNode *node,
|
|||||||
if (accu_used)
|
if (accu_used)
|
||||||
g_value_reset (&accu);
|
g_value_reset (&accu);
|
||||||
g_closure_invoke (handler->closure,
|
g_closure_invoke (handler->closure,
|
||||||
(signal_id << 8) | G_SIGNAL_RUN_LAST,
|
|
||||||
&accu,
|
&accu,
|
||||||
node->n_params + 1,
|
node->n_params + 1,
|
||||||
instance_and_params);
|
instance_and_params,
|
||||||
if (!accumulator (signal_id, return_value, &accu) &&
|
&ihint);
|
||||||
|
if (!accumulator (&ihint, return_value, &accu) &&
|
||||||
emission_state == EMISSION_RUN)
|
emission_state == EMISSION_RUN)
|
||||||
emission_state = EMISSION_STOP;
|
emission_state = EMISSION_STOP;
|
||||||
accu_used = TRUE;
|
accu_used = TRUE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
g_closure_invoke (handler->closure,
|
g_closure_invoke (handler->closure,
|
||||||
(signal_id << 8) | G_SIGNAL_RUN_LAST,
|
|
||||||
return_value,
|
return_value,
|
||||||
node->n_params + 1,
|
node->n_params + 1,
|
||||||
instance_and_params);
|
instance_and_params,
|
||||||
|
&ihint);
|
||||||
G_LOCK (g_signal_mutex);
|
G_LOCK (g_signal_mutex);
|
||||||
|
|
||||||
tmp = emission_state == EMISSION_RUN ? handler->next : NULL;
|
tmp = emission_state == EMISSION_RUN ? handler->next : NULL;
|
||||||
@ -1294,25 +1362,31 @@ signal_emit_R (SignalNode *node,
|
|||||||
|
|
||||||
EMIT_CLEANUP:
|
EMIT_CLEANUP:
|
||||||
|
|
||||||
|
ihint.run_type = G_SIGNAL_RUN_CLEANUP;
|
||||||
|
|
||||||
if ((node->flags & G_SIGNAL_RUN_CLEANUP) && class_closure)
|
if ((node->flags & G_SIGNAL_RUN_CLEANUP) && class_closure)
|
||||||
{
|
{
|
||||||
|
gboolean need_unset = FALSE;
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
if (!accumulator)
|
if (!accumulator)
|
||||||
|
{
|
||||||
g_value_init (&accu, node->return_type);
|
g_value_init (&accu, node->return_type);
|
||||||
|
need_unset = TRUE;
|
||||||
|
}
|
||||||
else if (accu_used)
|
else if (accu_used)
|
||||||
g_value_reset (&accu);
|
g_value_reset (&accu);
|
||||||
accu_used = TRUE;
|
|
||||||
}
|
}
|
||||||
g_closure_invoke (class_closure,
|
g_closure_invoke (class_closure,
|
||||||
(signal_id << 8) | G_SIGNAL_RUN_CLEANUP,
|
|
||||||
node->return_type != G_TYPE_NONE ? &accu : NULL,
|
node->return_type != G_TYPE_NONE ? &accu : NULL,
|
||||||
node->n_params + 1,
|
node->n_params + 1,
|
||||||
instance_and_params);
|
instance_and_params,
|
||||||
if (node->return_type != G_TYPE_NONE && !accumulator)
|
&ihint);
|
||||||
|
if (need_unset)
|
||||||
g_value_unset (&accu);
|
g_value_unset (&accu);
|
||||||
G_LOCK (g_signal_mutex);
|
G_LOCK (g_signal_mutex);
|
||||||
|
|
||||||
@ -1320,10 +1394,10 @@ signal_emit_R (SignalNode *node,
|
|||||||
goto EMIT_RESTART;
|
goto EMIT_RESTART;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (handlers)
|
if (handler_list)
|
||||||
handler_unref_R (signal_id, instance, handlers);
|
handler_unref_R (signal_id, instance, handler_list);
|
||||||
|
|
||||||
emission_pop ((node->flags & G_SIGNAL_NO_RECURSE) ? &g_restart_emissions : &g_recursive_emissions);
|
emission_pop ((node->flags & G_SIGNAL_NO_RECURSE) ? &g_restart_emissions : &g_recursive_emissions, &emission_state);
|
||||||
if (accumulator)
|
if (accumulator)
|
||||||
{
|
{
|
||||||
G_UNLOCK (g_signal_mutex);
|
G_UNLOCK (g_signal_mutex);
|
||||||
|
@ -30,9 +30,16 @@ extern "C" {
|
|||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
|
|
||||||
/* --- macros --- */
|
/* --- typedefs --- */
|
||||||
#define G_SIGNAL_HINT_ID(hint) ((hint) >> 8)
|
typedef struct _GSignalQuery GSignalQuery;
|
||||||
#define G_SIGNAL_HINT_RUN_TYPE(hint) ((hint) & 0xff)
|
typedef struct _GSignalInvocationHint GSignalInvocationHint;
|
||||||
|
typedef GClosureMarshal GSignalCMarshaller;
|
||||||
|
typedef gboolean (*GSignalEmissionHook) (GSignalInvocationHint *ihint,
|
||||||
|
guint n_param_values,
|
||||||
|
const GValue *param_values);
|
||||||
|
typedef gboolean (*GSignalAccumulator) (GSignalInvocationHint *ihint,
|
||||||
|
GValue *return_accu,
|
||||||
|
const GValue *return_value);
|
||||||
|
|
||||||
|
|
||||||
/* --- run & match types --- */
|
/* --- run & match types --- */
|
||||||
@ -42,48 +49,46 @@ typedef enum
|
|||||||
G_SIGNAL_RUN_LAST = 1 << 1,
|
G_SIGNAL_RUN_LAST = 1 << 1,
|
||||||
G_SIGNAL_RUN_CLEANUP = 1 << 2,
|
G_SIGNAL_RUN_CLEANUP = 1 << 2,
|
||||||
G_SIGNAL_NO_RECURSE = 1 << 3,
|
G_SIGNAL_NO_RECURSE = 1 << 3,
|
||||||
G_SIGNAL_ACTION = 1 << 4,
|
G_SIGNAL_DETAILED = 1 << 4,
|
||||||
G_SIGNAL_NO_HOOKS = 1 << 5
|
G_SIGNAL_ACTION = 1 << 5,
|
||||||
} GSignalType;
|
G_SIGNAL_NO_HOOKS = 1 << 6
|
||||||
|
#define G_SIGNAL_FLAGS_MASK 0x7f
|
||||||
|
} GSignalFlags;
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
G_SIGNAL_MATCH_ID = 1 << 0,
|
G_SIGNAL_MATCH_ID = 1 << 0,
|
||||||
G_SIGNAL_MATCH_CLOSURE = 1 << 1,
|
G_SIGNAL_MATCH_DETAIL = 1 << 1,
|
||||||
G_SIGNAL_MATCH_FUNC = 1 << 2,
|
G_SIGNAL_MATCH_CLOSURE = 1 << 2,
|
||||||
G_SIGNAL_MATCH_DATA = 1 << 3,
|
G_SIGNAL_MATCH_FUNC = 1 << 3,
|
||||||
G_SIGNAL_MATCH_UNBLOCKED = 1 << 4,
|
G_SIGNAL_MATCH_DATA = 1 << 4,
|
||||||
G_SIGNAL_MATCH_MASK = 0x1f
|
G_SIGNAL_MATCH_UNBLOCKED = 1 << 5
|
||||||
|
#define G_SIGNAL_MATCH_MASK 0x3f
|
||||||
} GSignalMatchType;
|
} GSignalMatchType;
|
||||||
|
|
||||||
|
|
||||||
/* --- signal queries --- */
|
/* --- signal information --- */
|
||||||
typedef struct _GSignalQuery GSignalQuery;
|
struct _GSignalInvocationHint
|
||||||
|
{
|
||||||
|
guint signal_id;
|
||||||
|
GQuark detail;
|
||||||
|
GSignalFlags run_type;
|
||||||
|
};
|
||||||
struct _GSignalQuery
|
struct _GSignalQuery
|
||||||
{
|
{
|
||||||
guint signal_id;
|
guint signal_id;
|
||||||
const gchar *signal_name;
|
const gchar *signal_name;
|
||||||
GType itype;
|
GType itype;
|
||||||
GSignalType signal_flags;
|
GSignalFlags signal_flags;
|
||||||
GType return_type;
|
GType return_type;
|
||||||
guint n_params;
|
guint n_params;
|
||||||
const GType *param_types;
|
const GType *param_types;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* --- function types --- */
|
|
||||||
typedef gboolean (*GSignalEmissionHook) (guint signal_id,
|
|
||||||
guint n_values,
|
|
||||||
const GValue *values);
|
|
||||||
typedef gboolean (*GSignalAccumulator) (guint signal_id,
|
|
||||||
GValue *return_accu,
|
|
||||||
const GValue *return_value);
|
|
||||||
typedef GClosureMarshal GSignalCMarshaller;
|
|
||||||
|
|
||||||
|
|
||||||
/* --- signals --- */
|
/* --- signals --- */
|
||||||
guint g_signal_newv (const gchar *signal_name,
|
guint g_signal_newv (const gchar *signal_name,
|
||||||
GType itype,
|
GType itype,
|
||||||
GSignalType signal_flags,
|
GSignalFlags signal_flags,
|
||||||
GClosure *class_closure,
|
GClosure *class_closure,
|
||||||
GSignalAccumulator accumulator,
|
GSignalAccumulator accumulator,
|
||||||
GSignalCMarshaller c_marshaller,
|
GSignalCMarshaller c_marshaller,
|
||||||
@ -92,6 +97,7 @@ guint g_signal_newv (const gchar *signal_name,
|
|||||||
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,
|
||||||
GValue *return_value);
|
GValue *return_value);
|
||||||
guint g_signal_lookup (const gchar *name,
|
guint g_signal_lookup (const gchar *name,
|
||||||
GType itype);
|
GType itype);
|
||||||
@ -103,6 +109,7 @@ void g_signal_query (guint signal_id,
|
|||||||
/* --- signal handlers --- */
|
/* --- signal handlers --- */
|
||||||
guint g_signal_connect_closure (gpointer instance,
|
guint g_signal_connect_closure (gpointer instance,
|
||||||
guint signal_id,
|
guint signal_id,
|
||||||
|
GQuark detail,
|
||||||
GClosure *closure,
|
GClosure *closure,
|
||||||
gboolean after);
|
gboolean after);
|
||||||
void g_signal_handler_disconnect (gpointer instance,
|
void g_signal_handler_disconnect (gpointer instance,
|
||||||
@ -114,17 +121,20 @@ void g_signal_handler_unblock (gpointer instance,
|
|||||||
guint g_signal_handler_find (gpointer instance,
|
guint g_signal_handler_find (gpointer instance,
|
||||||
GSignalMatchType mask,
|
GSignalMatchType mask,
|
||||||
guint signal_id,
|
guint signal_id,
|
||||||
|
GQuark detail,
|
||||||
GClosure *closure,
|
GClosure *closure,
|
||||||
gpointer func,
|
gpointer func,
|
||||||
gpointer data);
|
gpointer data);
|
||||||
gboolean g_signal_has_handler_pending (gpointer instance,
|
gboolean g_signal_has_handler_pending (gpointer instance,
|
||||||
guint signal_id,
|
guint signal_id,
|
||||||
|
GQuark detail,
|
||||||
gboolean may_be_blocked);
|
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);
|
||||||
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,
|
||||||
|
Loading…
Reference in New Issue
Block a user