[seed] support signals with annotated types
- From: Alan Knowles <alank src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [seed] support signals with annotated types
- Date: Fri, 29 Mar 2013 13:12:09 +0000 (UTC)
commit d4c63f31cb0d310754df21e4150a838604ac07ba
Author: Alban Crequy <alban crequy collabora co uk>
Date: Wed Feb 6 14:49:10 2013 +0000
support signals with annotated types
https://bugzilla.gnome.org/show_bug.cgi?id=695857
libseed/seed-closure.c | 16 ++++++++++++--
libseed/seed-closure.h | 8 +++++++
libseed/seed-signals.c | 26 +++++++++++++++++++++--
libseed/seed-types.c | 51 +++++++++++++++++++++++++++++++++++++++++++++--
libseed/seed-types.h | 4 +++
5 files changed, 96 insertions(+), 9 deletions(-)
---
diff --git a/libseed/seed-closure.c b/libseed/seed-closure.c
index bac1b9b..62241c8 100644
--- a/libseed/seed-closure.c
+++ b/libseed/seed-closure.c
@@ -400,14 +400,16 @@ seed_closure_invoke_with_context (JSContextRef ctx, GClosure * closure,
}
GClosure *
-seed_closure_new (JSContextRef ctx, JSObjectRef function,
- JSObjectRef user_data, const gchar * description)
+seed_closure_new_for_signal (JSContextRef ctx, JSObjectRef function,
+ JSObjectRef user_data, const gchar * description,
+ guint signal_id)
{
GClosure *closure;
closure = g_closure_new_simple (sizeof (SeedClosure), 0);
g_closure_add_finalize_notifier (closure, 0, closure_invalidated);
- g_closure_set_marshal (closure, seed_signal_marshal_func);
+ g_closure_set_meta_marshal (closure, GUINT_TO_POINTER (signal_id),
+ seed_signal_marshal_func);
JSValueProtect (ctx, function);
((SeedClosure *) closure)->function = function;
@@ -423,6 +425,14 @@ seed_closure_new (JSContextRef ctx, JSObjectRef function,
return closure;
}
+GClosure *
+seed_closure_new (JSContextRef ctx, JSObjectRef function,
+ JSObjectRef user_data, const gchar * description)
+{
+ return seed_closure_new_for_signal (ctx, function, user_data, description,
+ 0);
+}
+
void
seed_closure_warn_exception (GClosure * c,
JSContextRef ctx, JSValueRef exception)
diff --git a/libseed/seed-closure.h b/libseed/seed-closure.h
index 46a4563..49246f1 100644
--- a/libseed/seed-closure.h
+++ b/libseed/seed-closure.h
@@ -52,6 +52,14 @@ GClosure *seed_closure_new (JSContextRef ctx,
JSObjectRef function,
JSObjectRef user_data, const gchar * description);
+
+GClosure *seed_closure_new_for_signal (JSContextRef ctx,
+ JSObjectRef function,
+ JSObjectRef user_data,
+ const gchar *description,
+ guint signal_id);
+
+
JSObjectRef seed_closure_get_callable (GClosure * c);
JSValueRef
diff --git a/libseed/seed-signals.c b/libseed/seed-signals.c
index 8b6223a..f1bbddc 100644
--- a/libseed/seed-signals.c
+++ b/libseed/seed-signals.c
@@ -73,7 +73,8 @@ seed_gobject_signal_connect (JSContextRef ctx,
}
#endif
- closure = seed_closure_new (ctx, func, user_data, "signal handler");
+ closure = seed_closure_new_for_signal (ctx, func, user_data, "signal handler", query.signal_id);
+
// This seems wrong...
((SeedClosure *) closure)->return_type = query.return_type;
return g_signal_connect_closure (on_obj, signal_name, closure, FALSE);
@@ -151,13 +152,31 @@ seed_signal_marshal_func (GClosure * closure,
GValue * return_value,
guint n_param_values,
const GValue * param_values,
- gpointer invocation_hint, gpointer marshall_data)
+ gpointer invocation_hint, gpointer marshal_data)
{
SeedClosure *seed_closure = (SeedClosure *) closure;
JSValueRef *args, exception = 0;
JSValueRef ret = 0;
guint i;
gchar *mes;
+ GSignalQuery signal_query = { 0, };
+
+ if (marshal_data)
+ {
+ /* Inspired from gjs/gi/value.c:closure_marshal() */
+ /* we are used for a signal handler */
+ guint signal_id;
+
+ signal_id = GPOINTER_TO_UINT(marshal_data);
+
+ g_signal_query(signal_id, &signal_query);
+
+ if (!signal_query.signal_id)
+ g_error("Signal handler being called on invalid signal");
+
+ if (signal_query.n_params + 1 != n_param_values)
+ g_error("Signal handler being called with wrong number of parameters");
+ }
JSContextRef ctx = JSGlobalContextCreateInGroup (context_group,
0);
@@ -169,7 +188,8 @@ seed_signal_marshal_func (GClosure * closure,
for (i = 0; i < n_param_values; i++)
{
- args[i] = seed_value_from_gvalue (ctx, (GValue *) & param_values[i], 0);
+ args[i] = seed_value_from_gvalue_for_signal (ctx,
+ (GValue *) & param_values[i], 0, &signal_query, i);
if (!args[i])
g_error ("Error in signal marshal. "
diff --git a/libseed/seed-types.c b/libseed/seed-types.c
index 9972653..5f17d9b 100644
--- a/libseed/seed-types.c
+++ b/libseed/seed-types.c
@@ -1257,8 +1257,9 @@ seed_value_from_gi_argument_full (JSContextRef ctx,
}
JSValueRef
-seed_value_from_gvalue (JSContextRef ctx,
- GValue * gval, JSValueRef * exception)
+seed_value_from_gvalue_for_signal (JSContextRef ctx, GValue * gval,
+ JSValueRef * exception,
+ GSignalQuery *signal_query, gint arg_n)
{
if (!G_IS_VALUE (gval))
{
@@ -1295,7 +1296,44 @@ seed_value_from_gvalue (JSContextRef ctx,
return seed_value_from_string (ctx, (gchar *)
g_value_get_string (gval), exception);
case G_TYPE_POINTER:
- return seed_make_pointer (ctx, g_value_get_pointer (gval));
+ if (signal_query)
+ {
+ JSValueRef res;
+ GArgument arg;
+ GIBaseInfo *obj;
+ GISignalInfo *signal_info;
+ GIArgInfo *arg_info;
+ GITypeInfo type_info;
+
+ obj = g_irepository_find_by_gtype(NULL, signal_query->itype);
+ if (!obj)
+ return NULL;
+
+ signal_info = g_object_info_find_signal((GIObjectInfo *) obj,
+ signal_query->signal_name);
+
+ if (!signal_info) {
+ g_base_info_unref((GIBaseInfo *) obj);
+ return NULL;
+ }
+
+ arg_info = g_callable_info_get_arg(signal_info, arg_n - 1);
+ g_arg_info_load_type(arg_info, &type_info);
+
+ arg.v_pointer = g_value_get_pointer(gval);
+
+ res = seed_value_from_gi_argument (ctx, &arg, &type_info, exception);
+
+ g_base_info_unref((GIBaseInfo*)arg_info);
+ g_base_info_unref((GIBaseInfo*)signal_info);
+ g_base_info_unref((GIBaseInfo*)obj);
+
+ return res;
+ }
+ else
+ {
+ return seed_make_pointer (ctx, g_value_get_pointer (gval));
+ }
case G_TYPE_PARAM:
// Might need to dup and make a boxed.
return seed_make_pointer (ctx, g_value_get_param (gval));
@@ -1345,6 +1383,13 @@ seed_value_from_gvalue (JSContextRef ctx,
return NULL;
}
+JSValueRef
+seed_value_from_gvalue (JSContextRef ctx,
+ GValue * gval, JSValueRef * exception)
+{
+ return seed_value_from_gvalue_for_signal(ctx, gval, exception, NULL, 0);
+}
+
gboolean
seed_value_to_gvalue (JSContextRef ctx,
JSValueRef val,
diff --git a/libseed/seed-types.h b/libseed/seed-types.h
index 45a5bf4..1ffdac3 100644
--- a/libseed/seed-types.h
+++ b/libseed/seed-types.h
@@ -27,6 +27,10 @@ extern GQuark js_ref_quark;
JSValueRef seed_value_from_gvalue (JSContextRef ctx,
GValue * gval, JSValueRef * exception);
+JSValueRef seed_value_from_gvalue_for_signal (JSContextRef ctx,
+ GValue * gval, JSValueRef * exception,
+ GSignalQuery *signal_query, gint arg_n);
+
gboolean seed_value_to_gvalue (JSContextRef ctx,
JSValueRef val, GType type,
GValue * gval, JSValueRef * exception);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]