diff options
Diffstat (limited to 'gi')
-rw-r--r-- | gi/Makefile.in | 45 | ||||
-rw-r--r-- | gi/_glib/Makefile.in | 37 | ||||
-rw-r--r-- | gi/_gobject/Makefile.in | 39 | ||||
-rw-r--r-- | gi/_gobject/__init__.py | 2 | ||||
-rw-r--r-- | gi/_gobject/constants.py | 2 | ||||
-rw-r--r-- | gi/_gobject/propertyhelper.py | 10 | ||||
-rw-r--r-- | gi/_gobject/pygboxed.c | 3 | ||||
-rw-r--r-- | gi/_gobject/pygobject.c | 218 | ||||
-rw-r--r-- | gi/_gobject/pygtype.c | 47 | ||||
-rw-r--r-- | gi/overrides/GLib.py | 3 | ||||
-rw-r--r-- | gi/overrides/Gdk.py | 44 | ||||
-rw-r--r-- | gi/overrides/Gtk.py | 25 | ||||
-rw-r--r-- | gi/overrides/Makefile.in | 31 | ||||
-rw-r--r-- | gi/pygi-argument.c | 25 | ||||
-rw-r--r-- | gi/pygi-cache.c | 13 | ||||
-rw-r--r-- | gi/pygi-closure.c | 17 | ||||
-rw-r--r-- | gi/pygi-foreign-cairo.c | 85 | ||||
-rw-r--r-- | gi/pygi-property.c | 39 | ||||
-rw-r--r-- | gi/pygtkcompat.py | 45 | ||||
-rw-r--r-- | gi/repository/Makefile.in | 31 | ||||
-rw-r--r-- | gi/types.py | 6 |
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(¶m_values[0], FALSE)); + PyTuple_SetItem (params, 1, pyg_value_as_pyobject(¶m_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 (¶m_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): |