summaryrefslogtreecommitdiff
path: root/gi
diff options
context:
space:
mode:
Diffstat (limited to 'gi')
-rw-r--r--gi/Makefile.in45
-rw-r--r--gi/_glib/Makefile.in37
-rw-r--r--gi/_gobject/Makefile.in39
-rw-r--r--gi/_gobject/__init__.py2
-rw-r--r--gi/_gobject/constants.py2
-rw-r--r--gi/_gobject/propertyhelper.py10
-rw-r--r--gi/_gobject/pygboxed.c3
-rw-r--r--gi/_gobject/pygobject.c218
-rw-r--r--gi/_gobject/pygtype.c47
-rw-r--r--gi/overrides/GLib.py3
-rw-r--r--gi/overrides/Gdk.py44
-rw-r--r--gi/overrides/Gtk.py25
-rw-r--r--gi/overrides/Makefile.in31
-rw-r--r--gi/pygi-argument.c25
-rw-r--r--gi/pygi-cache.c13
-rw-r--r--gi/pygi-closure.c17
-rw-r--r--gi/pygi-foreign-cairo.c85
-rw-r--r--gi/pygi-property.c39
-rw-r--r--gi/pygtkcompat.py45
-rw-r--r--gi/repository/Makefile.in31
-rw-r--r--gi/types.py6
21 files changed, 714 insertions, 53 deletions
diff --git a/gi/Makefile.in b/gi/Makefile.in
index 87ad450..7defbd6 100644
--- a/gi/Makefile.in
+++ b/gi/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.11.3 from Makefile.am.
+# Makefile.in generated by automake 1.11.5 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -16,6 +16,23 @@
@SET_MAKE@
VPATH = @srcdir@
+am__make_dryrun = \
+ { \
+ am__dry=no; \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \
+ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
+ *) \
+ for am__flg in $$MAKEFLAGS; do \
+ case $$am__flg in \
+ *=*|--*) ;; \
+ *n*) am__dry=yes; break;; \
+ esac; \
+ done;; \
+ esac; \
+ test $$am__dry = yes; \
+ }
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
@@ -147,6 +164,11 @@ RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
install-pdf-recursive install-ps-recursive install-recursive \
installcheck-recursive installdirs-recursive pdf-recursive \
ps-recursive uninstall-recursive
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
am__py_compile = PYTHON=$(PYTHON) $(SHELL) $(py_compile)
py_compile = $(top_srcdir)/py-compile
RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
@@ -193,6 +215,8 @@ AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
+CAIRO_CFLAGS = @CAIRO_CFLAGS@
+CAIRO_LIBS = @CAIRO_LIBS@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
@@ -484,7 +508,6 @@ $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
$(am__aclocal_m4_deps):
install-pygiLTLIBRARIES: $(pygi_LTLIBRARIES)
@$(NORMAL_INSTALL)
- test -z "$(pygidir)" || $(MKDIR_P) "$(DESTDIR)$(pygidir)"
@list='$(pygi_LTLIBRARIES)'; test -n "$(pygidir)" || list=; \
list2=; for p in $$list; do \
if test -f $$p; then \
@@ -492,6 +515,8 @@ install-pygiLTLIBRARIES: $(pygi_LTLIBRARIES)
else :; fi; \
done; \
test -z "$$list2" || { \
+ echo " $(MKDIR_P) '$(DESTDIR)$(pygidir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(pygidir)" || exit 1; \
echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pygidir)'"; \
$(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pygidir)"; \
}
@@ -713,8 +738,11 @@ clean-libtool:
-rm -rf .libs _libs
install-pygiPYTHON: $(pygi_PYTHON)
@$(NORMAL_INSTALL)
- test -z "$(pygidir)" || $(MKDIR_P) "$(DESTDIR)$(pygidir)"
@list='$(pygi_PYTHON)'; dlist=; list2=; test -n "$(pygidir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(pygidir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(pygidir)" || exit 1; \
+ fi; \
for p in $$list; do \
if test -f "$$p"; then b=; else b="$(srcdir)/"; fi; \
if test -f $$b$$p; then \
@@ -914,13 +942,10 @@ distdir: $(DISTFILES)
done
@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
- test -d "$(distdir)/$$subdir" \
- || $(MKDIR_P) "$(distdir)/$$subdir" \
- || exit 1; \
- fi; \
- done
- @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
- if test "$$subdir" = .; then :; else \
+ $(am__make_dryrun) \
+ || test -d "$(distdir)/$$subdir" \
+ || $(MKDIR_P) "$(distdir)/$$subdir" \
+ || exit 1; \
dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
$(am__relativize); \
new_distdir=$$reldir; \
diff --git a/gi/_glib/Makefile.in b/gi/_glib/Makefile.in
index 950f540..02700bc 100644
--- a/gi/_glib/Makefile.in
+++ b/gi/_glib/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.11.3 from Makefile.am.
+# Makefile.in generated by automake 1.11.5 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -16,6 +16,23 @@
@SET_MAKE@
VPATH = @srcdir@
+am__make_dryrun = \
+ { \
+ am__dry=no; \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \
+ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
+ *) \
+ for am__flg in $$MAKEFLAGS; do \
+ case $$am__flg in \
+ *=*|--*) ;; \
+ *n*) am__dry=yes; break;; \
+ esac; \
+ done;; \
+ esac; \
+ test $$am__dry = yes; \
+ }
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
@@ -141,6 +158,11 @@ SOURCES = $(_glib_la_SOURCES) \
$(libpyglib_gi_2_0_@PYTHON_BASENAME@_la_SOURCES)
DIST_SOURCES = $(_glib_la_SOURCES) \
$(libpyglib_gi_2_0_@PYTHON_BASENAME@_la_SOURCES)
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
am__py_compile = PYTHON=$(PYTHON) $(SHELL) $(py_compile)
py_compile = $(top_srcdir)/py-compile
ETAGS = etags
@@ -156,6 +178,8 @@ AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
+CAIRO_CFLAGS = @CAIRO_CFLAGS@
+CAIRO_LIBS = @CAIRO_LIBS@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
@@ -409,7 +433,6 @@ $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
$(am__aclocal_m4_deps):
install-libLTLIBRARIES: $(lib_LTLIBRARIES)
@$(NORMAL_INSTALL)
- test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)"
@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
list2=; for p in $$list; do \
if test -f $$p; then \
@@ -417,6 +440,8 @@ install-libLTLIBRARIES: $(lib_LTLIBRARIES)
else :; fi; \
done; \
test -z "$$list2" || { \
+ echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \
echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
$(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
}
@@ -440,7 +465,6 @@ clean-libLTLIBRARIES:
done
install-pyglibLTLIBRARIES: $(pyglib_LTLIBRARIES)
@$(NORMAL_INSTALL)
- test -z "$(pyglibdir)" || $(MKDIR_P) "$(DESTDIR)$(pyglibdir)"
@list='$(pyglib_LTLIBRARIES)'; test -n "$(pyglibdir)" || list=; \
list2=; for p in $$list; do \
if test -f $$p; then \
@@ -448,6 +472,8 @@ install-pyglibLTLIBRARIES: $(pyglib_LTLIBRARIES)
else :; fi; \
done; \
test -z "$$list2" || { \
+ echo " $(MKDIR_P) '$(DESTDIR)$(pyglibdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(pyglibdir)" || exit 1; \
echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pyglibdir)'"; \
$(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pyglibdir)"; \
}
@@ -581,8 +607,11 @@ clean-libtool:
-rm -rf .libs _libs
install-pyglibPYTHON: $(pyglib_PYTHON)
@$(NORMAL_INSTALL)
- test -z "$(pyglibdir)" || $(MKDIR_P) "$(DESTDIR)$(pyglibdir)"
@list='$(pyglib_PYTHON)'; dlist=; list2=; test -n "$(pyglibdir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(pyglibdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(pyglibdir)" || exit 1; \
+ fi; \
for p in $$list; do \
if test -f "$$p"; then b=; else b="$(srcdir)/"; fi; \
if test -f $$b$$p; then \
diff --git a/gi/_gobject/Makefile.in b/gi/_gobject/Makefile.in
index 56caedf..9a5e1ef 100644
--- a/gi/_gobject/Makefile.in
+++ b/gi/_gobject/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.11.3 from Makefile.am.
+# Makefile.in generated by automake 1.11.5 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -17,6 +17,23 @@
VPATH = @srcdir@
+am__make_dryrun = \
+ { \
+ am__dry=no; \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \
+ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
+ *) \
+ for am__flg in $$MAKEFLAGS; do \
+ case $$am__flg in \
+ *=*|--*) ;; \
+ *n*) am__dry=yes; break;; \
+ esac; \
+ done;; \
+ esac; \
+ test $$am__dry = yes; \
+ }
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
@@ -128,6 +145,11 @@ am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
am__v_GEN_0 = @echo " GEN " $@;
SOURCES = $(_gobject_la_SOURCES)
DIST_SOURCES = $(_gobject_la_SOURCES)
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
am__py_compile = PYTHON=$(PYTHON) $(SHELL) $(py_compile)
py_compile = $(top_srcdir)/py-compile
HEADERS = $(pkginclude_HEADERS)
@@ -145,6 +167,8 @@ AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
+CAIRO_CFLAGS = @CAIRO_CFLAGS@
+CAIRO_LIBS = @CAIRO_LIBS@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
@@ -390,7 +414,6 @@ $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
$(am__aclocal_m4_deps):
install-pygobjectLTLIBRARIES: $(pygobject_LTLIBRARIES)
@$(NORMAL_INSTALL)
- test -z "$(pygobjectdir)" || $(MKDIR_P) "$(DESTDIR)$(pygobjectdir)"
@list='$(pygobject_LTLIBRARIES)'; test -n "$(pygobjectdir)" || list=; \
list2=; for p in $$list; do \
if test -f $$p; then \
@@ -398,6 +421,8 @@ install-pygobjectLTLIBRARIES: $(pygobject_LTLIBRARIES)
else :; fi; \
done; \
test -z "$$list2" || { \
+ echo " $(MKDIR_P) '$(DESTDIR)$(pygobjectdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(pygobjectdir)" || exit 1; \
echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pygobjectdir)'"; \
$(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pygobjectdir)"; \
}
@@ -529,8 +554,11 @@ clean-libtool:
-rm -rf .libs _libs
install-pygobjectPYTHON: $(pygobject_PYTHON)
@$(NORMAL_INSTALL)
- test -z "$(pygobjectdir)" || $(MKDIR_P) "$(DESTDIR)$(pygobjectdir)"
@list='$(pygobject_PYTHON)'; dlist=; list2=; test -n "$(pygobjectdir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(pygobjectdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(pygobjectdir)" || exit 1; \
+ fi; \
for p in $$list; do \
if test -f "$$p"; then b=; else b="$(srcdir)/"; fi; \
if test -f $$b$$p; then \
@@ -564,8 +592,11 @@ uninstall-pygobjectPYTHON:
exit $$st
install-pkgincludeHEADERS: $(pkginclude_HEADERS)
@$(NORMAL_INSTALL)
- test -z "$(pkgincludedir)" || $(MKDIR_P) "$(DESTDIR)$(pkgincludedir)"
@list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(pkgincludedir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(pkgincludedir)" || exit 1; \
+ fi; \
for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
echo "$$d$$p"; \
diff --git a/gi/_gobject/__init__.py b/gi/_gobject/__init__.py
index 8184130..d10d8e0 100644
--- a/gi/_gobject/__init__.py
+++ b/gi/_gobject/__init__.py
@@ -178,6 +178,8 @@ TYPE_OBJECT = constants.TYPE_OBJECT
TYPE_PYOBJECT = constants.TYPE_PYOBJECT
TYPE_GTYPE = constants.TYPE_GTYPE
TYPE_UNICHAR = constants.TYPE_UNICHAR
+TYPE_STRV = constants.TYPE_STRV
+TYPE_VARIANT = constants.TYPE_VARIANT
G_MINFLOAT = constants.G_MINFLOAT
G_MAXFLOAT = constants.G_MAXFLOAT
G_MINDOUBLE = constants.G_MINDOUBLE
diff --git a/gi/_gobject/constants.py b/gi/_gobject/constants.py
index 45234bc..3f83a3a 100644
--- a/gi/_gobject/constants.py
+++ b/gi/_gobject/constants.py
@@ -44,6 +44,8 @@ TYPE_PARAM = _gobject.type_from_name('GParam')
TYPE_OBJECT = _gobject.type_from_name('GObject')
TYPE_PYOBJECT = _gobject.type_from_name('PyObject')
TYPE_GTYPE = _gobject.type_from_name('GType')
+TYPE_STRV = _gobject.type_from_name('GStrv')
+TYPE_VARIANT = _gobject.type_from_name('GVariant')
TYPE_UNICHAR = TYPE_UINT
# do a little dance to maintain API compatibility
diff --git a/gi/_gobject/propertyhelper.py b/gi/_gobject/propertyhelper.py
index dff1d79..673b364 100644
--- a/gi/_gobject/propertyhelper.py
+++ b/gi/_gobject/propertyhelper.py
@@ -29,7 +29,7 @@ from .constants import \
TYPE_ULONG, TYPE_INT64, TYPE_UINT64, TYPE_ENUM, TYPE_FLAGS, \
TYPE_FLOAT, TYPE_DOUBLE, TYPE_STRING, \
TYPE_POINTER, TYPE_BOXED, TYPE_PARAM, TYPE_OBJECT, \
- TYPE_PYOBJECT, TYPE_GTYPE
+ TYPE_PYOBJECT, TYPE_GTYPE, TYPE_STRV
from .constants import \
G_MAXFLOAT, G_MAXDOUBLE, \
G_MININT, G_MAXINT, G_MAXUINT, G_MINLONG, G_MAXLONG, \
@@ -226,7 +226,7 @@ class Property(object):
TYPE_ULONG, TYPE_INT64, TYPE_UINT64,
TYPE_FLOAT, TYPE_DOUBLE, TYPE_POINTER,
TYPE_BOXED, TYPE_PARAM, TYPE_OBJECT, TYPE_STRING,
- TYPE_PYOBJECT, TYPE_GTYPE]:
+ TYPE_PYOBJECT, TYPE_GTYPE, TYPE_STRV]:
return type_
else:
raise TypeError("Unsupported type: %r" % (type_,))
@@ -268,6 +268,12 @@ class Property(object):
if not _gobject.type_is_a(default, ptype):
raise TypeError("flags value %s must be an instance of %r" %
(default, ptype))
+ elif _gobject.type_is_a(ptype, TYPE_STRV) and default is not None:
+ if not isinstance(default, list):
+ raise TypeError("Strv value %s must be a list" % repr(default))
+ for val in default:
+ if type(val) not in (str, bytes):
+ raise TypeError("Strv value %s must contain only strings" % str(default))
def _get_minimum(self):
ptype = self.type
diff --git a/gi/_gobject/pygboxed.c b/gi/_gobject/pygboxed.c
index a00386b..541e77b 100644
--- a/gi/_gobject/pygboxed.c
+++ b/gi/_gobject/pygboxed.c
@@ -50,7 +50,8 @@ pyg_boxed_dealloc(PyGBoxed *self)
static PyObject*
pyg_boxed_richcompare(PyObject *self, PyObject *other, int op)
{
- if (Py_TYPE(self) == Py_TYPE(other) && Py_TYPE(self) == &PyGBoxed_Type)
+ if (Py_TYPE(self) == Py_TYPE(other) &&
+ PyObject_IsInstance(self, (PyObject*)&PyGBoxed_Type))
return _pyglib_generic_ptr_richcompare(((PyGBoxed*)self)->boxed,
((PyGBoxed*)other)->boxed,
op);
diff --git a/gi/_gobject/pygobject.c b/gi/_gobject/pygobject.c
index 9d20b97..75c8ba3 100644
--- a/gi/_gobject/pygobject.c
+++ b/gi/_gobject/pygobject.c
@@ -38,8 +38,8 @@ static int pygobject_clear(PyGObject *self);
static PyObject * pyg_type_get_bases(GType gtype);
static inline int pygobject_clear(PyGObject *self);
static PyObject * pygobject_weak_ref_new(GObject *obj, PyObject *callback, PyObject *user_data);
+static PyObject * pygbinding_weak_ref_new(GObject *obj);
static inline PyGObjectData * pyg_object_peek_inst_data(GObject *obj);
-static PyObject * pygobject_weak_ref_new(GObject *obj, PyObject *callback, PyObject *user_data);
static void pygobject_inherit_slots(PyTypeObject *type, PyObject *bases,
gboolean check_for_present);
static void pygobject_find_slot_for(PyTypeObject *type, PyObject *bases, int slot_offset,
@@ -1485,6 +1485,164 @@ pygobject_set_properties(PyGObject *self, PyObject *args, PyObject *kwargs)
return result;
}
+/* custom closure for gobject bindings */
+static void
+pygbinding_closure_invalidate(gpointer data, GClosure *closure)
+{
+ PyGClosure *pc = (PyGClosure *)closure;
+ PyGILState_STATE state;
+
+ state = pyglib_gil_state_ensure();
+ Py_XDECREF(pc->callback);
+ Py_XDECREF(pc->extra_args);
+ pyglib_gil_state_release(state);
+
+ pc->callback = NULL;
+ pc->extra_args = NULL;
+}
+
+static void
+pygbinding_marshal (GClosure *closure,
+ GValue *return_value,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer invocation_hint,
+ gpointer marshal_data)
+{
+ PyGILState_STATE state;
+ PyGClosure *pc = (PyGClosure *)closure;
+ PyObject *params, *ret;
+ GValue *out_value;
+
+ state = pyglib_gil_state_ensure();
+
+ /* construct Python tuple for the parameter values */
+ params = PyTuple_New(2);
+ PyTuple_SetItem (params, 0, pyg_value_as_pyobject(&param_values[0], FALSE));
+ PyTuple_SetItem (params, 1, pyg_value_as_pyobject(&param_values[1], FALSE));
+
+ /* params passed to function may have extra arguments */
+ if (pc->extra_args) {
+ PyObject *tuple = params;
+ params = PySequence_Concat(tuple, pc->extra_args);
+ Py_DECREF(tuple);
+ }
+ ret = PyObject_CallObject(pc->callback, params);
+ if (!ret) {
+ PyErr_Print ();
+ goto out;
+ } else if (ret == Py_None) {
+ g_value_set_boolean (return_value, FALSE);
+ goto out;
+ }
+
+ out_value = g_value_get_boxed (&param_values[2]);
+ if (pyg_value_from_pyobject (out_value, ret) != 0) {
+ PyErr_SetString (PyExc_ValueError, "can't convert value");
+ PyErr_Print ();
+ g_value_set_boolean (return_value, FALSE);
+ } else {
+ g_value_set_boolean (return_value, TRUE);
+ }
+
+ Py_DECREF(ret);
+
+out:
+ Py_DECREF(params);
+ pyglib_gil_state_release(state);
+}
+
+static GClosure *
+pygbinding_closure_new (PyObject *callback, PyObject *extra_args)
+{
+ GClosure *closure;
+
+ g_return_val_if_fail(callback != NULL, NULL);
+ closure = g_closure_new_simple(sizeof(PyGClosure), NULL);
+ g_closure_add_invalidate_notifier(closure, NULL, pygbinding_closure_invalidate);
+ g_closure_set_marshal(closure, pygbinding_marshal);
+ Py_INCREF(callback);
+ ((PyGClosure *)closure)->callback = callback;
+ if (extra_args && extra_args != Py_None) {
+ Py_INCREF(extra_args);
+ if (!PyTuple_Check(extra_args)) {
+ PyObject *tmp = PyTuple_New(1);
+ PyTuple_SetItem(tmp, 0, extra_args);
+ extra_args = tmp;
+ }
+ ((PyGClosure *)closure)->extra_args = extra_args;
+ }
+ return closure;
+}
+
+static PyObject *
+pygobject_bind_property(PyGObject *self, PyObject *args)
+{
+ gchar *source_name, *target_name;
+ gchar *source_canon, *target_canon;
+ PyObject *target, *source_repr, *target_repr;
+ PyObject *transform_to, *transform_from, *user_data = NULL;
+ GBinding *binding;
+ GBindingFlags flags = G_BINDING_DEFAULT;
+ GClosure *to_closure = NULL, *from_closure = NULL;
+
+ transform_from = NULL;
+ transform_to = NULL;
+
+ if (!PyArg_ParseTuple(args, "sOs|iOOO:GObject.bind_property",
+ &source_name, &target, &target_name, &flags,
+ &transform_to, &transform_from, &user_data))
+ return NULL;
+
+ CHECK_GOBJECT(self);
+ if (!PyObject_TypeCheck(target, &PyGObject_Type)) {
+ PyErr_SetString(PyExc_TypeError, "Second argument must be a GObject");
+ return NULL;
+ }
+
+ if (transform_to && transform_to != Py_None) {
+ if (!PyCallable_Check (transform_to)) {
+ PyErr_SetString (PyExc_TypeError,
+ "transform_to must be callable or None");
+ return NULL;
+ }
+ to_closure = pygbinding_closure_new (transform_to, user_data);
+ }
+
+ if (transform_from && transform_from != Py_None) {
+ if (!PyCallable_Check (transform_from)) {
+ PyErr_SetString (PyExc_TypeError,
+ "transform_from must be callable or None");
+ return NULL;
+ }
+ from_closure = pygbinding_closure_new (transform_from, user_data);
+ }
+
+ /* Canonicalize underscores to hyphens. Note the results must be freed. */
+ source_canon = g_strdelimit(g_strdup(source_name), "_", '-');
+ target_canon = g_strdelimit(g_strdup(target_name), "_", '-');
+
+ binding = g_object_bind_property_with_closures (G_OBJECT(self->obj), source_canon,
+ pygobject_get(target), target_canon,
+ flags, to_closure, from_closure);
+ g_free(source_canon);
+ g_free(target_canon);
+ source_canon = target_canon = NULL;
+
+ if (binding == NULL) {
+ source_repr = PyObject_Repr((PyObject*)self);
+ target_repr = PyObject_Repr(target);
+ PyErr_Format(PyExc_TypeError, "Cannot create binding from %s.%s to %s.%s",
+ PYGLIB_PyUnicode_AsString(source_repr), source_name,
+ PYGLIB_PyUnicode_AsString(target_repr), target_name);
+ Py_DECREF(source_repr);
+ Py_DECREF(target_repr);
+ return NULL;
+ }
+
+ return pygbinding_weak_ref_new(G_OBJECT (binding));
+}
+
static PyObject *
pygobject_freeze_notify(PyGObject *self, PyObject *args)
{
@@ -2118,11 +2276,13 @@ pygobject_handler_unblock_by_func(PyGObject *self, PyObject *args)
return PYGLIB_PyLong_FromLong(retval);
}
+
static PyMethodDef pygobject_methods[] = {
{ "get_property", (PyCFunction)pygobject_get_property, METH_VARARGS },
{ "get_properties", (PyCFunction)pygobject_get_properties, METH_VARARGS },
{ "set_property", (PyCFunction)pygobject_set_property, METH_VARARGS },
{ "set_properties", (PyCFunction)pygobject_set_properties, METH_VARARGS|METH_KEYWORDS },
+ { "bind_property", (PyCFunction)pygobject_bind_property, METH_VARARGS|METH_KEYWORDS },
{ "freeze_notify", (PyCFunction)pygobject_freeze_notify, METH_VARARGS },
{ "notify", (PyCFunction)pygobject_notify, METH_VARARGS },
{ "thaw_notify", (PyCFunction)pygobject_thaw_notify, METH_VARARGS },
@@ -2325,6 +2485,54 @@ pygobject_weak_ref_call(PyGObjectWeakRef *self, PyObject *args, PyObject *kw)
}
}
+
+/* -------------- GBinding Weak Reference ----------------- */
+
+/**
+ * BindingWeakRef
+ *
+ * The BindingWeakRef object is used to manage GBinding objects within python
+ * created through GObject.bind_property. It is a sub-class PyGObjectWeakRef so
+ * that we can maintain the same reference counting semantics between Python
+ * and GObject Binding objects. This gives explicit direct control of the
+ * binding lifetime by using the "unbind" method on the BindingWeakRef object
+ * along with implicit management based on the lifetime of the source or
+ * target objects.
+ */
+
+PYGLIB_DEFINE_TYPE("gi._gobject.GBindingWeakRef", PyGBindingWeakRef_Type, PyGObjectWeakRef);
+
+static PyObject *
+pygbinding_weak_ref_new(GObject *obj)
+{
+ PyGObjectWeakRef *self;
+
+ self = PyObject_GC_New(PyGObjectWeakRef, &PyGBindingWeakRef_Type);
+ self->callback = NULL;
+ self->user_data = NULL;
+ self->obj = obj;
+ g_object_weak_ref(self->obj, (GWeakNotify) pygobject_weak_ref_notify, self);
+ return (PyObject *) self;
+}
+
+static PyObject *
+pygbinding_weak_ref_unbind(PyGObjectWeakRef *self, PyObject *args)
+{
+ if (!self->obj) {
+ PyErr_SetString(PyExc_ValueError, "weak binding ref already unreffed");
+ return NULL;
+ }
+ g_object_unref(self->obj);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyMethodDef pygbinding_weak_ref_methods[] = {
+ { "unbind", (PyCFunction)pygbinding_weak_ref_unbind, METH_NOARGS},
+ { NULL, NULL, 0}
+};
+
+
static gpointer
pyobject_copy(gpointer boxed)
{
@@ -2427,6 +2635,14 @@ pygobject_object_register_types(PyObject *d)
return;
PyDict_SetItemString(d, "GObjectWeakRef", (PyObject *) &PyGObjectWeakRef_Type);
+ PyGBindingWeakRef_Type.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_GC;
+ PyGBindingWeakRef_Type.tp_doc = "A GBinding weak reference";
+ PyGBindingWeakRef_Type.tp_methods = pygbinding_weak_ref_methods;
+ PyGBindingWeakRef_Type.tp_base = &PyGObjectWeakRef_Type;
+ if (PyType_Ready(&PyGBindingWeakRef_Type) < 0)
+ return;
+ PyDict_SetItemString(d, "GBindingWeakRef", (PyObject *) &PyGBindingWeakRef_Type);
+
PyGContextFreezeNotify_Type.tp_dealloc = (destructor)pygcontext_freeze_notify_dealloc;
PyGContextFreezeNotify_Type.tp_flags = Py_TPFLAGS_DEFAULT;
PyGContextFreezeNotify_Type.tp_doc = "Context manager for freeze/thaw of GObjects";
diff --git a/gi/_gobject/pygtype.c b/gi/_gobject/pygtype.c
index fa95d13..fe2c3b6 100644
--- a/gi/_gobject/pygtype.c
+++ b/gi/_gobject/pygtype.c
@@ -727,6 +727,26 @@ pyg_value_array_from_pyobject(GValue *value,
return 0;
}
+static
+PyObject *
+pyg_get_gvariant_type()
+{
+ static PyObject *variant_type = NULL;
+ PyObject *py_module;
+
+ if (variant_type == NULL) {
+ py_module = PyImport_ImportModule ("gi.repository.GLib");
+ if (py_module == NULL)
+ return NULL;
+
+ variant_type = PyObject_GetAttrString (py_module, "Variant");
+
+ Py_DECREF (py_module);
+ }
+
+ return variant_type;
+}
+
/**
* pyg_value_from_pyobject:
* @value: the GValue object to store the converted value in.
@@ -991,6 +1011,17 @@ pyg_value_from_pyobject(GValue *value, PyObject *obj)
} else
return -1;
break;
+ case G_TYPE_VARIANT:
+ {
+ PyObject* variant_type = pyg_get_gvariant_type();
+ if (obj == Py_None)
+ g_value_set_variant(value, NULL);
+ else if (variant_type != NULL && PyObject_IsInstance(obj, variant_type))
+ g_value_set_variant(value, pyg_boxed_get(obj, GVariant));
+ else
+ return -1;
+ break;
+ }
default:
{
PyGTypeMarshal *bm;
@@ -1147,6 +1178,15 @@ pyg_value_as_pyobject(const GValue *value, gboolean copy_boxed)
return pyg_param_spec_new(g_value_get_param(value));
case G_TYPE_OBJECT:
return pygobject_new(g_value_get_object(value));
+ case G_TYPE_VARIANT:
+ {
+ GVariant *v = g_value_get_variant(value);
+ if (v == NULL) {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ return pyg_boxed_new(G_TYPE_VARIANT, g_variant_ref(v), FALSE, FALSE);
+ }
default:
{
PyGTypeMarshal *bm;
@@ -1229,8 +1269,11 @@ pyg_closure_marshal(GClosure *closure,
}
if (return_value && pyg_value_from_pyobject(return_value, ret) != 0) {
- PyErr_SetString(PyExc_TypeError,
- "can't convert return value to desired type");
+ /* If we already have an exception set, use that, otherwise set a
+ * generic one */
+ if (!PyErr_Occurred())
+ PyErr_SetString(PyExc_TypeError,
+ "can't convert return value to desired type");
if (pc->exception_handler)
pc->exception_handler(return_value, n_param_values, param_values);
diff --git a/gi/overrides/GLib.py b/gi/overrides/GLib.py
index 41904c8..dcb2728 100644
--- a/gi/overrides/GLib.py
+++ b/gi/overrides/GLib.py
@@ -171,6 +171,9 @@ class Variant(GLib.Variant):
raise TypeError('invalid remaining format string: "%s"' % rest_format)
return v
+ def __del__(self):
+ self.unref()
+
def __repr__(self):
return '<GLib.Variant(%s)>' % getattr(self, 'print')(True)
diff --git a/gi/overrides/Gdk.py b/gi/overrides/Gdk.py
index 604ac37..66d47ef 100644
--- a/gi/overrides/Gdk.py
+++ b/gi/overrides/Gdk.py
@@ -30,6 +30,7 @@ __all__ = []
class Color(Gdk.Color):
+ MAX_VALUE = 65535
def __init__(self, red, green, blue):
Gdk.Color.__init__(self)
@@ -46,6 +47,28 @@ class Color(Gdk.Color):
def __repr__(self):
return '<Gdk.Color(red=%d, green=%d, blue=%d)>' % (self.red, self.green, self.blue)
+ red_float = property(fget=lambda self: self.red / float(self.MAX_VALUE),
+ fset=lambda self, v: setattr(self, 'red', int(v * self.MAX_VALUE)))
+
+ green_float = property(fget=lambda self: self.green / float(self.MAX_VALUE),
+ fset=lambda self, v: setattr(self, 'green', int(v * self.MAX_VALUE)))
+
+ blue_float = property(fget=lambda self: self.blue / float(self.MAX_VALUE),
+ fset=lambda self, v: setattr(self, 'blue', int(v * self.MAX_VALUE)))
+
+ def to_floats(self):
+ """Return (red_float, green_float, blue_float) triple."""
+
+ return (self.red_float, self.green_float, self.blue_float)
+
+ @staticmethod
+ def from_floats(red, green, blue):
+ """Return a new Color object from red/green/blue values from 0.0 to 1.0."""
+
+ return Color(int(red * Color.MAX_VALUE),
+ int(green * Color.MAX_VALUE),
+ int(blue * Color.MAX_VALUE))
+
Color = override(Color)
__all__.append('Color')
@@ -67,6 +90,27 @@ if Gdk._version == '3.0':
def __repr__(self):
return '<Gdk.Color(red=%f, green=%f, blue=%f, alpha=%f)>' % (self.red, self.green, self.blue, self.alpha)
+ def __iter__(self):
+ """Iterator which allows easy conversion to tuple and list types."""
+
+ yield self.red
+ yield self.green
+ yield self.blue
+ yield self.alpha
+
+ def to_color(self):
+ """Converts this RGBA into a Color instance which excludes alpha."""
+
+ return Color(int(self.red * Color.MAX_VALUE),
+ int(self.green * Color.MAX_VALUE),
+ int(self.blue * Color.MAX_VALUE))
+
+ @classmethod
+ def from_color(cls, color):
+ """Returns a new RGBA instance given a Color instance."""
+
+ return cls(color.red_float, color.green_float, color.blue_float)
+
RGBA = override(RGBA)
__all__.append('RGBA')
diff --git a/gi/overrides/Gtk.py b/gi/overrides/Gtk.py
index 5ae61b2..1043cbf 100644
--- a/gi/overrides/Gtk.py
+++ b/gi/overrides/Gtk.py
@@ -750,9 +750,9 @@ class TreeModel(Gtk.TreeModel):
# alias for Python 2.x object protocol
__nonzero__ = __bool__
- def __getitem__(self, key):
+ def _getiter(self, key):
if isinstance(key, Gtk.TreeIter):
- return TreeModelRow(self, key)
+ return key
elif isinstance(key, int) and key < 0:
index = len(self) + key
if index < 0:
@@ -761,18 +761,26 @@ class TreeModel(Gtk.TreeModel):
aiter = self.get_iter(index)
except ValueError:
raise IndexError("could not find tree path '%s'" % key)
- return TreeModelRow(self, aiter)
+ return aiter
else:
try:
aiter = self.get_iter(key)
except ValueError:
raise IndexError("could not find tree path '%s'" % key)
- return TreeModelRow(self, aiter)
+ return aiter
+
+ def __getitem__(self, key):
+ aiter = self._getiter(key)
+ return TreeModelRow(self, aiter)
def __setitem__(self, key, value):
row = self[key]
self.set_row(row.iter, value)
+ def __delitem__(self, key):
+ aiter = self._getiter(key)
+ self.remove(aiter)
+
def __iter__(self):
return TreeModelRowIter(self, self.get_iter_first())
@@ -1080,6 +1088,10 @@ class TreeModelRow(object):
return self.get_next()
@property
+ def previous(self):
+ return self.get_previous()
+
+ @property
def parent(self):
return self.get_parent()
@@ -1088,6 +1100,11 @@ class TreeModelRow(object):
if next_iter:
return TreeModelRow(self.model, next_iter)
+ def get_previous(self):
+ prev_iter = self.model.iter_previous(self.iter)
+ if prev_iter:
+ return TreeModelRow(self.model, prev_iter)
+
def get_parent(self):
parent_iter = self.model.iter_parent(self.iter)
if parent_iter:
diff --git a/gi/overrides/Makefile.in b/gi/overrides/Makefile.in
index d5409a3..85abd08 100644
--- a/gi/overrides/Makefile.in
+++ b/gi/overrides/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.11.3 from Makefile.am.
+# Makefile.in generated by automake 1.11.5 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -15,6 +15,23 @@
@SET_MAKE@
VPATH = @srcdir@
+am__make_dryrun = \
+ { \
+ am__dry=no; \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \
+ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
+ *) \
+ for am__flg in $$MAKEFLAGS; do \
+ case $$am__flg in \
+ *=*|--*) ;; \
+ *n*) am__dry=yes; break;; \
+ esac; \
+ done;; \
+ esac; \
+ test $$am__dry = yes; \
+ }
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
@@ -56,6 +73,11 @@ am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
SOURCES =
DIST_SOURCES =
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
@@ -97,6 +119,8 @@ AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
+CAIRO_CFLAGS = @CAIRO_CFLAGS@
+CAIRO_LIBS = @CAIRO_LIBS@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
@@ -296,8 +320,11 @@ clean-libtool:
-rm -rf .libs _libs
install-pygioverridesPYTHON: $(pygioverrides_PYTHON)
@$(NORMAL_INSTALL)
- test -z "$(pygioverridesdir)" || $(MKDIR_P) "$(DESTDIR)$(pygioverridesdir)"
@list='$(pygioverrides_PYTHON)'; dlist=; list2=; test -n "$(pygioverridesdir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(pygioverridesdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(pygioverridesdir)" || exit 1; \
+ fi; \
for p in $$list; do \
if test -f "$$p"; then b=; else b="$(srcdir)/"; fi; \
if test -f $$b$$p; then \
diff --git a/gi/pygi-argument.c b/gi/pygi-argument.c
index 64602f2..fb798e1 100644
--- a/gi/pygi-argument.c
+++ b/gi/pygi-argument.c
@@ -730,6 +730,7 @@ _pygi_argument_from_object (PyObject *object,
int_ = PYGLIB_PyNumber_Long (object);
if (int_ == NULL) {
+ PyErr_SetString (PyExc_TypeError, "expected int argument");
break;
}
@@ -754,6 +755,7 @@ _pygi_argument_from_object (PyObject *object,
number = PYGLIB_PyNumber_Long (object);
if (number == NULL) {
+ PyErr_SetString (PyExc_TypeError, "expected int argument");
break;
}
@@ -784,6 +786,7 @@ _pygi_argument_from_object (PyObject *object,
number = PYGLIB_PyNumber_Long (object);
if (number == NULL) {
+ PyErr_SetString (PyExc_TypeError, "expected int argument");
break;
}
@@ -806,6 +809,7 @@ _pygi_argument_from_object (PyObject *object,
float_ = PyNumber_Float (object);
if (float_ == NULL) {
+ PyErr_SetString (PyExc_TypeError, "expected float or int argument");
break;
}
@@ -820,6 +824,7 @@ _pygi_argument_from_object (PyObject *object,
float_ = PyNumber_Float (object);
if (float_ == NULL) {
+ PyErr_SetString (PyExc_TypeError, "expected float or int argument");
break;
}
@@ -951,6 +956,16 @@ _pygi_argument_from_object (PyObject *object,
break;
}
+ /* Note, strings are sequences, but we cannot accept them here */
+ if (!PySequence_Check (object) ||
+#if PY_VERSION_HEX < 0x03000000
+ PyString_Check (object) ||
+#endif
+ PyUnicode_Check (object)) {
+ PyErr_SetString (PyExc_TypeError, "expected sequence");
+ break;
+ }
+
length = PySequence_Length (object);
if (length < 0) {
break;
@@ -1097,9 +1112,13 @@ array_success:
result = pygi_struct_foreign_convert_to_g_argument (
object, info, transfer, &arg);
} else if (g_type_is_a (type, G_TYPE_BOXED)) {
- arg.v_pointer = pyg_boxed_get (object, void);
- if (transfer == GI_TRANSFER_EVERYTHING) {
- arg.v_pointer = g_boxed_copy (type, arg.v_pointer);
+ if (pyg_boxed_check (object, type)) {
+ arg.v_pointer = pyg_boxed_get (object, void);
+ if (transfer == GI_TRANSFER_EVERYTHING) {
+ arg.v_pointer = g_boxed_copy (type, arg.v_pointer);
+ }
+ } else {
+ PyErr_Format (PyExc_TypeError, "wrong boxed type");
}
} else if (g_type_is_a (type, G_TYPE_POINTER) ||
g_type_is_a (type, G_TYPE_VARIANT) ||
diff --git a/gi/pygi-cache.c b/gi/pygi-cache.c
index 610e35b..5083417 100644
--- a/gi/pygi-cache.c
+++ b/gi/pygi-cache.c
@@ -155,16 +155,11 @@ _sequence_cache_new (GITypeInfo *type_info,
sc = g_slice_new0 (PyGISequenceCache);
( (PyGIArgCache *)sc)->destroy_notify = (GDestroyNotify)_sequence_cache_free_func;
- sc->fixed_size = -1;
- sc->len_arg_index = -1;
sc->is_zero_terminated = g_type_info_is_zero_terminated (type_info);
- if (!sc->is_zero_terminated) {
- sc->fixed_size = g_type_info_get_array_fixed_size (type_info);
- if (sc->fixed_size < 0)
- sc->len_arg_index = g_type_info_get_array_length (type_info);
- if (sc->len_arg_index >= 0)
- sc->len_arg_index += child_offset;
- }
+ sc->fixed_size = g_type_info_get_array_fixed_size (type_info);
+ sc->len_arg_index = g_type_info_get_array_length (type_info);
+ if (sc->len_arg_index >= 0)
+ sc->len_arg_index += child_offset;
item_type_info = g_type_info_get_param_type (type_info, 0);
diff --git a/gi/pygi-closure.c b/gi/pygi-closure.c
index c89be64..241d91a 100644
--- a/gi/pygi-closure.c
+++ b/gi/pygi-closure.c
@@ -72,6 +72,23 @@ _pygi_closure_assign_pyobj_to_out_argument (gpointer out_arg, PyObject *object,
case GI_TYPE_TAG_DOUBLE:
*((gdouble *) out_arg) = arg.v_double;
break;
+ case GI_TYPE_TAG_INTERFACE:
+ {
+ GIBaseInfo *interface;
+ GIInfoType interface_type;
+
+ interface = g_type_info_get_interface (type_info);
+ interface_type = g_base_info_get_type (interface);
+
+ if (!g_type_info_is_pointer (type_info) &&
+ interface_type == GI_INFO_TYPE_STRUCT) {
+ gsize item_size = _pygi_g_type_info_size (type_info);
+ memcpy (out_arg, arg.v_pointer, item_size);
+ break;
+ }
+ }
+
+ /* Fall through */
default:
*((GIArgument *) out_arg) = arg;
break;
diff --git a/gi/pygi-foreign-cairo.c b/gi/pygi-foreign-cairo.c
index 4e12df3..ef3b0ab 100644
--- a/gi/pygi-foreign-cairo.c
+++ b/gi/pygi-foreign-cairo.c
@@ -112,6 +112,79 @@ cairo_surface_release (GIBaseInfo *base_info,
Py_RETURN_NONE;
}
+
+PyObject *
+cairo_path_to_arg (PyObject *value,
+ GIInterfaceInfo *interface_info,
+ GITransfer transfer,
+ GIArgument *arg)
+{
+ cairo_path_t *path;
+
+ g_assert (transfer == GI_TRANSFER_NOTHING);
+
+ path = ( (PycairoPath*) value)->path;
+ if (!path) {
+ PyErr_SetString (PyExc_ValueError, "Path instance wrapping a NULL path");
+ return NULL;
+ }
+
+ arg->v_pointer = path;
+ Py_RETURN_NONE;
+}
+
+PyObject *
+cairo_path_from_arg (GIInterfaceInfo *interface_info, gpointer data)
+{
+ cairo_path_t *path = (cairo_path_t*) data;
+
+ return PycairoPath_FromPath (path);
+}
+
+PyObject *
+cairo_path_release (GIBaseInfo *base_info,
+ gpointer struct_)
+{
+ cairo_path_destroy ( (cairo_path_t*) struct_);
+ Py_RETURN_NONE;
+}
+
+PyObject *
+cairo_font_options_to_arg (PyObject *value,
+ GIInterfaceInfo *interface_info,
+ GITransfer transfer,
+ GIArgument *arg)
+{
+ cairo_font_options_t *font_options;
+
+ g_assert (transfer == GI_TRANSFER_NOTHING);
+
+ font_options = ( (PycairoFontOptions*) value)->font_options;
+ if (!font_options) {
+ PyErr_SetString (PyExc_ValueError, "FontOptions instance wrapping a NULL font_options");
+ return NULL;
+ }
+
+ arg->v_pointer = font_options;
+ Py_RETURN_NONE;
+}
+
+PyObject *
+cairo_font_options_from_arg (GIInterfaceInfo *interface_info, gpointer data)
+{
+ cairo_font_options_t *font_options = (cairo_font_options_t*) data;
+
+ return PycairoFontOptions_FromFontOptions (cairo_font_options_copy (font_options));
+}
+
+PyObject *
+cairo_font_options_release (GIBaseInfo *base_info,
+ gpointer struct_)
+{
+ cairo_font_options_destroy ( (cairo_font_options_t*) struct_);
+ Py_RETURN_NONE;
+}
+
static PyMethodDef _gi_cairo_functions[] = { {0,} };
PYGLIB_MODULE_START(_gi_cairo, "_gi_cairo")
{
@@ -135,5 +208,17 @@ PYGLIB_MODULE_START(_gi_cairo, "_gi_cairo")
cairo_surface_to_arg,
cairo_surface_from_arg,
cairo_surface_release);
+
+ pygi_register_foreign_struct ("cairo",
+ "Path",
+ cairo_path_to_arg,
+ cairo_path_from_arg,
+ cairo_path_release);
+
+ pygi_register_foreign_struct ("cairo",
+ "FontOptions",
+ cairo_font_options_to_arg,
+ cairo_font_options_from_arg,
+ cairo_font_options_release);
}
PYGLIB_MODULE_END;
diff --git a/gi/pygi-property.c b/gi/pygi-property.c
index f400820..56a9745 100644
--- a/gi/pygi-property.c
+++ b/gi/pygi-property.c
@@ -213,6 +213,25 @@ pygi_get_property_value_real (PyGObject *instance,
case GI_TYPE_TAG_GLIST:
arg.v_pointer = g_value_get_pointer (&value);
break;
+ case GI_TYPE_TAG_ARRAY:
+ {
+ gchar** strings;
+ GArray *arg_items;
+ int i;
+
+ strings = g_value_get_boxed (&value);
+ if (strings == NULL)
+ arg.v_pointer = NULL;
+ else {
+ arg_items = g_array_sized_new (TRUE, TRUE, sizeof (GIArgument), g_strv_length (strings));
+ g_array_set_size (arg_items, g_strv_length (strings));
+ for (i = 0; strings[i] != NULL; ++i) {
+ g_array_index (arg_items, GIArgument, i).v_string = strings[i];
+ }
+ arg.v_pointer = arg_items;
+ }
+ break;
+ }
default:
PyErr_Format (PyExc_NotImplementedError,
"Retrieving properties of type %s is not implemented",
@@ -268,6 +287,9 @@ pygi_set_property_value_real (PyGObject *instance,
transfer = g_property_info_get_ownership_transfer (property_info);
arg = _pygi_argument_from_object (py_value, type_info, transfer);
+ if (PyErr_Occurred())
+ goto out;
+
g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
// FIXME: Lots of types still unhandled
@@ -366,6 +388,23 @@ pygi_set_property_value_real (PyGObject *instance,
case GI_TYPE_TAG_GLIST:
g_value_set_pointer (&value, arg.v_pointer);
break;
+ case GI_TYPE_TAG_ARRAY:
+ {
+ GArray *arg_items = (GArray*) arg.v_pointer;
+ gchar** strings;
+ int i;
+
+ if (arg_items == NULL)
+ goto out;
+
+ strings = g_new0 (char*, arg_items->len);
+ for (i = 0; i < arg_items->len; ++i) {
+ strings[i] = g_array_index (arg_items, GIArgument, i).v_string;
+ }
+ g_array_free (arg_items, TRUE);
+ g_value_set_boxed (&value, strings);
+ break;
+ }
default:
PyErr_Format (PyExc_NotImplementedError,
"Setting properties of type %s is not implemented",
diff --git a/gi/pygtkcompat.py b/gi/pygtkcompat.py
index 4eeaf04..9359219 100644
--- a/gi/pygtkcompat.py
+++ b/gi/pygtkcompat.py
@@ -71,9 +71,8 @@ def _install_enums(module, dest=None, strip=''):
try:
if issubclass(obj, GObject.GFlags):
for value, flag in obj.__flags_values__.items():
- for name in flag.value_names:
- name = name.replace(modname + '_', '')
- setattr(dest, name, flag)
+ name = flag.value_names[-1].replace(modname + '_', '')
+ setattr(dest, name, flag)
except TypeError:
continue
@@ -135,6 +134,26 @@ def enable_gtk(version='2.0'):
Gdk.pixbuf_new_from_file = GdkPixbuf.Pixbuf.new_from_file
Gdk.PixbufLoader = GdkPixbuf.PixbufLoader.new_with_type
+ orig_get_formats = GdkPixbuf.Pixbuf.get_formats
+
+ def get_formats():
+ formats = orig_get_formats()
+ result = []
+
+ def make_dict(format_):
+ result = {}
+ result['description'] = format_.get_description()
+ result['name'] = format_.get_name()
+ result['mime_types'] = format_.get_mime_types()
+ result['extensions'] = format_.get_extensions()
+ return result
+
+ for format_ in formats:
+ result.append(make_dict(format_))
+ return result
+
+ Gdk.pixbuf_get_formats = get_formats
+
orig_get_frame_extents = Gdk.Window.get_frame_extents
def get_frame_extents(window):
@@ -155,6 +174,9 @@ def enable_gtk(version='2.0'):
return orig_get_origin(self)[1:]
Gdk.Window.get_origin = get_origin
+ Gdk.screen_width = Gdk.Screen.width
+ Gdk.screen_height = Gdk.Screen.height
+
# gtk
gi.require_version('Gtk', version)
from gi.repository import Gtk
@@ -309,8 +331,19 @@ def enable_gtk(version='2.0'):
Gtk.icon_theme_get_default = Gtk.IconTheme.get_default
Gtk.image_new_from_pixbuf = Gtk.Image.new_from_pixbuf
Gtk.image_new_from_stock = Gtk.Image.new_from_stock
+ Gtk.image_new_from_animation = Gtk.Image.new_from_animation
+ Gtk.image_new_from_icon_set = Gtk.Image.new_from_icon_set
+ Gtk.image_new_from_file = Gtk.Image.new_from_file
Gtk.settings_get_default = Gtk.Settings.get_default
Gtk.window_set_default_icon = Gtk.Window.set_default_icon
+ Gtk.clipboard_get = Gtk.Clipboard.get
+
+ #AccelGroup
+ Gtk.AccelGroup.connect_group = Gtk.AccelGroup.connect
+
+ #StatusIcon
+ Gtk.status_icon_position_menu = Gtk.StatusIcon.position_menu
+ Gtk.StatusIcon.set_tooltip = Gtk.StatusIcon.set_tooltip_text
# Scale
@@ -351,9 +384,9 @@ def enable_gtk(version='2.0'):
def __getitem__(self, state):
color = self.context.get_background_color(state)
- return Gdk.Color(red=color.red,
- green=color.green,
- blue=color.blue)
+ return Gdk.Color(red=int(color.red * 65535),
+ green=int(color.green * 65535),
+ blue=int(color.blue * 65535))
class Styles(object):
def __init__(self, widget):
diff --git a/gi/repository/Makefile.in b/gi/repository/Makefile.in
index c52283c..4f03e5a 100644
--- a/gi/repository/Makefile.in
+++ b/gi/repository/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.11.3 from Makefile.am.
+# Makefile.in generated by automake 1.11.5 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -15,6 +15,23 @@
@SET_MAKE@
VPATH = @srcdir@
+am__make_dryrun = \
+ { \
+ am__dry=no; \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \
+ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
+ *) \
+ for am__flg in $$MAKEFLAGS; do \
+ case $$am__flg in \
+ *=*|--*) ;; \
+ *n*) am__dry=yes; break;; \
+ esac; \
+ done;; \
+ esac; \
+ test $$am__dry = yes; \
+ }
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
@@ -56,6 +73,11 @@ am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
SOURCES =
DIST_SOURCES =
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
@@ -97,6 +119,8 @@ AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
+CAIRO_CFLAGS = @CAIRO_CFLAGS@
+CAIRO_LIBS = @CAIRO_LIBS@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
@@ -289,8 +313,11 @@ clean-libtool:
-rm -rf .libs _libs
install-pygirepositoryPYTHON: $(pygirepository_PYTHON)
@$(NORMAL_INSTALL)
- test -z "$(pygirepositorydir)" || $(MKDIR_P) "$(DESTDIR)$(pygirepositorydir)"
@list='$(pygirepository_PYTHON)'; dlist=; list2=; test -n "$(pygirepositorydir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(pygirepositorydir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(pygirepositorydir)" || exit 1; \
+ fi; \
for p in $$list; do \
if test -f "$$p"; then b=; else b="$(srcdir)/"; fi; \
if test -f $$b$$p; then \
diff --git a/gi/types.py b/gi/types.py
index e44edba..95f1059 100644
--- a/gi/types.py
+++ b/gi/types.py
@@ -121,10 +121,10 @@ class MetaClassHelper(object):
# If a method name starts with "do_" assume it is a vfunc, and search
# in the base classes for a method with the same name to override.
- # Recursion is not necessary here because getattr() searches all
- # super class attributes as well.
+ # Recursion is necessary as overriden methods in most immediate parent
+ # classes may shadow vfuncs from classes higher in the hierarchy.
vfunc_info = None
- for base in cls.__bases__:
+ for base in cls.__mro__:
method = getattr(base, vfunc_name, None)
if method is not None and hasattr(method, '__info__') and \
isinstance(method.__info__, VFuncInfo):