[pygobject] Build the cairo shim as a python module so the _gi module stops linking to it
- From: Tomeu Vizoso <tomeuv src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pygobject] Build the cairo shim as a python module so the _gi module stops linking to it
- Date: Tue, 29 Jun 2010 08:30:12 +0000 (UTC)
commit 89827314fd183eac07443c8e9d275ca9d4ce59df
Author: Tomeu Vizoso <tomeu vizoso collabora co uk>
Date: Tue Jun 29 10:27:39 2010 +0200
Build the cairo shim as a python module so the _gi module stops linking to it
https://bugzilla.gnome.org/show_bug.cgi?id=623021
configure.ac | 2 +
gi/Makefile.am | 38 +++++++++-----
gi/gimodule.c | 8 +---
gi/pygi-argument.c | 10 +---
gi/pygi-foreign-cairo.c | 56 ++++++++++++++++-----
gi/pygi-foreign-cairo.h | 55 ---------------------
gi/pygi-foreign.c | 125 ++++++++++++++++++++++++++++-------------------
gi/pygi-foreign.h | 31 +++++------
gi/pygi.h | 40 +++++++++++++--
9 files changed, 196 insertions(+), 169 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index e9c5440..1458681 100644
--- a/configure.ac
+++ b/configure.ac
@@ -213,6 +213,8 @@ if test "$enable_introspection" != no; then
PKG_CHECK_MODULES(GI,
glib-2.0 >= glib_required_version
gobject-introspection-1.0 >= introspection_required_version
+ )
+ PKG_CHECK_MODULES(PYCAIRO,
pycairo >= pycairo_required_version
)
fi
diff --git a/gi/Makefile.am b/gi/Makefile.am
index f0c9ea2..ef4b8ff 100644
--- a/gi/Makefile.am
+++ b/gi/Makefile.am
@@ -9,11 +9,6 @@ SUBDIRS = \
INCLUDES = -I$(top_srcdir)/gobject
-AM_CFLAGS = \
- $(PYTHON_INCLUDES) \
- $(GI_CFLAGS) \
- $(PYCAIRO_CFLAGS)
-
pygidir = $(pkgpyexecdir)/gi
pygi_PYTHON = \
types.py \
@@ -21,13 +16,15 @@ pygi_PYTHON = \
importer.py \
__init__.py
+_gi_la_CFLAGS = \
+ $(PYTHON_INCLUDES) \
+ $(GI_CFLAGS)
_gi_la_LDFLAGS = \
-module \
-avoid-version \
-export-symbols-regex init_gi
_gi_la_LIBADD = \
- $(GI_LIBS) \
- $(PYCAIRO_LIBS)
+ $(GI_LIBS)
_gi_la_SOURCES = \
pygi-repository.c \
pygi-repository.h \
@@ -37,8 +34,6 @@ _gi_la_SOURCES = \
pygi-invoke.h \
pygi-foreign.c \
pygi-foreign.h \
- pygi-foreign-cairo.c \
- pygi-foreign-cairo.h \
pygi-struct.c \
pygi-struct.h \
pygi-argument.c \
@@ -56,16 +51,33 @@ _gi_la_SOURCES = \
pygobject-external.h \
gimodule.c
-pygi_LTLIBRARIES = _gi.la
+_gi_cairo_la_CFLAGS = \
+ $(PYTHON_INCLUDES) \
+ $(GI_CFLAGS) \
+ $(PYCAIRO_CFLAGS)
+_gi_cairo_la_LDFLAGS = \
+ -module \
+ -avoid-version \
+ -export-symbols-regex init_gi_cairo
+_gi_cairo_la_LIBADD = \
+ $(GI_LIBS) \
+ $(PYCAIRO_LIBS)
+_gi_cairo_la_SOURCES = \
+ pygi-foreign-cairo.c \
+ pygi-foreign-cairo.h
+
+pygi_LTLIBRARIES = _gi.la _gi_cairo.la
# This is to ensure we have a symlink to the .so in the
# build directory, which the Python interpreter can load
# directly without having to know how to parse .la files.
_gi.so: _gi.la
rm -f $@ && $(LN_S) .libs/$@ $@
+_gi_cairo.so: _gi_cairo.la
+ rm -f $@ && $(LN_S) .libs/$@ $@
-all-local: _gi.so
-check-local: _gi.so
+all-local: _gi.so _gi_cairo.so
+check-local: _gi.so _gi_cairo.so
clean-local:
- rm -f _gi.so
+ rm -f _gi.so _gi_cairo.so
diff --git a/gi/gimodule.c b/gi/gimodule.c
index 1a81abc..df0db7a 100644
--- a/gi/gimodule.c
+++ b/gi/gimodule.c
@@ -26,9 +26,6 @@
#include <pygobject.h>
-# include <pycairo.h>
-Pycairo_CAPI_t *Pycairo_CAPI;
-
static PyObject *
_wrap_pyg_enum_add (PyObject *self,
PyObject *args,
@@ -244,6 +241,7 @@ static PyMethodDef _pygi_functions[] = {
static struct PyGI_API CAPI = {
pygi_type_import_by_g_type_real,
+ pygi_register_foreign_struct_real,
};
PyMODINIT_FUNC
@@ -265,10 +263,6 @@ init_gi (void)
return;
}
- Pycairo_IMPORT;
- if (Pycairo_CAPI == NULL)
- return;
-
_pygi_repository_register_types (m);
_pygi_info_register_types (m);
_pygi_struct_register_types (m);
diff --git a/gi/pygi-argument.c b/gi/pygi-argument.c
index 7437175..c6df559 100644
--- a/gi/pygi-argument.c
+++ b/gi/pygi-argument.c
@@ -962,15 +962,9 @@ array_item_error:
arg.v_pointer = g_boxed_copy (type, arg.v_pointer);
}
} else if ( (type == G_TYPE_NONE) && (g_struct_info_is_foreign (info))) {
- gint retval;
-
- retval = pygi_struct_foreign_convert_to_g_argument (
+ PyObject *result;
+ result = pygi_struct_foreign_convert_to_g_argument (
object, type_info, transfer, &arg);
-
- if (!retval) {
- PyErr_SetString (PyExc_RuntimeError, "PyObject conversion to foreign struct failed");
- break;
- }
} else if (g_type_is_a (type, G_TYPE_POINTER) || type == G_TYPE_NONE) {
g_warn_if_fail (!g_type_info_is_pointer (type_info) || transfer == GI_TRANSFER_NOTHING);
arg.v_pointer = pyg_pointer_get (object, void);
diff --git a/gi/pygi-foreign-cairo.c b/gi/pygi-foreign-cairo.c
index 7ec71c1..08d50ad 100644
--- a/gi/pygi-foreign-cairo.c
+++ b/gi/pygi-foreign-cairo.c
@@ -23,12 +23,11 @@
#include <cairo.h>
#include <pycairo.h>
-extern Pycairo_CAPI_t *Pycairo_CAPI;
+Pycairo_CAPI_t *Pycairo_CAPI;
#include "pygi-foreign.h"
-#include "pygi-foreign-cairo.h"
-gboolean
+PyObject *
cairo_context_to_arg (PyObject *value,
GITypeInfo *type_info,
GITransfer transfer,
@@ -39,11 +38,12 @@ cairo_context_to_arg (PyObject *value,
g_assert (transfer == GI_TRANSFER_NOTHING);
cr = PycairoContext_GET (value);
- if (!cr)
- return FALSE;
+ if (!cr) {
+ return NULL;
+ }
arg->v_pointer = cr;
- return TRUE;
+ Py_RETURN_NONE;
}
PyObject *
@@ -56,16 +56,16 @@ cairo_context_from_arg (GITypeInfo *type_info, GArgument *arg)
return PycairoContext_FromContext (context, &PycairoContext_Type, NULL);
}
-gboolean
+PyObject *
cairo_context_release_arg (GITransfer transfer, GITypeInfo *type_info,
GArgument *arg)
{
cairo_destroy ( (cairo_t*) arg->v_pointer);
- return TRUE;
+ Py_RETURN_NONE;
}
-gboolean
+PyObject *
cairo_surface_to_arg (PyObject *value,
GITypeInfo *type_info,
GITransfer transfer,
@@ -76,11 +76,13 @@ cairo_surface_to_arg (PyObject *value,
g_assert (transfer == GI_TRANSFER_NOTHING);
surface = ( (PycairoSurface*) value)->surface;
- if (!surface)
- return FALSE;
+ if (!surface) {
+ PyErr_SetString (PyExc_ValueError, "Surface instance wrapping a NULL surface");
+ return NULL;
+ }
arg->v_pointer = surface;
- return TRUE;
+ Py_RETURN_NONE;
}
PyObject *
@@ -93,11 +95,37 @@ cairo_surface_from_arg (GITypeInfo *type_info, GArgument *arg)
return PycairoSurface_FromSurface (surface, NULL);
}
-gboolean
+PyObject *
cairo_surface_release_arg (GITransfer transfer, GITypeInfo *type_info,
GArgument *arg)
{
cairo_surface_destroy ( (cairo_surface_t*) arg->v_pointer);
- return TRUE;
+ Py_RETURN_NONE;
}
+PyMODINIT_FUNC
+init_gi_cairo (void)
+{
+ PyObject *m;
+
+ m = Py_InitModule ("_gi_cairo", NULL);
+ if (m == NULL) {
+ return;
+ }
+
+ Pycairo_IMPORT;
+ if (Pycairo_CAPI == NULL)
+ return;
+
+ pygi_register_foreign_struct ("cairo",
+ "Context",
+ cairo_context_to_arg,
+ cairo_context_from_arg,
+ cairo_context_release_arg);
+
+ pygi_register_foreign_struct ("cairo",
+ "Surface",
+ cairo_surface_to_arg,
+ cairo_surface_from_arg,
+ cairo_surface_release_arg);
+}
diff --git a/gi/pygi-foreign.c b/gi/pygi-foreign.c
index d2613df..13a0f77 100644
--- a/gi/pygi-foreign.c
+++ b/gi/pygi-foreign.c
@@ -27,99 +27,122 @@
#include <config.h>
#include <girepository.h>
-#include "pygi-foreign-cairo.h"
-
-static struct {
- char *namespace;
- char *name;
+typedef struct {
+ const char *namespace;
+ const char *name;
PyGIArgOverrideToGArgumentFunc to_func;
PyGIArgOverrideFromGArgumentFunc from_func;
PyGIArgOverrideReleaseGArgumentFunc release_func;
-} foreign_structs[] = {
- { "cairo", "Context", cairo_context_to_arg, cairo_context_from_arg,
- cairo_context_release_arg
- },
- { "cairo", "Surface", cairo_surface_to_arg, cairo_surface_from_arg,
- cairo_surface_release_arg
- },
- { NULL }
-};
-
-static gint
+} PyGIForeignStruct;
+
+static GPtrArray *foreign_structs = NULL;
+
+static PyGIForeignStruct *
pygi_struct_foreign_lookup (GITypeInfo *type_info)
{
+ gint i;
+ PyObject *module;
+ gchar *module_name;
GIBaseInfo *base_info;
+ const gchar *namespace;
+ const gchar *name;
base_info = g_type_info_get_interface (type_info);
- if (base_info) {
- gint i;
- const gchar *namespace = g_base_info_get_namespace (base_info);
- const gchar *name = g_base_info_get_name (base_info);
+ if (base_info == NULL) {
+ PyErr_Format (PyExc_ValueError, "Couldn't resolve the type of this foreign struct");
+ return NULL;
+ }
- for (i = 0; foreign_structs[i].namespace; ++i) {
+ namespace = g_base_info_get_namespace (base_info);
+ name = g_base_info_get_name (base_info);
- if ( (strcmp (namespace, foreign_structs[i].namespace) == 0) &&
- (strcmp (name, foreign_structs[i].name) == 0)) {
+ module_name = g_strconcat ("gi._gi_", g_base_info_get_namespace (base_info), NULL);
+ module = PyImport_ImportModule (module_name);
+ g_free (module_name);
+
+ if (foreign_structs != NULL) {
+ for (i = 0; i < foreign_structs->len; i++) {
+ PyGIForeignStruct *foreign_struct = \
+ g_ptr_array_index (foreign_structs, i);
+
+ if ( (strcmp (namespace, foreign_struct->namespace) == 0) &&
+ (strcmp (name, foreign_struct->name) == 0)) {
g_base_info_unref (base_info);
- return i;
+ return foreign_struct;
}
}
+ }
- PyErr_Format (PyExc_TypeError, "Couldn't find type %s.%s", namespace,
- name);
+ g_base_info_unref (base_info);
- g_base_info_unref (base_info);
- }
- return -1;
+ PyErr_Format (PyExc_TypeError, "Couldn't find conversion for foreign struct '%s.%s'", namespace, name);
+ return NULL;
}
-gboolean
+PyObject *
pygi_struct_foreign_convert_to_g_argument (PyObject *value,
GITypeInfo *type_info,
GITransfer transfer,
GArgument *arg)
{
- gint struct_index;
+ PyGIForeignStruct *foreign_struct = pygi_struct_foreign_lookup (type_info);
- struct_index = pygi_struct_foreign_lookup (type_info);
- if (struct_index < 0)
- return FALSE;
+ if (foreign_struct == NULL)
+ return NULL;
- if (!foreign_structs[struct_index].to_func (value, type_info, transfer, arg))
- return FALSE;
+ if (!foreign_struct->to_func (value, type_info, transfer, arg))
+ return NULL;
- return TRUE;
+ Py_RETURN_NONE;
}
PyObject *
pygi_struct_foreign_convert_from_g_argument (GITypeInfo *type_info,
GArgument *arg)
{
- gint struct_index;
+ PyGIForeignStruct *foreign_struct = pygi_struct_foreign_lookup (type_info);
- struct_index = pygi_struct_foreign_lookup (type_info);
- if (struct_index < 0)
+ if (foreign_struct == NULL)
return NULL;
- return foreign_structs[struct_index].from_func (type_info, arg);
+ return foreign_struct->from_func (type_info, arg);
}
-gboolean
+PyObject *
pygi_struct_foreign_release_g_argument (GITransfer transfer,
GITypeInfo *type_info,
GArgument *arg)
{
- gint struct_index;
+ PyGIForeignStruct *foreign_struct = pygi_struct_foreign_lookup (type_info);
+
+ if (foreign_struct == NULL)
+ return NULL;
- struct_index = pygi_struct_foreign_lookup (type_info);
- if (struct_index < 0)
- return FALSE;
+ if (!foreign_struct->release_func)
+ Py_RETURN_NONE;
- if (!foreign_structs[struct_index].release_func)
- return TRUE;
+ if (!foreign_struct->release_func (transfer, type_info, arg))
+ return NULL;
+
+ Py_RETURN_NONE;
+}
+
+void
+pygi_register_foreign_struct_real (const char* namespace_,
+ const char* name,
+ PyGIArgOverrideToGArgumentFunc to_func,
+ PyGIArgOverrideFromGArgumentFunc from_func,
+ PyGIArgOverrideReleaseGArgumentFunc release_func)
+{
+ PyGIForeignStruct *new_struct = g_slice_new0 (PyGIForeignStruct);
+ new_struct->namespace = namespace_;
+ new_struct->name = name;
+ new_struct->to_func = to_func;
+ new_struct->from_func = from_func;
+ new_struct->release_func = release_func;
- if (!foreign_structs[struct_index].release_func (transfer, type_info, arg))
- return FALSE;
+ if (foreign_structs == NULL)
+ foreign_structs = g_ptr_array_new ();
- return TRUE;
+ g_ptr_array_add (foreign_structs, new_struct);
}
diff --git a/gi/pygi-foreign.h b/gi/pygi-foreign.h
index 7962b49..9a35bd8 100644
--- a/gi/pygi-foreign.h
+++ b/gi/pygi-foreign.h
@@ -28,25 +28,22 @@
#include <Python.h>
#include <girepository.h>
-typedef gboolean (*PyGIArgOverrideToGArgumentFunc) (PyObject *value,
- GITypeInfo *type_info,
- GITransfer transfer,
- GArgument *arg);
+#include "pygi.h"
-typedef PyObject * (*PyGIArgOverrideFromGArgumentFunc) (GITypeInfo *type_info,
- GArgument *arg);
-typedef gboolean (*PyGIArgOverrideReleaseGArgumentFunc) (GITransfer transfer,
- GITypeInfo *type_info,
- GArgument *arg);
-
-gboolean pygi_struct_foreign_convert_to_g_argument (PyObject *value,
- GITypeInfo *type_info,
- GITransfer transfer,
- GArgument *arg);
+PyObject *pygi_struct_foreign_convert_to_g_argument (PyObject *value,
+ GITypeInfo *type_info,
+ GITransfer transfer,
+ GArgument *arg);
PyObject *pygi_struct_foreign_convert_from_g_argument (GITypeInfo *type_info,
GArgument *arg);
-gboolean pygi_struct_foreign_release_g_argument (GITransfer transfer,
- GITypeInfo *type_info,
- GArgument *arg);
+PyObject *pygi_struct_foreign_release_g_argument (GITransfer transfer,
+ GITypeInfo *type_info,
+ GArgument *arg);
+
+void pygi_register_foreign_struct_real (const char* namespace_,
+ const char* name,
+ PyGIArgOverrideToGArgumentFunc to_func,
+ PyGIArgOverrideFromGArgumentFunc from_func,
+ PyGIArgOverrideReleaseGArgumentFunc release_func);
#endif /* __PYGI_FOREIGN_H__ */
diff --git a/gi/pygi.h b/gi/pygi.h
index 667fa70..0a8cbf5 100644
--- a/gi/pygi.h
+++ b/gi/pygi.h
@@ -51,9 +51,23 @@ typedef struct {
gsize size;
} PyGIBoxed;
+typedef PyObject * (*PyGIArgOverrideToGArgumentFunc) (PyObject *value,
+ GITypeInfo *type_info,
+ GITransfer transfer,
+ GArgument *arg);
+typedef PyObject * (*PyGIArgOverrideFromGArgumentFunc) (GITypeInfo *type_info,
+ GArgument *arg);
+typedef PyObject * (*PyGIArgOverrideReleaseGArgumentFunc) (GITransfer transfer,
+ GITypeInfo *type_info,
+ GArgument *arg);
struct PyGI_API {
PyObject* (*type_import_by_g_type) (GType g_type);
+ void (*register_foreign_struct) (const char* namespace_,
+ const char* name,
+ PyGIArgOverrideToGArgumentFunc to_func,
+ PyGIArgOverrideFromGArgumentFunc from_func,
+ PyGIArgOverrideReleaseGArgumentFunc release_func);
};
static struct PyGI_API *PyGI_API = NULL;
@@ -76,10 +90,28 @@ _pygi_import (void)
static inline PyObject *
pygi_type_import_by_g_type (GType g_type)
{
- if (_pygi_import() < 0) {
- return NULL;
- }
- return PyGI_API->type_import_by_g_type(g_type);
+ if (_pygi_import() < 0) {
+ return NULL;
+ }
+ return PyGI_API->type_import_by_g_type(g_type);
+}
+
+static inline PyObject *
+pygi_register_foreign_struct (const char* namespace_,
+ const char* name,
+ PyGIArgOverrideToGArgumentFunc to_func,
+ PyGIArgOverrideFromGArgumentFunc from_func,
+ PyGIArgOverrideReleaseGArgumentFunc release_func)
+{
+ if (_pygi_import() < 0) {
+ return NULL;
+ }
+ PyGI_API->register_foreign_struct(namespace_,
+ name,
+ to_func,
+ from_func,
+ release_func);
+ Py_RETURN_NONE;
}
#else /* ENABLE_INTROSPECTION */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]