[gjs] value: implement marshalling of foreign structures to GValue



commit 080797c9f94dcd2afd1c3355a8cf31cd7259a3de
Author: Giovanni Campagna <gcampagna src gnome org>
Date:   Sun Aug 4 23:38:56 2013 +0200

    value: implement marshalling of foreign structures to GValue
    
    Previously when setting a GValue we would require a real boxed
    structure, but for foreign types the JS code should never see
    them, so allow passing a foreign wrapper instead.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=705465

 gi/value.cpp                            |   43 ++++++++++++++++++++++++------
 installed-tests/js/testGIMarshalling.js |   13 +++++++++
 2 files changed, 47 insertions(+), 9 deletions(-)
---
diff --git a/gi/value.cpp b/gi/value.cpp
index dcde4aa..5d16ea9 100644
--- a/gi/value.cpp
+++ b/gi/value.cpp
@@ -412,6 +412,29 @@ gjs_value_to_g_value_internal(JSContext    *context,
 
                 gboxed = gjs_gerror_from_error(context, obj);
             } else {
+                GIBaseInfo *registered = g_irepository_find_by_gtype (NULL, gtype);
+
+                /* We don't necessarily have the typelib loaded when
+                   we first see the structure... */
+                if (registered) {
+                    GIInfoType info_type = g_base_info_get_type (registered);
+
+                    if (info_type == GI_INFO_TYPE_STRUCT &&
+                        g_struct_info_is_foreign ((GIStructInfo*)registered)) {
+                        GArgument arg;
+
+                        if (!gjs_struct_foreign_convert_to_g_argument (context, value,
+                                                                       registered,
+                                                                       NULL,
+                                                                       GJS_ARGUMENT_ARGUMENT,
+                                                                       GI_TRANSFER_NOTHING,
+                                                                       TRUE, &arg))
+                            return FALSE;
+
+                        gboxed = arg.v_pointer;
+                    }
+                }
+
                 /* First try a union, if that fails,
                    assume a boxed struct. Distinguishing
                    which one is expected would require checking
@@ -419,15 +442,17 @@ gjs_value_to_g_value_internal(JSContext    *context,
                    possible, if e.g. we see the GType without
                    loading the typelib.
                 */
-                if (gjs_typecheck_union(context, obj,
-                                        NULL, gtype, JS_FALSE)) {
-                    gboxed = gjs_c_union_from_union(context, obj);
-                } else {
-                    if (!gjs_typecheck_boxed(context, obj,
-                                             NULL, gtype, JS_TRUE))
-                        return JS_FALSE;
-
-                    gboxed = gjs_c_struct_from_boxed(context, obj);
+                if (!gboxed) {
+                    if (gjs_typecheck_union(context, obj,
+                                            NULL, gtype, JS_FALSE)) {
+                        gboxed = gjs_c_union_from_union(context, obj);
+                    } else {
+                        if (!gjs_typecheck_boxed(context, obj,
+                                                 NULL, gtype, JS_TRUE))
+                            return JS_FALSE;
+
+                        gboxed = gjs_c_struct_from_boxed(context, obj);
+                    }
                 }
             }
         } else {
diff --git a/installed-tests/js/testGIMarshalling.js b/installed-tests/js/testGIMarshalling.js
index a3d45d1..da8af79 100644
--- a/installed-tests/js/testGIMarshalling.js
+++ b/installed-tests/js/testGIMarshalling.js
@@ -299,6 +299,19 @@ function testGValueGType() {
     // Other
     GIMarshallingTests.gvalue_in_with_type(GObject.ParamSpec.string('my-param', '', '', 
GObject.ParamFlags.READABLE, ''),
                                           GObject.TYPE_PARAM);
+
+    // Foreign
+    let Cairo;
+    try {
+        Cairo = imports.cairo;
+    } catch(e) {
+        return;
+    }
+
+    let surface = new Cairo.ImageSurface(Cairo.Format.ARGB32, 2, 2);
+    let cr = new Cairo.Context(surface);
+    GIMarshallingTests.gvalue_in_with_type(cr, Cairo.Context);
+    GIMarshallingTests.gvalue_in_with_type(surface, Cairo.Surface);
 }
 
 function callback_return_value_only() {


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]