Commit 89827314 authored by Tomeu Vizoso's avatar Tomeu Vizoso

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
parent a6a90551
......@@ -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
......
......@@ -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
......@@ -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);
......
......@@ -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);
......
......@@ -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);
}
/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
/*
* Copyright (c) 2010 Collabora Ltd. <http://www.collabora.co.uk/>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#ifndef __PYGI_FOREIGN_CAIRO_H__
#define __PYGI_FOREIGN_CAIRO_H__
#include "pygi-foreign.h"
gboolean cairo_context_to_arg (PyObject *value,
GITypeInfo *type_info,
GITransfer transfer,
GArgument *arg);
PyObject *cairo_context_from_arg (GITypeInfo *type_info,
GArgument *arg);
gboolean cairo_context_release_arg (GITransfer transfer,
GITypeInfo *type_info,
GArgument *arg);
gboolean cairo_surface_to_arg (PyObject *value,
GITypeInfo *type_info,
GITransfer transfer,
GArgument *arg);
PyObject *cairo_surface_from_arg (GITypeInfo *type_info,
GArgument *arg);
gboolean cairo_surface_release_arg (GITransfer transfer,
GITypeInfo *type_info,
GArgument *arg);
#endif /* __PYGI_FOREIGN_CAIRO_H__ */
......@@ -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);
}
......@@ -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__ */
......@@ -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 */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment