summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon van der Linden <svdlinden@src.gnome.org>2009-11-08 12:35:08 +0100
committerSimon van der Linden <svdlinden@src.gnome.org>2009-11-08 13:02:56 +0100
commitb24fd9633cabe1d95cde173a04e9a49833b06a26 (patch)
treed78195fc9dc55c4b59aecd7a7d992aaf10ead558
downloadpygi-b24fd9633cabe1d95cde173a04e9a49833b06a26.tar.gz
pygi-b24fd9633cabe1d95cde173a04e9a49833b06a26.tar.xz
pygi-b24fd9633cabe1d95cde173a04e9a49833b06a26.zip
Initial import
-rw-r--r--.gitignore33
-rw-r--r--Makefile.am10
-rwxr-xr-xautogen.sh159
-rw-r--r--configure.ac53
-rw-r--r--gi/Makefile.am50
-rw-r--r--gi/__init__.py24
-rw-r--r--gi/gimodule.c144
-rw-r--r--gi/importer.py89
-rw-r--r--gi/module.py167
-rw-r--r--gi/overrides/Gdk.py21
-rw-r--r--gi/overrides/Gtk.py13
-rw-r--r--gi/overrides/Makefile.am10
-rw-r--r--gi/overrides/__init__.py0
-rw-r--r--gi/pygi-argument.c1976
-rw-r--r--gi/pygi-argument.h65
-rw-r--r--gi/pygi-info.c2093
-rw-r--r--gi/pygi-info.h64
-rw-r--r--gi/pygi-private.h55
-rw-r--r--gi/pygi-repository.c238
-rw-r--r--gi/pygi-repository.h39
-rw-r--r--gi/pygi-struct.c175
-rw-r--r--gi/pygi-struct.h40
-rw-r--r--gi/pygi-type.c96
-rw-r--r--gi/pygi-type.h43
-rw-r--r--gi/pygi.h99
-rw-r--r--gi/pygobject-external.h83
-rw-r--r--gi/repository/Makefile.am8
-rw-r--r--gi/repository/__init__.py30
-rw-r--r--gi/types.py163
-rw-r--r--tests/Makefile.am48
-rw-r--r--tests/libtestgi.c3397
-rw-r--r--tests/libtestgi.h643
-rw-r--r--tests/runtests.py22
-rw-r--r--tests/test_gi.py1416
34 files changed, 11566 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..0d0d862
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,33 @@
+.libs/
+.deps/
+/COPYING
+Makefile
+Makefile.in
+/aclocal.m4
+/autom4te.cache/
+/config.guess
+/config.h
+/config.h.in
+/config.log
+/config.status
+/config.sub
+/configure
+/depcomp
+/install-sh
+/libtool
+/ltmain.sh
+/m4/
+/missing
+/py-compile
+/pygi-*.tar.gz
+/stamp-h1
+
+*.o
+*.lo
+*.la
+*.so
+*.pyc
+*.gir
+*.typelib
+
+.*.swp
diff --git a/Makefile.am b/Makefile.am
new file mode 100644
index 0000000..cbe9000
--- /dev/null
+++ b/Makefile.am
@@ -0,0 +1,10 @@
+ACLOCAL_AMFLAGS = -I m4
+
+AM_CFLAGS = \
+ -Wall \
+ -g
+
+SUBDIRS = \
+ gi \
+ tests
+
diff --git a/autogen.sh b/autogen.sh
new file mode 100755
index 0000000..955b538
--- /dev/null
+++ b/autogen.sh
@@ -0,0 +1,159 @@
+#!/bin/sh
+# Run this to generate all the initial makefiles, etc.
+
+srcdir=`dirname $0`
+test -z "$srcdir" && srcdir=.
+
+DIE=0
+
+if [ -n "$GNOME2_DIR" ]; then
+ ACLOCAL_FLAGS="-I $GNOME2_DIR/share/aclocal $ACLOCAL_FLAGS"
+ LD_LIBRARY_PATH="$GNOME2_DIR/lib:$LD_LIBRARY_PATH"
+ PATH="$GNOME2_DIR/bin:$PATH"
+ export PATH
+ export LD_LIBRARY_PATH
+fi
+
+(test -f $srcdir/configure.ac) || {
+ echo -n "**Error**: Directory "\`$srcdir\'" does not look like the"
+ echo " top-level package directory"
+ exit 1
+}
+
+(autoconf --version) < /dev/null > /dev/null 2>&1 || {
+ echo
+ echo "**Error**: You must have \`autoconf' installed."
+ echo "Download the appropriate package for your distribution,"
+ echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/"
+ DIE=1
+}
+
+(grep "^IT_PROG_INTLTOOL" $srcdir/configure.ac >/dev/null) && {
+ (intltoolize --version) < /dev/null > /dev/null 2>&1 || {
+ echo
+ echo "**Error**: You must have \`intltool' installed."
+ echo "You can get it from:"
+ echo " ftp://ftp.gnome.org/pub/GNOME/"
+ DIE=1
+ }
+}
+
+(grep "^AM_PROG_XML_I18N_TOOLS" $srcdir/configure.ac >/dev/null) && {
+ (xml-i18n-toolize --version) < /dev/null > /dev/null 2>&1 || {
+ echo
+ echo "**Error**: You must have \`xml-i18n-toolize' installed."
+ echo "You can get it from:"
+ echo " ftp://ftp.gnome.org/pub/GNOME/"
+ DIE=1
+ }
+}
+
+(grep "^AM_PROG_LIBTOOL" $srcdir/configure.ac >/dev/null) && {
+ (libtool --version) < /dev/null > /dev/null 2>&1 || {
+ echo
+ echo "**Error**: You must have \`libtool' installed."
+ echo "You can get it from: ftp://ftp.gnu.org/pub/gnu/"
+ DIE=1
+ }
+}
+
+(grep "^AM_GLIB_GNU_GETTEXT" $srcdir/configure.ac >/dev/null) && {
+ (grep "sed.*POTFILES" $srcdir/configure.ac) > /dev/null || \
+ (glib-gettextize --version) < /dev/null > /dev/null 2>&1 || {
+ echo
+ echo "**Error**: You must have \`glib' installed."
+ echo "You can get it from: ftp://ftp.gtk.org/pub/gtk"
+ DIE=1
+ }
+}
+
+(automake --version) < /dev/null > /dev/null 2>&1 || {
+ echo
+ echo "**Error**: You must have \`automake' installed."
+ echo "You can get it from: ftp://ftp.gnu.org/pub/gnu/"
+ DIE=1
+ NO_AUTOMAKE=yes
+}
+
+
+# if no automake, don't bother testing for aclocal
+test -n "$NO_AUTOMAKE" || (aclocal --version) < /dev/null > /dev/null 2>&1 || {
+ echo
+ echo "**Error**: Missing \`aclocal'. The version of \`automake'"
+ echo "installed doesn't appear recent enough."
+ echo "You can get automake from ftp://ftp.gnu.org/pub/gnu/"
+ DIE=1
+}
+
+if test "$DIE" -eq 1; then
+ exit 1
+fi
+
+if test -z "$*"; then
+ echo "**Warning**: I am going to run \`configure' with no arguments."
+ echo "If you wish to pass any to it, please specify them on the"
+ echo \`$0\'" command line."
+ echo
+fi
+
+case $CC in
+xlc )
+ am_opt=--include-deps;;
+esac
+
+for coin in `find $srcdir -path $srcdir/CVS -prune -o -name configure.ac -print`
+do
+ dr=`dirname $coin`
+ if test -f $dr/NO-AUTO-GEN; then
+ echo skipping $dr -- flagged as no auto-gen
+ else
+ echo processing $dr
+ ( cd $dr
+
+ aclocalinclude="$ACLOCAL_FLAGS"
+
+ if grep "^AM_GLIB_GNU_GETTEXT" configure.ac >/dev/null; then
+ echo "Creating $dr/aclocal.m4 ..."
+ test -r $dr/aclocal.m4 || touch $dr/aclocal.m4
+ echo "Running glib-gettextize... Ignore non-fatal messages."
+ echo "no" | glib-gettextize --force --copy
+ echo "Making $dr/aclocal.m4 writable ..."
+ test -r $dr/aclocal.m4 && chmod u+w $dr/aclocal.m4
+ fi
+ if grep "^IT_PROG_INTLTOOL" configure.ac >/dev/null; then
+ echo "Running intltoolize..."
+ intltoolize --copy --force --automake
+ fi
+ if grep "^AM_PROG_XML_I18N_TOOLS" configure.ac >/dev/null; then
+ echo "Running xml-i18n-toolize..."
+ xml-i18n-toolize --copy --force --automake
+ fi
+ if grep "^AM_PROG_LIBTOOL" configure.ac >/dev/null; then
+ if test -z "$NO_LIBTOOLIZE" ; then
+ echo "Running libtoolize..."
+ libtoolize --force --copy
+ fi
+ fi
+ echo "Running aclocal $aclocalinclude ..."
+ aclocal $aclocalinclude
+ if grep "^A[CM]_CONFIG_HEADER" configure.ac >/dev/null; then
+ echo "Running autoheader..."
+ autoheader
+ fi
+ echo "Running automake --foreign $am_opt ..."
+ automake --add-missing --foreign $am_opt
+ echo "Running autoconf ..."
+ autoconf
+ )
+ fi
+done
+
+conf_flags="--enable-maintainer-mode"
+
+if test x$NOCONFIGURE = x; then
+ echo Running $srcdir/configure $conf_flags "$@" ...
+ $srcdir/configure $conf_flags "$@" \
+ && echo Now type \`make\' to compile. || exit 1
+else
+ echo Skipping configure process.
+fi
diff --git a/configure.ac b/configure.ac
new file mode 100644
index 0000000..a14eb59
--- /dev/null
+++ b/configure.ac
@@ -0,0 +1,53 @@
+AC_INIT(pygi, 0.1)
+
+AM_INIT_AUTOMAKE(foreign)
+AC_CONFIG_HEADERS(config.h)
+AC_CONFIG_MACRO_DIR(m4)
+
+m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES])
+
+AM_MAINTAINER_MODE
+
+AC_ISC_POSIX
+AC_PROG_CC
+AM_PROG_CC_STDC
+AC_HEADER_STDC
+
+AM_PROG_LIBTOOL
+
+# Python
+AM_PATH_PYTHON(2.5.2)
+
+AC_PATH_TOOL(PYTHON_CONFIG, "/python${PYTHON_VERSION}-config")
+if test -z "$PYTHON_CONFIG"; then
+ AC_MSG_ERROR(Python development tools not found)
+fi
+PYTHON_INCLUDES=`$PYTHON_CONFIG --includes`
+AC_SUBST(PYTHON_INCLUDES)
+
+save_CPPFLAGS="${CPPFLAGS}"
+CPPFLAGS+="${PYTHON_INCLUDES}"
+AC_CHECK_HEADER(Python.h, , AC_MSG_ERROR(Python headers not found))
+CPPFLAGS="${save_CPPFLAGS}"
+
+
+# GNOME
+PKG_CHECK_MODULES(GNOME,
+ glib-2.0 >= 2.22
+ gobject-introspection-1.0 >= 0.6.4
+ pygobject-2.0 >= 2.20
+)
+
+INTROSPECTION_SCANNER=`$PKG_CONFIG --variable=g_ir_scanner gobject-introspection-1.0`
+INTROSPECTION_COMPILER=`$PKG_CONFIG --variable=g_ir_compiler gobject-introspection-1.0`
+
+AC_SUBST(INTROSPECTION_SCANNER)
+AC_SUBST(INTROSPECTION_COMPILER)
+
+AC_OUTPUT(
+ Makefile
+ gi/Makefile
+ gi/repository/Makefile
+ gi/overrides/Makefile
+ tests/Makefile
+)
diff --git a/gi/Makefile.am b/gi/Makefile.am
new file mode 100644
index 0000000..2657d3f
--- /dev/null
+++ b/gi/Makefile.am
@@ -0,0 +1,50 @@
+PLATFORM_VERSION = 2.0
+
+pkgincludedir = $(includedir)/pygtk-$(PLATFORM_VERSION)
+pkgpyexecdir = $(pyexecdir)/gtk-2.0
+
+SUBDIRS = \
+ repository \
+ overrides
+
+pygidir = $(pkgpyexecdir)/gi
+pygi_PYTHON = \
+ types.py \
+ module.py \
+ importer.py \
+ __init__.py
+
+_gi_la_CFLAGS = \
+ $(PYTHON_INCLUDES) \
+ $(GNOME_CFLAGS)
+_gi_la_LDFLAGS = \
+ -module \
+ -avoid-version \
+ -export-symbols-regex init_gi
+_gi_la_LIBADD = \
+ $(GNOME_LIBS)
+_gi_la_SOURCES = \
+ pygi-repository.c \
+ pygi-repository.h \
+ pygi-info.c \
+ pygi-info.h \
+ pygi-struct.c \
+ pygi-struct.h \
+ pygi-argument.c \
+ pygi-argument.h \
+ pygi-type.c \
+ pygi-type.h \
+ pygi.h \
+ pygi-private.h \
+ pygobject-external.h \
+ gimodule.c
+
+pygi_LTLIBRARIES = _gi.la
+
+.la.so:
+ $(LN_S) .libs/$@ $@ || true
+
+all: $(pygi_LTLIBRARIES:.la=.so)
+clean-local:
+ rm -f $(pygi_LTLIBRARIES:.la=.so)
+
diff --git a/gi/__init__.py b/gi/__init__.py
new file mode 100644
index 0000000..3edea9f
--- /dev/null
+++ b/gi/__init__.py
@@ -0,0 +1,24 @@
+# -*- Mode: Python; py-indent-offset: 4 -*-
+# vim: tabstop=4 shiftwidth=4 expandtab
+#
+# Copyright (C) 2005-2009 Johan Dahlin <johan@gnome.org>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+# USA
+
+from __future__ import absolute_import
+
+from ._gi import _API
+
diff --git a/gi/gimodule.c b/gi/gimodule.c
new file mode 100644
index 0000000..d9ee17b
--- /dev/null
+++ b/gi/gimodule.c
@@ -0,0 +1,144 @@
+/* -*- Mode: C; c-basic-offset: 4 -*-
+ * vim: tabstop=4 shiftwidth=4 expandtab
+ *
+ * Copyright (C) 2005-2009 Johan Dahlin <johan@gnome.org>
+ *
+ * gimodule.c: wrapper for the gobject-introspection library.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+ * USA
+ */
+
+#include "pygi-private.h"
+
+#include <pygobject.h>
+
+static PyObject *
+_wrap_pyg_enum_add (PyObject *self,
+ PyObject *args,
+ PyObject *kwargs)
+{
+ static char *kwlist[] = { "g_type", NULL };
+ PyObject *py_g_type;
+ GType g_type;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs,
+ "O!:enum_add",
+ kwlist, &PyGTypeWrapper_Type, &py_g_type)) {
+ return NULL;
+ }
+
+ g_type = pyg_type_from_object(py_g_type);
+ if (g_type == G_TYPE_INVALID) {
+ return NULL;
+ }
+
+ return pyg_enum_add(NULL, g_type_name(g_type), NULL, g_type);
+}
+
+static PyObject *
+_wrap_pyg_flags_add (PyObject *self,
+ PyObject *args,
+ PyObject *kwargs)
+{
+ static char *kwlist[] = { "g_type", NULL };
+ PyObject *py_g_type;
+ GType g_type;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs,
+ "O!:flags_add",
+ kwlist, &PyGTypeWrapper_Type, &py_g_type)) {
+ return NULL;
+ }
+
+ g_type = pyg_type_from_object(py_g_type);
+ if (g_type == G_TYPE_INVALID) {
+ return NULL;
+ }
+
+ return pyg_flags_add(NULL, g_type_name(g_type), NULL, g_type);
+}
+
+static PyObject *
+_wrap_pyg_set_object_has_new_constructor (PyObject *self,
+ PyObject *args,
+ PyObject *kwargs)
+{
+ static char *kwlist[] = { "g_type", NULL };
+ PyObject *py_g_type;
+ GType g_type;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs,
+ "O!:set_object_has_new_constructor",
+ kwlist, &PyGTypeWrapper_Type, &py_g_type)) {
+ return NULL;
+ }
+
+ g_type = pyg_type_from_object(py_g_type);
+ if (!g_type_is_a(g_type, G_TYPE_OBJECT)) {
+ PyErr_SetString(PyExc_TypeError, "must be a subtype of GObject");
+ return NULL;
+ }
+
+ pyg_set_object_has_new_constructor(g_type);
+
+ Py_RETURN_NONE;
+}
+
+
+static PyMethodDef _pygi_functions[] = {
+ { "enum_add", (PyCFunction)_wrap_pyg_enum_add, METH_VARARGS | METH_KEYWORDS },
+ { "flags_add", (PyCFunction)_wrap_pyg_flags_add, METH_VARARGS | METH_KEYWORDS },
+
+ { "set_object_has_new_constructor", (PyCFunction)_wrap_pyg_set_object_has_new_constructor, METH_VARARGS | METH_KEYWORDS },
+ { NULL, NULL, 0 }
+};
+
+struct PyGI_API PyGI_API = {
+ pygi_type_import_by_g_type
+};
+
+
+PyMODINIT_FUNC
+init_gi(void)
+{
+ PyObject *m;
+ PyObject *api;
+
+ m = Py_InitModule("_gi", _pygi_functions);
+ if (m == NULL) {
+ return;
+ }
+
+ if (pygobject_init(-1, -1, -1) == NULL) {
+ return;
+ }
+
+ if (_pygobject_import() < 0) {
+ return;
+ }
+
+ _pygi_repository_register_types(m);
+ _pygi_info_register_types(m);
+ _pygi_struct_register_types(m);
+ _pygi_argument_init();
+
+ api = PyCObject_FromVoidPtr((void *)&PyGI_API, NULL);
+ if (api == NULL) {
+ return;
+ }
+ PyModule_AddObject(m, "_API", api);
+}
+
diff --git a/gi/importer.py b/gi/importer.py
new file mode 100644
index 0000000..48392b4
--- /dev/null
+++ b/gi/importer.py
@@ -0,0 +1,89 @@
+# -*- Mode: Python; py-indent-offset: 4 -*-
+# vim: tabstop=4 shiftwidth=4 expandtab
+#
+# Copyright (C) 2005-2009 Johan Dahlin <johan@gnome.org>
+#
+# importer.py: dynamic importer for introspected libraries.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+# USA
+
+from __future__ import absolute_import
+
+import sys
+import gobject
+
+from ._gi import Repository, RepositoryError
+from .module import DynamicModule
+
+
+repository = Repository.get_default()
+
+
+class DynamicImporter(object):
+
+ # Note: see PEP302 for the Importer Protocol implemented below.
+
+ def __init__(self, path):
+ self.path = path
+
+ def find_module(self, fullname, path=None):
+ if not fullname.startswith(self.path):
+ return
+
+ path, namespace = fullname.rsplit('.', 1)
+ if path != self.path:
+ return
+ try:
+ repository.require(namespace)
+ except RepositoryError:
+ pass
+ else:
+ return self
+
+ def load_module(self, fullname):
+ if fullname in sys.modules:
+ return sys.modules[name]
+
+ path, namespace = fullname.rsplit('.', 1)
+
+ # Workaround for GObject
+ if namespace == 'GObject':
+ sys.modules[fullname] = gobject
+ return gobject
+
+ # Look for an overrides module
+ overrides_name = 'gi.overrides.%s' % namespace
+ try:
+ overrides_type_name = '%sModule' % namespace
+ overrides_module = __import__(overrides_name, fromlist=[overrides_type_name])
+ module_type = getattr(overrides_module, overrides_type_name)
+ except ImportError, e:
+ module_type = DynamicModule
+
+ module = module_type.__new__(module_type)
+ module.__dict__ = {
+ '__file__': '<%s>' % fullname,
+ '__name__': fullname,
+ '__namespace__': namespace,
+ '__loader__': self
+ }
+
+ sys.modules[fullname] = module
+
+ module.__init__()
+
+ return module
+
diff --git a/gi/module.py b/gi/module.py
new file mode 100644
index 0000000..1a54971
--- /dev/null
+++ b/gi/module.py
@@ -0,0 +1,167 @@
+# -*- Mode: Python; py-indent-offset: 4 -*-
+# vim: tabstop=4 shiftwidth=4 expandtab
+#
+# Copyright (C) 2007-2009 Johan Dahlin <johan@gnome.org>
+#
+# module.py: dynamic module for introspected libraries.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+# USA
+
+from __future__ import absolute_import
+
+import os
+import gobject
+
+from ._gi import \
+ Repository, \
+ FunctionInfo, \
+ RegisteredTypeInfo, \
+ EnumInfo, \
+ ObjectInfo, \
+ InterfaceInfo, \
+ ConstantInfo, \
+ StructInfo, \
+ Struct, \
+ enum_add, \
+ flags_add
+from .types import \
+ GObjectMeta, \
+ StructMeta, \
+ Boxed, \
+ Function
+
+repository = Repository.get_default()
+
+
+def get_parent_for_object(object_info):
+ parent_object_info = object_info.get_parent()
+
+ if not parent_object_info:
+ return object
+
+ namespace = parent_object_info.get_namespace()
+ name = parent_object_info.get_name()
+
+ # Workaround for GObject.Object and GObject.InitiallyUnowned.
+ if namespace == 'GObject' and name == 'Object' or name == 'InitiallyUnowned':
+ return gobject.GObject
+
+ module = __import__('gi.repository.%s' % namespace, fromlist=[name])
+ return getattr(module, name)
+
+def get_interfaces_for_object(object_info):
+ interfaces = []
+ for interface_info in object_info.get_interfaces():
+ namespace = interface_info.get_namespace()
+ name = interface_info.get_name()
+
+ module = __import__('gi.repository.%s' % namespace, fromlist=[name])
+ interfaces.append(getattr(module, name))
+ return interfaces
+
+
+class DynamicModule(object):
+
+ def __str__(self):
+ path = repository.get_typelib_path(self.__namespace__)
+ return "<dynamic module %r from %r>" % (self.__name__, path)
+
+ def __getattr__(self, name):
+ if self.__dict__.has_key(name):
+ return self.__dict__[name]
+
+ info = repository.find_by_name(self.__namespace__, name)
+ if not info:
+ raise AttributeError("%r object has no attribute %r" % (
+ self.__class__.__name__, name))
+
+ if isinstance(info, EnumInfo):
+ g_type = info.get_g_type()
+ value = g_type.pytype
+
+ if value is None:
+ if g_type.is_a(gobject.TYPE_ENUM):
+ value = enum_add(g_type)
+ else:
+ value = flags_add(g_type)
+
+ value.__info__ = info
+ value.__module__ = info.get_namespace()
+
+ for value_info in info.get_values():
+ name = value_info.get_name().upper()
+ setattr(value, name, value(value_info.get_value()))
+
+ elif isinstance(info, RegisteredTypeInfo):
+ g_type = info.get_g_type()
+
+ # Check if there is already a Python wrapper.
+ if g_type != gobject.TYPE_NONE:
+ type_ = g_type.pytype
+ if type_ is not None:
+ self.__dict__[name] = type_
+ return type_
+
+ # Create a wrapper.
+ if isinstance(info, ObjectInfo):
+ parent = get_parent_for_object(info)
+ interfaces = tuple(interface for interface in get_interfaces_for_object(info)
+ if not issubclass(parent, interface))
+ bases = (parent,) + interfaces
+ metaclass = GObjectMeta
+ elif isinstance(info, InterfaceInfo):
+ bases = (gobject.GInterface,)
+ metaclass = GObjectMeta
+ elif isinstance(info, StructInfo):
+ if g_type.is_a(gobject.TYPE_BOXED):
+ bases = (Boxed,)
+ elif g_type.is_a(gobject.TYPE_POINTER) or g_type == gobject.TYPE_NONE:
+ bases = (Struct,)
+ else:
+ raise TypeError, "unable to create a wrapper for %s.%s" % (info.get_namespace(), info.get_name())
+ metaclass = StructMeta
+ else:
+ raise NotImplementedError(info)
+
+ name = info.get_name()
+ dict_ = {
+ '__info__': info,
+ '__module__': self.__namespace__,
+ '__gtype__': g_type
+ }
+ value = metaclass(name, bases, dict_)
+
+ # Register the new Python wrapper.
+ if g_type != gobject.TYPE_NONE:
+ g_type.pytype = value
+
+ elif isinstance(info, FunctionInfo):
+ value = Function(info)
+ elif isinstance(info, ConstantInfo):
+ value = info.get_value()
+ else:
+ raise NotImplementedError(info)
+
+ self.__dict__[name] = value
+ return value
+
+ @property
+ def __members__(self):
+ r = []
+ for type_info in repository.get_infos(self.__namespace__):
+ r.append(type_info.get_name())
+ return r
+
diff --git a/gi/overrides/Gdk.py b/gi/overrides/Gdk.py
new file mode 100644
index 0000000..e3e2d29
--- /dev/null
+++ b/gi/overrides/Gdk.py
@@ -0,0 +1,21 @@
+import sys
+
+from ..module import DynamicModule
+
+class GdkModule(DynamicModule):
+
+ def __init__(self):
+ super(GdkModule, self).__init__()
+
+ initialized, argv = self.init_check(tuple(sys.argv))
+ if not initialized:
+ raise RuntimeError("Gdk couldn't be initialized")
+
+ def rectangle_new(self, x, y, width, height):
+ rectangle = self.Rectangle()
+ rectangle.x = x
+ rectangle.y = y
+ rectangle.width = width
+ rectangle.height = height
+ return rectangle
+
diff --git a/gi/overrides/Gtk.py b/gi/overrides/Gtk.py
new file mode 100644
index 0000000..3de0e7e
--- /dev/null
+++ b/gi/overrides/Gtk.py
@@ -0,0 +1,13 @@
+import sys
+
+from ..module import DynamicModule
+
+class GtkModule(DynamicModule):
+
+ def __init__(self):
+ super(GtkModule, self).__init__()
+
+ initialized, argv = self.init_check(tuple(sys.argv))
+ if not initialized:
+ raise RuntimeError("Gtk couldn't be initialized")
+
diff --git a/gi/overrides/Makefile.am b/gi/overrides/Makefile.am
new file mode 100644
index 0000000..1c3bee7
--- /dev/null
+++ b/gi/overrides/Makefile.am
@@ -0,0 +1,10 @@
+PLATFORM_VERSION = 2.0
+
+pkgpyexecdir = $(pyexecdir)/gtk-2.0/gi
+
+pygioverridesdir = $(pkgpyexecdir)/overrides
+pygioverrides_PYTHON = \
+ Gtk.py \
+ Gdk.py \
+ __init__.py
+
diff --git a/gi/overrides/__init__.py b/gi/overrides/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/gi/overrides/__init__.py
diff --git a/gi/pygi-argument.c b/gi/pygi-argument.c
new file mode 100644
index 0000000..34d68e2
--- /dev/null
+++ b/gi/pygi-argument.c
@@ -0,0 +1,1976 @@
+/* -*- Mode: C; c-basic-offset: 4 -*-
+ * vim: tabstop=4 shiftwidth=4 expandtab
+ *
+ * Copyright (C) 2005-2009 Johan Dahlin <johan@gnome.org>
+ *
+ * pygi-argument.c: GArgument - PyObject conversion functions.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
+ * USA
+ */
+
+#include "pygi-private.h"
+
+#include <string.h>
+#include <time.h>
+
+#include <datetime.h>
+#include <pygobject.h>
+
+static void
+_pygi_g_type_tag_py_bounds (GITypeTag type_tag,
+ PyObject **lower,
+ PyObject **upper)
+{
+ switch(type_tag) {
+ case GI_TYPE_TAG_INT8:
+ *lower = PyInt_FromLong(-128);
+ *upper = PyInt_FromLong(127);
+ break;
+ case GI_TYPE_TAG_UINT8:
+ *upper = PyInt_FromLong(255);
+ *lower = PyInt_FromLong(0);
+ break;
+ case GI_TYPE_TAG_INT16:
+ *lower = PyInt_FromLong(-32768);
+ *upper = PyInt_FromLong(32767);
+ break;
+ case GI_TYPE_TAG_UINT16:
+ *upper = PyInt_FromLong(65535);
+ *lower = PyInt_FromLong(0);
+ break;
+ case GI_TYPE_TAG_INT32:
+ *lower = PyInt_FromLong(-2147483648);
+ *upper = PyInt_FromLong(2147483647);
+ break;
+ case GI_TYPE_TAG_UINT32:
+ /* Note: On 32-bit archs, this number doesn't fit in a long. */
+ *upper = PyLong_FromLongLong(4294967295);
+ *lower = PyInt_FromLong(0);
+ break;
+ case GI_TYPE_TAG_INT64:
+ /* Note: On 32-bit archs, these numbers don't fit in a long. */
+ *lower = PyLong_FromLongLong(-9223372036854775808u);
+ *upper = PyLong_FromLongLong(9223372036854775807);
+ break;
+ case GI_TYPE_TAG_UINT64:
+ *upper = PyLong_FromUnsignedLongLong(18446744073709551615u);
+ *lower = PyInt_FromLong(0);
+ break;
+ case GI_TYPE_TAG_SHORT:
+ *lower = PyInt_FromLong(G_MINSHORT);
+ *upper = PyInt_FromLong(G_MAXSHORT);
+ break;
+ case GI_TYPE_TAG_USHORT:
+ *upper = PyInt_FromLong(G_MAXUSHORT);
+ *lower = PyInt_FromLong(0);
+ break;
+ case GI_TYPE_TAG_INT:
+ *lower = PyInt_FromLong(G_MININT);
+ *upper = PyInt_FromLong(G_MAXINT);
+ break;
+ case GI_TYPE_TAG_UINT:
+ /* Note: On 32-bit archs, this number doesn't fit in a long. */
+ *upper = PyLong_FromLongLong(G_MAXUINT);
+ *lower = PyInt_FromLong(0);
+ break;
+ case GI_TYPE_TAG_LONG:
+ case GI_TYPE_TAG_SSIZE:
+ *lower = PyInt_FromLong(G_MINLONG);
+ *upper = PyInt_FromLong(G_MAXLONG);
+ break;
+ case GI_TYPE_TAG_ULONG:
+ case GI_TYPE_TAG_SIZE:
+ *upper = PyLong_FromUnsignedLongLong(G_MAXULONG);
+ *lower = PyInt_FromLong(0);
+ break;
+ case GI_TYPE_TAG_FLOAT:
+ *upper = PyFloat_FromDouble(G_MAXFLOAT);
+ *lower = PyFloat_FromDouble(-G_MAXFLOAT);
+ break;
+ case GI_TYPE_TAG_DOUBLE:
+ *upper = PyFloat_FromDouble(G_MAXDOUBLE);
+ *lower = PyFloat_FromDouble(-G_MAXDOUBLE);
+ break;
+ default:
+ PyErr_SetString(PyExc_TypeError, "Non-numeric type tag");
+ *lower = *upper = NULL;
+ return;
+ }
+}
+
+gint
+_pygi_g_registered_type_info_check_object (GIRegisteredTypeInfo *info,
+ gboolean is_instance,
+ PyObject *object)
+{
+ gint retval;
+
+ GType g_type;
+ PyObject *py_type;
+ gchar *type_name_expected = NULL;
+
+ g_type = g_registered_type_info_get_g_type(info);
+
+ if (g_type != G_TYPE_NONE) {
+ py_type = _pygi_type_get_from_g_type(g_type);
+ } else {
+ py_type = _pygi_type_import_by_gi_info((GIBaseInfo *)info);
+ }
+
+ if (py_type == NULL) {
+ return FALSE;
+ }
+
+ g_assert(PyType_Check(py_type));
+
+ if (is_instance) {
+ retval = PyObject_IsInstance(object, py_type);
+ if (!retval) {
+ type_name_expected = _pygi_g_base_info_get_fullname(
+ (GIBaseInfo *)info);
+ }
+ } else {
+ if (!PyObject_Type(py_type)) {
+ type_name_expected = "type";
+ retval = 0;
+ } else if (!PyType_IsSubtype((PyTypeObject *)object,
+ (PyTypeObject *)py_type)) {
+ type_name_expected = _pygi_g_base_info_get_fullname(
+ (GIBaseInfo *)info);
+ retval = 0;
+ } else {
+ retval = 1;
+ }
+ }
+
+ Py_DECREF(py_type);
+
+ if (!retval) {
+ PyTypeObject *object_type;
+
+ if (type_name_expected == NULL) {
+ return -1;
+ }
+
+ object_type = (PyTypeObject *)PyObject_Type(object);
+ if (object_type == NULL) {
+ return -1;
+ }
+
+ PyErr_Format(PyExc_TypeError, "Must be %s, not %s",
+ type_name_expected, object_type->tp_name);
+
+ g_free(type_name_expected);
+ }
+
+ return retval;
+}
+
+gint
+_pygi_g_type_info_check_object (GITypeInfo *type_info,
+ gboolean may_be_null,
+ PyObject *object)
+{
+ GITypeTag type_tag;
+ gboolean is_pointer;
+ gint retval = 1;
+
+ type_tag = g_type_info_get_tag(type_info);
+ is_pointer = g_type_info_is_pointer(type_info);
+
+ if (is_pointer && may_be_null && object == Py_None) {
+ return retval;
+ }
+
+ switch (type_tag) {
+ case GI_TYPE_TAG_VOID:
+ if (object != Py_None) {
+ PyErr_Format(PyExc_TypeError, "Must be %s, not %s",
+ Py_None->ob_type->tp_name, object->ob_type->tp_name);
+ retval = 0;
+ }
+ break;
+ case GI_TYPE_TAG_BOOLEAN:
+ /* No check; every Python object has a truth value. */
+ break;
+ case GI_TYPE_TAG_INT8:
+ case GI_TYPE_TAG_UINT8:
+ case GI_TYPE_TAG_INT16:
+ case GI_TYPE_TAG_UINT16:
+ case GI_TYPE_TAG_INT32:
+ case GI_TYPE_TAG_UINT32:
+ case GI_TYPE_TAG_INT64:
+ case GI_TYPE_TAG_UINT64:
+ case GI_TYPE_TAG_SHORT:
+ case GI_TYPE_TAG_USHORT:
+ case GI_TYPE_TAG_INT:
+ case GI_TYPE_TAG_UINT:
+ case GI_TYPE_TAG_LONG:
+ case GI_TYPE_TAG_ULONG:
+ case GI_TYPE_TAG_SSIZE:
+ case GI_TYPE_TAG_SIZE:
+ case GI_TYPE_TAG_FLOAT:
+ case GI_TYPE_TAG_DOUBLE:
+ {
+ PyObject *number, *lower, *upper;
+
+ if (!PyNumber_Check(object)) {
+ PyErr_Format(PyExc_TypeError, "Must be number, not %s",
+ object->ob_type->tp_name);
+ retval = 0;
+ break;
+ }
+
+ if (type_tag == GI_TYPE_TAG_FLOAT || type_tag == GI_TYPE_TAG_DOUBLE) {
+ number = PyNumber_Float(object);
+ } else {
+ number = PyNumber_Int(object);
+ }
+
+ _pygi_g_type_tag_py_bounds(type_tag, &lower, &upper);
+
+ if (lower == NULL || upper == NULL || number == NULL) {
+ retval = -1;
+ goto check_number_release;
+ }
+
+ /* Check bounds */
+ if (PyObject_Compare(lower, number) > 0
+ || PyObject_Compare(upper, number) < 0) {
+ PyObject *lower_str;
+ PyObject *upper_str;
+
+ if (PyErr_Occurred()) {
+ retval = -1;
+ goto check_number_release;
+ }
+
+ lower_str = PyObject_Str(lower);
+ upper_str = PyObject_Str(upper);
+ if (lower_str == NULL || upper_str == NULL) {
+ retval = -1;
+ goto check_number_error_release;
+ }
+
+ PyErr_Format(PyExc_ValueError, "Must range from %s to %s",
+ PyString_AS_STRING(lower_str),
+ PyString_AS_STRING(upper_str));
+
+ retval = 0;
+
+check_number_error_release:
+ Py_XDECREF(lower_str);
+ Py_XDECREF(upper_str);
+ }
+
+check_number_release:
+ Py_XDECREF(number);
+ Py_XDECREF(lower);
+ Py_XDECREF(upper);
+ break;
+ }
+ case GI_TYPE_TAG_TIME_T:
+ if (!PyDateTime_Check(object)) {
+ PyErr_Format(PyExc_TypeError, "Must be datetime.datetime, not %s",
+ object->ob_type->tp_name);
+ retval = 0;
+ break;
+ }
+ break;
+ case GI_TYPE_TAG_GTYPE:
+ {
+ gint is_instance;
+
+ is_instance = PyObject_IsInstance(object, (PyObject *)&PyGTypeWrapper_Type);
+ if (is_instance < 0) {
+ retval = -1;
+ break;
+ }
+
+ if (!is_instance && (!PyType_Check(object) || pyg_type_from_object(object) == 0)) {
+ PyErr_Format(PyExc_TypeError, "Must be gobject.GType, not %s",
+ object->ob_type->tp_name);
+ retval = 0;
+ }
+ break;
+ }
+ case GI_TYPE_TAG_UTF8:
+ case GI_TYPE_TAG_FILENAME:
+ if (!PyString_Check(object) && (!may_be_null || object != Py_None)) {
+ PyErr_Format(PyExc_TypeError, "Must be string, not %s",
+ object->ob_type->tp_name);
+ retval = 0;
+ }
+ break;
+ case GI_TYPE_TAG_ARRAY:
+ {
+ gssize fixed_size;
+ Py_ssize_t length;
+ GITypeInfo *item_type_info;
+ Py_ssize_t i;
+
+ if (!PySequence_Check(object)) {
+ PyErr_Format(PyExc_TypeError, "Must be sequence, not %s",
+ object->ob_type->tp_name);
+ retval = 0;
+ break;
+ }
+
+ length = PySequence_Length(object);
+ if (length < 0) {
+ retval = -1;
+ break;
+ }
+
+ fixed_size = g_type_info_get_array_fixed_size(type_info);
+ if (fixed_size >= 0 && length != fixed_size) {
+ PyErr_Format(PyExc_ValueError, "Must contain %zd items, not %zd",
+ fixed_size, length);
+ retval = 0;
+ break;
+ }
+
+ item_type_info = g_type_info_get_param_type(type_info, 0);
+ g_assert(item_type_info != NULL);
+
+ for (i = 0; i < length; i++) {
+ PyObject *item;
+
+ item = PySequence_GetItem(object, i);
+ if (item == NULL) {
+ retval = -1;
+ break;
+ }
+
+ retval = _pygi_g_type_info_check_object(item_type_info, FALSE, item);
+
+ Py_DECREF(item);
+
+ if (retval < 0) {
+ break;
+ }
+ if (!retval) {
+ _PyGI_ERROR_PREFIX("Item %zd: ", i);
+ break;
+ }
+ }
+
+ g_base_info_unref((GIBaseInfo *)item_type_info);
+
+ break;
+ }
+ case GI_TYPE_TAG_INTERFACE:
+ {
+ GIBaseInfo *info;
+ GIInfoType info_type;
+
+ info = g_type_info_get_interface(type_info);
+ g_assert(info != NULL);
+
+ info_type = g_base_info_get_type(info);
+
+ switch (info_type) {
+ case GI_INFO_TYPE_CALLBACK:
+ /* TODO */
+ PyErr_SetString(PyExc_NotImplementedError, "callback marshalling is not supported yet");
+ break;
+ case GI_INFO_TYPE_ENUM:
+ case GI_INFO_TYPE_FLAGS:
+ retval = _pygi_g_registered_type_info_check_object((GIRegisteredTypeInfo *)info, TRUE, object);
+ break;
+ case GI_INFO_TYPE_STRUCT:
+ {
+ GType type;
+
+ /* Handle special cases. */
+ type = g_registered_type_info_get_g_type((GIRegisteredTypeInfo *)info);
+ if (g_type_is_a(type, G_TYPE_VALUE)) {
+ GType object_type;
+ object_type = pyg_type_from_object((PyObject *)object->ob_type);
+ if (object_type == G_TYPE_INVALID) {
+ PyErr_Format(PyExc_TypeError, "Must be of a known GType, not %s",
+ object->ob_type->tp_name);
+ retval = 0;
+ }
+ break;
+ } else if (g_type_is_a(type, G_TYPE_CLOSURE)) {
+ if (!PyCallable_Check(object)) {
+ PyErr_Format(PyExc_TypeError, "Must be callable, not %s",
+ object->ob_type->tp_name);
+ retval = 0;
+ }
+ break;
+ }
+
+ /* Fallback. */
+ }
+ case GI_INFO_TYPE_BOXED:
+ case GI_INFO_TYPE_OBJECT:
+ retval = _pygi_g_registered_type_info_check_object((GIRegisteredTypeInfo *)info, TRUE, object);
+ break;
+ case GI_INFO_TYPE_UNION:
+ /* TODO */
+ PyErr_SetString(PyExc_NotImplementedError, "union marshalling is not supported yet");
+ break;
+ default:
+ g_assert_not_reached();
+ }
+
+ g_base_info_unref(info);
+ break;
+ }
+ case GI_TYPE_TAG_GLIST:
+ case GI_TYPE_TAG_GSLIST:
+ {
+ Py_ssize_t length;
+ GITypeInfo *item_type_info;
+ Py_ssize_t i;
+
+ if (!PySequence_Check(object)) {
+ PyErr_Format(PyExc_TypeError, "Must be sequence, not %s",
+ object->ob_type->tp_name);
+ retval = 0;
+ break;
+ }
+
+ length = PySequence_Length(object);
+ if (length < 0) {
+ retval = -1;
+ break;
+ }
+
+ item_type_info = g_type_info_get_param_type(type_info, 0);
+ g_assert(item_type_info != NULL);
+
+ for (i = 0; i < length; i++) {
+ PyObject *item;
+
+ item = PySequence_GetItem(object, i);
+ if (item == NULL) {
+ retval = -1;
+ break;
+ }
+
+ retval = _pygi_g_type_info_check_object(item_type_info, FALSE, item);
+
+ Py_DECREF(item);
+
+ if (retval < 0) {
+ break;
+ }
+ if (!retval) {
+ _PyGI_ERROR_PREFIX("Item %zd: ", i);
+ break;
+ }
+ }
+
+ g_base_info_unref((GIBaseInfo *)item_type_info);
+ break;
+ }
+ case GI_TYPE_TAG_GHASH:
+ {
+ Py_ssize_t length;
+ PyObject *keys;
+ PyObject *values;
+ GITypeInfo *key_type_info;
+ GITypeInfo *value_type_info;
+ Py_ssize_t i;
+
+ if (!PyMapping_Check(object)) {
+ PyErr_Format(PyExc_TypeError, "Must be mapping, not %s",
+ object->ob_type->tp_name);
+ retval = 0;
+ break;
+ }
+
+ length = PyMapping_Length(object);
+ if (length < 0) {
+ retval = -1;
+ break;
+ }
+
+ keys = PyMapping_Keys(object);
+ if (keys == NULL) {
+ retval = -1;
+ break;
+ }
+
+ values = PyMapping_Values(object);
+ if (values == NULL) {
+ retval = -1;
+ Py_DECREF(keys);
+ break;
+ }
+
+ key_type_info = g_type_info_get_param_type(type_info, 0);
+ g_assert(key_type_info != NULL);
+
+ value_type_info = g_type_info_get_param_type(type_info, 1);
+ g_assert(value_type_info != NULL);
+
+ for (i = 0; i < length; i++) {
+ PyObject *key;
+ PyObject *value;
+
+ key = PyList_GET_ITEM(keys, i);
+ value = PyList_GET_ITEM(values, i);
+
+ retval = _pygi_g_type_info_check_object(key_type_info, FALSE, key);
+ if (retval < 0) {
+ break;
+ }
+ if (!retval) {
+ _PyGI_ERROR_PREFIX("Key %zd :", i);
+ break;
+ }
+
+ retval = _pygi_g_type_info_check_object(value_type_info, FALSE, value);
+ if (retval < 0) {
+ break;
+ }
+ if (!retval) {
+ _PyGI_ERROR_PREFIX("Value %zd :", i);
+ break;
+ }
+ }
+
+ g_base_info_unref((GIBaseInfo *)key_type_info);
+ g_base_info_unref((GIBaseInfo *)value_type_info);
+ Py_DECREF(values);
+ Py_DECREF(keys);
+ break;
+ }
+ case GI_TYPE_TAG_ERROR:
+ PyErr_SetString(PyExc_NotImplementedError, "Error marshalling is not supported yet");
+ /* TODO */
+ break;
+ }
+
+ return retval;
+}
+
+GArray *
+_pygi_argument_to_array (GArgument *arg,
+ GArgument *args[],
+ GITypeInfo *type_info)
+{
+ GITypeInfo *item_type_info;
+ gboolean is_zero_terminated;
+ gsize item_size;
+ gssize length;
+ GArray *g_array;
+
+ is_zero_terminated = g_type_info_is_zero_terminated(type_info);
+ item_type_info = g_type_info_get_param_type(type_info, 0);
+
+ item_size = _pygi_g_type_info_size(item_type_info);
+
+ g_base_info_unref((GIBaseInfo *)item_type_info);
+
+ if (is_zero_terminated) {
+ length = g_strv_length(arg->v_pointer);
+ } else {
+ length = g_type_info_get_array_fixed_size(type_info);
+ if (length < 0) {
+ gint length_arg_pos;
+
+ length_arg_pos = g_type_info_get_array_length(type_info);
+ g_assert(length_arg_pos >= 0);
+
+ /* FIXME: Take into account the type of the argument. */
+ length = args[length_arg_pos]->v_int;
+ }
+ }
+
+ g_array = g_array_new(is_zero_terminated, FALSE, item_size);
+
+ g_array->data = arg->v_pointer;
+ g_array->len = length;
+
+ return g_array;
+}
+
+GArgument
+_pygi_argument_from_object (PyObject *object,
+ GITypeInfo *type_info,
+ GITransfer transfer)
+{
+ GArgument arg;
+ GITypeTag type_tag;
+ gboolean is_pointer;
+
+ type_tag = g_type_info_get_tag(type_info);
+ is_pointer = g_type_info_is_pointer(type_info);
+
+ if (object == Py_None && is_pointer
+ && type_tag != GI_TYPE_TAG_BOOLEAN) { /* We want None == FALSE. */
+ arg.v_pointer = NULL;
+ return arg;
+ }
+
+ switch (type_tag) {
+ case GI_TYPE_TAG_VOID:
+ arg.v_pointer = NULL;
+ break;
+ case GI_TYPE_TAG_BOOLEAN:
+ {
+ gboolean value;
+
+ value = PyObject_IsTrue(object);
+
+ if (is_pointer) {
+ g_warn_if_fail(transfer == GI_TRANSFER_NOTHING);
+ arg.v_pointer = g_try_new(gboolean, 1);
+ if (arg.v_pointer == NULL) {
+ PyErr_NoMemory();
+ break;
+ }
+ *(gboolean *)arg.v_pointer = value;
+ } else {
+ arg.v_boolean = value;
+ }
+
+ break;
+ }
+ case GI_TYPE_TAG_INT8:
+ case GI_TYPE_TAG_UINT8:
+ case GI_TYPE_TAG_INT16:
+ case GI_TYPE_TAG_UINT16:
+ case GI_TYPE_TAG_INT32:
+ case GI_TYPE_TAG_SHORT:
+ case GI_TYPE_TAG_USHORT:
+ case GI_TYPE_TAG_INT:
+ case GI_TYPE_TAG_LONG:
+ case GI_TYPE_TAG_SSIZE:
+ {
+ PyObject *int_;
+ glong value;
+
+ int_ = PyNumber_Int(object);
+ if (int_ == NULL) {
+ break;
+ }
+
+ value = PyInt_AsLong(int_);
+ Py_DECREF(int_);
+
+ if (is_pointer) {
+ g_warn_if_fail(transfer == GI_TRANSFER_NOTHING);
+ arg.v_pointer = g_try_new(glong, 1);
+ if (arg.v_pointer == NULL) {
+ PyErr_NoMemory();
+ break;
+ }
+ *(glong *)arg.v_pointer = value;
+ } else {
+ arg.v_long = value;
+ }
+
+ break;
+ }
+ case GI_TYPE_TAG_UINT32:
+ case GI_TYPE_TAG_UINT64:
+ case GI_TYPE_TAG_UINT:
+ case GI_TYPE_TAG_ULONG:
+ case GI_TYPE_TAG_SIZE:
+ {
+ PyObject *number;
+ guint64 value;
+
+ number = PyNumber_Int(object);
+ if (number == NULL) {
+ break;
+ }
+
+ if (PyInt_Check(number)) {
+ value = PyInt_AS_LONG(number);
+ } else {
+ value = PyLong_AsUnsignedLongLong(number);
+ }
+
+ Py_DECREF(number);
+
+ if (is_pointer) {
+ g_warn_if_fail(transfer == GI_TRANSFER_NOTHING);
+ arg.v_pointer = g_try_new(guint64, 1);
+ if (arg.v_pointer == NULL) {
+ PyErr_NoMemory();
+ break;
+ }
+ *(guint64 *)arg.v_pointer = value;
+ } else {
+ arg.v_uint64 = value;
+ }
+
+ break;
+ }
+ case GI_TYPE_TAG_INT64:
+ {
+ PyObject *number;
+ gint64 value;
+
+ number = PyNumber_Int(object);
+ if (number == NULL) {
+ break;
+ }
+
+ if (PyInt_Check(number)) {
+ value = PyInt_AS_LONG(number);
+ } else {
+ value = PyLong_AsLongLong(number);
+ }
+
+ Py_DECREF(number);
+
+ if (is_pointer) {
+ g_warn_if_fail(transfer == GI_TRANSFER_NOTHING);
+ arg.v_pointer = g_try_new(gint64, 1);
+ if (arg.v_pointer == NULL) {
+ PyErr_NoMemory();
+ break;
+ }
+ *(gint64 *)arg.v_pointer = value;
+ } else {
+ arg.v_int64 = value;
+ }
+
+ break;
+ }
+ case GI_TYPE_TAG_FLOAT:
+ {
+ PyObject *float_;
+ gfloat value;
+
+ float_ = PyNumber_Float(object);
+ if (float_ == NULL) {
+ break;
+ }
+
+ value = (float)PyFloat_AsDouble(float_);
+ Py_DECREF(float_);
+
+ if (is_pointer) {
+ g_warn_if_fail(transfer == GI_TRANSFER_NOTHING);
+ arg.v_pointer = g_try_new(gfloat, 1);
+ if (arg.v_pointer == NULL) {
+ PyErr_NoMemory();
+ break;
+ }
+ *(gfloat *)arg.v_pointer = value;
+ } else {
+ arg.v_float = value;
+ }
+
+ break;
+ }
+ case GI_TYPE_TAG_DOUBLE:
+ {
+ PyObject *float_;
+ gdouble value;
+
+ float_ = PyNumber_Float(object);
+ if (float_ == NULL) {
+ break;
+ }
+
+ value = PyFloat_AsDouble(float_);
+ Py_DECREF(float_);
+
+ if (is_pointer) {
+ g_warn_if_fail(transfer == GI_TRANSFER_NOTHING);
+ arg.v_pointer = g_try_new(gdouble, 1);
+ if (arg.v_pointer == NULL) {
+ PyErr_NoMemory();
+ break;
+ }
+ *(gdouble *)arg.v_pointer = value;
+ } else {
+ arg.v_double = value;
+ }
+
+ break;
+ }
+ case GI_TYPE_TAG_TIME_T:
+ {
+ PyDateTime_DateTime *py_datetime;
+ struct tm datetime;
+ time_t time_;
+
+ py_datetime = (PyDateTime_DateTime *)object;
+
+ if (py_datetime->hastzinfo) {
+ if (PyErr_WarnEx(NULL, "tzinfo ignored; only local time is supported", 1) < 0) {
+ break;
+ }
+ }
+
+ datetime.tm_sec = PyDateTime_DATE_GET_SECOND(py_datetime);
+ datetime.tm_min = PyDateTime_DATE_GET_MINUTE(py_datetime);
+ datetime.tm_hour = PyDateTime_DATE_GET_HOUR(py_datetime);
+ datetime.tm_mday = PyDateTime_GET_DAY(py_datetime);
+ datetime.tm_mon = PyDateTime_GET_MONTH(py_datetime) - 1;
+ datetime.tm_year = PyDateTime_GET_YEAR(py_datetime) - 1900;
+ datetime.tm_isdst = -1;
+
+ time_ = mktime(&datetime);
+ if (time_ == -1) {
+ PyErr_SetString(PyExc_RuntimeError, "datetime conversion failed");
+ break;
+ }
+
+ if (is_pointer) {
+ g_warn_if_fail(transfer == GI_TRANSFER_NOTHING);
+ arg.v_pointer = g_try_new(time_t, 1);
+ if (arg.v_pointer == NULL) {
+ PyErr_NoMemory();
+ break;
+ }
+ *(time_t *)arg.v_pointer = time_;
+ } else {
+ arg.v_long = time_;
+ }
+
+ break;
+ }
+ case GI_TYPE_TAG_GTYPE:
+ {
+ GType type;
+
+ type = pyg_type_from_object(object);
+
+ if (is_pointer) {
+ g_warn_if_fail(transfer == GI_TRANSFER_NOTHING);
+ arg.v_pointer = g_try_new(GType, 1);
+ if (arg.v_pointer == NULL) {
+ PyErr_NoMemory();
+ break;
+ }
+ *(GType *)arg.v_pointer = type;
+ } else {
+ arg.v_long = type;
+ }
+
+ break;
+ }
+ case GI_TYPE_TAG_UTF8:
+ {
+ const gchar *string;
+
+ g_assert(is_pointer);
+
+ string = PyString_AsString(object);
+
+ /* Don't need to check for errors, since g_strdup is NULL-proof. */
+ arg.v_string = g_strdup(string);
+ break;
+ }
+ case GI_TYPE_TAG_FILENAME:
+ {
+ GError *error = NULL;
+ const gchar *string;
+
+ g_assert(is_pointer);
+
+ string = PyString_AsString(object);
+ if (string == NULL) {
+ break;
+ }
+
+ arg.v_string = g_filename_from_utf8(string, -1, NULL, NULL, &error);
+ if (arg.v_string == NULL) {
+ PyErr_SetString(PyExc_Exception, error->message);
+ /* TODO: Convert the error to an exception. */
+ }
+
+ break;
+ }
+ case GI_TYPE_TAG_ARRAY:
+ {
+ Py_ssize_t length;
+ gboolean is_zero_terminated;
+ GITypeInfo *item_type_info;
+ gsize item_size;
+ GArray *array;
+ GITransfer item_transfer;
+ Py_ssize_t i;
+
+ length = PySequence_Length(object);
+ if (length < 0) {
+ break;
+ }
+
+ is_zero_terminated = g_type_info_is_zero_terminated(type_info);
+ item_type_info = g_type_info_get_param_type(type_info, 0);
+
+ item_size = _pygi_g_type_info_size(item_type_info);
+
+ array = g_array_sized_new(is_zero_terminated, FALSE, item_size, length);
+ if (array == NULL) {
+ g_base_info_unref((GIBaseInfo *)item_type_info);
+ PyErr_NoMemory();
+ break;
+ }
+
+ item_transfer = transfer == GI_TRANSFER_CONTAINER ? GI_TRANSFER_NOTHING : transfer;
+
+ for (i = 0; i < length; i++) {
+ PyObject *py_item;
+ GArgument item;
+
+ py_item = PySequence_GetItem(object, i);
+ if (py_item == NULL) {
+ goto array_item_error;
+ }
+
+ item = _pygi_argument_from_object(py_item, item_type_info, item_transfer);
+
+ Py_DECREF(py_item);
+
+ if (PyErr_Occurred()) {
+ goto array_item_error;
+ }
+
+ g_array_insert_val(array, i, item);
+ continue;
+
+array_item_error:
+ /* Free everything we have converted so far. */
+ _pygi_argument_release((GArgument *)&array, type_info,
+ GI_TRANSFER_NOTHING, GI_DIRECTION_IN);
+ array = NULL;
+
+ _PyGI_ERROR_PREFIX("Item %zd: ", i);
+ break;
+ }
+
+ arg.v_pointer = array;
+
+ g_base_info_unref((GIBaseInfo *)item_type_info);
+ break;
+ }
+ case GI_TYPE_TAG_INTERFACE:
+ {
+ GIBaseInfo *info;
+ GIInfoType info_type;
+
+ info = g_type_info_get_interface(type_info);
+ info_type = g_base_info_get_type(info);
+
+ switch (info_type) {
+ case GI_INFO_TYPE_CALLBACK:
+ PyErr_SetString(PyExc_NotImplementedError, "callback marshalling is not supported yet");
+ /* TODO */
+ break;
+ case GI_INFO_TYPE_BOXED:
+ case GI_INFO_TYPE_STRUCT:
+ {
+ GType type;
+
+ type = g_registered_type_info_get_g_type((GIRegisteredTypeInfo *)info);
+
+ /* Handle special cases first. */
+ if (g_type_is_a(type, G_TYPE_VALUE)) {
+ GValue *value;
+ GType object_type;
+ gint retval;
+
+ object_type = pyg_type_from_object((PyObject *)object->ob_type);
+ if (object_type == G_TYPE_INVALID) {
+ PyErr_SetString(PyExc_RuntimeError, "unable to retrieve object's GType");
+ break;
+ }
+
+ g_assert(is_pointer);
+ g_warn_if_fail(transfer == GI_TRANSFER_NOTHING);
+
+ value = g_slice_new0(GValue);
+ g_value_init(value, object_type);
+
+ retval = pyg_value_from_pyobject(value, object);
+ if (retval < 0) {
+ g_slice_free(GValue, value);
+ PyErr_SetString(PyExc_RuntimeError, "PyObject conversion to GValue failed");
+ break;
+ }
+
+ arg.v_pointer = value;
+ } else if (g_type_is_a(type, G_TYPE_CLOSURE)) {
+ GClosure *closure;
+
+ g_assert(is_pointer);
+ g_warn_if_fail(transfer == GI_TRANSFER_NOTHING);
+
+ closure = pyg_closure_new(object, NULL, NULL);
+ if (closure == NULL) {
+ PyErr_SetString(PyExc_RuntimeError, "PyObject conversion to GClosure failed");
+ break;
+ }
+
+ arg.v_pointer = closure;
+ } else if (g_type_is_a(type, G_TYPE_BOXED)) {
+ g_assert(is_pointer);
+ arg.v_pointer = pyg_boxed_get(object, void);
+ if (transfer == GI_TRANSFER_EVERYTHING) {
+ arg.v_pointer = g_boxed_copy(type, arg.v_pointer);
+ }
+ } else if (g_type_is_a(type, G_TYPE_POINTER) || type == G_TYPE_NONE) {
+ g_warn_if_fail(!is_pointer || transfer == GI_TRANSFER_NOTHING);
+ arg.v_pointer = pyg_pointer_get(object, void);
+ } else {
+ PyErr_Format(PyExc_NotImplementedError, "structure type '%s' is not supported yet", g_type_name(type));
+ }
+
+ break;
+ }
+ case GI_INFO_TYPE_ENUM:
+ case GI_INFO_TYPE_FLAGS:
+ {
+ PyObject *int_;
+ glong value;
+
+ int_ = PyNumber_Int(object);
+ if (int_ == NULL) {
+ break;
+ }
+
+ value = PyInt_AsLong(int_);
+ Py_DECREF(int_);
+
+ if (is_pointer) {
+ g_warn_if_fail(transfer == GI_TRANSFER_NOTHING);
+ arg.v_pointer = g_try_new(glong, 1);
+ if (arg.v_pointer == NULL) {
+ PyErr_NoMemory();
+ break;
+ }
+ *(glong *)arg.v_pointer = value;
+ } else {
+ arg.v_long = value;
+ }
+
+ break;
+ }
+ case GI_INFO_TYPE_OBJECT:
+ g_assert(is_pointer);
+
+ arg.v_pointer = pygobject_get(object);
+ if (transfer == GI_TRANSFER_EVERYTHING) {
+ g_object_ref(arg.v_pointer);
+ }
+
+ break;
+ case GI_INFO_TYPE_UNION:
+ PyErr_SetString(PyExc_NotImplementedError, "union marshalling is not supported yet");
+ /* TODO */
+ break;
+ default:
+ g_assert_not_reached();
+ }
+ g_base_info_unref(info);
+ break;
+ }
+ case GI_TYPE_TAG_GLIST:
+ case GI_TYPE_TAG_GSLIST:
+ {
+ Py_ssize_t length;
+ GITypeInfo *item_type_info;
+ GSList *list = NULL;
+ GITransfer item_transfer;
+ Py_ssize_t i;
+
+ g_assert(is_pointer);
+
+ length = PySequence_Length(object);
+ if (length < 0) {
+ break;
+ }
+
+ item_type_info = g_type_info_get_param_type(type_info, 0);
+ g_assert(item_type_info != NULL);
+
+ item_transfer = transfer == GI_TRANSFER_CONTAINER ? GI_TRANSFER_NOTHING : transfer;
+
+ for (i = length - 1; i >= 0; i--) {
+ PyObject *py_item;
+ GArgument item;
+
+ py_item = PySequence_GetItem(object, i);
+ if (py_item == NULL) {
+ goto list_item_error;
+ }
+
+ item = _pygi_argument_from_object(py_item, item_type_info, item_transfer);
+
+ Py_DECREF(py_item);
+
+ if (PyErr_Occurred()) {
+ goto list_item_error;
+ }
+
+ if (type_tag == GI_TYPE_TAG_GLIST) {
+ list = (GSList *)g_list_prepend((GList *)list, item.v_pointer);
+ } else {
+ list = g_slist_prepend(list, item.v_pointer);
+ }
+
+ continue;
+
+list_item_error:
+ /* Free everything we have converted so far. */
+ _pygi_argument_release((GArgument *)&list, type_info,
+ GI_TRANSFER_NOTHING, GI_DIRECTION_IN);
+ list = NULL;
+
+ _PyGI_ERROR_PREFIX("Item %zd: ", i);
+ break;
+ }
+
+ arg.v_pointer = list;
+
+ g_base_info_unref((GIBaseInfo *)item_type_info);
+
+ break;
+ }
+ case GI_TYPE_TAG_GHASH:
+ {
+ Py_ssize_t length;
+ PyObject *keys;
+ PyObject *values;
+ GITypeInfo *key_type_info;
+ GITypeInfo *value_type_info;
+ GITypeTag key_type_tag;
+ GHashFunc hash_func;
+ GEqualFunc equal_func;
+ GHashTable *hash_table;
+ GITransfer item_transfer;
+ Py_ssize_t i;
+
+ g_assert(is_pointer);
+
+ length = PyMapping_Length(object);
+ if (length < 0) {
+ break;
+ }
+
+ keys = PyMapping_Keys(object);
+ if (keys == NULL) {
+ break;
+ }
+
+ values = PyMapping_Values(object);
+ if (values == NULL) {
+ Py_DECREF(keys);
+ break;
+ }
+
+ key_type_info = g_type_info_get_param_type(type_info, 0);
+ g_assert(key_type_info != NULL);
+
+ value_type_info = g_type_info_get_param_type(type_info, 1);
+ g_assert(value_type_info != NULL);
+
+ key_type_tag = g_type_info_get_tag(key_type_info);
+
+ switch(key_type_tag) {
+ case GI_TYPE_TAG_UTF8:
+ case GI_TYPE_TAG_FILENAME:
+ hash_func = g_str_hash;
+ equal_func = g_str_equal;
+ break;
+ default:
+ hash_func = NULL;
+ equal_func = NULL;
+ }
+
+ hash_table = g_hash_table_new(hash_func, equal_func);
+ if (hash_table == NULL) {
+ PyErr_NoMemory();
+ goto hash_table_release;
+ }
+
+ item_transfer = transfer == GI_TRANSFER_CONTAINER ? GI_TRANSFER_NOTHING : transfer;
+
+ for (i = 0; i < length; i++) {
+ PyObject *py_key;
+ PyObject *py_value;
+ GArgument key;
+ GArgument value;
+
+ py_key = PyList_GET_ITEM(keys, i);
+ py_value = PyList_GET_ITEM(values, i);
+
+ key = _pygi_argument_from_object(py_key, key_type_info, item_transfer);
+ if (PyErr_Occurred()) {
+ goto hash_table_item_error;
+ }
+
+ value = _pygi_argument_from_object(py_value, value_type_info, item_transfer);
+ if (PyErr_Occurred()) {
+ _pygi_argument_release(&key, type_info, GI_TRANSFER_NOTHING, GI_DIRECTION_IN);
+ goto hash_table_item_error;
+ }
+
+ g_hash_table_insert(hash_table, key.v_pointer, value.v_pointer);
+ continue;
+
+hash_table_item_error:
+ /* Free everything we have converted so far. */
+ _pygi_argument_release((GArgument *)&hash_table, type_info,
+ GI_TRANSFER_NOTHING, GI_DIRECTION_IN);
+ hash_table = NULL;
+
+ _PyGI_ERROR_PREFIX("Item %zd: ", i);
+ break;
+ }
+
+ arg.v_pointer = hash_table;
+
+hash_table_release:
+ g_base_info_unref((GIBaseInfo *)key_type_info);
+ g_base_info_unref((GIBaseInfo *)value_type_info);
+ Py_DECREF(keys);
+ Py_DECREF(values);
+ break;
+ }
+ case GI_TYPE_TAG_ERROR:
+ PyErr_SetString(PyExc_NotImplementedError, "error marshalling is not supported yet");
+ /* TODO */
+ break;
+ }
+
+ return arg;
+}
+
+PyObject *
+_pygi_argument_to_object (GArgument *arg,
+ GITypeInfo *type_info,
+ GITransfer transfer)
+{
+ GITypeTag type_tag;
+ gboolean is_pointer;
+ PyObject *object = NULL;
+
+ type_tag = g_type_info_get_tag(type_info);
+ is_pointer = g_type_info_is_pointer(type_info);
+
+ if (is_pointer && arg->v_pointer == NULL) {
+ Py_RETURN_NONE;
+ }
+
+ switch (type_tag) {
+ case GI_TYPE_TAG_VOID:
+ Py_INCREF(Py_None);
+ object = Py_None;
+ break;
+ case GI_TYPE_TAG_BOOLEAN:
+ {
+ gboolean value;
+ value = is_pointer ? *(gboolean *)arg->v_pointer : arg->v_boolean;
+ object = PyBool_FromLong(value);
+ break;
+ }
+ case GI_TYPE_TAG_INT8:
+ {
+ gint8 value;
+ value = is_pointer ? *(gint8 *)arg->v_pointer : arg->v_int8;
+ object = PyInt_FromLong(value);
+ break;
+ }
+ case GI_TYPE_TAG_UINT8:
+ {
+ guint8 value;
+ value = is_pointer ? *(guint8 *)arg->v_pointer : arg->v_uint8;
+ object = PyInt_FromLong(value);
+ break;
+ }
+ case GI_TYPE_TAG_INT16:
+ {
+ gint16 value;
+ value = is_pointer ? *(gint16 *)arg->v_pointer : arg->v_int16;
+ object = PyInt_FromLong(value);
+ break;
+ }
+ case GI_TYPE_TAG_UINT16:
+ {
+ guint16 value;
+ value = is_pointer ? *(guint16 *)arg->v_pointer : arg->v_uint16;
+ object = PyInt_FromLong(value);
+ break;
+ }
+ case GI_TYPE_TAG_INT32:
+ {
+ gint32 value;
+ value = is_pointer ? *(gint32 *)arg->v_pointer : arg->v_int32;
+ object = PyInt_FromLong(value);
+ break;
+ }
+ case GI_TYPE_TAG_UINT32:
+ {
+ guint32 value;
+ value = is_pointer ? *(guint32 *)arg->v_pointer : arg->v_uint32;
+ object = PyInt_FromLong(value);
+ break;
+ }
+ case GI_TYPE_TAG_INT64:
+ {
+ gint64 value;
+ value = is_pointer ? *(gint64 *)arg->v_pointer : arg->v_int64;
+ object = PyLong_FromLongLong(value);
+ break;
+ }
+ case GI_TYPE_TAG_UINT64:
+ {
+ guint64 value;
+ value = is_pointer ? *(guint64 *)arg->v_pointer : arg->v_uint64;
+ object = PyLong_FromUnsignedLongLong(value);
+ break;
+ }
+ case GI_TYPE_TAG_SHORT:
+ {
+ gshort value;
+ value = is_pointer ? *(gshort *)arg->v_pointer : arg->v_short;
+ object = PyInt_FromLong(value);
+ break;
+ }
+ case GI_TYPE_TAG_USHORT:
+ {
+ gushort value;
+ value = is_pointer ? *(gushort *)arg->v_pointer : arg->v_ushort;
+ object = PyInt_FromLong(value);
+ break;
+ }
+ case GI_TYPE_TAG_INT:
+ {
+ gint value;
+ value = is_pointer ? *(gint *)arg->v_pointer : arg->v_int;
+ object = PyInt_FromLong(value);
+ break;
+ }
+ case GI_TYPE_TAG_UINT:
+ {
+ guint value;
+ value = is_pointer ? *(guint *)arg->v_pointer : arg->v_uint;
+ object = PyLong_FromLongLong(value);
+ break;
+ }
+ case GI_TYPE_TAG_LONG:
+ {
+ glong value;
+ value = is_pointer ? *(glong *)arg->v_pointer : arg->v_long;
+ object = PyInt_FromLong(value);
+ break;
+ }
+ case GI_TYPE_TAG_ULONG:
+ {
+ gulong value;
+ value = is_pointer ? *(gulong *)arg->v_pointer : arg->v_ulong;
+ object = PyLong_FromUnsignedLongLong(value);
+ break;
+ }
+ case GI_TYPE_TAG_SSIZE:
+ {
+ gssize value;
+ value = is_pointer ? *(gssize *)arg->v_pointer : arg->v_ssize;
+ object = PyInt_FromLong(value);
+ break;
+ }
+ case GI_TYPE_TAG_SIZE:
+ {
+ gsize value;
+ value = is_pointer ? *(gsize *)arg->v_pointer : arg->v_size;
+ object = PyLong_FromUnsignedLongLong(value);
+ break;
+ }
+ case GI_TYPE_TAG_FLOAT:
+ {
+ gfloat value;
+ value = is_pointer ? *(gfloat *)arg->v_pointer : arg->v_float;
+ object = PyFloat_FromDouble(value);
+ break;
+ }
+ case GI_TYPE_TAG_DOUBLE:
+ {
+ gdouble value;
+ value = is_pointer ? *(gdouble *)arg->v_pointer : arg->v_double;
+ object = PyFloat_FromDouble(value);
+ break;
+ }
+ case GI_TYPE_TAG_TIME_T:
+ {
+ time_t *time_;
+ struct tm *datetime;
+ time_ = is_pointer ? arg->v_pointer : &arg->v_long;
+ datetime = localtime(time_);
+ object = PyDateTime_FromDateAndTime(
+ datetime->tm_year + 1900,
+ datetime->tm_mon + 1,
+ datetime->tm_mday,
+ datetime->tm_hour,
+ datetime->tm_min,
+ datetime->tm_sec,
+ 0);
+ break;
+ }
+ case GI_TYPE_TAG_GTYPE:
+ {
+ GType type;
+ type = is_pointer ? *(GType *)arg->v_pointer : arg->v_long;
+ object = pyg_type_wrapper_new(type);
+ break;
+ }
+ case GI_TYPE_TAG_UTF8:
+ g_assert(is_pointer);
+ object = PyString_FromString(arg->v_string);
+ break;
+ case GI_TYPE_TAG_FILENAME:
+ {
+ GError *error = NULL;
+ gchar *string;
+
+ g_assert(is_pointer);
+
+ string = g_filename_to_utf8(arg->v_string, -1, NULL, NULL, &error);
+ if (string == NULL) {
+ PyErr_SetString(PyExc_Exception, error->message);
+ /* TODO: Convert the error to an exception. */
+ break;
+ }
+
+ object = PyString_FromString(string);
+
+ g_free(string);
+
+ break;
+ }
+ case GI_TYPE_TAG_ARRAY:
+ {
+ GArray *array;
+ GITypeInfo *item_type_info;
+ GITransfer item_transfer;
+ gsize i;
+
+ array = arg->v_pointer;
+
+ object = PyTuple_New(array->len);
+ if (object == NULL) {
+ break;
+ }
+
+ item_type_info = g_type_info_get_param_type(type_info, 0);
+ g_assert(item_type_info != NULL);
+
+ item_transfer = transfer == GI_TRANSFER_CONTAINER ? GI_TRANSFER_NOTHING : transfer;
+
+ for(i = 0; i < array->len; i++) {
+ GArgument item;
+ PyObject *py_item;
+
+ item = _g_array_index(array, GArgument, i);
+ py_item = _pygi_argument_to_object(&item, item_type_info, item_transfer);
+ if (py_item == NULL) {
+ Py_CLEAR(object);
+ _PyGI_ERROR_PREFIX("Item %zu: ", i);
+ break;
+ }
+
+ PyTuple_SET_ITEM(object, i, py_item);
+ }
+
+ g_base_info_unref((GIBaseInfo *)item_type_info);
+ break;
+ }
+ case GI_TYPE_TAG_INTERFACE:
+ {
+ GIBaseInfo *info;
+ GIInfoType info_type;
+
+ info = g_type_info_get_interface(type_info);
+ info_type = g_base_info_get_type(info);
+
+ switch (info_type) {
+ case GI_INFO_TYPE_CALLBACK:
+ {
+ PyErr_SetString(PyExc_NotImplementedError, "callback marshalling is not supported yet");
+ /* TODO */
+ break;
+ }
+ case GI_INFO_TYPE_BOXED:
+ case GI_INFO_TYPE_STRUCT:
+ {
+ GType type;
+
+ type = g_registered_type_info_get_g_type((GIRegisteredTypeInfo *)info);
+ if (g_type_is_a(type, G_TYPE_VALUE)) {
+ g_assert(is_pointer);
+ object = pyg_value_as_pyobject(arg->v_pointer, FALSE);
+ } else if (g_type_is_a(type, G_TYPE_BOXED)) {
+ g_assert(is_pointer);
+ object = pyg_boxed_new(type, arg->v_pointer, FALSE, transfer == GI_TRANSFER_EVERYTHING);
+ } else if (g_type_is_a(type, G_TYPE_POINTER)) {
+ PyObject *py_type;
+
+ g_assert(is_pointer);
+
+ py_type = _pygi_type_get_from_g_type(type);
+
+ if (py_type == NULL || !PyType_IsSubtype((PyTypeObject *)type, &PyGIStruct_Type)) {
+ g_warn_if_fail(transfer == GI_TRANSFER_NOTHING);
+ object = pyg_pointer_new(type, arg->v_pointer);
+ } else {
+ object = _pygi_struct_new((PyTypeObject *)py_type, arg->v_pointer, transfer == GI_TRANSFER_EVERYTHING);
+ }
+
+ Py_XDECREF(py_type);
+ } else if (type == G_TYPE_NONE) {
+ PyObject *py_type;
+
+ py_type = _pygi_type_import_by_gi_info(info);
+ if (py_type == NULL) {
+ break;
+ }
+
+ object = _pygi_struct_new((PyTypeObject *)py_type, arg->v_pointer,
+ transfer == GI_TRANSFER_EVERYTHING);
+
+ Py_DECREF(py_type);
+ } else {
+ PyErr_Format(PyExc_NotImplementedError, "structure type '%s' is not supported yet", g_type_name(type));
+ }
+
+ break;
+ }
+ case GI_INFO_TYPE_ENUM:
+ case GI_INFO_TYPE_FLAGS:
+ {
+ GType type;
+ glong value;
+
+ type = g_registered_type_info_get_g_type((GIRegisteredTypeInfo *)info);
+ value = is_pointer ? *(glong *)arg->v_pointer : arg->v_long;
+
+ if (info_type == GI_INFO_TYPE_ENUM) {
+ object = pyg_enum_from_gtype(type, value);
+ } else {
+ object = pyg_flags_from_gtype(type, value);
+ }
+
+ break;
+ }
+ case GI_INFO_TYPE_OBJECT:
+ g_assert(is_pointer);
+ object = pygobject_new(arg->v_pointer);
+ break;
+ case GI_INFO_TYPE_UNION:
+ /* TODO */
+ PyErr_SetString(PyExc_NotImplementedError, "union marshalling is not supported yet");
+ break;
+ default:
+ g_assert_not_reached();
+ }
+
+ g_base_info_unref(info);
+ break;
+ }
+ case GI_TYPE_TAG_GLIST:
+ case GI_TYPE_TAG_GSLIST:
+ {
+ GSList *list;
+ gsize length;
+ GITypeInfo *item_type_info;
+ GITransfer item_transfer;
+ gsize i;
+
+ g_assert(is_pointer);
+
+ list = arg->v_pointer;
+ length = g_slist_length(list);
+
+ object = PyList_New(length);
+ if (object == NULL) {
+ break;
+ }
+
+ item_type_info = g_type_info_get_param_type(type_info, 0);
+ g_assert(item_type_info != NULL);
+
+ item_transfer = transfer == GI_TRANSFER_CONTAINER ? GI_TRANSFER_NOTHING : transfer;
+
+ for (i = 0; list != NULL; list = g_slist_next(list), i++) {
+ GArgument item;
+ PyObject *py_item;
+
+ item.v_pointer = list->data;
+
+ py_item = _pygi_argument_to_object(&item, item_type_info, item_transfer);
+ if (py_item == NULL) {
+ Py_CLEAR(object);
+ _PyGI_ERROR_PREFIX("Item %zu: ", i);
+ break;
+ }
+
+ PyList_SET_ITEM(object, i, py_item);
+ }
+
+ g_base_info_unref((GIBaseInfo *)item_type_info);
+ break;
+ }
+ case GI_TYPE_TAG_GHASH:
+ {
+ GITypeInfo *key_type_info;
+ GITypeInfo *value_type_info;
+ GITransfer item_transfer;
+ GHashTableIter hash_table_iter;
+ GArgument key;
+ GArgument value;
+
+ g_assert(is_pointer);
+
+ object = PyDict_New();
+ if (object == NULL) {
+ break;
+ }
+
+ key_type_info = g_type_info_get_param_type(type_info, 0);
+ g_assert(key_type_info != NULL);
+
+ value_type_info = g_type_info_get_param_type(type_info, 1);
+ g_assert(value_type_info != NULL);
+
+ item_transfer = transfer == GI_TRANSFER_CONTAINER ? GI_TRANSFER_NOTHING : transfer;
+
+ g_hash_table_iter_init(&hash_table_iter, (GHashTable *)arg->v_pointer);
+ while (g_hash_table_iter_next(&hash_table_iter, &key.v_pointer, &value.v_pointer)) {
+ PyObject *py_key;
+ PyObject *py_value;
+ int retval;
+
+ py_key = _pygi_argument_to_object(&key, key_type_info, item_transfer);
+ if (py_key == NULL) {
+ break;
+ }
+
+ py_value = _pygi_argument_to_object(&value, value_type_info, item_transfer);
+ if (py_value == NULL) {
+ Py_DECREF(py_key);
+ break;
+ }
+
+ retval = PyDict_SetItem(object, py_key, py_value);
+
+ Py_DECREF(py_key);
+ Py_DECREF(py_value);
+
+ if (retval < 0) {
+ Py_CLEAR(object);
+ break;
+ }
+ }
+
+ g_base_info_unref((GIBaseInfo *)key_type_info);
+ g_base_info_unref((GIBaseInfo *)value_type_info);
+ break;
+ }
+ case GI_TYPE_TAG_ERROR:
+ /* Errors should be handled in the invoke wrapper. */
+ g_assert_not_reached();
+ }
+
+ return object;
+}
+
+void
+_pygi_argument_release (GArgument *arg,
+ GITypeInfo *type_info,
+ GITransfer transfer,
+ GIDirection direction)
+{
+ GITypeTag type_tag;
+ gboolean is_pointer;
+
+ type_tag = g_type_info_get_tag(type_info);
+ is_pointer = g_type_info_is_pointer(type_info);
+
+ if (is_pointer && arg->v_pointer == NULL) {
+ return;
+ }
+
+ switch(type_tag) {
+ case GI_TYPE_TAG_VOID:
+ case GI_TYPE_TAG_BOOLEAN:
+ case GI_TYPE_TAG_INT8:
+ case GI_TYPE_TAG_UINT8:
+ case GI_TYPE_TAG_INT16:
+ case GI_TYPE_TAG_UINT16:
+ case GI_TYPE_TAG_INT32:
+ case GI_TYPE_TAG_UINT32:
+ case GI_TYPE_TAG_INT64:
+ case GI_TYPE_TAG_UINT64:
+ case GI_TYPE_TAG_SHORT:
+ case GI_TYPE_TAG_USHORT:
+ case GI_TYPE_TAG_INT:
+ case GI_TYPE_TAG_UINT:
+ case GI_TYPE_TAG_LONG:
+ case GI_TYPE_TAG_ULONG:
+ case GI_TYPE_TAG_SSIZE:
+ case GI_TYPE_TAG_SIZE:
+ case GI_TYPE_TAG_FLOAT:
+ case GI_TYPE_TAG_DOUBLE:
+ case GI_TYPE_TAG_TIME_T:
+ case GI_TYPE_TAG_GTYPE:
+ if (is_pointer) {
+ g_warn_if_fail(transfer == GI_TRANSFER_NOTHING);
+ if ((direction == GI_DIRECTION_IN && transfer == GI_TRANSFER_NOTHING)
+ || (direction == GI_DIRECTION_OUT && transfer == GI_TRANSFER_EVERYTHING)) {
+ g_free(arg->v_pointer);
+ }
+ }
+ break;
+ case GI_TYPE_TAG_FILENAME:
+ case GI_TYPE_TAG_UTF8:
+ g_assert(is_pointer);
+ if ((direction == GI_DIRECTION_IN && transfer == GI_TRANSFER_NOTHING)
+ || (direction == GI_DIRECTION_OUT && transfer == GI_TRANSFER_EVERYTHING)) {
+ g_free(arg->v_string);
+ }
+ break;
+ case GI_TYPE_TAG_ARRAY:
+ {
+ GArray *array;
+ gsize i;
+
+ g_assert(is_pointer);
+
+ array = arg->v_pointer;
+
+ if ((direction == GI_DIRECTION_IN && transfer != GI_TRANSFER_EVERYTHING)
+ || (direction == GI_DIRECTION_OUT && transfer == GI_TRANSFER_EVERYTHING)) {
+ GITypeInfo *item_type_info;
+ GITransfer item_transfer;
+
+ item_type_info = g_type_info_get_param_type(type_info, 0);
+
+ item_transfer = direction == GI_DIRECTION_IN ? GI_TRANSFER_NOTHING : GI_TRANSFER_EVERYTHING;
+
+ /* Free the items */
+ for (i = 0; i < array->len; i++) {
+ GArgument item;
+ item = _g_array_index(array, GArgument, i);
+ _pygi_argument_release(&item, item_type_info, item_transfer, direction);
+ }
+
+ g_base_info_unref((GIBaseInfo *)item_type_info);
+ }
+
+ if ((direction == GI_DIRECTION_IN && transfer == GI_TRANSFER_NOTHING)
+ || (direction == GI_DIRECTION_OUT && transfer != GI_TRANSFER_NOTHING)) {
+ g_array_free(array, TRUE);
+ }
+
+ break;
+ }
+ case GI_TYPE_TAG_INTERFACE:
+ {
+ GIBaseInfo *info;
+ GIInfoType info_type;
+
+ info = g_type_info_get_interface(type_info);
+ info_type = g_base_info_get_type(info);
+
+ switch (info_type) {
+ case GI_INFO_TYPE_CALLBACK:
+ /* TODO */
+ break;
+ case GI_INFO_TYPE_BOXED:
+ case GI_INFO_TYPE_STRUCT:
+ {
+ GType type;
+
+ type = g_registered_type_info_get_g_type((GIRegisteredTypeInfo *)info);
+
+ if (g_type_is_a(type, G_TYPE_VALUE)) {
+ GValue *value;
+
+ g_assert(is_pointer);
+
+ value = arg->v_pointer;
+
+ if ((direction == GI_DIRECTION_IN && transfer != GI_TRANSFER_EVERYTHING)
+ || (direction == GI_DIRECTION_OUT && transfer == GI_TRANSFER_EVERYTHING)) {
+ g_value_unset(value);
+ }
+
+ if ((direction == GI_DIRECTION_IN && transfer == GI_TRANSFER_NOTHING)
+ || (direction == GI_DIRECTION_OUT && transfer != GI_TRANSFER_NOTHING)) {
+ g_slice_free(GValue, value);
+ }
+ } else if (g_type_is_a(type, G_TYPE_CLOSURE)) {
+ g_assert(is_pointer);
+ if (direction == GI_DIRECTION_IN && transfer == GI_TRANSFER_NOTHING) {
+ g_closure_unref(arg->v_pointer);
+ }
+ } else if (g_type_is_a(type, G_TYPE_BOXED)) {
+ g_assert(is_pointer);
+ } else if (g_type_is_a(type, G_TYPE_POINTER) || type == G_TYPE_NONE) {
+ g_warn_if_fail(!is_pointer || transfer == GI_TRANSFER_NOTHING);
+ }
+
+ break;
+ }
+ case GI_INFO_TYPE_ENUM:
+ case GI_INFO_TYPE_FLAGS:
+ if (is_pointer) {
+ g_warn_if_fail(transfer == GI_TRANSFER_NOTHING);
+ if ((direction == GI_DIRECTION_IN && transfer == GI_TRANSFER_NOTHING)
+ || (direction == GI_DIRECTION_OUT && transfer == GI_TRANSFER_EVERYTHING)) {
+ g_free(arg->v_pointer);
+ }
+ }
+ break;
+ case GI_INFO_TYPE_OBJECT:
+ g_assert(is_pointer);
+ if (direction == GI_DIRECTION_OUT && transfer == GI_TRANSFER_EVERYTHING) {
+ g_object_unref(arg->v_pointer);
+ }
+ break;
+ case GI_INFO_TYPE_UNION:
+ /* TODO */
+ break;
+ default:
+ g_assert_not_reached();
+ }
+
+ g_base_info_unref(info);
+ break;
+ }
+ case GI_TYPE_TAG_GLIST:
+ case GI_TYPE_TAG_GSLIST:
+ {
+ GSList *list;
+
+ g_assert(is_pointer);
+
+ list = arg->v_pointer;
+
+ if ((direction == GI_DIRECTION_IN && transfer != GI_TRANSFER_EVERYTHING)
+ || (direction == GI_DIRECTION_OUT && transfer == GI_TRANSFER_EVERYTHING)) {
+ GITypeInfo *item_type_info;
+ GITransfer item_transfer;
+ GSList *item;
+
+ item_type_info = g_type_info_get_param_type(type_info, 0);
+ g_assert(item_type_info != NULL);
+
+ item_transfer = direction == GI_DIRECTION_IN ? GI_TRANSFER_NOTHING : GI_TRANSFER_EVERYTHING;
+
+ /* Free the items */
+ for (item = list; item != NULL; item = g_slist_next(item)) {
+ _pygi_argument_release((GArgument *)&item->data, item_type_info,
+ item_transfer, direction);
+ }
+
+ g_base_info_unref((GIBaseInfo *)item_type_info);
+ }
+
+ if ((direction == GI_DIRECTION_IN && transfer == GI_TRANSFER_NOTHING)
+ || (direction == GI_DIRECTION_OUT && transfer != GI_TRANSFER_NOTHING)) {
+ if (type_tag == GI_TYPE_TAG_GLIST) {
+ g_list_free((GList *)list);
+ } else {
+ /* type_tag == GI_TYPE_TAG_GSLIST */
+ g_slist_free(list);
+ }
+ }
+
+ break;
+ }
+ case GI_TYPE_TAG_GHASH:
+ {
+ GHashTable *hash_table;
+
+ g_assert(is_pointer);
+
+ hash_table = arg->v_pointer;
+
+ if (direction == GI_DIRECTION_IN && transfer != GI_TRANSFER_EVERYTHING) {
+ /* We created the table without a destroy function, so keys and
+ * values need to be released. */
+ GITypeInfo *key_type_info;
+ GITypeInfo *value_type_info;
+ GITransfer item_transfer;
+ GHashTableIter hash_table_iter;
+ gpointer key;
+ gpointer value;
+
+ key_type_info = g_type_info_get_param_type(type_info, 0);
+ g_assert(key_type_info != NULL);
+
+ value_type_info = g_type_info_get_param_type(type_info, 1);
+ g_assert(value_type_info != NULL);
+
+ if (direction == GI_DIRECTION_IN) {
+ item_transfer = GI_TRANSFER_NOTHING;
+ } else {
+ item_transfer = GI_TRANSFER_EVERYTHING;
+ }
+
+ g_hash_table_iter_init(&hash_table_iter, hash_table);
+ while (g_hash_table_iter_next(&hash_table_iter, &key, &value)) {
+ _pygi_argument_release((GArgument *)&key, key_type_info,
+ item_transfer, direction);
+ _pygi_argument_release((GArgument *)&value, value_type_info,
+ item_transfer, direction);
+ }
+
+ g_base_info_unref((GIBaseInfo *)key_type_info);
+ g_base_info_unref((GIBaseInfo *)value_type_info);
+ } else if (direction == GI_DIRECTION_OUT && transfer == GI_TRANSFER_CONTAINER) {
+ /* Be careful to avoid keys and values being freed if the
+ * callee gave a destroy function. */
+ g_hash_table_steal_all(hash_table);
+ }
+
+ if ((direction == GI_DIRECTION_IN && transfer == GI_TRANSFER_NOTHING)
+ || (direction == GI_DIRECTION_OUT && transfer != GI_TRANSFER_NOTHING)) {
+ g_hash_table_unref(hash_table);
+ }
+
+ break;
+ }
+ case GI_TYPE_TAG_ERROR:
+ {
+ GError *error;
+
+ g_assert(is_pointer);
+
+ error = *(GError **)arg->v_pointer;
+
+ if (error != NULL) {
+ g_error_free(error);
+ }
+
+ g_slice_free(GError *, arg->v_pointer);
+ break;
+ }
+ }
+}
+
+void
+_pygi_argument_init (void)
+{
+ PyDateTime_IMPORT;
+ _pygobject_import();
+}
+
diff --git a/gi/pygi-argument.h b/gi/pygi-argument.h
new file mode 100644
index 0000000..59458fc
--- /dev/null
+++ b/gi/pygi-argument.h
@@ -0,0 +1,65 @@
+/* -*- Mode: C; c-basic-offset: 4 -*-
+ * vim: tabstop=4 shiftwidth=4 expandtab
+ *
+ * Copyright (C) 2005-2009 Johan Dahlin <johan@gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
+ * USA
+ */
+
+#ifndef __PYGI_ARGUMENT_H__
+#define __PYGI_ARGUMENT_H__
+
+#include <Python.h>
+
+#include <girepository.h>
+
+G_BEGIN_DECLS
+
+
+/* Private */
+
+gint _pygi_g_type_info_check_object (GITypeInfo *type_info,
+ gboolean may_be_null,
+ PyObject *object);
+
+gint _pygi_g_registered_type_info_check_object (GIRegisteredTypeInfo *info,
+ gboolean is_instance,
+ PyObject *object);
+
+
+GArray* _pygi_argument_to_array (GArgument *arg,
+ GArgument *args[],
+ GITypeInfo *type_info);
+
+GArgument _pygi_argument_from_object (PyObject *object,
+ GITypeInfo *type_info,
+ GITransfer transfer);
+
+PyObject* _pygi_argument_to_object (GArgument *arg,
+ GITypeInfo *type_info,
+ GITransfer transfer);
+
+
+void _pygi_argument_release (GArgument *arg,
+ GITypeInfo *type_info,
+ GITransfer transfer,
+ GIDirection direction);
+
+void _pygi_argument_init (void);
+
+G_END_DECLS
+
+#endif /* __PYGI_ARGUMENT_H__ */
diff --git a/gi/pygi-info.c b/gi/pygi-info.c
new file mode 100644
index 0000000..5f4a174
--- /dev/null
+++ b/gi/pygi-info.c
@@ -0,0 +1,2093 @@
+/* -*- Mode: C; c-basic-offset: 4 -*-
+ * vim: tabstop=4 shiftwidth=4 expandtab
+ *
+ * Copyright (C) 2005-2009 Johan Dahlin <johan@gnome.org>
+ *
+ * pygi-info.c: GI.*Info wrappers.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
+ * USA
+ */
+
+#include "pygi-private.h"
+
+#include <pygobject.h>
+
+#define _PyGI_DEFINE_INFO_TYPE(name, cname, base) \
+static PyMethodDef _Py##cname##_methods[]; \
+PyTypeObject Py##cname##_Type = { \
+ PyObject_HEAD_INIT(NULL) \
+ 0, \
+ "gi." name, /* tp_name */ \
+ sizeof(PyGIBaseInfo), /* tp_basicsize */ \
+ 0, /* tp_itemsize */ \
+ (destructor)NULL, /* tp_dealloc */ \
+ (printfunc)NULL, /* tp_print */ \
+ (getattrfunc)NULL, /* tp_getattr */ \
+ (setattrfunc)NULL, /* tp_setattr */ \
+ (cmpfunc)NULL, /* tp_compare */ \
+ (reprfunc)NULL, /* tp_repr */ \
+ NULL, /* tp_as_number */ \
+ NULL, /* tp_as_sequence */ \
+ NULL, /* tp_as_mapping */ \
+ (hashfunc)NULL, /* tp_hash */ \
+ (ternaryfunc)NULL, /* tp_call */ \
+ (reprfunc)NULL, /* tp_str */ \
+ (getattrofunc)NULL, /* tp_getattro */ \
+ (setattrofunc)NULL, /* tp_setattro */ \
+ NULL, /* tp_as_buffer */ \
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ \
+ NULL, /* tp_doc */ \
+ (traverseproc)NULL, /* tp_traverse */ \
+ (inquiry)NULL, /* tp_clear */ \
+ (richcmpfunc)NULL, /* tp_richcompare */ \
+ offsetof(PyGIBaseInfo, inst_weakreflist), /* tp_weaklistoffset */ \
+ (getiterfunc)NULL, /* tp_iter */ \
+ (iternextfunc)NULL, /* tp_iternext */ \
+ _Py##cname##_methods, /* tp_methods */ \
+ NULL, /* tp_members */ \
+ NULL, /* tp_getset */ \
+ &base /* tp_base */ \
+}
+
+
+/* BaseInfo */
+
+static void
+_base_info_dealloc (PyGIBaseInfo *self)
+{
+ PyObject_GC_UnTrack((PyObject *)self);
+
+ PyObject_ClearWeakRefs((PyObject *)self);
+
+ g_base_info_unref(self->info);
+
+ self->ob_type->tp_free((PyObject *)self);
+}
+
+static int
+_base_info_traverse (PyGIBaseInfo *self,
+ visitproc visit,
+ void *arg)
+{
+ return 0;
+}
+
+static PyObject *
+_base_info_repr (PyGIBaseInfo *self)
+{
+ return PyString_FromFormat("<%s object (%s) at 0x%p>",
+ self->ob_type->tp_name, g_base_info_get_name(self->info), (void *)self);
+}
+
+static PyMethodDef _PyGIBaseInfo_methods[];
+
+PyTypeObject PyGIBaseInfo_Type = {
+ PyObject_HEAD_INIT(NULL)
+ 0,
+ "gi.BaseInfo", /* tp_name */
+ sizeof(PyGIBaseInfo), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ (destructor)_base_info_dealloc, /* tp_dealloc */
+ (printfunc)NULL, /* tp_print */
+ (getattrfunc)NULL, /* tp_getattr */
+ (setattrfunc)NULL, /* tp_setattr */
+ (cmpfunc)NULL, /* tp_compare */
+ (reprfunc)_base_info_repr, /* tp_repr */
+ NULL, /* tp_as_number */
+ NULL, /* tp_as_sequence */
+ NULL, /* tp_as_mapping */
+ (hashfunc)NULL, /* tp_hash */
+ (ternaryfunc)NULL, /* tp_call */
+ (reprfunc)NULL, /* tp_str */
+ (getattrofunc)NULL, /* tp_getattro */
+ (setattrofunc)NULL, /* tp_setattro */
+ NULL, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
+ Py_TPFLAGS_HAVE_GC, /* tp_flags */
+ NULL, /* tp_doc */
+ (traverseproc)_base_info_traverse, /* tp_traverse */
+ (inquiry)NULL, /* tp_clear */
+ (richcmpfunc)NULL, /* tp_richcompare */
+ offsetof(PyGIBaseInfo, inst_weakreflist), /* tp_weaklistoffset */
+ (getiterfunc)NULL, /* tp_iter */
+ (iternextfunc)NULL, /* tp_iternext */
+ _PyGIBaseInfo_methods, /* tp_methods */
+};
+
+static PyObject *
+_wrap_g_base_info_get_name (PyGIBaseInfo *self)
+{
+ return PyString_FromString(g_base_info_get_name(self->info));
+}
+
+static PyObject *
+_wrap_g_base_info_get_namespace (PyGIBaseInfo *self)
+{
+ return PyString_FromString(g_base_info_get_namespace(self->info));
+}
+
+static PyObject *
+_wrap_g_base_info_get_container (PyGIBaseInfo *self)
+{
+ GIBaseInfo *info;
+
+ info = g_base_info_get_container(self->info);
+
+ if (info == NULL) {
+ Py_RETURN_NONE;
+ }
+
+ return _pygi_info_new(info);
+}
+
+
+static PyMethodDef _PyGIBaseInfo_methods[] = {
+ { "get_name", (PyCFunction)_wrap_g_base_info_get_name, METH_NOARGS },
+ { "get_namespace", (PyCFunction)_wrap_g_base_info_get_namespace, METH_NOARGS },
+ { "get_container", (PyCFunction)_wrap_g_base_info_get_container, METH_NOARGS },
+ { NULL, NULL, 0 }
+};
+
+PyObject *
+_pygi_info_new (GIBaseInfo *info)
+{
+ GIInfoType info_type;
+ PyTypeObject *type = NULL;
+ PyGIBaseInfo *self;
+
+ info_type = g_base_info_get_type(info);
+
+ switch (info_type)
+ {
+ case GI_INFO_TYPE_INVALID:
+ PyErr_SetString(PyExc_RuntimeError, "Invalid info type");
+ return NULL;
+ case GI_INFO_TYPE_FUNCTION:
+ type = &PyGIFunctionInfo_Type;
+ break;
+ case GI_INFO_TYPE_CALLBACK:
+ PyErr_SetString(PyExc_NotImplementedError, "GICallbackInfo bindings not implemented");
+ return NULL;
+ case GI_INFO_TYPE_STRUCT:
+ type = &PyGIStructInfo_Type;
+ break;
+ case GI_INFO_TYPE_BOXED:
+ PyErr_SetString(PyExc_NotImplementedError, "GIBoxedInfo bindings not implemented");
+ return NULL;
+ case GI_INFO_TYPE_ENUM:
+ case GI_INFO_TYPE_FLAGS:
+ type = &PyGIEnumInfo_Type;
+ break;
+ case GI_INFO_TYPE_OBJECT:
+ type = &PyGIObjectInfo_Type;
+ break;
+ case GI_INFO_TYPE_INTERFACE:
+ type = &PyGIInterfaceInfo_Type;
+ break;
+ case GI_INFO_TYPE_CONSTANT:
+ type = &PyGIConstantInfo_Type;
+ break;
+ case GI_INFO_TYPE_ERROR_DOMAIN:
+ PyErr_SetString(PyExc_NotImplementedError, "GIErrorDomainInfo bindings not implemented");
+ return NULL;
+ case GI_INFO_TYPE_UNION:
+ PyErr_SetString(PyExc_NotImplementedError, "GIUnionInfo bindings not implemented");
+ return NULL;
+ case GI_INFO_TYPE_VALUE:
+ type = &PyGIValueInfo_Type;
+ break;
+ case GI_INFO_TYPE_SIGNAL:
+ PyErr_SetString(PyExc_NotImplementedError, "GISignalInfo bindings not implemented");
+ return NULL;
+ case GI_INFO_TYPE_VFUNC:
+ PyErr_SetString(PyExc_NotImplementedError, "GIVFuncInfo bindings not implemented");
+ return NULL;
+ case GI_INFO_TYPE_PROPERTY:
+ PyErr_SetString(PyExc_NotImplementedError, "GIPropertyInfo bindings not implemented");
+ return NULL;
+ case GI_INFO_TYPE_FIELD:
+ type = &PyGIFieldInfo_Type;
+ break;
+ case GI_INFO_TYPE_ARG:
+ PyErr_SetString(PyExc_NotImplementedError, "GIArgInfo bindings not implemented");
+ return NULL;
+ case GI_INFO_TYPE_TYPE:
+ PyErr_SetString(PyExc_NotImplementedError, "GITypeInfo bindings not implemented");
+ return NULL;
+ case GI_INFO_TYPE_UNRESOLVED:
+ type = &PyGIUnresolvedInfo_Type;
+ break;
+ }
+
+ self = (PyGIBaseInfo *)type->tp_alloc(type, 0);
+ if (self == NULL) {
+ return NULL;
+ }
+
+ self->info = g_base_info_ref(info);
+
+ return (PyObject *)self;
+}
+
+GIBaseInfo *
+_pygi_object_get_gi_info (PyObject *object,
+ PyTypeObject *type)
+{
+ PyObject *py_info;
+ GIBaseInfo *info = NULL;
+
+ py_info = PyObject_GetAttrString(object, "__info__");
+ if (py_info == NULL) {
+ return NULL;
+ }
+ if (!PyObject_TypeCheck(py_info, type)) {
+ PyErr_Format(PyExc_TypeError, "attribute '__info__' must be %s, not %s",
+ type->tp_name, py_info->ob_type->tp_name);
+ goto out;
+ }
+
+ info = ((PyGIBaseInfo *)py_info)->info;
+ g_base_info_ref(info);
+
+out:
+ Py_DECREF(py_info);
+
+ return info;
+}
+
+
+/* CallableInfo */
+_PyGI_DEFINE_INFO_TYPE("CallableInfo", GICallableInfo, PyGIBaseInfo_Type);
+
+static PyMethodDef _PyGICallableInfo_methods[] = {
+ { NULL, NULL, 0 }
+};
+
+
+/* FunctionInfo */
+_PyGI_DEFINE_INFO_TYPE("FunctionInfo", GIFunctionInfo, PyGICallableInfo_Type);
+
+static PyObject *
+_wrap_g_function_info_is_constructor (PyGIBaseInfo *self)
+{
+ GIFunctionInfoFlags flags;
+ gboolean is_constructor;
+
+ flags = g_function_info_get_flags((GIFunctionInfo*)self->info);
+ is_constructor = flags & GI_FUNCTION_IS_CONSTRUCTOR;
+
+ return PyBool_FromLong(is_constructor);
+}
+
+static PyObject *
+_wrap_g_function_info_is_method (PyGIBaseInfo *self)
+{
+ GIFunctionInfoFlags flags;
+ gboolean is_method;
+
+ flags = g_function_info_get_flags((GIFunctionInfo*)self->info);
+ is_method = flags & GI_FUNCTION_IS_METHOD;
+
+ return PyBool_FromLong(is_method);
+}
+
+gsize
+_pygi_g_type_tag_size (GITypeTag type_tag)
+{
+ gsize size = 0;
+
+ switch(type_tag) {
+ case GI_TYPE_TAG_BOOLEAN:
+ size = sizeof(gboolean);
+ break;
+ case GI_TYPE_TAG_INT8:
+ case GI_TYPE_TAG_UINT8:
+ size = sizeof(gint8);
+ break;
+ case GI_TYPE_TAG_INT16:
+ case GI_TYPE_TAG_UINT16:
+ size = sizeof(gint16);
+ break;
+ case GI_TYPE_TAG_INT32:
+ case GI_TYPE_TAG_UINT32:
+ size = sizeof(gint32);
+ break;
+ case GI_TYPE_TAG_INT64:
+ case GI_TYPE_TAG_UINT64:
+ size = sizeof(gint64);
+ break;
+ case GI_TYPE_TAG_SHORT:
+ case GI_TYPE_TAG_USHORT:
+ size = sizeof(gshort);
+ break;
+ case GI_TYPE_TAG_INT:
+ case GI_TYPE_TAG_UINT:
+ size = sizeof(gint);
+ break;
+ case GI_TYPE_TAG_LONG:
+ case GI_TYPE_TAG_ULONG:
+ size = sizeof(glong);
+ break;
+ case GI_TYPE_TAG_SIZE:
+ case GI_TYPE_TAG_SSIZE:
+ size = sizeof(gsize);
+ break;
+ case GI_TYPE_TAG_FLOAT:
+ size = sizeof(gfloat);
+ break;
+ case GI_TYPE_TAG_DOUBLE:
+ size = sizeof(gdouble);
+ break;
+ case GI_TYPE_TAG_TIME_T:
+ size = sizeof(time_t);
+ break;
+ case GI_TYPE_TAG_GTYPE:
+ size = sizeof(GType);
+ break;
+ case GI_TYPE_TAG_VOID:
+ case GI_TYPE_TAG_UTF8:
+ case GI_TYPE_TAG_FILENAME:
+ case GI_TYPE_TAG_ARRAY:
+ case GI_TYPE_TAG_INTERFACE:
+ case GI_TYPE_TAG_GLIST:
+ case GI_TYPE_TAG_GSLIST:
+ case GI_TYPE_TAG_GHASH:
+ case GI_TYPE_TAG_ERROR:
+ PyErr_Format(PyExc_TypeError,
+ "Unable to know the size (assuming %s is not a pointer)",
+ g_type_tag_to_string(type_tag));
+ break;
+ }
+
+ return size;
+}
+
+gsize
+_pygi_g_type_info_size (GITypeInfo *type_info)
+{
+ gsize size = 0;
+ gboolean is_pointer;
+
+ is_pointer = g_type_info_is_pointer(type_info);
+
+ if (is_pointer) {
+ size = sizeof(gpointer);
+ } else {
+ GITypeTag type_tag;
+
+ type_tag = g_type_info_get_tag(type_info);
+ switch(type_tag) {
+ case GI_TYPE_TAG_BOOLEAN:
+ case GI_TYPE_TAG_INT8:
+ case GI_TYPE_TAG_UINT8:
+ case GI_TYPE_TAG_INT16:
+ case GI_TYPE_TAG_UINT16:
+ case GI_TYPE_TAG_INT32:
+ case GI_TYPE_TAG_UINT32:
+ case GI_TYPE_TAG_INT64:
+ case GI_TYPE_TAG_UINT64:
+ case GI_TYPE_TAG_SHORT:
+ case GI_TYPE_TAG_USHORT:
+ case GI_TYPE_TAG_INT:
+ case GI_TYPE_TAG_UINT:
+ case GI_TYPE_TAG_LONG:
+ case GI_TYPE_TAG_ULONG:
+ case GI_TYPE_TAG_SIZE:
+ case GI_TYPE_TAG_SSIZE:
+ case GI_TYPE_TAG_FLOAT:
+ case GI_TYPE_TAG_DOUBLE:
+ case GI_TYPE_TAG_TIME_T:
+ case GI_TYPE_TAG_GTYPE:
+ size = _pygi_g_type_tag_size(type_tag);
+ g_assert(size > 0);
+ break;
+ case GI_TYPE_TAG_INTERFACE:
+ {
+ GIBaseInfo *info;
+ GIInfoType info_type;
+
+ info = g_type_info_get_interface(type_info);
+ info_type = g_base_info_get_type(info);
+
+ switch (info_type) {
+ case GI_INFO_TYPE_STRUCT:
+ size = g_struct_info_get_size((GIStructInfo *)info);
+ break;
+ case GI_INFO_TYPE_UNION:
+ size = g_union_info_get_size((GIUnionInfo *)info);
+ break;
+ case GI_INFO_TYPE_ENUM:
+ case GI_INFO_TYPE_FLAGS:
+ {
+ GITypeTag type_tag;
+
+ type_tag = g_enum_info_get_storage_type((GIEnumInfo *)info);
+ size = _pygi_g_type_tag_size(type_tag);
+ break;
+ }
+ case GI_INFO_TYPE_BOXED:
+ case GI_INFO_TYPE_OBJECT:
+ case GI_INFO_TYPE_INTERFACE:
+ case GI_INFO_TYPE_CALLBACK:
+ /* Should have been catched by is_pointer above. */
+ case GI_INFO_TYPE_VFUNC:
+ case GI_INFO_TYPE_INVALID:
+ case GI_INFO_TYPE_FUNCTION:
+ case GI_INFO_TYPE_CONSTANT:
+ case GI_INFO_TYPE_ERROR_DOMAIN:
+ case GI_INFO_TYPE_VALUE:
+ case GI_INFO_TYPE_SIGNAL:
+ case GI_INFO_TYPE_PROPERTY:
+ case GI_INFO_TYPE_FIELD:
+ case GI_INFO_TYPE_ARG:
+ case GI_INFO_TYPE_TYPE:
+ case GI_INFO_TYPE_UNRESOLVED:
+ g_assert_not_reached();
+ break;
+ }
+
+ g_base_info_unref(info);
+ break;
+ }
+ case GI_TYPE_TAG_ARRAY:
+ case GI_TYPE_TAG_VOID:
+ case GI_TYPE_TAG_UTF8:
+ case GI_TYPE_TAG_FILENAME:
+ case GI_TYPE_TAG_GLIST:
+ case GI_TYPE_TAG_GSLIST:
+ case GI_TYPE_TAG_GHASH:
+ case GI_TYPE_TAG_ERROR:
+ /* Should have been catched by is_pointer above. */
+ g_assert_not_reached();
+ break;
+ }
+ }
+
+ return size;
+}
+
+
+static PyObject *
+_wrap_g_function_info_invoke (PyGIBaseInfo *self,
+ PyObject *py_args)
+{
+ gboolean is_method;
+ gboolean is_constructor;
+
+ gsize n_args;
+ gsize n_in_args;
+ gsize n_out_args;
+ gsize n_backup_args;
+ Py_ssize_t n_py_args;
+ gsize n_aux_in_args;
+ gsize n_aux_out_args;
+ gsize n_return_values;
+
+ glong error_arg_pos;
+
+ GIArgInfo **arg_infos;
+ GITypeInfo **arg_type_infos;
+ GITypeInfo *return_type_info;
+ GITypeTag return_type_tag;
+
+ GArgument **args;
+ gboolean *args_is_auxiliary;
+
+ GArgument *in_args;
+ GArgument *out_args;
+ GArgument *out_values;
+ GArgument *backup_args;
+ GArgument return_arg;
+
+ PyObject *return_value = NULL;
+
+ gsize i;
+
+ {
+ GIFunctionInfoFlags flags;
+
+ flags = g_function_info_get_flags((GIFunctionInfo *)self->info);
+ is_method = (flags & GI_FUNCTION_IS_METHOD) != 0;
+ is_constructor = (flags & GI_FUNCTION_IS_CONSTRUCTOR) != 0;
+ }
+
+ /* Count arguments. */
+ n_args = g_callable_info_get_n_args((GICallableInfo *)self->info);
+ n_in_args = 0;
+ n_out_args = 0;
+ n_backup_args = 0;
+ n_aux_in_args = 0;
+ n_aux_out_args = 0;
+
+ error_arg_pos = -1;
+
+ arg_infos = g_newa(GIArgInfo *, n_args);
+ arg_type_infos = g_newa(GITypeInfo *, n_args);
+
+ args_is_auxiliary = g_newa(gboolean, n_args);
+ memset(args_is_auxiliary, 0, sizeof(args_is_auxiliary) * n_args);
+
+ if (is_method) {
+ /* The first argument is the instance. */
+ n_in_args += 1;
+ }
+
+ for (i = 0; i < n_args; i++) {
+ GIDirection direction;
+ GITransfer transfer;
+ GITypeTag arg_type_tag;
+
+ arg_infos[i] = g_callable_info_get_arg((GICallableInfo *)self->info, i);
+ arg_type_infos[i] = g_arg_info_get_type(arg_infos[i]);
+
+ direction = g_arg_info_get_direction(arg_infos[i]);
+ transfer = g_arg_info_get_ownership_transfer(arg_infos[i]);
+ arg_type_tag = g_type_info_get_tag(arg_type_infos[i]);
+
+ if (direction == GI_DIRECTION_IN || direction == GI_DIRECTION_INOUT) {
+ n_in_args += 1;
+ if (transfer == GI_TRANSFER_CONTAINER) {
+ n_backup_args += 1;
+ }
+ }
+ if (direction == GI_DIRECTION_OUT || direction == GI_DIRECTION_INOUT) {
+ n_out_args += 1;
+ }
+
+ if (direction == GI_DIRECTION_INOUT && transfer == GI_TRANSFER_NOTHING) {
+ n_backup_args += 1;
+ }
+
+ switch (arg_type_tag) {
+ case GI_TYPE_TAG_ARRAY:
+ {
+ gint length_arg_pos;
+
+ length_arg_pos = g_type_info_get_array_length(arg_type_infos[i]);
+ if (length_arg_pos < 0) {
+ break;
+ }
+
+ g_assert(length_arg_pos < n_args);
+ args_is_auxiliary[length_arg_pos] = TRUE;
+
+ if (direction == GI_DIRECTION_IN || direction == GI_DIRECTION_INOUT) {
+ n_aux_in_args += 1;
+ }
+ if (direction == GI_DIRECTION_OUT || direction == GI_DIRECTION_INOUT) {
+ n_aux_out_args += 1;
+ }
+
+ break;
+ }
+ case GI_TYPE_TAG_ERROR:
+ g_warn_if_fail(error_arg_pos < 0);
+ error_arg_pos = i;
+ break;
+ default:
+ break;
+ }
+ }
+
+ return_type_info = g_callable_info_get_return_type((GICallableInfo *)self->info);
+ return_type_tag = g_type_info_get_tag(return_type_info);
+
+ if (return_type_tag == GI_TYPE_TAG_ARRAY) {
+ gint length_arg_pos;
+ length_arg_pos = g_type_info_get_array_length(return_type_info);
+ if (length_arg_pos >= 0) {
+ g_assert(length_arg_pos < n_args);
+ args_is_auxiliary[length_arg_pos] = TRUE;
+ n_aux_out_args += 1;
+ }
+ }
+
+ n_return_values = n_out_args - n_aux_out_args;
+ if (return_type_tag != GI_TYPE_TAG_VOID) {
+ n_return_values += 1;
+ }
+
+ {
+ gsize n_py_args_expected;
+ Py_ssize_t py_args_pos;
+
+ /* Check the argument count. */
+ n_py_args = PyTuple_Size(py_args);
+ g_assert(n_py_args >= 0);
+
+ n_py_args_expected = n_in_args
+ + (is_constructor ? 1 : 0)
+ - n_aux_in_args
+ - (error_arg_pos >= 0 ? 1 : 0);
+
+ if (n_py_args != n_py_args_expected) {
+ PyErr_Format(PyExc_TypeError,
+ "takes exactly %zd argument(s) (%zd given)",
+ n_py_args_expected, n_py_args);
+ goto out;
+ }
+
+ /* Check argument types. */
+ py_args_pos = 0;
+ if (is_constructor || is_method) {
+ py_args_pos += 1;
+ }
+
+ for (i = 0; i < n_args; i++) {
+ GIDirection direction;
+ GITypeTag type_tag;
+ gboolean may_be_null;
+ PyObject *py_arg;
+ gint retval;
+
+ direction = g_arg_info_get_direction(arg_infos[i]);
+ type_tag = g_type_info_get_tag(arg_type_infos[i]);
+
+ if (direction == GI_DIRECTION_OUT
+ || args_is_auxiliary[i]
+ || type_tag == GI_TYPE_TAG_ERROR) {
+ continue;
+ }
+
+ g_assert(py_args_pos < n_py_args);
+ py_arg = PyTuple_GET_ITEM(py_args, py_args_pos);
+
+ may_be_null = g_arg_info_may_be_null(arg_infos[i]);
+
+ retval = _pygi_g_type_info_check_object(arg_type_infos[i],
+ may_be_null, py_arg);
+
+ if (retval < 0) {
+ goto out;
+ } else if (!retval) {
+ _PyGI_ERROR_PREFIX("argument %zd: ", py_args_pos);
+ goto out;
+ }
+
+ py_args_pos += 1;
+ }
+
+ g_assert(py_args_pos == n_py_args);
+ }
+
+ args = g_newa(GArgument *, n_args);
+ in_args = g_newa(GArgument, n_in_args);
+ out_args = g_newa(GArgument, n_out_args);
+ out_values = g_newa(GArgument, n_out_args);
+ backup_args = g_newa(GArgument, n_backup_args);
+
+ /* Bind args so we can use an unique index. */
+ {
+ gsize in_args_pos;
+ gsize out_args_pos;
+
+ in_args_pos = is_method ? 1 : 0;
+ out_args_pos = 0;
+
+ for (i = 0; i < n_args; i++) {
+ GIDirection direction;
+
+ direction = g_arg_info_get_direction(arg_infos[i]);
+
+ switch (direction) {
+ case GI_DIRECTION_IN:
+ g_assert(in_args_pos < n_in_args);
+ args[i] = &in_args[in_args_pos];
+ in_args_pos += 1;
+ break;
+ case GI_DIRECTION_INOUT:
+ g_assert(in_args_pos < n_in_args);
+ g_assert(out_args_pos < n_out_args);
+ in_args[in_args_pos].v_pointer = &out_values[out_args_pos];
+ in_args_pos += 1;
+ case GI_DIRECTION_OUT:
+ g_assert(out_args_pos < n_out_args);
+ out_args[out_args_pos].v_pointer = &out_values[out_args_pos];
+ args[i] = &out_values[out_args_pos];
+ out_args_pos += 1;
+ }
+ }
+
+ g_assert(in_args_pos == n_in_args);
+ g_assert(out_args_pos == n_out_args);
+ }
+
+ /* Convert the input arguments. */
+ {
+ Py_ssize_t py_args_pos;
+ gsize backup_args_pos;
+
+ py_args_pos = 0;
+ backup_args_pos = 0;
+
+ if (is_constructor) {
+ /* Skip the first argument. */
+ py_args_pos += 1;
+ } else if (is_method) {
+ /* Get the instance. */
+ GIBaseInfo *container_info;
+ GIInfoType container_info_type;
+ PyObject *py_arg;
+
+ container_info = g_base_info_get_container(self->info);
+ container_info_type = g_base_info_get_type(container_info);
+
+ g_assert(py_args_pos < n_py_args);
+ py_arg = PyTuple_GET_ITEM(py_args, py_args_pos);
+
+ switch(container_info_type) {
+ case GI_INFO_TYPE_UNION:
+ PyErr_SetString(PyExc_NotImplementedError, "calling methods on unions is not supported yet.");
+ goto out;
+ break;
+ case GI_INFO_TYPE_STRUCT:
+ {
+ GType type;
+
+ type = g_registered_type_info_get_g_type((GIRegisteredTypeInfo *)container_info);
+
+ if (g_type_is_a(type, G_TYPE_BOXED)) {
+ g_assert(n_in_args > 0);
+ in_args[0].v_pointer = pyg_boxed_get(py_arg, void);
+ } else if (g_type_is_a(type, G_TYPE_POINTER) || type == G_TYPE_NONE) {
+ g_assert(n_in_args > 0);
+ in_args[0].v_pointer = pyg_pointer_get(py_arg, void);
+ } else {
+ PyErr_Format(PyExc_TypeError, "unable to convert an instance of '%s'", g_type_name(type));
+ goto out;
+ }
+
+ break;
+ }
+ case GI_INFO_TYPE_OBJECT:
+ case GI_INFO_TYPE_INTERFACE:
+ g_assert(n_in_args > 0);
+ in_args[0].v_pointer = pygobject_get(py_arg);
+ break;
+ default:
+ /* Other types don't have methods. */
+ g_assert_not_reached();
+ }
+
+ py_args_pos += 1;
+ }
+
+ for (i = 0; i < n_args; i++) {
+ GIDirection direction;
+
+ if (args_is_auxiliary[i]) {
+ continue;
+ }
+
+ direction = g_arg_info_get_direction(arg_infos[i]);
+
+ if (direction == GI_DIRECTION_IN || direction == GI_DIRECTION_INOUT) {
+ PyObject *py_arg;
+ GITypeTag arg_type_tag;
+ GITransfer transfer;
+
+ arg_type_tag = g_type_info_get_tag(arg_type_infos[i]);
+
+ if (arg_type_tag == GI_TYPE_TAG_ERROR) {
+ GError **error;
+
+ error = g_slice_new(GError *);
+ *error = NULL;
+
+ args[i]->v_pointer = error;
+ continue;
+ }
+
+ transfer = g_arg_info_get_ownership_transfer(arg_infos[i]);
+
+ g_assert(py_args_pos < n_py_args);
+ py_arg = PyTuple_GET_ITEM(py_args, py_args_pos);
+
+ *args[i] = _pygi_argument_from_object(py_arg, arg_type_infos[i], transfer);
+
+ if (PyErr_Occurred()) {
+ /* TODO: release previous input arguments. */
+ goto out;
+ }
+
+ if (direction == GI_DIRECTION_INOUT && transfer == GI_TRANSFER_NOTHING) {
+ /* We need to keep a copy of the argument to be able to release it later. */
+ g_assert(backup_args_pos < n_backup_args);
+ backup_args[backup_args_pos] = *args[i];
+ backup_args_pos += 1;
+ } else if (transfer == GI_TRANSFER_CONTAINER) {
+ /* We need to keep a copy of the items to be able to release them later. */
+ switch (arg_type_tag) {
+ case GI_TYPE_TAG_ARRAY:
+ {
+ GArray *array;
+ gsize item_size;
+ GArray *new_array;
+
+ array = args[i]->v_pointer;
+
+ item_size = g_array_get_element_size(array);
+
+ new_array = g_array_sized_new(FALSE, FALSE, item_size, array->len);
+ g_array_append_vals(new_array, array->data, array->len);
+
+ g_assert(backup_args_pos < n_backup_args);
+ backup_args[backup_args_pos].v_pointer = new_array;
+
+ break;
+ }
+ case GI_TYPE_TAG_GLIST:
+ g_assert(backup_args_pos < n_backup_args);
+ backup_args[backup_args_pos].v_pointer = g_list_copy(args[i]->v_pointer);
+ break;
+ case GI_TYPE_TAG_GSLIST:
+ g_assert(backup_args_pos < n_backup_args);
+ backup_args[backup_args_pos].v_pointer = g_slist_copy(args[i]->v_pointer);
+ break;
+ case GI_TYPE_TAG_GHASH:
+ {
+ GHashTable *hash_table;
+ GList *keys;
+ GList *values;
+
+ hash_table = args[i]->v_pointer;
+
+ keys = g_hash_table_get_keys(hash_table);
+ values = g_hash_table_get_values(hash_table);
+
+ g_assert(backup_args_pos < n_backup_args);
+ backup_args[backup_args_pos].v_pointer = g_list_concat(keys, values);
+
+ break;
+ }
+ default:
+ g_warn_if_reached();
+ }
+
+ backup_args_pos += 1;
+ }
+
+ if (arg_type_tag == GI_TYPE_TAG_ARRAY) {
+ GArray *array;
+ gssize length_arg_pos;
+
+ array = args[i]->v_pointer;
+
+ length_arg_pos = g_type_info_get_array_length(arg_type_infos[i]);
+ if (length_arg_pos >= 0) {
+ /* Set the auxiliary argument holding the length. */
+ args[length_arg_pos]->v_size = array->len;
+ }
+
+ /* Get rid of the GArray. */
+ args[i]->v_pointer = array->data;
+
+ if (direction != GI_DIRECTION_INOUT || transfer != GI_TRANSFER_NOTHING) {
+ /* The array hasn't been referenced anywhere, so free it to avoid losing memory. */
+ g_array_free(array, FALSE);
+ }
+ }
+
+ py_args_pos += 1;
+ }
+ }
+
+ g_assert(py_args_pos == n_py_args);
+ g_assert(backup_args_pos == n_backup_args);
+ }
+
+ /* Invoke the callable. */
+ {
+ GError *error;
+ gint retval;
+
+ error = NULL;
+
+ retval = g_function_info_invoke((GIFunctionInfo *)self->info,
+ in_args, n_in_args, out_args, n_out_args, &return_arg, &error);
+ if (!retval) {
+ g_assert(error != NULL);
+ /* TODO: raise the right error, out of the error domain. */
+ PyErr_SetString(PyExc_RuntimeError, error->message);
+ g_error_free(error);
+
+ /* TODO: release input arguments. */
+
+ goto out;
+ }
+ }
+
+ if (error_arg_pos >= 0) {
+ GError **error;
+
+ error = args[error_arg_pos]->v_pointer;
+
+ if (*error != NULL) {
+ /* TODO: raise the right error, out of the error domain, if applicable. */
+ PyErr_SetString(PyExc_Exception, (*error)->message);
+ g_error_free(*error);
+
+ /* TODO: release input arguments. */
+
+ goto out;
+ }
+ }
+
+ /* Convert the return value. */
+ if (is_constructor) {
+ PyTypeObject *py_type;
+ GIBaseInfo *info;
+ GIInfoType info_type;
+ GITransfer transfer;
+
+ g_assert(n_py_args > 0);
+ py_type = (PyTypeObject *)PyTuple_GET_ITEM(py_args, 0);
+
+ info = g_type_info_get_interface(return_type_info);
+ g_assert(info != NULL);
+
+ info_type = g_base_info_get_type(info);
+
+ transfer = g_callable_info_get_caller_owns((GICallableInfo *)self->info);
+
+ switch (info_type) {
+ case GI_INFO_TYPE_UNION:
+ /* TODO */
+ PyErr_SetString(PyExc_NotImplementedError, "creating unions is not supported yet");
+ g_base_info_unref(info);
+ goto out;
+ case GI_INFO_TYPE_STRUCT:
+ {
+ GType type;
+
+ type = g_registered_type_info_get_g_type((GIRegisteredTypeInfo *)info);
+
+ if (g_type_is_a(type, G_TYPE_BOXED)) {
+ if (return_arg.v_pointer == NULL) {
+ PyErr_SetString(PyExc_TypeError, "constructor returned NULL");
+ break;
+ }
+ g_warn_if_fail(transfer == GI_TRANSFER_EVERYTHING);
+ return_value = pyg_boxed_new(type, return_arg.v_pointer, FALSE, transfer == GI_TRANSFER_EVERYTHING);
+ } else if (g_type_is_a(type, G_TYPE_POINTER) || type == G_TYPE_NONE) {
+ if (return_arg.v_pointer == NULL) {
+ PyErr_SetString(PyExc_TypeError, "constructor returned NULL");
+ break;
+ }
+ g_warn_if_fail(transfer == GI_TRANSFER_NOTHING);
+ return_value = _pygi_struct_new(py_type, return_arg.v_pointer, transfer == GI_TRANSFER_EVERYTHING);
+ } else {
+ PyErr_Format(PyExc_TypeError, "cannot create '%s' instances", py_type->tp_name);
+ g_base_info_unref(info);
+ goto out;
+ }
+
+ break;
+ }
+ case GI_INFO_TYPE_OBJECT:
+ if (return_arg.v_pointer == NULL) {
+ PyErr_SetString(PyExc_TypeError, "constructor returned NULL");
+ break;
+ }
+ return_value = pygobject_new(return_arg.v_pointer);
+ if (transfer == GI_TRANSFER_EVERYTHING) {
+ /* The new wrapper increased the reference count, so decrease it. */
+ g_object_unref (return_arg.v_pointer);
+ }
+ break;
+ default:
+ /* Other types don't have neither methods nor constructors. */
+ g_assert_not_reached();
+ }
+
+ g_base_info_unref(info);
+
+ if (return_value == NULL) {
+ /* TODO: release arguments. */
+ goto out;
+ }
+ } else {
+ GITransfer transfer;
+
+ if (return_type_tag == GI_TYPE_TAG_ARRAY) {
+ /* Create a #GArray. */
+ return_arg.v_pointer = _pygi_argument_to_array(&return_arg, args, return_type_info);
+ }
+
+ transfer = g_callable_info_get_caller_owns((GICallableInfo *)self->info);
+
+ return_value = _pygi_argument_to_object(&return_arg, return_type_info, transfer);
+ if (return_value == NULL) {
+ /* TODO: release argument. */
+ goto out;
+ }
+
+ _pygi_argument_release(&return_arg, return_type_info, transfer, GI_DIRECTION_OUT);
+
+ if (return_type_tag == GI_TYPE_TAG_ARRAY
+ && transfer == GI_TRANSFER_NOTHING) {
+ /* We created a #GArray, so free it. */
+ return_arg.v_pointer = g_array_free(return_arg.v_pointer, FALSE);
+ }
+ }
+
+ /* Convert output arguments and release arguments. */
+ {
+ gsize backup_args_pos;
+ gsize return_values_pos;
+
+ backup_args_pos = 0;
+ return_values_pos = 0;
+
+ if (n_return_values > 1) {
+ /* Return a tuple. */
+ PyObject *return_values;
+
+ return_values = PyTuple_New(n_return_values);
+ if (return_values == NULL) {
+ /* TODO: release arguments. */
+ goto out;
+ }
+
+ if (return_type_tag == GI_TYPE_TAG_VOID) {
+ /* The current return value is None. */
+ Py_DECREF(return_value);
+ } else {
+ /* Put the return value first. */
+ g_assert(return_value != NULL);
+ PyTuple_SET_ITEM(return_values, return_values_pos, return_value);
+ return_values_pos += 1;
+ }
+
+ return_value = return_values;
+ }
+
+ for (i = 0; i < n_args; i++) {
+ GIDirection direction;
+ GITypeTag type_tag;
+ GITransfer transfer;
+
+ if (args_is_auxiliary[i]) {
+ /* Auxiliary arguments are handled at the same time as their relatives. */
+ continue;
+ }
+
+ direction = g_arg_info_get_direction(arg_infos[i]);
+ transfer = g_arg_info_get_ownership_transfer(arg_infos[i]);
+
+ type_tag = g_type_info_get_tag(arg_type_infos[i]);
+
+ if (type_tag == GI_TYPE_TAG_ARRAY
+ && (direction != GI_DIRECTION_IN || transfer == GI_TRANSFER_NOTHING)) {
+ /* Create a #GArray. */
+ args[i]->v_pointer = _pygi_argument_to_array(args[i], args, arg_type_infos[i]);
+ }
+
+ if (direction == GI_DIRECTION_INOUT || direction == GI_DIRECTION_OUT) {
+ /* Convert the argument. */
+ PyObject *obj;
+
+ obj = _pygi_argument_to_object(args[i], arg_type_infos[i], transfer);
+ if (obj == NULL) {
+ /* TODO: release arguments. */
+ goto out;
+ }
+
+ g_assert(return_values_pos < n_return_values);
+
+ if (n_return_values > 1) {
+ PyTuple_SET_ITEM(return_value, return_values_pos, obj);
+ } else {
+ /* The current return value is None. */
+ Py_DECREF(return_value);
+ return_value = obj;
+ }
+
+ return_values_pos += 1;
+ }
+
+ /* Release the argument. */
+
+ if ((direction == GI_DIRECTION_IN || direction == GI_DIRECTION_INOUT)
+ && transfer == GI_TRANSFER_CONTAINER) {
+ /* Release the items we kept in another container. */
+ switch (type_tag) {
+ case GI_TYPE_TAG_ARRAY:
+ case GI_TYPE_TAG_GLIST:
+ case GI_TYPE_TAG_GSLIST:
+ g_assert(backup_args_pos < n_backup_args);
+ _pygi_argument_release(&backup_args[backup_args_pos], arg_type_infos[i],
+ transfer, GI_DIRECTION_IN);
+ break;
+ case GI_TYPE_TAG_GHASH:
+ {
+ GITypeInfo *key_type_info;
+ GITypeInfo *value_type_info;
+ GList *item;
+ gsize length;
+ gsize j;
+
+ key_type_info = g_type_info_get_param_type(arg_type_infos[i], 0);
+ value_type_info = g_type_info_get_param_type(arg_type_infos[i], 1);
+
+ g_assert(backup_args_pos < n_backup_args);
+ item = backup_args[backup_args_pos].v_pointer;
+
+ length = g_list_length(item) / 2;
+
+ for (j = 0; j < length; j++, item = g_list_next(item)) {
+ _pygi_argument_release((GArgument *)&item->data, key_type_info,
+ GI_TRANSFER_NOTHING, GI_DIRECTION_IN);
+ }
+
+ for (j = 0; j < length; j++, item = g_list_next(item)) {
+ _pygi_argument_release((GArgument *)&item->data, value_type_info,
+ GI_TRANSFER_NOTHING, GI_DIRECTION_IN);
+ }
+
+ g_list_free(backup_args[backup_args_pos].v_pointer);
+
+ break;
+ }
+ default:
+ g_warn_if_reached();
+ }
+
+ if (direction == GI_DIRECTION_INOUT) {
+ /* Release the output argument. */
+ _pygi_argument_release(args[i], arg_type_infos[i], GI_TRANSFER_CONTAINER,
+ GI_DIRECTION_OUT);
+ }
+
+ backup_args_pos += 1;
+ } else if (direction == GI_DIRECTION_INOUT) {
+ if (transfer == GI_TRANSFER_NOTHING) {
+ g_assert(backup_args_pos < n_backup_args);
+ _pygi_argument_release(&backup_args[backup_args_pos], arg_type_infos[i],
+ GI_TRANSFER_NOTHING, GI_DIRECTION_IN);
+ backup_args_pos += 1;
+ }
+
+ _pygi_argument_release(args[i], arg_type_infos[i], transfer,
+ GI_DIRECTION_OUT);
+ } else {
+ _pygi_argument_release(args[i], arg_type_infos[i], transfer, direction);
+ }
+
+ if (type_tag == GI_TYPE_TAG_ARRAY
+ && (direction != GI_DIRECTION_IN && transfer == GI_TRANSFER_NOTHING)) {
+ /* We created a #GArray and it has not been released above, so free it. */
+ args[i]->v_pointer = g_array_free(args[i]->v_pointer, FALSE);
+ }
+ }
+
+ g_assert(n_return_values <= 1 || return_values_pos == n_return_values);
+ g_assert(backup_args_pos == n_backup_args);
+ }
+
+out:
+ g_base_info_unref((GIBaseInfo *)return_type_info);
+
+ for (i = 0; i < n_args; i++) {
+ g_base_info_unref((GIBaseInfo *)arg_type_infos[i]);
+ g_base_info_unref((GIBaseInfo *)arg_infos[i]);
+ }
+
+ if (PyErr_Occurred()) {
+ Py_CLEAR(return_value);
+ }
+
+ return return_value;
+}
+
+static PyMethodDef _PyGIFunctionInfo_methods[] = {
+ { "is_constructor", (PyCFunction)_wrap_g_function_info_is_constructor, METH_NOARGS },
+ { "is_method", (PyCFunction)_wrap_g_function_info_is_method, METH_NOARGS },
+ { "invoke", (PyCFunction)_wrap_g_function_info_invoke, METH_VARARGS },
+ { NULL, NULL, 0 }
+};
+
+
+/* RegisteredTypeInfo */
+_PyGI_DEFINE_INFO_TYPE("RegisteredTypeInfo", GIRegisteredTypeInfo, PyGIBaseInfo_Type);
+
+static PyObject *
+_wrap_g_registered_type_info_get_g_type (PyGIBaseInfo *self)
+{
+ GType type;
+
+ type = g_registered_type_info_get_g_type((GIRegisteredTypeInfo *)self->info);
+
+ return pyg_type_wrapper_new(type);
+}
+
+static PyMethodDef _PyGIRegisteredTypeInfo_methods[] = {
+ { "get_g_type", (PyCFunction)_wrap_g_registered_type_info_get_g_type, METH_NOARGS },
+ { NULL, NULL, 0 }
+};
+
+
+/* GIStructInfo */
+_PyGI_DEFINE_INFO_TYPE("StructInfo", GIStructInfo, PyGIRegisteredTypeInfo_Type);
+
+static PyObject *
+_wrap_g_struct_info_get_fields (PyGIBaseInfo *self)
+{
+ gssize n_infos;
+ PyObject *infos;
+ gssize i;
+
+ n_infos = g_struct_info_get_n_fields((GIStructInfo *)self->info);
+
+ infos = PyTuple_New(n_infos);
+ if (infos == NULL) {
+ return NULL;
+ }
+
+ for (i = 0; i < n_infos; i++) {
+ GIBaseInfo *info;
+ PyObject *py_info;
+
+ info = (GIBaseInfo *)g_struct_info_get_field((GIStructInfo *)self->info, i);
+ g_assert(info != NULL);
+
+ py_info = _pygi_info_new(info);
+
+ g_base_info_unref(info);
+
+ if (py_info == NULL) {
+ Py_CLEAR(infos);
+ break;
+ }
+
+ PyTuple_SET_ITEM(infos, i, py_info);
+ }
+
+ return infos;
+}
+
+static PyObject *
+_wrap_g_struct_info_get_methods (PyGIBaseInfo *self)
+{
+ gssize n_infos;
+ PyObject *infos;
+ gssize i;
+
+ n_infos = g_struct_info_get_n_methods((GIStructInfo *)self->info);
+
+ infos = PyTuple_New(n_infos);
+ if (infos == NULL) {
+ return NULL;
+ }
+
+ for (i = 0; i < n_infos; i++) {
+ GIBaseInfo *info;
+ PyObject *py_info;
+
+ info = (GIBaseInfo *)g_struct_info_get_method((GIStructInfo *)self->info, i);
+ g_assert(info != NULL);
+
+ py_info = _pygi_info_new(info);
+
+ g_base_info_unref(info);
+
+ if (py_info == NULL) {
+ Py_CLEAR(infos);
+ break;
+ }
+
+ PyTuple_SET_ITEM(infos, i, py_info);
+ }
+
+ return infos;
+}
+
+static PyMethodDef _PyGIStructInfo_methods[] = {
+ { "get_fields", (PyCFunction)_wrap_g_struct_info_get_fields, METH_NOARGS },
+ { "get_methods", (PyCFunction)_wrap_g_struct_info_get_methods, METH_NOARGS },
+ { NULL, NULL, 0 }
+};
+
+gboolean
+pygi_g_struct_info_is_simple (GIStructInfo *struct_info)
+{
+ gboolean is_simple;
+ gsize n_field_infos;
+ gsize i;
+
+ is_simple = TRUE;
+
+ n_field_infos = g_struct_info_get_n_fields(struct_info);
+
+ for (i = 0; i < n_field_infos && is_simple; i++) {
+ GIFieldInfo *field_info;
+ GITypeInfo *field_type_info;
+ gboolean is_pointer;
+
+ field_info = g_struct_info_get_field(struct_info, i);
+ field_type_info = g_field_info_get_type(field_info);
+ is_pointer = g_type_info_is_pointer(field_type_info);
+
+ if (is_pointer) {
+ is_simple = FALSE;
+ } else {
+ GITypeTag field_type_tag;
+
+ field_type_tag = g_type_info_get_tag(field_type_info);
+
+ switch (field_type_tag) {
+ case GI_TYPE_TAG_BOOLEAN:
+ case GI_TYPE_TAG_INT8:
+ case GI_TYPE_TAG_UINT8:
+ case GI_TYPE_TAG_INT16:
+ case GI_TYPE_TAG_UINT16:
+ case GI_TYPE_TAG_INT32:
+ case GI_TYPE_TAG_UINT32:
+ case GI_TYPE_TAG_SHORT:
+ case GI_TYPE_TAG_USHORT:
+ case GI_TYPE_TAG_INT:
+ case GI_TYPE_TAG_UINT:
+ case GI_TYPE_TAG_INT64:
+ case GI_TYPE_TAG_UINT64:
+ case GI_TYPE_TAG_LONG:
+ case GI_TYPE_TAG_ULONG:
+ case GI_TYPE_TAG_SSIZE:
+ case GI_TYPE_TAG_SIZE:
+ case GI_TYPE_TAG_FLOAT:
+ case GI_TYPE_TAG_DOUBLE:
+ case GI_TYPE_TAG_TIME_T:
+ break;
+ case GI_TYPE_TAG_VOID:
+ case GI_TYPE_TAG_GTYPE:
+ case GI_TYPE_TAG_ERROR:
+ case GI_TYPE_TAG_UTF8:
+ case GI_TYPE_TAG_FILENAME:
+ case GI_TYPE_TAG_ARRAY:
+ case GI_TYPE_TAG_GLIST:
+ case GI_TYPE_TAG_GSLIST:
+ case GI_TYPE_TAG_GHASH:
+ /* Should have been catched by is_pointer above. */
+ g_assert_not_reached();
+ break;
+ case GI_TYPE_TAG_INTERFACE:
+ {
+ GIBaseInfo *info;
+ GIInfoType info_type;
+
+ info = g_type_info_get_interface(field_type_info);
+ info_type = g_base_info_get_type(info);
+
+ switch (info_type) {
+ case GI_INFO_TYPE_BOXED:
+ case GI_INFO_TYPE_STRUCT:
+ is_simple = pygi_g_struct_info_is_simple((GIStructInfo *)info);
+ break;
+ case GI_INFO_TYPE_UNION:
+ /* TODO */
+ is_simple = FALSE;
+ break;
+ case GI_INFO_TYPE_ENUM:
+ case GI_INFO_TYPE_FLAGS:
+ break;
+ case GI_INFO_TYPE_OBJECT:
+ case GI_INFO_TYPE_VFUNC:
+ case GI_INFO_TYPE_CALLBACK:
+ case GI_INFO_TYPE_INVALID:
+ case GI_INFO_TYPE_INTERFACE:
+ case GI_INFO_TYPE_FUNCTION:
+ case GI_INFO_TYPE_CONSTANT:
+ case GI_INFO_TYPE_ERROR_DOMAIN:
+ case GI_INFO_TYPE_VALUE:
+ case GI_INFO_TYPE_SIGNAL:
+ case GI_INFO_TYPE_PROPERTY:
+ case GI_INFO_TYPE_FIELD:
+ case GI_INFO_TYPE_ARG:
+ case GI_INFO_TYPE_TYPE:
+ case GI_INFO_TYPE_UNRESOLVED:
+ is_simple = FALSE;
+ break;
+ }
+
+ g_base_info_unref(info);
+ break;
+ }
+ }
+ }
+
+ g_base_info_unref((GIBaseInfo *)field_type_info);
+ g_base_info_unref((GIBaseInfo *)field_info);
+ }
+
+ return is_simple;
+}
+
+
+/* EnumInfo */
+_PyGI_DEFINE_INFO_TYPE("EnumInfo", GIEnumInfo, PyGIRegisteredTypeInfo_Type);
+
+static PyObject *
+_wrap_g_enum_info_get_values (PyGIBaseInfo *self)
+{
+ gssize n_infos;
+ PyObject *infos;
+ gssize i;
+
+ n_infos = g_enum_info_get_n_values((GIEnumInfo *)self->info);
+
+ infos = PyTuple_New(n_infos);
+ if (infos == NULL) {
+ return NULL;
+ }
+
+ for (i = 0; i < n_infos; i++) {
+ GIBaseInfo *info;
+ PyObject *py_info;
+
+ info = (GIBaseInfo *)g_enum_info_get_value((GIEnumInfo *)self->info, i);
+ g_assert(info != NULL);
+
+ py_info = _pygi_info_new(info);
+
+ g_base_info_unref(info);
+
+ if (py_info == NULL) {
+ Py_CLEAR(infos);
+ break;
+ }
+
+ PyTuple_SET_ITEM(infos, i, py_info);
+ }
+
+ return infos;
+}
+
+static PyMethodDef _PyGIEnumInfo_methods[] = {
+ { "get_values", (PyCFunction)_wrap_g_enum_info_get_values, METH_NOARGS },
+ { NULL, NULL, 0 }
+};
+
+
+/* ObjectInfo */
+_PyGI_DEFINE_INFO_TYPE("ObjectInfo", GIObjectInfo, PyGIRegisteredTypeInfo_Type);
+
+static PyObject *
+_wrap_g_object_info_get_parent (PyGIBaseInfo *self)
+{
+ GIBaseInfo *info;
+ PyObject *py_info;
+
+ info = (GIBaseInfo *)g_object_info_get_parent((GIObjectInfo*)self->info);
+
+ if (info == NULL) {
+ Py_RETURN_NONE;
+ }
+
+ py_info = _pygi_info_new(info);
+
+ g_base_info_unref(info);
+
+ return py_info;
+}
+
+static PyObject *
+_wrap_g_object_info_get_methods (PyGIBaseInfo *self)
+{
+ gssize n_infos;
+ PyObject *infos;
+ gssize i;
+
+ n_infos = g_object_info_get_n_methods((GIObjectInfo *)self->info);
+
+ infos = PyTuple_New(n_infos);
+ if (infos == NULL) {
+ return NULL;
+ }
+
+ for (i = 0; i < n_infos; i++) {
+ GIBaseInfo *info;
+ PyObject *py_info;
+
+ info = (GIBaseInfo *)g_object_info_get_method((GIObjectInfo *)self->info, i);
+ g_assert(info != NULL);
+
+ py_info = _pygi_info_new(info);
+
+ g_base_info_unref(info);
+
+ if (py_info == NULL) {
+ Py_CLEAR(infos);
+ break;
+ }
+
+ PyTuple_SET_ITEM(infos, i, py_info);
+ }
+
+ return infos;
+}
+
+static PyObject *
+_wrap_g_object_info_get_fields (PyGIBaseInfo *self)
+{
+ gssize n_infos;
+ PyObject *infos;
+ gssize i;
+
+ n_infos = g_object_info_get_n_fields((GIObjectInfo *)self->info);
+
+ infos = PyTuple_New(n_infos);
+ if (infos == NULL) {
+ return NULL;
+ }
+
+ for (i = 0; i < n_infos; i++) {
+ GIBaseInfo *info;
+ PyObject *py_info;
+
+ info = (GIBaseInfo *)g_object_info_get_field((GIObjectInfo *)self->info, i);
+ g_assert(info != NULL);
+
+ py_info = _pygi_info_new(info);
+
+ g_base_info_unref(info);
+
+ if (py_info == NULL) {
+ Py_CLEAR(infos);
+ break;
+ }
+
+ PyTuple_SET_ITEM(infos, i, py_info);
+ }
+
+ return infos;
+}
+
+static PyObject *
+_wrap_g_object_info_get_interfaces (PyGIBaseInfo *self)
+{
+ gssize n_infos;
+ PyObject *infos;
+ gssize i;
+
+ n_infos = g_object_info_get_n_interfaces((GIObjectInfo *)self->info);
+
+ infos = PyTuple_New(n_infos);
+ if (infos == NULL) {
+ return NULL;
+ }
+
+ for (i = 0; i < n_infos; i++) {
+ GIBaseInfo *info;
+ PyObject *py_info;
+
+ info = (GIBaseInfo *)g_object_info_get_interface((GIObjectInfo *)self->info, i);
+ g_assert(info != NULL);
+
+ py_info = _pygi_info_new(info);
+
+ g_base_info_unref(info);
+
+ if (py_info == NULL) {
+ Py_CLEAR(infos);
+ break;
+ }
+
+ PyTuple_SET_ITEM(infos, i, py_info);
+ }
+
+ return infos;
+}
+
+static PyObject *
+_wrap_g_object_info_get_constants (PyGIBaseInfo *self)
+{
+ gssize n_infos;
+ PyObject *infos;
+ gssize i;
+
+ n_infos = g_object_info_get_n_constants((GIObjectInfo *)self->info);
+
+ infos = PyTuple_New(n_infos);
+ if (infos == NULL) {
+ return NULL;
+ }
+
+ for (i = 0; i < n_infos; i++) {
+ GIBaseInfo *info;
+ PyObject *py_info;
+
+ info = (GIBaseInfo *)g_object_info_get_constant((GIObjectInfo *)self->info, i);
+ g_assert(info != NULL);
+
+ py_info = _pygi_info_new(info);
+
+ g_base_info_unref(info);
+
+ if (py_info == NULL) {
+ Py_CLEAR(infos);
+ break;
+ }
+
+ PyTuple_SET_ITEM(infos, i, py_info);
+ }
+
+ return infos;
+}
+
+static PyMethodDef _PyGIObjectInfo_methods[] = {
+ { "get_parent", (PyCFunction)_wrap_g_object_info_get_parent, METH_NOARGS },
+ { "get_methods", (PyCFunction)_wrap_g_object_info_get_methods, METH_NOARGS },
+ { "get_fields", (PyCFunction)_wrap_g_object_info_get_fields, METH_NOARGS },
+ { "get_interfaces", (PyCFunction)_wrap_g_object_info_get_interfaces, METH_NOARGS },
+ { "get_constants", (PyCFunction)_wrap_g_object_info_get_constants, METH_NOARGS },
+ { NULL, NULL, 0 }
+};
+
+
+/* GIInterfaceInfo */
+_PyGI_DEFINE_INFO_TYPE("InterfaceInfo", GIInterfaceInfo, PyGIRegisteredTypeInfo_Type);
+
+static PyObject *
+_wrap_g_interface_info_get_methods (PyGIBaseInfo *self)
+{
+ gssize n_infos;
+ PyObject *infos;
+ gssize i;
+
+ n_infos = g_interface_info_get_n_methods((GIInterfaceInfo *)self->info);
+
+ infos = PyTuple_New(n_infos);
+ if (infos == NULL) {
+ return NULL;
+ }
+
+ for (i = 0; i < n_infos; i++) {
+ GIBaseInfo *info;
+ PyObject *py_info;
+
+ info = (GIBaseInfo *)g_interface_info_get_method((GIInterfaceInfo *)self->info, i);
+ g_assert(info != NULL);
+
+ py_info = _pygi_info_new(info);
+
+ g_base_info_unref(info);
+
+ if (py_info == NULL) {
+ Py_CLEAR(infos);
+ break;
+ }
+
+ PyTuple_SET_ITEM(infos, i, py_info);
+ }
+
+ return infos;
+}
+
+static PyObject *
+_wrap_g_interface_info_get_constants (PyGIBaseInfo *self)
+{
+ gssize n_infos;
+ PyObject *infos;
+ gssize i;
+
+ n_infos = g_interface_info_get_n_constants((GIInterfaceInfo *)self->info);
+
+ infos = PyTuple_New(n_infos);
+ if (infos == NULL) {
+ return NULL;
+ }
+
+ for (i = 0; i < n_infos; i++) {
+ GIBaseInfo *info;
+ PyObject *py_info;
+
+ info = (GIBaseInfo *)g_interface_info_get_constant((GIInterfaceInfo *)self->info, i);
+ g_assert(info != NULL);
+
+ py_info = _pygi_info_new(info);
+
+ g_base_info_unref(info);
+
+ if (py_info == NULL) {
+ Py_CLEAR(infos);
+ break;
+ }
+
+ PyTuple_SET_ITEM(infos, i, py_info);
+ }
+
+ return infos;
+}
+
+static PyMethodDef _PyGIInterfaceInfo_methods[] = {
+ { "get_methods", (PyCFunction)_wrap_g_interface_info_get_methods, METH_NOARGS },
+ { "get_constants", (PyCFunction)_wrap_g_interface_info_get_constants, METH_NOARGS },
+ { NULL, NULL, 0 }
+};
+
+/* GIConstantInfo */
+_PyGI_DEFINE_INFO_TYPE("ConstantInfo", GIConstantInfo, PyGIBaseInfo_Type);
+
+static PyObject *
+_wrap_g_constant_info_get_value (PyGIBaseInfo *self)
+{
+ GITypeInfo *type_info;
+ GArgument value;
+ PyObject *py_value;
+
+ if (g_constant_info_get_value((GIConstantInfo *)self->info, &value) < 0) {
+ PyErr_SetString(PyExc_RuntimeError, "unable to get value");
+ return NULL;
+ }
+
+ type_info = g_constant_info_get_type((GIConstantInfo *)self->info);
+
+ py_value = _pygi_argument_to_object(&value, type_info, GI_TRANSFER_NOTHING);
+
+ g_base_info_unref((GIBaseInfo *)type_info);
+
+ return py_value;
+}
+
+static PyMethodDef _PyGIConstantInfo_methods[] = {
+ { "get_value", (PyCFunction)_wrap_g_constant_info_get_value, METH_NOARGS },
+ { NULL, NULL, 0 }
+};
+
+/* GIValueInfo */
+_PyGI_DEFINE_INFO_TYPE("ValueInfo", GIValueInfo, PyGIBaseInfo_Type);
+
+static PyObject *
+_wrap_g_value_info_get_value (PyGIBaseInfo *self)
+{
+ glong value;
+
+ value = g_value_info_get_value((GIValueInfo *)self->info);
+
+ return PyInt_FromLong(value);
+}
+
+
+static PyMethodDef _PyGIValueInfo_methods[] = {
+ { "get_value", (PyCFunction)_wrap_g_value_info_get_value, METH_NOARGS },
+ { NULL, NULL, 0 }
+};
+
+
+/* GIFieldInfo */
+_PyGI_DEFINE_INFO_TYPE("FieldInfo", GIFieldInfo, PyGIBaseInfo_Type);
+
+static PyObject *
+_wrap_g_field_info_get_value (PyGIBaseInfo *self,
+ PyObject *args)
+{
+ PyObject *instance;
+ GIBaseInfo *container_info;
+ GIInfoType container_info_type;
+ gpointer pointer;
+ GITypeInfo *field_type_info;
+ GArgument value;
+ PyObject *py_value = NULL;
+
+ if (!PyArg_ParseTuple(args, "O:FieldInfo.get_value", &instance)) {
+ return NULL;
+ }
+
+ container_info = g_base_info_get_container(self->info);
+ g_assert(container_info != NULL);
+
+ /* Check the instance. */
+ if (!_pygi_g_registered_type_info_check_object((GIRegisteredTypeInfo *)container_info, TRUE, instance)) {
+ _PyGI_ERROR_PREFIX("argument 1: ");
+ return NULL;
+ }
+
+ /* Get the pointer to the container. */
+ container_info_type = g_base_info_get_type(container_info);
+ switch (container_info_type) {
+ case GI_INFO_TYPE_UNION:
+ PyErr_SetString(PyExc_NotImplementedError, "getting a field from an union is not supported yet");
+ return NULL;
+ case GI_INFO_TYPE_STRUCT:
+ pointer = pyg_boxed_get(instance, void);
+ break;
+ case GI_INFO_TYPE_OBJECT:
+ pointer = pygobject_get(instance);
+ break;
+ default:
+ /* Other types don't have fields. */
+ g_assert_not_reached();
+ }
+
+ /* Get the field's value. */
+ field_type_info = g_field_info_get_type((GIFieldInfo *)self->info);
+
+ /* A few types are not handled by g_field_info_get_field, so do it here. */
+ if (!g_type_info_is_pointer(field_type_info)
+ && g_type_info_get_tag(field_type_info) == GI_TYPE_TAG_INTERFACE) {
+ GIBaseInfo *info;
+ GIInfoType info_type;
+
+ if (!(g_field_info_get_flags((GIFieldInfo *)self->info) & GI_FIELD_IS_READABLE)) {
+ PyErr_SetString(PyExc_RuntimeError, "field is not readable");
+ goto out;
+ }
+
+ info = g_type_info_get_interface(field_type_info);
+
+ info_type = g_base_info_get_type(info);
+
+ g_base_info_unref(info);
+
+ switch(info_type) {
+ case GI_INFO_TYPE_UNION:
+ PyErr_SetString(PyExc_NotImplementedError, "getting an union is not supported yet");
+ goto out;
+ case GI_INFO_TYPE_STRUCT:
+ {
+ gsize offset;
+
+ offset = g_field_info_get_offset((GIFieldInfo *)self->info);
+
+ value.v_pointer = pointer + offset;
+
+ goto argument_to_object;
+ }
+ default:
+ /* Fallback. */
+ break;
+ }
+ }
+
+ if (!g_field_info_get_field((GIFieldInfo *)self->info, pointer, &value)) {
+ PyErr_SetString(PyExc_RuntimeError, "unable to get the value");
+ goto out;
+ }
+
+argument_to_object:
+ py_value = _pygi_argument_to_object(&value, field_type_info, GI_TRANSFER_NOTHING);
+
+out:
+ g_base_info_unref((GIBaseInfo *)field_type_info);
+
+ return py_value;
+}
+
+static PyObject *
+_wrap_g_field_info_set_value (PyGIBaseInfo *self,
+ PyObject *args)
+{
+ PyObject *instance;
+ PyObject *py_value;
+ GIBaseInfo *container_info;
+ GIInfoType container_info_type;
+ gpointer pointer;
+ GITypeInfo *field_type_info;
+ GArgument value;
+ PyObject *retval = NULL;
+
+ if (!PyArg_ParseTuple(args, "OO:FieldInfo.set_value", &instance, &py_value)) {
+ return NULL;
+ }
+
+ container_info = g_base_info_get_container(self->info);
+ g_assert(container_info != NULL);
+
+ /* Check the instance. */
+ if (!_pygi_g_registered_type_info_check_object((GIRegisteredTypeInfo *)container_info, TRUE, instance)) {
+ _PyGI_ERROR_PREFIX("argument 1: ");
+ return NULL;
+ }
+
+ /* Get the pointer to the container. */
+ container_info_type = g_base_info_get_type(container_info);
+ switch (container_info_type) {
+ case GI_INFO_TYPE_UNION:
+ PyErr_SetString(PyExc_NotImplementedError, "setting a field in an union is not supported yet");
+ return NULL;
+ case GI_INFO_TYPE_STRUCT:
+ pointer = pyg_boxed_get(instance, void);
+ break;
+ case GI_INFO_TYPE_OBJECT:
+ pointer = pygobject_get(instance);
+ break;
+ default:
+ /* Other types don't have fields. */
+ g_assert_not_reached();
+ }
+
+ field_type_info = g_field_info_get_type((GIFieldInfo *)self->info);
+
+ /* Check the value. */
+ {
+ gboolean retval;
+
+ retval = _pygi_g_type_info_check_object(field_type_info, TRUE, py_value);
+ if (retval < 0) {
+ goto out;
+ }
+
+ if (!retval) {
+ _PyGI_ERROR_PREFIX("argument 2: ");
+ goto out;
+ }
+ }
+
+ /* Set the field's value. */
+ /* A few types are not handled by g_field_info_set_field, so do it here. */
+ if (!g_type_info_is_pointer(field_type_info)
+ && g_type_info_get_tag(field_type_info) == GI_TYPE_TAG_INTERFACE) {
+ GIBaseInfo *info;
+ GIInfoType info_type;
+
+ if (!(g_field_info_get_flags((GIFieldInfo *)self->info) & GI_FIELD_IS_WRITABLE)) {
+ PyErr_SetString(PyExc_RuntimeError, "field is not writable");
+ goto out;
+ }
+
+ info = g_type_info_get_interface(field_type_info);
+
+ info_type = g_base_info_get_type(info);
+
+ switch (info_type) {
+ case GI_INFO_TYPE_UNION:
+ PyErr_SetString(PyExc_NotImplementedError, "setting an union is not supported yet");
+ goto out;
+ case GI_INFO_TYPE_STRUCT:
+ {
+ gboolean is_simple;
+ gsize offset;
+ gssize size;
+
+ is_simple = pygi_g_struct_info_is_simple((GIStructInfo *)info);
+
+ if (!is_simple) {
+ PyErr_SetString(PyExc_TypeError,
+ "cannot set a structure which has no well-defined ownership transfer rules");
+ g_base_info_unref(info);
+ goto out;
+ }
+
+ value = _pygi_argument_from_object(py_value, field_type_info, GI_TRANSFER_NOTHING);
+ if (PyErr_Occurred()) {
+ g_base_info_unref(info);
+ goto out;
+ }
+
+ offset = g_field_info_get_offset((GIFieldInfo *)self->info);
+ size = g_struct_info_get_size((GIStructInfo *)info);
+ g_assert(size > 0);
+
+ g_memmove(pointer + offset, value.v_pointer, size);
+
+ g_base_info_unref(info);
+
+ retval = Py_None;
+ goto out;
+ }
+ default:
+ /* Fallback. */
+ break;
+ }
+
+ g_base_info_unref(info);
+ }
+
+ value = _pygi_argument_from_object(py_value, field_type_info, GI_TRANSFER_EVERYTHING);
+ if (PyErr_Occurred()) {
+ goto out;
+ }
+
+ if (!g_field_info_set_field((GIFieldInfo *)self->info, pointer, &value)) {
+ _pygi_argument_release(&value, field_type_info, GI_TRANSFER_NOTHING, GI_DIRECTION_IN);
+ PyErr_SetString(PyExc_RuntimeError, "unable to set value for field");
+ goto out;
+ }
+
+ retval = Py_None;
+
+out:
+ g_base_info_unref((GIBaseInfo *)field_type_info);
+
+ Py_XINCREF(retval);
+ return retval;
+}
+
+static PyMethodDef _PyGIFieldInfo_methods[] = {
+ { "get_value", (PyCFunction)_wrap_g_field_info_get_value, METH_VARARGS },
+ { "set_value", (PyCFunction)_wrap_g_field_info_set_value, METH_VARARGS },
+ { NULL, NULL, 0 }
+};
+
+
+/* GIUnresolvedInfo */
+_PyGI_DEFINE_INFO_TYPE("UnresolvedInfo", GIUnresolvedInfo, PyGIBaseInfo_Type);
+
+static PyMethodDef _PyGIUnresolvedInfo_methods[] = {
+ { NULL, NULL, 0 }
+};
+
+/* Private */
+
+gchar *
+_pygi_g_base_info_get_fullname (GIBaseInfo *info)
+{
+ GIBaseInfo *container_info;
+ gchar *fullname;
+
+ container_info = g_base_info_get_container(info);
+ if (container_info != NULL) {
+ fullname = g_strdup_printf("%s.%s.%s",
+ g_base_info_get_namespace(container_info),
+ g_base_info_get_name(container_info),
+ g_base_info_get_name(info));
+ } else {
+ fullname = g_strdup_printf("%s.%s",
+ g_base_info_get_namespace(info),
+ g_base_info_get_name(info));
+ }
+
+ if (fullname == NULL) {
+ PyErr_NoMemory();
+ }
+
+ return fullname;
+}
+
+void
+_pygi_info_register_types (PyObject *m)
+{
+#define _PyGI_REGISTER_TYPE(m, type, name) \
+ type.ob_type = &PyType_Type; \
+ if (PyType_Ready(&type)) \
+ return; \
+ if (PyModule_AddObject(m, name, (PyObject *)&type)) \
+ return
+
+ _PyGI_REGISTER_TYPE(m, PyGIBaseInfo_Type, "BaseInfo");
+ _PyGI_REGISTER_TYPE(m, PyGIUnresolvedInfo_Type, "UnresolvedInfo");
+ _PyGI_REGISTER_TYPE(m, PyGICallableInfo_Type, "CallableInfo");
+ _PyGI_REGISTER_TYPE(m, PyGIFunctionInfo_Type, "FunctionInfo");
+ _PyGI_REGISTER_TYPE(m, PyGIRegisteredTypeInfo_Type, "RegisteredTypeInfo");
+ _PyGI_REGISTER_TYPE(m, PyGIStructInfo_Type, "StructInfo");
+ _PyGI_REGISTER_TYPE(m, PyGIEnumInfo_Type, "EnumInfo");
+ _PyGI_REGISTER_TYPE(m, PyGIObjectInfo_Type, "ObjectInfo");
+ _PyGI_REGISTER_TYPE(m, PyGIInterfaceInfo_Type, "InterfaceInfo");
+ _PyGI_REGISTER_TYPE(m, PyGIConstantInfo_Type, "ConstantInfo");
+ _PyGI_REGISTER_TYPE(m, PyGIValueInfo_Type, "ValueInfo");
+ _PyGI_REGISTER_TYPE(m, PyGIFieldInfo_Type, "FieldInfo");
+
+#undef _PyGI_REGISTER_TYPE
+}
diff --git a/gi/pygi-info.h b/gi/pygi-info.h
new file mode 100644
index 0000000..437ef9a
--- /dev/null
+++ b/gi/pygi-info.h
@@ -0,0 +1,64 @@
+/* -*- Mode: C; c-basic-offset: 4 -*-
+ * vim: tabstop=4 shiftwidth=4 expandtab
+ *
+ * Copyright (C) 2005-2009 Johan Dahlin <johan@gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
+ * USA
+ */
+
+#ifndef __PYGI_INFO_H__
+#define __PYGI_INFO_H__
+
+#include <Python.h>
+
+#include <girepository.h>
+
+G_BEGIN_DECLS
+
+gboolean pygi_g_struct_info_is_simple (GIStructInfo *struct_info);
+
+
+/* Private */
+
+extern PyTypeObject PyGIBaseInfo_Type;
+extern PyTypeObject PyGICallableInfo_Type;
+extern PyTypeObject PyGIFunctionInfo_Type;
+extern PyTypeObject PyGIRegisteredTypeInfo_Type;
+extern PyTypeObject PyGIStructInfo_Type;
+extern PyTypeObject PyGIEnumInfo_Type;
+extern PyTypeObject PyGIObjectInfo_Type;
+extern PyTypeObject PyGIInterfaceInfo_Type;
+extern PyTypeObject PyGIConstantInfo_Type;
+extern PyTypeObject PyGIValueInfo_Type;
+extern PyTypeObject PyGIFieldInfo_Type;
+extern PyTypeObject PyGIUnresolvedInfo_Type;
+
+#define PyGIBaseInfo_GET_GI_INFO(object) g_base_info_ref(((PyGIBaseInfo *)object)->info)
+
+PyObject* _pygi_info_new (GIBaseInfo *info);
+GIBaseInfo* _pygi_object_get_gi_info (PyObject *object,
+ PyTypeObject *type);
+
+gchar* _pygi_g_base_info_get_fullname (GIBaseInfo *info);
+
+gsize _pygi_g_type_tag_size (GITypeTag type_tag);
+gsize _pygi_g_type_info_size (GITypeInfo *type_info);
+
+void _pygi_info_register_types (PyObject *m);
+
+G_END_DECLS
+
+#endif /* __PYGI_INFO_H__ */
diff --git a/gi/pygi-private.h b/gi/pygi-private.h
new file mode 100644
index 0000000..6ca85c8
--- /dev/null
+++ b/gi/pygi-private.h
@@ -0,0 +1,55 @@
+/* -*- Mode: C; c-basic-offset: 4 -*-
+ * vim: tabstop=4 shiftwidth=4 expandtab
+ */
+#ifndef __PYGI_PRIVATE_H__
+#define __PYGI_PRIVATE_H__
+
+#ifdef __PYGI_H__
+# error "Import pygi.h or pygi-private.h, but not both"
+#endif
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <Python.h>
+
+#include "pygi.h"
+
+#include "pygobject-external.h"
+
+#include "pygi-repository.h"
+#include "pygi-info.h"
+#include "pygi-struct.h"
+#include "pygi-argument.h"
+#include "pygi-type.h"
+
+G_BEGIN_DECLS
+
+#define _PyGI_ERROR_PREFIX(format, ...) G_STMT_START { \
+ PyObject *py_error_prefix; \
+ py_error_prefix = PyString_FromFormat(format, ## __VA_ARGS__); \
+ if (py_error_prefix != NULL) { \
+ PyObject *py_error_type, *py_error_value, *py_error_traceback; \
+ PyErr_Fetch(&py_error_type, &py_error_value, &py_error_traceback); \
+ if (PyString_Check(py_error_value)) { \
+ PyString_ConcatAndDel(&py_error_prefix, py_error_value); \
+ if (py_error_prefix != NULL) { \
+ py_error_value = py_error_prefix; \
+ } \
+ } \
+ PyErr_Restore(py_error_type, py_error_value, py_error_traceback); \
+ } \
+} G_STMT_END
+
+
+/* Redefine g_array_index because we want it to return the i-th element, casted
+ * to the type t, of the array a, and not the i-th element of the array a
+ * casted to the type t. */
+#define _g_array_index(a,t,i) \
+ *(t *)((a)->data + g_array_get_element_size(a) * (i))
+
+
+G_END_DECLS
+
+#endif /* __PYGI_PRIVATE_H__ */
diff --git a/gi/pygi-repository.c b/gi/pygi-repository.c
new file mode 100644
index 0000000..f84fc7b
--- /dev/null
+++ b/gi/pygi-repository.c
@@ -0,0 +1,238 @@
+/* -*- Mode: C; c-basic-offset: 4 -*-
+ * vim: tabstop=4 shiftwidth=4 expandtab
+ *
+ * Copyright (C) 2005-2009 Johan Dahlin <johan@gnome.org>
+ *
+ * pygi-repository.c: GIRepository wrapper.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
+ * USA
+ */
+
+#include "pygi-private.h"
+
+PyObject *PyGIRepositoryError;
+
+static PyMethodDef _PyGIRepository_methods[];
+
+PyTypeObject PyGIRepository_Type = {
+ PyObject_HEAD_INIT(NULL)
+ 0,
+ "gi.Repository", /* tp_name */
+ sizeof(PyGIRepository), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ (destructor)NULL, /* tp_dealloc */
+ (printfunc)NULL, /* tp_print */
+ (getattrfunc)NULL, /* tp_getattr */
+ (setattrfunc)NULL, /* tp_setattr */
+ (cmpfunc)NULL, /* tp_compare */
+ (reprfunc)NULL, /* tp_repr */
+ NULL, /* tp_as_number */
+ NULL, /* tp_as_sequence */
+ NULL, /* tp_as_mapping */
+ (hashfunc)NULL, /* tp_hash */
+ (ternaryfunc)NULL, /* tp_call */
+ (reprfunc)NULL, /* tp_str */
+ (getattrofunc)NULL, /* tp_getattro */
+ (setattrofunc)NULL, /* tp_setattro */
+ NULL, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT, /* tp_flags */
+ NULL, /* tp_doc */
+ (traverseproc)NULL, /* tp_traverse */
+ (inquiry)NULL, /* tp_clear */
+ (richcmpfunc)NULL, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ (getiterfunc)NULL, /* tp_iter */
+ (iternextfunc)NULL, /* tp_iternext */
+ _PyGIRepository_methods, /* tp_methods */
+};
+
+static PyObject *
+_wrap_g_irepository_get_default (PyObject *self)
+{
+ static PyGIRepository *repository = NULL;
+
+ if (!repository) {
+ repository = (PyGIRepository *)PyObject_New(PyGIRepository, &PyGIRepository_Type);
+ if (repository == NULL) {
+ return NULL;
+ }
+
+ repository->repository = g_irepository_get_default();
+ }
+
+ Py_INCREF((PyObject *)repository);
+ return (PyObject *)repository;
+}
+
+static PyObject *
+_wrap_g_irepository_require (PyGIRepository *self,
+ PyObject *args,
+ PyObject *kwargs)
+{
+ static char *kwlist[] = { "namespace", "version", "lazy", NULL };
+
+ const char *namespace_;
+ const char *version = NULL;
+ PyObject *lazy = NULL;
+ GIRepositoryLoadFlags flags = 0;
+ GTypelib *typelib;
+ GError *error;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|sO:Repository.require",
+ kwlist, &namespace_, &version, &lazy)) {
+ return NULL;
+ }
+
+ if (lazy != NULL && PyObject_IsTrue(lazy)) {
+ flags |= G_IREPOSITORY_LOAD_FLAG_LAZY;
+ }
+
+ error = NULL;
+ typelib = g_irepository_require(self->repository, namespace_, version, flags, &error);
+ if (error != NULL) {
+ PyErr_SetString(PyGIRepositoryError, error->message);
+ g_error_free(error);
+ return NULL;
+ }
+
+ Py_RETURN_NONE;
+}
+
+static PyObject *
+_wrap_g_irepository_find_by_name (PyGIRepository *self,
+ PyObject *args,
+ PyObject *kwargs)
+{
+ static char *kwlist[] = { "namespace", "name", NULL };
+
+ const char *namespace_;
+ const char *name;
+ GIBaseInfo *info;
+ PyObject *py_info;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs,
+ "ss:Repository.find_by_name", kwlist, &namespace_, &name)) {
+ return NULL;
+ }
+
+ info = g_irepository_find_by_name(self->repository, namespace_, name);
+ if (info == NULL) {
+ Py_RETURN_NONE;
+ }
+
+ py_info = _pygi_info_new(info);
+
+ g_base_info_unref(info);
+
+ return py_info;
+}
+
+static PyObject *
+_wrap_g_irepository_get_infos (PyGIRepository *self,
+ PyObject *args,
+ PyObject *kwargs)
+{
+ static char *kwlist[] = { "namespace", NULL };
+
+ const char *namespace_;
+ gssize n_infos;
+ PyObject *infos;
+ gssize i;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s:Repository.get_infos",
+ kwlist, &namespace_)) {
+ return NULL;
+ }
+
+ n_infos = g_irepository_get_n_infos(self->repository, namespace_);
+ if (n_infos < 0) {
+ PyErr_Format(PyExc_RuntimeError, "Namespace '%s' not loaded", namespace_);
+ return NULL;
+ }
+
+ infos = PyTuple_New(n_infos);
+
+ for (i = 0; i < n_infos; i++) {
+ GIBaseInfo *info;
+ PyObject *py_info;
+
+ info = g_irepository_get_info(self->repository, namespace_, i);
+ g_assert(info != NULL);
+
+ py_info = _pygi_info_new(info);
+
+ g_base_info_unref(info);
+
+ if (py_info == NULL) {
+ Py_CLEAR(infos);
+ break;
+ }
+
+ PyTuple_SET_ITEM(infos, i, py_info);
+ }
+
+ return infos;
+}
+
+static PyObject *
+_wrap_g_irepository_get_typelib_path (PyGIRepository *self,
+ PyObject *args,
+ PyObject *kwargs)
+{
+ static char *kwlist[] = { "namespace", NULL };
+ const char *namespace_;
+ const gchar *typelib_path;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs,
+ "s:Repository.get_typelib_path", kwlist, &namespace_)) {
+ return NULL;
+ }
+
+ typelib_path = g_irepository_get_typelib_path(self->repository, namespace_);
+ if (typelib_path == NULL) {
+ PyErr_Format(PyExc_RuntimeError, "Namespace '%s' not loaded", namespace_);
+ return NULL;
+ }
+
+ return PyString_FromString(typelib_path);
+}
+
+static PyMethodDef _PyGIRepository_methods[] = {
+ { "get_default", (PyCFunction)_wrap_g_irepository_get_default, METH_STATIC|METH_NOARGS },
+ { "require", (PyCFunction)_wrap_g_irepository_require, METH_VARARGS|METH_KEYWORDS },
+ { "get_infos", (PyCFunction)_wrap_g_irepository_get_infos, METH_VARARGS|METH_KEYWORDS },
+ { "find_by_name", (PyCFunction)_wrap_g_irepository_find_by_name, METH_VARARGS|METH_KEYWORDS },
+ { "get_typelib_path", (PyCFunction)_wrap_g_irepository_get_typelib_path, METH_VARARGS|METH_KEYWORDS },
+ { NULL, NULL, 0 }
+};
+
+void
+_pygi_repository_register_types (PyObject *m)
+{
+ PyGIRepository_Type.ob_type = &PyType_Type;
+ if (PyType_Ready(&PyGIRepository_Type)) {
+ return;
+ }
+ if (PyModule_AddObject(m, "Repository", (PyObject *)&PyGIRepository_Type)) {
+ return;
+ }
+
+ PyGIRepositoryError = PyErr_NewException("gi.RepositoryError", NULL, NULL);
+ if (PyModule_AddObject(m, "RepositoryError", PyGIRepositoryError)) {
+ return;
+ }
+}
+
diff --git a/gi/pygi-repository.h b/gi/pygi-repository.h
new file mode 100644
index 0000000..d8eb8cf
--- /dev/null
+++ b/gi/pygi-repository.h
@@ -0,0 +1,39 @@
+/* -*- Mode: C; c-basic-offset: 4 -*-
+ * vim: tabstop=4 shiftwidth=4 expandtab
+ *
+ * Copyright (C) 2005-2009 Johan Dahlin <johan@gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
+ * USA
+ */
+
+#ifndef __PYGI_REPOSITORY_H__
+#define __PYGI_REPOSITORY_H__
+
+#include <Python.h>
+
+G_BEGIN_DECLS
+
+/* Private */
+
+extern PyTypeObject PyGIRepository_Type;
+
+extern PyObject *PyGIRepositoryError;
+
+void _pygi_repository_register_types (PyObject *m);
+
+G_END_DECLS
+
+#endif /* __PYGI_REPOSITORY_H__ */
diff --git a/gi/pygi-struct.c b/gi/pygi-struct.c
new file mode 100644
index 0000000..8b672c7
--- /dev/null
+++ b/gi/pygi-struct.c
@@ -0,0 +1,175 @@
+/* -*- Mode: C; c-basic-offset: 4 -*-
+ * vim: tabstop=4 shiftwidth=4 expandtab
+ *
+ * Copyright (C) 2009 Simon van der Linden <svdlinden@src.gnome.org>
+ *
+ * pygi-struct.c: wrapper to handle non-registered structures.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
+ * USA
+ */
+
+#include "pygi-private.h"
+
+#include <pygobject.h>
+#include <girepository.h>
+
+static void
+_struct_dealloc (PyGIStruct *self)
+{
+ PyObject_GC_UnTrack((PyObject *)self);
+
+ PyObject_ClearWeakRefs((PyObject *)self);
+
+ if (self->free_on_dealloc) {
+ g_free(((PyGPointer *)self)->pointer);
+ }
+
+ ((PyGPointer *)self)->ob_type->tp_free((PyObject *)self);
+}
+
+static PyObject *
+_struct_new (PyTypeObject *type,
+ PyObject *args,
+ PyObject *kwargs)
+{
+ static char *kwlist[] = { NULL };
+
+ GIBaseInfo *info;
+ gboolean is_simple;
+ gsize size;
+ gpointer pointer;
+ PyObject *self = NULL;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "", kwlist)) {
+ return NULL;
+ }
+
+ info = _pygi_object_get_gi_info((PyObject *)type, &PyGIStructInfo_Type);
+ if (info == NULL) {
+ if (PyErr_ExceptionMatches(PyExc_AttributeError)) {
+ PyErr_Format(PyExc_TypeError, "missing introspection information");
+ }
+ return NULL;
+ }
+
+ is_simple = pygi_g_struct_info_is_simple((GIStructInfo *)info);
+ if (!is_simple) {
+ PyErr_Format(PyExc_TypeError, "cannot create '%s' instances", type->tp_name);
+ goto out;
+ }
+
+ size = g_struct_info_get_size((GIStructInfo *)info);
+ pointer = g_try_malloc(size);
+ if (pointer == NULL) {
+ PyErr_NoMemory();
+ goto out;
+ }
+
+ self = _pygi_struct_new(type, pointer, TRUE);
+ if (self == NULL) {
+ g_free(pointer);
+ }
+
+out:
+ g_base_info_unref(info);
+
+ return (PyObject *)self;
+}
+
+static int
+_struct_init (PyObject *self,
+ PyObject *args,
+ PyObject *kwargs)
+{
+ /* Don't call PyGPointer's init, which raises an exception. */
+ return 0;
+}
+
+
+PyTypeObject PyGIStruct_Type = {
+ PyObject_HEAD_INIT(NULL)
+ 0,
+ "gi.Struct", /* tp_name */
+ sizeof(PyGIStruct), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ (destructor)_struct_dealloc, /* tp_dealloc */
+ (printfunc)NULL, /* tp_print */
+ (getattrfunc)NULL, /* tp_getattr */
+ (setattrfunc)NULL, /* tp_setattr */
+ (cmpfunc)NULL, /* tp_compare */
+ (reprfunc)NULL, /* tp_repr */
+ NULL, /* tp_as_number */
+ NULL, /* tp_as_sequence */
+ NULL, /* tp_as_mapping */
+ (hashfunc)NULL, /* tp_hash */
+ (ternaryfunc)NULL, /* tp_call */
+ (reprfunc)NULL, /* tp_str */
+ (getattrofunc)NULL, /* tp_getattro */
+ (setattrofunc)NULL, /* tp_setattro */
+ NULL, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
+ NULL, /* tp_doc */
+ (traverseproc)NULL, /* tp_traverse */
+ (inquiry)NULL, /* tp_clear */
+ (richcmpfunc)NULL, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ (getiterfunc)NULL, /* tp_iter */
+ (iternextfunc)NULL, /* tp_iternext */
+ NULL, /* tp_methods */
+ NULL, /* tp_members */
+ NULL, /* tp_getset */
+ (PyTypeObject *)NULL, /* tp_base */
+};
+
+PyObject *
+_pygi_struct_new (PyTypeObject *type,
+ gpointer pointer,
+ gboolean free_on_dealloc)
+{
+ PyGIStruct *self;
+ GType g_type;
+
+ if (!PyType_IsSubtype(type, &PyGIStruct_Type)) {
+ PyErr_SetString(PyExc_TypeError, "must be a subtype of gi.Struct");
+ return NULL;
+ }
+
+ self = (PyGIStruct *)type->tp_alloc(type, 0);
+ if (self == NULL) {
+ return NULL;
+ }
+
+ g_type = pyg_type_from_object((PyObject *)type);
+
+ ((PyGPointer *)self)->gtype = g_type;
+ ((PyGPointer *)self)->pointer = pointer;
+ self->free_on_dealloc = free_on_dealloc;
+
+ return (PyObject *)self;
+}
+
+void
+_pygi_struct_register_types (PyObject *m)
+{
+ PyGIStruct_Type.ob_type = &PyType_Type;
+ PyGIStruct_Type.tp_base = &PyGPointer_Type;
+ PyGIStruct_Type.tp_new = (newfunc)_struct_new;
+ PyGIStruct_Type.tp_init = (initproc)_struct_init;
+ if (PyType_Ready(&PyGIStruct_Type))
+ return;
+ if (PyModule_AddObject(m, "Struct", (PyObject *)&PyGIStruct_Type))
+ return;
+}
diff --git a/gi/pygi-struct.h b/gi/pygi-struct.h
new file mode 100644
index 0000000..963d05a
--- /dev/null
+++ b/gi/pygi-struct.h
@@ -0,0 +1,40 @@
+/* -*- Mode: C; c-basic-offset: 4 -*-
+ * vim: tabstop=4 shiftwidth=4 expandtab
+ *
+ * Copyright (C) 2009 Simon van der Linden <svdlinden@src.gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
+ * USA
+ */
+
+#ifndef __PYGI_STRUCT_H__
+#define __PYGI_STRUCT_H__
+
+#include <Python.h>
+
+G_BEGIN_DECLS
+
+extern PyTypeObject PyGIStruct_Type;
+
+PyObject *
+_pygi_struct_new (PyTypeObject *type,
+ gpointer pointer,
+ gboolean free_on_dealloc);
+
+void _pygi_struct_register_types (PyObject *m);
+
+G_END_DECLS
+
+#endif /* __PYGI_STRUCT_H__ */
diff --git a/gi/pygi-type.c b/gi/pygi-type.c
new file mode 100644
index 0000000..c95da86
--- /dev/null
+++ b/gi/pygi-type.c
@@ -0,0 +1,96 @@
+/* -*- Mode: C; c-basic-offset: 4 -*-
+ * vim: tabstop=4 shiftwidth=4 expandtab
+ *
+ * Copyright (C) 2009 Simon van der Linden <svdlinden@src.gnome.org>
+ *
+ * pygi-type.c: helpers to lookup Python wrappers from GType and GIBaseInfo.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
+ * USA
+ */
+
+#include "pygi-private.h"
+
+
+PyObject *
+_pygi_type_import_by_gi_info (GIBaseInfo *info)
+{
+ const gchar *namespace_;
+ const gchar *name;
+ gchar *module_name;
+ PyObject *py_module;
+ PyObject *py_object;
+
+ namespace_ = g_base_info_get_namespace(info);
+ name = g_base_info_get_name(info);
+
+ module_name = g_strconcat("gi.repository.", namespace_, NULL);
+
+ py_module = PyImport_ImportModule(module_name);
+
+ g_free(module_name);
+
+ if (py_module == NULL) {
+ return NULL;
+ }
+
+ py_object = PyObject_GetAttrString(py_module, name);
+
+ Py_DECREF(py_module);
+
+ return py_object;
+}
+
+PyObject *
+pygi_type_import_by_g_type (GType g_type)
+{
+ GIRepository *repository;
+ GIBaseInfo *info;
+ PyObject *type;
+
+ repository = g_irepository_get_default();
+
+ info = g_irepository_find_by_gtype(repository, g_type);
+ if (info == NULL) {
+ return NULL;
+ }
+
+ type = _pygi_type_import_by_gi_info(info);
+ g_base_info_unref(info);
+
+ return type;
+}
+
+PyObject *
+_pygi_type_get_from_g_type(GType g_type)
+{
+ PyObject *py_g_type;
+ PyObject *py_type;
+
+ py_g_type = pyg_type_wrapper_new(g_type);
+ if (py_g_type == NULL) {
+ return NULL;
+ }
+
+ py_type = PyObject_GetAttrString(py_g_type, "pytype");
+ if (py_type == Py_None) {
+ py_type = pygi_type_import_by_g_type(g_type);
+ }
+
+ Py_DECREF(py_g_type);
+
+ return py_type;
+}
+
diff --git a/gi/pygi-type.h b/gi/pygi-type.h
new file mode 100644
index 0000000..19d07dc
--- /dev/null
+++ b/gi/pygi-type.h
@@ -0,0 +1,43 @@
+/* -*- Mode: C; c-basic-offset: 4 -*-
+ * vim: tabstop=4 shiftwidth=4 expandtab
+ *
+ * Copyright (C) 2009 Simon van der Linden <svdlinden@src.gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
+ * USA
+ */
+
+#ifndef __PYGI_TYPE_H__
+#define __PYGI_TYPE_H__
+
+#include <Python.h>
+
+G_BEGIN_DECLS
+
+/* Public */
+
+PyObject *pygi_type_import_by_g_type (GType g_type);
+
+
+/* Private */
+
+PyObject *_pygi_type_import_by_gi_info (GIBaseInfo *info);
+
+PyObject *_pygi_type_get_from_g_type (GType g_type);
+
+
+G_END_DECLS
+
+#endif /* __PYGI_TYPE_H__ */
diff --git a/gi/pygi.h b/gi/pygi.h
new file mode 100644
index 0000000..930017d
--- /dev/null
+++ b/gi/pygi.h
@@ -0,0 +1,99 @@
+/* -*- Mode: C; c-basic-offset: 4 -*-
+ * vim: tabstop=4 shiftwidth=4 expandtab
+ *
+ * Copyright (C) 2005-2009 Johan Dahlin <johan@gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
+ * USA
+ */
+
+#ifndef __PYGI_H__
+#define __PYGI_H__
+
+#include <pygobject.h>
+
+#include <girepository.h>
+
+G_BEGIN_DECLS
+
+typedef struct {
+ PyObject_HEAD
+ GIRepository *repository;
+} PyGIRepository;
+
+typedef struct {
+ PyObject_HEAD
+ GIBaseInfo *info;
+ PyObject *inst_weakreflist;
+} PyGIBaseInfo;
+
+typedef struct {
+ PyGPointer base;
+ gboolean free_on_dealloc;
+} PyGIStruct;
+
+
+struct PyGI_API {
+ PyObject* (*type_import_by_g_type) (GType g_type);
+};
+
+
+#ifndef __PYGI_PRIVATE_H__
+
+static struct PyGI_API *PyGI_API = NULL;
+
+#define pygi_type_import_by_g_type (PyGI_API->type_import_by_g_type)
+
+
+static int
+pygi_import (void)
+{
+ PyObject *module;
+ PyObject *api;
+
+ if (PyGI_API != NULL) {
+ return 1;
+ }
+
+ module = PyImport_ImportModule("gi");
+ if (module == NULL) {
+ return -1;
+ }
+
+ api = PyObject_GetAttrString(module, "_API");
+ if (api == NULL) {
+ Py_DECREF(module);
+ return -1;
+ }
+ if (!PyCObject_Check(api)) {
+ Py_DECREF(module);
+ Py_DECREF(api);
+ PyErr_Format(PyExc_TypeError, "gi._API must be cobject, not %s",
+ api->ob_type->tp_name);
+ return -1;
+ }
+
+ PyGI_API = (struct PyGI_API *)PyCObject_AsVoidPtr(api);
+
+ Py_DECREF(api);
+
+ return 0;
+}
+
+#endif /* __PYGI_PRIVATE_H__ */
+
+G_END_DECLS
+
+#endif /* __PYGI_H__ */
diff --git a/gi/pygobject-external.h b/gi/pygobject-external.h
new file mode 100644
index 0000000..6dc63a5
--- /dev/null
+++ b/gi/pygobject-external.h
@@ -0,0 +1,83 @@
+/* -*- Mode: C; c-basic-offset: 4 -*-
+ * vim: tabstop=4 shiftwidth=4 expandtab
+ *
+ * Copyright (C) 2009 Simon van der Linden <svdlinden@src.gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
+ * USA
+ */
+
+#ifndef __PYGOBJECT_EXTERN_H__
+#define __PYGOBJECT_EXTERN_H__
+
+#include <Python.h>
+
+G_BEGIN_DECLS
+
+static PyTypeObject *_PyGObject_Type;
+static PyTypeObject *_PyGTypeWrapper_Type;
+
+#define PyGObject_Type (*_PyGObject_Type)
+#define PyGTypeWrapper_Type (*_PyGTypeWrapper_Type)
+
+
+static int
+_pygobject_import (void)
+{
+ static gboolean imported = FALSE;
+ PyObject *from_list;
+ PyObject *module;
+ int retval = 0;
+
+ if (imported) {
+ return 1;
+ }
+
+ from_list = Py_BuildValue("(ss)", "GObject", "GTypeWrapper");
+ if (from_list == NULL) {
+ return -1;
+ }
+
+ module = PyImport_ImportModuleEx("gobject", NULL, NULL, from_list);
+
+ Py_DECREF(from_list);
+
+ if (module == NULL) {
+ return -1;
+ }
+
+ _PyGObject_Type = (PyTypeObject *)PyObject_GetAttrString(module, "GObject");
+ if (_PyGObject_Type == NULL) {
+ retval = -1;
+ goto out;
+ }
+
+ _PyGTypeWrapper_Type = (PyTypeObject *)PyObject_GetAttrString(module, "GType");
+ if (_PyGTypeWrapper_Type == NULL) {
+ retval = -1;
+ goto out;
+ }
+
+ imported = TRUE;
+
+out:
+ Py_DECREF(module);
+
+ return retval;
+}
+
+G_END_DECLS
+
+#endif /* __PYGOBJECT_EXTERN_H__ */
diff --git a/gi/repository/Makefile.am b/gi/repository/Makefile.am
new file mode 100644
index 0000000..c9138ce
--- /dev/null
+++ b/gi/repository/Makefile.am
@@ -0,0 +1,8 @@
+PLATFORM_VERSION = 2.0
+
+pkgpyexecdir = $(pyexecdir)/gtk-2.0/gi
+
+pygirepositorydir = $(pkgpyexecdir)/repository
+pygirepository_PYTHON = \
+ __init__.py
+
diff --git a/gi/repository/__init__.py b/gi/repository/__init__.py
new file mode 100644
index 0000000..5c5552a
--- /dev/null
+++ b/gi/repository/__init__.py
@@ -0,0 +1,30 @@
+# -*- Mode: Python; py-indent-offset: 4 -*-
+# vim: tabstop=4 shiftwidth=4 expandtab
+#
+# Copyright (C) 2009 Johan Dahlin <johan@gnome.org>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+# USA
+
+from __future__ import absolute_import
+
+import sys
+
+from ..importer import DynamicImporter
+
+sys.meta_path.append(DynamicImporter('gi.repository'))
+
+del DynamicImporter
+del sys
diff --git a/gi/types.py b/gi/types.py
new file mode 100644
index 0000000..10d7fde
--- /dev/null
+++ b/gi/types.py
@@ -0,0 +1,163 @@
+# -*- Mode: Python; py-indent-offset: 4 -*-
+# vim: tabstop=4 shiftwidth=4 expandtab
+#
+# Copyright (C) 2005-2009 Johan Dahlin <johan@gnome.org>
+#
+# types.py: base types for introspected items.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+# USA
+
+from __future__ import absolute_import
+
+import sys
+import gobject
+
+from ._gi import \
+ InterfaceInfo, \
+ ObjectInfo, \
+ StructInfo, \
+ set_object_has_new_constructor
+
+
+class Boxed(gobject.GBoxed):
+ # Instances of boxed structures cannot be constructed unless they have a
+ # specific constructor.
+ #
+ # To achieve this behavior, PyGBoxed_Type's constructor creates an
+ # instance, and the initializer eventually raises an exception. If things
+ # had been implemented correctly, PyGBoxed_Type.tp_new would have been set to
+ # NULL, and neither a creator nor an initializer wouldn't have been needed.
+ #
+ # In order to keep the code generic, we need to revert the right behavior.
+
+ def __new__(cls):
+ raise TypeError, "instances of '%s' cannot be created" % cls.__name__
+
+ def __init__(self, *args, **kwargs):
+ pass
+
+
+def Function(info):
+
+ def function(*args):
+ return info.invoke(*args)
+ function.__info__ = info
+ function.__name__ = info.get_name()
+ function.__module__ = info.get_namespace()
+
+ return function
+
+
+def Constructor(info):
+
+ def constructor(cls, *args):
+ cls_name = info.get_container().get_name()
+ if cls.__name__ != cls_name:
+ raise TypeError, '%s constructor cannot be used to create instances of a subclass' % cls_name
+ return info.invoke(cls, *args)
+
+ constructor.__info__ = info
+ constructor.__name__ = info.get_name()
+ constructor.__module__ = info.get_namespace()
+
+ return constructor
+
+
+class MetaClassHelper(object):
+
+ def _setup_methods(cls):
+ for method_info in cls.__info__.get_methods():
+ name = method_info.get_name()
+ function = Function(method_info)
+ if method_info.is_method():
+ method = function
+ elif method_info.is_constructor():
+ continue
+ else:
+ method = staticmethod(function)
+ setattr(cls, name, method)
+
+ def _setup_fields(cls):
+ for field_info in cls.__info__.get_fields():
+ name = field_info.get_name().replace('-', '_')
+ setattr(cls, name, property(field_info.get_value, field_info.set_value))
+
+ def _setup_constants(cls):
+ for constant_info in cls.__info__.get_constants():
+ name = constant_info.get_name()
+ value = constant_info.get_value()
+ setattr(cls, name, value)
+
+
+class GObjectMeta(gobject.GObjectMeta, MetaClassHelper):
+
+ def _setup_constructors(cls):
+ for method_info in cls.__info__.get_methods():
+ if method_info.is_constructor():
+ name = method_info.get_name()
+ constructor = classmethod(Constructor(method_info))
+ setattr(cls, name, constructor)
+
+ def __init__(cls, name, bases, dict_):
+ super(GObjectMeta, cls).__init__(name, bases, dict_)
+
+ # Avoid touching anything else than the base class.
+ if cls.__name__ != cls.__info__.get_name():
+ return;
+
+ cls._setup_methods()
+ cls._setup_constants()
+
+ if (isinstance(cls.__info__, ObjectInfo)):
+ cls._setup_fields()
+ cls._setup_constructors()
+ set_object_has_new_constructor(cls.__info__.get_g_type())
+
+
+class StructMeta(type, MetaClassHelper):
+
+ def _setup_constructors(cls):
+ constructor_infos = []
+ default_constructor_info = None
+
+ for method_info in cls.__info__.get_methods():
+ if method_info.is_constructor():
+ name = method_info.get_name()
+ constructor = classmethod(Function(method_info))
+
+ setattr(cls, name, constructor)
+
+ constructor_infos.append(method_info)
+ if name == "new":
+ default_constructor_info = method_info
+
+ if default_constructor_info is None and constructor_infos:
+ default_constructor_info = constructor_infos[0]
+
+ if default_constructor_info is not None:
+ cls.__new__ = staticmethod(Function(default_constructor_info))
+
+ def __init__(cls, name, bases, dict_):
+ super(StructMeta, cls).__init__(name, bases, dict_)
+
+ # Avoid touching anything else than the base class.
+ if cls.__name__ != cls.__info__.get_name():
+ return;
+
+ cls._setup_fields()
+ cls._setup_methods()
+ cls._setup_constructors()
+
diff --git a/tests/Makefile.am b/tests/Makefile.am
new file mode 100644
index 0000000..a014bfd
--- /dev/null
+++ b/tests/Makefile.am
@@ -0,0 +1,48 @@
+
+noinst_LTLIBRARIES = libtestgi.la
+
+libtestgi_la_CFLAGS = $(GNOME_CFLAGS)
+libtestgi_la_LDFLAGS = -avoid-version
+libtestgi_la_LIBADD = $(GNOME_LIBS)
+libtestgi_la_SOURCES = \
+ libtestgi.c \
+ libtestgi.h
+
+# Force linking of a shared object.
+libtestgi_la_LINK = $(LINK) -rpath $(pkgpyexecdir)
+
+TestGI-0.0.gir: libtestgi.la
+ $(AM_V_GEN) \
+ $(INTROSPECTION_SCANNER) -v \
+ --namespace TestGI \
+ --nsversion 0.0 \
+ $(GNOME_CFLAGS) \
+ --include GObject-2.0 \
+ --library libtestgi.la \
+ --libtool "$(top_builddir)/libtool" \
+ --pkg gobject-2.0 \
+ --output $@ \
+ $(addprefix $(srcdir)/,$(libtestgi_la_SOURCES))
+
+BUILT_GIRSOURCES = TestGI-0.0.gir
+
+noinst_PYTHON = \
+ runtests.py \
+ test_gi.py
+
+nodist_noinst_DATA = $(BUILT_GIRSOURCES:.gir=.typelib)
+
+CLEANFILES = \
+ $(BUILT_GIRSOURCES) \
+ $(BUILT_GIRSOURCES:.gir=.typelib)
+
+
+check-local:
+ GI_TYPELIB_PATH=$(srcdir)$${GI_TYPELIB_PATH:+:$$GI_TYPELIB_PATH} \
+ LD_LIBRARY_PATH=$(srcdir)/.libs$${LD_LIBRARY_PATH:+:$$LD_LIBRARY_PATH} \
+ $(PYTHON) $(srcdir)/runtests.py $$TEST_NAMES
+
+.gir.typelib:
+ $(AM_V_GEN) \
+ LD_LIBRARY_PATH=$(srcdir)/.libs$${LD_LIBRARY_PATH:+:$$LD_LIBRARY_PATH} \
+ $(INTROSPECTION_COMPILER) --includedir=$(srcdir) $< -o $(@F)
diff --git a/tests/libtestgi.c b/tests/libtestgi.c
new file mode 100644
index 0000000..ddc99b1
--- /dev/null
+++ b/tests/libtestgi.c
@@ -0,0 +1,3397 @@
+/* -*- Mode: C; c-basic-offset: 4 -*-
+ * vim: tabstop=4 shiftwidth=4 expandtab
+ */
+
+#include "libtestgi.h"
+
+#include <string.h>
+
+
+/* Booleans */
+
+gboolean
+test_gi_boolean_return_true (void)
+{
+ return TRUE;
+}
+
+gboolean
+test_gi_boolean_return_false (void)
+{
+ return FALSE;
+}
+
+/**
+ * test_gi_boolean_return_ptr_true:
+ * Returns: (transfer none):
+ */
+gboolean *
+test_gi_boolean_return_ptr_true (void)
+{
+ static gboolean bool_ = TRUE;
+ return &bool_;
+}
+
+/**
+ * test_gi_boolean_return_ptr_false:
+ * Returns: (transfer none):
+ */
+gboolean *
+test_gi_boolean_return_ptr_false (void)
+{
+ static gboolean bool_ = FALSE;
+ return &bool_;
+}
+
+void
+test_gi_boolean_in_true (gboolean bool_)
+{
+ g_assert (bool_ == TRUE);
+}
+
+void
+test_gi_boolean_in_false (gboolean bool_)
+{
+ g_assert (bool_ == FALSE);
+}
+
+/**
+ * test_gi_boolean_in_ptr_true:
+ * bool_: (in):
+ */
+void
+test_gi_boolean_in_ptr_true (gboolean *bool_)
+{
+ g_assert (*bool_ == TRUE);
+}
+
+/**
+ * test_gi_boolean_in_ptr_false:
+ * bool_: (in):
+ */
+void
+test_gi_boolean_in_ptr_false (gboolean *bool_)
+{
+ g_assert (*bool_ == FALSE);
+}
+
+/**
+ * test_gi_boolean_out_true:
+ * bool_: (out):
+ */
+void
+test_gi_boolean_out_true (gboolean *bool_)
+{
+ *bool_ = TRUE;
+}
+
+/**
+ * test_gi_boolean_out_false:
+ * bool_: (out):
+ */
+void
+test_gi_boolean_out_false (gboolean *bool_)
+{
+ *bool_ = FALSE;
+}
+
+/**
+ * test_gi_boolean_inout_true_false:
+ * bool_: (inout):
+ */
+void
+test_gi_boolean_inout_true_false (gboolean *bool_)
+{
+ g_assert (*bool_ == TRUE);
+ *bool_ = FALSE;
+}
+
+/**
+ * test_gi_boolean_inout_false_true:
+ * bool_: (inout):
+ */
+void
+test_gi_boolean_inout_false_true (gboolean *bool_)
+{
+ g_assert (*bool_ == FALSE);
+ *bool_ = TRUE;
+}
+
+
+/* Integers */
+
+gint8
+test_gi_int8_return_max (void)
+{
+ return G_MAXINT8;
+}
+
+gint8
+test_gi_int8_return_min (void)
+{
+ return G_MININT8;
+}
+
+/**
+ * test_gi_int8_return_ptr_max:
+ * Returns: (transfer none):
+ */
+gint8 *
+test_gi_int8_return_ptr_max (void)
+{
+ static gint8 int8 = G_MAXINT8;
+ return &int8;
+}
+
+/**
+ * test_gi_int8_return_ptr_min:
+ * Returns: (transfer none):
+ */
+gint8 *
+test_gi_int8_return_ptr_min (void)
+{
+ static gint8 int8 = G_MININT8;
+ return &int8;
+}
+
+void
+test_gi_int8_in_max (gint8 int8)
+{
+ g_assert(int8 == G_MAXINT8);
+}
+
+void
+test_gi_int8_in_min (gint8 int8)
+{
+ g_assert(int8 == G_MININT8);
+}
+
+/**
+ * test_gi_int8_in_ptr_max:
+ * int8: (in):
+ */
+void
+test_gi_int8_in_ptr_max (gint8 *int8)
+{
+ g_assert(*int8 == G_MAXINT8);
+}
+
+/**
+ * test_gi_int8_in_ptr_min:
+ * int8: (in):
+ */
+void
+test_gi_int8_in_ptr_min (gint8 *int8)
+{
+ g_assert(*int8 == G_MININT8);
+}
+
+/**
+ * test_gi_int8_out_max:
+ * int8: (out):
+ */
+void
+test_gi_int8_out_max (gint8 *int8)
+{
+ *int8 = G_MAXINT8;
+}
+
+/**
+ * test_gi_int8_out_min:
+ * int8: (out):
+ */
+void
+test_gi_int8_out_min (gint8 *int8)
+{
+ *int8 = G_MININT8;
+}
+
+/**
+ * test_gi_int8_inout_max_min:
+ * int8: (inout):
+ */
+void
+test_gi_int8_inout_max_min (gint8 *int8)
+{
+ g_assert(*int8 == G_MAXINT8);
+ *int8 = G_MININT8;
+}
+
+/**
+ * test_gi_int8_inout_min_max:
+ * int8: (inout):
+ */
+void
+test_gi_int8_inout_min_max (gint8 *int8)
+{
+ g_assert(*int8 == G_MININT8);
+ *int8 = G_MAXINT8;
+}
+
+
+guint8
+test_gi_uint8_return (void)
+{
+ return G_MAXUINT8;
+}
+
+/**
+ * test_gi_uint8_return_ptr:
+ * Returns: (transfer none):
+ */
+guint8 *
+test_gi_uint8_return_ptr (void)
+{
+ static guint8 uint8 = G_MAXUINT8;
+ return &uint8;
+}
+
+void
+test_gi_uint8_in (guint8 uint8)
+{
+ g_assert(uint8 == G_MAXUINT8);
+}
+
+/**
+ * test_gi_uint8_in_ptr:
+ * uint8: (in):
+ */
+void
+test_gi_uint8_in_ptr (guint8 *uint8)
+{
+ g_assert(*uint8 == G_MAXUINT8);
+}
+
+/**
+ * test_gi_uint8_out:
+ * uint8: (out):
+ */
+void
+test_gi_uint8_out (guint8 *uint8)
+{
+ *uint8 = G_MAXUINT8;
+}
+
+/**
+ * test_gi_uint8_inout:
+ * uint8: (inout):
+ */
+void
+test_gi_uint8_inout (guint8 *uint8)
+{
+ g_assert(*uint8 == G_MAXUINT8);
+ *uint8 = 0;
+}
+
+
+gint16
+test_gi_int16_return_max (void)
+{
+ return G_MAXINT16;
+}
+
+gint16
+test_gi_int16_return_min (void)
+{
+ return G_MININT16;
+}
+
+/**
+ * test_gi_int16_return_ptr_max:
+ * Returns: (transfer none):
+ */
+gint16 *
+test_gi_int16_return_ptr_max (void)
+{
+ static gint16 int16 = G_MAXINT16;
+ return &int16;
+}
+
+/**
+ * test_gi_int16_return_ptr_min:
+ * Returns: (transfer none):
+ */
+gint16 *
+test_gi_int16_return_ptr_min (void)
+{
+ static gint16 int16 = G_MININT16;
+ return &int16;
+}
+
+void
+test_gi_int16_in_max (gint16 int16)
+{
+ g_assert(int16 == G_MAXINT16);
+}
+
+void
+test_gi_int16_in_min (gint16 int16)
+{
+ g_assert(int16 == G_MININT16);
+}
+
+/**
+ * test_gi_int16_in_ptr_max:
+ * int16: (in):
+ */
+void
+test_gi_int16_in_ptr_max (gint16 *int16)
+{
+ g_assert(*int16 == G_MAXINT16);
+}
+
+/**
+ * test_gi_int16_in_ptr_min:
+ * int16: (in):
+ */
+void
+test_gi_int16_in_ptr_min (gint16 *int16)
+{
+ g_assert(*int16 == G_MININT16);
+}
+
+/**
+ * test_gi_int16_out_max:
+ * int16: (out):
+ */
+void
+test_gi_int16_out_max (gint16 *int16)
+{
+ *int16 = G_MAXINT16;
+}
+
+/**
+ * test_gi_int16_out_min:
+ * int16: (out):
+ */
+void
+test_gi_int16_out_min (gint16 *int16)
+{
+ *int16 = G_MININT16;
+}
+
+/**
+ * test_gi_int16_inout_max_min:
+ * int16: (inout):
+ */
+void
+test_gi_int16_inout_max_min (gint16 *int16)
+{
+ g_assert(*int16 == G_MAXINT16);
+ *int16 = G_MININT16;
+}
+
+/**
+ * test_gi_int16_inout_min_max:
+ * int16: (inout):
+ */
+void
+test_gi_int16_inout_min_max (gint16 *int16)
+{
+ g_assert(*int16 == G_MININT16);
+ *int16 = G_MAXINT16;
+}
+
+
+guint16
+test_gi_uint16_return (void)
+{
+ return G_MAXUINT16;
+}
+
+/**
+ * test_gi_uint16_return_ptr:
+ * Returns: (transfer none):
+ */
+guint16 *
+test_gi_uint16_return_ptr (void)
+{
+ static guint16 uint16 = G_MAXUINT16;
+ return &uint16;
+}
+
+void
+test_gi_uint16_in (guint16 uint16)
+{
+ g_assert(uint16 == G_MAXUINT16);
+}
+
+/**
+ * test_gi_uint16_in_ptr:
+ * uint16: (in):
+ */
+void
+test_gi_uint16_in_ptr (guint16 *uint16)
+{
+ g_assert(*uint16 == G_MAXUINT16);
+}
+
+/**
+ * test_gi_uint16_out:
+ * uint16: (out):
+ */
+void
+test_gi_uint16_out (guint16 *uint16)
+{
+ *uint16 = G_MAXUINT16;
+}
+
+/**
+ * test_gi_uint16_inout:
+ * uint16: (inout):
+ */
+void
+test_gi_uint16_inout (guint16 *uint16)
+{
+ g_assert(*uint16 == G_MAXUINT16);
+ *uint16 = 0;
+}
+
+
+gint32
+test_gi_int32_return_max (void)
+{
+ return G_MAXINT32;
+}
+
+gint32
+test_gi_int32_return_min (void)
+{
+ return G_MININT32;
+}
+
+/**
+ * test_gi_int32_return_ptr_max:
+ * Returns: (transfer none):
+ */
+gint32 *
+test_gi_int32_return_ptr_max (void)
+{
+ static gint32 int32 = G_MAXINT32;
+ return &int32;
+}
+
+/**
+ * test_gi_int32_return_ptr_min:
+ * Returns: (transfer none):
+ */
+gint32 *
+test_gi_int32_return_ptr_min (void)
+{
+ static gint32 int32 = G_MININT32;
+ return &int32;
+}
+
+void
+test_gi_int32_in_max (gint32 int32)
+{
+ g_assert(int32 == G_MAXINT32);
+}
+
+void
+test_gi_int32_in_min (gint32 int32)
+{
+ g_assert(int32 == G_MININT32);
+}
+
+/**
+ * test_gi_int32_in_ptr_max:
+ * int32: (in):
+ */
+void
+test_gi_int32_in_ptr_max (gint32 *int32)
+{
+ g_assert(*int32 == G_MAXINT32);
+}
+
+/**
+ * test_gi_int32_in_ptr_min:
+ * int32: (in):
+ */
+void
+test_gi_int32_in_ptr_min (gint32 *int32)
+{
+ g_assert(*int32 == G_MININT32);
+}
+
+/**
+ * test_gi_int32_out_max:
+ * int32: (out):
+ */
+void
+test_gi_int32_out_max (gint32 *int32)
+{
+ *int32 = G_MAXINT32;
+}
+
+/**
+ * test_gi_int32_out_min:
+ * int32: (out):
+ */
+void
+test_gi_int32_out_min (gint32 *int32)
+{
+ *int32 = G_MININT32;
+}
+
+/**
+ * test_gi_int32_inout_max_min:
+ * int32: (inout):
+ */
+void
+test_gi_int32_inout_max_min (gint32 *int32)
+{
+ g_assert(*int32 == G_MAXINT32);
+ *int32 = G_MININT32;
+}
+
+/**
+ * test_gi_int32_inout_min_max:
+ * int32: (inout):
+ */
+void
+test_gi_int32_inout_min_max (gint32 *int32)
+{
+ g_assert(*int32 == G_MININT32);
+ *int32 = G_MAXINT32;
+}
+
+
+guint32
+test_gi_uint32_return (void)
+{
+ return G_MAXUINT32;
+}
+
+/**
+ * test_gi_uint32_return_ptr:
+ * Returns: (transfer none):
+ */
+guint32 *
+test_gi_uint32_return_ptr (void)
+{
+ static guint32 uint32 = G_MAXUINT32;
+ return &uint32;
+}
+
+void
+test_gi_uint32_in (guint32 uint32)
+{
+ g_assert(uint32 == G_MAXUINT32);
+}
+
+/**
+ * test_gi_uint32_in_ptr:
+ * uint32: (in):
+ */
+void
+test_gi_uint32_in_ptr (guint32 *uint32)
+{
+ g_assert(*uint32 == G_MAXUINT32);
+}
+
+/**
+ * test_gi_uint32_out:
+ * uint32: (out):
+ */
+void
+test_gi_uint32_out (guint32 *uint32)
+{
+ *uint32 = G_MAXUINT32;
+}
+
+/**
+ * test_gi_uint32_inout:
+ * uint32: (inout):
+ */
+void
+test_gi_uint32_inout (guint32 *uint32)
+{
+ g_assert(*uint32 == G_MAXUINT32);
+ *uint32 = 0;
+}
+
+
+gint64
+test_gi_int64_return_max (void)
+{
+ return G_MAXINT64;
+}
+
+gint64
+test_gi_int64_return_min (void)
+{
+ return G_MININT64;
+}
+
+/**
+ * test_gi_int64_return_ptr_max:
+ * Returns: (transfer none):
+ */
+gint64 *
+test_gi_int64_return_ptr_max (void)
+{
+ static gint64 int64 = G_MAXINT64;
+ return &int64;
+}
+
+/**
+ * test_gi_int64_return_ptr_min:
+ * Returns: (transfer none):
+ */
+gint64 *
+test_gi_int64_return_ptr_min (void)
+{
+ static gint64 int64 = G_MININT64;
+ return &int64;
+}
+
+void
+test_gi_int64_in_max (gint64 int64)
+{
+ g_assert(int64 == G_MAXINT64);
+}
+
+void
+test_gi_int64_in_min (gint64 int64)
+{
+ g_assert(int64 == G_MININT64);
+}
+
+/**
+ * test_gi_int64_in_ptr_max:
+ * int64: (in):
+ */
+void
+test_gi_int64_in_ptr_max (gint64 *int64)
+{
+ g_assert(*int64 == G_MAXINT64);
+}
+
+/**
+ * test_gi_int64_in_ptr_min:
+ * int64: (in):
+ */
+void
+test_gi_int64_in_ptr_min (gint64 *int64)
+{
+ g_assert(*int64 == G_MININT64);
+}
+
+/**
+ * test_gi_int64_out_max:
+ * int64: (out):
+ */
+void
+test_gi_int64_out_max (gint64 *int64)
+{
+ *int64 = G_MAXINT64;
+}
+
+/**
+ * test_gi_int64_out_min:
+ * int64: (out):
+ */
+void
+test_gi_int64_out_min (gint64 *int64)
+{
+ *int64 = G_MININT64;
+}
+
+/**
+ * test_gi_int64_inout_max_min:
+ * int64: (inout):
+ */
+void
+test_gi_int64_inout_max_min (gint64 *int64)
+{
+ g_assert(*int64 == G_MAXINT64);
+ *int64 = G_MININT64;
+}
+
+/**
+ * test_gi_int64_inout_min_max:
+ * int64: (inout):
+ */
+void
+test_gi_int64_inout_min_max (gint64 *int64)
+{
+ g_assert(*int64 == G_MININT64);
+ *int64 = G_MAXINT64;
+}
+
+
+guint64
+test_gi_uint64_return (void)
+{
+ return G_MAXUINT64;
+}
+
+/**
+ * test_gi_uint64_return_ptr:
+ * Returns: (transfer none):
+ */
+guint64 *
+test_gi_uint64_return_ptr (void)
+{
+ static guint64 uint64 = G_MAXUINT64;
+ return &uint64;
+}
+
+void
+test_gi_uint64_in (guint64 uint64)
+{
+ g_assert(uint64 == G_MAXUINT64);
+}
+
+/**
+ * test_gi_uint64_in_ptr:
+ * uint64: (in):
+ */
+void
+test_gi_uint64_in_ptr (guint64 *uint64)
+{
+ g_assert(*uint64 == G_MAXUINT64);
+}
+
+/**
+ * test_gi_uint64_out:
+ * uint64: (out):
+ */
+void
+test_gi_uint64_out (guint64 *uint64)
+{
+ *uint64 = G_MAXUINT64;
+}
+
+/**
+ * test_gi_uint64_inout:
+ * uint64: (inout):
+ */
+void
+test_gi_uint64_inout (guint64 *uint64)
+{
+ g_assert(*uint64 == G_MAXUINT64);
+ *uint64 = 0;
+}
+
+
+gshort
+test_gi_short_return_max (void)
+{
+ return G_MAXSHORT;
+}
+
+gshort
+test_gi_short_return_min (void)
+{
+ return G_MINSHORT;
+}
+
+/**
+ * test_gi_short_return_ptr_max:
+ * Returns: (transfer none):
+ */
+gshort *
+test_gi_short_return_ptr_max (void)
+{
+ static gshort short_ = G_MAXSHORT;
+ return &short_;
+}
+
+/**
+ * test_gi_short_return_ptr_min:
+ * Returns: (transfer none):
+ */
+gshort *
+test_gi_short_return_ptr_min (void)
+{
+ static gshort short_ = G_MINSHORT;
+ return &short_;
+}
+
+void
+test_gi_short_in_max (gshort short_)
+{
+ g_assert(short_ == G_MAXSHORT);
+}
+
+void
+test_gi_short_in_min (gshort short_)
+{
+ g_assert(short_ == G_MINSHORT);
+}
+
+/**
+ * test_gi_short_in_ptr_max:
+ * short_: (in):
+ */
+void
+test_gi_short_in_ptr_max (gshort *short_)
+{
+ g_assert(*short_ == G_MAXSHORT);
+}
+
+/**
+ * test_gi_short_in_ptr_min:
+ * short_: (in):
+ */
+void
+test_gi_short_in_ptr_min (gshort *short_)
+{
+ g_assert(*short_ == G_MINSHORT);
+}
+
+/**
+ * test_gi_short_out_max:
+ * short_: (out):
+ */
+void
+test_gi_short_out_max (gshort *short_)
+{
+ *short_ = G_MAXSHORT;
+}
+
+/**
+ * test_gi_short_out_min:
+ * short_: (out):
+ */
+void
+test_gi_short_out_min (gshort *short_)
+{
+ *short_ = G_MINSHORT;
+}
+
+/**
+ * test_gi_short_inout_max_min:
+ * short_: (inout):
+ */
+void
+test_gi_short_inout_max_min (gshort *short_)
+{
+ g_assert(*short_ == G_MAXSHORT);
+ *short_ = G_MINSHORT;
+}
+
+/**
+ * test_gi_short_inout_min_max:
+ * short_: (inout):
+ */
+void
+test_gi_short_inout_min_max (gshort *short_)
+{
+ g_assert(*short_ == G_MINSHORT);
+ *short_ = G_MAXSHORT;
+}
+
+
+gushort
+test_gi_ushort_return (void)
+{
+ return G_MAXUSHORT;
+}
+
+/**
+ * test_gi_ushort_return_ptr:
+ * Returns: (transfer none):
+ */
+gushort *
+test_gi_ushort_return_ptr (void)
+{
+ static gushort ushort = G_MAXUSHORT;
+ return &ushort;
+}
+
+void
+test_gi_ushort_in (gushort ushort)
+{
+ g_assert(ushort == G_MAXUSHORT);
+}
+
+/**
+ * test_gi_ushort_in_ptr:
+ * ushort: (in):
+ */
+void
+test_gi_ushort_in_ptr (gushort *ushort)
+{
+ g_assert(*ushort == G_MAXUSHORT);
+}
+
+/**
+ * test_gi_ushort_out:
+ * ushort: (out):
+ */
+void
+test_gi_ushort_out (gushort *ushort)
+{
+ *ushort = G_MAXUSHORT;
+}
+
+/**
+ * test_gi_ushort_inout:
+ * ushort: (inout):
+ */
+void
+test_gi_ushort_inout (gushort *ushort)
+{
+ g_assert(*ushort == G_MAXUSHORT);
+ *ushort = 0;
+}
+
+
+gint
+test_gi_int_return_max (void)
+{
+ return G_MAXINT;
+}
+
+gint
+test_gi_int_return_min (void)
+{
+ return G_MININT;
+}
+
+/**
+ * test_gi_int_return_ptr_max:
+ * Returns: (transfer none):
+ */
+gint *
+test_gi_int_return_ptr_max (void)
+{
+ static gint int_ = G_MAXINT;
+ return &int_;
+}
+
+/**
+ * test_gi_int_return_ptr_min:
+ * Returns: (transfer none):
+ */
+gint *
+test_gi_int_return_ptr_min (void)
+{
+ static gint int_ = G_MININT;
+ return &int_;
+}
+
+void
+test_gi_int_in_max (gint int_)
+{
+ g_assert(int_ == G_MAXINT);
+}
+
+void
+test_gi_int_in_min (gint int_)
+{
+ g_assert(int_ == G_MININT);
+}
+
+/**
+ * test_gi_int_in_ptr_max:
+ * int_: (in):
+ */
+void
+test_gi_int_in_ptr_max (gint *int_)
+{
+ g_assert(*int_ == G_MAXINT);
+}
+
+/**
+ * test_gi_int_in_ptr_min:
+ * int_: (in):
+ */
+void
+test_gi_int_in_ptr_min (gint *int_)
+{
+ g_assert(*int_ == G_MININT);
+}
+
+/**
+ * test_gi_int_out_max:
+ * int_: (out):
+ */
+void
+test_gi_int_out_max (gint *int_)
+{
+ *int_ = G_MAXINT;
+}
+
+/**
+ * test_gi_int_out_min:
+ * int_: (out):
+ */
+void
+test_gi_int_out_min (gint *int_)
+{
+ *int_ = G_MININT;
+}
+
+/**
+ * test_gi_int_inout_max_min:
+ * int_: (inout):
+ */
+void
+test_gi_int_inout_max_min (gint *int_)
+{
+ g_assert(*int_ == G_MAXINT);
+ *int_ = G_MININT;
+}
+
+/**
+ * test_gi_int_inout_min_max:
+ * int_: (inout):
+ */
+void
+test_gi_int_inout_min_max (gint *int_)
+{
+ g_assert(*int_ == G_MININT);
+ *int_ = G_MAXINT;
+}
+
+
+guint
+test_gi_uint_return (void)
+{
+ return G_MAXUINT;
+}
+
+/**
+ * test_gi_uint_return_ptr:
+ * Returns: (transfer none):
+ */
+guint *
+test_gi_uint_return_ptr (void)
+{
+ static guint uint = G_MAXUINT;
+ return &uint;
+}
+
+void
+test_gi_uint_in (guint uint)
+{
+ g_assert(uint == G_MAXUINT);
+}
+
+/**
+ * test_gi_uint_in_ptr:
+ * uint: (in):
+ */
+void
+test_gi_uint_in_ptr (guint *uint)
+{
+ g_assert(*uint == G_MAXUINT);
+}
+
+/**
+ * test_gi_uint_out:
+ * uint: (out):
+ */
+void
+test_gi_uint_out (guint *uint)
+{
+ *uint = G_MAXUINT;
+}
+
+/**
+ * test_gi_uint_inout:
+ * uint: (inout):
+ */
+void
+test_gi_uint_inout (guint *uint)
+{
+ g_assert(*uint == G_MAXUINT);
+ *uint = 0;
+}
+
+
+glong
+test_gi_long_return_max (void)
+{
+ return G_MAXLONG;
+}
+
+glong
+test_gi_long_return_min (void)
+{
+ return G_MINLONG;
+}
+
+/**
+ * test_gi_long_return_ptr_max:
+ * Returns: (transfer none):
+ */
+glong *
+test_gi_long_return_ptr_max (void)
+{
+ static glong long_ = G_MAXLONG;
+ return &long_;
+}
+
+/**
+ * test_gi_long_return_ptr_min:
+ * Returns: (transfer none):
+ */
+glong *
+test_gi_long_return_ptr_min (void)
+{
+ static glong long_ = G_MINLONG;
+ return &long_;
+}
+
+void
+test_gi_long_in_max (glong long_)
+{
+ g_assert(long_ == G_MAXLONG);
+}
+
+void
+test_gi_long_in_min (glong long_)
+{
+ g_assert(long_ == G_MINLONG);
+}
+
+/**
+ * test_gi_long_in_ptr_max:
+ * long_: (in):
+ */
+void
+test_gi_long_in_ptr_max (glong *long_)
+{
+ g_assert(*long_ == G_MAXLONG);
+}
+
+/**
+ * test_gi_long_in_ptr_min:
+ * long_: (in):
+ */
+void
+test_gi_long_in_ptr_min (glong *long_)
+{
+ g_assert(*long_ == G_MINLONG);
+}
+
+/**
+ * test_gi_long_out_max:
+ * long_: (out):
+ */
+void
+test_gi_long_out_max (glong *long_)
+{
+ *long_ = G_MAXLONG;
+}
+
+/**
+ * test_gi_long_out_min:
+ * long_: (out):
+ */
+void
+test_gi_long_out_min (glong *long_)
+{
+ *long_ = G_MINLONG;
+}
+
+/**
+ * test_gi_long_inout_max_min:
+ * long_: (inout):
+ */
+void
+test_gi_long_inout_max_min (glong *long_)
+{
+ g_assert(*long_ == G_MAXLONG);
+ *long_ = G_MINLONG;
+}
+
+/**
+ * test_gi_long_inout_min_max:
+ * long_: (inout):
+ */
+void
+test_gi_long_inout_min_max (glong *long_)
+{
+ g_assert(*long_ == G_MINLONG);
+ *long_ = G_MAXLONG;
+}
+
+
+gulong
+test_gi_ulong_return (void)
+{
+ return G_MAXULONG;
+}
+
+/**
+ * test_gi_ulong_return_ptr:
+ * Returns: (transfer none):
+ */
+gulong *
+test_gi_ulong_return_ptr (void)
+{
+ static gulong ulong = G_MAXULONG;
+ return &ulong;
+}
+
+void
+test_gi_ulong_in (gulong ulong)
+{
+ g_assert(ulong == G_MAXULONG);
+}
+
+/**
+ * test_gi_ulong_in_ptr:
+ * ulong: (in):
+ */
+void
+test_gi_ulong_in_ptr (gulong *ulong)
+{
+ g_assert(*ulong == G_MAXULONG);
+}
+
+/**
+ * test_gi_ulong_out:
+ * ulong: (out):
+ */
+void
+test_gi_ulong_out (gulong *ulong)
+{
+ *ulong = G_MAXULONG;
+}
+
+/**
+ * test_gi_ulong_inout:
+ * ulong: (inout):
+ */
+void
+test_gi_ulong_inout (gulong *ulong)
+{
+ g_assert(*ulong == G_MAXULONG);
+ *ulong = 0;
+}
+
+
+gssize
+test_gi_ssize_return_max (void)
+{
+ return G_MAXSSIZE;
+}
+
+gssize
+test_gi_ssize_return_min (void)
+{
+ return G_MINSSIZE;
+}
+
+/**
+ * test_gi_ssize_return_ptr_max:
+ * Returns: (transfer none):
+ */
+gssize *
+test_gi_ssize_return_ptr_max (void)
+{
+ static gssize ssize = G_MAXSSIZE;
+ return &ssize;
+}
+
+/**
+ * test_gi_ssize_return_ptr_min:
+ * Returns: (transfer none):
+ */
+gssize *
+test_gi_ssize_return_ptr_min (void)
+{
+ static gssize ssize = G_MINSSIZE;
+ return &ssize;
+}
+
+void
+test_gi_ssize_in_max (gssize ssize)
+{
+ g_assert(ssize == G_MAXSSIZE);
+}
+
+void
+test_gi_ssize_in_min (gssize ssize)
+{
+ g_assert(ssize == G_MINSSIZE);
+}
+
+/**
+ * test_gi_ssize_in_ptr_max:
+ * ssize: (in):
+ */
+void
+test_gi_ssize_in_ptr_max (gssize *ssize)
+{
+ g_assert(*ssize == G_MAXSSIZE);
+}
+
+/**
+ * test_gi_ssize_in_ptr_min:
+ * ssize: (in):
+ */
+void
+test_gi_ssize_in_ptr_min (gssize *ssize)
+{
+ g_assert(*ssize == G_MINSSIZE);
+}
+
+/**
+ * test_gi_ssize_out_max:
+ * ssize: (out):
+ */
+void
+test_gi_ssize_out_max (gssize *ssize)
+{
+ *ssize = G_MAXSSIZE;
+}
+
+/**
+ * test_gi_ssize_out_min:
+ * ssize: (out):
+ */
+void
+test_gi_ssize_out_min (gssize *ssize)
+{
+ *ssize = G_MINSSIZE;
+}
+
+/**
+ * test_gi_ssize_inout_max_min:
+ * ssize: (inout):
+ */
+void
+test_gi_ssize_inout_max_min (gssize *ssize)
+{
+ g_assert(*ssize == G_MAXSSIZE);
+ *ssize = G_MINSSIZE;
+}
+
+/**
+ * test_gi_ssize_inout_min_max:
+ * ssize: (inout):
+ */
+void
+test_gi_ssize_inout_min_max (gssize *ssize)
+{
+ g_assert(*ssize == G_MINSSIZE);
+ *ssize = G_MAXSSIZE;
+}
+
+
+gsize
+test_gi_size_return (void)
+{
+ return G_MAXSIZE;
+}
+
+/**
+ * test_gi_size_return_ptr:
+ * Returns: (transfer none):
+ */
+gsize *
+test_gi_size_return_ptr (void)
+{
+ static gsize size = G_MAXSIZE;
+ return &size;
+}
+
+void
+test_gi_size_in (gsize size)
+{
+ g_assert(size == G_MAXSIZE);
+}
+
+/**
+ * test_gi_size_in_ptr:
+ * size: (in):
+ */
+void
+test_gi_size_in_ptr (gsize *size)
+{
+ g_assert(*size == G_MAXSIZE);
+}
+
+/**
+ * test_gi_size_out:
+ * size: (out):
+ */
+void
+test_gi_size_out (gsize *size)
+{
+ *size = G_MAXSIZE;
+}
+
+/**
+ * test_gi_size_inout:
+ * size: (inout):
+ */
+void
+test_gi_size_inout (gsize *size)
+{
+ g_assert(*size == G_MAXSIZE);
+ *size = 0;
+}
+
+
+gfloat
+test_gi_float_return (void)
+{
+ return G_MAXFLOAT;
+}
+
+/**
+ * test_gi_float_return_ptr:
+ * Returns: (transfer none):
+ */
+gfloat *
+test_gi_float_return_ptr (void)
+{
+ static gfloat float_ = G_MAXFLOAT;
+ return &float_;
+}
+
+void
+test_gi_float_in (gfloat float_)
+{
+ g_assert(float_ == G_MAXFLOAT);
+}
+
+/**
+ * test_gi_float_in_ptr:
+ * float_: (in):
+ */
+void
+test_gi_float_in_ptr (gfloat *float_)
+{
+ g_assert(*float_ == G_MAXFLOAT);
+}
+
+/**
+ * test_gi_float_out:
+ * float_: (out):
+ */
+void
+test_gi_float_out (gfloat *float_)
+{
+ *float_ = G_MAXFLOAT;
+}
+
+/**
+ * test_gi_float_inout:
+ * float_: (inout):
+ */
+void
+test_gi_float_inout (gfloat *float_)
+{
+ g_assert(*float_ == G_MAXFLOAT);
+ *float_ = G_MINFLOAT;
+}
+
+
+gdouble
+test_gi_double_return (void)
+{
+ return G_MAXDOUBLE;
+}
+
+/**
+ * test_gi_double_return_ptr:
+ * Returns: (transfer none):
+ */
+gdouble *
+test_gi_double_return_ptr (void)
+{
+ static gdouble double_ = G_MAXDOUBLE;
+ return &double_;
+}
+
+void
+test_gi_double_in (gdouble double_)
+{
+ g_assert(double_ == G_MAXDOUBLE);
+}
+
+/**
+ * test_gi_double_in_ptr:
+ * double_: (in):
+ */
+void
+test_gi_double_in_ptr (gdouble *double_)
+{
+ g_assert(*double_ == G_MAXDOUBLE);
+}
+
+/**
+ * test_gi_double_out:
+ * double_: (out):
+ */
+void
+test_gi_double_out (gdouble *double_)
+{
+ *double_ = G_MAXDOUBLE;
+}
+
+/**
+ * test_gi_double_inout:
+ * double_: (inout):
+ */
+void
+test_gi_double_inout (gdouble *double_)
+{
+ g_assert(*double_ == G_MAXDOUBLE);
+ *double_ = G_MINDOUBLE;
+}
+
+
+time_t
+test_gi_time_t_return (void)
+{
+ return 1234567890;
+}
+
+/**
+ * test_gi_time_t_return_ptr:
+ * Returns: (transfer none):
+ */
+time_t *
+test_gi_time_t_return_ptr (void)
+{
+ static time_t time_t_ = 1234567890;
+ return &time_t_;
+}
+
+void
+test_gi_time_t_in (time_t time_t_)
+{
+ g_assert(time_t_ == 1234567890);
+}
+
+/**
+ * test_gi_time_t_in_ptr:
+ * time_t_: (in):
+ */
+void
+test_gi_time_t_in_ptr (time_t *time_t_)
+{
+ g_assert(*time_t_ == 1234567890);
+}
+
+/**
+ * test_gi_time_t_out:
+ * time_t_: (out):
+ */
+void
+test_gi_time_t_out (time_t *time_t_)
+{
+ *time_t_ = 1234567890;
+}
+
+/**
+ * test_gi_time_t_inout:
+ * time_t_: (inout):
+ */
+void
+test_gi_time_t_inout (time_t *time_t_)
+{
+ g_assert(*time_t_ == 1234567890);
+ *time_t_ = 0;
+}
+
+
+GType
+test_gi_gtype_return (void)
+{
+ return G_TYPE_NONE;
+}
+
+/**
+ * test_gi_gtype_return_ptr:
+ * Returns: (transfer none):
+ */
+GType *
+test_gi_gtype_return_ptr (void)
+{
+ static GType gtype = G_TYPE_NONE;
+ return &gtype;
+}
+
+void
+test_gi_gtype_in (GType gtype)
+{
+ g_assert(gtype == G_TYPE_NONE);
+}
+
+/**
+ * test_gi_gtype_in_ptr:
+ * gtype: (in):
+ */
+void
+test_gi_gtype_in_ptr (GType *gtype)
+{
+ g_assert(*gtype == G_TYPE_NONE);
+}
+
+/**
+ * test_gi_gtype_out:
+ * gtype: (out):
+ */
+void
+test_gi_gtype_out (GType *gtype)
+{
+ *gtype = G_TYPE_NONE;
+}
+
+/**
+ * test_gi_gtype_inout:
+ * gtype: (inout):
+ */
+void
+test_gi_gtype_inout (GType *gtype)
+{
+ g_assert(*gtype == G_TYPE_NONE);
+ *gtype = G_TYPE_INT;
+}
+
+
+const gchar *
+test_gi_utf8_none_return (void)
+{
+ return TESTGI_CONSTANT_UTF8;
+}
+
+gchar *
+test_gi_utf8_full_return (void)
+{
+ return g_strdup(TESTGI_CONSTANT_UTF8);
+}
+
+void
+test_gi_utf8_none_in (const gchar *utf8)
+{
+ g_assert(strcmp(TESTGI_CONSTANT_UTF8, utf8) == 0);
+}
+
+void
+test_gi_utf8_full_in (gchar *utf8)
+{
+ g_assert(strcmp(TESTGI_CONSTANT_UTF8, utf8) == 0);
+ g_free(utf8);
+}
+
+/**
+ * test_gi_utf8_none_out:
+ * utf8: (out) (transfer none):
+ */
+void
+test_gi_utf8_none_out (gchar **utf8)
+{
+ *utf8 = TESTGI_CONSTANT_UTF8;
+}
+
+/**
+ * test_gi_utf8_full_out:
+ * utf8: (out) (transfer full):
+ */
+void
+test_gi_utf8_full_out (gchar **utf8)
+{
+ *utf8 = g_strdup(TESTGI_CONSTANT_UTF8);
+}
+
+/**
+ * test_gi_utf8_none_inout:
+ * utf8: (inout) (transfer none):
+ */
+void
+test_gi_utf8_none_inout (gchar **utf8)
+{
+ g_assert(strcmp(TESTGI_CONSTANT_UTF8, *utf8) == 0);
+ *utf8 = "";
+}
+
+/**
+ * test_gi_utf8_full_inout:
+ * utf8: (inout) (transfer full):
+ */
+void
+test_gi_utf8_full_inout (gchar **utf8)
+{
+ g_assert(strcmp(TESTGI_CONSTANT_UTF8, *utf8) == 0);
+ g_free(*utf8);
+ *utf8 = g_strdup("");
+}
+
+
+/**
+ * test_gi_array_fixed_int_return:
+ * Returns: (array fixed-size=4):
+ */
+const gint *
+test_gi_array_fixed_int_return (void)
+{
+ static gint ints[] = {-1, 0, 1, 2};
+ return ints;
+}
+
+/**
+ * test_gi_array_fixed_short_return:
+ * Returns: (array fixed-size=4):
+ */
+const gshort *
+test_gi_array_fixed_short_return (void)
+{
+ static gshort shorts[] = {-1, 0, 1, 2};
+ return shorts;
+}
+
+/**
+ * test_gi_array_fixed_int_in:
+ * @ints: (array fixed-size=4):
+ */
+void
+test_gi_array_fixed_int_in (const gint *ints)
+{
+ g_assert(ints[0] == -1);
+ g_assert(ints[1] == 0);
+ g_assert(ints[2] == 1);
+ g_assert(ints[3] == 2);
+}
+
+/**
+ * test_gi_array_fixed_short_in:
+ * @shorts: (array fixed-size=4):
+ */
+void
+test_gi_array_fixed_short_in (const gshort *shorts)
+{
+ g_assert(shorts[0] == -1);
+ g_assert(shorts[1] == 0);
+ g_assert(shorts[2] == 1);
+ g_assert(shorts[3] == 2);
+}
+
+/**
+ * test_gi_array_fixed_out:
+ * @ints: (out) (array fixed-size=4) (transfer none):
+ */
+void
+test_gi_array_fixed_out (gint **ints)
+{
+ static gint values[] = {-1, 0, 1, 2};
+ *ints = values;
+}
+
+/**
+ * test_gi_array_fixed_inout:
+ * @ints: (inout) (array fixed-size=4) (transfer none):
+ */
+void
+test_gi_array_fixed_inout (gint **ints)
+{
+ static gint values[] = {2, 1, 0, -1};
+
+ g_assert((*ints)[0] == -1);
+ g_assert((*ints)[1] == 0);
+ g_assert((*ints)[2] == 1);
+ g_assert((*ints)[3] == 2);
+
+ *ints = values;
+}
+
+
+/**
+ * test_gi_array_return:
+ * Returns: (array length=length):
+ */
+const gint *
+test_gi_array_return (gint *length)
+{
+ static gint ints[] = {-1, 0, 1, 2};
+
+ *length = 4;
+ return ints;
+}
+
+/**
+ * test_gi_array_in:
+ * @ints: (array length=length):
+ */
+void
+test_gi_array_in (const gint *ints, gint length)
+{
+ g_assert(length == 4);
+ g_assert(ints[0] == -1);
+ g_assert(ints[1] == 0);
+ g_assert(ints[2] == 1);
+ g_assert(ints[3] == 2);
+}
+
+/**
+ * test_gi_array_out:
+ * @ints: (out) (array length=length) (transfer none):
+ */
+void
+test_gi_array_out (gint **ints, gint *length)
+{
+ static gint values[] = {-1, 0, 1, 2};
+
+ *length = 4;
+ *ints = values;
+}
+
+/**
+ * test_gi_array_inout:
+ * @ints: (inout) (array length=length) (transfer none):
+ * @length: (inout):
+ */
+void
+test_gi_array_inout (gint **ints, gint *length)
+{
+ static gint values[] = {-2, -1, 0, 1, 2};
+
+ g_assert(*length == 4);
+ g_assert((*ints)[0] == -1);
+ g_assert((*ints)[1] == 0);
+ g_assert((*ints)[2] == 1);
+ g_assert((*ints)[3] == 2);
+
+ *length = 5;
+ *ints = values;
+}
+
+
+/**
+ * test_gi_array_zero_terminated_return:
+ * Returns: (array zero-terminated=1) (transfer none):
+ */
+gchar **
+test_gi_array_zero_terminated_return (void)
+{
+ static gchar *values[] = {"0", "1", "2", NULL};
+ return values;
+}
+
+/**
+ * test_gi_array_zero_terminated_in:
+ * @utf8s: (array zero-terminated=1) (transfer none):
+ */
+void
+test_gi_array_zero_terminated_in (gchar **utf8s)
+{
+ g_assert(g_strv_length(utf8s));
+ g_assert(strcmp(utf8s[0], "0") == 0);
+ g_assert(strcmp(utf8s[1], "1") == 0);
+ g_assert(strcmp(utf8s[2], "2") == 0);
+}
+
+/**
+ * test_gi_array_zero_terminated_out:
+ * @utf8s: (out) (array zero-terminated=1) (transfer none):
+ */
+void
+test_gi_array_zero_terminated_out (gchar ***utf8s)
+{
+ static gchar *values[] = {"0", "1", "2", NULL};
+ *utf8s = values;
+}
+
+/**
+ * test_gi_array_zero_terminated_inout:
+ * @utf8s: (inout) (array zero-terminated=1) (transfer none):
+ */
+void
+test_gi_array_zero_terminated_inout (gchar ***utf8s)
+{
+ static gchar *values[] = {"-1", "0", "1", "2", NULL};
+
+ g_assert(g_strv_length(*utf8s));
+ g_assert(strcmp((*utf8s)[0], "0") == 0);
+ g_assert(strcmp((*utf8s)[1], "1") == 0);
+ g_assert(strcmp((*utf8s)[2], "2") == 0);
+
+ *utf8s = values;
+}
+
+
+/**
+ * test_gi_glist_int_none_return:
+ * Returns: (element-type gint) (transfer none):
+ */
+GList *
+test_gi_glist_int_none_return (void)
+{
+ static GList *list = NULL;
+
+ if (list == NULL) {
+ list = g_list_append(list, GINT_TO_POINTER(-1));
+ list = g_list_append(list, GINT_TO_POINTER(0));
+ list = g_list_append(list, GINT_TO_POINTER(1));
+ list = g_list_append(list, GINT_TO_POINTER(2));
+ }
+
+ return list;
+}
+
+/**
+ * test_gi_glist_utf8_none_return:
+ * Returns: (element-type utf8) (transfer none):
+ */
+GList *
+test_gi_glist_utf8_none_return (void)
+{
+ static GList *list = NULL;
+
+ if (list == NULL) {
+ list = g_list_append(list, "0");
+ list = g_list_append(list, "1");
+ list = g_list_append(list, "2");
+ }
+
+ return list;
+}
+
+/**
+ * test_gi_glist_utf8_container_return:
+ * Returns: (element-type utf8) (transfer container):
+ */
+GList *
+test_gi_glist_utf8_container_return (void)
+{
+ GList *list = NULL;
+
+ list = g_list_append(list, "0");
+ list = g_list_append(list, "1");
+ list = g_list_append(list, "2");
+
+ return list;
+}
+
+/**
+ * test_gi_glist_utf8_full_return:
+ * Returns: (element-type utf8) (transfer full):
+ */
+GList *
+test_gi_glist_utf8_full_return (void)
+{
+ GList *list = NULL;
+
+ list = g_list_append(list, g_strdup("0"));
+ list = g_list_append(list, g_strdup("1"));
+ list = g_list_append(list, g_strdup("2"));
+
+ return list;
+}
+
+/**
+ * test_gi_glist_int_none_in:
+ * @list: (element-type gint) (transfer none):
+ */
+void
+test_gi_glist_int_none_in (GList *list)
+{
+ g_assert(g_list_length(list) == 4);
+ g_assert(GPOINTER_TO_INT(g_list_nth_data(list, 0)) == -1);
+ g_assert(GPOINTER_TO_INT(g_list_nth_data(list, 1)) == 0);
+ g_assert(GPOINTER_TO_INT(g_list_nth_data(list, 2)) == 1);
+ g_assert(GPOINTER_TO_INT(g_list_nth_data(list, 3)) == 2);
+}
+
+/**
+ * test_gi_glist_utf8_none_in:
+ * @list: (element-type utf8) (transfer none):
+ */
+void
+test_gi_glist_utf8_none_in (GList *list)
+{
+ g_assert(g_list_length(list) == 3);
+ g_assert(strcmp(g_list_nth_data(list, 0), "0") == 0);
+ g_assert(strcmp(g_list_nth_data(list, 1), "1") == 0);
+ g_assert(strcmp(g_list_nth_data(list, 2), "2") == 0);
+}
+
+/**
+ * test_gi_glist_utf8_container_in:
+ * @list: (element-type utf8) (transfer container):
+ */
+void
+test_gi_glist_utf8_container_in (GList *list)
+{
+ g_assert(g_list_length(list) == 3);
+ g_assert(strcmp(g_list_nth_data(list, 0), "0") == 0);
+ g_assert(strcmp(g_list_nth_data(list, 1), "1") == 0);
+ g_assert(strcmp(g_list_nth_data(list, 2), "2") == 0);
+ g_list_free(list);
+}
+
+/**
+ * test_gi_glist_utf8_full_in:
+ * @list: (element-type utf8) (transfer full):
+ */
+void
+test_gi_glist_utf8_full_in (GList *list)
+{
+ g_assert(g_list_length(list) == 3);
+ g_assert(strcmp(g_list_nth_data(list, 0), "0") == 0);
+ g_assert(strcmp(g_list_nth_data(list, 1), "1") == 0);
+ g_assert(strcmp(g_list_nth_data(list, 2), "2") == 0);
+ g_free(g_list_nth_data(list, 0));
+ g_free(g_list_nth_data(list, 1));
+ g_free(g_list_nth_data(list, 2));
+ g_list_free(list);
+}
+
+/**
+ * test_gi_glist_utf8_none_out:
+ * @list: (out) (element-type utf8) (transfer none):
+ */
+void
+test_gi_glist_utf8_none_out (GList **list)
+{
+ static GList *values = NULL;
+
+ if (values == NULL) {
+ values = g_list_append(values, "0");
+ values = g_list_append(values, "1");
+ values = g_list_append(values, "2");
+ }
+
+ *list = values;
+}
+
+/**
+ * test_gi_glist_utf8_container_out:
+ * @list: (out) (element-type utf8) (transfer container):
+ */
+void
+test_gi_glist_utf8_container_out (GList **list)
+{
+ *list = NULL;
+
+ *list = g_list_append(*list, "0");
+ *list = g_list_append(*list, "1");
+ *list = g_list_append(*list, "2");
+}
+
+/**
+ * test_gi_glist_utf8_full_out:
+ * @list: (out) (element-type utf8) (transfer full):
+ */
+void
+test_gi_glist_utf8_full_out (GList **list)
+{
+ *list = NULL;
+
+ *list = g_list_append(*list, g_strdup("0"));
+ *list = g_list_append(*list, g_strdup("1"));
+ *list = g_list_append(*list, g_strdup("2"));
+}
+
+/**
+ * test_gi_glist_utf8_none_inout:
+ * @list: (inout) (element-type utf8) (transfer none):
+ */
+void
+test_gi_glist_utf8_none_inout (GList **list)
+{
+ static GList *values = NULL;
+
+ g_assert(g_list_length(*list) == 3);
+ g_assert(strcmp(g_list_nth_data(*list, 0), "0") == 0);
+ g_assert(strcmp(g_list_nth_data(*list, 1), "1") == 0);
+ g_assert(strcmp(g_list_nth_data(*list, 2), "2") == 0);
+
+ if (values == NULL) {
+ values = g_list_append(values, "-2");
+ values = g_list_append(values, "-1");
+ values = g_list_append(values, "0");
+ values = g_list_append(values, "1");
+ }
+
+ *list = values;
+}
+
+/**
+ * test_gi_glist_utf8_container_inout:
+ * @list: (inout) (element-type utf8) (transfer container):
+ */
+void
+test_gi_glist_utf8_container_inout (GList **list)
+{
+ g_assert(g_list_length(*list) == 3);
+ g_assert(strcmp(g_list_nth_data(*list, 0), "0") == 0);
+ g_assert(strcmp(g_list_nth_data(*list, 1), "1") == 0);
+ g_assert(strcmp(g_list_nth_data(*list, 2), "2") == 0);
+
+ *list = g_list_remove_link(*list, g_list_last(*list));
+
+ *list = g_list_prepend(*list, "-1");
+ *list = g_list_prepend(*list, "-2");
+}
+
+/**
+ * test_gi_glist_utf8_full_inout:
+ * @list: (inout) (element-type utf8) (transfer full):
+ */
+void
+test_gi_glist_utf8_full_inout (GList **list)
+{
+ gpointer *data;
+
+ g_assert(g_list_length(*list) == 3);
+ g_assert(strcmp(g_list_nth_data(*list, 0), "0") == 0);
+ g_assert(strcmp(g_list_nth_data(*list, 1), "1") == 0);
+ g_assert(strcmp(g_list_nth_data(*list, 2), "2") == 0);
+
+ data = g_list_last(*list)->data;
+ *list = g_list_remove(*list, data);
+ g_free(data);
+
+ *list = g_list_prepend(*list, g_strdup("-1"));
+ *list = g_list_prepend(*list, g_strdup("-2"));
+}
+
+
+/**
+ * test_gi_gslist_int_none_return:
+ * Returns: (element-type gint) (transfer none):
+ */
+GSList *
+test_gi_gslist_int_none_return (void)
+{
+ static GSList *list = NULL;
+
+ if (list == NULL) {
+ list = g_slist_prepend(list, GINT_TO_POINTER(-1));
+ list = g_slist_prepend(list, GINT_TO_POINTER(0));
+ list = g_slist_prepend(list, GINT_TO_POINTER(1));
+ list = g_slist_prepend(list, GINT_TO_POINTER(2));
+ list = g_slist_reverse(list);
+ }
+
+ return list;
+}
+
+/**
+ * test_gi_gslist_utf8_none_return:
+ * Returns: (element-type utf8) (transfer none):
+ */
+GSList *
+test_gi_gslist_utf8_none_return (void)
+{
+ static GSList *list = NULL;
+
+ if (list == NULL) {
+ list = g_slist_prepend(list, "0");
+ list = g_slist_prepend(list, "1");
+ list = g_slist_prepend(list, "2");
+ list = g_slist_reverse(list);
+ }
+
+ return list;
+}
+
+/**
+ * test_gi_gslist_utf8_container_return:
+ * Returns: (element-type utf8) (transfer container):
+ */
+GSList *
+test_gi_gslist_utf8_container_return (void)
+{
+ GSList *list = NULL;
+
+ list = g_slist_prepend(list, "0");
+ list = g_slist_prepend(list, "1");
+ list = g_slist_prepend(list, "2");
+ list = g_slist_reverse(list);
+
+ return list;
+}
+
+/**
+ * test_gi_gslist_utf8_full_return:
+ * Returns: (element-type utf8) (transfer full):
+ */
+GSList *
+test_gi_gslist_utf8_full_return (void)
+{
+ GSList *list = NULL;
+
+ list = g_slist_prepend(list, g_strdup("0"));
+ list = g_slist_prepend(list, g_strdup("1"));
+ list = g_slist_prepend(list, g_strdup("2"));
+ list = g_slist_reverse(list);
+
+ return list;
+}
+
+/**
+ * test_gi_gslist_int_none_in:
+ * @list: (element-type gint) (transfer none):
+ */
+void
+test_gi_gslist_int_none_in (GSList *list)
+{
+ g_assert(g_slist_length(list) == 4);
+ g_assert(GPOINTER_TO_INT(g_slist_nth_data(list, 0)) == -1);
+ g_assert(GPOINTER_TO_INT(g_slist_nth_data(list, 1)) == 0);
+ g_assert(GPOINTER_TO_INT(g_slist_nth_data(list, 2)) == 1);
+ g_assert(GPOINTER_TO_INT(g_slist_nth_data(list, 3)) == 2);
+}
+
+/**
+ * test_gi_gslist_utf8_none_in:
+ * @list: (element-type utf8) (transfer none):
+ */
+void
+test_gi_gslist_utf8_none_in (GSList *list)
+{
+ g_assert(g_slist_length(list) == 3);
+ g_assert(strcmp(g_slist_nth_data(list, 0), "0") == 0);
+ g_assert(strcmp(g_slist_nth_data(list, 1), "1") == 0);
+ g_assert(strcmp(g_slist_nth_data(list, 2), "2") == 0);
+}
+
+/**
+ * test_gi_gslist_utf8_container_in:
+ * @list: (element-type utf8) (transfer container):
+ */
+void
+test_gi_gslist_utf8_container_in (GSList *list)
+{
+ g_assert(g_slist_length(list) == 3);
+ g_assert(strcmp(g_slist_nth_data(list, 0), "0") == 0);
+ g_assert(strcmp(g_slist_nth_data(list, 1), "1") == 0);
+ g_assert(strcmp(g_slist_nth_data(list, 2), "2") == 0);
+ g_slist_free(list);
+}
+
+/**
+ * test_gi_gslist_utf8_full_in:
+ * @list: (element-type utf8) (transfer full):
+ */
+void
+test_gi_gslist_utf8_full_in (GSList *list)
+{
+ g_assert(g_slist_length(list) == 3);
+ g_assert(strcmp(g_slist_nth_data(list, 0), "0") == 0);
+ g_assert(strcmp(g_slist_nth_data(list, 1), "1") == 0);
+ g_assert(strcmp(g_slist_nth_data(list, 2), "2") == 0);
+ g_free(g_slist_nth_data(list, 0));
+ g_free(g_slist_nth_data(list, 1));
+ g_free(g_slist_nth_data(list, 2));
+ g_slist_free(list);
+}
+
+/**
+ * test_gi_gslist_utf8_none_out:
+ * @list: (out) (element-type utf8) (transfer none):
+ */
+void
+test_gi_gslist_utf8_none_out (GSList **list)
+{
+ static GSList *values = NULL;
+
+ if (values == NULL) {
+ values = g_slist_prepend(values, "0");
+ values = g_slist_prepend(values, "1");
+ values = g_slist_prepend(values, "2");
+ values = g_slist_reverse(values);
+ }
+
+ *list = values;
+}
+
+/**
+ * test_gi_gslist_utf8_container_out:
+ * @list: (out) (element-type utf8) (transfer container):
+ */
+void
+test_gi_gslist_utf8_container_out (GSList **list)
+{
+ *list = NULL;
+
+ *list = g_slist_prepend(*list, "0");
+ *list = g_slist_prepend(*list, "1");
+ *list = g_slist_prepend(*list, "2");
+ *list = g_slist_reverse(*list);
+}
+
+/**
+ * test_gi_gslist_utf8_full_out:
+ * @list: (out) (element-type utf8) (transfer full):
+ */
+void
+test_gi_gslist_utf8_full_out (GSList **list)
+{
+ *list = NULL;
+
+ *list = g_slist_prepend(*list, g_strdup("0"));
+ *list = g_slist_prepend(*list, g_strdup("1"));
+ *list = g_slist_prepend(*list, g_strdup("2"));
+ *list = g_slist_reverse(*list);
+}
+
+/**
+ * test_gi_gslist_utf8_none_inout:
+ * @list: (inout) (element-type utf8) (transfer none):
+ */
+void
+test_gi_gslist_utf8_none_inout (GSList **list)
+{
+ static GSList *values = NULL;
+
+ g_assert(g_slist_length(*list) == 3);
+ g_assert(strcmp(g_slist_nth_data(*list, 0), "0") == 0);
+ g_assert(strcmp(g_slist_nth_data(*list, 1), "1") == 0);
+ g_assert(strcmp(g_slist_nth_data(*list, 2), "2") == 0);
+
+ if (values == NULL) {
+ values = g_slist_prepend(values, "-2");
+ values = g_slist_prepend(values, "-1");
+ values = g_slist_prepend(values, "0");
+ values = g_slist_prepend(values, "1");
+ values = g_slist_reverse(values);
+ }
+
+ *list = values;
+}
+
+/**
+ * test_gi_gslist_utf8_container_inout:
+ * @list: (inout) (element-type utf8) (transfer container):
+ */
+void
+test_gi_gslist_utf8_container_inout (GSList **list)
+{
+ g_assert(g_slist_length(*list) == 3);
+ g_assert(strcmp(g_slist_nth_data(*list, 0), "0") == 0);
+ g_assert(strcmp(g_slist_nth_data(*list, 1), "1") == 0);
+ g_assert(strcmp(g_slist_nth_data(*list, 2), "2") == 0);
+
+ *list = g_slist_remove_link(*list, g_slist_last(*list));
+
+ *list = g_slist_prepend(*list, "-1");
+ *list = g_slist_prepend(*list, "-2");
+}
+
+/**
+ * test_gi_gslist_utf8_full_inout:
+ * @list: (inout) (element-type utf8) (transfer full):
+ */
+void
+test_gi_gslist_utf8_full_inout (GSList **list)
+{
+ gpointer *data;
+
+ g_assert(g_slist_length(*list) == 3);
+ g_assert(strcmp(g_slist_nth_data(*list, 0), "0") == 0);
+ g_assert(strcmp(g_slist_nth_data(*list, 1), "1") == 0);
+ g_assert(strcmp(g_slist_nth_data(*list, 2), "2") == 0);
+
+ data = g_slist_last(*list)->data;
+ *list = g_slist_remove(*list, data);
+ g_free(data);
+
+ *list = g_slist_prepend(*list, g_strdup("-1"));
+ *list = g_slist_prepend(*list, g_strdup("-2"));
+}
+
+
+/**
+ * test_gi_ghashtable_int_none_return:
+ * Returns: (element-type gint gint) (transfer none):
+ */
+GHashTable *
+test_gi_ghashtable_int_none_return (void)
+{
+ static GHashTable *hash_table = NULL;
+
+ if (hash_table == NULL) {
+ hash_table = g_hash_table_new(NULL, NULL);
+ g_hash_table_insert(hash_table, GINT_TO_POINTER(-1), GINT_TO_POINTER(1));
+ g_hash_table_insert(hash_table, GINT_TO_POINTER(0), GINT_TO_POINTER(0));
+ g_hash_table_insert(hash_table, GINT_TO_POINTER(1), GINT_TO_POINTER(-1));
+ g_hash_table_insert(hash_table, GINT_TO_POINTER(2), GINT_TO_POINTER(-2));
+ }
+
+ return hash_table;
+}
+
+/**
+ * test_gi_ghashtable_utf8_none_return:
+ * Returns: (element-type utf8 utf8) (transfer none):
+ */
+GHashTable *
+test_gi_ghashtable_utf8_none_return (void)
+{
+ static GHashTable *hash_table = NULL;
+
+ if (hash_table == NULL) {
+ hash_table = g_hash_table_new(g_str_hash, g_str_equal);
+ g_hash_table_insert(hash_table, "-1", "1");
+ g_hash_table_insert(hash_table, "0", "0");
+ g_hash_table_insert(hash_table, "1", "-1");
+ g_hash_table_insert(hash_table, "2", "-2");
+ }
+
+ return hash_table;
+}
+
+/**
+ * test_gi_ghashtable_utf8_container_return:
+ * Returns: (element-type utf8 utf8) (transfer container):
+ */
+GHashTable *
+test_gi_ghashtable_utf8_container_return (void)
+{
+ GHashTable *hash_table = NULL;
+
+ hash_table = g_hash_table_new(g_str_hash, g_str_equal);
+ g_hash_table_insert(hash_table, "-1", "1");
+ g_hash_table_insert(hash_table, "0", "0");
+ g_hash_table_insert(hash_table, "1", "-1");
+ g_hash_table_insert(hash_table, "2", "-2");
+
+ return hash_table;
+}
+
+/**
+ * test_gi_ghashtable_utf8_full_return:
+ * Returns: (element-type utf8 utf8) (transfer full):
+ */
+GHashTable *
+test_gi_ghashtable_utf8_full_return (void)
+{
+ GHashTable *hash_table = NULL;
+
+ hash_table = g_hash_table_new(g_str_hash, g_str_equal);
+ g_hash_table_insert(hash_table, g_strdup("-1"), g_strdup("1"));
+ g_hash_table_insert(hash_table, g_strdup("0"), g_strdup("0"));
+ g_hash_table_insert(hash_table, g_strdup("1"), g_strdup("-1"));
+ g_hash_table_insert(hash_table, g_strdup("2"), g_strdup("-2"));
+
+ return hash_table;
+}
+
+/**
+ * test_gi_ghashtable_int_none_in:
+ * @hash_table: (element-type gint gint) (transfer none):
+ */
+void
+test_gi_ghashtable_int_none_in (GHashTable *hash_table)
+{
+ g_assert(GPOINTER_TO_INT(g_hash_table_lookup(hash_table, GINT_TO_POINTER(-1))) == 1);
+ g_assert(GPOINTER_TO_INT(g_hash_table_lookup(hash_table, GINT_TO_POINTER(0))) == 0);
+ g_assert(GPOINTER_TO_INT(g_hash_table_lookup(hash_table, GINT_TO_POINTER(1))) == -1);
+ g_assert(GPOINTER_TO_INT(g_hash_table_lookup(hash_table, GINT_TO_POINTER(2))) == -2);
+}
+
+/**
+ * test_gi_ghashtable_utf8_none_in:
+ * @hash_table: (element-type utf8 utf8) (transfer none):
+ */
+void
+test_gi_ghashtable_utf8_none_in (GHashTable *hash_table)
+{
+ g_assert(strcmp(g_hash_table_lookup(hash_table, "-1"), "1") == 0);
+ g_assert(strcmp(g_hash_table_lookup(hash_table, "0"), "0") == 0);
+ g_assert(strcmp(g_hash_table_lookup(hash_table, "1"), "-1") == 0);
+ g_assert(strcmp(g_hash_table_lookup(hash_table, "2"), "-2") == 0);
+}
+
+/**
+ * test_gi_ghashtable_utf8_container_in:
+ * @hash_table: (element-type utf8 utf8) (transfer container):
+ */
+void
+test_gi_ghashtable_utf8_container_in (GHashTable *hash_table)
+{
+ g_assert(strcmp(g_hash_table_lookup(hash_table, "-1"), "1") == 0);
+ g_assert(strcmp(g_hash_table_lookup(hash_table, "0"), "0") == 0);
+ g_assert(strcmp(g_hash_table_lookup(hash_table, "1"), "-1") == 0);
+ g_assert(strcmp(g_hash_table_lookup(hash_table, "2"), "-2") == 0);
+ g_hash_table_steal_all(hash_table);
+ g_hash_table_unref(hash_table);
+}
+
+/**
+ * test_gi_ghashtable_utf8_full_in:
+ * @hash_table: (element-type utf8 utf8) (transfer full):
+ */
+void
+test_gi_ghashtable_utf8_full_in (GHashTable *hash_table)
+{
+ GHashTableIter hash_table_iter;
+ gpointer key, value;
+
+ g_assert(strcmp(g_hash_table_lookup(hash_table, "-1"), "1") == 0);
+ g_assert(strcmp(g_hash_table_lookup(hash_table, "0"), "0") == 0);
+ g_assert(strcmp(g_hash_table_lookup(hash_table, "1"), "-1") == 0);
+ g_assert(strcmp(g_hash_table_lookup(hash_table, "2"), "-2") == 0);
+
+ g_hash_table_iter_init(&hash_table_iter, hash_table);
+ while (g_hash_table_iter_next(&hash_table_iter, &key, &value)) {
+ g_free(key);
+ g_free(value);
+ g_hash_table_iter_steal(&hash_table_iter);
+ }
+
+ g_hash_table_unref(hash_table);
+}
+
+/**
+ * test_gi_ghashtable_utf8_none_out:
+ * @hash_table: (out) (element-type utf8 utf8) (transfer none):
+ */
+void
+test_gi_ghashtable_utf8_none_out (GHashTable **hash_table)
+{
+ static GHashTable *new_hash_table = NULL;
+
+ if (new_hash_table == NULL) {
+ new_hash_table = g_hash_table_new(g_str_hash, g_str_equal);
+ g_hash_table_insert(new_hash_table, "-1", "1");
+ g_hash_table_insert(new_hash_table, "0", "0");
+ g_hash_table_insert(new_hash_table, "1", "-1");
+ g_hash_table_insert(new_hash_table, "2", "-2");
+ }
+
+ *hash_table = new_hash_table;
+}
+
+/**
+ * test_gi_ghashtable_utf8_container_out:
+ * @hash_table: (out) (element-type utf8 utf8) (transfer container):
+ */
+void
+test_gi_ghashtable_utf8_container_out (GHashTable **hash_table)
+{
+ *hash_table = g_hash_table_new(g_str_hash, g_str_equal);
+ g_hash_table_insert(*hash_table, "-1", "1");
+ g_hash_table_insert(*hash_table, "0", "0");
+ g_hash_table_insert(*hash_table, "1", "-1");
+ g_hash_table_insert(*hash_table, "2", "-2");
+}
+
+/**
+ * test_gi_ghashtable_utf8_full_out:
+ * @hash_table: (out) (element-type utf8 utf8) (transfer full):
+ */
+void
+test_gi_ghashtable_utf8_full_out (GHashTable **hash_table)
+{
+ *hash_table = g_hash_table_new(g_str_hash, g_str_equal);
+ g_hash_table_insert(*hash_table, g_strdup("-1"), g_strdup("1"));
+ g_hash_table_insert(*hash_table, g_strdup("0"), g_strdup("0"));
+ g_hash_table_insert(*hash_table, g_strdup("1"), g_strdup("-1"));
+ g_hash_table_insert(*hash_table, g_strdup("2"), g_strdup("-2"));
+}
+
+/**
+ * test_gi_ghashtable_utf8_none_inout:
+ * @hash_table: (inout) (element-type utf8 utf8) (transfer none):
+ */
+void
+test_gi_ghashtable_utf8_none_inout (GHashTable **hash_table)
+{
+ static GHashTable *new_hash_table = NULL;
+
+ g_assert(strcmp(g_hash_table_lookup(*hash_table, "-1"), "1") == 0);
+ g_assert(strcmp(g_hash_table_lookup(*hash_table, "0"), "0") == 0);
+ g_assert(strcmp(g_hash_table_lookup(*hash_table, "1"), "-1") == 0);
+ g_assert(strcmp(g_hash_table_lookup(*hash_table, "2"), "-2") == 0);
+
+ if (new_hash_table == NULL) {
+ new_hash_table = g_hash_table_new(g_str_hash, g_str_equal);
+ g_hash_table_insert(new_hash_table, "-1", "1");
+ g_hash_table_insert(new_hash_table, "0", "0");
+ g_hash_table_insert(new_hash_table, "1", "1");
+ }
+
+ *hash_table = new_hash_table;
+}
+
+/**
+ * test_gi_ghashtable_utf8_container_inout:
+ * @hash_table: (inout) (element-type utf8 utf8) (transfer container):
+ */
+void
+test_gi_ghashtable_utf8_container_inout (GHashTable **hash_table)
+{
+ g_assert(strcmp(g_hash_table_lookup(*hash_table, "-1"), "1") == 0);
+ g_assert(strcmp(g_hash_table_lookup(*hash_table, "0"), "0") == 0);
+ g_assert(strcmp(g_hash_table_lookup(*hash_table, "1"), "-1") == 0);
+ g_assert(strcmp(g_hash_table_lookup(*hash_table, "2"), "-2") == 0);
+
+ g_hash_table_steal(*hash_table, "2");
+ g_hash_table_steal(*hash_table, "1");
+ g_hash_table_insert(*hash_table, "1", "1");
+}
+
+/**
+ * test_gi_ghashtable_utf8_full_inout:
+ * @hash_table: (inout) (element-type utf8 utf8) (transfer full):
+ */
+void
+test_gi_ghashtable_utf8_full_inout (GHashTable **hash_table)
+{
+ g_assert(strcmp(g_hash_table_lookup(*hash_table, "-1"), "1") == 0);
+ g_assert(strcmp(g_hash_table_lookup(*hash_table, "0"), "0") == 0);
+ g_assert(strcmp(g_hash_table_lookup(*hash_table, "1"), "-1") == 0);
+ g_assert(strcmp(g_hash_table_lookup(*hash_table, "2"), "-2") == 0);
+
+ g_hash_table_steal(*hash_table, "2");
+ g_hash_table_steal(*hash_table, "1");
+ g_hash_table_insert(*hash_table, "1", g_strdup("1"));
+}
+
+
+/**
+ * test_gi_gvalue_return:
+ * Returns: (transfer none):
+ */
+GValue *
+test_gi_gvalue_return (void)
+{
+ static GValue *value = NULL;
+
+ if (value == NULL) {
+ value = g_new0(GValue, 1);
+ g_value_init(value, G_TYPE_INT);
+ g_value_set_int(value, 42);
+ }
+
+ return value;
+}
+
+/**
+ * test_gi_gvalue_in:
+ * @value: (transfer none):
+ */
+void
+test_gi_gvalue_in (GValue *value)
+{
+ g_assert(g_value_get_int(value) == 42);
+}
+
+/**
+ * test_gi_gvalue_out:
+ * @value: (out) (transfer none):
+ */
+void
+test_gi_gvalue_out (GValue **value)
+{
+ static GValue *new_value = NULL;
+
+ if (new_value == NULL) {
+ new_value = g_new0(GValue, 1);
+ g_value_init(new_value, G_TYPE_INT);
+ g_value_set_int(new_value, 42);
+ }
+
+ *value = new_value;
+}
+
+/**
+ * test_gi_gvalue_inout:
+ * @value: (inout) (transfer none):
+ */
+void
+test_gi_gvalue_inout (GValue **value)
+{
+ g_assert(g_value_get_int(*value) == 42);
+ g_value_unset(*value);
+ g_value_init(*value, G_TYPE_STRING);
+ g_value_set_string(*value, "42");
+}
+
+
+/**
+ * test_gi_gclosure_in:
+ * @closure: (transfer none):
+ */
+void
+test_gi_gclosure_in (GClosure *closure)
+{
+ GValue return_value = {0, };
+
+ g_value_init (&return_value, G_TYPE_INT);
+
+ g_closure_invoke (closure,
+ &return_value,
+ 0, NULL,
+ NULL);
+
+ g_assert(g_value_get_int (&return_value) == 42);
+
+ g_value_unset(&return_value);
+}
+
+
+GType
+test_gi_enum_get_type (void)
+{
+ static GType type = 0;
+ if (G_UNLIKELY(type == 0)) {
+ static const GEnumValue values[] = {
+ { TESTGI_ENUM_VALUE1, "TESTGI_ENUM_VALUE1", "value1" },
+ { TESTGI_ENUM_VALUE2, "TESTGI_ENUM_VALUE2", "value2" },
+ { TESTGI_ENUM_VALUE3, "TESTGI_ENUM_VALUE3", "value3" },
+ { 0, NULL, NULL }
+ };
+ type = g_enum_register_static (g_intern_static_string ("TestGIEnum"), values);
+ }
+
+ return type;
+}
+
+TestGIEnum
+test_gi_enum_return (void)
+{
+ return TESTGI_ENUM_VALUE3;
+}
+
+void
+test_gi_enum_in (TestGIEnum enum_)
+{
+ g_assert(enum_ == TESTGI_ENUM_VALUE3);
+}
+
+/**
+ * test_gi_enum_in_ptr:
+ * @enum_: (in) (transfer none):
+ */
+void
+test_gi_enum_in_ptr (TestGIEnum *enum_)
+{
+ g_assert(*enum_ == TESTGI_ENUM_VALUE3);
+}
+
+/**
+ * test_gi_enum_out:
+ * @enum_: (out):
+ */
+void
+test_gi_enum_out (TestGIEnum *enum_)
+{
+ *enum_ = TESTGI_ENUM_VALUE3;
+}
+
+/**
+ * test_gi_enum_inout:
+ * @enum_: (inout):
+ */
+void
+test_gi_enum_inout (TestGIEnum *enum_)
+{
+ g_assert(*enum_ == TESTGI_ENUM_VALUE3);
+ *enum_ = TESTGI_ENUM_VALUE1;
+}
+
+
+GType
+test_gi_flags_get_type (void)
+{
+ static GType type = 0;
+ if (G_UNLIKELY(type == 0)) {
+ static const GFlagsValue values[] = {
+ { TESTGI_FLAGS_VALUE1, "TESTGI_FLAGS_VALUE1", "value1" },
+ { TESTGI_FLAGS_VALUE2, "TESTGI_FLAGS_VALUE2", "value2" },
+ { TESTGI_FLAGS_VALUE3, "TESTGI_FLAGS_VALUE3", "value3" },
+ { 0, NULL, NULL }
+ };
+ type = g_flags_register_static (g_intern_static_string ("TestGIFlags"), values);
+ }
+
+ return type;
+}
+
+TestGIFlags
+test_gi_flags_return (void)
+{
+ return TESTGI_FLAGS_VALUE2;
+}
+
+void
+test_gi_flags_in (TestGIFlags flags_)
+{
+ g_assert(flags_ == TESTGI_FLAGS_VALUE2);
+}
+
+/**
+ * test_gi_flags_in_ptr:
+ * @flags_: (in) (transfer none):
+ */
+void
+test_gi_flags_in_ptr (TestGIFlags *flags_)
+{
+ g_assert(*flags_ == TESTGI_FLAGS_VALUE2);
+}
+
+/**
+ * test_gi_flags_out:
+ * @flags_: (out):
+ */
+void
+test_gi_flags_out (TestGIFlags *flags_)
+{
+ *flags_ = TESTGI_FLAGS_VALUE2;
+}
+
+/**
+ * test_gi_flags_inout:
+ * @flags_: (inout):
+ */
+void
+test_gi_flags_inout (TestGIFlags *flags_)
+{
+ g_assert(*flags_ == TESTGI_FLAGS_VALUE2);
+ *flags_ = TESTGI_FLAGS_VALUE1;
+}
+
+
+/**
+ * test_gi__simple_struct_return:
+ * Returns: (transfer none):
+ */
+TestGISimpleStruct *
+test_gi__simple_struct_return (void)
+{
+ static TestGISimpleStruct *struct_ = NULL;
+
+ if (struct_ == NULL) {
+ struct_ = g_new(TestGISimpleStruct, 1);
+
+ struct_->long_ = 6;
+ struct_->int8 = 7;
+ }
+
+ return struct_;
+}
+
+/**
+ * test_gi__simple_struct_in:
+ * @struct_: (transfer none):
+ */
+void
+test_gi__simple_struct_in (TestGISimpleStruct *struct_)
+{
+ g_assert(struct_->long_ == 6);
+ g_assert(struct_->int8 == 7);
+}
+
+/**
+ * test_gi__simple_struct_out:
+ * @struct_: (out) (transfer none):
+ */
+void
+test_gi__simple_struct_out (TestGISimpleStruct **struct_)
+{
+ static TestGISimpleStruct *new_struct = NULL;
+
+ if (new_struct == NULL) {
+ new_struct = g_new(TestGISimpleStruct, 1);
+
+ new_struct->long_ = 6;
+ new_struct->int8 = 7;
+ }
+
+ *struct_ = new_struct;
+}
+
+/**
+ * test_gi__simple_struct_inout:
+ * @struct_: (inout) (transfer none):
+ */
+void
+test_gi__simple_struct_inout (TestGISimpleStruct **struct_)
+{
+ g_assert((*struct_)->long_ == 6);
+ g_assert((*struct_)->int8 == 7);
+
+ (*struct_)->long_ = 7;
+ (*struct_)->int8 = 6;
+}
+
+void
+test_gi_simple_struct_method (TestGISimpleStruct *struct_)
+{
+ g_assert(struct_->long_ == 6);
+ g_assert(struct_->int8 == 7);
+}
+
+
+GType
+test_gi_pointer_struct_get_type (void)
+{
+ static GType type = 0;
+
+ if (type == 0) {
+ type = g_pointer_type_register_static ("TestGIPointerStruct");
+ }
+
+ return type;
+}
+
+/**
+ * test_gi__pointer_struct_return:
+ * Returns: (transfer none):
+ */
+TestGIPointerStruct *
+test_gi__pointer_struct_return (void)
+{
+ static TestGIPointerStruct *struct_ = NULL;
+
+ if (struct_ == NULL) {
+ struct_ = g_new(TestGIPointerStruct, 1);
+
+ struct_->long_ = 42;
+ }
+
+ return struct_;
+}
+
+/**
+ * test_gi__pointer_struct_in:
+ * @struct_: (transfer none):
+ */
+void
+test_gi__pointer_struct_in (TestGIPointerStruct *struct_)
+{
+ g_assert(struct_->long_ == 42);
+}
+
+/**
+ * test_gi__pointer_struct_out:
+ * @struct_: (out) (transfer none):
+ */
+void
+test_gi__pointer_struct_out (TestGIPointerStruct **struct_)
+{
+ static TestGIPointerStruct *new_struct = NULL;
+
+ if (new_struct == NULL) {
+ new_struct = g_new(TestGIPointerStruct, 1);
+
+ new_struct->long_ = 42;
+ }
+
+ *struct_ = new_struct;
+}
+
+/**
+ * test_gi__pointer_struct_inout:
+ * @struct_: (inout) (transfer none):
+ */
+void
+test_gi__pointer_struct_inout (TestGIPointerStruct **struct_)
+{
+ g_assert((*struct_)->long_ == 42);
+
+ (*struct_)->long_ = 0;
+}
+
+
+TestGIBoxedStruct *
+test_gi_boxed_struct_copy (TestGIBoxedStruct *struct_)
+{
+ TestGIBoxedStruct *new_struct;
+
+ new_struct = g_slice_new (TestGIBoxedStruct);
+
+ *new_struct = *struct_;
+
+ return new_struct;
+}
+
+static void
+test_gi_boxed_struct_free (TestGIBoxedStruct *struct_)
+{
+ g_slice_free (TestGIBoxedStruct, struct_);
+}
+
+GType
+test_gi_boxed_struct_get_type (void)
+{
+ static GType type = 0;
+
+ if (type == 0) {
+ type = g_boxed_type_register_static ("TestGIBoxedStruct",
+ (GBoxedCopyFunc) test_gi_boxed_struct_copy,
+ (GBoxedFreeFunc) test_gi_boxed_struct_free);
+ }
+
+ return type;
+}
+
+
+TestGIBoxedInstantiableStruct *
+test_gi_boxed_instantiable_struct_copy (TestGIBoxedInstantiableStruct *struct_)
+{
+ TestGIBoxedInstantiableStruct *new_struct;
+
+ new_struct = g_slice_new (TestGIBoxedInstantiableStruct);
+
+ *new_struct = *struct_;
+
+ return new_struct;
+}
+
+static void
+test_gi_boxed_instantiable_struct_free (TestGIBoxedInstantiableStruct *struct_)
+{
+ g_slice_free (TestGIBoxedInstantiableStruct, struct_);
+}
+
+GType
+test_gi_boxed_instantiable_struct_get_type (void)
+{
+ static GType type = 0;
+
+ if (type == 0) {
+ type = g_boxed_type_register_static ("TestGIBoxedInstantiableStruct",
+ (GBoxedCopyFunc) test_gi_boxed_instantiable_struct_copy,
+ (GBoxedFreeFunc) test_gi_boxed_instantiable_struct_free);
+ }
+
+ return type;
+}
+
+TestGIBoxedInstantiableStruct *
+test_gi_boxed_instantiable_struct_new (void)
+{
+ return g_slice_new (TestGIBoxedInstantiableStruct);
+}
+
+/**
+ * test_gi__boxed_instantiable_struct_return:
+ * Returns: (transfer none):
+ */
+TestGIBoxedInstantiableStruct *
+test_gi__boxed_instantiable_struct_return (void)
+{
+ static TestGIBoxedInstantiableStruct *struct_ = NULL;
+
+ if (struct_ == NULL) {
+ struct_ = g_new(TestGIBoxedInstantiableStruct, 1);
+
+ struct_->long_ = 42;
+ }
+
+ return struct_;
+}
+
+/**
+ * test_gi__boxed_instantiable_struct_in:
+ * @struct_: (transfer none):
+ */
+void
+test_gi__boxed_instantiable_struct_in (TestGIBoxedInstantiableStruct *struct_)
+{
+ g_assert(struct_->long_ == 42);
+}
+
+/**
+ * test_gi__boxed_instantiable_struct_out:
+ * @struct_: (out) (transfer none):
+ */
+void
+test_gi__boxed_instantiable_struct_out (TestGIBoxedInstantiableStruct **struct_)
+{
+ static TestGIBoxedInstantiableStruct *new_struct = NULL;
+
+ if (new_struct == NULL) {
+ new_struct = g_new(TestGIBoxedInstantiableStruct, 1);
+
+ new_struct->long_ = 42;
+ }
+
+ *struct_ = new_struct;
+}
+
+/**
+ * test_gi__boxed_instantiable_struct_inout:
+ * @struct_: (inout) (transfer none):
+ */
+void
+test_gi__boxed_instantiable_struct_inout (TestGIBoxedInstantiableStruct **struct_)
+{
+ g_assert((*struct_)->long_ == 42);
+
+ (*struct_)->long_ = 0;
+}
+
+
+enum
+{
+ PROP_0,
+ PROP_INT_
+};
+
+G_DEFINE_TYPE (TestGIObject, test_gi_object, G_TYPE_OBJECT);
+
+static void
+test_gi_object_init (TestGIObject *object)
+{
+}
+
+static void
+test_gi_object_finalize (GObject *object)
+{
+ G_OBJECT_CLASS (test_gi_object_parent_class)->finalize (object);
+}
+
+static void
+test_gi_object_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
+{
+ g_return_if_fail (TESTGI_IS_OBJECT (object));
+
+ switch (prop_id) {
+ case PROP_INT_:
+ TESTGI_OBJECT (object)->int_ = g_value_get_int (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+test_gi_object_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
+{
+ g_return_if_fail (TESTGI_IS_OBJECT (object));
+
+ switch (prop_id) {
+ case PROP_INT_:
+ g_value_set_int (value, TESTGI_OBJECT (object)->int_);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+test_gi_object_class_init (TestGIObjectClass *klass)
+{
+ GObjectClass* object_class = G_OBJECT_CLASS (klass);
+#if 0
+ GObjectClass* parent_class = G_OBJECT_CLASS (klass);
+#endif
+
+ object_class->finalize = test_gi_object_finalize;
+ object_class->set_property = test_gi_object_set_property;
+ object_class->get_property = test_gi_object_get_property;
+
+ g_object_class_install_property (object_class, PROP_INT_,
+ g_param_spec_int ("int", "Integer", "An integer", G_MININT, G_MAXINT, 0,
+ G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT));
+}
+
+
+void
+test_gi_object_static_method (void)
+{
+}
+
+void
+test_gi_object_method (TestGIObject *object)
+{
+ g_return_if_fail (TESTGI_IS_OBJECT (object));
+ g_assert (object->int_ == 42);
+}
+
+void
+test_gi_object_overridden_method (TestGIObject *object)
+{
+ g_return_if_fail (TESTGI_IS_OBJECT (object));
+ g_assert (object->int_ == 0);
+}
+
+TestGIObject *
+test_gi_object_new (gint int_)
+{
+ return g_object_new (TESTGI_TYPE_OBJECT, "int", int_, NULL);
+}
+
+
+/**
+ * test_gi__object_none_return:
+ * Returns: (transfer none):
+ */
+TestGIObject *
+test_gi__object_none_return (void)
+{
+ static TestGIObject *object = NULL;
+
+ if (object == NULL) {
+ object = g_object_new(TESTGI_TYPE_OBJECT, NULL);
+ }
+
+ return object;
+}
+
+/**
+ * test_gi__object_full_return:
+ * Returns: (transfer full):
+ */
+TestGIObject *
+test_gi__object_full_return (void)
+{
+ return g_object_new(TESTGI_TYPE_OBJECT, NULL);
+}
+
+/**
+ * test_gi__object_none_in:
+ * @object: (transfer none):
+ */
+void
+test_gi__object_none_in (TestGIObject *object)
+{
+ g_assert(object->int_ == 42);
+}
+
+/**
+ * test_gi__object_full_in:
+ * @object: (transfer full):
+ */
+void
+test_gi__object_full_in (TestGIObject *object)
+{
+ g_assert(object->int_ == 42);
+ g_object_unref(object);
+}
+
+/**
+ * test_gi__object_none_out:
+ * @object: (out) (transfer none):
+ */
+void
+test_gi__object_none_out (TestGIObject **object)
+{
+ static TestGIObject *new_object = NULL;
+
+ if (new_object == NULL) {
+ new_object = g_object_new(TESTGI_TYPE_OBJECT, NULL);
+ }
+
+ *object = new_object;
+}
+
+/**
+ * test_gi__object_full_out:
+ * @object: (out) (transfer full):
+ */
+void
+test_gi__object_full_out (TestGIObject **object)
+{
+ *object = g_object_new(TESTGI_TYPE_OBJECT, NULL);
+}
+
+/**
+ * test_gi__object_none_inout:
+ * @object: (inout) (transfer none):
+ */
+void
+test_gi__object_none_inout (TestGIObject **object)
+{
+ static TestGIObject *new_object = NULL;
+
+ g_assert((*object)->int_ == 42);
+
+ if (new_object == NULL) {
+ new_object = g_object_new(TESTGI_TYPE_OBJECT, NULL);
+ new_object->int_ = 0;
+ }
+
+ *object = new_object;
+}
+
+/**
+ * test_gi__object_full_inout:
+ * @object: (inout) (transfer full):
+ */
+void
+test_gi__object_full_inout (TestGIObject **object)
+{
+ g_assert((*object)->int_ == 42);
+ g_object_unref(*object);
+
+ *object = g_object_new(TESTGI_TYPE_OBJECT, NULL);
+}
+
+/**
+ * test_gi__object_inout_same:
+ * @object: (inout):
+ */
+void
+test_gi__object_inout_same (TestGIObject **object)
+{
+ g_assert((*object)->int_ == 42);
+ (*object)->int_ = 0;
+}
+
+
+G_DEFINE_TYPE (TestGISubObject, test_gi_sub_object, TESTGI_TYPE_OBJECT);
+
+static void
+test_gi_sub_object_init (TestGISubObject *object)
+{
+}
+
+static void
+test_gi_sub_object_finalize (GObject *object)
+{
+ G_OBJECT_CLASS(test_gi_sub_object_parent_class)->finalize(object);
+}
+
+static void
+test_gi_sub_object_class_init (TestGISubObjectClass *klass)
+{
+ G_OBJECT_CLASS(klass)->finalize = test_gi_sub_object_finalize;
+}
+
+void
+test_gi_sub_object_sub_method (TestGISubObject *object)
+{
+ g_assert(TESTGI_OBJECT(object)->int_ == 0);
+}
+
+void
+test_gi_sub_object_overwritten_method (TestGISubObject *object)
+{
+ g_assert(TESTGI_OBJECT(object)->int_ == 0);
+}
+
+/**
+ * test_gi_int_out_out:
+ * int0: (out):
+ * int1: (out):
+ */
+void
+test_gi_int_out_out (gint *int0, gint *int1)
+{
+ *int0 = 6;
+ *int1 = 7;
+}
+
+/**
+ * test_gi_int_return_out:
+ * int_: (out):
+ */
+gint
+test_gi_int_return_out (gint *int_)
+{
+ *int_ = 7;
+ return 6;
+}
+
+/**
+ * test_gi_ptr_return_null:
+ * Returns: (allow-none):
+ */
+gint *
+test_gi_int_return_ptr_null (void)
+{
+ return NULL;
+}
+
diff --git a/tests/libtestgi.h b/tests/libtestgi.h
new file mode 100644
index 0000000..9fbdbbd
--- /dev/null
+++ b/tests/libtestgi.h
@@ -0,0 +1,643 @@
+/* -*- Mode: C; c-basic-offset: 4 -*-
+ * vim: tabstop=4 shiftwidth=4 expandtab
+ */
+
+#include <glib-object.h>
+
+#ifndef __TEST_GI_H__
+#define __TEST_GI_H__
+
+
+/* Constants */
+
+#define TESTGI_CONSTANT_NUMBER 42
+#define TESTGI_CONSTANT_UTF8 "const \xe2\x99\xa5 utf8"
+
+
+/* Booleans */
+
+gboolean test_gi_boolean_return_true (void);
+gboolean test_gi_boolean_return_false (void);
+
+gboolean *test_gi_boolean_return_ptr_true (void);
+gboolean *test_gi_boolean_return_ptr_false (void);
+
+void test_gi_boolean_in_true (gboolean bool_);
+void test_gi_boolean_in_false (gboolean bool_);
+
+void test_gi_boolean_out_true (gboolean *bool_);
+void test_gi_boolean_out_false (gboolean *bool_);
+
+void test_gi_boolean_inout_true_false (gboolean *bool_);
+void test_gi_boolean_inout_false_true (gboolean *bool_);
+
+void test_gi_boolean_in_ptr_true (gboolean *bool_);
+void test_gi_boolean_in_ptr_false (gboolean *bool_);
+
+
+/* Integers */
+
+gint8 test_gi_int8_return_max (void);
+gint8 test_gi_int8_return_min (void);
+
+gint8 *test_gi_int8_return_ptr_max (void);
+gint8 *test_gi_int8_return_ptr_min (void);
+
+void test_gi_int8_in_max (gint8 int8);
+void test_gi_int8_in_min (gint8 int8);
+
+void test_gi_int8_in_ptr_max (gint8 *int8);
+void test_gi_int8_in_ptr_min (gint8 *int8);
+
+void test_gi_int8_out_max (gint8 *int8);
+void test_gi_int8_out_min (gint8 *int8);
+
+void test_gi_int8_inout_max_min (gint8 *int8);
+void test_gi_int8_inout_min_max (gint8 *int8);
+
+
+guint8 test_gi_uint8_return (void);
+guint8 *test_gi_uint8_return_ptr (void);
+
+void test_gi_uint8_in (guint8 uint8);
+void test_gi_uint8_in_ptr (guint8 *uint8);
+
+void test_gi_uint8_out (guint8 *uint8);
+void test_gi_uint8_inout (guint8 *uint8);
+
+
+gint16 test_gi_int16_return_max (void);
+gint16 test_gi_int16_return_min (void);
+
+gint16 *test_gi_int16_return_ptr_max (void);
+gint16 *test_gi_int16_return_ptr_min (void);
+
+void test_gi_int16_in_max (gint16 int16);
+void test_gi_int16_in_min (gint16 int16);
+
+void test_gi_int16_in_ptr_max (gint16 *int16);
+void test_gi_int16_in_ptr_min (gint16 *int16);
+
+void test_gi_int16_out_max (gint16 *int16);
+void test_gi_int16_out_min (gint16 *int16);
+
+void test_gi_int16_inout_max_min (gint16 *int16);
+void test_gi_int16_inout_min_max (gint16 *int16);
+
+
+guint16 test_gi_uint16_return (void);
+guint16 *test_gi_uint16_return_ptr (void);
+
+void test_gi_uint16_in (guint16 uint16);
+void test_gi_uint16_in_ptr (guint16 *uint16);
+
+void test_gi_uint16_out (guint16 *uint16);
+void test_gi_uint16_inout (guint16 *uint16);
+
+
+gint32 test_gi_int32_return_max (void);
+gint32 test_gi_int32_return_min (void);
+
+gint32 *test_gi_int32_return_ptr_max (void);
+gint32 *test_gi_int32_return_ptr_min (void);
+
+void test_gi_int32_in_max (gint32 int32);
+void test_gi_int32_in_min (gint32 int32);
+
+void test_gi_int32_in_ptr_max (gint32 *int32);
+void test_gi_int32_in_ptr_min (gint32 *int32);
+
+void test_gi_int32_out_max (gint32 *int32);
+void test_gi_int32_out_min (gint32 *int32);
+
+void test_gi_int32_inout_max_min (gint32 *int32);
+void test_gi_int32_inout_min_max (gint32 *int32);
+
+
+guint32 test_gi_uint32_return (void);
+guint32 *test_gi_uint32_return_ptr (void);
+
+void test_gi_uint32_in (guint32 uint32);
+void test_gi_uint32_in_ptr (guint32 *uint32);
+
+void test_gi_uint32_out (guint32 *uint32);
+void test_gi_uint32_inout (guint32 *uint32);
+
+
+gint64 test_gi_int64_return_max (void);
+gint64 test_gi_int64_return_min (void);
+
+gint64 *test_gi_int64_return_ptr_max (void);
+gint64 *test_gi_int64_return_ptr_min (void);
+
+void test_gi_int64_in_max (gint64 int64);
+void test_gi_int64_in_min (gint64 int64);
+
+void test_gi_int64_in_ptr_max (gint64 *int64);
+void test_gi_int64_in_ptr_min (gint64 *int64);
+
+void test_gi_int64_out_max (gint64 *int64);
+void test_gi_int64_out_min (gint64 *int64);
+
+void test_gi_int64_inout_max_min (gint64 *int64);
+void test_gi_int64_inout_min_max (gint64 *int64);
+
+
+guint64 test_gi_uint64_return (void);
+guint64 *test_gi_uint64_return_ptr (void);
+
+void test_gi_uint64_in (guint64 uint64);
+void test_gi_uint64_in_ptr (guint64 *uint64);
+
+void test_gi_uint64_out (guint64 *uint64);
+void test_gi_uint64_inout (guint64 *uint64);
+
+
+gshort test_gi_short_return_max (void);
+gshort test_gi_short_return_min (void);
+
+gshort *test_gi_short_return_ptr_max (void);
+gshort *test_gi_short_return_ptr_min (void);
+
+void test_gi_short_in_max (gshort short_);
+void test_gi_short_in_min (gshort short_);
+
+void test_gi_short_in_ptr_max (gshort *short_);
+void test_gi_short_in_ptr_min (gshort *short_);
+
+void test_gi_short_out_max (gshort *short_);
+void test_gi_short_out_min (gshort *short_);
+
+void test_gi_short_inout_max_min (gshort *short_);
+void test_gi_short_inout_min_max (gshort *short_);
+
+
+gushort test_gi_ushort_return (void);
+gushort *test_gi_ushort_return_ptr (void);
+
+void test_gi_ushort_in (gushort ushort);
+void test_gi_ushort_in_ptr (gushort *ushort);
+
+void test_gi_ushort_out (gushort *ushort);
+void test_gi_ushort_inout (gushort *ushort);
+
+
+gint test_gi_int_return_max (void);
+gint test_gi_int_return_min (void);
+
+gint *test_gi_int_return_ptr_max (void);
+gint *test_gi_int_return_ptr_min (void);
+
+void test_gi_int_in_max (gint int_);
+void test_gi_int_in_min (gint int_);
+
+void test_gi_int_in_ptr_max (gint *int_);
+void test_gi_int_in_ptr_min (gint *int_);
+
+void test_gi_int_out_max (gint *int_);
+void test_gi_int_out_min (gint *int_);
+
+void test_gi_int_inout_max_min (gint *int_);
+void test_gi_int_inout_min_max (gint *int_);
+
+
+guint test_gi_uint_return (void);
+guint *test_gi_uint_return_ptr (void);
+
+void test_gi_uint_in (guint uint);
+void test_gi_uint_in_ptr (guint *uint);
+
+void test_gi_uint_out (guint *uint);
+void test_gi_uint_inout (guint *uint);
+
+
+glong test_gi_long_return_max (void);
+glong test_gi_long_return_min (void);
+
+glong *test_gi_long_return_ptr_max (void);
+glong *test_gi_long_return_ptr_min (void);
+
+void test_gi_long_in_max (glong long_);
+void test_gi_long_in_min (glong long_);
+
+void test_gi_long_in_ptr_max (glong *long_);
+void test_gi_long_in_ptr_min (glong *long_);
+
+void test_gi_long_out_max (glong *long_);
+void test_gi_long_out_min (glong *long_);
+
+void test_gi_long_inout_max_min (glong *long_);
+void test_gi_long_inout_min_max (glong *long_);
+
+
+gulong test_gi_ulong_return (void);
+gulong *test_gi_ulong_return_ptr (void);
+
+void test_gi_ulong_in (gulong ulong);
+void test_gi_ulong_in_ptr (gulong *ulong);
+
+void test_gi_ulong_out (gulong *ulong);
+void test_gi_ulong_inout (gulong *ulong);
+
+
+gssize test_gi_ssize_return_max (void);
+gssize test_gi_ssize_return_min (void);
+
+gssize *test_gi_ssize_return_ptr_max (void);
+gssize *test_gi_ssize_return_ptr_min (void);
+
+void test_gi_ssize_in_max (gssize ssize);
+void test_gi_ssize_in_min (gssize ssize);
+
+void test_gi_ssize_in_ptr_max (gssize *ssize);
+void test_gi_ssize_in_ptr_min (gssize *ssize);
+
+void test_gi_ssize_out_max (gssize *ssize);
+void test_gi_ssize_out_min (gssize *ssize);
+
+void test_gi_ssize_inout_max_min (gssize *ssize);
+void test_gi_ssize_inout_min_max (gssize *ssize);
+
+
+gsize test_gi_size_return (void);
+gsize *test_gi_size_return_ptr (void);
+
+void test_gi_size_in (gsize size);
+void test_gi_size_in_ptr (gsize *size);
+
+void test_gi_size_out (gsize *size);
+void test_gi_size_inout (gsize *size);
+
+
+/* Floating-point */
+
+gfloat test_gi_float_return (void);
+gfloat *test_gi_float_return_ptr (void);
+
+void test_gi_float_in (gfloat float_);
+void test_gi_float_in_ptr (gfloat *float_);
+
+void test_gi_float_out (gfloat *float_);
+
+void test_gi_float_inout (gfloat *float_);
+
+
+gdouble test_gi_double_return (void);
+gdouble *test_gi_double_return_ptr (void);
+
+void test_gi_double_in (gdouble double_);
+void test_gi_double_in_ptr (gdouble *double_);
+
+void test_gi_double_out (gdouble *double_);
+
+void test_gi_double_inout (gdouble *double_);
+
+
+/* Timestamps */
+
+time_t test_gi_time_t_return (void);
+time_t *test_gi_time_t_return_ptr (void);
+
+void test_gi_time_t_in (time_t time_t_);
+void test_gi_time_t_in_ptr (time_t *time_t_);
+
+void test_gi_time_t_out (time_t *time_t_);
+
+void test_gi_time_t_inout (time_t *time_t_);
+
+
+/* GType */
+
+GType test_gi_gtype_return (void);
+GType *test_gi_gtype_return_ptr (void);
+
+void test_gi_gtype_in (GType gtype);
+void test_gi_gtype_in_ptr (GType *gtype);
+
+void test_gi_gtype_out (GType *gtype);
+
+void test_gi_gtype_inout (GType *gtype);
+
+
+/* UTF-8 */
+
+const gchar *test_gi_utf8_none_return (void);
+gchar *test_gi_utf8_full_return (void);
+
+void test_gi_utf8_none_in (const gchar *utf8);
+void test_gi_utf8_full_in (gchar *utf8);
+
+void test_gi_utf8_none_out (gchar **utf8);
+void test_gi_utf8_full_out (gchar **utf8);
+
+void test_gi_utf8_none_inout (gchar **utf8);
+void test_gi_utf8_full_inout (gchar **utf8);
+
+
+/* Arrays */
+
+/* Fixed-size */
+const gint *test_gi_array_fixed_int_return (void);
+const gshort *test_gi_array_fixed_short_return (void);
+
+void test_gi_array_fixed_int_in (const gint *ints);
+void test_gi_array_fixed_short_in (const gshort *shorts);
+
+void test_gi_array_fixed_out (gint **ints);
+
+void test_gi_array_fixed_inout (gint **ints);
+
+/* Variable-size */
+
+const gint *test_gi_array_return (gint *length);
+
+void test_gi_array_in (const gint *ints, gint length);
+
+void test_gi_array_out (gint **ints, gint *length);
+
+void test_gi_array_inout (gint **ints, gint *length);
+
+/* Zero-terminated */
+
+gchar **test_gi_array_zero_terminated_return (void);
+
+void test_gi_array_zero_terminated_in (gchar **utf8s);
+
+void test_gi_array_zero_terminated_out (gchar ***utf8s);
+
+void test_gi_array_zero_terminated_inout (gchar ***utf8s);
+
+
+/* GList */
+
+GList *test_gi_glist_int_none_return (void);
+GList *test_gi_glist_utf8_none_return (void);
+GList *test_gi_glist_utf8_container_return (void);
+GList *test_gi_glist_utf8_full_return (void);
+
+void test_gi_glist_int_none_in (GList *list);
+void test_gi_glist_utf8_none_in (GList *list);
+void test_gi_glist_utf8_container_in (GList *list);
+void test_gi_glist_utf8_full_in (GList *list);
+
+void test_gi_glist_utf8_none_out (GList **list);
+void test_gi_glist_utf8_container_out (GList **list);
+void test_gi_glist_utf8_full_out (GList **list);
+
+void test_gi_glist_utf8_none_inout (GList **list);
+void test_gi_glist_utf8_container_inout (GList **list);
+void test_gi_glist_utf8_full_inout (GList **list);
+
+
+/* GSList */
+
+GSList *test_gi_gslist_int_none_return (void);
+GSList *test_gi_gslist_utf8_none_return (void);
+GSList *test_gi_gslist_utf8_container_return (void);
+GSList *test_gi_gslist_utf8_full_return (void);
+
+void test_gi_gslist_int_none_in (GSList *list);
+void test_gi_gslist_utf8_none_in (GSList *list);
+void test_gi_gslist_utf8_container_in (GSList *list);
+void test_gi_gslist_utf8_full_in (GSList *list);
+
+void test_gi_gslist_utf8_none_out (GSList **list);
+void test_gi_gslist_utf8_container_out (GSList **list);
+void test_gi_gslist_utf8_full_out (GSList **list);
+
+void test_gi_gslist_utf8_none_inout (GSList **list);
+void test_gi_gslist_utf8_container_inout (GSList **list);
+void test_gi_gslist_utf8_full_inout (GSList **list);
+
+
+/* GHashTable */
+
+GHashTable *test_gi_ghashtable_int_none_return (void);
+GHashTable *test_gi_ghashtable_utf8_none_return (void);
+GHashTable *test_gi_ghashtable_utf8_container_return (void);
+GHashTable *test_gi_ghashtable_utf8_full_return (void);
+
+void test_gi_ghashtable_int_none_in (GHashTable *hash_table);
+void test_gi_ghashtable_utf8_none_in (GHashTable *hash_table);
+void test_gi_ghashtable_utf8_container_in (GHashTable *hash_table);
+void test_gi_ghashtable_utf8_full_in (GHashTable *hash_table);
+
+void test_gi_ghashtable_utf8_none_out (GHashTable **hash_table);
+void test_gi_ghashtable_utf8_container_out (GHashTable **hash_table);
+void test_gi_ghashtable_utf8_full_out (GHashTable **hash_table);
+
+void test_gi_ghashtable_utf8_none_inout (GHashTable **hash_table);
+void test_gi_ghashtable_utf8_container_inout (GHashTable **hash_table);
+void test_gi_ghashtable_utf8_full_inout (GHashTable **hash_table);
+
+
+/* GValue */
+
+GValue *test_gi_gvalue_return (void);
+
+void test_gi_gvalue_in (GValue *value);
+
+void test_gi_gvalue_out (GValue **value);
+
+void test_gi_gvalue_inout (GValue **value);
+
+
+/* GClosure */
+
+void test_gi_gclosure_in (GClosure *closure);
+
+
+/* GEnum */
+
+typedef enum
+{
+ TESTGI_ENUM_VALUE1,
+ TESTGI_ENUM_VALUE2,
+ TESTGI_ENUM_VALUE3 = 42
+} TestGIEnum;
+
+GType test_gi_enum_get_type (void) G_GNUC_CONST;
+#define TESTGI_TYPE_ENUM (test_gi_enum_get_type ())
+
+TestGIEnum test_gi_enum_return (void);
+
+void test_gi_enum_in (TestGIEnum enum_);
+void test_gi_enum_in_ptr (TestGIEnum *enum_);
+
+void test_gi_enum_out (TestGIEnum *enum_);
+
+void test_gi_enum_inout (TestGIEnum *enum_);
+
+
+/* GFlags */
+
+typedef enum
+{
+ TESTGI_FLAGS_VALUE1 = 1 << 0,
+ TESTGI_FLAGS_VALUE2 = 1 << 1,
+ TESTGI_FLAGS_VALUE3 = 1 << 2
+} TestGIFlags;
+
+GType test_gi_flags_get_type (void) G_GNUC_CONST;
+#define TESTGI_TYPE_FLAGS (test_gi_flags_get_type ())
+
+TestGIFlags test_gi_flags_return (void);
+
+void test_gi_flags_in (TestGIFlags flags_);
+void test_gi_flags_in_ptr (TestGIFlags *flags_);
+
+void test_gi_flags_out (TestGIFlags *flags_);
+
+void test_gi_flags_inout (TestGIFlags *flags_);
+
+
+/* Structure */
+
+typedef struct {
+ glong long_;
+ gint8 int8;
+} TestGISimpleStruct;
+
+typedef struct {
+ TestGISimpleStruct simple_struct;
+} TestGINestedStruct;
+
+typedef struct {
+ gpointer pointer;
+} TestGINotSimpleStruct;
+
+
+TestGISimpleStruct *test_gi__simple_struct_return (void);
+
+void test_gi__simple_struct_in (TestGISimpleStruct *struct_);
+
+void test_gi__simple_struct_out (TestGISimpleStruct **struct_);
+
+void test_gi__simple_struct_inout (TestGISimpleStruct **struct_);
+
+void test_gi_simple_struct_method (TestGISimpleStruct *struct_);
+
+
+typedef struct {
+ glong long_;
+} TestGIPointerStruct;
+
+GType test_gi_pointer_struct_get_type (void) G_GNUC_CONST;
+
+TestGIPointerStruct *test_gi__pointer_struct_return (void);
+
+void test_gi__pointer_struct_in (TestGIPointerStruct *struct_);
+
+void test_gi__pointer_struct_out (TestGIPointerStruct **struct_);
+
+void test_gi__pointer_struct_inout (TestGIPointerStruct **struct_);
+
+
+typedef struct {
+ glong long_;
+} TestGIBoxedStruct;
+
+GType test_gi_boxed_struct_get_type (void) G_GNUC_CONST;
+
+
+typedef struct {
+ glong long_;
+} TestGIBoxedInstantiableStruct;
+
+GType test_gi_boxed_instantiable_struct_get_type (void) G_GNUC_CONST;
+
+TestGIBoxedInstantiableStruct *test_gi_boxed_instantiable_struct_new (void);
+
+TestGIBoxedInstantiableStruct *test_gi__boxed_instantiable_struct_return (void);
+
+void test_gi__boxed_instantiable_struct_in (TestGIBoxedInstantiableStruct *struct_);
+
+void test_gi__boxed_instantiable_struct_out (TestGIBoxedInstantiableStruct **struct_);
+
+void test_gi__boxed_instantiable_struct_inout (TestGIBoxedInstantiableStruct **struct_);
+
+
+/* Object */
+
+#define TESTGI_TYPE_OBJECT (test_gi_object_get_type ())
+#define TESTGI_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TESTGI_TYPE_OBJECT, TestGIObject))
+#define TESTGI_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TESTGI_TYPE_OBJECT, TestGIObjectClass))
+#define TESTGI_IS_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TESTGI_TYPE_OBJECT))
+#define TESTGI_IS_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TESTGI_TYPE_OBJECT))
+#define TESTGI_OBJECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TESTGI_TYPE_OBJECT, TestGIObjectClass))
+
+typedef struct _TestGIObjectClass TestGIObjectClass;
+typedef struct _TestGIObject TestGIObject;
+
+struct _TestGIObjectClass
+{
+ GObjectClass parent_class;
+};
+
+struct _TestGIObject
+{
+ GObject parent_instance;
+
+ gint int_;
+};
+
+GType test_gi_object_get_type (void) G_GNUC_CONST;
+void test_gi_object_static_method (void);
+void test_gi_object_method (TestGIObject *object);
+void test_gi_object_overridden_method (TestGIObject *object);
+TestGIObject *test_gi_object_new (gint int_);
+
+
+TestGIObject *test_gi__object_none_return (void);
+TestGIObject *test_gi__object_full_return (void);
+
+void test_gi__object_none_in (TestGIObject *object);
+void test_gi__object_full_in (TestGIObject *object);
+
+void test_gi__object_none_out (TestGIObject **object);
+void test_gi__object_full_out (TestGIObject **object);
+
+void test_gi__object_none_inout (TestGIObject **object);
+void test_gi__object_full_inout (TestGIObject **object);
+void test_gi__object_inout_same (TestGIObject **object);
+
+
+#define TESTGI_TYPE_SUB_OBJECT (test_gi_sub_object_get_type ())
+#define TESTGI_SUB_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TESTGI_TYPE_SUB_OBJECT, TestGISubObject))
+#define TESTGI_SUB_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TESTGI_TYPE_SUB_OBJECT, TestGISubObjectClass))
+#define TESTGI_IS_SUB_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TESTGI_TYPE_SUB_OBJECT))
+#define TESTGI_IS_SUB_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TESTGI_TYPE_SUB_OBJECT))
+#define TESTGI_SUB_OBJECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TESTGI_TYPE_SUB_OBJECT, TestGISubObjectClass))
+
+typedef struct _TestGISubObjectClass TestGISubObjectClass;
+typedef struct _TestGISubObject TestGISubObject;
+
+struct _TestGISubObjectClass
+{
+ TestGIObjectClass parent_class;
+};
+
+struct _TestGISubObject
+{
+ TestGIObject parent_instance;
+};
+
+GType test_gi_sub_object_get_type (void) G_GNUC_CONST;
+
+void test_gi_sub_object_sub_method (TestGISubObject *object);
+void test_gi_sub_object_overwritten_method (TestGISubObject *object);
+
+
+/* Multiple output arguments */
+
+void test_gi_int_out_out (gint *int0, gint *int1);
+gint test_gi_int_return_out (gint *int_);
+
+
+/* Nullable arguments */
+
+gint *test_gi_int_return_ptr_null (void);
+void test_gi_int_in_ptr_null (gint *int_);
+
+
+#endif /* __TEST_GI_H__ */
diff --git a/tests/runtests.py b/tests/runtests.py
new file mode 100644
index 0000000..7ba5c42
--- /dev/null
+++ b/tests/runtests.py
@@ -0,0 +1,22 @@
+#!/usr/bin/env python
+
+import sys
+import unittest
+import glob
+
+sys.path.insert(0, "../")
+
+loader = unittest.TestLoader()
+
+if len(sys.argv) > 1:
+ names = sys.argv[1:]
+ suite = loader.loadTestsFromNames(names)
+else:
+ names = []
+ for filename in glob.iglob("test_*.py"):
+ names.append(filename[:-3])
+ suite = loader.loadTestsFromNames(names)
+
+runner = unittest.TextTestRunner(verbosity=2)
+runner.run(suite)
+
diff --git a/tests/test_gi.py b/tests/test_gi.py
new file mode 100644
index 0000000..7c29615
--- /dev/null
+++ b/tests/test_gi.py
@@ -0,0 +1,1416 @@
+# -*- Mode: Python; py-indent-offset: 4 -*-
+# vim: tabstop=4 shiftwidth=4 expandtab
+
+import unittest
+import gobject
+
+from datetime import datetime
+
+from gi.repository import TestGI
+
+
+CONSTANT_UTF8 = "const \xe2\x99\xa5 utf8"
+CONSTANT_NUMBER = 42
+
+
+class Number(object):
+
+ def __init__(self, value):
+ self.value = value
+
+ def __int__(self):
+ return int(self.value)
+
+ def __float__(self):
+ return float(self.value)
+
+
+class Sequence(object):
+
+ def __init__(self, sequence):
+ self.sequence = sequence
+
+ def __len__(self):
+ return len(self.sequence)
+
+ def __getitem__(self, key):
+ return self.sequence[key]
+
+
+class TestConstant(unittest.TestCase):
+
+# Blocked by https://bugzilla.gnome.org/show_bug.cgi?id=595773
+# def test_constant_utf8(self):
+# self.assertEquals(CONSTANT_UTF8, TestGI.CONSTANT_UTF8)
+
+ def test_constant_number(self):
+ self.assertEquals(CONSTANT_NUMBER, TestGI.CONSTANT_NUMBER)
+
+
+class TestBoolean(unittest.TestCase):
+
+ def test_boolean_return(self):
+ self.assertEquals(True, TestGI.boolean_return_true())
+ self.assertEquals(False, TestGI.boolean_return_false())
+
+ def test_boolean_return_ptr(self):
+ self.assertEquals(True, TestGI.boolean_return_ptr_true())
+ self.assertEquals(False, TestGI.boolean_return_ptr_false())
+
+ def test_boolean_in(self):
+ TestGI.boolean_in_true(True)
+ TestGI.boolean_in_false(False)
+
+ TestGI.boolean_in_true(1)
+ TestGI.boolean_in_false(0)
+
+ def test_boolean_in_ptr(self):
+ TestGI.boolean_in_ptr_true(True)
+ TestGI.boolean_in_ptr_false(False)
+ TestGI.boolean_in_ptr_false(None)
+
+ def test_boolean_out(self):
+ self.assertEquals(True, TestGI.boolean_out_true())
+ self.assertEquals(False, TestGI.boolean_out_false())
+
+ def test_boolean_inout(self):
+ self.assertEquals(False, TestGI.boolean_inout_true_false(True))
+ self.assertEquals(True, TestGI.boolean_inout_false_true(False))
+
+
+class TestInt8(unittest.TestCase):
+
+ MAX = 2 ** 7 - 1
+ MIN = - (2 ** 7)
+
+ def test_int8_return(self):
+ self.assertEquals(self.MAX, TestGI.int8_return_max())
+ self.assertEquals(self.MIN, TestGI.int8_return_min())
+
+ def test_int8_return_ptr(self):
+ self.assertEquals(self.MAX, TestGI.int8_return_ptr_max())
+ self.assertEquals(self.MIN, TestGI.int8_return_ptr_min())
+
+ def test_int8_in(self):
+ max = Number(self.MAX)
+ min = Number(self.MIN)
+
+ TestGI.int8_in_max(max)
+ TestGI.int8_in_min(min)
+
+ max.value += 1
+ min.value -= 1
+
+ self.assertRaises(ValueError, TestGI.int8_in_max, max)
+ self.assertRaises(ValueError, TestGI.int8_in_min, min)
+
+ self.assertRaises(TypeError, TestGI.int8_in_max, "self.MAX")
+
+ def test_int8_in_ptr(self):
+ TestGI.int8_in_ptr_max(Number(self.MAX))
+ TestGI.int8_in_ptr_min(Number(self.MIN))
+ self.assertRaises(TypeError, TestGI.int8_in_ptr_max, None)
+
+ def test_int8_out(self):
+ self.assertEquals(self.MAX, TestGI.int8_out_max())
+ self.assertEquals(self.MIN, TestGI.int8_out_min())
+
+ def test_int8_inout(self):
+ self.assertEquals(self.MIN, TestGI.int8_inout_max_min(Number(self.MAX)))
+ self.assertEquals(self.MAX, TestGI.int8_inout_min_max(Number(self.MIN)))
+
+
+class TestUInt8(unittest.TestCase):
+
+ MAX = 2 ** 8 - 1
+
+ def test_uint8_return(self):
+ self.assertEquals(self.MAX, TestGI.uint8_return())
+
+# Blocked by https://bugzilla.gnome.org/show_bug.cgi?id=596420
+# def test_uint8_return_ptr(self):
+# self.assertEquals(self.MAX, TestGI.uint8_return_ptr())
+
+ def test_uint8_in(self):
+ number = Number(self.MAX)
+
+ TestGI.uint8_in(number)
+
+ number.value += 1
+
+ self.assertRaises(ValueError, TestGI.uint8_in, number)
+ self.assertRaises(ValueError, TestGI.uint8_in, Number(-1))
+
+ self.assertRaises(TypeError, TestGI.uint8_in, "self.MAX")
+
+ def test_uint8_out(self):
+ self.assertEquals(self.MAX, TestGI.uint8_out())
+
+ def test_uint8_inout(self):
+ self.assertEquals(0, TestGI.uint8_inout(Number(self.MAX)))
+
+
+class TestInt16(unittest.TestCase):
+
+ MAX = 2 ** 15 - 1
+ MIN = - (2 ** 15)
+
+ def test_int16_return(self):
+ self.assertEquals(self.MAX, TestGI.int16_return_max())
+ self.assertEquals(self.MIN, TestGI.int16_return_min())
+
+ def test_int16_return_ptr(self):
+ self.assertEquals(self.MAX, TestGI.int16_return_ptr_max())
+ self.assertEquals(self.MIN, TestGI.int16_return_ptr_min())
+
+ def test_int16_in(self):
+ max = Number(self.MAX)
+ min = Number(self.MIN)
+
+ TestGI.int16_in_max(max)
+ TestGI.int16_in_min(min)
+
+ max.value += 1
+ min.value -= 1
+
+ self.assertRaises(ValueError, TestGI.int16_in_max, max)
+ self.assertRaises(ValueError, TestGI.int16_in_min, min)
+
+ self.assertRaises(TypeError, TestGI.int16_in_max, "self.MAX")
+
+ def test_int16_in_ptr(self):
+ TestGI.int16_in_ptr_max(Number(self.MAX))
+ TestGI.int16_in_ptr_min(Number(self.MIN))
+ self.assertRaises(TypeError, TestGI.int16_in_ptr_max, None)
+
+ def test_int16_out(self):
+ self.assertEquals(self.MAX, TestGI.int16_out_max())
+ self.assertEquals(self.MIN, TestGI.int16_out_min())
+
+ def test_int16_inout(self):
+ self.assertEquals(self.MIN, TestGI.int16_inout_max_min(Number(self.MAX)))
+ self.assertEquals(self.MAX, TestGI.int16_inout_min_max(Number(self.MIN)))
+
+
+class TestUInt16(unittest.TestCase):
+
+ MAX = 2 ** 16 - 1
+
+ def test_uint16_return(self):
+ self.assertEquals(self.MAX, TestGI.uint16_return())
+
+ def test_uint16_return_ptr(self):
+ self.assertEquals(self.MAX, TestGI.uint16_return_ptr())
+
+ def test_uint16_in(self):
+ number = Number(self.MAX)
+
+ TestGI.uint16_in(number)
+
+ number.value += 1
+
+ self.assertRaises(ValueError, TestGI.uint16_in, number)
+ self.assertRaises(ValueError, TestGI.uint16_in, Number(-1))
+
+ self.assertRaises(TypeError, TestGI.uint16_in, "self.MAX")
+
+ def test_uint16_out(self):
+ self.assertEquals(self.MAX, TestGI.uint16_out())
+
+ def test_uint16_inout(self):
+ self.assertEquals(0, TestGI.uint16_inout(Number(self.MAX)))
+
+
+class TestInt32(unittest.TestCase):
+
+ MAX = 2 ** 31 - 1
+ MIN = - (2 ** 31)
+
+ def test_int32_return(self):
+ self.assertEquals(self.MAX, TestGI.int32_return_max())
+ self.assertEquals(self.MIN, TestGI.int32_return_min())
+
+ def test_int32_return_ptr(self):
+ self.assertEquals(self.MAX, TestGI.int32_return_ptr_max())
+ self.assertEquals(self.MIN, TestGI.int32_return_ptr_min())
+
+ def test_int32_in(self):
+ max = Number(self.MAX)
+ min = Number(self.MIN)
+
+ TestGI.int32_in_max(max)
+ TestGI.int32_in_min(min)
+
+ max.value += 1
+ min.value -= 1
+
+ self.assertRaises(ValueError, TestGI.int32_in_max, max)
+ self.assertRaises(ValueError, TestGI.int32_in_min, min)
+
+ self.assertRaises(TypeError, TestGI.int32_in_max, "self.MAX")
+
+ def test_int32_in_ptr(self):
+ TestGI.int32_in_ptr_max(Number(self.MAX))
+ TestGI.int32_in_ptr_min(Number(self.MIN))
+ self.assertRaises(TypeError, TestGI.int32_in_ptr_max, None)
+
+ def test_int32_out(self):
+ self.assertEquals(self.MAX, TestGI.int32_out_max())
+ self.assertEquals(self.MIN, TestGI.int32_out_min())
+
+ def test_int32_inout(self):
+ self.assertEquals(self.MIN, TestGI.int32_inout_max_min(Number(self.MAX)))
+ self.assertEquals(self.MAX, TestGI.int32_inout_min_max(Number(self.MIN)))
+
+
+class TestUInt32(unittest.TestCase):
+
+ MAX = 2 ** 32 - 1
+
+ def test_uint32_return(self):
+ self.assertEquals(self.MAX, TestGI.uint32_return())
+
+ def test_uint32_return_ptr(self):
+ self.assertEquals(self.MAX, TestGI.uint32_return_ptr())
+
+ def test_uint32_in(self):
+ number = Number(self.MAX)
+
+ TestGI.uint32_in(number)
+
+ number.value += 1
+
+ self.assertRaises(ValueError, TestGI.uint32_in, number)
+ self.assertRaises(ValueError, TestGI.uint32_in, Number(-1))
+
+ self.assertRaises(TypeError, TestGI.uint32_in, "self.MAX")
+
+ def test_uint32_out(self):
+ self.assertEquals(self.MAX, TestGI.uint32_out())
+
+ def test_uint32_inout(self):
+ self.assertEquals(0, TestGI.uint32_inout(Number(self.MAX)))
+
+
+class TestInt64(unittest.TestCase):
+
+ MAX = 2 ** 63 - 1
+ MIN = - (2 ** 63)
+
+ def test_int64_return(self):
+ self.assertEquals(self.MAX, TestGI.int64_return_max())
+ self.assertEquals(self.MIN, TestGI.int64_return_min())
+
+ def test_int64_return_ptr(self):
+ self.assertEquals(self.MAX, TestGI.int64_return_ptr_max())
+ self.assertEquals(self.MIN, TestGI.int64_return_ptr_min())
+
+ def test_int64_in(self):
+ max = Number(self.MAX)
+ min = Number(self.MIN)
+
+ TestGI.int64_in_max(max)
+ TestGI.int64_in_min(min)
+
+ max.value += 1
+ min.value -= 1
+
+ self.assertRaises(ValueError, TestGI.int64_in_max, max)
+ self.assertRaises(ValueError, TestGI.int64_in_min, min)
+
+ self.assertRaises(TypeError, TestGI.int64_in_max, "self.MAX")
+
+ def test_int64_in_ptr(self):
+ TestGI.int64_in_ptr_max(Number(self.MAX))
+ TestGI.int64_in_ptr_min(Number(self.MIN))
+ self.assertRaises(TypeError, TestGI.int64_in_ptr_max, None)
+
+ def test_int64_out(self):
+ self.assertEquals(self.MAX, TestGI.int64_out_max())
+ self.assertEquals(self.MIN, TestGI.int64_out_min())
+
+ def test_int64_inout(self):
+ self.assertEquals(self.MIN, TestGI.int64_inout_max_min(Number(self.MAX)))
+ self.assertEquals(self.MAX, TestGI.int64_inout_min_max(Number(self.MIN)))
+
+
+class TestUInt64(unittest.TestCase):
+
+ MAX = 2 ** 64 - 1
+
+ def test_uint64_return(self):
+ self.assertEquals(self.MAX, TestGI.uint64_return())
+
+ def test_uint64_return_ptr(self):
+ self.assertEquals(self.MAX, TestGI.uint64_return_ptr())
+
+ def test_uint64_in(self):
+ number = Number(self.MAX)
+
+ TestGI.uint64_in(number)
+
+ number.value += 1
+
+ self.assertRaises(ValueError, TestGI.uint64_in, number)
+ self.assertRaises(ValueError, TestGI.uint64_in, Number(-1))
+
+ self.assertRaises(TypeError, TestGI.uint64_in, "self.MAX")
+
+ def test_uint64_out(self):
+ self.assertEquals(self.MAX, TestGI.uint64_out())
+
+ def test_uint64_inout(self):
+ self.assertEquals(0, TestGI.uint64_inout(Number(self.MAX)))
+
+
+class TestShort(unittest.TestCase):
+
+ MAX = gobject.constants.G_MAXSHORT
+ MIN = gobject.constants.G_MINSHORT
+
+ def test_short_return(self):
+ self.assertEquals(self.MAX, TestGI.short_return_max())
+ self.assertEquals(self.MIN, TestGI.short_return_min())
+
+ def test_short_return_ptr(self):
+ self.assertEquals(self.MAX, TestGI.short_return_ptr_max())
+ self.assertEquals(self.MIN, TestGI.short_return_ptr_min())
+
+ def test_short_in(self):
+ max = Number(self.MAX)
+ min = Number(self.MIN)
+
+ TestGI.short_in_max(max)
+ TestGI.short_in_min(min)
+
+ max.value += 1
+ min.value -= 1
+
+ self.assertRaises(ValueError, TestGI.short_in_max, max)
+ self.assertRaises(ValueError, TestGI.short_in_min, min)
+
+ self.assertRaises(TypeError, TestGI.short_in_max, "self.MAX")
+
+ def test_short_in_ptr(self):
+ TestGI.short_in_ptr_max(Number(self.MAX))
+ TestGI.short_in_ptr_min(Number(self.MIN))
+ self.assertRaises(TypeError, TestGI.short_in_ptr_max, None)
+
+ def test_short_out(self):
+ self.assertEquals(self.MAX, TestGI.short_out_max())
+ self.assertEquals(self.MIN, TestGI.short_out_min())
+
+ def test_short_inout(self):
+ self.assertEquals(self.MIN, TestGI.short_inout_max_min(Number(self.MAX)))
+ self.assertEquals(self.MAX, TestGI.short_inout_min_max(Number(self.MIN)))
+
+
+class TestUShort(unittest.TestCase):
+
+ MAX = gobject.constants.G_MAXUSHORT
+
+ def test_ushort_return(self):
+ self.assertEquals(self.MAX, TestGI.ushort_return())
+
+ def test_ushort_return_ptr(self):
+ self.assertEquals(self.MAX, TestGI.ushort_return_ptr())
+
+ def test_ushort_in(self):
+ number = Number(self.MAX)
+
+ TestGI.ushort_in(number)
+
+ number.value += 1
+
+ self.assertRaises(ValueError, TestGI.ushort_in, number)
+ self.assertRaises(ValueError, TestGI.ushort_in, Number(-1))
+
+ self.assertRaises(TypeError, TestGI.ushort_in, "self.MAX")
+
+ def test_ushort_out(self):
+ self.assertEquals(self.MAX, TestGI.ushort_out())
+
+ def test_ushort_inout(self):
+ self.assertEquals(0, TestGI.ushort_inout(Number(self.MAX)))
+
+
+class TestInt(unittest.TestCase):
+
+ MAX = gobject.constants.G_MAXINT
+ MIN = gobject.constants.G_MININT
+
+ def test_int_return(self):
+ self.assertEquals(self.MAX, TestGI.int_return_max())
+ self.assertEquals(self.MIN, TestGI.int_return_min())
+
+ def test_int_return_ptr(self):
+ self.assertEquals(self.MAX, TestGI.int_return_ptr_max())
+ self.assertEquals(self.MIN, TestGI.int_return_ptr_min())
+
+ def test_int_in(self):
+ max = Number(self.MAX)
+ min = Number(self.MIN)
+
+ TestGI.int_in_max(max)
+ TestGI.int_in_min(min)
+
+ max.value += 1
+ min.value -= 1
+
+ self.assertRaises(ValueError, TestGI.int_in_max, max)
+ self.assertRaises(ValueError, TestGI.int_in_min, min)
+
+ self.assertRaises(TypeError, TestGI.int_in_max, "self.MAX")
+
+ def test_int_in_ptr(self):
+ TestGI.int_in_ptr_max(Number(self.MAX))
+ TestGI.int_in_ptr_min(Number(self.MIN))
+ self.assertRaises(TypeError, TestGI.int_in_ptr_max, None)
+
+ def test_int_out(self):
+ self.assertEquals(self.MAX, TestGI.int_out_max())
+ self.assertEquals(self.MIN, TestGI.int_out_min())
+
+ def test_int_inout(self):
+ self.assertEquals(self.MIN, TestGI.int_inout_max_min(Number(self.MAX)))
+ self.assertEquals(self.MAX, TestGI.int_inout_min_max(Number(self.MIN)))
+
+
+class TestUInt(unittest.TestCase):
+
+ MAX = gobject.constants.G_MAXUINT
+
+ def test_uint_return(self):
+ self.assertEquals(self.MAX, TestGI.uint_return())
+
+ def test_uint_return_ptr(self):
+ self.assertEquals(self.MAX, TestGI.uint_return_ptr())
+
+ def test_uint_in(self):
+ number = Number(self.MAX)
+
+ TestGI.uint_in(number)
+
+ number.value += 1
+
+ self.assertRaises(ValueError, TestGI.uint_in, number)
+ self.assertRaises(ValueError, TestGI.uint_in, Number(-1))
+
+ self.assertRaises(TypeError, TestGI.uint_in, "self.MAX")
+
+ def test_uint_out(self):
+ self.assertEquals(self.MAX, TestGI.uint_out())
+
+ def test_uint_inout(self):
+ self.assertEquals(0, TestGI.uint_inout(Number(self.MAX)))
+
+
+class TestLong(unittest.TestCase):
+
+ MAX = gobject.constants.G_MAXLONG
+ MIN = gobject.constants.G_MINLONG
+
+ def test_long_return(self):
+ self.assertEquals(self.MAX, TestGI.long_return_max())
+ self.assertEquals(self.MIN, TestGI.long_return_min())
+
+ def test_long_return_ptr(self):
+ self.assertEquals(self.MAX, TestGI.long_return_ptr_max())
+ self.assertEquals(self.MIN, TestGI.long_return_ptr_min())
+
+ def test_long_in(self):
+ max = Number(self.MAX)
+ min = Number(self.MIN)
+
+ TestGI.long_in_max(max)
+ TestGI.long_in_min(min)
+
+ max.value += 1
+ min.value -= 1
+
+ self.assertRaises(ValueError, TestGI.long_in_max, max)
+ self.assertRaises(ValueError, TestGI.long_in_min, min)
+
+ self.assertRaises(TypeError, TestGI.long_in_max, "self.MAX")
+
+ def test_long_in_ptr(self):
+ TestGI.long_in_ptr_max(Number(self.MAX))
+ TestGI.long_in_ptr_min(Number(self.MIN))
+ self.assertRaises(TypeError, TestGI.long_in_ptr_max, None)
+
+ def test_long_out(self):
+ self.assertEquals(self.MAX, TestGI.long_out_max())
+ self.assertEquals(self.MIN, TestGI.long_out_min())
+
+ def test_long_inout(self):
+ self.assertEquals(self.MIN, TestGI.long_inout_max_min(Number(self.MAX)))
+ self.assertEquals(self.MAX, TestGI.long_inout_min_max(Number(self.MIN)))
+
+
+class TestULong(unittest.TestCase):
+
+ MAX = gobject.constants.G_MAXULONG
+
+ def test_ulong_return(self):
+ self.assertEquals(self.MAX, TestGI.ulong_return())
+
+ def test_ulong_return_ptr(self):
+ self.assertEquals(self.MAX, TestGI.ulong_return_ptr())
+
+ def test_ulong_in(self):
+ number = Number(self.MAX)
+
+ TestGI.ulong_in(number)
+
+ number.value += 1
+
+ self.assertRaises(ValueError, TestGI.ulong_in, number)
+ self.assertRaises(ValueError, TestGI.ulong_in, Number(-1))
+
+ self.assertRaises(TypeError, TestGI.ulong_in, "self.MAX")
+
+ def test_ulong_out(self):
+ self.assertEquals(self.MAX, TestGI.ulong_out())
+
+ def test_ulong_inout(self):
+ self.assertEquals(0, TestGI.ulong_inout(Number(self.MAX)))
+
+
+class TestSSize(unittest.TestCase):
+
+ MAX = gobject.constants.G_MAXLONG
+ MIN = gobject.constants.G_MINLONG
+
+ def test_ssize_return(self):
+ self.assertEquals(self.MAX, TestGI.ssize_return_max())
+ self.assertEquals(self.MIN, TestGI.ssize_return_min())
+
+ def test_ssize_return_ptr(self):
+ self.assertEquals(self.MAX, TestGI.ssize_return_ptr_max())
+ self.assertEquals(self.MIN, TestGI.ssize_return_ptr_min())
+
+ def test_ssize_in(self):
+ max = Number(self.MAX)
+ min = Number(self.MIN)
+
+ TestGI.ssize_in_max(max)
+ TestGI.ssize_in_min(min)
+
+ max.value += 1
+ min.value -= 1
+
+ self.assertRaises(ValueError, TestGI.ssize_in_max, max)
+ self.assertRaises(ValueError, TestGI.ssize_in_min, min)
+
+ self.assertRaises(TypeError, TestGI.ssize_in_max, "self.MAX")
+
+ def test_ssize_in_ptr(self):
+ TestGI.ssize_in_ptr_max(Number(self.MAX))
+ TestGI.ssize_in_ptr_min(Number(self.MIN))
+ self.assertRaises(TypeError, TestGI.ssize_in_ptr_max, None)
+
+ def test_ssize_out(self):
+ self.assertEquals(self.MAX, TestGI.ssize_out_max())
+ self.assertEquals(self.MIN, TestGI.ssize_out_min())
+
+ def test_ssize_inout(self):
+ self.assertEquals(self.MIN, TestGI.ssize_inout_max_min(Number(self.MAX)))
+ self.assertEquals(self.MAX, TestGI.ssize_inout_min_max(Number(self.MIN)))
+
+
+class TestSize(unittest.TestCase):
+
+ MAX = gobject.constants.G_MAXULONG
+
+ def test_size_return(self):
+ self.assertEquals(self.MAX, TestGI.size_return())
+
+ def test_size_return_ptr(self):
+ self.assertEquals(self.MAX, TestGI.size_return_ptr())
+
+ def test_size_in(self):
+ number = Number(self.MAX)
+
+ TestGI.size_in(number)
+
+ number.value += 1
+
+ self.assertRaises(ValueError, TestGI.size_in, number)
+ self.assertRaises(ValueError, TestGI.size_in, Number(-1))
+
+ self.assertRaises(TypeError, TestGI.size_in, "self.MAX")
+
+ def test_size_out(self):
+ self.assertEquals(self.MAX, TestGI.size_out())
+
+ def test_size_inout(self):
+ self.assertEquals(0, TestGI.size_inout(Number(self.MAX)))
+
+
+class TestFloat(unittest.TestCase):
+
+ MAX = gobject.constants.G_MAXFLOAT
+ MIN = gobject.constants.G_MINFLOAT
+
+ def test_float_return(self):
+ self.assertAlmostEquals(self.MAX, TestGI.float_return())
+
+ def test_float_return_ptr(self):
+ self.assertAlmostEquals(self.MAX, TestGI.float_return_ptr())
+
+ def test_float_in(self):
+ TestGI.float_in(Number(self.MAX))
+
+ self.assertRaises(TypeError, TestGI.float_in, "self.MAX")
+
+ def test_float_in_ptr(self):
+ TestGI.float_in_ptr(Number(self.MAX))
+ self.assertRaises(TypeError, TestGI.float_in_ptr, None)
+
+ def test_float_out(self):
+ self.assertAlmostEquals(self.MAX, TestGI.float_out())
+
+ def test_float_inout(self):
+ self.assertAlmostEquals(self.MIN, TestGI.float_inout(Number(self.MAX)))
+
+
+class TestDouble(unittest.TestCase):
+
+ MAX = gobject.constants.G_MAXDOUBLE
+ MIN = gobject.constants.G_MINDOUBLE
+
+ def test_double_return(self):
+ self.assertAlmostEquals(self.MAX, TestGI.double_return())
+
+ def test_double_return_ptr(self):
+ self.assertAlmostEquals(self.MAX, TestGI.double_return_ptr())
+
+ def test_double_in(self):
+ TestGI.double_in(Number(self.MAX))
+
+ self.assertRaises(TypeError, TestGI.double_in, "self.MAX")
+
+ def test_double_in_ptr(self):
+ TestGI.double_in_ptr(Number(self.MAX))
+ self.assertRaises(TypeError, TestGI.double_in_ptr, None)
+
+ def test_double_out(self):
+ self.assertAlmostEquals(self.MAX, TestGI.double_out())
+
+ def test_double_inout(self):
+ self.assertAlmostEquals(self.MIN, TestGI.double_inout(Number(self.MAX)))
+
+
+class TestTimeT(unittest.TestCase):
+
+ DATETIME = datetime.fromtimestamp(1234567890)
+
+ def test_time_t_return(self):
+ self.assertEquals(self.DATETIME, TestGI.time_t_return())
+
+ def test_time_t_return_ptr(self):
+ self.assertEquals(self.DATETIME, TestGI.time_t_return_ptr())
+
+ def test_time_t_in(self):
+ TestGI.time_t_in(self.DATETIME)
+
+ self.assertRaises(TypeError, TestGI.time_t_in, "self.DATETIME")
+
+ def test_time_t_in_ptr(self):
+ TestGI.time_t_in_ptr(self.DATETIME)
+ self.assertRaises(TypeError, TestGI.time_t_in_ptr, None)
+
+ def test_time_t_out(self):
+ self.assertEquals(self.DATETIME, TestGI.time_t_out())
+
+ def test_time_t_inout(self):
+ self.assertEquals(datetime.fromtimestamp(0), TestGI.time_t_inout(self.DATETIME))
+
+
+class TestGType(unittest.TestCase):
+
+ def test_gtype_return(self):
+ self.assertEquals(gobject.TYPE_NONE, TestGI.gtype_return())
+
+ def test_gtype_return_ptr(self):
+ self.assertEquals(gobject.TYPE_NONE, TestGI.gtype_return_ptr())
+
+ def test_gtype_in(self):
+ TestGI.gtype_in(gobject.TYPE_NONE)
+
+ self.assertRaises(TypeError, TestGI.gtype_in, "gobject.TYPE_NONE")
+
+ def test_gtype_in_ptr(self):
+ TestGI.gtype_in_ptr(gobject.TYPE_NONE)
+ self.assertRaises(TypeError, TestGI.gtype_in_ptr, None)
+
+ def test_gtype_out(self):
+ self.assertEquals(gobject.TYPE_NONE, TestGI.gtype_out())
+
+ def test_gtype_inout(self):
+ self.assertEquals(gobject.TYPE_INT, TestGI.gtype_inout(gobject.TYPE_NONE))
+
+
+class TestUtf8(unittest.TestCase):
+
+ def test_utf8_none_return(self):
+ self.assertEquals(CONSTANT_UTF8, TestGI.utf8_none_return())
+
+ def test_utf8_full_return(self):
+ self.assertEquals(CONSTANT_UTF8, TestGI.utf8_full_return())
+
+ def test_utf8_none_in(self):
+ TestGI.utf8_none_in(CONSTANT_UTF8)
+
+ self.assertRaises(TypeError, TestGI.utf8_none_in, CONSTANT_NUMBER)
+ self.assertRaises(TypeError, TestGI.utf8_none_in, None)
+
+ def test_utf8_full_in(self):
+ TestGI.utf8_full_in(CONSTANT_UTF8)
+
+ def test_utf8_none_out(self):
+ self.assertEquals(CONSTANT_UTF8, TestGI.utf8_none_out())
+
+ def test_utf8_full_out(self):
+ self.assertEquals(CONSTANT_UTF8, TestGI.utf8_full_out())
+
+ def test_utf8_none_inout(self):
+ self.assertEquals("", TestGI.utf8_none_inout(CONSTANT_UTF8))
+
+ def test_utf8_full_inout(self):
+ self.assertEquals("", TestGI.utf8_full_inout(CONSTANT_UTF8))
+
+
+class TestArray(unittest.TestCase):
+
+ def test_array_fixed_int_return(self):
+ self.assertEquals((-1, 0, 1, 2), TestGI.array_fixed_int_return())
+
+ def test_array_fixed_short_return(self):
+ self.assertEquals((-1, 0, 1, 2), TestGI.array_fixed_short_return())
+
+ def test_array_fixed_int_in(self):
+ TestGI.array_fixed_int_in(Sequence((-1, 0, 1, 2)))
+
+ self.assertRaises(TypeError, TestGI.array_fixed_int_in, Sequence((-1, '0', 1, 2)))
+
+ self.assertRaises(TypeError, TestGI.array_fixed_int_in, 42)
+ self.assertRaises(TypeError, TestGI.array_fixed_int_in, None)
+
+ def test_array_fixed_short_in(self):
+ TestGI.array_fixed_short_in(Sequence((-1, 0, 1, 2)))
+
+ def test_array_fixed_out(self):
+ self.assertEquals((-1, 0, 1, 2), TestGI.array_fixed_out())
+
+ def test_array_fixed_inout(self):
+ self.assertEquals((2, 1, 0, -1), TestGI.array_fixed_inout((-1, 0, 1, 2)))
+
+
+ def test_array_return(self):
+ self.assertEquals((-1, 0, 1, 2), TestGI.array_return())
+
+ def test_array_in(self):
+ TestGI.array_in(Sequence((-1, 0, 1, 2)))
+
+ def test_array_out(self):
+ self.assertEquals((-1, 0, 1, 2), TestGI.array_out())
+
+ def test_array_inout(self):
+ self.assertEquals((-2, -1, 0, 1, 2), TestGI.array_inout(Sequence((-1, 0, 1, 2))))
+
+
+ def test_array_zero_terminated_return(self):
+ self.assertEquals(('0', '1', '2'), TestGI.array_zero_terminated_return())
+
+ def test_array_zero_terminated_in(self):
+ TestGI.array_zero_terminated_in(Sequence(('0', '1', '2')))
+
+ def test_array_zero_terminated_out(self):
+ self.assertEquals(('0', '1', '2'), TestGI.array_zero_terminated_out())
+
+ def test_array_zero_terminated_out(self):
+ self.assertEquals(('0', '1', '2'), TestGI.array_zero_terminated_out())
+
+ def test_array_zero_terminated_inout(self):
+ self.assertEquals(('-1', '0', '1', '2'), TestGI.array_zero_terminated_inout(('0', '1', '2')))
+
+
+class TestGList(unittest.TestCase):
+
+ def test_glist_int_none_return(self):
+ self.assertEquals([-1, 0, 1, 2], TestGI.glist_int_none_return())
+
+ def test_glist_utf8_none_return(self):
+ self.assertEquals(['0', '1', '2'], TestGI.glist_utf8_none_return())
+
+ def test_glist_utf8_container_return(self):
+ self.assertEquals(['0', '1', '2'], TestGI.glist_utf8_container_return())
+
+ def test_glist_utf8_full_return(self):
+ self.assertEquals(['0', '1', '2'], TestGI.glist_utf8_full_return())
+
+ def test_glist_int_none_in(self):
+ TestGI.glist_int_none_in(Sequence((-1, 0, 1, 2)))
+
+ self.assertRaises(TypeError, TestGI.glist_int_none_in, Sequence((-1, '0', 1, 2)))
+
+ self.assertRaises(TypeError, TestGI.glist_int_none_in, 42)
+ self.assertRaises(TypeError, TestGI.glist_int_none_in, None)
+
+ def test_glist_utf8_none_in(self):
+ TestGI.glist_utf8_none_in(Sequence(('0', '1', '2')))
+
+ def test_glist_utf8_container_in(self):
+ TestGI.glist_utf8_container_in(Sequence(('0', '1', '2')))
+
+ def test_glist_utf8_full_in(self):
+ TestGI.glist_utf8_full_in(Sequence(('0', '1', '2')))
+
+ def test_glist_utf8_none_out(self):
+ self.assertEquals(['0', '1', '2'], TestGI.glist_utf8_none_out())
+
+ def test_glist_utf8_container_out(self):
+ self.assertEquals(['0', '1', '2'], TestGI.glist_utf8_container_out())
+
+ def test_glist_utf8_full_out(self):
+ self.assertEquals(['0', '1', '2'], TestGI.glist_utf8_full_out())
+
+ def test_glist_utf8_none_inout(self):
+ self.assertEquals(['-2', '-1', '0', '1'], TestGI.glist_utf8_none_inout(Sequence(('0', '1', '2'))))
+
+ def test_glist_utf8_container_inout(self):
+ self.assertEquals(['-2', '-1','0', '1'], TestGI.glist_utf8_container_inout(('0', '1', '2')))
+
+ def test_glist_utf8_full_inout(self):
+ self.assertEquals(['-2', '-1','0', '1'], TestGI.glist_utf8_full_inout(('0', '1', '2')))
+
+
+class TestGSList(unittest.TestCase):
+
+ def test_gslist_int_none_return(self):
+ self.assertEquals([-1, 0, 1, 2], TestGI.gslist_int_none_return())
+
+ def test_gslist_utf8_none_return(self):
+ self.assertEquals(['0', '1', '2'], TestGI.gslist_utf8_none_return())
+
+ def test_gslist_utf8_container_return(self):
+ self.assertEquals(['0', '1', '2'], TestGI.gslist_utf8_container_return())
+
+ def test_gslist_utf8_full_return(self):
+ self.assertEquals(['0', '1', '2'], TestGI.gslist_utf8_full_return())
+
+ def test_gslist_int_none_in(self):
+ TestGI.gslist_int_none_in(Sequence((-1, 0, 1, 2)))
+
+ self.assertRaises(TypeError, TestGI.gslist_int_none_in, Sequence((-1, '0', 1, 2)))
+
+ self.assertRaises(TypeError, TestGI.gslist_int_none_in, 42)
+ self.assertRaises(TypeError, TestGI.gslist_int_none_in, None)
+
+ def test_gslist_utf8_none_in(self):
+ TestGI.gslist_utf8_none_in(Sequence(('0', '1', '2')))
+
+ def test_gslist_utf8_container_in(self):
+ TestGI.gslist_utf8_container_in(Sequence(('0', '1', '2')))
+
+ def test_gslist_utf8_full_in(self):
+ TestGI.gslist_utf8_full_in(Sequence(('0', '1', '2')))
+
+ def test_gslist_utf8_none_out(self):
+ self.assertEquals(['0', '1', '2'], TestGI.gslist_utf8_none_out())
+
+ def test_gslist_utf8_container_out(self):
+ self.assertEquals(['0', '1', '2'], TestGI.gslist_utf8_container_out())
+
+ def test_gslist_utf8_full_out(self):
+ self.assertEquals(['0', '1', '2'], TestGI.gslist_utf8_full_out())
+
+ def test_gslist_utf8_none_inout(self):
+ self.assertEquals(['-2', '-1', '0', '1'], TestGI.gslist_utf8_none_inout(Sequence(('0', '1', '2'))))
+
+ def test_gslist_utf8_container_inout(self):
+ self.assertEquals(['-2', '-1','0', '1'], TestGI.gslist_utf8_container_inout(('0', '1', '2')))
+
+ def test_gslist_utf8_full_inout(self):
+ self.assertEquals(['-2', '-1','0', '1'], TestGI.gslist_utf8_full_inout(('0', '1', '2')))
+
+
+class TestGHashTable(unittest.TestCase):
+
+ def test_ghashtable_int_none_return(self):
+ self.assertEquals({-1: 1, 0: 0, 1: -1, 2: -2}, TestGI.ghashtable_int_none_return())
+
+ def test_ghashtable_int_none_return(self):
+ self.assertEquals({'-1': '1', '0': '0', '1': '-1', '2': '-2'}, TestGI.ghashtable_utf8_none_return())
+
+ def test_ghashtable_int_container_return(self):
+ self.assertEquals({'-1': '1', '0': '0', '1': '-1', '2': '-2'}, TestGI.ghashtable_utf8_container_return())
+
+ def test_ghashtable_int_full_return(self):
+ self.assertEquals({'-1': '1', '0': '0', '1': '-1', '2': '-2'}, TestGI.ghashtable_utf8_full_return())
+
+ def test_ghashtable_int_none_in(self):
+ TestGI.ghashtable_int_none_in({-1: 1, 0: 0, 1: -1, 2: -2})
+
+ self.assertRaises(TypeError, TestGI.ghashtable_int_none_in, {-1: 1, '0': 0, 1: -1, 2: -2})
+ self.assertRaises(TypeError, TestGI.ghashtable_int_none_in, {-1: 1, 0: '0', 1: -1, 2: -2})
+
+ self.assertRaises(TypeError, TestGI.ghashtable_int_none_in, '{-1: 1, 0: 0, 1: -1, 2: -2}')
+ self.assertRaises(TypeError, TestGI.ghashtable_int_none_in, None)
+
+ def test_ghashtable_utf8_none_in(self):
+ TestGI.ghashtable_utf8_none_in({'-1': '1', '0': '0', '1': '-1', '2': '-2'})
+
+ def test_ghashtable_utf8_container_in(self):
+ TestGI.ghashtable_utf8_container_in({'-1': '1', '0': '0', '1': '-1', '2': '-2'})
+
+ def test_ghashtable_utf8_full_in(self):
+ TestGI.ghashtable_utf8_full_in({'-1': '1', '0': '0', '1': '-1', '2': '-2'})
+
+ def test_ghashtable_utf8_none_out(self):
+ self.assertEquals({'-1': '1', '0': '0', '1': '-1', '2': '-2'}, TestGI.ghashtable_utf8_none_out())
+
+ def test_ghashtable_utf8_container_out(self):
+ self.assertEquals({'-1': '1', '0': '0', '1': '-1', '2': '-2'}, TestGI.ghashtable_utf8_container_out())
+
+ def test_ghashtable_utf8_full_out(self):
+ self.assertEquals({'-1': '1', '0': '0', '1': '-1', '2': '-2'}, TestGI.ghashtable_utf8_full_out())
+
+ def test_ghashtable_utf8_none_inout(self):
+ self.assertEquals({'-1': '1', '0': '0', '1': '1'},
+ TestGI.ghashtable_utf8_none_inout({'-1': '1', '0': '0', '1': '-1', '2': '-2'}))
+
+ def test_ghashtable_utf8_container_inout(self):
+ self.assertEquals({'-1': '1', '0': '0', '1': '1'},
+ TestGI.ghashtable_utf8_container_inout({'-1': '1', '0': '0', '1': '-1', '2': '-2'}))
+
+ def test_ghashtable_utf8_full_inout(self):
+ self.assertEquals({'-1': '1', '0': '0', '1': '1'},
+ TestGI.ghashtable_utf8_full_inout({'-1': '1', '0': '0', '1': '-1', '2': '-2'}))
+
+
+class TestGValue(unittest.TestCase):
+
+ def test_gvalue_return(self):
+ self.assertEquals(42, TestGI.gvalue_return())
+
+ def test_gvalue_in(self):
+ TestGI.gvalue_in(42)
+ self.assertRaises(TypeError, TestGI.gvalue_in, None)
+
+ def test_gvalue_out(self):
+ self.assertEquals(42, TestGI.gvalue_out())
+
+ def test_gvalue_inout(self):
+ self.assertEquals('42', TestGI.gvalue_inout(42))
+
+
+class TestGClosure(unittest.TestCase):
+
+ def test_gclosure_in(self):
+ TestGI.gclosure_in(lambda: 42)
+
+ self.assertRaises(TypeError, TestGI.gclosure_in, 42)
+ self.assertRaises(TypeError, TestGI.gclosure_in, None)
+
+
+class TestGEnum(unittest.TestCase):
+
+ def test_enum(self):
+ self.assertTrue(issubclass(TestGI.Enum, gobject.GEnum))
+ self.assertTrue(isinstance(TestGI.Enum.VALUE1, TestGI.Enum))
+ self.assertTrue(isinstance(TestGI.Enum.VALUE2, TestGI.Enum))
+ self.assertTrue(isinstance(TestGI.Enum.VALUE3, TestGI.Enum))
+ self.assertEquals(42, TestGI.Enum.VALUE3)
+
+ def test_enum_in(self):
+ TestGI.enum_in(TestGI.Enum.VALUE3)
+
+ self.assertRaises(TypeError, TestGI.enum_in, 42)
+ self.assertRaises(TypeError, TestGI.enum_in, 'TestGI.Enum.VALUE3')
+
+ def test_enum_in_ptr(self):
+ TestGI.enum_in_ptr(TestGI.Enum.VALUE3)
+
+ self.assertRaises(TypeError, TestGI.enum_in_ptr, None)
+
+ def test_enum_out(self):
+ enum = TestGI.enum_out()
+ self.assertTrue(isinstance(enum, TestGI.Enum))
+ self.assertEquals(enum, TestGI.Enum.VALUE3)
+
+ def test_enum_inout(self):
+ enum = TestGI.enum_inout(TestGI.Enum.VALUE3)
+ self.assertTrue(isinstance(enum, TestGI.Enum))
+ self.assertEquals(enum, TestGI.Enum.VALUE1)
+
+
+class TestGFlags(unittest.TestCase):
+
+ def test_flags(self):
+ self.assertTrue(issubclass(TestGI.Flags, gobject.GFlags))
+ self.assertTrue(isinstance(TestGI.Flags.VALUE1, TestGI.Flags))
+ self.assertTrue(isinstance(TestGI.Flags.VALUE2, TestGI.Flags))
+ self.assertTrue(isinstance(TestGI.Flags.VALUE3, TestGI.Flags))
+ self.assertEquals(1 << 1, TestGI.Flags.VALUE2)
+
+ def test_flags_in(self):
+ TestGI.flags_in(TestGI.Flags.VALUE2)
+
+ self.assertRaises(TypeError, TestGI.flags_in, 1 << 1)
+ self.assertRaises(TypeError, TestGI.flags_in, 'TestGI.Flags.VALUE2')
+
+ def test_flags_in_ptr(self):
+ TestGI.flags_in_ptr(TestGI.Flags.VALUE2)
+
+ self.assertRaises(TypeError, TestGI.flags_in_ptr, None)
+
+ def test_flags_out(self):
+ flags = TestGI.flags_out()
+ self.assertTrue(isinstance(flags, TestGI.Flags))
+ self.assertEquals(flags, TestGI.Flags.VALUE2)
+
+ def test_flags_inout(self):
+ flags = TestGI.flags_inout(TestGI.Flags.VALUE2)
+ self.assertTrue(isinstance(flags, TestGI.Flags))
+ self.assertEquals(flags, TestGI.Flags.VALUE1)
+
+
+class TestStructure(unittest.TestCase):
+
+ def test_simple_struct(self):
+ self.assertTrue(issubclass(TestGI.SimpleStruct, gobject.GPointer))
+
+ struct = TestGI.SimpleStruct()
+ self.assertTrue(isinstance(struct, TestGI.SimpleStruct))
+
+ struct.long_ = 6
+ struct.int8 = 7
+
+ self.assertEquals(6, struct.long_)
+ self.assertEquals(7, struct.int8)
+
+ del struct
+
+ def test_nested_struct(self):
+ struct = TestGI.NestedStruct()
+
+ self.assertTrue(isinstance(struct.simple_struct, TestGI.SimpleStruct))
+
+ struct.simple_struct.long_ = 42
+ self.assertEquals(42, struct.simple_struct.long_)
+
+ del struct
+
+ def test_not_simple_struct(self):
+ self.assertRaises(TypeError, TestGI.NotSimpleStruct)
+
+ def test_simple_struct_return(self):
+ struct = TestGI.simple_struct_return()
+
+ self.assertTrue(isinstance(struct, TestGI.SimpleStruct))
+ self.assertEquals(6, struct.long_)
+ self.assertEquals(7, struct.int8)
+
+ del struct
+
+ def test_simple_struct_in(self):
+ struct = TestGI.SimpleStruct()
+ struct.long_ = 6
+ struct.int8 = 7
+
+ TestGI.simple_struct_in(struct)
+
+ del struct
+
+ struct = TestGI.NestedStruct()
+
+ self.assertRaises(TypeError, TestGI.simple_struct_in, struct)
+
+ del struct
+
+ self.assertRaises(TypeError, TestGI.simple_struct_in, None)
+
+ def test_simple_struct_out(self):
+ struct = TestGI.simple_struct_out()
+
+ self.assertTrue(isinstance(struct, TestGI.SimpleStruct))
+ self.assertEquals(6, struct.long_)
+ self.assertEquals(7, struct.int8)
+
+ del struct
+
+ def test_simple_struct_inout(self):
+ in_struct = TestGI.SimpleStruct()
+ in_struct.long_ = 6
+ in_struct.int8 = 7
+
+ out_struct = TestGI.simple_struct_inout(in_struct)
+
+ self.assertTrue(isinstance(out_struct, TestGI.SimpleStruct))
+ self.assertEquals(7, out_struct.long_)
+ self.assertEquals(6, out_struct.int8)
+
+ del in_struct
+ del out_struct
+
+ def test_simple_struct_method(self):
+ struct = TestGI.SimpleStruct()
+ struct.long_ = 6
+ struct.int8 = 7
+
+ struct.method()
+
+ del struct
+
+ self.assertRaises(TypeError, TestGI.SimpleStruct.method)
+
+
+ def test_pointer_struct(self):
+ self.assertTrue(issubclass(TestGI.PointerStruct, gobject.GPointer))
+
+ struct = TestGI.PointerStruct()
+ self.assertTrue(isinstance(struct, TestGI.PointerStruct))
+
+ del struct
+
+ def test_pointer_struct_return(self):
+ struct = TestGI.pointer_struct_return()
+
+ self.assertTrue(isinstance(struct, TestGI.PointerStruct))
+ self.assertEquals(42, struct.long_)
+
+ del struct
+
+ def test_pointer_struct_in(self):
+ struct = TestGI.PointerStruct()
+ struct.long_ = 42
+
+ TestGI.pointer_struct_in(struct)
+
+ del struct
+
+ def test_pointer_struct_out(self):
+ struct = TestGI.pointer_struct_out()
+
+ self.assertTrue(isinstance(struct, TestGI.PointerStruct))
+ self.assertEquals(42, struct.long_)
+
+ del struct
+
+ def test_pointer_struct_inout(self):
+ in_struct = TestGI.PointerStruct()
+ in_struct.long_ = 42
+
+ out_struct = TestGI.pointer_struct_inout(in_struct)
+
+ self.assertTrue(isinstance(out_struct, TestGI.PointerStruct))
+ self.assertEquals(0, out_struct.long_)
+
+ del in_struct
+ del out_struct
+
+
+ def test_boxed_struct(self):
+ self.assertTrue(issubclass(TestGI.BoxedStruct, gobject.GBoxed))
+
+ self.assertRaises(TypeError, TestGI.BoxedStruct)
+
+ def test_boxed_instantiable_struct(self):
+ struct = TestGI.BoxedInstantiableStruct()
+
+ self.assertTrue(isinstance(struct, TestGI.BoxedInstantiableStruct))
+
+ new_struct = struct.copy()
+ self.assertTrue(isinstance(new_struct, TestGI.BoxedInstantiableStruct))
+
+ del struct
+ del new_struct
+
+ def test_boxed_instantiable_struct_return(self):
+ struct = TestGI.boxed_instantiable_struct_return()
+
+ self.assertTrue(isinstance(struct, TestGI.BoxedInstantiableStruct))
+ self.assertEquals(42, struct.long_)
+
+ del struct
+
+ def test_boxed_instantiable_struct_in(self):
+ struct = TestGI.BoxedInstantiableStruct()
+ struct.long_ = 42
+
+ TestGI.boxed_instantiable_struct_in(struct)
+
+ del struct
+
+ def test_boxed_instantiable_struct_out(self):
+ struct = TestGI.boxed_instantiable_struct_out()
+
+ self.assertTrue(isinstance(struct, TestGI.BoxedInstantiableStruct))
+ self.assertEquals(42, struct.long_)
+
+ del struct
+
+ def test_boxed_instantiable_struct_inout(self):
+ in_struct = TestGI.BoxedInstantiableStruct()
+ in_struct.long_ = 42
+
+ out_struct = TestGI.boxed_instantiable_struct_inout(in_struct)
+
+ self.assertTrue(isinstance(out_struct, TestGI.BoxedInstantiableStruct))
+ self.assertEquals(0, out_struct.long_)
+
+ del in_struct
+ del out_struct
+
+
+class TestGObject(unittest.TestCase):
+
+ def test_object(self):
+ self.assertTrue(issubclass(TestGI.Object, gobject.GObject))
+
+ object_ = TestGI.Object()
+ self.assertTrue(isinstance(object_, TestGI.Object))
+ self.assertEquals(object_.__grefcount__, 1)
+
+ def test_object_new(self):
+ object_ = TestGI.Object.new(42)
+ self.assertTrue(isinstance(object_, TestGI.Object))
+ self.assertEquals(object_.__grefcount__, 1)
+
+ def test_object_int(self):
+ object_ = TestGI.Object(int = 42)
+ self.assertEquals(object_.int_, 42)
+# FIXME: Don't work yet.
+# object_.int_ = 0
+# self.assertEquals(object_.int_, 0)
+
+ def test_object_static_method(self):
+ TestGI.Object.static_method()
+
+ def test_object_method(self):
+ TestGI.Object(int = 42).method()
+ self.assertRaises(TypeError, TestGI.Object.method, gobject.GObject())
+ self.assertRaises(TypeError, TestGI.Object.method)
+
+
+ def test_sub_object(self):
+ self.assertTrue(issubclass(TestGI.SubObject, TestGI.Object))
+
+ object_ = TestGI.SubObject()
+ self.assertTrue(isinstance(object_, TestGI.SubObject))
+
+ def test_sub_object_new(self):
+ self.assertRaises(TypeError, TestGI.SubObject.new, 42)
+
+ def test_sub_object_static_method(self):
+ object_ = TestGI.SubObject()
+ object_.static_method()
+
+ def test_sub_object_method(self):
+ object_ = TestGI.SubObject(int = 42)
+ object_.method()
+
+ def test_sub_object_sub_method(self):
+ object_ = TestGI.SubObject()
+ object_.sub_method()
+
+ def test_sub_object_overwritten_method(self):
+ object_ = TestGI.SubObject()
+ object_.overwritten_method()
+
+ self.assertRaises(TypeError, TestGI.SubObject.overwritten_method, TestGI.Object())
+
+ def test_sub_object_int(self):
+ object_ = TestGI.SubObject()
+ self.assertEquals(object_.int_, 0)
+# FIXME: Don't work yet.
+# object_.int_ = 42
+# self.assertEquals(object_.int_, 42)
+
+ def test_object_none_return(self):
+ object_ = TestGI.object_none_return()
+ self.assertTrue(isinstance(object_, TestGI.Object))
+ self.assertEquals(object_.__grefcount__, 2)
+
+ def test_object_full_return(self):
+ object_ = TestGI.object_full_return()
+ self.assertTrue(isinstance(object_, TestGI.Object))
+ self.assertEquals(object_.__grefcount__, 1)
+
+ def test_object_none_in(self):
+ object_ = TestGI.Object(int = 42)
+ TestGI.object_none_in(object_)
+ self.assertEquals(object_.__grefcount__, 1)
+
+ object_ = TestGI.SubObject(int = 42)
+ TestGI.object_none_in(object_)
+
+ object_ = gobject.GObject()
+ self.assertRaises(TypeError, TestGI.object_none_in, object_)
+
+ self.assertRaises(TypeError, TestGI.object_none_in, None)
+
+ def test_object_full_in(self):
+ object_ = TestGI.Object(int = 42)
+ TestGI.object_full_in(object_)
+ self.assertEquals(object_.__grefcount__, 1)
+
+ def test_object_none_out(self):
+ object_ = TestGI.object_none_out()
+ self.assertTrue(isinstance(object_, TestGI.Object))
+ self.assertEquals(object_.__grefcount__, 2)
+
+ new_object = TestGI.object_none_out()
+ self.assertTrue(new_object is object_)
+
+ def test_object_full_out(self):
+ object_ = TestGI.object_full_out()
+ self.assertTrue(isinstance(object_, TestGI.Object))
+ self.assertEquals(object_.__grefcount__, 1)
+
+ def test_object_none_inout(self):
+ object_ = TestGI.Object(int = 42)
+ new_object = TestGI.object_none_inout(object_)
+
+ self.assertTrue(isinstance(new_object, TestGI.Object))
+
+ self.assertFalse(object_ is new_object)
+
+ self.assertEquals(object_.__grefcount__, 1)
+ self.assertEquals(new_object.__grefcount__, 2)
+
+ new_new_object = TestGI.object_none_inout(object_)
+ self.assertTrue(new_new_object is new_object)
+
+ TestGI.object_none_inout(TestGI.SubObject(int = 42))
+
+ def test_object_full_inout(self):
+ object_ = TestGI.Object(int = 42)
+ new_object = TestGI.object_full_inout(object_)
+
+ self.assertTrue(isinstance(new_object, TestGI.Object))
+
+ self.assertFalse(object_ is new_object)
+
+ self.assertEquals(object_.__grefcount__, 1)
+ self.assertEquals(new_object.__grefcount__, 1)
+
+# FIXME: Doesn't actually return the same object.
+# def test_object_inout_same(self):
+# object_ = TestGI.Object()
+# new_object = TestGI.object_full_inout(object_)
+# self.assertTrue(object_ is new_object)
+# self.assertEquals(object_.__grefcount__, 1)
+
+
+class TestMultiOutputArgs(unittest.TestCase):
+
+ def test_int_out_out(self):
+ self.assertEquals((6, 7), TestGI.int_out_out())
+
+ def test_int_return_out(self):
+ self.assertEquals((6, 7), TestGI.int_return_out())
+
+