diff options
author | DongHun Kwak <dh0128.kwak@samsung.com> | 2017-07-12 08:33:01 +0900 |
---|---|---|
committer | DongHun Kwak <dh0128.kwak@samsung.com> | 2017-07-12 08:33:58 +0900 |
commit | 042fed5140cf6643eab1081664993b0d392f09ad (patch) | |
tree | 12182549be574532fae8632521eab6fcfbba25ae /gi | |
parent | ab8bccfcb4b6be6d38390d730780d82c56c77308 (diff) | |
download | pygobject2-042fed5140cf6643eab1081664993b0d392f09ad.tar.gz pygobject2-042fed5140cf6643eab1081664993b0d392f09ad.tar.bz2 pygobject2-042fed5140cf6643eab1081664993b0d392f09ad.zip |
Imported Upstream version 2.21.4upstream/2.21.4
Change-Id: Idd424be3991e2f8c1e75cb8db3f4e2986aa2fccd
Signed-off-by: DongHun Kwak <dh0128.kwak@samsung.com>
Diffstat (limited to 'gi')
41 files changed, 11713 insertions, 0 deletions
diff --git a/gi/Makefile.am b/gi/Makefile.am new file mode 100644 index 0000000..c651c97 --- /dev/null +++ b/gi/Makefile.am @@ -0,0 +1,81 @@ +PLATFORM_VERSION = 2.0 + +pkgincludedir = $(includedir)/pygtk-$(PLATFORM_VERSION) +pkgpyexecdir = $(pyexecdir)/gtk-2.0 + +SUBDIRS = \ + repository \ + overrides + +INCLUDES = -I$(top_srcdir)/gobject + +pygidir = $(pkgpyexecdir)/gi +pygi_PYTHON = \ + types.py \ + module.py \ + importer.py \ + __init__.py + +_gi_la_CFLAGS = \ + $(PYTHON_INCLUDES) \ + $(GI_CFLAGS) +_gi_la_LDFLAGS = \ + -module \ + -avoid-version \ + -export-symbols-regex init_gi +_gi_la_LIBADD = \ + $(GI_LIBS) +_gi_la_SOURCES = \ + pygi-repository.c \ + pygi-repository.h \ + pygi-info.c \ + pygi-info.h \ + pygi-invoke.c \ + pygi-invoke.h \ + pygi-foreign.c \ + pygi-foreign.h \ + pygi-struct.c \ + pygi-struct.h \ + pygi-argument.c \ + pygi-argument.h \ + pygi-type.c \ + pygi-type.h \ + pygi-boxed.c \ + pygi-boxed.h \ + pygi-closure.c \ + pygi-closure.h \ + pygi-callbacks.c \ + pygi-callbacks.h \ + pygi.h \ + pygi-private.h \ + pygobject-external.h \ + gimodule.c + +_gi_cairo_la_CFLAGS = \ + $(PYTHON_INCLUDES) \ + $(GI_CFLAGS) \ + $(PYCAIRO_CFLAGS) +_gi_cairo_la_LDFLAGS = \ + -module \ + -avoid-version \ + -export-symbols-regex init_gi_cairo +_gi_cairo_la_LIBADD = \ + $(GI_LIBS) \ + $(PYCAIRO_LIBS) +_gi_cairo_la_SOURCES = pygi-foreign-cairo.c + +pygi_LTLIBRARIES = _gi.la _gi_cairo.la + +# This is to ensure we have a symlink to the .so in the +# build directory, which the Python interpreter can load +# directly without having to know how to parse .la files. +_gi.so: _gi.la + rm -f $@ && $(LN_S) .libs/$@ $@ +_gi_cairo.so: _gi_cairo.la + rm -f $@ && $(LN_S) .libs/$@ $@ + +all-local: _gi.so _gi_cairo.so +check-local: _gi.so _gi_cairo.so +clean-local: + rm -f _gi.so _gi_cairo.so + diff --git a/gi/Makefile.in b/gi/Makefile.in new file mode 100644 index 0000000..2f1000a --- /dev/null +++ b/gi/Makefile.in @@ -0,0 +1,972 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = gi +DIST_COMMON = $(pygi_PYTHON) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/as-ac-expand.m4 \ + $(top_srcdir)/m4/jhflags.m4 $(top_srcdir)/m4/python.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__installdirs = "$(DESTDIR)$(pygidir)" "$(DESTDIR)$(pygidir)" +LTLIBRARIES = $(pygi_LTLIBRARIES) +am__DEPENDENCIES_1 = +_gi_la_DEPENDENCIES = $(am__DEPENDENCIES_1) +am__gi_la_OBJECTS = _gi_la-pygi-repository.lo _gi_la-pygi-info.lo \ + _gi_la-pygi-invoke.lo _gi_la-pygi-foreign.lo \ + _gi_la-pygi-struct.lo _gi_la-pygi-argument.lo \ + _gi_la-pygi-type.lo _gi_la-pygi-boxed.lo \ + _gi_la-pygi-closure.lo _gi_la-pygi-callbacks.lo \ + _gi_la-gimodule.lo +_gi_la_OBJECTS = $(am__gi_la_OBJECTS) +AM_V_lt = $(am__v_lt_$(V)) +am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY)) +am__v_lt_0 = --silent +_gi_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(_gi_la_CFLAGS) $(CFLAGS) \ + $(_gi_la_LDFLAGS) $(LDFLAGS) -o $@ +_gi_cairo_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am__gi_cairo_la_OBJECTS = _gi_cairo_la-pygi-foreign-cairo.lo +_gi_cairo_la_OBJECTS = $(am__gi_cairo_la_OBJECTS) +_gi_cairo_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(_gi_cairo_la_CFLAGS) \ + $(CFLAGS) $(_gi_cairo_la_LDFLAGS) $(LDFLAGS) -o $@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_$(V)) +am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY)) +am__v_CC_0 = @echo " CC " $@; +AM_V_at = $(am__v_at_$(V)) +am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY)) +am__v_at_0 = @ +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_$(V)) +am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY)) +am__v_CCLD_0 = @echo " CCLD " $@; +AM_V_GEN = $(am__v_GEN_$(V)) +am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) +am__v_GEN_0 = @echo " GEN " $@; +SOURCES = $(_gi_la_SOURCES) $(_gi_cairo_la_SOURCES) +DIST_SOURCES = $(_gi_la_SOURCES) $(_gi_cairo_la_SOURCES) +RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ + html-recursive info-recursive install-data-recursive \ + install-dvi-recursive install-exec-recursive \ + install-html-recursive install-info-recursive \ + install-pdf-recursive install-ps-recursive install-recursive \ + installcheck-recursive installdirs-recursive pdf-recursive \ + ps-recursive uninstall-recursive +py_compile = $(top_srcdir)/py-compile +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ + $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ + distdir +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = $(SUBDIRS) +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +pkgincludedir = $(includedir)/pygtk-$(PLATFORM_VERSION) +ACLOCAL = @ACLOCAL@ +ACLOCAL_AMFLAGS = @ACLOCAL_AMFLAGS@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DATADIR = @DATADIR@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FFI_CFLAGS = @FFI_CFLAGS@ +FFI_LIBS = @FFI_LIBS@ +FGREP = @FGREP@ +GIOUNIX_CFLAGS = @GIOUNIX_CFLAGS@ +GIOUNIX_LIBS = @GIOUNIX_LIBS@ +GIO_CFLAGS = @GIO_CFLAGS@ +GIO_LIBS = @GIO_LIBS@ +GI_CFLAGS = @GI_CFLAGS@ +GI_LIBS = @GI_LIBS@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ +GLIB_LIBS = @GLIB_LIBS@ +GLIB_MKENUMS = @GLIB_MKENUMS@ +GOBJECT_QUERY = @GOBJECT_QUERY@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@ +INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBFFI_PC = @LIBFFI_PC@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PLATFORM = @PLATFORM@ +PYCAIRO_CFLAGS = @PYCAIRO_CFLAGS@ +PYCAIRO_LIBS = @PYCAIRO_LIBS@ +PYGOBJECT_MAJOR_VERSION = @PYGOBJECT_MAJOR_VERSION@ +PYGOBJECT_MICRO_VERSION = @PYGOBJECT_MICRO_VERSION@ +PYGOBJECT_MINOR_VERSION = @PYGOBJECT_MINOR_VERSION@ +PYTHON = @PYTHON@ +PYTHON_BASENAME = @PYTHON_BASENAME@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_INCLUDES = @PYTHON_INCLUDES@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +THREADING_CFLAGS = @THREADING_CFLAGS@ +VERSION = @VERSION@ +XSLTPROC = @XSLTPROC@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +lt_ECHO = @lt_ECHO@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +pkgpyexecdir = $(pyexecdir)/gtk-2.0 +pkgpythondir = @pkgpythondir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pyexecdir = @pyexecdir@ +pygobject_CODEGEN_DEFINES = @pygobject_CODEGEN_DEFINES@ +pythondir = @pythondir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +PLATFORM_VERSION = 2.0 +SUBDIRS = \ + repository \ + overrides + +INCLUDES = -I$(top_srcdir)/gobject +pygidir = $(pkgpyexecdir)/gi +pygi_PYTHON = \ + types.py \ + module.py \ + importer.py \ + __init__.py + +_gi_la_CFLAGS = \ + $(PYTHON_INCLUDES) \ + $(GI_CFLAGS) + +_gi_la_LDFLAGS = \ + -module \ + -avoid-version \ + -export-symbols-regex init_gi + +_gi_la_LIBADD = \ + $(GI_LIBS) + +_gi_la_SOURCES = \ + pygi-repository.c \ + pygi-repository.h \ + pygi-info.c \ + pygi-info.h \ + pygi-invoke.c \ + pygi-invoke.h \ + pygi-foreign.c \ + pygi-foreign.h \ + pygi-struct.c \ + pygi-struct.h \ + pygi-argument.c \ + pygi-argument.h \ + pygi-type.c \ + pygi-type.h \ + pygi-boxed.c \ + pygi-boxed.h \ + pygi-closure.c \ + pygi-closure.h \ + pygi-callbacks.c \ + pygi-callbacks.h \ + pygi.h \ + pygi-private.h \ + pygobject-external.h \ + gimodule.c + +_gi_cairo_la_CFLAGS = \ + $(PYTHON_INCLUDES) \ + $(GI_CFLAGS) \ + $(PYCAIRO_CFLAGS) + +_gi_cairo_la_LDFLAGS = \ + -module \ + -avoid-version \ + -export-symbols-regex init_gi_cairo + +_gi_cairo_la_LIBADD = \ + $(GI_LIBS) \ + $(PYCAIRO_LIBS) + +_gi_cairo_la_SOURCES = pygi-foreign-cairo.c +pygi_LTLIBRARIES = _gi.la _gi_cairo.la +all: all-recursive + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign gi/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign gi/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(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 \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + 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)"; \ + } + +uninstall-pygiLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(pygi_LTLIBRARIES)'; test -n "$(pygidir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pygidir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pygidir)/$$f"; \ + done + +clean-pygiLTLIBRARIES: + -test -z "$(pygi_LTLIBRARIES)" || rm -f $(pygi_LTLIBRARIES) + @list='$(pygi_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +_gi.la: $(_gi_la_OBJECTS) $(_gi_la_DEPENDENCIES) + $(AM_V_CCLD)$(_gi_la_LINK) -rpath $(pygidir) $(_gi_la_OBJECTS) $(_gi_la_LIBADD) $(LIBS) +_gi_cairo.la: $(_gi_cairo_la_OBJECTS) $(_gi_cairo_la_DEPENDENCIES) + $(AM_V_CCLD)$(_gi_cairo_la_LINK) -rpath $(pygidir) $(_gi_cairo_la_OBJECTS) $(_gi_cairo_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_gi_cairo_la-pygi-foreign-cairo.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_gi_la-gimodule.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_gi_la-pygi-argument.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_gi_la-pygi-boxed.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_gi_la-pygi-callbacks.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_gi_la-pygi-closure.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_gi_la-pygi-foreign.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_gi_la-pygi-info.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_gi_la-pygi-invoke.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_gi_la-pygi-repository.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_gi_la-pygi-struct.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_gi_la-pygi-type.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +_gi_la-pygi-repository.lo: pygi-repository.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -MT _gi_la-pygi-repository.lo -MD -MP -MF $(DEPDIR)/_gi_la-pygi-repository.Tpo -c -o _gi_la-pygi-repository.lo `test -f 'pygi-repository.c' || echo '$(srcdir)/'`pygi-repository.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/_gi_la-pygi-repository.Tpo $(DEPDIR)/_gi_la-pygi-repository.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pygi-repository.c' object='_gi_la-pygi-repository.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -c -o _gi_la-pygi-repository.lo `test -f 'pygi-repository.c' || echo '$(srcdir)/'`pygi-repository.c + +_gi_la-pygi-info.lo: pygi-info.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -MT _gi_la-pygi-info.lo -MD -MP -MF $(DEPDIR)/_gi_la-pygi-info.Tpo -c -o _gi_la-pygi-info.lo `test -f 'pygi-info.c' || echo '$(srcdir)/'`pygi-info.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/_gi_la-pygi-info.Tpo $(DEPDIR)/_gi_la-pygi-info.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pygi-info.c' object='_gi_la-pygi-info.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -c -o _gi_la-pygi-info.lo `test -f 'pygi-info.c' || echo '$(srcdir)/'`pygi-info.c + +_gi_la-pygi-invoke.lo: pygi-invoke.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -MT _gi_la-pygi-invoke.lo -MD -MP -MF $(DEPDIR)/_gi_la-pygi-invoke.Tpo -c -o _gi_la-pygi-invoke.lo `test -f 'pygi-invoke.c' || echo '$(srcdir)/'`pygi-invoke.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/_gi_la-pygi-invoke.Tpo $(DEPDIR)/_gi_la-pygi-invoke.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pygi-invoke.c' object='_gi_la-pygi-invoke.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -c -o _gi_la-pygi-invoke.lo `test -f 'pygi-invoke.c' || echo '$(srcdir)/'`pygi-invoke.c + +_gi_la-pygi-foreign.lo: pygi-foreign.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -MT _gi_la-pygi-foreign.lo -MD -MP -MF $(DEPDIR)/_gi_la-pygi-foreign.Tpo -c -o _gi_la-pygi-foreign.lo `test -f 'pygi-foreign.c' || echo '$(srcdir)/'`pygi-foreign.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/_gi_la-pygi-foreign.Tpo $(DEPDIR)/_gi_la-pygi-foreign.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pygi-foreign.c' object='_gi_la-pygi-foreign.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -c -o _gi_la-pygi-foreign.lo `test -f 'pygi-foreign.c' || echo '$(srcdir)/'`pygi-foreign.c + +_gi_la-pygi-struct.lo: pygi-struct.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -MT _gi_la-pygi-struct.lo -MD -MP -MF $(DEPDIR)/_gi_la-pygi-struct.Tpo -c -o _gi_la-pygi-struct.lo `test -f 'pygi-struct.c' || echo '$(srcdir)/'`pygi-struct.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/_gi_la-pygi-struct.Tpo $(DEPDIR)/_gi_la-pygi-struct.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pygi-struct.c' object='_gi_la-pygi-struct.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -c -o _gi_la-pygi-struct.lo `test -f 'pygi-struct.c' || echo '$(srcdir)/'`pygi-struct.c + +_gi_la-pygi-argument.lo: pygi-argument.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -MT _gi_la-pygi-argument.lo -MD -MP -MF $(DEPDIR)/_gi_la-pygi-argument.Tpo -c -o _gi_la-pygi-argument.lo `test -f 'pygi-argument.c' || echo '$(srcdir)/'`pygi-argument.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/_gi_la-pygi-argument.Tpo $(DEPDIR)/_gi_la-pygi-argument.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pygi-argument.c' object='_gi_la-pygi-argument.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -c -o _gi_la-pygi-argument.lo `test -f 'pygi-argument.c' || echo '$(srcdir)/'`pygi-argument.c + +_gi_la-pygi-type.lo: pygi-type.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -MT _gi_la-pygi-type.lo -MD -MP -MF $(DEPDIR)/_gi_la-pygi-type.Tpo -c -o _gi_la-pygi-type.lo `test -f 'pygi-type.c' || echo '$(srcdir)/'`pygi-type.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/_gi_la-pygi-type.Tpo $(DEPDIR)/_gi_la-pygi-type.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pygi-type.c' object='_gi_la-pygi-type.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -c -o _gi_la-pygi-type.lo `test -f 'pygi-type.c' || echo '$(srcdir)/'`pygi-type.c + +_gi_la-pygi-boxed.lo: pygi-boxed.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -MT _gi_la-pygi-boxed.lo -MD -MP -MF $(DEPDIR)/_gi_la-pygi-boxed.Tpo -c -o _gi_la-pygi-boxed.lo `test -f 'pygi-boxed.c' || echo '$(srcdir)/'`pygi-boxed.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/_gi_la-pygi-boxed.Tpo $(DEPDIR)/_gi_la-pygi-boxed.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pygi-boxed.c' object='_gi_la-pygi-boxed.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -c -o _gi_la-pygi-boxed.lo `test -f 'pygi-boxed.c' || echo '$(srcdir)/'`pygi-boxed.c + +_gi_la-pygi-closure.lo: pygi-closure.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -MT _gi_la-pygi-closure.lo -MD -MP -MF $(DEPDIR)/_gi_la-pygi-closure.Tpo -c -o _gi_la-pygi-closure.lo `test -f 'pygi-closure.c' || echo '$(srcdir)/'`pygi-closure.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/_gi_la-pygi-closure.Tpo $(DEPDIR)/_gi_la-pygi-closure.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pygi-closure.c' object='_gi_la-pygi-closure.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -c -o _gi_la-pygi-closure.lo `test -f 'pygi-closure.c' || echo '$(srcdir)/'`pygi-closure.c + +_gi_la-pygi-callbacks.lo: pygi-callbacks.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -MT _gi_la-pygi-callbacks.lo -MD -MP -MF $(DEPDIR)/_gi_la-pygi-callbacks.Tpo -c -o _gi_la-pygi-callbacks.lo `test -f 'pygi-callbacks.c' || echo '$(srcdir)/'`pygi-callbacks.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/_gi_la-pygi-callbacks.Tpo $(DEPDIR)/_gi_la-pygi-callbacks.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pygi-callbacks.c' object='_gi_la-pygi-callbacks.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -c -o _gi_la-pygi-callbacks.lo `test -f 'pygi-callbacks.c' || echo '$(srcdir)/'`pygi-callbacks.c + +_gi_la-gimodule.lo: gimodule.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -MT _gi_la-gimodule.lo -MD -MP -MF $(DEPDIR)/_gi_la-gimodule.Tpo -c -o _gi_la-gimodule.lo `test -f 'gimodule.c' || echo '$(srcdir)/'`gimodule.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/_gi_la-gimodule.Tpo $(DEPDIR)/_gi_la-gimodule.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gimodule.c' object='_gi_la-gimodule.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_gi_la_CFLAGS) $(CFLAGS) -c -o _gi_la-gimodule.lo `test -f 'gimodule.c' || echo '$(srcdir)/'`gimodule.c + +_gi_cairo_la-pygi-foreign-cairo.lo: pygi-foreign-cairo.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_gi_cairo_la_CFLAGS) $(CFLAGS) -MT _gi_cairo_la-pygi-foreign-cairo.lo -MD -MP -MF $(DEPDIR)/_gi_cairo_la-pygi-foreign-cairo.Tpo -c -o _gi_cairo_la-pygi-foreign-cairo.lo `test -f 'pygi-foreign-cairo.c' || echo '$(srcdir)/'`pygi-foreign-cairo.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/_gi_cairo_la-pygi-foreign-cairo.Tpo $(DEPDIR)/_gi_cairo_la-pygi-foreign-cairo.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pygi-foreign-cairo.c' object='_gi_cairo_la-pygi-foreign-cairo.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_gi_cairo_la_CFLAGS) $(CFLAGS) -c -o _gi_cairo_la-pygi-foreign-cairo.lo `test -f 'pygi-foreign-cairo.c' || echo '$(srcdir)/'`pygi-foreign-cairo.c + +mostlyclean-libtool: + -rm -f *.lo + +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=; \ + for p in $$list; do \ + if test -f "$$p"; then b=; else b="$(srcdir)/"; fi; \ + if test -f $$b$$p; then \ + $(am__strip_dir) \ + dlist="$$dlist $$f"; \ + list2="$$list2 $$b$$p"; \ + else :; fi; \ + done; \ + for file in $$list2; do echo $$file; done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pygidir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(pygidir)" || exit $$?; \ + done || exit $$?; \ + if test -n "$$dlist"; then \ + if test -z "$(DESTDIR)"; then \ + PYTHON=$(PYTHON) $(py_compile) --basedir "$(pygidir)" $$dlist; \ + else \ + PYTHON=$(PYTHON) $(py_compile) --destdir "$(DESTDIR)" --basedir "$(pygidir)" $$dlist; \ + fi; \ + else :; fi + +uninstall-pygiPYTHON: + @$(NORMAL_UNINSTALL) + @list='$(pygi_PYTHON)'; test -n "$(pygidir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + test -n "$$files" || exit 0; \ + filesc=`echo "$$files" | sed 's|$$|c|'`; \ + fileso=`echo "$$files" | sed 's|$$|o|'`; \ + echo " ( cd '$(DESTDIR)$(pygidir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(pygidir)" && rm -f $$files || exit $$?; \ + echo " ( cd '$(DESTDIR)$(pygidir)' && rm -f" $$filesc ")"; \ + cd "$(DESTDIR)$(pygidir)" && rm -f $$filesc || exit $$?; \ + echo " ( cd '$(DESTDIR)$(pygidir)' && rm -f" $$fileso ")"; \ + cd "$(DESTDIR)$(pygidir)" && rm -f $$fileso + +# This directory's subdirectories are mostly independent; you can cd +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (which will cause the Makefiles to be regenerated when you run `make'); +# (2) otherwise, pass the desired values on the `make' command line. +$(RECURSIVE_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +$(RECURSIVE_CLEAN_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + rev=''; for subdir in $$list; do \ + if test "$$subdir" = "."; then :; else \ + rev="$$subdir $$rev"; \ + fi; \ + done; \ + rev="$$rev ."; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done +ctags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ + done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + 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 \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) check-local +check: check-recursive +all-am: Makefile $(LTLIBRARIES) all-local +installdirs: installdirs-recursive +installdirs-am: + for dir in "$(DESTDIR)$(pygidir)" "$(DESTDIR)$(pygidir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-recursive + +clean-am: clean-generic clean-libtool clean-local \ + clean-pygiLTLIBRARIES mostlyclean-am + +distclean: distclean-recursive + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: install-pygiLTLIBRARIES install-pygiPYTHON + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: uninstall-pygiLTLIBRARIES uninstall-pygiPYTHON + +.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) check-am \ + ctags-recursive install-am install-strip tags-recursive + +.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ + all all-am all-local check check-am check-local clean \ + clean-generic clean-libtool clean-local clean-pygiLTLIBRARIES \ + ctags ctags-recursive distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-ps install-ps-am \ + install-pygiLTLIBRARIES install-pygiPYTHON install-strip \ + installcheck installcheck-am installdirs installdirs-am \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags tags-recursive uninstall uninstall-am \ + uninstall-pygiLTLIBRARIES uninstall-pygiPYTHON + + +# This is to ensure we have a symlink to the .so in the +# build directory, which the Python interpreter can load +# directly without having to know how to parse .la files. +_gi.so: _gi.la + rm -f $@ && $(LN_S) .libs/$@ $@ +_gi_cairo.so: _gi_cairo.la + rm -f $@ && $(LN_S) .libs/$@ $@ + +all-local: _gi.so _gi_cairo.so +check-local: _gi.so _gi_cairo.so +clean-local: + rm -f _gi.so _gi_cairo.so + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/gi/__init__.py b/gi/__init__.py new file mode 100644 index 0000000..fb711c3 --- /dev/null +++ b/gi/__init__.py @@ -0,0 +1,27 @@ +# -*- 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 + +# Force loading the GObject typelib so we have available the wrappers for +# base classes such as GInitiallyUnowned +from gi.repository import GObject diff --git a/gi/gimodule.c b/gi/gimodule.c new file mode 100644 index 0000000..df0db7a --- /dev/null +++ b/gi/gimodule.c @@ -0,0 +1,278 @@ +/* -*- 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 "pygi.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 void +initialize_interface (GTypeInterface *iface, PyTypeObject *pytype) +{ + // pygobject prints a warning if interface_init is NULL +} + +static PyObject * +_wrap_pyg_register_interface_info (PyObject *self, PyObject *args) +{ + PyObject *py_g_type; + GType g_type; + GInterfaceInfo *info; + + if (!PyArg_ParseTuple (args, "O!:register_interface_info", + &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_INTERFACE)) { + PyErr_SetString (PyExc_TypeError, "must be an interface"); + return NULL; + } + + info = g_new0 (GInterfaceInfo, 1); + info->interface_init = (GInterfaceInitFunc) initialize_interface; + + pyg_register_interface_info (g_type, info); + + Py_RETURN_NONE; +} + +static PyObject * +_wrap_pyg_hook_up_vfunc_implementation (PyObject *self, PyObject *args) +{ + PyGIBaseInfo *py_info; + PyObject *py_type; + PyObject *py_function; + gpointer implementor_class = NULL; + GType ancestor_g_type = 0; + GType implementor_gtype = 0; + gpointer *method_ptr = NULL; + int length, i; + GIBaseInfo *vfunc_info; + GIBaseInfo *ancestor_info; + GIStructInfo *struct_info; + gboolean is_interface = FALSE; + PyGICClosure *closure = NULL; + + if (!PyArg_ParseTuple (args, "O!O!O:hook_up_vfunc_implementation", + &PyGIBaseInfo_Type, &py_info, + &PyGTypeWrapper_Type, &py_type, + &py_function)) + return NULL; + + implementor_gtype = pyg_type_from_object (py_type); + g_assert (G_TYPE_IS_CLASSED (implementor_gtype)); + + vfunc_info = py_info->info; + ancestor_info = g_base_info_get_container (vfunc_info); + is_interface = g_base_info_get_type (ancestor_info) == GI_INFO_TYPE_INTERFACE; + + ancestor_g_type = g_registered_type_info_get_g_type ( + (GIRegisteredTypeInfo *) ancestor_info); + + implementor_class = g_type_class_ref (implementor_gtype); + if (is_interface) { + GTypeInstance *implementor_iface_class; + implementor_iface_class = g_type_interface_peek (implementor_class, + ancestor_g_type); + if (implementor_iface_class == NULL) { + g_type_class_unref (implementor_class); + PyErr_Format (PyExc_RuntimeError, + "Couldn't find GType of implementor of interface %s. " + "Forgot to set __gtype_name__?", + g_type_name (ancestor_g_type)); + return NULL; + } + + g_type_class_unref (implementor_class); + implementor_class = implementor_iface_class; + + struct_info = g_interface_info_get_iface_struct ( (GIInterfaceInfo*) ancestor_info); + } else + struct_info = g_object_info_get_class_struct ( (GIObjectInfo*) ancestor_info); + + length = g_struct_info_get_n_fields (struct_info); + for (i = 0; i < length; i++) { + GIFieldInfo *field_info; + GITypeInfo *type_info; + GIBaseInfo *interface_info; + GICallbackInfo *callback_info; + gint offset; + + field_info = g_struct_info_get_field (struct_info, i); + + if (strcmp (g_base_info_get_name ( (GIBaseInfo*) field_info), + g_base_info_get_name ( (GIBaseInfo*) vfunc_info)) != 0) + continue; + + type_info = g_field_info_get_type (field_info); + if (g_type_info_get_tag (type_info) != GI_TYPE_TAG_INTERFACE) + continue; + + interface_info = g_type_info_get_interface (type_info); + g_assert (g_base_info_get_type (interface_info) == GI_INFO_TYPE_CALLBACK); + + callback_info = (GICallbackInfo*) interface_info; + offset = g_field_info_get_offset (field_info); + method_ptr = G_STRUCT_MEMBER_P (implementor_class, offset); + + closure = _pygi_make_native_closure ( (GICallableInfo*) callback_info, + GI_SCOPE_TYPE_NOTIFIED, py_function, NULL); + + *method_ptr = closure->closure; + + g_base_info_unref (interface_info); + g_base_info_unref (type_info); + g_base_info_unref (field_info); + + break; + } + + g_base_info_unref (struct_info); + + if (!is_interface) + g_type_class_unref (implementor_class); + + 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 }, + { "register_interface_info", (PyCFunction) _wrap_pyg_register_interface_info, METH_VARARGS }, + { "hook_up_vfunc_implementation", (PyCFunction) _wrap_pyg_hook_up_vfunc_implementation, METH_VARARGS }, + { NULL, NULL, 0 } +}; + +static struct PyGI_API CAPI = { + pygi_type_import_by_g_type_real, + pygi_register_foreign_struct_real, +}; + +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_boxed_register_types (m); + _pygi_argument_init(); + + api = PyCObject_FromVoidPtr ( (void *) &CAPI, 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..c79318e --- /dev/null +++ b/gi/importer.py @@ -0,0 +1,85 @@ +# -*- 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, DynamicGObjectModule, ModuleProxy + + +repository = Repository.get_default() +modules = {} + + +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[fullname] + + path, namespace = fullname.rsplit('.', 1) + + # Workaround for GObject + if namespace == 'GObject': + sys.modules[fullname] = DynamicGObjectModule() + return sys.modules[fullname] + + dynamic_module = DynamicModule(namespace) + modules[namespace] = dynamic_module + + overrides_modules = __import__('gi.overrides', fromlist=[namespace]) + overrides_module = getattr(overrides_modules, namespace, None) + + if overrides_module is not None: + module = ModuleProxy(fullname, namespace, dynamic_module, overrides_module) + else: + module = dynamic_module + + module.__file__ = '<%s>' % fullname + module.__loader__ = self + + sys.modules[fullname] = module + + return module + diff --git a/gi/module.py b/gi/module.py new file mode 100644 index 0000000..e1326aa --- /dev/null +++ b/gi/module.py @@ -0,0 +1,216 @@ +# -*- 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, \ + UnionInfo, \ + Struct, \ + Boxed, \ + enum_add, \ + flags_add +from .types import \ + GObjectMeta, \ + StructMeta, \ + Function, \ + Enum + +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 __init__(self, namespace): + self._namespace = namespace + + def __getattr__(self, 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() + wrapper = g_type.pytype + + if wrapper is None: + if g_type.is_a(gobject.TYPE_ENUM): + wrapper = enum_add(g_type) + elif g_type.is_a(gobject.TYPE_NONE): + # An enum with a GType of None is an enum without GType + wrapper = Enum + else: + wrapper = flags_add(g_type) + + wrapper.__info__ = info + wrapper.__module__ = 'gi.repository.' + info.get_namespace() + + for value_info in info.get_values(): + name = value_info.get_name().upper() + setattr(wrapper, name, wrapper(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, UnionInfo)): + 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__': 'gi.repository.' + self._namespace, + '__gtype__': g_type + } + wrapper = metaclass(name, bases, dict_) + + # Register the new Python wrapper. + if g_type != gobject.TYPE_NONE: + g_type.pytype = wrapper + + elif isinstance(info, FunctionInfo): + wrapper = Function(info) + elif isinstance(info, ConstantInfo): + wrapper = info.get_value() + else: + raise NotImplementedError(info) + + self.__dict__[name] = wrapper + return wrapper + + def __repr__(self): + path = repository.get_typelib_path(self._namespace) + return "<DynamicModule %r from %r>" % (self._namespace, path) + + +class DynamicGObjectModule(DynamicModule): + """Wrapper for the GObject module + + This class allows us to access both the static PyGObject module and the GI GObject module + through the same interface. It is returned when by importing GObject from the gi repository: + + from gi.repository import GObject + + We use this because some PyGI interfaces generated from the GIR require GObject types not wrapped + by the static bindings. This also allows access to module attributes in a way that is more + familiar to GI application developers. Take signal flags as an example. The G_SIGNAL_RUN_FIRST + flag would be accessed as GObject.SIGNAL_RUN_FIRST in the static bindings but in the dynamic bindings + can be accessed as GObject.SignalFlags.RUN_FIRST. The latter follows a GI naming convention which + would be familiar to GI application developers in a number of languages. + """ + + def __init__(self): + self._namespace = 'GObject' + self._module = gobject + + def __getattr__(self, name): + # first see if this attr is in the gobject module + attr = getattr(self._module, name, None) + + # if not in module assume request for an attr exported through GI + if attr is None: + attr = super(DynamicGObjectModule, self).__getattr__(name) + + return attr + +class ModuleProxy(object): + + def __init__(self, name, namespace, dynamic_module, overrides_module): + self.__name__ = name + + self._namespace = namespace + self._dynamic_module = dynamic_module + self._overrides_module = overrides_module + + def __getattr__(self, name): + override_exports = getattr(self._overrides_module, '__all__', ()) + if (name in override_exports): + attribute = getattr(self._overrides_module, name, None) + else: + attribute = getattr(self._dynamic_module, name) + return attribute + + def __str__(self): + return "<ModuleProxy %r>" % self.__name__ + diff --git a/gi/overrides/GIMarshallingTests.py b/gi/overrides/GIMarshallingTests.py new file mode 100644 index 0000000..768efd7 --- /dev/null +++ b/gi/overrides/GIMarshallingTests.py @@ -0,0 +1,67 @@ +# -*- Mode: Python; py-indent-offset: 4 -*- +# vim: tabstop=4 shiftwidth=4 expandtab +# +# Copyright (C) 2010 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 St, Fifth Floor, Boston, MA 02110-1301 +# USA + +from ..types import override +from ..importer import modules + +GIMarshallingTests = modules['GIMarshallingTests'] + +__all__ = [] + +OVERRIDES_CONSTANT = 7 +__all__.append('OVERRIDES_CONSTANT') + +class OverridesStruct(GIMarshallingTests.OverridesStruct): + + def __new__(cls, long_): + return GIMarshallingTests.OverridesStruct.__new__(cls) + + def __init__(self, long_): + GIMarshallingTests.OverridesStruct.__init__(self) + self.long_ = long_ + + def method(self): + return GIMarshallingTests.OverridesStruct.method(self) / 7 + +OverridesStruct = override(OverridesStruct) +__all__.append('OverridesStruct') + +class OverridesObject(GIMarshallingTests.OverridesObject): + + def __new__(cls, long_): + return GIMarshallingTests.OverridesObject.__new__(cls) + + def __init__(self, long_): + GIMarshallingTests.OverridesObject.__init__(self) + # FIXME: doesn't work yet + #self.long_ = long_ + + @classmethod + def new(cls, long_): + self = GIMarshallingTests.OverridesObject.new() + # FIXME: doesn't work yet + #self.long_ = long_ + return self + + def method(self): + return GIMarshallingTests.OverridesObject.method(self) / 7 + +OverridesObject = override(OverridesObject) +__all__.append('OverridesObject') diff --git a/gi/overrides/Gdk.py b/gi/overrides/Gdk.py new file mode 100644 index 0000000..34d3a10 --- /dev/null +++ b/gi/overrides/Gdk.py @@ -0,0 +1,77 @@ +# -*- Mode: Python; py-indent-offset: 4 -*- +# vim: tabstop=4 shiftwidth=4 expandtab +# +# Copyright (C) 2009 Johan Dahlin <johan@gnome.org> +# 2010 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 St, Fifth Floor, Boston, MA 02110-1301 +# USA + +from ..types import override +from ..importer import modules + +Gdk = modules['Gdk'] + +__all__ = [] + +class Rectangle(Gdk.Rectangle): + + def __init__(self, x, y, width, height): + Gdk.Rectangle.__init__(self) + self.x = x + self.y = y + self.width = width + self.height = height + + def __new__(cls, *args, **kwargs): + return Gdk.Rectangle.__new__(cls) + + def __repr__(self): + return '<Gdk.Rectangle(x=%d, y=%d, width=%d, height=%d)>' % ( + self.x, self.y, self.width, self.height) + +Rectangle = override(Rectangle) +__all__.append('Rectangle') + +class Color(Gdk.Color): + + def __init__(self, red, green, blue): + Gdk.Color.__init__(self) + self.red = red + self.green = green + self.blue = blue + + def __new__(cls, *args, **kwargs): + return Gdk.Color.__new__(cls) + + def __repr__(self): + return '<Gdk.Color(red=%d, green=%d, blue=%d)>' % (self.red, self.green, self.blue) + +Color = override(Color) +__all__.append('Color') + +class Drawable(Gdk.Drawable): + def cairo_create(self): + return Gdk.cairo_create(self) + +Drawable = override(Drawable) +__all__.append('Drawable') + + +import sys + +initialized, argv = Gdk.init_check(sys.argv) +if not initialized: + raise RuntimeError("Gdk couldn't be initialized") diff --git a/gi/overrides/Gtk.py b/gi/overrides/Gtk.py new file mode 100644 index 0000000..0c3dcc5 --- /dev/null +++ b/gi/overrides/Gtk.py @@ -0,0 +1,407 @@ +# -*- Mode: Python; py-indent-offset: 4 -*- +# vim: tabstop=4 shiftwidth=4 expandtab +# +# Copyright (C) 2009 Johan Dahlin <johan@gnome.org> +# 2010 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 St, Fifth Floor, Boston, MA 02110-1301 +# USA + +import gobject +from gi.repository import Gdk +from gi.repository import GObject +from ..types import override +from ..importer import modules + +Gtk = modules['Gtk'] +__all__ = [] + +class ActionGroup(Gtk.ActionGroup): + def add_actions(self, entries, user_data=None): + """ + The add_actions() method is a convenience method that creates a number + of gtk.Action objects based on the information in the list of action + entry tuples contained in entries and adds them to the action group. + The entry tuples can vary in size from one to six items with the + following information: + + * The name of the action. Must be specified. + * The stock id for the action. Optional with a default value of None + if a label is specified. + * The label for the action. This field should typically be marked + for translation, see the set_translation_domain() method. Optional + with a default value of None if a stock id is specified. + * The accelerator for the action, in the format understood by the + gtk.accelerator_parse() function. Optional with a default value of + None. + * The tooltip for the action. This field should typically be marked + for translation, see the set_translation_domain() method. Optional + with a default value of None. + * The callback function invoked when the action is activated. + Optional with a default value of None. + + The "activate" signals of the actions are connected to the callbacks and + their accel paths are set to <Actions>/group-name/action-name. + """ + try: + iter(entries) + except (TypeError): + raise TypeError('entries must be iterable') + + def _process_action(name, stock_id=None, label=None, accelerator=None, tooltip=None, callback=None): + action = Gtk.Action(name=name, label=label, tooltip=tooltip, stock_id=stock_id) + if callback is not None: + action.connect('activate', callback, user_data) + + self.add_action_with_accel(action, accelerator) + + for e in entries: + # using inner function above since entries can leave out optional arguments + _process_action(*e) + + def add_toggle_actions(self, entries, user_data=None): + """ + The add_toggle_actions() method is a convenience method that creates a + number of gtk.ToggleAction objects based on the information in the list + of action entry tuples contained in entries and adds them to the action + group. The toggle action entry tuples can vary in size from one to seven + items with the following information: + + * The name of the action. Must be specified. + * The stock id for the action. Optional with a default value of None + if a label is specified. + * The label for the action. This field should typically be marked + for translation, see the set_translation_domain() method. Optional + with a default value of None if a stock id is specified. + * The accelerator for the action, in the format understood by the + gtk.accelerator_parse() function. Optional with a default value of + None. + * The tooltip for the action. This field should typically be marked + for translation, see the set_translation_domain() method. Optional + with a default value of None. + * The callback function invoked when the action is activated. + Optional with a default value of None. + * A flag indicating whether the toggle action is active. Optional + with a default value of False. + + The "activate" signals of the actions are connected to the callbacks and + their accel paths are set to <Actions>/group-name/action-name. + """ + + try: + iter(entries) + except (TypeError): + raise TypeError('entries must be iterable') + + def _process_action(name, stock_id=None, label=None, accelerator=None, tooltip=None, callback=None, is_active=False): + action = Gtk.ToggleAction(name=name, label=label, tooltip=tooltip, stock_id=stock_id) + action.set_active(is_active) + if callback is not None: + action.connect('activate', callback, user_data) + + self.add_action_with_accel(action, accelerator) + + for e in entries: + # using inner function above since entries can leave out optional arguments + _process_action(*e) + + + def add_radio_actions(self, entries, value=None, on_change=None, user_data=None): + """ + The add_radio_actions() method is a convenience method that creates a + number of gtk.RadioAction objects based on the information in the list + of action entry tuples contained in entries and adds them to the action + group. The entry tuples can vary in size from one to six items with the + following information: + + * The name of the action. Must be specified. + * The stock id for the action. Optional with a default value of None + if a label is specified. + * The label for the action. This field should typically be marked + for translation, see the set_translation_domain() method. Optional + with a default value of None if a stock id is specified. + * The accelerator for the action, in the format understood by the + gtk.accelerator_parse() function. Optional with a default value of + None. + * The tooltip for the action. This field should typically be marked + for translation, see the set_translation_domain() method. Optional + with a default value of None. + * The value to set on the radio action. Optional with a default + value of 0. Should be specified in applications. + + The value parameter specifies the radio action that should be set + active. The "changed" signal of the first radio action is connected to + the on_change callback (if specified and not None) and the accel paths + of the actions are set to <Actions>/group-name/action-name. + """ + try: + iter(entries) + except (TypeError): + raise TypeError('entries must be iterable') + + first_action = None + + def _process_action(group_source, name, stock_id=None, label=None, accelerator=None, tooltip=None, entry_value=0): + action = Gtk.RadioAction(name=name, label=label, tooltip=tooltip, stock_id=stock_id, value=entry_value) + + # FIXME: join_group is a patch to Gtk+ 3.0 + # otherwise we can't effectively add radio actions to a + # group. Should we depend on 3.0 and error out here + # or should we offer the functionality via a compat + # C module? + if hasattr(action, 'join_group'): + action.join_group(group_source) + + if value == entry_value: + action.set_active(True) + + self.add_action_with_accel(action, accelerator) + return action + + for e in entries: + # using inner function above since entries can leave out optional arguments + action = _process_action(first_action, *e) + if first_action is None: + first_action = action + + if first_action is not None and on_change is not None: + first_action.connect('changed', on_change, user_data) + +ActionGroup = override(ActionGroup) +__all__.append('ActionGroup') + +class UIManager(Gtk.UIManager): + def add_ui_from_string(self, buffer): + if not isinstance(buffer, basestring): + raise TypeError('buffer must be a string') + + length = len(buffer) + + return Gtk.UIManager.add_ui_from_string(self, buffer, length) + +UIManager = override(UIManager) +__all__.append('UIManager') + +class Builder(Gtk.Builder): + + def connect_signals(self, obj_or_map): + def _full_callback(builder, gobj, signal_name, handler_name, connect_obj, flags, obj_or_map): + handler = None + if isinstance(obj_or_map, dict): + handler = obj_or_map.get(handler_name, None) + else: + handler = getattr(obj_or_map, handler_name, None) + + if handler is None: + raise AttributeError('Handler %s not found' % handler_name) + + if not callable(handler): + raise TypeError('Handler %s is not a method or function' % handler_name) + + after = flags or GObject.ConnectFlags.AFTER + if connect_obj is not None: + if after: + gobj.connect_object_after(signal_name, handler, connect_obj) + else: + gobj.connect_object(signal_name, handler, connect_obj) + else: + if after: + gobj.connect_after(signal_name, handler) + else: + gobj.connect(signal_name, handler) + + self.connect_signals_full(_full_callback, + obj_or_map); + + def add_from_string(self, buffer): + if not isinstance(buffer, basestring): + raise TypeError('buffer must be a string') + + length = len(buffer) + + return Gtk.Builder.add_from_string(self, buffer, length) + + def add_objects_from_string(self, buffer, object_ids): + if not isinstance(buffer, basestring): + raise TypeError('buffer must be a string') + + length = len(buffer) + + return Gtk.Builder.add_objects_from_string(self, buffer, length, object_ids) + +Builder = override(Builder) +__all__.append('Builder') + +class Dialog(Gtk.Dialog): + + def __init__(self, title=None, parent=None, flags=0, buttons=None): + Gtk.Dialog.__init__(self) + if title: + self.set_title(title) + if parent: + self.set_transient_for(parent) + if flags & Gtk.DialogFlags.MODAL: + self.set_modal(True) + if flags & Gtk.DialogFlags.DESTROY_WITH_PARENT: + self.set_destroy_with_parent(True) + if flags & Gtk.DialogFlags.NO_SEPARATOR: + self.set_has_separator(False) + if buttons: + self.add_buttons(*buttons) + + def add_buttons(self, *args): + """ + The add_buttons() method adds several buttons to the Gtk.Dialog using + the button data passed as arguments to the method. This method is the + same as calling the Gtk.Dialog.add_button() repeatedly. The button data + pairs - button text (or stock ID) and a response ID integer are passed + individually. For example: + + >>> dialog.add_buttons(Gtk.STOCK_OPEN, 42, "Close", Gtk.ResponseType.CLOSE) + + will add "Open" and "Close" buttons to dialog. + """ + + def buttons(b): + while b: + t, r = b[0:2] + b = b[2:] + yield t, r + + try: + for text, response in buttons(args): + self.add_button(text, response) + except (IndexError): + raise TypeError('Must pass an even number of arguments') + +Dialog = override(Dialog) +__all__.append('Dialog') + +class TextBuffer(Gtk.TextBuffer): + def _get_or_create_tag_table(self): + table = self.get_tag_table() + if table is None: + table = Gtk.TextTagTable() + self.set_tag_table(table) + + return table + + def create_tag(self, tag_name=None, **properties): + """ + @tag_name: name of the new tag, or None + @properties: keyword list of properties and their values + + Creates a tag and adds it to the tag table of the TextBuffer. + Equivalent to creating a Gtk.TextTag and then adding the + tag to the buffer's tag table. The returned tag is owned by + the buffer's tag table. + + If @tag_name is None, the tag is anonymous. + + If @tag_name is not None, a tag called @tag_name must not already + exist in the tag table for this buffer. + + Properties are passed as a keyword list of names and values (e.g. + foreground = 'DodgerBlue', weight = Pango.Weight.BOLD) + + Return value: a new tag + """ + + tag = Gtk.TextTag(name=tag_name, **properties) + self._get_or_create_tag_table().add(tag) + return tag + + def insert(self, iter, text): + if not isinstance(text , basestring): + raise TypeError('text must be a string, not %s' % type(text)) + + length = len(text) + Gtk.TextBuffer.insert(self, iter, text, length) + + def insert_at_cursor(self, text): + if not isinstance(text , basestring): + raise TypeError('text must be a string, not %s' % type(text)) + + length = len(text) + Gtk.TextBuffer.insert_at_cursor(self, text, length) + +TextBuffer = override(TextBuffer) +__all__.append('TextBuffer') + +class ListStore(Gtk.ListStore): + def __init__(self, *column_types): + Gtk.ListStore.__init__(self) + self.set_column_types(column_types) + + def append(self, row): + treeiter = Gtk.TreeIter() + Gtk.ListStore.append(self, treeiter) + + n_columns = self.get_n_columns(); + if len(row) != n_columns: + raise ValueError('row sequence has the incorrect number of elements') + + for i in range(n_columns): + if row[i] is not None: + self.set_value(treeiter, i, row[i]) + + return treeiter + +ListStore = override(ListStore) +__all__.append('ListStore') + +class TreeStore(Gtk.TreeStore): + + def __init__(self, *column_types): + Gtk.TreeStore.__init__(self) + self.set_column_types(column_types) + + def append(self, parent, row): + treeiter = Gtk.TreeIter() + Gtk.TreeStore.append(self, treeiter, parent) + + n_columns = self.get_n_columns(); + if len(row) != n_columns: + raise ValueError('row sequence has the incorrect number of elements') + + for i in xrange(n_columns): + if row[i] is not None: + self.set_value(treeiter, i, row[i]) + + return treeiter + +TreeStore = override(TreeStore) +__all__.append('TreeStore') + +class TreeViewColumn(Gtk.TreeViewColumn): + def __init__(self, title='', + cell_renderer=None, + **attributes): + Gtk.TreeViewColumn.__init__(self, title=title) + if cell_renderer: + self.pack_start(cell_renderer, True) + + for (name, value) in attributes.iteritems(): + self.add_attribute(cell_renderer, name, value) + +TreeViewColumn = override(TreeViewColumn) +__all__.append('TreeViewColumn') + +import sys + +initialized, argv = Gtk.init_check(sys.argv) +sys.argv = list(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..62f6457 --- /dev/null +++ b/gi/overrides/Makefile.am @@ -0,0 +1,12 @@ +PLATFORM_VERSION = 2.0 + +pkgpyexecdir = $(pyexecdir)/gtk-2.0/gi + +pygioverridesdir = $(pkgpyexecdir)/overrides +pygioverrides_PYTHON = \ + Gtk.py \ + Gdk.py \ + GIMarshallingTests.py \ + keysyms.py \ + __init__.py + diff --git a/gi/overrides/Makefile.in b/gi/overrides/Makefile.in new file mode 100644 index 0000000..3c3d18e --- /dev/null +++ b/gi/overrides/Makefile.in @@ -0,0 +1,473 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = gi/overrides +DIST_COMMON = $(pygioverrides_PYTHON) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/as-ac-expand.m4 \ + $(top_srcdir)/m4/jhflags.m4 $(top_srcdir)/m4/python.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +AM_V_GEN = $(am__v_GEN_$(V)) +am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) +am__v_GEN_0 = @echo " GEN " $@; +AM_V_at = $(am__v_at_$(V)) +am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY)) +am__v_at_0 = @ +SOURCES = +DIST_SOURCES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__installdirs = "$(DESTDIR)$(pygioverridesdir)" +py_compile = $(top_srcdir)/py-compile +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ACLOCAL_AMFLAGS = @ACLOCAL_AMFLAGS@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DATADIR = @DATADIR@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FFI_CFLAGS = @FFI_CFLAGS@ +FFI_LIBS = @FFI_LIBS@ +FGREP = @FGREP@ +GIOUNIX_CFLAGS = @GIOUNIX_CFLAGS@ +GIOUNIX_LIBS = @GIOUNIX_LIBS@ +GIO_CFLAGS = @GIO_CFLAGS@ +GIO_LIBS = @GIO_LIBS@ +GI_CFLAGS = @GI_CFLAGS@ +GI_LIBS = @GI_LIBS@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ +GLIB_LIBS = @GLIB_LIBS@ +GLIB_MKENUMS = @GLIB_MKENUMS@ +GOBJECT_QUERY = @GOBJECT_QUERY@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@ +INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBFFI_PC = @LIBFFI_PC@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PLATFORM = @PLATFORM@ +PYCAIRO_CFLAGS = @PYCAIRO_CFLAGS@ +PYCAIRO_LIBS = @PYCAIRO_LIBS@ +PYGOBJECT_MAJOR_VERSION = @PYGOBJECT_MAJOR_VERSION@ +PYGOBJECT_MICRO_VERSION = @PYGOBJECT_MICRO_VERSION@ +PYGOBJECT_MINOR_VERSION = @PYGOBJECT_MINOR_VERSION@ +PYTHON = @PYTHON@ +PYTHON_BASENAME = @PYTHON_BASENAME@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_INCLUDES = @PYTHON_INCLUDES@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +THREADING_CFLAGS = @THREADING_CFLAGS@ +VERSION = @VERSION@ +XSLTPROC = @XSLTPROC@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +lt_ECHO = @lt_ECHO@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +pkgpyexecdir = $(pyexecdir)/gtk-2.0/gi +pkgpythondir = @pkgpythondir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pyexecdir = @pyexecdir@ +pygobject_CODEGEN_DEFINES = @pygobject_CODEGEN_DEFINES@ +pythondir = @pythondir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +PLATFORM_VERSION = 2.0 +pygioverridesdir = $(pkgpyexecdir)/overrides +pygioverrides_PYTHON = \ + Gtk.py \ + Gdk.py \ + GIMarshallingTests.py \ + keysyms.py \ + __init__.py + +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign gi/overrides/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign gi/overrides/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +mostlyclean-libtool: + -rm -f *.lo + +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=; \ + for p in $$list; do \ + if test -f "$$p"; then b=; else b="$(srcdir)/"; fi; \ + if test -f $$b$$p; then \ + $(am__strip_dir) \ + dlist="$$dlist $$f"; \ + list2="$$list2 $$b$$p"; \ + else :; fi; \ + done; \ + for file in $$list2; do echo $$file; done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pygioverridesdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(pygioverridesdir)" || exit $$?; \ + done || exit $$?; \ + if test -n "$$dlist"; then \ + if test -z "$(DESTDIR)"; then \ + PYTHON=$(PYTHON) $(py_compile) --basedir "$(pygioverridesdir)" $$dlist; \ + else \ + PYTHON=$(PYTHON) $(py_compile) --destdir "$(DESTDIR)" --basedir "$(pygioverridesdir)" $$dlist; \ + fi; \ + else :; fi + +uninstall-pygioverridesPYTHON: + @$(NORMAL_UNINSTALL) + @list='$(pygioverrides_PYTHON)'; test -n "$(pygioverridesdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + test -n "$$files" || exit 0; \ + filesc=`echo "$$files" | sed 's|$$|c|'`; \ + fileso=`echo "$$files" | sed 's|$$|o|'`; \ + echo " ( cd '$(DESTDIR)$(pygioverridesdir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(pygioverridesdir)" && rm -f $$files || exit $$?; \ + echo " ( cd '$(DESTDIR)$(pygioverridesdir)' && rm -f" $$filesc ")"; \ + cd "$(DESTDIR)$(pygioverridesdir)" && rm -f $$filesc || exit $$?; \ + echo " ( cd '$(DESTDIR)$(pygioverridesdir)' && rm -f" $$fileso ")"; \ + cd "$(DESTDIR)$(pygioverridesdir)" && rm -f $$fileso +tags: TAGS +TAGS: + +ctags: CTAGS +CTAGS: + + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile +installdirs: + for dir in "$(DESTDIR)$(pygioverridesdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-pygioverridesPYTHON + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-pygioverridesPYTHON + +.MAKE: install-am install-strip + +.PHONY: all all-am check check-am clean clean-generic clean-libtool \ + distclean distclean-generic distclean-libtool distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-ps install-ps-am \ + install-pygioverridesPYTHON install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am uninstall uninstall-am \ + uninstall-pygioverridesPYTHON + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: 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/overrides/keysyms.py b/gi/overrides/keysyms.py new file mode 100644 index 0000000..35ee8eb --- /dev/null +++ b/gi/overrides/keysyms.py @@ -0,0 +1,1499 @@ +# -*- Mode: Python; py-indent-offset: 4 -*- +# pygtk - Python bindings for the GTK toolkit. +# Copyright (C) 1998-2003 James Henstridge +# +# gtk/keysyms.py: list of keysyms. +# +# 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 + +VoidSymbol = 0xFFFFFF +BackSpace = 0xFF08 +Tab = 0xFF09 +Linefeed = 0xFF0A +Clear = 0xFF0B +Return = 0xFF0D +Pause = 0xFF13 +Scroll_Lock = 0xFF14 +Sys_Req = 0xFF15 +Escape = 0xFF1B +Delete = 0xFFFF +Multi_key = 0xFF20 +Codeinput = 0xFF37 +SingleCandidate = 0xFF3C +MultipleCandidate = 0xFF3D +PreviousCandidate = 0xFF3E +Kanji = 0xFF21 +Muhenkan = 0xFF22 +Henkan_Mode = 0xFF23 +Henkan = 0xFF23 +Romaji = 0xFF24 +Hiragana = 0xFF25 +Katakana = 0xFF26 +Hiragana_Katakana = 0xFF27 +Zenkaku = 0xFF28 +Hankaku = 0xFF29 +Zenkaku_Hankaku = 0xFF2A +Touroku = 0xFF2B +Massyo = 0xFF2C +Kana_Lock = 0xFF2D +Kana_Shift = 0xFF2E +Eisu_Shift = 0xFF2F +Eisu_toggle = 0xFF30 +Kanji_Bangou = 0xFF37 +Zen_Koho = 0xFF3D +Mae_Koho = 0xFF3E +Home = 0xFF50 +Left = 0xFF51 +Up = 0xFF52 +Right = 0xFF53 +Down = 0xFF54 +Prior = 0xFF55 +Page_Up = 0xFF55 +Next = 0xFF56 +Page_Down = 0xFF56 +End = 0xFF57 +Begin = 0xFF58 +Select = 0xFF60 +Print = 0xFF61 +Execute = 0xFF62 +Insert = 0xFF63 +Undo = 0xFF65 +Redo = 0xFF66 +Menu = 0xFF67 +Find = 0xFF68 +Cancel = 0xFF69 +Help = 0xFF6A +Break = 0xFF6B +Mode_switch = 0xFF7E +script_switch = 0xFF7E +Num_Lock = 0xFF7F +KP_Space = 0xFF80 +KP_Tab = 0xFF89 +KP_Enter = 0xFF8D +KP_F1 = 0xFF91 +KP_F2 = 0xFF92 +KP_F3 = 0xFF93 +KP_F4 = 0xFF94 +KP_Home = 0xFF95 +KP_Left = 0xFF96 +KP_Up = 0xFF97 +KP_Right = 0xFF98 +KP_Down = 0xFF99 +KP_Prior = 0xFF9A +KP_Page_Up = 0xFF9A +KP_Next = 0xFF9B +KP_Page_Down = 0xFF9B +KP_End = 0xFF9C +KP_Begin = 0xFF9D +KP_Insert = 0xFF9E +KP_Delete = 0xFF9F +KP_Equal = 0xFFBD +KP_Multiply = 0xFFAA +KP_Add = 0xFFAB +KP_Separator = 0xFFAC +KP_Subtract = 0xFFAD +KP_Decimal = 0xFFAE +KP_Divide = 0xFFAF +KP_0 = 0xFFB0 +KP_1 = 0xFFB1 +KP_2 = 0xFFB2 +KP_3 = 0xFFB3 +KP_4 = 0xFFB4 +KP_5 = 0xFFB5 +KP_6 = 0xFFB6 +KP_7 = 0xFFB7 +KP_8 = 0xFFB8 +KP_9 = 0xFFB9 +F1 = 0xFFBE +F2 = 0xFFBF +F3 = 0xFFC0 +F4 = 0xFFC1 +F5 = 0xFFC2 +F6 = 0xFFC3 +F7 = 0xFFC4 +F8 = 0xFFC5 +F9 = 0xFFC6 +F10 = 0xFFC7 +F11 = 0xFFC8 +L1 = 0xFFC8 +F12 = 0xFFC9 +L2 = 0xFFC9 +F13 = 0xFFCA +L3 = 0xFFCA +F14 = 0xFFCB +L4 = 0xFFCB +F15 = 0xFFCC +L5 = 0xFFCC +F16 = 0xFFCD +L6 = 0xFFCD +F17 = 0xFFCE +L7 = 0xFFCE +F18 = 0xFFCF +L8 = 0xFFCF +F19 = 0xFFD0 +L9 = 0xFFD0 +F20 = 0xFFD1 +L10 = 0xFFD1 +F21 = 0xFFD2 +R1 = 0xFFD2 +F22 = 0xFFD3 +R2 = 0xFFD3 +F23 = 0xFFD4 +R3 = 0xFFD4 +F24 = 0xFFD5 +R4 = 0xFFD5 +F25 = 0xFFD6 +R5 = 0xFFD6 +F26 = 0xFFD7 +R6 = 0xFFD7 +F27 = 0xFFD8 +R7 = 0xFFD8 +F28 = 0xFFD9 +R8 = 0xFFD9 +F29 = 0xFFDA +R9 = 0xFFDA +F30 = 0xFFDB +R10 = 0xFFDB +F31 = 0xFFDC +R11 = 0xFFDC +F32 = 0xFFDD +R12 = 0xFFDD +F33 = 0xFFDE +R13 = 0xFFDE +F34 = 0xFFDF +R14 = 0xFFDF +F35 = 0xFFE0 +R15 = 0xFFE0 +Shift_L = 0xFFE1 +Shift_R = 0xFFE2 +Control_L = 0xFFE3 +Control_R = 0xFFE4 +Caps_Lock = 0xFFE5 +Shift_Lock = 0xFFE6 +Meta_L = 0xFFE7 +Meta_R = 0xFFE8 +Alt_L = 0xFFE9 +Alt_R = 0xFFEA +Super_L = 0xFFEB +Super_R = 0xFFEC +Hyper_L = 0xFFED +Hyper_R = 0xFFEE +ISO_Lock = 0xFE01 +ISO_Level2_Latch = 0xFE02 +ISO_Level3_Shift = 0xFE03 +ISO_Level3_Latch = 0xFE04 +ISO_Level3_Lock = 0xFE05 +ISO_Group_Shift = 0xFF7E +ISO_Group_Latch = 0xFE06 +ISO_Group_Lock = 0xFE07 +ISO_Next_Group = 0xFE08 +ISO_Next_Group_Lock = 0xFE09 +ISO_Prev_Group = 0xFE0A +ISO_Prev_Group_Lock = 0xFE0B +ISO_First_Group = 0xFE0C +ISO_First_Group_Lock = 0xFE0D +ISO_Last_Group = 0xFE0E +ISO_Last_Group_Lock = 0xFE0F +ISO_Left_Tab = 0xFE20 +ISO_Move_Line_Up = 0xFE21 +ISO_Move_Line_Down = 0xFE22 +ISO_Partial_Line_Up = 0xFE23 +ISO_Partial_Line_Down = 0xFE24 +ISO_Partial_Space_Left = 0xFE25 +ISO_Partial_Space_Right = 0xFE26 +ISO_Set_Margin_Left = 0xFE27 +ISO_Set_Margin_Right = 0xFE28 +ISO_Release_Margin_Left = 0xFE29 +ISO_Release_Margin_Right = 0xFE2A +ISO_Release_Both_Margins = 0xFE2B +ISO_Fast_Cursor_Left = 0xFE2C +ISO_Fast_Cursor_Right = 0xFE2D +ISO_Fast_Cursor_Up = 0xFE2E +ISO_Fast_Cursor_Down = 0xFE2F +ISO_Continuous_Underline = 0xFE30 +ISO_Discontinuous_Underline = 0xFE31 +ISO_Emphasize = 0xFE32 +ISO_Center_Object = 0xFE33 +ISO_Enter = 0xFE34 +dead_grave = 0xFE50 +dead_acute = 0xFE51 +dead_circumflex = 0xFE52 +dead_tilde = 0xFE53 +dead_macron = 0xFE54 +dead_breve = 0xFE55 +dead_abovedot = 0xFE56 +dead_diaeresis = 0xFE57 +dead_abovering = 0xFE58 +dead_doubleacute = 0xFE59 +dead_caron = 0xFE5A +dead_cedilla = 0xFE5B +dead_ogonek = 0xFE5C +dead_iota = 0xFE5D +dead_voiced_sound = 0xFE5E +dead_semivoiced_sound = 0xFE5F +dead_belowdot = 0xFE60 +First_Virtual_Screen = 0xFED0 +Prev_Virtual_Screen = 0xFED1 +Next_Virtual_Screen = 0xFED2 +Last_Virtual_Screen = 0xFED4 +Terminate_Server = 0xFED5 +AccessX_Enable = 0xFE70 +AccessX_Feedback_Enable = 0xFE71 +RepeatKeys_Enable = 0xFE72 +SlowKeys_Enable = 0xFE73 +BounceKeys_Enable = 0xFE74 +StickyKeys_Enable = 0xFE75 +MouseKeys_Enable = 0xFE76 +MouseKeys_Accel_Enable = 0xFE77 +Overlay1_Enable = 0xFE78 +Overlay2_Enable = 0xFE79 +AudibleBell_Enable = 0xFE7A +Pointer_Left = 0xFEE0 +Pointer_Right = 0xFEE1 +Pointer_Up = 0xFEE2 +Pointer_Down = 0xFEE3 +Pointer_UpLeft = 0xFEE4 +Pointer_UpRight = 0xFEE5 +Pointer_DownLeft = 0xFEE6 +Pointer_DownRight = 0xFEE7 +Pointer_Button_Dflt = 0xFEE8 +Pointer_Button1 = 0xFEE9 +Pointer_Button2 = 0xFEEA +Pointer_Button3 = 0xFEEB +Pointer_Button4 = 0xFEEC +Pointer_Button5 = 0xFEED +Pointer_DblClick_Dflt = 0xFEEE +Pointer_DblClick1 = 0xFEEF +Pointer_DblClick2 = 0xFEF0 +Pointer_DblClick3 = 0xFEF1 +Pointer_DblClick4 = 0xFEF2 +Pointer_DblClick5 = 0xFEF3 +Pointer_Drag_Dflt = 0xFEF4 +Pointer_Drag1 = 0xFEF5 +Pointer_Drag2 = 0xFEF6 +Pointer_Drag3 = 0xFEF7 +Pointer_Drag4 = 0xFEF8 +Pointer_Drag5 = 0xFEFD +Pointer_EnableKeys = 0xFEF9 +Pointer_Accelerate = 0xFEFA +Pointer_DfltBtnNext = 0xFEFB +Pointer_DfltBtnPrev = 0xFEFC +_3270_Duplicate = 0xFD01 +_3270_FieldMark = 0xFD02 +_3270_Right2 = 0xFD03 +_3270_Left2 = 0xFD04 +_3270_BackTab = 0xFD05 +_3270_EraseEOF = 0xFD06 +_3270_EraseInput = 0xFD07 +_3270_Reset = 0xFD08 +_3270_Quit = 0xFD09 +_3270_PA1 = 0xFD0A +_3270_PA2 = 0xFD0B +_3270_PA3 = 0xFD0C +_3270_Test = 0xFD0D +_3270_Attn = 0xFD0E +_3270_CursorBlink = 0xFD0F +_3270_AltCursor = 0xFD10 +_3270_KeyClick = 0xFD11 +_3270_Jump = 0xFD12 +_3270_Ident = 0xFD13 +_3270_Rule = 0xFD14 +_3270_Copy = 0xFD15 +_3270_Play = 0xFD16 +_3270_Setup = 0xFD17 +_3270_Record = 0xFD18 +_3270_ChangeScreen = 0xFD19 +_3270_DeleteWord = 0xFD1A +_3270_ExSelect = 0xFD1B +_3270_CursorSelect = 0xFD1C +_3270_PrintScreen = 0xFD1D +_3270_Enter = 0xFD1E +space = 0x020 +exclam = 0x021 +quotedbl = 0x022 +numbersign = 0x023 +dollar = 0x024 +percent = 0x025 +ampersand = 0x026 +apostrophe = 0x027 +quoteright = 0x027 +parenleft = 0x028 +parenright = 0x029 +asterisk = 0x02a +plus = 0x02b +comma = 0x02c +minus = 0x02d +period = 0x02e +slash = 0x02f +_0 = 0x030 +_1 = 0x031 +_2 = 0x032 +_3 = 0x033 +_4 = 0x034 +_5 = 0x035 +_6 = 0x036 +_7 = 0x037 +_8 = 0x038 +_9 = 0x039 +colon = 0x03a +semicolon = 0x03b +less = 0x03c +equal = 0x03d +greater = 0x03e +question = 0x03f +at = 0x040 +A = 0x041 +B = 0x042 +C = 0x043 +D = 0x044 +E = 0x045 +F = 0x046 +G = 0x047 +H = 0x048 +I = 0x049 +J = 0x04a +K = 0x04b +L = 0x04c +M = 0x04d +N = 0x04e +O = 0x04f +P = 0x050 +Q = 0x051 +R = 0x052 +S = 0x053 +T = 0x054 +U = 0x055 +V = 0x056 +W = 0x057 +X = 0x058 +Y = 0x059 +Z = 0x05a +bracketleft = 0x05b +backslash = 0x05c +bracketright = 0x05d +asciicircum = 0x05e +underscore = 0x05f +grave = 0x060 +quoteleft = 0x060 +a = 0x061 +b = 0x062 +c = 0x063 +d = 0x064 +e = 0x065 +f = 0x066 +g = 0x067 +h = 0x068 +i = 0x069 +j = 0x06a +k = 0x06b +l = 0x06c +m = 0x06d +n = 0x06e +o = 0x06f +p = 0x070 +q = 0x071 +r = 0x072 +s = 0x073 +t = 0x074 +u = 0x075 +v = 0x076 +w = 0x077 +x = 0x078 +y = 0x079 +z = 0x07a +braceleft = 0x07b +bar = 0x07c +braceright = 0x07d +asciitilde = 0x07e +nobreakspace = 0x0a0 +exclamdown = 0x0a1 +cent = 0x0a2 +sterling = 0x0a3 +currency = 0x0a4 +yen = 0x0a5 +brokenbar = 0x0a6 +section = 0x0a7 +diaeresis = 0x0a8 +copyright = 0x0a9 +ordfeminine = 0x0aa +guillemotleft = 0x0ab +notsign = 0x0ac +hyphen = 0x0ad +registered = 0x0ae +macron = 0x0af +degree = 0x0b0 +plusminus = 0x0b1 +twosuperior = 0x0b2 +threesuperior = 0x0b3 +acute = 0x0b4 +mu = 0x0b5 +paragraph = 0x0b6 +periodcentered = 0x0b7 +cedilla = 0x0b8 +onesuperior = 0x0b9 +masculine = 0x0ba +guillemotright = 0x0bb +onequarter = 0x0bc +onehalf = 0x0bd +threequarters = 0x0be +questiondown = 0x0bf +Agrave = 0x0c0 +Aacute = 0x0c1 +Acircumflex = 0x0c2 +Atilde = 0x0c3 +Adiaeresis = 0x0c4 +Aring = 0x0c5 +AE = 0x0c6 +Ccedilla = 0x0c7 +Egrave = 0x0c8 +Eacute = 0x0c9 +Ecircumflex = 0x0ca +Ediaeresis = 0x0cb +Igrave = 0x0cc +Iacute = 0x0cd +Icircumflex = 0x0ce +Idiaeresis = 0x0cf +ETH = 0x0d0 +Eth = 0x0d0 +Ntilde = 0x0d1 +Ograve = 0x0d2 +Oacute = 0x0d3 +Ocircumflex = 0x0d4 +Otilde = 0x0d5 +Odiaeresis = 0x0d6 +multiply = 0x0d7 +Ooblique = 0x0d8 +Ugrave = 0x0d9 +Uacute = 0x0da +Ucircumflex = 0x0db +Udiaeresis = 0x0dc +Yacute = 0x0dd +THORN = 0x0de +Thorn = 0x0de +ssharp = 0x0df +agrave = 0x0e0 +aacute = 0x0e1 +acircumflex = 0x0e2 +atilde = 0x0e3 +adiaeresis = 0x0e4 +aring = 0x0e5 +ae = 0x0e6 +ccedilla = 0x0e7 +egrave = 0x0e8 +eacute = 0x0e9 +ecircumflex = 0x0ea +ediaeresis = 0x0eb +igrave = 0x0ec +iacute = 0x0ed +icircumflex = 0x0ee +idiaeresis = 0x0ef +eth = 0x0f0 +ntilde = 0x0f1 +ograve = 0x0f2 +oacute = 0x0f3 +ocircumflex = 0x0f4 +otilde = 0x0f5 +odiaeresis = 0x0f6 +division = 0x0f7 +oslash = 0x0f8 +ugrave = 0x0f9 +uacute = 0x0fa +ucircumflex = 0x0fb +udiaeresis = 0x0fc +yacute = 0x0fd +thorn = 0x0fe +ydiaeresis = 0x0ff +Aogonek = 0x1a1 +breve = 0x1a2 +Lstroke = 0x1a3 +Lcaron = 0x1a5 +Sacute = 0x1a6 +Scaron = 0x1a9 +Scedilla = 0x1aa +Tcaron = 0x1ab +Zacute = 0x1ac +Zcaron = 0x1ae +Zabovedot = 0x1af +aogonek = 0x1b1 +ogonek = 0x1b2 +lstroke = 0x1b3 +lcaron = 0x1b5 +sacute = 0x1b6 +caron = 0x1b7 +scaron = 0x1b9 +scedilla = 0x1ba +tcaron = 0x1bb +zacute = 0x1bc +doubleacute = 0x1bd +zcaron = 0x1be +zabovedot = 0x1bf +Racute = 0x1c0 +Abreve = 0x1c3 +Lacute = 0x1c5 +Cacute = 0x1c6 +Ccaron = 0x1c8 +Eogonek = 0x1ca +Ecaron = 0x1cc +Dcaron = 0x1cf +Dstroke = 0x1d0 +Nacute = 0x1d1 +Ncaron = 0x1d2 +Odoubleacute = 0x1d5 +Rcaron = 0x1d8 +Uring = 0x1d9 +Udoubleacute = 0x1db +Tcedilla = 0x1de +racute = 0x1e0 +abreve = 0x1e3 +lacute = 0x1e5 +cacute = 0x1e6 +ccaron = 0x1e8 +eogonek = 0x1ea +ecaron = 0x1ec +dcaron = 0x1ef +dstroke = 0x1f0 +nacute = 0x1f1 +ncaron = 0x1f2 +odoubleacute = 0x1f5 +udoubleacute = 0x1fb +rcaron = 0x1f8 +uring = 0x1f9 +tcedilla = 0x1fe +abovedot = 0x1ff +Hstroke = 0x2a1 +Hcircumflex = 0x2a6 +Iabovedot = 0x2a9 +Gbreve = 0x2ab +Jcircumflex = 0x2ac +hstroke = 0x2b1 +hcircumflex = 0x2b6 +idotless = 0x2b9 +gbreve = 0x2bb +jcircumflex = 0x2bc +Cabovedot = 0x2c5 +Ccircumflex = 0x2c6 +Gabovedot = 0x2d5 +Gcircumflex = 0x2d8 +Ubreve = 0x2dd +Scircumflex = 0x2de +cabovedot = 0x2e5 +ccircumflex = 0x2e6 +gabovedot = 0x2f5 +gcircumflex = 0x2f8 +ubreve = 0x2fd +scircumflex = 0x2fe +kra = 0x3a2 +kappa = 0x3a2 +Rcedilla = 0x3a3 +Itilde = 0x3a5 +Lcedilla = 0x3a6 +Emacron = 0x3aa +Gcedilla = 0x3ab +Tslash = 0x3ac +rcedilla = 0x3b3 +itilde = 0x3b5 +lcedilla = 0x3b6 +emacron = 0x3ba +gcedilla = 0x3bb +tslash = 0x3bc +ENG = 0x3bd +eng = 0x3bf +Amacron = 0x3c0 +Iogonek = 0x3c7 +Eabovedot = 0x3cc +Imacron = 0x3cf +Ncedilla = 0x3d1 +Omacron = 0x3d2 +Kcedilla = 0x3d3 +Uogonek = 0x3d9 +Utilde = 0x3dd +Umacron = 0x3de +amacron = 0x3e0 +iogonek = 0x3e7 +eabovedot = 0x3ec +imacron = 0x3ef +ncedilla = 0x3f1 +omacron = 0x3f2 +kcedilla = 0x3f3 +uogonek = 0x3f9 +utilde = 0x3fd +umacron = 0x3fe +OE = 0x13bc +oe = 0x13bd +Ydiaeresis = 0x13be +overline = 0x47e +kana_fullstop = 0x4a1 +kana_openingbracket = 0x4a2 +kana_closingbracket = 0x4a3 +kana_comma = 0x4a4 +kana_conjunctive = 0x4a5 +kana_middledot = 0x4a5 +kana_WO = 0x4a6 +kana_a = 0x4a7 +kana_i = 0x4a8 +kana_u = 0x4a9 +kana_e = 0x4aa +kana_o = 0x4ab +kana_ya = 0x4ac +kana_yu = 0x4ad +kana_yo = 0x4ae +kana_tsu = 0x4af +kana_tu = 0x4af +prolongedsound = 0x4b0 +kana_A = 0x4b1 +kana_I = 0x4b2 +kana_U = 0x4b3 +kana_E = 0x4b4 +kana_O = 0x4b5 +kana_KA = 0x4b6 +kana_KI = 0x4b7 +kana_KU = 0x4b8 +kana_KE = 0x4b9 +kana_KO = 0x4ba +kana_SA = 0x4bb +kana_SHI = 0x4bc +kana_SU = 0x4bd +kana_SE = 0x4be +kana_SO = 0x4bf +kana_TA = 0x4c0 +kana_CHI = 0x4c1 +kana_TI = 0x4c1 +kana_TSU = 0x4c2 +kana_TU = 0x4c2 +kana_TE = 0x4c3 +kana_TO = 0x4c4 +kana_NA = 0x4c5 +kana_NI = 0x4c6 +kana_NU = 0x4c7 +kana_NE = 0x4c8 +kana_NO = 0x4c9 +kana_HA = 0x4ca +kana_HI = 0x4cb +kana_FU = 0x4cc +kana_HU = 0x4cc +kana_HE = 0x4cd +kana_HO = 0x4ce +kana_MA = 0x4cf +kana_MI = 0x4d0 +kana_MU = 0x4d1 +kana_ME = 0x4d2 +kana_MO = 0x4d3 +kana_YA = 0x4d4 +kana_YU = 0x4d5 +kana_YO = 0x4d6 +kana_RA = 0x4d7 +kana_RI = 0x4d8 +kana_RU = 0x4d9 +kana_RE = 0x4da +kana_RO = 0x4db +kana_WA = 0x4dc +kana_N = 0x4dd +voicedsound = 0x4de +semivoicedsound = 0x4df +kana_switch = 0xFF7E +Arabic_comma = 0x5ac +Arabic_semicolon = 0x5bb +Arabic_question_mark = 0x5bf +Arabic_hamza = 0x5c1 +Arabic_maddaonalef = 0x5c2 +Arabic_hamzaonalef = 0x5c3 +Arabic_hamzaonwaw = 0x5c4 +Arabic_hamzaunderalef = 0x5c5 +Arabic_hamzaonyeh = 0x5c6 +Arabic_alef = 0x5c7 +Arabic_beh = 0x5c8 +Arabic_tehmarbuta = 0x5c9 +Arabic_teh = 0x5ca +Arabic_theh = 0x5cb +Arabic_jeem = 0x5cc +Arabic_hah = 0x5cd +Arabic_khah = 0x5ce +Arabic_dal = 0x5cf +Arabic_thal = 0x5d0 +Arabic_ra = 0x5d1 +Arabic_zain = 0x5d2 +Arabic_seen = 0x5d3 +Arabic_sheen = 0x5d4 +Arabic_sad = 0x5d5 +Arabic_dad = 0x5d6 +Arabic_tah = 0x5d7 +Arabic_zah = 0x5d8 +Arabic_ain = 0x5d9 +Arabic_ghain = 0x5da +Arabic_tatweel = 0x5e0 +Arabic_feh = 0x5e1 +Arabic_qaf = 0x5e2 +Arabic_kaf = 0x5e3 +Arabic_lam = 0x5e4 +Arabic_meem = 0x5e5 +Arabic_noon = 0x5e6 +Arabic_ha = 0x5e7 +Arabic_heh = 0x5e7 +Arabic_waw = 0x5e8 +Arabic_alefmaksura = 0x5e9 +Arabic_yeh = 0x5ea +Arabic_fathatan = 0x5eb +Arabic_dammatan = 0x5ec +Arabic_kasratan = 0x5ed +Arabic_fatha = 0x5ee +Arabic_damma = 0x5ef +Arabic_kasra = 0x5f0 +Arabic_shadda = 0x5f1 +Arabic_sukun = 0x5f2 +Arabic_switch = 0xFF7E +Serbian_dje = 0x6a1 +Macedonia_gje = 0x6a2 +Cyrillic_io = 0x6a3 +Ukrainian_ie = 0x6a4 +Ukranian_je = 0x6a4 +Macedonia_dse = 0x6a5 +Ukrainian_i = 0x6a6 +Ukranian_i = 0x6a6 +Ukrainian_yi = 0x6a7 +Ukranian_yi = 0x6a7 +Cyrillic_je = 0x6a8 +Serbian_je = 0x6a8 +Cyrillic_lje = 0x6a9 +Serbian_lje = 0x6a9 +Cyrillic_nje = 0x6aa +Serbian_nje = 0x6aa +Serbian_tshe = 0x6ab +Macedonia_kje = 0x6ac +Ukrainian_ghe_with_upturn = 0x6ad +Byelorussian_shortu = 0x6ae +Cyrillic_dzhe = 0x6af +Serbian_dze = 0x6af +numerosign = 0x6b0 +Serbian_DJE = 0x6b1 +Macedonia_GJE = 0x6b2 +Cyrillic_IO = 0x6b3 +Ukrainian_IE = 0x6b4 +Ukranian_JE = 0x6b4 +Macedonia_DSE = 0x6b5 +Ukrainian_I = 0x6b6 +Ukranian_I = 0x6b6 +Ukrainian_YI = 0x6b7 +Ukranian_YI = 0x6b7 +Cyrillic_JE = 0x6b8 +Serbian_JE = 0x6b8 +Cyrillic_LJE = 0x6b9 +Serbian_LJE = 0x6b9 +Cyrillic_NJE = 0x6ba +Serbian_NJE = 0x6ba +Serbian_TSHE = 0x6bb +Macedonia_KJE = 0x6bc +Ukrainian_GHE_WITH_UPTURN = 0x6bd +Byelorussian_SHORTU = 0x6be +Cyrillic_DZHE = 0x6bf +Serbian_DZE = 0x6bf +Cyrillic_yu = 0x6c0 +Cyrillic_a = 0x6c1 +Cyrillic_be = 0x6c2 +Cyrillic_tse = 0x6c3 +Cyrillic_de = 0x6c4 +Cyrillic_ie = 0x6c5 +Cyrillic_ef = 0x6c6 +Cyrillic_ghe = 0x6c7 +Cyrillic_ha = 0x6c8 +Cyrillic_i = 0x6c9 +Cyrillic_shorti = 0x6ca +Cyrillic_ka = 0x6cb +Cyrillic_el = 0x6cc +Cyrillic_em = 0x6cd +Cyrillic_en = 0x6ce +Cyrillic_o = 0x6cf +Cyrillic_pe = 0x6d0 +Cyrillic_ya = 0x6d1 +Cyrillic_er = 0x6d2 +Cyrillic_es = 0x6d3 +Cyrillic_te = 0x6d4 +Cyrillic_u = 0x6d5 +Cyrillic_zhe = 0x6d6 +Cyrillic_ve = 0x6d7 +Cyrillic_softsign = 0x6d8 +Cyrillic_yeru = 0x6d9 +Cyrillic_ze = 0x6da +Cyrillic_sha = 0x6db +Cyrillic_e = 0x6dc +Cyrillic_shcha = 0x6dd +Cyrillic_che = 0x6de +Cyrillic_hardsign = 0x6df +Cyrillic_YU = 0x6e0 +Cyrillic_A = 0x6e1 +Cyrillic_BE = 0x6e2 +Cyrillic_TSE = 0x6e3 +Cyrillic_DE = 0x6e4 +Cyrillic_IE = 0x6e5 +Cyrillic_EF = 0x6e6 +Cyrillic_GHE = 0x6e7 +Cyrillic_HA = 0x6e8 +Cyrillic_I = 0x6e9 +Cyrillic_SHORTI = 0x6ea +Cyrillic_KA = 0x6eb +Cyrillic_EL = 0x6ec +Cyrillic_EM = 0x6ed +Cyrillic_EN = 0x6ee +Cyrillic_O = 0x6ef +Cyrillic_PE = 0x6f0 +Cyrillic_YA = 0x6f1 +Cyrillic_ER = 0x6f2 +Cyrillic_ES = 0x6f3 +Cyrillic_TE = 0x6f4 +Cyrillic_U = 0x6f5 +Cyrillic_ZHE = 0x6f6 +Cyrillic_VE = 0x6f7 +Cyrillic_SOFTSIGN = 0x6f8 +Cyrillic_YERU = 0x6f9 +Cyrillic_ZE = 0x6fa +Cyrillic_SHA = 0x6fb +Cyrillic_E = 0x6fc +Cyrillic_SHCHA = 0x6fd +Cyrillic_CHE = 0x6fe +Cyrillic_HARDSIGN = 0x6ff +Greek_ALPHAaccent = 0x7a1 +Greek_EPSILONaccent = 0x7a2 +Greek_ETAaccent = 0x7a3 +Greek_IOTAaccent = 0x7a4 +Greek_IOTAdiaeresis = 0x7a5 +Greek_OMICRONaccent = 0x7a7 +Greek_UPSILONaccent = 0x7a8 +Greek_UPSILONdieresis = 0x7a9 +Greek_OMEGAaccent = 0x7ab +Greek_accentdieresis = 0x7ae +Greek_horizbar = 0x7af +Greek_alphaaccent = 0x7b1 +Greek_epsilonaccent = 0x7b2 +Greek_etaaccent = 0x7b3 +Greek_iotaaccent = 0x7b4 +Greek_iotadieresis = 0x7b5 +Greek_iotaaccentdieresis = 0x7b6 +Greek_omicronaccent = 0x7b7 +Greek_upsilonaccent = 0x7b8 +Greek_upsilondieresis = 0x7b9 +Greek_upsilonaccentdieresis = 0x7ba +Greek_omegaaccent = 0x7bb +Greek_ALPHA = 0x7c1 +Greek_BETA = 0x7c2 +Greek_GAMMA = 0x7c3 +Greek_DELTA = 0x7c4 +Greek_EPSILON = 0x7c5 +Greek_ZETA = 0x7c6 +Greek_ETA = 0x7c7 +Greek_THETA = 0x7c8 +Greek_IOTA = 0x7c9 +Greek_KAPPA = 0x7ca +Greek_LAMDA = 0x7cb +Greek_LAMBDA = 0x7cb +Greek_MU = 0x7cc +Greek_NU = 0x7cd +Greek_XI = 0x7ce +Greek_OMICRON = 0x7cf +Greek_PI = 0x7d0 +Greek_RHO = 0x7d1 +Greek_SIGMA = 0x7d2 +Greek_TAU = 0x7d4 +Greek_UPSILON = 0x7d5 +Greek_PHI = 0x7d6 +Greek_CHI = 0x7d7 +Greek_PSI = 0x7d8 +Greek_OMEGA = 0x7d9 +Greek_alpha = 0x7e1 +Greek_beta = 0x7e2 +Greek_gamma = 0x7e3 +Greek_delta = 0x7e4 +Greek_epsilon = 0x7e5 +Greek_zeta = 0x7e6 +Greek_eta = 0x7e7 +Greek_theta = 0x7e8 +Greek_iota = 0x7e9 +Greek_kappa = 0x7ea +Greek_lamda = 0x7eb +Greek_lambda = 0x7eb +Greek_mu = 0x7ec +Greek_nu = 0x7ed +Greek_xi = 0x7ee +Greek_omicron = 0x7ef +Greek_pi = 0x7f0 +Greek_rho = 0x7f1 +Greek_sigma = 0x7f2 +Greek_finalsmallsigma = 0x7f3 +Greek_tau = 0x7f4 +Greek_upsilon = 0x7f5 +Greek_phi = 0x7f6 +Greek_chi = 0x7f7 +Greek_psi = 0x7f8 +Greek_omega = 0x7f9 +Greek_switch = 0xFF7E +leftradical = 0x8a1 +topleftradical = 0x8a2 +horizconnector = 0x8a3 +topintegral = 0x8a4 +botintegral = 0x8a5 +vertconnector = 0x8a6 +topleftsqbracket = 0x8a7 +botleftsqbracket = 0x8a8 +toprightsqbracket = 0x8a9 +botrightsqbracket = 0x8aa +topleftparens = 0x8ab +botleftparens = 0x8ac +toprightparens = 0x8ad +botrightparens = 0x8ae +leftmiddlecurlybrace = 0x8af +rightmiddlecurlybrace = 0x8b0 +topleftsummation = 0x8b1 +botleftsummation = 0x8b2 +topvertsummationconnector = 0x8b3 +botvertsummationconnector = 0x8b4 +toprightsummation = 0x8b5 +botrightsummation = 0x8b6 +rightmiddlesummation = 0x8b7 +lessthanequal = 0x8bc +notequal = 0x8bd +greaterthanequal = 0x8be +integral = 0x8bf +therefore = 0x8c0 +variation = 0x8c1 +infinity = 0x8c2 +nabla = 0x8c5 +approximate = 0x8c8 +similarequal = 0x8c9 +ifonlyif = 0x8cd +implies = 0x8ce +identical = 0x8cf +radical = 0x8d6 +includedin = 0x8da +includes = 0x8db +intersection = 0x8dc +union = 0x8dd +logicaland = 0x8de +logicalor = 0x8df +partialderivative = 0x8ef +function = 0x8f6 +leftarrow = 0x8fb +uparrow = 0x8fc +rightarrow = 0x8fd +downarrow = 0x8fe +blank = 0x9df +soliddiamond = 0x9e0 +checkerboard = 0x9e1 +ht = 0x9e2 +ff = 0x9e3 +cr = 0x9e4 +lf = 0x9e5 +nl = 0x9e8 +vt = 0x9e9 +lowrightcorner = 0x9ea +uprightcorner = 0x9eb +upleftcorner = 0x9ec +lowleftcorner = 0x9ed +crossinglines = 0x9ee +horizlinescan1 = 0x9ef +horizlinescan3 = 0x9f0 +horizlinescan5 = 0x9f1 +horizlinescan7 = 0x9f2 +horizlinescan9 = 0x9f3 +leftt = 0x9f4 +rightt = 0x9f5 +bott = 0x9f6 +topt = 0x9f7 +vertbar = 0x9f8 +emspace = 0xaa1 +enspace = 0xaa2 +em3space = 0xaa3 +em4space = 0xaa4 +digitspace = 0xaa5 +punctspace = 0xaa6 +thinspace = 0xaa7 +hairspace = 0xaa8 +emdash = 0xaa9 +endash = 0xaaa +signifblank = 0xaac +ellipsis = 0xaae +doubbaselinedot = 0xaaf +onethird = 0xab0 +twothirds = 0xab1 +onefifth = 0xab2 +twofifths = 0xab3 +threefifths = 0xab4 +fourfifths = 0xab5 +onesixth = 0xab6 +fivesixths = 0xab7 +careof = 0xab8 +figdash = 0xabb +leftanglebracket = 0xabc +decimalpoint = 0xabd +rightanglebracket = 0xabe +marker = 0xabf +oneeighth = 0xac3 +threeeighths = 0xac4 +fiveeighths = 0xac5 +seveneighths = 0xac6 +trademark = 0xac9 +signaturemark = 0xaca +trademarkincircle = 0xacb +leftopentriangle = 0xacc +rightopentriangle = 0xacd +emopencircle = 0xace +emopenrectangle = 0xacf +leftsinglequotemark = 0xad0 +rightsinglequotemark = 0xad1 +leftdoublequotemark = 0xad2 +rightdoublequotemark = 0xad3 +prescription = 0xad4 +minutes = 0xad6 +seconds = 0xad7 +latincross = 0xad9 +hexagram = 0xada +filledrectbullet = 0xadb +filledlefttribullet = 0xadc +filledrighttribullet = 0xadd +emfilledcircle = 0xade +emfilledrect = 0xadf +enopencircbullet = 0xae0 +enopensquarebullet = 0xae1 +openrectbullet = 0xae2 +opentribulletup = 0xae3 +opentribulletdown = 0xae4 +openstar = 0xae5 +enfilledcircbullet = 0xae6 +enfilledsqbullet = 0xae7 +filledtribulletup = 0xae8 +filledtribulletdown = 0xae9 +leftpointer = 0xaea +rightpointer = 0xaeb +club = 0xaec +diamond = 0xaed +heart = 0xaee +maltesecross = 0xaf0 +dagger = 0xaf1 +doubledagger = 0xaf2 +checkmark = 0xaf3 +ballotcross = 0xaf4 +musicalsharp = 0xaf5 +musicalflat = 0xaf6 +malesymbol = 0xaf7 +femalesymbol = 0xaf8 +telephone = 0xaf9 +telephonerecorder = 0xafa +phonographcopyright = 0xafb +caret = 0xafc +singlelowquotemark = 0xafd +doublelowquotemark = 0xafe +cursor = 0xaff +leftcaret = 0xba3 +rightcaret = 0xba6 +downcaret = 0xba8 +upcaret = 0xba9 +overbar = 0xbc0 +downtack = 0xbc2 +upshoe = 0xbc3 +downstile = 0xbc4 +underbar = 0xbc6 +jot = 0xbca +quad = 0xbcc +uptack = 0xbce +circle = 0xbcf +upstile = 0xbd3 +downshoe = 0xbd6 +rightshoe = 0xbd8 +leftshoe = 0xbda +lefttack = 0xbdc +righttack = 0xbfc +hebrew_doublelowline = 0xcdf +hebrew_aleph = 0xce0 +hebrew_bet = 0xce1 +hebrew_beth = 0xce1 +hebrew_gimel = 0xce2 +hebrew_gimmel = 0xce2 +hebrew_dalet = 0xce3 +hebrew_daleth = 0xce3 +hebrew_he = 0xce4 +hebrew_waw = 0xce5 +hebrew_zain = 0xce6 +hebrew_zayin = 0xce6 +hebrew_chet = 0xce7 +hebrew_het = 0xce7 +hebrew_tet = 0xce8 +hebrew_teth = 0xce8 +hebrew_yod = 0xce9 +hebrew_finalkaph = 0xcea +hebrew_kaph = 0xceb +hebrew_lamed = 0xcec +hebrew_finalmem = 0xced +hebrew_mem = 0xcee +hebrew_finalnun = 0xcef +hebrew_nun = 0xcf0 +hebrew_samech = 0xcf1 +hebrew_samekh = 0xcf1 +hebrew_ayin = 0xcf2 +hebrew_finalpe = 0xcf3 +hebrew_pe = 0xcf4 +hebrew_finalzade = 0xcf5 +hebrew_finalzadi = 0xcf5 +hebrew_zade = 0xcf6 +hebrew_zadi = 0xcf6 +hebrew_qoph = 0xcf7 +hebrew_kuf = 0xcf7 +hebrew_resh = 0xcf8 +hebrew_shin = 0xcf9 +hebrew_taw = 0xcfa +hebrew_taf = 0xcfa +Hebrew_switch = 0xFF7E +Thai_kokai = 0xda1 +Thai_khokhai = 0xda2 +Thai_khokhuat = 0xda3 +Thai_khokhwai = 0xda4 +Thai_khokhon = 0xda5 +Thai_khorakhang = 0xda6 +Thai_ngongu = 0xda7 +Thai_chochan = 0xda8 +Thai_choching = 0xda9 +Thai_chochang = 0xdaa +Thai_soso = 0xdab +Thai_chochoe = 0xdac +Thai_yoying = 0xdad +Thai_dochada = 0xdae +Thai_topatak = 0xdaf +Thai_thothan = 0xdb0 +Thai_thonangmontho = 0xdb1 +Thai_thophuthao = 0xdb2 +Thai_nonen = 0xdb3 +Thai_dodek = 0xdb4 +Thai_totao = 0xdb5 +Thai_thothung = 0xdb6 +Thai_thothahan = 0xdb7 +Thai_thothong = 0xdb8 +Thai_nonu = 0xdb9 +Thai_bobaimai = 0xdba +Thai_popla = 0xdbb +Thai_phophung = 0xdbc +Thai_fofa = 0xdbd +Thai_phophan = 0xdbe +Thai_fofan = 0xdbf +Thai_phosamphao = 0xdc0 +Thai_moma = 0xdc1 +Thai_yoyak = 0xdc2 +Thai_rorua = 0xdc3 +Thai_ru = 0xdc4 +Thai_loling = 0xdc5 +Thai_lu = 0xdc6 +Thai_wowaen = 0xdc7 +Thai_sosala = 0xdc8 +Thai_sorusi = 0xdc9 +Thai_sosua = 0xdca +Thai_hohip = 0xdcb +Thai_lochula = 0xdcc +Thai_oang = 0xdcd +Thai_honokhuk = 0xdce +Thai_paiyannoi = 0xdcf +Thai_saraa = 0xdd0 +Thai_maihanakat = 0xdd1 +Thai_saraaa = 0xdd2 +Thai_saraam = 0xdd3 +Thai_sarai = 0xdd4 +Thai_saraii = 0xdd5 +Thai_saraue = 0xdd6 +Thai_sarauee = 0xdd7 +Thai_sarau = 0xdd8 +Thai_sarauu = 0xdd9 +Thai_phinthu = 0xdda +Thai_maihanakat_maitho = 0xdde +Thai_baht = 0xddf +Thai_sarae = 0xde0 +Thai_saraae = 0xde1 +Thai_sarao = 0xde2 +Thai_saraaimaimuan = 0xde3 +Thai_saraaimaimalai = 0xde4 +Thai_lakkhangyao = 0xde5 +Thai_maiyamok = 0xde6 +Thai_maitaikhu = 0xde7 +Thai_maiek = 0xde8 +Thai_maitho = 0xde9 +Thai_maitri = 0xdea +Thai_maichattawa = 0xdeb +Thai_thanthakhat = 0xdec +Thai_nikhahit = 0xded +Thai_leksun = 0xdf0 +Thai_leknung = 0xdf1 +Thai_leksong = 0xdf2 +Thai_leksam = 0xdf3 +Thai_leksi = 0xdf4 +Thai_lekha = 0xdf5 +Thai_lekhok = 0xdf6 +Thai_lekchet = 0xdf7 +Thai_lekpaet = 0xdf8 +Thai_lekkao = 0xdf9 +Hangul = 0xff31 +Hangul_Start = 0xff32 +Hangul_End = 0xff33 +Hangul_Hanja = 0xff34 +Hangul_Jamo = 0xff35 +Hangul_Romaja = 0xff36 +Hangul_Codeinput = 0xff37 +Hangul_Jeonja = 0xff38 +Hangul_Banja = 0xff39 +Hangul_PreHanja = 0xff3a +Hangul_PostHanja = 0xff3b +Hangul_SingleCandidate = 0xff3c +Hangul_MultipleCandidate = 0xff3d +Hangul_PreviousCandidate = 0xff3e +Hangul_Special = 0xff3f +Hangul_switch = 0xFF7E +Hangul_Kiyeog = 0xea1 +Hangul_SsangKiyeog = 0xea2 +Hangul_KiyeogSios = 0xea3 +Hangul_Nieun = 0xea4 +Hangul_NieunJieuj = 0xea5 +Hangul_NieunHieuh = 0xea6 +Hangul_Dikeud = 0xea7 +Hangul_SsangDikeud = 0xea8 +Hangul_Rieul = 0xea9 +Hangul_RieulKiyeog = 0xeaa +Hangul_RieulMieum = 0xeab +Hangul_RieulPieub = 0xeac +Hangul_RieulSios = 0xead +Hangul_RieulTieut = 0xeae +Hangul_RieulPhieuf = 0xeaf +Hangul_RieulHieuh = 0xeb0 +Hangul_Mieum = 0xeb1 +Hangul_Pieub = 0xeb2 +Hangul_SsangPieub = 0xeb3 +Hangul_PieubSios = 0xeb4 +Hangul_Sios = 0xeb5 +Hangul_SsangSios = 0xeb6 +Hangul_Ieung = 0xeb7 +Hangul_Jieuj = 0xeb8 +Hangul_SsangJieuj = 0xeb9 +Hangul_Cieuc = 0xeba +Hangul_Khieuq = 0xebb +Hangul_Tieut = 0xebc +Hangul_Phieuf = 0xebd +Hangul_Hieuh = 0xebe +Hangul_A = 0xebf +Hangul_AE = 0xec0 +Hangul_YA = 0xec1 +Hangul_YAE = 0xec2 +Hangul_EO = 0xec3 +Hangul_E = 0xec4 +Hangul_YEO = 0xec5 +Hangul_YE = 0xec6 +Hangul_O = 0xec7 +Hangul_WA = 0xec8 +Hangul_WAE = 0xec9 +Hangul_OE = 0xeca +Hangul_YO = 0xecb +Hangul_U = 0xecc +Hangul_WEO = 0xecd +Hangul_WE = 0xece +Hangul_WI = 0xecf +Hangul_YU = 0xed0 +Hangul_EU = 0xed1 +Hangul_YI = 0xed2 +Hangul_I = 0xed3 +Hangul_J_Kiyeog = 0xed4 +Hangul_J_SsangKiyeog = 0xed5 +Hangul_J_KiyeogSios = 0xed6 +Hangul_J_Nieun = 0xed7 +Hangul_J_NieunJieuj = 0xed8 +Hangul_J_NieunHieuh = 0xed9 +Hangul_J_Dikeud = 0xeda +Hangul_J_Rieul = 0xedb +Hangul_J_RieulKiyeog = 0xedc +Hangul_J_RieulMieum = 0xedd +Hangul_J_RieulPieub = 0xede +Hangul_J_RieulSios = 0xedf +Hangul_J_RieulTieut = 0xee0 +Hangul_J_RieulPhieuf = 0xee1 +Hangul_J_RieulHieuh = 0xee2 +Hangul_J_Mieum = 0xee3 +Hangul_J_Pieub = 0xee4 +Hangul_J_PieubSios = 0xee5 +Hangul_J_Sios = 0xee6 +Hangul_J_SsangSios = 0xee7 +Hangul_J_Ieung = 0xee8 +Hangul_J_Jieuj = 0xee9 +Hangul_J_Cieuc = 0xeea +Hangul_J_Khieuq = 0xeeb +Hangul_J_Tieut = 0xeec +Hangul_J_Phieuf = 0xeed +Hangul_J_Hieuh = 0xeee +Hangul_RieulYeorinHieuh = 0xeef +Hangul_SunkyeongeumMieum = 0xef0 +Hangul_SunkyeongeumPieub = 0xef1 +Hangul_PanSios = 0xef2 +Hangul_KkogjiDalrinIeung = 0xef3 +Hangul_SunkyeongeumPhieuf = 0xef4 +Hangul_YeorinHieuh = 0xef5 +Hangul_AraeA = 0xef6 +Hangul_AraeAE = 0xef7 +Hangul_J_PanSios = 0xef8 +Hangul_J_KkogjiDalrinIeung = 0xef9 +Hangul_J_YeorinHieuh = 0xefa +Korean_Won = 0xeff +Armenian_eternity = 0x14a1 +Armenian_section_sign = 0x14a2 +Armenian_full_stop = 0x14a3 +Armenian_verjaket = 0x14a3 +Armenian_parenright = 0x14a4 +Armenian_parenleft = 0x14a5 +Armenian_guillemotright = 0x14a6 +Armenian_guillemotleft = 0x14a7 +Armenian_em_dash = 0x14a8 +Armenian_dot = 0x14a9 +Armenian_mijaket = 0x14a9 +Armenian_separation_mark = 0x14aa +Armenian_but = 0x14aa +Armenian_comma = 0x14ab +Armenian_en_dash = 0x14ac +Armenian_hyphen = 0x14ad +Armenian_yentamna = 0x14ad +Armenian_ellipsis = 0x14ae +Armenian_exclam = 0x14af +Armenian_amanak = 0x14af +Armenian_accent = 0x14b0 +Armenian_shesht = 0x14b0 +Armenian_question = 0x14b1 +Armenian_paruyk = 0x14b1 +Armenian_AYB = 0x14b2 +Armenian_ayb = 0x14b3 +Armenian_BEN = 0x14b4 +Armenian_ben = 0x14b5 +Armenian_GIM = 0x14b6 +Armenian_gim = 0x14b7 +Armenian_DA = 0x14b8 +Armenian_da = 0x14b9 +Armenian_YECH = 0x14ba +Armenian_yech = 0x14bb +Armenian_ZA = 0x14bc +Armenian_za = 0x14bd +Armenian_E = 0x14be +Armenian_e = 0x14bf +Armenian_AT = 0x14c0 +Armenian_at = 0x14c1 +Armenian_TO = 0x14c2 +Armenian_to = 0x14c3 +Armenian_ZHE = 0x14c4 +Armenian_zhe = 0x14c5 +Armenian_INI = 0x14c6 +Armenian_ini = 0x14c7 +Armenian_LYUN = 0x14c8 +Armenian_lyun = 0x14c9 +Armenian_KHE = 0x14ca +Armenian_khe = 0x14cb +Armenian_TSA = 0x14cc +Armenian_tsa = 0x14cd +Armenian_KEN = 0x14ce +Armenian_ken = 0x14cf +Armenian_HO = 0x14d0 +Armenian_ho = 0x14d1 +Armenian_DZA = 0x14d2 +Armenian_dza = 0x14d3 +Armenian_GHAT = 0x14d4 +Armenian_ghat = 0x14d5 +Armenian_TCHE = 0x14d6 +Armenian_tche = 0x14d7 +Armenian_MEN = 0x14d8 +Armenian_men = 0x14d9 +Armenian_HI = 0x14da +Armenian_hi = 0x14db +Armenian_NU = 0x14dc +Armenian_nu = 0x14dd +Armenian_SHA = 0x14de +Armenian_sha = 0x14df +Armenian_VO = 0x14e0 +Armenian_vo = 0x14e1 +Armenian_CHA = 0x14e2 +Armenian_cha = 0x14e3 +Armenian_PE = 0x14e4 +Armenian_pe = 0x14e5 +Armenian_JE = 0x14e6 +Armenian_je = 0x14e7 +Armenian_RA = 0x14e8 +Armenian_ra = 0x14e9 +Armenian_SE = 0x14ea +Armenian_se = 0x14eb +Armenian_VEV = 0x14ec +Armenian_vev = 0x14ed +Armenian_TYUN = 0x14ee +Armenian_tyun = 0x14ef +Armenian_RE = 0x14f0 +Armenian_re = 0x14f1 +Armenian_TSO = 0x14f2 +Armenian_tso = 0x14f3 +Armenian_VYUN = 0x14f4 +Armenian_vyun = 0x14f5 +Armenian_PYUR = 0x14f6 +Armenian_pyur = 0x14f7 +Armenian_KE = 0x14f8 +Armenian_ke = 0x14f9 +Armenian_O = 0x14fa +Armenian_o = 0x14fb +Armenian_FE = 0x14fc +Armenian_fe = 0x14fd +Armenian_apostrophe = 0x14fe +Armenian_ligature_ew = 0x14ff +Georgian_an = 0x15d0 +Georgian_ban = 0x15d1 +Georgian_gan = 0x15d2 +Georgian_don = 0x15d3 +Georgian_en = 0x15d4 +Georgian_vin = 0x15d5 +Georgian_zen = 0x15d6 +Georgian_tan = 0x15d7 +Georgian_in = 0x15d8 +Georgian_kan = 0x15d9 +Georgian_las = 0x15da +Georgian_man = 0x15db +Georgian_nar = 0x15dc +Georgian_on = 0x15dd +Georgian_par = 0x15de +Georgian_zhar = 0x15df +Georgian_rae = 0x15e0 +Georgian_san = 0x15e1 +Georgian_tar = 0x15e2 +Georgian_un = 0x15e3 +Georgian_phar = 0x15e4 +Georgian_khar = 0x15e5 +Georgian_ghan = 0x15e6 +Georgian_qar = 0x15e7 +Georgian_shin = 0x15e8 +Georgian_chin = 0x15e9 +Georgian_can = 0x15ea +Georgian_jil = 0x15eb +Georgian_cil = 0x15ec +Georgian_char = 0x15ed +Georgian_xan = 0x15ee +Georgian_jhan = 0x15ef +Georgian_hae = 0x15f0 +Georgian_he = 0x15f1 +Georgian_hie = 0x15f2 +Georgian_we = 0x15f3 +Georgian_har = 0x15f4 +Georgian_hoe = 0x15f5 +Georgian_fi = 0x15f6 +EcuSign = 0x20a0 +ColonSign = 0x20a1 +CruzeiroSign = 0x20a2 +FFrancSign = 0x20a3 +LiraSign = 0x20a4 +MillSign = 0x20a5 +NairaSign = 0x20a6 +PesetaSign = 0x20a7 +RupeeSign = 0x20a8 +WonSign = 0x20a9 +NewSheqelSign = 0x20aa +DongSign = 0x20ab +EuroSign = 0x20ac diff --git a/gi/pygi-argument.c b/gi/pygi-argument.c new file mode 100644 index 0000000..c6df559 --- /dev/null +++ b/gi/pygi-argument.c @@ -0,0 +1,1950 @@ +/* -*- 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 (G_MININT32); + *upper = PyInt_FromLong (G_MAXINT32); + break; + case GI_TYPE_TAG_UINT32: + /* Note: On 32-bit archs, this number doesn't fit in a long. */ + *upper = PyLong_FromLongLong (G_MAXUINT32); + *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 (G_MININT64); + *upper = PyLong_FromLongLong (G_MAXINT64); + break; + case GI_TYPE_TAG_UINT64: + *upper = PyLong_FromUnsignedLongLong (G_MAXUINT64); + *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; + GIInfoType interface_type; + + interface_type = g_base_info_get_type (info); + if ( (interface_type == GI_INFO_TYPE_STRUCT) && + (g_struct_info_is_foreign ( (GIStructInfo*) info))) { + /* TODO: Could we check is the correct foreign type? */ + return 1; + } + + 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 0; + } + + 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, + PyObject *object, + gboolean allow_none) +{ + GITypeTag type_tag; + gint retval = 1; + + if (allow_none && object == Py_None) { + return retval; + } + + type_tag = g_type_info_get_tag (type_info); + + switch (type_tag) { + case GI_TYPE_TAG_VOID: + /* No check; VOID means undefined type */ + 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; + 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)) { + 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, item, TRUE); + + 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: + if (!PyCallable_Check (object)) { + PyErr_Format (PyExc_TypeError, "Must be callable, not %s", + object->ob_type->tp_name); + retval = 0; + } + break; + case GI_INFO_TYPE_ENUM: + retval = _pygi_g_registered_type_info_check_object ( + (GIRegisteredTypeInfo *) info, TRUE, object); + break; + case GI_INFO_TYPE_FLAGS: + if (PyNumber_Check (object)) { + /* Accept 0 as a valid flag value */ + PyObject *number = PyNumber_Int (object); + if (number == NULL) + PyErr_Clear(); + else { + long value = PyInt_AsLong (number); + if (value == 0) + break; + else if (value == -1) + PyErr_Clear(); + } + } + 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_INTERFACE: + case GI_INFO_TYPE_OBJECT: + case GI_INFO_TYPE_UNION: + retval = _pygi_g_registered_type_info_check_object ( (GIRegisteredTypeInfo *) info, TRUE, object); + 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, item, TRUE); + + 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, key, TRUE); + if (retval < 0) { + break; + } + if (!retval) { + _PyGI_ERROR_PREFIX ("Key %zd :", i); + break; + } + + retval = _pygi_g_type_info_check_object (value_type_info, value, TRUE); + 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, + gboolean is_method) +{ + GITypeInfo *item_type_info; + gboolean is_zero_terminated; + gsize item_size; + gssize length; + GArray *g_array; + + if (arg->v_pointer == NULL) { + return NULL; + } + + 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); + + if (is_method) { + length_arg_pos--; + } + + g_assert (length_arg_pos >= 0); + + /* FIXME: Take into account the type of the argument. */ + length = args[length_arg_pos]->v_int; + } + } + + g_assert (length >= 0); + + 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; + + memset(&arg, 0, sizeof(GArgument)); + type_tag = g_type_info_get_tag (type_info); + + switch (type_tag) { + case GI_TYPE_TAG_VOID: + g_warn_if_fail (transfer == GI_TRANSFER_NOTHING); + arg.v_pointer = object; + break; + case GI_TYPE_TAG_BOOLEAN: + { + arg.v_boolean = PyObject_IsTrue (object); + 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_; + + int_ = PyNumber_Int (object); + if (int_ == NULL) { + break; + } + + arg.v_long = PyInt_AsLong (int_); + + Py_DECREF (int_); + + 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); + } + + arg.v_uint64 = value; + + Py_DECREF (number); + + 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); + } + + arg.v_int64 = value; + + Py_DECREF (number); + + break; + } + case GI_TYPE_TAG_FLOAT: + { + PyObject *float_; + + float_ = PyNumber_Float (object); + if (float_ == NULL) { + break; + } + + arg.v_float = (float) PyFloat_AsDouble (float_); + Py_DECREF (float_); + + break; + } + case GI_TYPE_TAG_DOUBLE: + { + PyObject *float_; + + float_ = PyNumber_Float (object); + if (float_ == NULL) { + break; + } + + arg.v_double = PyFloat_AsDouble (float_); + Py_DECREF (float_); + + break; + } + case GI_TYPE_TAG_TIME_T: + { + PyDateTime_DateTime *py_datetime; + struct tm datetime; + + 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; + + arg.v_long = mktime (&datetime); + if (arg.v_long == -1) { + PyErr_SetString (PyExc_RuntimeError, "datetime conversion failed"); + break; + } + + break; + } + case GI_TYPE_TAG_GTYPE: + { + arg.v_long = pyg_type_from_object (object); + + break; + } + case GI_TYPE_TAG_UTF8: + { + const gchar *string; + + if (object == Py_None) { + arg.v_string = NULL; + break; + } + + 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; + + 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; + + if (object == Py_None) { + arg.v_pointer = NULL; + break; + } + + 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: + /* This should be handled in invoke() */ + g_assert_not_reached(); + break; + case GI_INFO_TYPE_BOXED: + case GI_INFO_TYPE_STRUCT: + case GI_INFO_TYPE_UNION: + { + GType type; + + if (object == Py_None) { + arg.v_pointer = NULL; + break; + } + + 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_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_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)) { + 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 ( (type == G_TYPE_NONE) && (g_struct_info_is_foreign (info))) { + PyObject *result; + result = pygi_struct_foreign_convert_to_g_argument ( + object, type_info, transfer, &arg); + } else if (g_type_is_a (type, G_TYPE_POINTER) || type == G_TYPE_NONE) { + g_warn_if_fail (!g_type_info_is_pointer (type_info) || transfer == GI_TRANSFER_NOTHING); + arg.v_pointer = pyg_pointer_get (object, void); + } 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_; + + int_ = PyNumber_Int (object); + if (int_ == NULL) { + break; + } + + arg.v_long = PyInt_AsLong (int_); + + Py_DECREF (int_); + + break; + } + case GI_INFO_TYPE_INTERFACE: + case GI_INFO_TYPE_OBJECT: + if (object == Py_None) { + arg.v_pointer = NULL; + break; + } + + arg.v_pointer = pygobject_get (object); + if (transfer == GI_TRANSFER_EVERYTHING) { + g_object_ref (arg.v_pointer); + } + + 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; + + if (object == Py_None) { + arg.v_pointer = NULL; + break; + } + + 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; + + + if (object == Py_None) { + arg.v_pointer = NULL; + break; + } + + 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; + PyObject *object = NULL; + + type_tag = g_type_info_get_tag (type_info); + switch (type_tag) { + case GI_TYPE_TAG_VOID: + if (g_type_info_is_pointer (type_info)) { + /* Raw Python objects are passed to void* args */ + g_warn_if_fail (transfer == GI_TRANSFER_NOTHING); + object = arg->v_pointer; + } else + object = Py_None; + Py_XINCREF (object); + break; + case GI_TYPE_TAG_BOOLEAN: + { + object = PyBool_FromLong (arg->v_boolean); + break; + } + case GI_TYPE_TAG_INT8: + { + object = PyInt_FromLong (arg->v_int8); + break; + } + case GI_TYPE_TAG_UINT8: + { + object = PyInt_FromLong (arg->v_uint8); + break; + } + case GI_TYPE_TAG_INT16: + { + object = PyInt_FromLong (arg->v_int16); + break; + } + case GI_TYPE_TAG_UINT16: + { + object = PyInt_FromLong (arg->v_uint16); + break; + } + case GI_TYPE_TAG_INT32: + { + object = PyInt_FromLong (arg->v_int32); + break; + } + case GI_TYPE_TAG_UINT32: + { + object = PyLong_FromLongLong (arg->v_uint32); + break; + } + case GI_TYPE_TAG_INT64: + { + object = PyLong_FromLongLong (arg->v_int64); + break; + } + case GI_TYPE_TAG_UINT64: + { + object = PyLong_FromUnsignedLongLong (arg->v_uint64); + break; + } + case GI_TYPE_TAG_SHORT: + { + object = PyInt_FromLong (arg->v_short); + break; + } + case GI_TYPE_TAG_USHORT: + { + object = PyInt_FromLong (arg->v_ushort); + break; + } + case GI_TYPE_TAG_INT: + { + object = PyInt_FromLong (arg->v_int); + break; + } + case GI_TYPE_TAG_UINT: + { + object = PyLong_FromLongLong (arg->v_uint); + break; + } + case GI_TYPE_TAG_LONG: + { + object = PyInt_FromLong (arg->v_long); + break; + } + case GI_TYPE_TAG_ULONG: + { + object = PyLong_FromUnsignedLongLong (arg->v_ulong); + break; + } + case GI_TYPE_TAG_SSIZE: + { + object = PyInt_FromLong (arg->v_ssize); + break; + } + case GI_TYPE_TAG_SIZE: + { + object = PyLong_FromUnsignedLongLong (arg->v_size); + break; + } + case GI_TYPE_TAG_FLOAT: + { + object = PyFloat_FromDouble (arg->v_float); + break; + } + case GI_TYPE_TAG_DOUBLE: + { + object = PyFloat_FromDouble (arg->v_double); + break; + } + case GI_TYPE_TAG_TIME_T: + { + time_t *time_; + struct tm *datetime; + + time_ = (time_t *) &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: + { + object = pyg_type_wrapper_new ( (GType) arg->v_long); + break; + } + case GI_TYPE_TAG_UTF8: + if (arg->v_string == NULL) { + object = Py_None; + Py_INCREF (object); + break; + } + + object = PyString_FromString (arg->v_string); + break; + case GI_TYPE_TAG_FILENAME: + { + GError *error = NULL; + gchar *string; + + if (arg->v_string == NULL) { + object = Py_None; + Py_INCREF (object); + break; + } + + 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; + GITypeTag item_type_tag; + GITransfer item_transfer; + gsize i, item_size; + + if (arg->v_pointer == NULL) { + object = PyList_New (0); + break; + } + + array = arg->v_pointer; + + object = PyList_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_type_tag = g_type_info_get_tag (item_type_info); + item_transfer = transfer == GI_TRANSFER_CONTAINER ? GI_TRANSFER_NOTHING : transfer; + item_size = g_array_get_element_size (array); + + for (i = 0; i < array->len; i++) { + GArgument item; + PyObject *py_item; + gboolean is_struct = FALSE; + + if (item_type_tag == GI_TYPE_TAG_INTERFACE) { + GIBaseInfo *iface_info = g_type_info_get_interface (item_type_info); + switch (g_base_info_get_type (iface_info)) { + case GI_INFO_TYPE_STRUCT: + case GI_INFO_TYPE_BOXED: + is_struct = TRUE; + default: + break; + } + g_base_info_unref ( (GIBaseInfo *) iface_info); + } + + if (is_struct) { + item.v_pointer = &_g_array_index (array, GArgument, i); + } else { + memcpy (&item, &_g_array_index (array, GArgument, i), item_size); + } + + 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_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: + { + /* There is no way we can support a callback return + * as we are never sure if the callback was set from C + * or Python. API that return callbacks are broken + * so we print a warning and send back a None + */ + + g_warning ("You are trying to use an API which returns a callback." + "Callback returns can not be supported. Returning None instead."); + object = Py_None; + Py_INCREF (object); + break; + } + case GI_INFO_TYPE_BOXED: + case GI_INFO_TYPE_STRUCT: + case GI_INFO_TYPE_UNION: + { + GType type; + + if (arg->v_pointer == NULL) { + object = Py_None; + Py_INCREF (object); + break; + } + + type = g_registered_type_info_get_g_type ( (GIRegisteredTypeInfo *) info); + if (g_type_is_a (type, G_TYPE_VALUE)) { + object = pyg_value_as_pyobject (arg->v_pointer, FALSE); + } else if (g_type_is_a (type, G_TYPE_BOXED)) { + PyObject *py_type; + + py_type = _pygi_type_get_from_g_type (type); + if (py_type == NULL) + break; + + object = _pygi_boxed_new ( (PyTypeObject *) py_type, arg->v_pointer, transfer == GI_TRANSFER_EVERYTHING); + + Py_DECREF (py_type); + } else if (g_type_is_a (type, G_TYPE_POINTER)) { + PyObject *py_type; + + 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) && (g_struct_info_is_foreign (info))) { + object = pygi_struct_foreign_convert_from_g_argument (type_info, arg->v_pointer); + } else if (type == G_TYPE_NONE) { + PyObject *py_type; + + py_type = _pygi_type_import_by_gi_info (info); + if (py_type == NULL) { + break; + } + + if (transfer != GI_TRANSFER_NOTHING) + g_warning ("Transfer mode should be set to None for " + "struct types as there is no way to free " + "them safely. Ignoring transfer mode " + "to prevent a potential invalid free. " + "This may cause a leak in your application."); + + object = _pygi_struct_new ( (PyTypeObject *) py_type, arg->v_pointer, + FALSE); + + 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; + + type = g_registered_type_info_get_g_type ( (GIRegisteredTypeInfo *) info); + + if (type == G_TYPE_NONE) { + /* An enum with a GType of None is an enum without GType */ + PyObject *py_type = _pygi_type_import_by_gi_info (info); + PyObject *py_args = NULL; + + if (!py_type) + return NULL; + + py_args = PyTuple_New (1); + if (PyTuple_SetItem (py_args, 0, PyLong_FromLong (arg->v_long)) != 0) { + Py_DECREF (py_args); + Py_DECREF (py_type); + return NULL; + } + + object = PyObject_CallFunction (py_type, "l", arg->v_long); + + Py_DECREF (py_args); + Py_DECREF (py_type); + + } else if (info_type == GI_INFO_TYPE_ENUM) { + object = pyg_enum_from_gtype (type, arg->v_long); + } else { + object = pyg_flags_from_gtype (type, arg->v_long); + } + + break; + } + case GI_INFO_TYPE_INTERFACE: + case GI_INFO_TYPE_OBJECT: + if (arg->v_pointer == NULL) { + object = Py_None; + Py_INCREF (object); + break; + } + object = pygobject_new (arg->v_pointer); + 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; + + 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; + + if (arg->v_pointer == NULL) { + object = Py_None; + Py_INCREF (object); + break; + } + + 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; + + type_tag = g_type_info_get_tag (type_info); + + switch (type_tag) { + case GI_TYPE_TAG_VOID: + /* Don't do anything, it's transparent to the C side */ + break; + 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: + break; + case GI_TYPE_TAG_FILENAME: + case GI_TYPE_TAG_UTF8: + /* With allow-none support the string could be NULL */ + if (arg->v_string != NULL && + (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; + + if (arg->v_pointer == NULL) { + return; + } + + 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: + case GI_INFO_TYPE_UNION: + { + GType type; + + if (arg->v_pointer == NULL) { + return; + } + + type = g_registered_type_info_get_g_type ( (GIRegisteredTypeInfo *) info); + + if (g_type_is_a (type, G_TYPE_VALUE)) { + GValue *value; + + 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)) { + if (direction == GI_DIRECTION_IN && transfer == GI_TRANSFER_NOTHING) { + g_closure_unref (arg->v_pointer); + } + } else if (g_struct_info_is_foreign ( (GIStructInfo*) info)) { + if (direction == GI_DIRECTION_OUT && transfer == GI_TRANSFER_EVERYTHING) { + pygi_struct_foreign_release_g_argument (transfer, type_info, arg); + } + } else if (g_type_is_a (type, G_TYPE_BOXED)) { + } else if (g_type_is_a (type, G_TYPE_POINTER) || type == G_TYPE_NONE) { + g_warn_if_fail (!g_type_info_is_pointer (type_info) || transfer == GI_TRANSFER_NOTHING); + } + + break; + } + case GI_INFO_TYPE_ENUM: + case GI_INFO_TYPE_FLAGS: + break; + case GI_INFO_TYPE_INTERFACE: + case GI_INFO_TYPE_OBJECT: + if (arg->v_pointer == NULL) { + return; + } + if (direction == GI_DIRECTION_OUT && transfer == GI_TRANSFER_EVERYTHING) { + g_object_unref (arg->v_pointer); + } + break; + default: + g_assert_not_reached(); + } + + g_base_info_unref (info); + break; + } + case GI_TYPE_TAG_GLIST: + case GI_TYPE_TAG_GSLIST: + { + GSList *list; + + if (arg->v_pointer == NULL) { + return; + } + + 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; + + if (arg->v_pointer == NULL) { + return; + } + + 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; + + if (arg->v_pointer == NULL) { + return; + } + + 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..821737a --- /dev/null +++ b/gi/pygi-argument.h @@ -0,0 +1,66 @@ +/* -*- 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, + PyObject *object, + gboolean allow_none); + +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, + gboolean is_method); + +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-boxed.c b/gi/pygi-boxed.c new file mode 100644 index 0000000..4903834 --- /dev/null +++ b/gi/pygi-boxed.c @@ -0,0 +1,196 @@ +/* -*- Mode: C; c-basic-offset: 4 -*- + * vim: tabstop=4 shiftwidth=4 expandtab + * + * Copyright (C) 2009 Simon van der Linden <svdlinden@src.gnome.org> + * + * pygi-boxed.c: wrapper to handle 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 +_boxed_dealloc (PyGIBoxed *self) +{ + GType g_type; + + PyObject_GC_UnTrack ( (PyObject *) self); + + PyObject_ClearWeakRefs ( (PyObject *) self); + + if ( ( (PyGBoxed *) self)->free_on_dealloc) { + if (self->slice_allocated) { + g_slice_free1 (self->size, ( (PyGBoxed *) self)->boxed); + } else { + g_type = pyg_type_from_object ( (PyObject *) self); + g_boxed_free (g_type, ( (PyGBoxed *) self)->boxed); + } + } + + ( (PyGObject *) self)->ob_type->tp_free ( (PyObject *) self); +} + +static PyObject * +_boxed_new (PyTypeObject *type, + PyObject *args, + PyObject *kwargs) +{ + static char *kwlist[] = { NULL }; + + GIBaseInfo *info; + gsize size; + gpointer boxed; + PyGIBoxed *self = NULL; + + if (!PyArg_ParseTupleAndKeywords (args, kwargs, "", kwlist)) { + return NULL; + } + + info = _pygi_object_get_gi_info ( (PyObject *) type, &PyGIBaseInfo_Type); + if (info == NULL) { + if (PyErr_ExceptionMatches (PyExc_AttributeError)) { + PyErr_Format (PyExc_TypeError, "missing introspection information"); + } + return NULL; + } + + switch (g_base_info_get_type (info)) { + case GI_INFO_TYPE_UNION: + size = g_union_info_get_size ( (GIUnionInfo *) info); + break; + case GI_INFO_TYPE_BOXED: + case GI_INFO_TYPE_STRUCT: + size = g_struct_info_get_size ( (GIStructInfo *) info); + break; + default: + PyErr_Format (PyExc_TypeError, + "info should be Boxed or Union, not '%d'", + g_base_info_get_type (info)); + return NULL; + } + + boxed = g_slice_alloc0 (size); + if (boxed == NULL) { + PyErr_NoMemory(); + goto out; + } + + self = (PyGIBoxed *) _pygi_boxed_new (type, boxed, TRUE); + if (self == NULL) { + g_slice_free1 (size, boxed); + goto out; + } + + self->size = size; + self->slice_allocated = TRUE; + +out: + g_base_info_unref (info); + + return (PyObject *) self; +} + +static int +_boxed_init (PyObject *self, + PyObject *args, + PyObject *kwargs) +{ + /* Don't call PyGBoxed's init, which raises an exception. */ + return 0; +} + + +PyTypeObject PyGIBoxed_Type = { + PyObject_HEAD_INIT (NULL) + 0, + "gi.Boxed", /* tp_name */ + sizeof (PyGIBoxed), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor) _boxed_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_boxed_new (PyTypeObject *type, + gpointer boxed, + gboolean free_on_dealloc) +{ + PyGIBoxed *self; + + if (!boxed) { + Py_RETURN_NONE; + } + + if (!PyType_IsSubtype (type, &PyGIBoxed_Type)) { + PyErr_SetString (PyExc_TypeError, "must be a subtype of gi.Boxed"); + return NULL; + } + + self = (PyGIBoxed *) type->tp_alloc (type, 0); + if (self == NULL) { + return NULL; + } + + ( (PyGBoxed *) self)->gtype = pyg_type_from_object ( (PyObject *) type); + ( (PyGBoxed *) self)->boxed = boxed; + ( (PyGBoxed *) self)->free_on_dealloc = free_on_dealloc; + self->size = 0; + self->slice_allocated = FALSE; + + return (PyObject *) self; +} + +void +_pygi_boxed_register_types (PyObject *m) +{ + PyGIBoxed_Type.ob_type = &PyType_Type; + PyGIBoxed_Type.tp_base = &PyGBoxed_Type; + PyGIBoxed_Type.tp_new = (newfunc) _boxed_new; + PyGIBoxed_Type.tp_init = (initproc) _boxed_init; + if (PyType_Ready (&PyGIBoxed_Type)) + return; + if (PyModule_AddObject (m, "Boxed", (PyObject *) &PyGIBoxed_Type)) + return; +} diff --git a/gi/pygi-boxed.h b/gi/pygi-boxed.h new file mode 100644 index 0000000..4f84060 --- /dev/null +++ b/gi/pygi-boxed.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_BOXED_H__ +#define __PYGI_BOXED_H__ + +#include <Python.h> + +G_BEGIN_DECLS + +extern PyTypeObject PyGIBoxed_Type; + +PyObject * +_pygi_boxed_new (PyTypeObject *type, + gpointer boxed, + gboolean free_on_dealloc); + +void _pygi_boxed_register_types (PyObject *m); + +G_END_DECLS + +#endif /* __PYGI_BOXED_H__ */ diff --git a/gi/pygi-callbacks.c b/gi/pygi-callbacks.c new file mode 100644 index 0000000..868f2fb --- /dev/null +++ b/gi/pygi-callbacks.c @@ -0,0 +1,223 @@ +/* -*- Mode: C; c-basic-offset: 4 -*- + * vim: tabstop=4 shiftwidth=4 expandtab + * + * pygi-callbacks.c: PyGI C Callback Functions and Helpers + * + * 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" + +static PyGICClosure *global_destroy_notify; + +static void +_pygi_destroy_notify_callback_closure (ffi_cif *cif, + void *result, + void **args, + void *data) +{ + PyGICClosure *info = * (void**) (args[0]); + + g_assert (info); + + _pygi_invoke_closure_free (info); +} + + +PyGICClosure* +_pygi_destroy_notify_create (void) +{ + if (!global_destroy_notify) { + + ffi_status status; + PyGICClosure *destroy_notify = g_slice_new0 (PyGICClosure); + + g_assert (destroy_notify); + + GIBaseInfo* glib_destroy_notify = g_irepository_find_by_name (NULL, "GLib", "DestroyNotify"); + g_assert (glib_destroy_notify != NULL); + g_assert (g_base_info_get_type (glib_destroy_notify) == GI_INFO_TYPE_CALLBACK); + + destroy_notify->closure = g_callable_info_prepare_closure ( (GICallableInfo*) glib_destroy_notify, + &destroy_notify->cif, + _pygi_destroy_notify_callback_closure, + NULL); + + global_destroy_notify = destroy_notify; + } + + return global_destroy_notify; +} + + +gboolean +_pygi_scan_for_callbacks (GIFunctionInfo *function_info, + gboolean is_method, + guint8 *callback_index, + guint8 *user_data_index, + guint8 *destroy_notify_index) +{ + guint i, n_args; + + *callback_index = G_MAXUINT8; + *user_data_index = G_MAXUINT8; + *destroy_notify_index = G_MAXUINT8; + + n_args = g_callable_info_get_n_args ( (GICallableInfo *) function_info); + for (i = 0; i < n_args; i++) { + GIDirection direction; + GIArgInfo *arg_info; + GITypeInfo *type_info; + guint8 destroy, closure; + GITypeTag type_tag; + + arg_info = g_callable_info_get_arg ( (GICallableInfo*) function_info, i); + type_info = g_arg_info_get_type (arg_info); + type_tag = g_type_info_get_tag (type_info); + + if (type_tag == GI_TYPE_TAG_INTERFACE) { + GIBaseInfo* interface_info; + GIInfoType interface_type; + + interface_info = g_type_info_get_interface (type_info); + interface_type = g_base_info_get_type (interface_info); + if (interface_type == GI_INFO_TYPE_CALLBACK && + ! (strcmp (g_base_info_get_namespace ( (GIBaseInfo*) interface_info), "GLib") == 0 && + strcmp (g_base_info_get_name ( (GIBaseInfo*) interface_info), "DestroyNotify") == 0)) { + if (*callback_index != G_MAXUINT8) { + PyErr_Format (PyExc_TypeError, "Function %s.%s has multiple callbacks, not supported", + g_base_info_get_namespace ( (GIBaseInfo*) function_info), + g_base_info_get_name ( (GIBaseInfo*) function_info)); + g_base_info_unref (interface_info); + return FALSE; + } + *callback_index = i; + } + g_base_info_unref (interface_info); + } + destroy = g_arg_info_get_destroy (arg_info); + if (is_method) + --destroy; + closure = g_arg_info_get_closure (arg_info); + if (is_method) + --closure; + direction = g_arg_info_get_direction (arg_info); + + if (destroy > 0 && destroy < n_args) { + if (*destroy_notify_index != G_MAXUINT8) { + PyErr_Format (PyExc_TypeError, "Function %s has multiple GDestroyNotify, not supported", + g_base_info_get_name ( (GIBaseInfo*) function_info)); + return FALSE; + } + *destroy_notify_index = destroy; + } + + if (closure > 0 && closure < n_args) { + if (*user_data_index != G_MAXUINT8) { + PyErr_Format (PyExc_TypeError, "Function %s has multiple user_data arguments, not supported", + g_base_info_get_name ( (GIBaseInfo*) function_info)); + return FALSE; + } + *user_data_index = closure; + } + + g_base_info_unref ( (GIBaseInfo*) arg_info); + g_base_info_unref ( (GIBaseInfo*) type_info); + } + + return TRUE; +} + +gboolean +_pygi_create_callback (GIBaseInfo *function_info, + gboolean is_method, + gboolean is_constructor, + int n_args, + Py_ssize_t py_argc, + PyObject *py_argv, + guint8 callback_index, + guint8 user_data_index, + guint8 destroy_notify_index, + PyGICClosure **closure_out) +{ + GIArgInfo *callback_arg; + GITypeInfo *callback_type; + GICallbackInfo *callback_info; + GIScopeType scope; + gboolean found_py_function; + PyObject *py_function; + guint8 i, py_argv_pos; + PyObject *py_user_data; + gboolean allow_none; + + callback_arg = g_callable_info_get_arg ( (GICallableInfo*) function_info, callback_index); + scope = g_arg_info_get_scope (callback_arg); + allow_none = g_arg_info_may_be_null (callback_arg); + + callback_type = g_arg_info_get_type (callback_arg); + g_assert (g_type_info_get_tag (callback_type) == GI_TYPE_TAG_INTERFACE); + + callback_info = (GICallbackInfo*) g_type_info_get_interface (callback_type); + g_assert (g_base_info_get_type ( (GIBaseInfo*) callback_info) == GI_INFO_TYPE_CALLBACK); + + /* Find the Python function passed for the callback */ + found_py_function = FALSE; + py_function = Py_None; + py_user_data = NULL; + + /* if its a method then we need to skip over 'self' */ + if (is_method || is_constructor) + py_argv_pos = 1; + else + py_argv_pos = 0; + + for (i = 0; i < n_args && i < py_argc; i++) { + if (i == callback_index) { + py_function = PyTuple_GetItem (py_argv, py_argv_pos); + /* if we allow none then set the closure to NULL and return */ + if (allow_none && py_function == Py_None) { + *closure_out = NULL; + goto out; + } + found_py_function = TRUE; + } else if (i == user_data_index) { + py_user_data = PyTuple_GetItem (py_argv, py_argv_pos); + } + py_argv_pos++; + } + + if (!found_py_function + || (py_function == Py_None || !PyCallable_Check (py_function))) { + PyErr_Format (PyExc_TypeError, "Error invoking %s.%s: Invalid callback given for argument %s", + g_base_info_get_namespace ( (GIBaseInfo*) function_info), + g_base_info_get_name ( (GIBaseInfo*) function_info), + g_base_info_get_name ( (GIBaseInfo*) callback_arg)); + g_base_info_unref ( (GIBaseInfo*) callback_info); + g_base_info_unref ( (GIBaseInfo*) callback_type); + return FALSE; + } + + /** Now actually build the closure **/ + *closure_out = _pygi_make_native_closure ( (GICallableInfo *) callback_info, + g_arg_info_get_scope (callback_arg), + py_function, + py_user_data); +out: + g_base_info_unref ( (GIBaseInfo*) callback_info); + g_base_info_unref ( (GIBaseInfo*) callback_type); + + return TRUE; +} diff --git a/gi/pygi-callbacks.h b/gi/pygi-callbacks.h new file mode 100644 index 0000000..7535bba --- /dev/null +++ b/gi/pygi-callbacks.h @@ -0,0 +1,48 @@ +/* -*- Mode: C; c-basic-offset: 4 -*- + * vim: tabstop=4 shiftwidth=4 expandtab + * + * 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_CALLBACKS_H__ +#define __PYGI_CALLBACKS_H__ + +G_BEGIN_DECLS + +void _pygi_callback_notify_info_free (gpointer user_data); + +PyGICClosure*_pygi_destroy_notify_create (void); + +gboolean _pygi_scan_for_callbacks (GIFunctionInfo *self, + gboolean is_method, + guint8 *callback_index, + guint8 *user_data_index, + guint8 *destroy_notify_index); + +gboolean _pygi_create_callback (GIFunctionInfo *self, + gboolean is_method, + gboolean is_constructor, + int n_args, + Py_ssize_t py_argc, + PyObject *py_argv, + guint8 callback_index, + guint8 user_data_index, + guint8 destroy_notify_index, + PyGICClosure **closure_out); + +G_END_DECLS + +#endif diff --git a/gi/pygi-closure.c b/gi/pygi-closure.c new file mode 100644 index 0000000..a752ae2 --- /dev/null +++ b/gi/pygi-closure.c @@ -0,0 +1,399 @@ +/* -*- Mode: C; c-basic-offset: 4 -*- + * vim: tabstop=4 shiftwidth=4 expandtab + * + * pygi-closure.c: PyGI C Closure 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" + +/* This maintains a list of closures which can be free'd whenever + as they have been called. We will free them on the next + library function call. + */ +static GSList* async_free_list; + + +static GArgument * +_pygi_closure_convert_ffi_arguments (GICallableInfo *callable_info, void **args) +{ + gint num_args, i; + GIArgInfo *arg_info; + GITypeInfo *arg_type; + GITypeTag tag; + GIDirection direction; + GArgument *g_args; + + num_args = g_callable_info_get_n_args (callable_info); + g_args = g_new0 (GArgument, num_args); + + for (i = 0; i < num_args; i++) { + arg_info = g_callable_info_get_arg (callable_info, i); + arg_type = g_arg_info_get_type (arg_info); + tag = g_type_info_get_tag (arg_type); + direction = g_arg_info_get_direction (arg_info); + + if (direction == GI_DIRECTION_OUT || direction == GI_DIRECTION_INOUT) { + g_args[i].v_pointer = * (gpointer *) args[i]; + } else { + switch (tag) { + case GI_TYPE_TAG_BOOLEAN: + g_args[i].v_boolean = * (gboolean *) args[i]; + break; + case GI_TYPE_TAG_INT8: + g_args[i].v_int8 = * (gint8 *) args[i]; + break; + case GI_TYPE_TAG_UINT8: + g_args[i].v_uint8 = * (guint8 *) args[i]; + break; + case GI_TYPE_TAG_INT16: + g_args[i].v_int16 = * (gint16 *) args[i]; + break; + case GI_TYPE_TAG_UINT16: + g_args[i].v_uint16 = * (guint16 *) args[i]; + break; + case GI_TYPE_TAG_INT32: + g_args[i].v_int32 = * (gint32 *) args[i]; + break; + case GI_TYPE_TAG_UINT32: + g_args[i].v_uint32 = * (guint32 *) args[i]; + break; + case GI_TYPE_TAG_LONG: + case GI_TYPE_TAG_INT64: + g_args[i].v_int64 = * (glong *) args[i]; + break; + case GI_TYPE_TAG_ULONG: + case GI_TYPE_TAG_UINT64: + g_args[i].v_uint64 = * (glong *) args[i]; + break; + case GI_TYPE_TAG_INT: + case GI_TYPE_TAG_SSIZE: + case GI_TYPE_TAG_SIZE: + g_args[i].v_int32 = * (gint *) args[i]; + break; + case GI_TYPE_TAG_UINT: + g_args[i].v_uint32 = * (guint *) args[i]; + break; + case GI_TYPE_TAG_FLOAT: + g_args[i].v_float = * (gfloat *) args[i]; + break; + case GI_TYPE_TAG_DOUBLE: + g_args[i].v_double = * (gdouble *) args[i]; + break; + case GI_TYPE_TAG_UTF8: + g_args[i].v_string = * (gchar **) args[i]; + break; + case GI_TYPE_TAG_INTERFACE: + { + GIBaseInfo *interface; + GIInfoType interface_type; + + interface = g_type_info_get_interface (arg_type); + interface_type = g_base_info_get_type (interface); + + if (interface_type == GI_INFO_TYPE_OBJECT || + interface_type == GI_INFO_TYPE_INTERFACE) { + g_args[i].v_pointer = * (gpointer *) args[i]; + g_base_info_unref (interface); + break; + } else if (interface_type == GI_INFO_TYPE_ENUM || + interface_type == GI_INFO_TYPE_FLAGS) { + g_args[i].v_double = * (double *) args[i]; + g_base_info_unref (interface); + break; + } else if (interface_type == GI_INFO_TYPE_STRUCT) { + g_args[i].v_pointer = * (gpointer *) args[i]; + g_base_info_unref (interface); + break; + } + + g_base_info_unref (interface); + } + case GI_TYPE_TAG_GLIST: + case GI_TYPE_TAG_GSLIST: + g_args[i].v_pointer = * (gpointer *) args[i]; + break; + default: + g_args[i].v_pointer = 0; + } + } + g_base_info_unref ( (GIBaseInfo *) arg_info); + g_base_info_unref ( (GIBaseInfo *) arg_type); + } + return g_args; +} + +static gboolean +_pygi_closure_convert_arguments (GICallableInfo *callable_info, void **args, + void *user_data, PyObject **py_args, + GArgument **out_args) +{ + int n_args = g_callable_info_get_n_args (callable_info); + int n_in_args = 0; + int n_out_args = 0; + int i; + GArgument *g_args = NULL; + + *py_args = NULL; + *py_args = PyTuple_New (n_args); + if (*py_args == NULL) + goto error; + + *out_args = NULL; + *out_args = g_new0 (GArgument, n_args); + g_args = _pygi_closure_convert_ffi_arguments (callable_info, args); + + for (i = 0; i < n_args; i++) { + GIArgInfo *arg_info = g_callable_info_get_arg (callable_info, i); + GIDirection direction = g_arg_info_get_direction (arg_info); + + if (direction == GI_DIRECTION_IN || direction == GI_DIRECTION_INOUT) { + GITypeInfo *arg_type = g_arg_info_get_type (arg_info); + GITypeTag arg_tag = g_type_info_get_tag (arg_type); + GITransfer transfer = g_arg_info_get_ownership_transfer (arg_info); + PyObject *value; + GArgument *arg; + + if (direction == GI_DIRECTION_IN && arg_tag == GI_TYPE_TAG_VOID && + g_type_info_is_pointer (arg_type)) { + + if (user_data == NULL) { + Py_INCREF (Py_None); + value = Py_None; + } else { + value = user_data; + Py_INCREF (value); + } + } else { + if (direction == GI_DIRECTION_IN) + arg = (GArgument*) &g_args[i]; + else + arg = (GArgument*) g_args[i].v_pointer; + + value = _pygi_argument_to_object (arg, arg_type, transfer); + if (value == NULL) { + g_base_info_unref (arg_type); + g_base_info_unref (arg_info); + goto error; + } + } + PyTuple_SET_ITEM (*py_args, n_in_args, value); + n_in_args++; + + g_base_info_unref (arg_type); + } + + if (direction == GI_DIRECTION_OUT || direction == GI_DIRECTION_INOUT) { + (*out_args) [n_out_args] = g_args[i]; + n_out_args++; + } + + g_base_info_unref (arg_info); + } + + if (_PyTuple_Resize (py_args, n_in_args) == -1) + goto error; + + return TRUE; + +error: + Py_CLEAR (*py_args); + + if (*out_args != NULL) + g_free (*out_args); + + if (g_args != NULL) + g_free (g_args); + + return FALSE; +} + +static void +_pygi_closure_set_out_arguments (GICallableInfo *callable_info, + PyObject *py_retval, GArgument *out_args, + void *resp) +{ + int n_args, i, i_py_retval, i_out_args; + GITypeInfo *return_type_info; + GITypeTag return_type_tag; + + i_py_retval = 0; + return_type_info = g_callable_info_get_return_type (callable_info); + return_type_tag = g_type_info_get_tag (return_type_info); + if (return_type_tag != GI_TYPE_TAG_VOID) { + GArgument arg; + GITransfer transfer = g_callable_info_get_caller_owns (callable_info); + if (PyTuple_Check (py_retval)) { + PyObject *item = PyTuple_GET_ITEM (py_retval, 0); + arg = _pygi_argument_from_object (item, return_type_info, transfer); + * ( (GArgument*) resp) = arg; + } else { + arg = _pygi_argument_from_object (py_retval, return_type_info, transfer); + * ( (GArgument*) resp) = arg; + } + i_py_retval++; + } + g_base_info_unref (return_type_info); + + i_out_args = 0; + n_args = g_callable_info_get_n_args (callable_info); + for (i = 1; i < n_args; i++) { + GIArgInfo *arg_info = g_callable_info_get_arg (callable_info, i); + GITypeInfo *type_info = g_arg_info_get_type (arg_info); + GIDirection direction = g_arg_info_get_direction (arg_info); + + if (direction == GI_DIRECTION_OUT || direction == GI_DIRECTION_INOUT) { + GITransfer transfer = g_arg_info_get_ownership_transfer (arg_info); + GArgument arg; + if (PyTuple_Check (py_retval)) { + PyObject *item = PyTuple_GET_ITEM (py_retval, i_py_retval); + arg = _pygi_argument_from_object (item, type_info, transfer); + * ( (GArgument*) out_args[i_out_args].v_pointer) = arg; + } else if (i_py_retval == 0) { + arg = _pygi_argument_from_object (py_retval, type_info, transfer); + * ( (GArgument*) out_args[i_out_args].v_pointer) = arg; + } else + g_assert_not_reached(); + + i_out_args++; + i_py_retval++; + } + g_base_info_unref (type_info); + g_base_info_unref (arg_info); + } +} + +void +_pygi_closure_handle (ffi_cif *cif, + void *result, + void **args, + void *data) +{ + PyGILState_STATE state; + PyGICClosure *closure = data; + GITypeTag return_tag; + GITransfer return_transfer; + GITypeInfo *return_type; + PyObject *retval; + PyObject *py_args; + GArgument *out_args; + + /* Lock the GIL as we are coming into this code without the lock and we + may be executing python code */ + state = PyGILState_Ensure(); + + return_type = g_callable_info_get_return_type (closure->info); + return_tag = g_type_info_get_tag (return_type); + return_transfer = g_callable_info_get_caller_owns (closure->info); + + if (!_pygi_closure_convert_arguments ( (GICallableInfo *) closure->info, args, + closure->user_data, + &py_args, &out_args)) { + if (PyErr_Occurred ()) + PyErr_Print(); + goto end; + } + + retval = PyObject_CallObject ( (PyObject *) closure->function, py_args); + Py_DECREF (py_args); + + if (retval == NULL) { + PyErr_Print(); + goto end; + } + + _pygi_closure_set_out_arguments (closure->info, retval, out_args, result); + +end: + g_base_info_unref ( (GIBaseInfo*) return_type); + + PyGILState_Release (state); + + /* Now that the closure has finished we can make a decision about how + to free it. Scope call gets free'd at the end of wrap_g_function_info_invoke + scope notified will be freed, when the notify is called and we can free async + anytime we want as long as its after we return from this function (you can't free the closure + you are currently using!) + */ + switch (closure->scope) { + case GI_SCOPE_TYPE_CALL: + case GI_SCOPE_TYPE_NOTIFIED: + break; + case GI_SCOPE_TYPE_ASYNC: + /* Append this PyGICClosure to a list of closure that we will free + after we're done with this function invokation */ + async_free_list = g_slist_prepend (async_free_list, closure); + break; + default: + g_error ("Invalid scope reached inside %s. Possibly a bad annotation?", + g_base_info_get_name (closure->info)); + } +} + +void _pygi_invoke_closure_free (gpointer data) +{ + PyGICClosure* invoke_closure = (PyGICClosure *) data; + + Py_DECREF (invoke_closure->function); + + g_callable_info_free_closure (invoke_closure->info, + invoke_closure->closure); + + if (invoke_closure->info) + g_base_info_unref ( (GIBaseInfo*) invoke_closure->info); + + Py_XDECREF (invoke_closure->user_data); + + g_slice_free (PyGICClosure, invoke_closure); +} + + +PyGICClosure* +_pygi_make_native_closure (GICallableInfo* info, + GIScopeType scope, + PyObject *py_function, + gpointer py_user_data) +{ + PyGICClosure *closure; + ffi_closure *fficlosure; + + /* Begin by cleaning up old async functions */ + g_slist_foreach (async_free_list, (GFunc) _pygi_invoke_closure_free, NULL); + g_slist_free (async_free_list); + async_free_list = NULL; + + /* Build the closure itself */ + closure = g_slice_new0 (PyGICClosure); + closure->info = (GICallableInfo *) g_base_info_ref ( (GIBaseInfo *) info); + closure->function = py_function; + closure->user_data = py_user_data; + + Py_INCREF (py_function); + if (closure->user_data) + Py_INCREF (closure->user_data); + + fficlosure = + g_callable_info_prepare_closure (info, &closure->cif, _pygi_closure_handle, + closure); + closure->closure = fficlosure; + + /* Give the closure the information it needs to determine when + to free itself later */ + closure->scope = scope; + + return closure; +} diff --git a/gi/pygi-closure.h b/gi/pygi-closure.h new file mode 100644 index 0000000..6f98339 --- /dev/null +++ b/gi/pygi-closure.h @@ -0,0 +1,57 @@ +/* -*- Mode: C; c-basic-offset: 4 -*- + * vim: tabstop=4 shiftwidth=4 expandtab + * + * 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_CLOSURE_H__ +#define __PYGI_CLOSURE_H__ + +#include <Python.h> +#include <girffi.h> +#include <ffi.h> + +G_BEGIN_DECLS + + +/* Private */ + +typedef struct _PyGICClosure +{ + GICallableInfo *info; + PyObject *function; + + ffi_closure *closure; + ffi_cif cif; + + GIScopeType scope; + + PyObject* user_data; +} PyGICClosure; + +void _pygi_closure_handle (ffi_cif *cif, void *result, void + **args, void *userdata); + +void _pygi_invoke_closure_free (gpointer user_data); + +PyGICClosure* _pygi_make_native_closure (GICallableInfo* info, + GIScopeType scope, + PyObject *function, + gpointer user_data); + +G_END_DECLS + +#endif /* __PYGI_CLOSURE_H__ */ diff --git a/gi/pygi-foreign-cairo.c b/gi/pygi-foreign-cairo.c new file mode 100644 index 0000000..08d50ad --- /dev/null +++ b/gi/pygi-foreign-cairo.c @@ -0,0 +1,131 @@ +/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */ +/* + * Copyright (c) 2010 Collabora Ltd. <http://www.collabora.co.uk/> + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include <cairo.h> +#include <pycairo.h> +Pycairo_CAPI_t *Pycairo_CAPI; + +#include "pygi-foreign.h" + +PyObject * +cairo_context_to_arg (PyObject *value, + GITypeInfo *type_info, + GITransfer transfer, + GArgument *arg) +{ + cairo_t *cr; + + g_assert (transfer == GI_TRANSFER_NOTHING); + + cr = PycairoContext_GET (value); + if (!cr) { + return NULL; + } + + arg->v_pointer = cr; + Py_RETURN_NONE; +} + +PyObject * +cairo_context_from_arg (GITypeInfo *type_info, GArgument *arg) +{ + cairo_t *context = (cairo_t*) arg; + + cairo_reference (context); + + return PycairoContext_FromContext (context, &PycairoContext_Type, NULL); +} + +PyObject * +cairo_context_release_arg (GITransfer transfer, GITypeInfo *type_info, + GArgument *arg) +{ + cairo_destroy ( (cairo_t*) arg->v_pointer); + Py_RETURN_NONE; +} + + +PyObject * +cairo_surface_to_arg (PyObject *value, + GITypeInfo *type_info, + GITransfer transfer, + GArgument *arg) +{ + cairo_surface_t *surface; + + g_assert (transfer == GI_TRANSFER_NOTHING); + + surface = ( (PycairoSurface*) value)->surface; + if (!surface) { + PyErr_SetString (PyExc_ValueError, "Surface instance wrapping a NULL surface"); + return NULL; + } + + arg->v_pointer = surface; + Py_RETURN_NONE; +} + +PyObject * +cairo_surface_from_arg (GITypeInfo *type_info, GArgument *arg) +{ + cairo_surface_t *surface = (cairo_surface_t*) arg; + + cairo_surface_reference (surface); + + return PycairoSurface_FromSurface (surface, NULL); +} + +PyObject * +cairo_surface_release_arg (GITransfer transfer, GITypeInfo *type_info, + GArgument *arg) +{ + cairo_surface_destroy ( (cairo_surface_t*) arg->v_pointer); + Py_RETURN_NONE; +} + +PyMODINIT_FUNC +init_gi_cairo (void) +{ + PyObject *m; + + m = Py_InitModule ("_gi_cairo", NULL); + if (m == NULL) { + return; + } + + Pycairo_IMPORT; + if (Pycairo_CAPI == NULL) + return; + + pygi_register_foreign_struct ("cairo", + "Context", + cairo_context_to_arg, + cairo_context_from_arg, + cairo_context_release_arg); + + pygi_register_foreign_struct ("cairo", + "Surface", + cairo_surface_to_arg, + cairo_surface_from_arg, + cairo_surface_release_arg); +} diff --git a/gi/pygi-foreign.c b/gi/pygi-foreign.c new file mode 100644 index 0000000..13a0f77 --- /dev/null +++ b/gi/pygi-foreign.c @@ -0,0 +1,148 @@ +/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */ +/* + * Copyright (c) 2010 litl, LLC + * Copyright (c) 2010 Collabora Ltd. <http://www.collabora.co.uk/> + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "pygi-foreign.h" + +#include <config.h> +#include <girepository.h> + +typedef struct { + const char *namespace; + const char *name; + PyGIArgOverrideToGArgumentFunc to_func; + PyGIArgOverrideFromGArgumentFunc from_func; + PyGIArgOverrideReleaseGArgumentFunc release_func; +} PyGIForeignStruct; + +static GPtrArray *foreign_structs = NULL; + +static PyGIForeignStruct * +pygi_struct_foreign_lookup (GITypeInfo *type_info) +{ + gint i; + PyObject *module; + gchar *module_name; + GIBaseInfo *base_info; + const gchar *namespace; + const gchar *name; + + base_info = g_type_info_get_interface (type_info); + if (base_info == NULL) { + PyErr_Format (PyExc_ValueError, "Couldn't resolve the type of this foreign struct"); + return NULL; + } + + namespace = g_base_info_get_namespace (base_info); + name = g_base_info_get_name (base_info); + + module_name = g_strconcat ("gi._gi_", g_base_info_get_namespace (base_info), NULL); + module = PyImport_ImportModule (module_name); + g_free (module_name); + + if (foreign_structs != NULL) { + for (i = 0; i < foreign_structs->len; i++) { + PyGIForeignStruct *foreign_struct = \ + g_ptr_array_index (foreign_structs, i); + + if ( (strcmp (namespace, foreign_struct->namespace) == 0) && + (strcmp (name, foreign_struct->name) == 0)) { + g_base_info_unref (base_info); + return foreign_struct; + } + } + } + + g_base_info_unref (base_info); + + PyErr_Format (PyExc_TypeError, "Couldn't find conversion for foreign struct '%s.%s'", namespace, name); + return NULL; +} + +PyObject * +pygi_struct_foreign_convert_to_g_argument (PyObject *value, + GITypeInfo *type_info, + GITransfer transfer, + GArgument *arg) +{ + PyGIForeignStruct *foreign_struct = pygi_struct_foreign_lookup (type_info); + + if (foreign_struct == NULL) + return NULL; + + if (!foreign_struct->to_func (value, type_info, transfer, arg)) + return NULL; + + Py_RETURN_NONE; +} + +PyObject * +pygi_struct_foreign_convert_from_g_argument (GITypeInfo *type_info, + GArgument *arg) +{ + PyGIForeignStruct *foreign_struct = pygi_struct_foreign_lookup (type_info); + + if (foreign_struct == NULL) + return NULL; + + return foreign_struct->from_func (type_info, arg); +} + +PyObject * +pygi_struct_foreign_release_g_argument (GITransfer transfer, + GITypeInfo *type_info, + GArgument *arg) +{ + PyGIForeignStruct *foreign_struct = pygi_struct_foreign_lookup (type_info); + + if (foreign_struct == NULL) + return NULL; + + if (!foreign_struct->release_func) + Py_RETURN_NONE; + + if (!foreign_struct->release_func (transfer, type_info, arg)) + return NULL; + + Py_RETURN_NONE; +} + +void +pygi_register_foreign_struct_real (const char* namespace_, + const char* name, + PyGIArgOverrideToGArgumentFunc to_func, + PyGIArgOverrideFromGArgumentFunc from_func, + PyGIArgOverrideReleaseGArgumentFunc release_func) +{ + PyGIForeignStruct *new_struct = g_slice_new0 (PyGIForeignStruct); + new_struct->namespace = namespace_; + new_struct->name = name; + new_struct->to_func = to_func; + new_struct->from_func = from_func; + new_struct->release_func = release_func; + + if (foreign_structs == NULL) + foreign_structs = g_ptr_array_new (); + + g_ptr_array_add (foreign_structs, new_struct); +} diff --git a/gi/pygi-foreign.h b/gi/pygi-foreign.h new file mode 100644 index 0000000..9a35bd8 --- /dev/null +++ b/gi/pygi-foreign.h @@ -0,0 +1,49 @@ +/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */ +/* + * Copyright (c) 2010 litl, LLC + * Copyright (c) 2010 Collabora Ltd. <http://www.collabora.co.uk/> + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef __PYGI_FOREIGN_H__ +#define __PYGI_FOREIGN_H__ + +#include <Python.h> +#include <girepository.h> + +#include "pygi.h" + +PyObject *pygi_struct_foreign_convert_to_g_argument (PyObject *value, + GITypeInfo *type_info, + GITransfer transfer, + GArgument *arg); +PyObject *pygi_struct_foreign_convert_from_g_argument (GITypeInfo *type_info, + GArgument *arg); +PyObject *pygi_struct_foreign_release_g_argument (GITransfer transfer, + GITypeInfo *type_info, + GArgument *arg); + +void pygi_register_foreign_struct_real (const char* namespace_, + const char* name, + PyGIArgOverrideToGArgumentFunc to_func, + PyGIArgOverrideFromGArgumentFunc from_func, + PyGIArgOverrideReleaseGArgumentFunc release_func); + +#endif /* __PYGI_FOREIGN_H__ */ diff --git a/gi/pygi-info.c b/gi/pygi-info.c new file mode 100644 index 0000000..3d23271 --- /dev/null +++ b/gi/pygi-info.c @@ -0,0 +1,1521 @@ +/* -*- 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: + type = &PyGIUnionInfo_Type; + break; + 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: + type = &PyGIVFuncInfo_Type; + break; + 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; + + 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: + if (g_type_info_is_pointer (type_info)) { + size = sizeof (gpointer); + } else { + 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: + if (g_type_info_is_pointer (type_info)) { + size = sizeof (gpointer); + } else { + size = g_struct_info_get_size ( (GIStructInfo *) info); + } + break; + case GI_INFO_TYPE_UNION: + if (g_type_info_is_pointer (type_info)) { + size = sizeof (gpointer); + } else { + size = g_union_info_get_size ( (GIUnionInfo *) info); + } + break; + case GI_INFO_TYPE_ENUM: + case GI_INFO_TYPE_FLAGS: + if (g_type_info_is_pointer (type_info)) { + size = sizeof (gpointer); + } else { + 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: + size = sizeof (gpointer); + break; + 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: + size = sizeof (gpointer); + break; + } + + return size; +} + +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 * +_get_fields (PyGIBaseInfo *self, GIInfoType info_type) +{ + gssize n_infos; + PyObject *infos; + gssize i; + + switch (info_type) { + case GI_INFO_TYPE_STRUCT: + n_infos = g_struct_info_get_n_fields ( (GIStructInfo *) self->info); + break; + case GI_INFO_TYPE_OBJECT: + n_infos = g_object_info_get_n_fields ( (GIObjectInfo *) self->info); + break; + default: + g_assert_not_reached(); + } + + infos = PyTuple_New (n_infos); + if (infos == NULL) { + return NULL; + } + + for (i = 0; i < n_infos; i++) { + GIBaseInfo *info; + PyObject *py_info; + + switch (info_type) { + case GI_INFO_TYPE_STRUCT: + info = (GIBaseInfo *) g_struct_info_get_field ( (GIStructInfo *) self->info, i); + break; + case GI_INFO_TYPE_OBJECT: + info = (GIBaseInfo *) g_object_info_get_field ( (GIObjectInfo *) self->info, i); + break; + default: + g_assert_not_reached(); + } + 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 * +_get_methods (PyGIBaseInfo *self, GIInfoType info_type) +{ + gssize n_infos; + PyObject *infos; + gssize i; + + switch (info_type) { + case GI_INFO_TYPE_STRUCT: + n_infos = g_struct_info_get_n_methods ( (GIStructInfo *) self->info); + break; + case GI_INFO_TYPE_OBJECT: + n_infos = g_object_info_get_n_methods ( (GIObjectInfo *) self->info); + break; + default: + g_assert_not_reached(); + } + + infos = PyTuple_New (n_infos); + if (infos == NULL) { + return NULL; + } + + for (i = 0; i < n_infos; i++) { + GIBaseInfo *info; + PyObject *py_info; + + switch (info_type) { + case GI_INFO_TYPE_STRUCT: + info = (GIBaseInfo *) g_struct_info_get_method ( (GIStructInfo *) self->info, i); + break; + case GI_INFO_TYPE_OBJECT: + info = (GIBaseInfo *) g_object_info_get_method ( (GIObjectInfo *) self->info, i); + break; + default: + g_assert_not_reached(); + } + 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 * +_get_constants (PyGIBaseInfo *self, GIInfoType info_type) +{ + gssize n_infos; + PyObject *infos; + gssize i; + + switch (info_type) { + case GI_INFO_TYPE_INTERFACE: + n_infos = g_interface_info_get_n_constants ( (GIInterfaceInfo *) self->info); + break; + case GI_INFO_TYPE_OBJECT: + n_infos = g_object_info_get_n_constants ( (GIObjectInfo *) self->info); + break; + default: + g_assert_not_reached(); + } + + infos = PyTuple_New (n_infos); + if (infos == NULL) { + return NULL; + } + + for (i = 0; i < n_infos; i++) { + GIBaseInfo *info; + PyObject *py_info; + + switch (info_type) { + case GI_INFO_TYPE_INTERFACE: + info = (GIBaseInfo *) g_interface_info_get_constant ( (GIInterfaceInfo *) self->info, i); + break; + case GI_INFO_TYPE_OBJECT: + info = (GIBaseInfo *) g_object_info_get_constant ( (GIObjectInfo *) self->info, i); + break; + default: + g_assert_not_reached(); + } + 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 * +_get_vfuncs (PyGIBaseInfo *self, GIInfoType info_type) +{ + gssize n_infos; + PyObject *infos; + gssize i; + + switch (info_type) { + case GI_INFO_TYPE_INTERFACE: + n_infos = g_interface_info_get_n_vfuncs ( (GIInterfaceInfo *) self->info); + break; + case GI_INFO_TYPE_OBJECT: + n_infos = g_object_info_get_n_vfuncs ( (GIObjectInfo *) self->info); + break; + default: + g_assert_not_reached(); + } + + infos = PyTuple_New (n_infos); + if (infos == NULL) { + return NULL; + } + + for (i = 0; i < n_infos; i++) { + GIBaseInfo *info; + PyObject *py_info; + + switch (info_type) { + case GI_INFO_TYPE_INTERFACE: + info = (GIBaseInfo *) g_interface_info_get_vfunc ( (GIInterfaceInfo *) self->info, i); + break; + case GI_INFO_TYPE_OBJECT: + info = (GIBaseInfo *) g_object_info_get_vfunc ( (GIObjectInfo *) self->info, i); + break; + default: + g_assert_not_reached(); + } + 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_fields (PyGIBaseInfo *self) +{ + return _get_fields (self, GI_INFO_TYPE_STRUCT); +} + +static PyObject * +_wrap_g_struct_info_get_methods (PyGIBaseInfo *self) +{ + return _get_methods (self, GI_INFO_TYPE_STRUCT); +} + +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; + + field_info = g_struct_info_get_field (struct_info, i); + field_type_info = g_field_info_get_type (field_info); + + 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: + if (g_type_info_is_pointer (field_type_info)) { + is_simple = FALSE; + } + 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: + is_simple = FALSE; + 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_STRUCT: + if (g_type_info_is_pointer (field_type_info)) { + is_simple = FALSE; + } else { + 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: + if (g_type_info_is_pointer (field_type_info)) { + is_simple = FALSE; + } + break; + case GI_INFO_TYPE_BOXED: + case GI_INFO_TYPE_OBJECT: + case GI_INFO_TYPE_CALLBACK: + case GI_INFO_TYPE_INTERFACE: + is_simple = FALSE; + break; + 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(); + } + + 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) +{ + return _get_methods (self, GI_INFO_TYPE_OBJECT); +} + +static PyObject * +_wrap_g_object_info_get_fields (PyGIBaseInfo *self) +{ + return _get_fields (self, GI_INFO_TYPE_OBJECT); +} + +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) +{ + return _get_constants (self, GI_INFO_TYPE_OBJECT); +} + +static PyObject * +_wrap_g_object_info_get_vfuncs (PyGIBaseInfo *self) +{ + return _get_vfuncs (self, GI_INFO_TYPE_OBJECT); +} + +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 }, + { "get_vfuncs", (PyCFunction) _wrap_g_object_info_get_vfuncs, 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) +{ + return _get_constants (self, GI_INFO_TYPE_INTERFACE); +} + +static PyObject * +_wrap_g_interface_info_get_vfuncs (PyGIBaseInfo *self) +{ + return _get_vfuncs (self, GI_INFO_TYPE_INTERFACE); +} + +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 }, + { "get_vfuncs", (PyCFunction) _wrap_g_interface_info_get_vfuncs, 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; + + memset(&value, 0, sizeof(GArgument)); + + 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: + 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; + } + + if ( (g_type_info_get_tag (field_type_info) == GI_TYPE_TAG_ARRAY) && + (g_type_info_get_array_type (field_type_info) == GI_ARRAY_TYPE_C)) { + value.v_pointer = _pygi_argument_to_array (&value, NULL, + field_type_info, FALSE); + } + +argument_to_object: + py_value = _pygi_argument_to_object (&value, field_type_info, GI_TRANSFER_NOTHING); + + if ( (value.v_pointer != NULL) && + (g_type_info_get_tag (field_type_info) == GI_TYPE_TAG_ARRAY) && + (g_type_info_get_array_type (field_type_info) == GI_ARRAY_TYPE_C)) { + g_array_free (value.v_pointer, FALSE); + } + +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: + 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, py_value, TRUE); + 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 } +}; + +/* GIVFuncInfo */ +_PyGI_DEFINE_INFO_TYPE ("VFuncInfo", GIVFuncInfo, PyGIBaseInfo_Type); + +static PyMethodDef _PyGIVFuncInfo_methods[] = { + { NULL, NULL, 0 } +}; + + +/* GIUnionInfo */ +_PyGI_DEFINE_INFO_TYPE ("UnionInfo", GIUnionInfo, PyGIRegisteredTypeInfo_Type); + +static PyObject * +_wrap_g_union_info_get_fields (PyGIBaseInfo *self) +{ + gssize n_infos; + PyObject *infos; + gssize i; + + n_infos = g_union_info_get_n_fields ( (GIUnionInfo *) 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_union_info_get_field ( (GIUnionInfo *) 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_union_info_get_methods (PyGIBaseInfo *self) +{ + gssize n_infos; + PyObject *infos; + gssize i; + + n_infos = g_union_info_get_n_methods ( (GIUnionInfo *) 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_union_info_get_method ( (GIUnionInfo *) 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 _PyGIUnionInfo_methods[] = { + { "get_fields", (PyCFunction) _wrap_g_union_info_get_fields, METH_NOARGS }, + { "get_methods", (PyCFunction) _wrap_g_union_info_get_methods, METH_NOARGS }, + { 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"); + _PyGI_REGISTER_TYPE (m, PyGIVFuncInfo_Type, "VFuncInfo"); + _PyGI_REGISTER_TYPE (m, PyGIUnionInfo_Type, "UnionInfo"); + +#undef _PyGI_REGISTER_TYPE +} diff --git a/gi/pygi-info.h b/gi/pygi-info.h new file mode 100644 index 0000000..0d2bade --- /dev/null +++ b/gi/pygi-info.h @@ -0,0 +1,66 @@ +/* -*- 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; +extern PyTypeObject PyGIVFuncInfo_Type; +extern PyTypeObject PyGIUnionInfo_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-invoke.c b/gi/pygi-invoke.c new file mode 100644 index 0000000..214d500 --- /dev/null +++ b/gi/pygi-invoke.c @@ -0,0 +1,1007 @@ +/* -*- Mode: C; c-basic-offset: 4 -*- + * vim: tabstop=4 shiftwidth=4 expandtab + * + * Copyright (C) 2005-2009 Johan Dahlin <johan@gnome.org> + * + * pygi-invoke.c: main invocation function + * + * 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-invoke.h" + +struct invocation_state +{ + 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; + + guint8 callback_index; + guint8 user_data_index; + guint8 destroy_notify_index; + PyGICClosure *closure; + + 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; +}; + +static void +_initialize_invocation_state (struct invocation_state *state, + GIFunctionInfo *info, + PyObject *py_args) +{ + GIFunctionInfoFlags flags; + + flags = g_function_info_get_flags (info); + state->is_method = (flags & GI_FUNCTION_IS_METHOD) != 0; + state->is_constructor = (flags & GI_FUNCTION_IS_CONSTRUCTOR) != 0; + + /* Count arguments. */ + state->n_args = g_callable_info_get_n_args ( (GICallableInfo *) info); + state->n_in_args = 0; + state->n_out_args = 0; + state->n_backup_args = 0; + state->n_aux_in_args = 0; + state->n_aux_out_args = 0; + + /* Check the argument count. */ + state->n_py_args = PyTuple_Size (py_args); + g_assert (state->n_py_args >= 0); + + state->error_arg_pos = -1; + + state->arg_infos = g_slice_alloc0 (sizeof (gpointer) * state->n_args); + state->arg_type_infos = g_slice_alloc0 (sizeof (gpointer) * state->n_args); + state->args_is_auxiliary = g_slice_alloc0 (sizeof (gboolean) * state->n_args); + + state->return_value = NULL; + state->closure = NULL; + state->return_type_info = NULL; + state->args = NULL; + state->in_args = NULL; + state->out_args = NULL; + state->out_values = NULL; + state->backup_args = NULL; +} + +static gboolean +_prepare_invocation_state (struct invocation_state *state, + GIFunctionInfo *function_info, PyObject *py_args) +{ + gsize i; + + if (!_pygi_scan_for_callbacks (function_info, + state->is_method, + &state->callback_index, &state->user_data_index, + &state->destroy_notify_index)) + return FALSE; + + if (state->callback_index != G_MAXUINT8) { + + if (!_pygi_create_callback (function_info, + state->is_method, + state->is_constructor, + state->n_args, state->n_py_args, + py_args, state->callback_index, + state->user_data_index, + state->destroy_notify_index, &state->closure)) + return FALSE; + + state->args_is_auxiliary[state->callback_index] = FALSE; + if (state->destroy_notify_index != G_MAXUINT8) { + state->args_is_auxiliary[state->destroy_notify_index] = TRUE; + state->n_aux_in_args += 1; + } + } + + if (state->is_method) { + /* The first argument is the instance. */ + state->n_in_args += 1; + } + + /* We do a first (well, second) pass here over the function to scan for special cases. + * This is currently array+length combinations, GError and GValue. + */ + for (i = 0; i < state->n_args; i++) { + GIDirection direction; + GITransfer transfer; + GITypeTag arg_type_tag; + + state->arg_infos[i] = g_callable_info_get_arg ( (GICallableInfo *) function_info, + i); + + state->arg_type_infos[i] = g_arg_info_get_type (state->arg_infos[i]); + + direction = g_arg_info_get_direction (state->arg_infos[i]); + transfer = g_arg_info_get_ownership_transfer (state->arg_infos[i]); + arg_type_tag = g_type_info_get_tag (state->arg_type_infos[i]); + + if (direction == GI_DIRECTION_IN || direction == GI_DIRECTION_INOUT) { + state->n_in_args += 1; + if (transfer == GI_TRANSFER_CONTAINER) { + state->n_backup_args += 1; + } + } + if (direction == GI_DIRECTION_OUT || direction == GI_DIRECTION_INOUT) { + state->n_out_args += 1; + } + + if (direction == GI_DIRECTION_INOUT && transfer == GI_TRANSFER_NOTHING) { + state->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 (state->arg_type_infos[i]); + + if (state->is_method) + length_arg_pos--; // length_arg_pos refers to C args + + if (length_arg_pos < 0) { + break; + } + + g_assert (length_arg_pos < state->n_args); + state->args_is_auxiliary[length_arg_pos] = TRUE; + + if (direction == GI_DIRECTION_IN || direction == GI_DIRECTION_INOUT) { + state->n_aux_in_args += 1; + } + if (direction == GI_DIRECTION_OUT || direction == GI_DIRECTION_INOUT) { + state->n_aux_out_args += 1; + } + + break; + } + case GI_TYPE_TAG_ERROR: + g_warn_if_fail (state->error_arg_pos < 0); + state->error_arg_pos = i; + break; + default: + break; + } + } + + state->return_type_info = g_callable_info_get_return_type ( (GICallableInfo *) function_info); + state->return_type_tag = g_type_info_get_tag (state->return_type_info); + + if (state->return_type_tag == GI_TYPE_TAG_ARRAY) { + gint length_arg_pos; + length_arg_pos = g_type_info_get_array_length (state->return_type_info); + + if (state->is_method) + length_arg_pos--; // length_arg_pos refers to C args + + if (length_arg_pos >= 0) { + g_assert (length_arg_pos < state->n_args); + state->args_is_auxiliary[length_arg_pos] = TRUE; + state->n_aux_out_args += 1; + } + } + + state->n_return_values = state->n_out_args - state->n_aux_out_args; + if (state->return_type_tag != GI_TYPE_TAG_VOID) { + state->n_return_values += 1; + } + + { + gsize n_py_args_expected; + Py_ssize_t py_args_pos; + + n_py_args_expected = state->n_in_args + + (state->is_constructor ? 1 : 0) + - state->n_aux_in_args + - (state->error_arg_pos >= 0 ? 1 : 0); + + if (state->n_py_args != n_py_args_expected) { + PyErr_Format (PyExc_TypeError, + "%s() takes exactly %zd argument(s) (%zd given)", + g_base_info_get_name ( (GIBaseInfo *) function_info), + n_py_args_expected, state->n_py_args); + return FALSE; + } + + /* Check argument typestate-> */ + py_args_pos = 0; + if (state->is_constructor || state->is_method) { + py_args_pos += 1; + } + + for (i = 0; i < state->n_args; i++) { + GIDirection direction; + GITypeTag type_tag; + PyObject *py_arg; + gint retval; + gboolean allow_none; + + direction = g_arg_info_get_direction (state->arg_infos[i]); + type_tag = g_type_info_get_tag (state->arg_type_infos[i]); + + if (direction == GI_DIRECTION_OUT + || state->args_is_auxiliary[i] + || type_tag == GI_TYPE_TAG_ERROR) { + continue; + } + + g_assert (py_args_pos < state->n_py_args); + py_arg = PyTuple_GET_ITEM (py_args, py_args_pos); + + allow_none = g_arg_info_may_be_null (state->arg_infos[i]); + + retval = _pygi_g_type_info_check_object (state->arg_type_infos[i], + py_arg, + allow_none); + + if (retval < 0) { + return FALSE; + } else if (!retval) { + _PyGI_ERROR_PREFIX ("argument %zd: ", py_args_pos); + return FALSE; + } + + py_args_pos += 1; + } + + g_assert (py_args_pos == state->n_py_args); + } + + state->args = g_slice_alloc0 (sizeof (gpointer) * state->n_args); + state->in_args = g_slice_alloc0 (sizeof (GArgument) * state->n_in_args); + state->out_args = g_slice_alloc0 (sizeof (GArgument) * state->n_out_args); + state->out_values = g_slice_alloc0 (sizeof (GArgument) * state->n_out_args); + state->backup_args = g_slice_alloc0 (sizeof (GArgument) * state->n_backup_args); + + /* Bind args so we can use an unique index. */ + { + gsize in_args_pos; + gsize out_args_pos; + + in_args_pos = state->is_method ? 1 : 0; + out_args_pos = 0; + + for (i = 0; i < state->n_args; i++) { + GIDirection direction; + GIBaseInfo *info; + gboolean is_caller_allocates; + + direction = g_arg_info_get_direction (state->arg_infos[i]); + is_caller_allocates = g_arg_info_is_caller_allocates (state->arg_infos[i]); + + switch (direction) { + case GI_DIRECTION_IN: + g_assert (in_args_pos < state->n_in_args); + state->args[i] = &state->in_args[in_args_pos]; + in_args_pos += 1; + break; + case GI_DIRECTION_INOUT: + g_assert (in_args_pos < state->n_in_args); + g_assert (out_args_pos < state->n_out_args); + + state->in_args[in_args_pos].v_pointer = &state->out_values[out_args_pos]; + in_args_pos += 1; + case GI_DIRECTION_OUT: + g_assert (out_args_pos < state->n_out_args); + + /* caller allocates only applies to structures but GI has + * no way to denote that yet, so we only use caller allocates + * if we see a structure + */ + if (is_caller_allocates) { + GITypeTag type_tag; + + is_caller_allocates = FALSE; + type_tag = g_type_info_get_tag (state->arg_type_infos[i]); + + if (type_tag == GI_TYPE_TAG_INTERFACE) { + GIInfoType info_type; + + info = g_type_info_get_interface (state->arg_type_infos[i]); + g_assert (info != NULL); + info_type = g_base_info_get_type (info); + + if (info_type == GI_INFO_TYPE_STRUCT) + is_caller_allocates = TRUE; + } + } + + if (is_caller_allocates) { + gsize size; + gpointer value; + + /* if caller allocates only use one level of indirection */ + state->out_args[out_args_pos].v_pointer = NULL; + state->args[i] = &state->out_args[out_args_pos]; + + /* FIXME: Remove when bgo#622711 is fixed */ + if (g_registered_type_info_get_g_type (info) == G_TYPE_VALUE) + size = sizeof (GValue); + else + size = g_struct_info_get_size ( (GIStructInfo *) info); + + state->args[i]->v_pointer = g_malloc0 (size); + } else { + state->out_args[out_args_pos].v_pointer = &state->out_values[out_args_pos]; + state->out_values[out_args_pos].v_pointer = NULL; + state->args[i] = &state->out_values[out_args_pos]; + } + + out_args_pos += 1; + } + } + + g_assert (in_args_pos == state->n_in_args); + g_assert (out_args_pos == state->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 (state->is_constructor) { + /* Skip the first argument. */ + py_args_pos += 1; + } else if (state->is_method) { + /* Get the instance. */ + GIBaseInfo *container_info; + GIInfoType container_info_type; + PyObject *py_arg; + + container_info = g_base_info_get_container (function_info); + container_info_type = g_base_info_get_type (container_info); + + g_assert (py_args_pos < state->n_py_args); + py_arg = PyTuple_GET_ITEM (py_args, py_args_pos); + + switch (container_info_type) { + case GI_INFO_TYPE_UNION: + 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 (state->n_in_args > 0); + state->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 (state->n_in_args > 0); + state->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)); + return FALSE; + } + + break; + } + case GI_INFO_TYPE_OBJECT: + case GI_INFO_TYPE_INTERFACE: + g_assert (state->n_in_args > 0); + state->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 < state->n_args; i++) { + GIDirection direction; + + if (i == state->callback_index) { + if (state->closure) + state->args[i]->v_pointer = state->closure->closure; + else + /* Some callbacks params accept NULL */ + state->args[i]->v_pointer = NULL; + py_args_pos++; + continue; + } else if (i == state->user_data_index) { + state->args[i]->v_pointer = state->closure; + py_args_pos++; + continue; + } else if (i == state->destroy_notify_index) { + if (state->closure) { + /* No need to clean up if the callback is NULL */ + PyGICClosure *destroy_notify = _pygi_destroy_notify_create(); + state->args[i]->v_pointer = destroy_notify->closure; + } + continue; + } + + if (state->args_is_auxiliary[i]) { + continue; + } + + direction = g_arg_info_get_direction (state->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 (state->arg_type_infos[i]); + + if (arg_type_tag == GI_TYPE_TAG_ERROR) { + GError **error; + + error = g_slice_new (GError *); + *error = NULL; + + state->args[i]->v_pointer = error; + continue; + } + + transfer = g_arg_info_get_ownership_transfer (state->arg_infos[i]); + + g_assert (py_args_pos < state->n_py_args); + py_arg = PyTuple_GET_ITEM (py_args, py_args_pos); + + *state->args[i] = _pygi_argument_from_object (py_arg, state->arg_type_infos[i], transfer); + + if (PyErr_Occurred()) { + /* TODO: release previous input arguments. */ + return FALSE; + } + + 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 < state->n_backup_args); + state->backup_args[backup_args_pos] = *state->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 = state->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 < state->n_backup_args); + state->backup_args[backup_args_pos].v_pointer = new_array; + + break; + } + case GI_TYPE_TAG_GLIST: + g_assert (backup_args_pos < state->n_backup_args); + state->backup_args[backup_args_pos].v_pointer = g_list_copy (state->args[i]->v_pointer); + break; + case GI_TYPE_TAG_GSLIST: + g_assert (backup_args_pos < state->n_backup_args); + state->backup_args[backup_args_pos].v_pointer = g_slist_copy (state->args[i]->v_pointer); + break; + case GI_TYPE_TAG_GHASH: + { + GHashTable *hash_table; + GList *keys; + GList *values; + + hash_table = state->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 < state->n_backup_args); + state->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 = state->args[i]->v_pointer; + + length_arg_pos = g_type_info_get_array_length (state->arg_type_infos[i]); + if (state->is_method) + length_arg_pos--; // length_arg_pos refers to C args + if (length_arg_pos >= 0) { + int len = 0; + /* Set the auxiliary argument holding the length. */ + if (array) + len = array->len; + + state->args[length_arg_pos]->v_size = len; + } + + /* Get rid of the GArray. */ + if ( (array != NULL) && + (g_type_info_get_array_type (state->arg_type_infos[i]) == GI_ARRAY_TYPE_C)) { + state->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 == state->n_py_args); + g_assert (backup_args_pos == state->n_backup_args); + } + + return TRUE; +} + +static gboolean +_invoke_function (struct invocation_state *state, + GIFunctionInfo *function_info, PyObject *py_args) +{ + GError *error; + gint retval; + + error = NULL; + + retval = g_function_info_invoke ( (GIFunctionInfo *) function_info, + state->in_args, state->n_in_args, state->out_args, state->n_out_args, &state->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. */ + + return FALSE; + } + + if (state->error_arg_pos >= 0) { + GError **error; + + error = state->args[state->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. */ + + return FALSE; + } + } + + return TRUE; +} + +static gboolean +_process_invocation_state (struct invocation_state *state, + GIFunctionInfo *function_info, PyObject *py_args) +{ + gsize i; + + /* Convert the return value. */ + if (state->is_constructor) { + PyTypeObject *py_type; + GIBaseInfo *info; + GIInfoType info_type; + GITransfer transfer; + + g_assert (state->n_py_args > 0); + py_type = (PyTypeObject *) PyTuple_GET_ITEM (py_args, 0); + + info = g_type_info_get_interface (state->return_type_info); + g_assert (info != NULL); + + info_type = g_base_info_get_type (info); + + transfer = g_callable_info_get_caller_owns ( (GICallableInfo *) function_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); + return FALSE; + 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 (state->return_arg.v_pointer == NULL) { + PyErr_SetString (PyExc_TypeError, "constructor returned NULL"); + break; + } + g_warn_if_fail (transfer == GI_TRANSFER_EVERYTHING); + state->return_value = _pygi_boxed_new (py_type, state->return_arg.v_pointer, transfer == GI_TRANSFER_EVERYTHING); + } else if (g_type_is_a (type, G_TYPE_POINTER) || type == G_TYPE_NONE) { + if (state->return_arg.v_pointer == NULL) { + PyErr_SetString (PyExc_TypeError, "constructor returned NULL"); + break; + } + + if (transfer != GI_TRANSFER_NOTHING) + g_warning ("Transfer mode should be set to None for " + "struct types as there is no way to free " + "them safely. Ignoring transfer mode " + "to prevent a potential invalid free. " + "This may cause a leak in your application."); + + state->return_value = _pygi_struct_new (py_type, state->return_arg.v_pointer, FALSE); + } else { + PyErr_Format (PyExc_TypeError, "cannot create '%s' instances", py_type->tp_name); + g_base_info_unref (info); + return FALSE; + } + + break; + } + case GI_INFO_TYPE_OBJECT: + if (state->return_arg.v_pointer == NULL) { + PyErr_SetString (PyExc_TypeError, "constructor returned NULL"); + break; + } + state->return_value = pygobject_new (state->return_arg.v_pointer); + if (transfer == GI_TRANSFER_EVERYTHING) { + /* The new wrapper increased the reference count, so decrease it. */ + g_object_unref (state->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 (state->return_value == NULL) { + /* TODO: release arguments. */ + return FALSE; + } + } else { + GITransfer transfer; + + if ( (state->return_type_tag == GI_TYPE_TAG_ARRAY) && + (g_type_info_get_array_type (state->return_type_info) == GI_ARRAY_TYPE_C)) { + /* Create a #GArray. */ + state->return_arg.v_pointer = _pygi_argument_to_array (&state->return_arg, state->args, state->return_type_info, state->is_method); + } + + transfer = g_callable_info_get_caller_owns ( (GICallableInfo *) function_info); + + state->return_value = _pygi_argument_to_object (&state->return_arg, state->return_type_info, transfer); + if (state->return_value == NULL) { + /* TODO: release argument. */ + return FALSE; + } + + _pygi_argument_release (&state->return_arg, state->return_type_info, transfer, GI_DIRECTION_OUT); + + if (state->return_type_tag == GI_TYPE_TAG_ARRAY + && transfer == GI_TRANSFER_NOTHING) { + /* We created a #GArray, so free it. */ + state->return_arg.v_pointer = g_array_free (state->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 (state->n_return_values > 1) { + /* Return a tuple. */ + PyObject *return_values; + + return_values = PyTuple_New (state->n_return_values); + if (return_values == NULL) { + /* TODO: release arguments. */ + return FALSE; + } + + if (state->return_type_tag == GI_TYPE_TAG_VOID) { + /* The current return value is None. */ + Py_DECREF (state->return_value); + } else { + /* Put the return value first. */ + g_assert (state->return_value != NULL); + PyTuple_SET_ITEM (return_values, return_values_pos, state->return_value); + return_values_pos += 1; + } + + state->return_value = return_values; + } + + for (i = 0; i < state->n_args; i++) { + GIDirection direction; + GITypeTag type_tag; + GITransfer transfer; + + if (state->args_is_auxiliary[i]) { + /* Auxiliary arguments are handled at the same time as their relatives. */ + continue; + } + + direction = g_arg_info_get_direction (state->arg_infos[i]); + transfer = g_arg_info_get_ownership_transfer (state->arg_infos[i]); + + type_tag = g_type_info_get_tag (state->arg_type_infos[i]); + + if ( (type_tag == GI_TYPE_TAG_ARRAY) && + (g_type_info_get_array_type (state->arg_type_infos[i]) == GI_ARRAY_TYPE_C) && + (direction != GI_DIRECTION_IN || transfer == GI_TRANSFER_NOTHING)) { + /* Create a #GArray. */ + state->args[i]->v_pointer = _pygi_argument_to_array (state->args[i], state->args, state->arg_type_infos[i], state->is_method); + } + + if (direction == GI_DIRECTION_INOUT || direction == GI_DIRECTION_OUT) { + /* Convert the argument. */ + PyObject *obj; + + obj = _pygi_argument_to_object (state->args[i], state->arg_type_infos[i], transfer); + if (obj == NULL) { + /* TODO: release arguments. */ + return FALSE; + } + + g_assert (return_values_pos < state->n_return_values); + + if (state->n_return_values > 1) { + PyTuple_SET_ITEM (state->return_value, return_values_pos, obj); + } else { + /* The current return value is None. */ + Py_DECREF (state->return_value); + state->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 < state->n_backup_args); + _pygi_argument_release (&state->backup_args[backup_args_pos], state->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 (state->arg_type_infos[i], 0); + value_type_info = g_type_info_get_param_type (state->arg_type_infos[i], 1); + + g_assert (backup_args_pos < state->n_backup_args); + item = state->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 (state->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 (state->args[i], state->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 < state->n_backup_args); + _pygi_argument_release (&state->backup_args[backup_args_pos], state->arg_type_infos[i], + GI_TRANSFER_NOTHING, GI_DIRECTION_IN); + backup_args_pos += 1; + } + + _pygi_argument_release (state->args[i], state->arg_type_infos[i], transfer, + GI_DIRECTION_OUT); + } else { + _pygi_argument_release (state->args[i], state->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. */ + state->args[i]->v_pointer = g_array_free (state->args[i]->v_pointer, FALSE); + } + } + + g_assert (state->n_return_values <= 1 || return_values_pos == state->n_return_values); + g_assert (backup_args_pos == state->n_backup_args); + } + + return TRUE; +} + +static void +_free_invocation_state (struct invocation_state *state) +{ + gsize i; + + if (state->return_type_info != NULL) { + g_base_info_unref ( (GIBaseInfo *) state->return_type_info); + } + + if (state->closure != NULL) { + if (state->closure->scope == GI_SCOPE_TYPE_CALL) + _pygi_invoke_closure_free (state->closure); + } + + for (i = 0; i < state->n_args; i++) { + + /* check for caller-allocated values we need to free */ + if (g_arg_info_is_caller_allocates (state->arg_infos[i])) { + GIBaseInfo *info; + GIInfoType info_type; + + info = g_type_info_get_interface (state->arg_type_infos[i]); + g_assert (info != NULL); + info_type = g_base_info_get_type (info); + + /* caller-allocates applies only to structs right now + * the GI scanner is overzealous when marking parameters + * as caller-allocates, so we only free if this was a struct + */ + if (info_type == GI_INFO_TYPE_STRUCT) { + /* special case GValues so we make sure to unset them */ + if (g_registered_type_info_get_g_type ( (GIRegisteredTypeInfo *) info) == G_TYPE_VALUE) { + g_value_unset ( (GValue *) state->args[i]); + } + + g_free (state->args[i]); + } + } + + if (state->arg_type_infos[i] != NULL) + g_base_info_unref ( (GIBaseInfo *) state->arg_type_infos[i]); + if (state->arg_infos[i] != NULL) + g_base_info_unref ( (GIBaseInfo *) state->arg_infos[i]); + } + + if (state->arg_infos != NULL) { + g_slice_free1 (sizeof (gpointer) * state->n_args, state->arg_infos); + } + + if (state->arg_type_infos != NULL) { + g_slice_free1 (sizeof (gpointer) * state->n_args, state->arg_type_infos); + } + + if (state->args != NULL) { + g_slice_free1 (sizeof (gpointer) * state->n_args, state->args); + } + + if (state->args_is_auxiliary != NULL) { + g_slice_free1 (sizeof (gboolean) * state->n_args, state->args_is_auxiliary); + } + + if (state->in_args != NULL) { + g_slice_free1 (sizeof (GArgument) * state->n_in_args, state->in_args); + } + + if (state->out_args != NULL) { + g_slice_free1 (sizeof (GArgument) * state->n_out_args, state->out_args); + } + + if (state->out_values != NULL) { + g_slice_free1 (sizeof (GArgument) * state->n_out_args, state->out_values); + } + + if (state->backup_args != NULL) { + g_slice_free1 (sizeof (GArgument) * state->n_backup_args, state->backup_args); + } + + if (PyErr_Occurred()) { + Py_CLEAR (state->return_value); + } +} + + +PyObject * +_wrap_g_function_info_invoke (PyGIBaseInfo *self, PyObject *py_args) +{ + struct invocation_state state = { 0, }; + + _initialize_invocation_state (&state, self->info, py_args); + + if (!_prepare_invocation_state (&state, self->info, py_args)) { + _free_invocation_state (&state); + return NULL; + } + + if (!_invoke_function (&state, self->info, py_args)) { + _free_invocation_state (&state); + return NULL; + } + + if (!_process_invocation_state (&state, self->info, py_args)) { + _free_invocation_state (&state); + return NULL; + } + + return state.return_value; +} + diff --git a/gi/pygi-invoke.h b/gi/pygi-invoke.h new file mode 100644 index 0000000..0d07b21 --- /dev/null +++ b/gi/pygi-invoke.h @@ -0,0 +1,37 @@ +/* -*- 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_INVOKE_H__ +#define __PYGI_INVOKE_H__ + +#include <Python.h> + +#include <girepository.h> + +#include "pygi-private.h" + +G_BEGIN_DECLS + +PyObject *_wrap_g_function_info_invoke (PyGIBaseInfo *self, PyObject *py_args); + +G_END_DECLS + +#endif /* __PYGI_INVOKE_H__ */ diff --git a/gi/pygi-private.h b/gi/pygi-private.h new file mode 100644 index 0000000..0ff5df7 --- /dev/null +++ b/gi/pygi-private.h @@ -0,0 +1,59 @@ +/* -*- 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-boxed.h" +#include "pygi-argument.h" +#include "pygi-type.h" +#include "pygi-foreign.h" +#include "pygi-closure.h" +#include "pygi-callbacks.h" +#include "pygi-invoke.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..783b4aa --- /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..2f1ce42 --- /dev/null +++ b/gi/pygi-struct.c @@ -0,0 +1,169 @@ +/* -*- 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; + } + + size = g_struct_info_get_size ( (GIStructInfo *) info); + pointer = g_try_malloc0 (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..bd9804e --- /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_real (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_real (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..16d5bdc --- /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_real (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..0a8cbf5 --- /dev/null +++ b/gi/pygi.h @@ -0,0 +1,127 @@ +/* -*- 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 <config.h> +#include <pygobject.h> + +#if ENABLE_INTROSPECTION + +#include <girepository.h> + +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; + +typedef struct { + PyGBoxed base; + gboolean slice_allocated; + gsize size; +} PyGIBoxed; + +typedef PyObject * (*PyGIArgOverrideToGArgumentFunc) (PyObject *value, + GITypeInfo *type_info, + GITransfer transfer, + GArgument *arg); +typedef PyObject * (*PyGIArgOverrideFromGArgumentFunc) (GITypeInfo *type_info, + GArgument *arg); +typedef PyObject * (*PyGIArgOverrideReleaseGArgumentFunc) (GITransfer transfer, + GITypeInfo *type_info, + GArgument *arg); + +struct PyGI_API { + PyObject* (*type_import_by_g_type) (GType g_type); + void (*register_foreign_struct) (const char* namespace_, + const char* name, + PyGIArgOverrideToGArgumentFunc to_func, + PyGIArgOverrideFromGArgumentFunc from_func, + PyGIArgOverrideReleaseGArgumentFunc release_func); +}; + +static struct PyGI_API *PyGI_API = NULL; + +static int +_pygi_import (void) +{ + if (PyGI_API != NULL) { + return 1; + } + + PyGI_API = (struct PyGI_API*) PyCObject_Import("gi", "_API"); + if (PyGI_API == NULL) { + return -1; + } + + return 0; +} + +static inline PyObject * +pygi_type_import_by_g_type (GType g_type) +{ + if (_pygi_import() < 0) { + return NULL; + } + return PyGI_API->type_import_by_g_type(g_type); +} + +static inline PyObject * +pygi_register_foreign_struct (const char* namespace_, + const char* name, + PyGIArgOverrideToGArgumentFunc to_func, + PyGIArgOverrideFromGArgumentFunc from_func, + PyGIArgOverrideReleaseGArgumentFunc release_func) +{ + if (_pygi_import() < 0) { + return NULL; + } + PyGI_API->register_foreign_struct(namespace_, + name, + to_func, + from_func, + release_func); + Py_RETURN_NONE; +} + +#else /* ENABLE_INTROSPECTION */ + +static inline PyObject * +pygi_type_import_by_g_type (GType g_type) +{ + return NULL; +} + +#endif /* ENABLE_INTROSPECTION */ + +#endif /* __PYGI_H__ */ diff --git a/gi/pygobject-external.h b/gi/pygobject-external.h new file mode 100644 index 0000000..00b8b6f --- /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) + +__attribute__ ( (unused)) +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/Makefile.in b/gi/repository/Makefile.in new file mode 100644 index 0000000..033d1ad --- /dev/null +++ b/gi/repository/Makefile.in @@ -0,0 +1,469 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = gi/repository +DIST_COMMON = $(pygirepository_PYTHON) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/as-ac-expand.m4 \ + $(top_srcdir)/m4/jhflags.m4 $(top_srcdir)/m4/python.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +AM_V_GEN = $(am__v_GEN_$(V)) +am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) +am__v_GEN_0 = @echo " GEN " $@; +AM_V_at = $(am__v_at_$(V)) +am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY)) +am__v_at_0 = @ +SOURCES = +DIST_SOURCES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__installdirs = "$(DESTDIR)$(pygirepositorydir)" +py_compile = $(top_srcdir)/py-compile +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ACLOCAL_AMFLAGS = @ACLOCAL_AMFLAGS@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DATADIR = @DATADIR@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FFI_CFLAGS = @FFI_CFLAGS@ +FFI_LIBS = @FFI_LIBS@ +FGREP = @FGREP@ +GIOUNIX_CFLAGS = @GIOUNIX_CFLAGS@ +GIOUNIX_LIBS = @GIOUNIX_LIBS@ +GIO_CFLAGS = @GIO_CFLAGS@ +GIO_LIBS = @GIO_LIBS@ +GI_CFLAGS = @GI_CFLAGS@ +GI_LIBS = @GI_LIBS@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ +GLIB_LIBS = @GLIB_LIBS@ +GLIB_MKENUMS = @GLIB_MKENUMS@ +GOBJECT_QUERY = @GOBJECT_QUERY@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@ +INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBFFI_PC = @LIBFFI_PC@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PLATFORM = @PLATFORM@ +PYCAIRO_CFLAGS = @PYCAIRO_CFLAGS@ +PYCAIRO_LIBS = @PYCAIRO_LIBS@ +PYGOBJECT_MAJOR_VERSION = @PYGOBJECT_MAJOR_VERSION@ +PYGOBJECT_MICRO_VERSION = @PYGOBJECT_MICRO_VERSION@ +PYGOBJECT_MINOR_VERSION = @PYGOBJECT_MINOR_VERSION@ +PYTHON = @PYTHON@ +PYTHON_BASENAME = @PYTHON_BASENAME@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_INCLUDES = @PYTHON_INCLUDES@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +THREADING_CFLAGS = @THREADING_CFLAGS@ +VERSION = @VERSION@ +XSLTPROC = @XSLTPROC@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +lt_ECHO = @lt_ECHO@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +pkgpyexecdir = $(pyexecdir)/gtk-2.0/gi +pkgpythondir = @pkgpythondir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pyexecdir = @pyexecdir@ +pygobject_CODEGEN_DEFINES = @pygobject_CODEGEN_DEFINES@ +pythondir = @pythondir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +PLATFORM_VERSION = 2.0 +pygirepositorydir = $(pkgpyexecdir)/repository +pygirepository_PYTHON = \ + __init__.py + +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign gi/repository/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign gi/repository/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +mostlyclean-libtool: + -rm -f *.lo + +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=; \ + for p in $$list; do \ + if test -f "$$p"; then b=; else b="$(srcdir)/"; fi; \ + if test -f $$b$$p; then \ + $(am__strip_dir) \ + dlist="$$dlist $$f"; \ + list2="$$list2 $$b$$p"; \ + else :; fi; \ + done; \ + for file in $$list2; do echo $$file; done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pygirepositorydir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(pygirepositorydir)" || exit $$?; \ + done || exit $$?; \ + if test -n "$$dlist"; then \ + if test -z "$(DESTDIR)"; then \ + PYTHON=$(PYTHON) $(py_compile) --basedir "$(pygirepositorydir)" $$dlist; \ + else \ + PYTHON=$(PYTHON) $(py_compile) --destdir "$(DESTDIR)" --basedir "$(pygirepositorydir)" $$dlist; \ + fi; \ + else :; fi + +uninstall-pygirepositoryPYTHON: + @$(NORMAL_UNINSTALL) + @list='$(pygirepository_PYTHON)'; test -n "$(pygirepositorydir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + test -n "$$files" || exit 0; \ + filesc=`echo "$$files" | sed 's|$$|c|'`; \ + fileso=`echo "$$files" | sed 's|$$|o|'`; \ + echo " ( cd '$(DESTDIR)$(pygirepositorydir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(pygirepositorydir)" && rm -f $$files || exit $$?; \ + echo " ( cd '$(DESTDIR)$(pygirepositorydir)' && rm -f" $$filesc ")"; \ + cd "$(DESTDIR)$(pygirepositorydir)" && rm -f $$filesc || exit $$?; \ + echo " ( cd '$(DESTDIR)$(pygirepositorydir)' && rm -f" $$fileso ")"; \ + cd "$(DESTDIR)$(pygirepositorydir)" && rm -f $$fileso +tags: TAGS +TAGS: + +ctags: CTAGS +CTAGS: + + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile +installdirs: + for dir in "$(DESTDIR)$(pygirepositorydir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-pygirepositoryPYTHON + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-pygirepositoryPYTHON + +.MAKE: install-am install-strip + +.PHONY: all all-am check check-am clean clean-generic clean-libtool \ + distclean distclean-generic distclean-libtool distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-ps install-ps-am \ + install-pygirepositoryPYTHON install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am uninstall uninstall-am \ + uninstall-pygirepositoryPYTHON + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: 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..8ac9cab --- /dev/null +++ b/gi/types.py @@ -0,0 +1,180 @@ +# -*- 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, \ + register_interface_info, \ + hook_up_vfunc_implementation + + +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_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 _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) + + def _setup_vfuncs(cls): + for base in cls.__bases__: + if not hasattr(base, '__info__') or \ + not hasattr(base.__info__, 'get_vfuncs'): + continue + for vfunc_info in base.__info__.get_vfuncs(): + vfunc = getattr(cls, 'do_' + vfunc_info.get_name(), None) + if vfunc is None and isinstance(base.__info__, InterfaceInfo) and \ + not hasattr(cls, vfunc_info.get_name()): + raise TypeError('Class implementing %s.%s should implement ' + 'the method do_%s()' % (base.__info__.get_namespace(), + base.__info__.get_name(), + vfunc_info.get_name())) + elif vfunc is not None and not \ + is_function_in_classes(vfunc.im_func, cls.__bases__): + hook_up_vfunc_implementation(vfunc_info, cls.__gtype__, + vfunc) + +def is_function_in_classes(function, classes): + for klass in classes: + if function in klass.__dict__.values(): + return True + elif is_function_in_classes(function, klass.__bases__): + return True + return False + +class GObjectMeta(gobject.GObjectMeta, MetaClassHelper): + + def __init__(cls, name, bases, dict_): + super(GObjectMeta, cls).__init__(name, bases, dict_) + + is_gi_defined = False + if cls.__module__ == 'gi.repository.' + cls.__info__.get_namespace(): + is_gi_defined = True + + is_python_defined = False + if not is_gi_defined and cls.__module__ != GObjectMeta.__module__: + is_python_defined = True + + if is_python_defined: + cls._setup_vfuncs() + elif is_gi_defined: + 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()) + elif isinstance(cls.__info__, InterfaceInfo): + register_interface_info(cls.__info__.get_g_type()) + +class StructMeta(type, MetaClassHelper): + + def __init__(cls, name, bases, dict_): + super(StructMeta, cls).__init__(name, bases, dict_) + + # Avoid touching anything else than the base class. + g_type = cls.__info__.get_g_type() + if g_type != gobject.TYPE_INVALID and g_type.pytype is not None: + return + + cls._setup_fields() + cls._setup_methods() + cls._setup_constructors() + + +def override(type_): + g_type = type_.__info__.get_g_type() + if g_type != gobject.TYPE_INVALID: + g_type.pytype = type_ + return type_ + +class Enum(int): + __info__ = None + def __init__(self, value): + int.__init__(value) + + def __repr__(self): + value_name = str(self) + for value_info in self.__info__.get_values(): + if self == value_info.get_value(): + value_name = value_info.get_name().upper() + return "<enum %s of type %s.%s>" % (value_name, + self.__info__.get_namespace(), + self.__info__.get_name()) |