[pygobject] add a foreign type for cairo_rectangle_int_t and allow it to be caller-allocated



commit 68b8211d8b014cf26ca7e9ab751fb3f61f228290
Author: John (J5) Palmieri <johnp redhat com>
Date:   Mon Oct 25 18:28:36 2010 -0400

    add a foreign type for cairo_rectangle_int_t and allow it to be caller-allocated
    
    * this is needed because Gdk and Gtk switched from returning a GdkRectangle
      to a CairoRectangleInt structure
    * the patch in https://bugs.freedesktop.org/show_bug.cgi?id=31111 is required
      for pycairo (however there is currently no patch for python 2)
    * added fix for foreign types to allow them to be caller allocated
    * in order for a type to be caller allocated it must be able to take a NULL
      and create an empty struct in foreign_struct_from_arg and it must be able
      to handle GI_TRANFER_EVERYTHING in foreign_struct_to_arg.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=627545

 gi/pygi-foreign-cairo.c |   57 +++++++++++++++++++++++++++++++++++++++++++++++
 gi/pygi-invoke.c        |   15 ++++++++++-
 2 files changed, 70 insertions(+), 2 deletions(-)
---
diff --git a/gi/pygi-foreign-cairo.c b/gi/pygi-foreign-cairo.c
index 63d12f5..d3c05f3 100644
--- a/gi/pygi-foreign-cairo.c
+++ b/gi/pygi-foreign-cairo.c
@@ -112,6 +112,56 @@ cairo_surface_release (GIBaseInfo *base_info,
     Py_RETURN_NONE;
 }
 
+PyObject *
+cairo_rectangle_int_to_arg (PyObject       *value,
+                            GITypeInfo     *type_info,
+                            GITransfer      transfer,
+                            GIArgument      *arg)
+{
+    cairo_rectangle_int_t *rect;
+
+    rect = ( (PycairoRectangleInt *) value)->rectangle_int;
+    if (!rect) {
+        PyErr_SetString (PyExc_ValueError, "RectangleInt instance wrapping a NULL pointer");
+        return NULL;
+    }
+
+    if (transfer == GI_TRANSFER_EVERYTHING) {
+        unsigned int size = sizeof(cairo_rectangle_int_t);
+        cairo_rectangle_int_t *transfer = malloc(size);
+        if (!transfer) {
+            PyErr_NoMemory();
+            return NULL;
+        }
+
+        memcpy(transfer, rect, size);
+        rect = transfer;
+    }
+
+    arg->v_pointer = rect;
+    Py_RETURN_NONE;
+}
+
+PyObject *
+cairo_rectangle_int_from_arg (GITypeInfo *type_info, GIArgument  *arg)
+{
+    cairo_rectangle_int_t *rect = (cairo_rectangle_int_t*) arg;
+
+    if (rect)
+      return PycairoRectangleInt_FromRectangleInt (rect);
+    else {
+      cairo_rectangle_int_t temp = {};
+      return PycairoRectangleInt_FromRectangleInt (&temp);
+    }
+}
+
+PyObject *
+cairo_rectangle_int_release (GIBaseInfo *base_info,
+                             gpointer    struct_)
+{
+    g_free (struct_);
+    Py_RETURN_NONE;
+}
 
 static PyMethodDef _gi_cairo_functions[] = {};
 PYGLIB_MODULE_START(_gi_cairo, "_gi_cairo")
@@ -131,5 +181,12 @@ PYGLIB_MODULE_START(_gi_cairo, "_gi_cairo")
                                   cairo_surface_to_arg,
                                   cairo_surface_from_arg,
                                   cairo_surface_release);
+
+     pygi_register_foreign_struct ("cairo",
+                                  "RectangleInt",
+                                  cairo_rectangle_int_to_arg,
+                                  cairo_rectangle_int_from_arg,
+                                  cairo_rectangle_int_release);
+
 }
 PYGLIB_MODULE_END;
diff --git a/gi/pygi-invoke.c b/gi/pygi-invoke.c
index b96eeaf..71d5859 100644
--- a/gi/pygi-invoke.c
+++ b/gi/pygi-invoke.c
@@ -343,9 +343,20 @@ _prepare_invocation_state (struct invocation_state *state,
                         /* if caller allocates only use one level of indirection */
                         state->out_args[out_args_pos].v_pointer = NULL;
                         state->args[i] = &state->out_args[out_args_pos];
-                        if (g_type_is_a (g_registered_type_info_get_g_type (info), G_TYPE_BOXED))
+                        if (g_type_is_a (g_registered_type_info_get_g_type (info), G_TYPE_BOXED)) {
                             state->args[i]->v_pointer = _pygi_boxed_alloc (info, NULL);
-                        else {
+                        } else if (g_struct_info_is_foreign((GIStructInfo *) info) ) {
+                            PyObject *foreign_struct =
+                                pygi_struct_foreign_convert_from_g_argument(state->arg_type_infos[i], NULL);
+
+                            pygi_struct_foreign_convert_to_g_argument(
+                                foreign_struct,
+                                state->arg_type_infos[i],
+                                GI_TRANSFER_EVERYTHING,
+                                state->args[i]);
+
+                            Py_DECREF(foreign_struct);
+                        } else {
                             gssize size = g_struct_info_get_size ( (GIStructInfo *) info);
                             state->args[i]->v_pointer = g_malloc0 (size);
                         }



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