[seed] support signals with annotated types



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]