summaryrefslogtreecommitdiff
path: root/glib
diff options
context:
space:
mode:
Diffstat (limited to 'glib')
-rw-r--r--glib/Makefile.am59
-rw-r--r--glib/Makefile.in787
-rw-r--r--glib/__init__.py25
-rw-r--r--glib/glibmodule.c896
-rw-r--r--glib/option.py350
-rw-r--r--glib/pygiochannel.c740
-rw-r--r--glib/pygiochannel.h29
-rw-r--r--glib/pyglib-private.h46
-rw-r--r--glib/pyglib-python-compat.h120
-rw-r--r--glib/pyglib.c577
-rw-r--r--glib/pyglib.h94
-rw-r--r--glib/pygmaincontext.c99
-rw-r--r--glib/pygmaincontext.h40
-rw-r--r--glib/pygmainloop.c354
-rw-r--r--glib/pygmainloop.h36
-rw-r--r--glib/pygoptioncontext.c312
-rw-r--r--glib/pygoptioncontext.h37
-rw-r--r--glib/pygoptiongroup.c270
-rw-r--r--glib/pygoptiongroup.h40
-rw-r--r--glib/pygsource.c723
-rw-r--r--glib/pygsource.h39
-rw-r--r--glib/pygspawn.c263
-rw-r--r--glib/pygspawn.h32
23 files changed, 5968 insertions, 0 deletions
diff --git a/glib/Makefile.am b/glib/Makefile.am
new file mode 100644
index 0000000..d230da4
--- /dev/null
+++ b/glib/Makefile.am
@@ -0,0 +1,59 @@
+AUTOMAKE_OPTIONS = 1.7
+INCLUDES = $(PYTHON_INCLUDES) $(GLIB_CFLAGS) -DPY_SSIZE_T_CLEAN
+
+pkgincludedir = $(includedir)/pygtk-2.0
+pkginclude_HEADERS = pyglib.h
+
+lib_LTLIBRARIES = libpyglib-2.0-@PYTHON_BASENAME@.la
+
+pkgpyexecdir = $(pyexecdir)/gtk-2.0
+
+pyglibdir = $(pkgpyexecdir)/glib
+pyglib_PYTHON = \
+ __init__.py \
+ option.py
+pyglib_LTLIBRARIES = _glib.la
+
+common_ldflags = -module -avoid-version
+if PLATFORM_WIN32
+common_ldflags += -no-undefined
+endif
+
+libpyglib_2_0_@PYTHON_BASENAME@_la_CFLAGS = $(GLIB_CFLAGS)
+libpyglib_2_0_@PYTHON_BASENAME@_la_LIBADD = $(GLIB_LIBS) $(FFI_LIBS)
+libpyglib_2_0_@PYTHON_BASENAME@_la_SOURCES = \
+ pyglib.c \
+ pyglib.h \
+ pyglib-private.h \
+ pyglib-python-compat.h
+
+_glib_la_CFLAGS = $(GLIB_CFLAGS)
+_glib_la_LDFLAGS = $(common_ldflags) -export-symbols-regex "_glib|PyInit__glib"
+_glib_la_LIBADD = $(GLIB_LIBS) libpyglib-2.0-@PYTHON_BASENAME@.la
+_glib_la_SOURCES = \
+ glibmodule.c \
+ pygiochannel.c \
+ pygiochannel.h \
+ pygoptioncontext.c \
+ pygoptioncontext.h \
+ pygoptiongroup.c \
+ pygoptiongroup.h \
+ pygmaincontext.c \
+ pygmaincontext.h \
+ pygmainloop.c \
+ pygmainloop.h \
+ pygsource.c \
+ pygsource.h \
+ pygspawn.c \
+ pygspawn.h
+
+if PLATFORM_WIN32
+_glib_la_CFLAGS += -DPLATFORM_WIN32
+endif
+
+
+all: $(pyglib_LTLIBRARIES:.la=.so)
+clean-local:
+ rm -f $(pyglib_LTLIBRARIES:.la=.so)
+.la.so:
+ $(LN_S) .libs/$@ $@ || true
diff --git a/glib/Makefile.in b/glib/Makefile.in
new file mode 100644
index 0000000..634bdce
--- /dev/null
+++ b/glib/Makefile.in
@@ -0,0 +1,787 @@
+# 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@
+@PLATFORM_WIN32_TRUE@am__append_1 = -no-undefined
+@PLATFORM_WIN32_TRUE@am__append_2 = -DPLATFORM_WIN32
+subdir = glib
+DIST_COMMON = $(pkginclude_HEADERS) $(pyglib_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/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.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)$(libdir)" "$(DESTDIR)$(pyglibdir)" \
+ "$(DESTDIR)$(pyglibdir)" "$(DESTDIR)$(pkgincludedir)"
+LTLIBRARIES = $(lib_LTLIBRARIES) $(pyglib_LTLIBRARIES)
+am__DEPENDENCIES_1 =
+_glib_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \
+ libpyglib-2.0-@PYTHON_BASENAME@.la
+am__glib_la_OBJECTS = _glib_la-glibmodule.lo _glib_la-pygiochannel.lo \
+ _glib_la-pygoptioncontext.lo _glib_la-pygoptiongroup.lo \
+ _glib_la-pygmaincontext.lo _glib_la-pygmainloop.lo \
+ _glib_la-pygsource.lo _glib_la-pygspawn.lo
+_glib_la_OBJECTS = $(am__glib_la_OBJECTS)
+_glib_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(_glib_la_CFLAGS) $(CFLAGS) \
+ $(_glib_la_LDFLAGS) $(LDFLAGS) -o $@
+libpyglib_2_0_@PYTHON_BASENAME@_la_DEPENDENCIES = \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
+am_libpyglib_2_0_@PYTHON_BASENAME@_la_OBJECTS = \
+ libpyglib_2_0_@PYTHON_BASENAME@_la-pyglib.lo
+libpyglib_2_0_@PYTHON_BASENAME@_la_OBJECTS = \
+ $(am_libpyglib_2_0_@PYTHON_BASENAME@_la_OBJECTS)
+libpyglib_2_0_@PYTHON_BASENAME@_la_LINK = $(LIBTOOL) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(libpyglib_2_0_@PYTHON_BASENAME@_la_CFLAGS) $(CFLAGS) \
+ $(AM_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) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(_glib_la_SOURCES) \
+ $(libpyglib_2_0_@PYTHON_BASENAME@_la_SOURCES)
+DIST_SOURCES = $(_glib_la_SOURCES) \
+ $(libpyglib_2_0_@PYTHON_BASENAME@_la_SOURCES)
+py_compile = $(top_srcdir)/py-compile
+HEADERS = $(pkginclude_HEADERS)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+pkgincludedir = $(includedir)/pygtk-2.0
+ACLOCAL = @ACLOCAL@
+ACLOCAL_AMFLAGS = @ACLOCAL_AMFLAGS@
+AMTAR = @AMTAR@
+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@
+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@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBFFI_PC = @LIBFFI_PC@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+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@
+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@
+AUTOMAKE_OPTIONS = 1.7
+INCLUDES = $(PYTHON_INCLUDES) $(GLIB_CFLAGS) -DPY_SSIZE_T_CLEAN
+pkginclude_HEADERS = pyglib.h
+lib_LTLIBRARIES = libpyglib-2.0-@PYTHON_BASENAME@.la
+pyglibdir = $(pkgpyexecdir)/glib
+pyglib_PYTHON = \
+ __init__.py \
+ option.py
+
+pyglib_LTLIBRARIES = _glib.la
+common_ldflags = -module -avoid-version $(am__append_1)
+libpyglib_2_0_@PYTHON_BASENAME@_la_CFLAGS = $(GLIB_CFLAGS)
+libpyglib_2_0_@PYTHON_BASENAME@_la_LIBADD = $(GLIB_LIBS) $(FFI_LIBS)
+libpyglib_2_0_@PYTHON_BASENAME@_la_SOURCES = \
+ pyglib.c \
+ pyglib.h \
+ pyglib-private.h \
+ pyglib-python-compat.h
+
+_glib_la_CFLAGS = $(GLIB_CFLAGS) $(am__append_2)
+_glib_la_LDFLAGS = $(common_ldflags) -export-symbols-regex "_glib|PyInit__glib"
+_glib_la_LIBADD = $(GLIB_LIBS) libpyglib-2.0-@PYTHON_BASENAME@.la
+_glib_la_SOURCES = \
+ glibmodule.c \
+ pygiochannel.c \
+ pygiochannel.h \
+ pygoptioncontext.c \
+ pygoptioncontext.h \
+ pygoptiongroup.c \
+ pygoptiongroup.h \
+ pygmaincontext.c \
+ pygmaincontext.h \
+ pygmainloop.c \
+ pygmainloop.h \
+ pygsource.c \
+ pygsource.h \
+ pygspawn.c \
+ pygspawn.h
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .la .lo .o .obj .so
+$(srcdir)/Makefile.in: $(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) --gnu glib/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu glib/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: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+install-libLTLIBRARIES: $(lib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)"
+ @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
+ }
+
+uninstall-libLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \
+ done
+
+clean-libLTLIBRARIES:
+ -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
+ @list='$(lib_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
+install-pyglibLTLIBRARIES: $(pyglib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(pyglibdir)" || $(MKDIR_P) "$(DESTDIR)$(pyglibdir)"
+ @list='$(pyglib_LTLIBRARIES)'; test -n "$(pyglibdir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pyglibdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pyglibdir)"; \
+ }
+
+uninstall-pyglibLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(pyglib_LTLIBRARIES)'; test -n "$(pyglibdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pyglibdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pyglibdir)/$$f"; \
+ done
+
+clean-pyglibLTLIBRARIES:
+ -test -z "$(pyglib_LTLIBRARIES)" || rm -f $(pyglib_LTLIBRARIES)
+ @list='$(pyglib_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
+_glib.la: $(_glib_la_OBJECTS) $(_glib_la_DEPENDENCIES)
+ $(_glib_la_LINK) -rpath $(pyglibdir) $(_glib_la_OBJECTS) $(_glib_la_LIBADD) $(LIBS)
+libpyglib-2.0-@PYTHON_BASENAME@.la: $(libpyglib_2_0_@PYTHON_BASENAME@_la_OBJECTS) $(libpyglib_2_0_@PYTHON_BASENAME@_la_DEPENDENCIES)
+ $(libpyglib_2_0_@PYTHON_BASENAME@_la_LINK) -rpath $(libdir) $(libpyglib_2_0_@PYTHON_BASENAME@_la_OBJECTS) $(libpyglib_2_0_@PYTHON_BASENAME@_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_glib_la-glibmodule.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_glib_la-pygiochannel.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_glib_la-pygmaincontext.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_glib_la-pygmainloop.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_glib_la-pygoptioncontext.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_glib_la-pygoptiongroup.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_glib_la-pygsource.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_glib_la-pygspawn.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpyglib_2_0_@PYTHON_BASENAME@_la-pyglib.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@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@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@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@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@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 $@ $<
+
+_glib_la-glibmodule.lo: glibmodule.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_glib_la_CFLAGS) $(CFLAGS) -MT _glib_la-glibmodule.lo -MD -MP -MF $(DEPDIR)/_glib_la-glibmodule.Tpo -c -o _glib_la-glibmodule.lo `test -f 'glibmodule.c' || echo '$(srcdir)/'`glibmodule.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/_glib_la-glibmodule.Tpo $(DEPDIR)/_glib_la-glibmodule.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='glibmodule.c' object='_glib_la-glibmodule.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_glib_la_CFLAGS) $(CFLAGS) -c -o _glib_la-glibmodule.lo `test -f 'glibmodule.c' || echo '$(srcdir)/'`glibmodule.c
+
+_glib_la-pygiochannel.lo: pygiochannel.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_glib_la_CFLAGS) $(CFLAGS) -MT _glib_la-pygiochannel.lo -MD -MP -MF $(DEPDIR)/_glib_la-pygiochannel.Tpo -c -o _glib_la-pygiochannel.lo `test -f 'pygiochannel.c' || echo '$(srcdir)/'`pygiochannel.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/_glib_la-pygiochannel.Tpo $(DEPDIR)/_glib_la-pygiochannel.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pygiochannel.c' object='_glib_la-pygiochannel.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_glib_la_CFLAGS) $(CFLAGS) -c -o _glib_la-pygiochannel.lo `test -f 'pygiochannel.c' || echo '$(srcdir)/'`pygiochannel.c
+
+_glib_la-pygoptioncontext.lo: pygoptioncontext.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_glib_la_CFLAGS) $(CFLAGS) -MT _glib_la-pygoptioncontext.lo -MD -MP -MF $(DEPDIR)/_glib_la-pygoptioncontext.Tpo -c -o _glib_la-pygoptioncontext.lo `test -f 'pygoptioncontext.c' || echo '$(srcdir)/'`pygoptioncontext.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/_glib_la-pygoptioncontext.Tpo $(DEPDIR)/_glib_la-pygoptioncontext.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pygoptioncontext.c' object='_glib_la-pygoptioncontext.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_glib_la_CFLAGS) $(CFLAGS) -c -o _glib_la-pygoptioncontext.lo `test -f 'pygoptioncontext.c' || echo '$(srcdir)/'`pygoptioncontext.c
+
+_glib_la-pygoptiongroup.lo: pygoptiongroup.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_glib_la_CFLAGS) $(CFLAGS) -MT _glib_la-pygoptiongroup.lo -MD -MP -MF $(DEPDIR)/_glib_la-pygoptiongroup.Tpo -c -o _glib_la-pygoptiongroup.lo `test -f 'pygoptiongroup.c' || echo '$(srcdir)/'`pygoptiongroup.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/_glib_la-pygoptiongroup.Tpo $(DEPDIR)/_glib_la-pygoptiongroup.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pygoptiongroup.c' object='_glib_la-pygoptiongroup.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_glib_la_CFLAGS) $(CFLAGS) -c -o _glib_la-pygoptiongroup.lo `test -f 'pygoptiongroup.c' || echo '$(srcdir)/'`pygoptiongroup.c
+
+_glib_la-pygmaincontext.lo: pygmaincontext.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_glib_la_CFLAGS) $(CFLAGS) -MT _glib_la-pygmaincontext.lo -MD -MP -MF $(DEPDIR)/_glib_la-pygmaincontext.Tpo -c -o _glib_la-pygmaincontext.lo `test -f 'pygmaincontext.c' || echo '$(srcdir)/'`pygmaincontext.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/_glib_la-pygmaincontext.Tpo $(DEPDIR)/_glib_la-pygmaincontext.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pygmaincontext.c' object='_glib_la-pygmaincontext.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_glib_la_CFLAGS) $(CFLAGS) -c -o _glib_la-pygmaincontext.lo `test -f 'pygmaincontext.c' || echo '$(srcdir)/'`pygmaincontext.c
+
+_glib_la-pygmainloop.lo: pygmainloop.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_glib_la_CFLAGS) $(CFLAGS) -MT _glib_la-pygmainloop.lo -MD -MP -MF $(DEPDIR)/_glib_la-pygmainloop.Tpo -c -o _glib_la-pygmainloop.lo `test -f 'pygmainloop.c' || echo '$(srcdir)/'`pygmainloop.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/_glib_la-pygmainloop.Tpo $(DEPDIR)/_glib_la-pygmainloop.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pygmainloop.c' object='_glib_la-pygmainloop.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_glib_la_CFLAGS) $(CFLAGS) -c -o _glib_la-pygmainloop.lo `test -f 'pygmainloop.c' || echo '$(srcdir)/'`pygmainloop.c
+
+_glib_la-pygsource.lo: pygsource.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_glib_la_CFLAGS) $(CFLAGS) -MT _glib_la-pygsource.lo -MD -MP -MF $(DEPDIR)/_glib_la-pygsource.Tpo -c -o _glib_la-pygsource.lo `test -f 'pygsource.c' || echo '$(srcdir)/'`pygsource.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/_glib_la-pygsource.Tpo $(DEPDIR)/_glib_la-pygsource.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pygsource.c' object='_glib_la-pygsource.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_glib_la_CFLAGS) $(CFLAGS) -c -o _glib_la-pygsource.lo `test -f 'pygsource.c' || echo '$(srcdir)/'`pygsource.c
+
+_glib_la-pygspawn.lo: pygspawn.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_glib_la_CFLAGS) $(CFLAGS) -MT _glib_la-pygspawn.lo -MD -MP -MF $(DEPDIR)/_glib_la-pygspawn.Tpo -c -o _glib_la-pygspawn.lo `test -f 'pygspawn.c' || echo '$(srcdir)/'`pygspawn.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/_glib_la-pygspawn.Tpo $(DEPDIR)/_glib_la-pygspawn.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pygspawn.c' object='_glib_la-pygspawn.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_glib_la_CFLAGS) $(CFLAGS) -c -o _glib_la-pygspawn.lo `test -f 'pygspawn.c' || echo '$(srcdir)/'`pygspawn.c
+
+libpyglib_2_0_@PYTHON_BASENAME@_la-pyglib.lo: pyglib.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpyglib_2_0_@PYTHON_BASENAME@_la_CFLAGS) $(CFLAGS) -MT libpyglib_2_0_@PYTHON_BASENAME@_la-pyglib.lo -MD -MP -MF $(DEPDIR)/libpyglib_2_0_@PYTHON_BASENAME@_la-pyglib.Tpo -c -o libpyglib_2_0_@PYTHON_BASENAME@_la-pyglib.lo `test -f 'pyglib.c' || echo '$(srcdir)/'`pyglib.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libpyglib_2_0_@PYTHON_BASENAME@_la-pyglib.Tpo $(DEPDIR)/libpyglib_2_0_@PYTHON_BASENAME@_la-pyglib.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pyglib.c' object='libpyglib_2_0_@PYTHON_BASENAME@_la-pyglib.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpyglib_2_0_@PYTHON_BASENAME@_la_CFLAGS) $(CFLAGS) -c -o libpyglib_2_0_@PYTHON_BASENAME@_la-pyglib.lo `test -f 'pyglib.c' || echo '$(srcdir)/'`pyglib.c
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-pyglibPYTHON: $(pyglib_PYTHON)
+ @$(NORMAL_INSTALL)
+ test -z "$(pyglibdir)" || $(MKDIR_P) "$(DESTDIR)$(pyglibdir)"
+ @list='$(pyglib_PYTHON)'; dlist=; list2=; test -n "$(pyglibdir)" || list=; \
+ 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)$(pyglibdir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(pyglibdir)" || exit $$?; \
+ done || exit $$?; \
+ if test -n "$$dlist"; then \
+ if test -z "$(DESTDIR)"; then \
+ PYTHON=$(PYTHON) $(py_compile) --basedir "$(pyglibdir)" $$dlist; \
+ else \
+ PYTHON=$(PYTHON) $(py_compile) --destdir "$(DESTDIR)" --basedir "$(pyglibdir)" $$dlist; \
+ fi; \
+ else :; fi
+
+uninstall-pyglibPYTHON:
+ @$(NORMAL_UNINSTALL)
+ @list='$(pyglib_PYTHON)'; test -n "$(pyglibdir)" || 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)$(pyglibdir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(pyglibdir)" && rm -f $$files || exit $$?; \
+ echo " ( cd '$(DESTDIR)$(pyglibdir)' && rm -f" $$filesc ")"; \
+ cd "$(DESTDIR)$(pyglibdir)" && rm -f $$filesc || exit $$?; \
+ echo " ( cd '$(DESTDIR)$(pyglibdir)' && rm -f" $$fileso ")"; \
+ cd "$(DESTDIR)$(pyglibdir)" && rm -f $$fileso
+install-pkgincludeHEADERS: $(pkginclude_HEADERS)
+ @$(NORMAL_INSTALL)
+ test -z "$(pkgincludedir)" || $(MKDIR_P) "$(DESTDIR)$(pkgincludedir)"
+ @list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(pkgincludedir)'"; \
+ $(INSTALL_HEADER) $$files "$(DESTDIR)$(pkgincludedir)" || exit $$?; \
+ done
+
+uninstall-pkgincludeHEADERS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ test -n "$$files" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(pkgincludedir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(pkgincludedir)" && rm -f $$files
+
+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: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ 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: $(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
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES) $(HEADERS)
+installdirs:
+ for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(pyglibdir)" "$(DESTDIR)$(pyglibdir)" "$(DESTDIR)$(pkgincludedir)"; 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-libLTLIBRARIES clean-libtool clean-local \
+ clean-pyglibLTLIBRARIES mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-pkgincludeHEADERS install-pyglibLTLIBRARIES \
+ install-pyglibPYTHON
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am: install-libLTLIBRARIES
+
+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 -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-libLTLIBRARIES uninstall-pkgincludeHEADERS \
+ uninstall-pyglibLTLIBRARIES uninstall-pyglibPYTHON
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libLTLIBRARIES clean-libtool clean-local \
+ clean-pyglibLTLIBRARIES ctags 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-libLTLIBRARIES \
+ install-man install-pdf install-pdf-am \
+ install-pkgincludeHEADERS install-ps install-ps-am \
+ install-pyglibLTLIBRARIES install-pyglibPYTHON install-strip \
+ installcheck installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am uninstall-libLTLIBRARIES \
+ uninstall-pkgincludeHEADERS uninstall-pyglibLTLIBRARIES \
+ uninstall-pyglibPYTHON
+
+
+all: $(pyglib_LTLIBRARIES:.la=.so)
+clean-local:
+ rm -f $(pyglib_LTLIBRARIES:.la=.so)
+.la.so:
+ $(LN_S) .libs/$@ $@ || true
+
+# 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/glib/__init__.py b/glib/__init__.py
new file mode 100644
index 0000000..b114cb9
--- /dev/null
+++ b/glib/__init__.py
@@ -0,0 +1,25 @@
+# -*- Mode: Python; py-indent-offset: 4 -*-
+# pygobject - Python bindings for the GObject library
+# Copyright (C) 2006-2008 Johan Dahlin
+#
+# glib/__init__.py: initialisation file for glib module
+#
+# 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
+
+from glib._glib import *
+_PyGLib_API = _glib._PyGLib_API
+
+del _glib
diff --git a/glib/glibmodule.c b/glib/glibmodule.c
new file mode 100644
index 0000000..f794d5d
--- /dev/null
+++ b/glib/glibmodule.c
@@ -0,0 +1,896 @@
+/* -*- Mode: C; c-set-style: python; c-basic-offset: 4 -*-
+ * pyglib - Python bindings for GLib toolkit.
+ * Copyright (C) 1998-2003 James Henstridge
+ * 2004-2008 Johan Dahlin
+ *
+ * glibmodule.c: wrapper for the glib 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 Street, Fifth Floor, Boston, MA 02110-1301
+ * USA
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <Python.h>
+#include <glib.h>
+#include "pyglib.h"
+#include "pyglib-private.h"
+#include "pygiochannel.h"
+#include "pygmaincontext.h"
+#include "pygmainloop.h"
+#include "pygoptioncontext.h"
+#include "pygoptiongroup.h"
+#include "pygsource.h"
+#include "pygspawn.h"
+
+#define PYGLIB_MAJOR_VERSION PYGOBJECT_MAJOR_VERSION
+#define PYGLIB_MINOR_VERSION PYGOBJECT_MINOR_VERSION
+#define PYGLIB_MICRO_VERSION PYGOBJECT_MICRO_VERSION
+
+
+/* ---------------- glib module functions -------------------- */
+
+struct _PyGChildData {
+ PyObject *func;
+ PyObject *data;
+};
+
+static gint
+get_handler_priority(gint *priority, PyObject *kwargs)
+{
+ Py_ssize_t len, pos;
+ PyObject *key, *val;
+
+ /* no keyword args? leave as default */
+ if (kwargs == NULL) return 0;
+
+ len = PyDict_Size(kwargs);
+ if (len == 0) return 0;
+
+ if (len != 1) {
+ PyErr_SetString(PyExc_TypeError,
+ "expecting at most one keyword argument");
+ return -1;
+ }
+ pos = 0;
+ PyDict_Next(kwargs, &pos, &key, &val);
+ if (!_PyUnicode_Check(key)) {
+ PyErr_SetString(PyExc_TypeError,
+ "keyword argument name is not a string");
+ return -1;
+ }
+
+ if (strcmp(_PyUnicode_AsString(key), "priority") != 0) {
+ PyErr_SetString(PyExc_TypeError,
+ "only 'priority' keyword argument accepted");
+ return -1;
+ }
+
+ *priority = _PyLong_AsLong(val);
+ if (PyErr_Occurred()) {
+ PyErr_Clear();
+ PyErr_SetString(PyExc_ValueError, "could not get priority value");
+ return -1;
+ }
+ return 0;
+}
+
+static PyObject *
+pyglib_threads_init(PyObject *unused, PyObject *args, PyObject *kwargs)
+{
+ if (!pyglib_enable_threads())
+ return NULL;
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+pyglib_idle_add(PyObject *self, PyObject *args, PyObject *kwargs)
+{
+ PyObject *first, *callback, *cbargs = NULL, *data;
+ gint len, priority = G_PRIORITY_DEFAULT_IDLE;
+ guint handler_id;
+
+ len = PyTuple_Size(args);
+ if (len < 1) {
+ PyErr_SetString(PyExc_TypeError,
+ "idle_add requires at least 1 argument");
+ return NULL;
+ }
+ first = PySequence_GetSlice(args, 0, 1);
+ if (!PyArg_ParseTuple(first, "O:idle_add", &callback)) {
+ Py_DECREF(first);
+ return NULL;
+ }
+ Py_DECREF(first);
+ if (!PyCallable_Check(callback)) {
+ PyErr_SetString(PyExc_TypeError, "first argument not callable");
+ return NULL;
+ }
+ if (get_handler_priority(&priority, kwargs) < 0)
+ return NULL;
+
+ cbargs = PySequence_GetSlice(args, 1, len);
+ if (cbargs == NULL)
+ return NULL;
+
+ data = Py_BuildValue("(ON)", callback, cbargs);
+ if (data == NULL)
+ return NULL;
+ handler_id = g_idle_add_full(priority,
+ _pyglib_handler_marshal, data,
+ _pyglib_destroy_notify);
+ return _PyLong_FromLong(handler_id);
+}
+
+
+static PyObject *
+pyglib_timeout_add(PyObject *self, PyObject *args, PyObject *kwargs)
+{
+ PyObject *first, *callback, *cbargs = NULL, *data;
+ gint len, priority = G_PRIORITY_DEFAULT;
+ guint interval, handler_id;
+
+ len = PyTuple_Size(args);
+ if (len < 2) {
+ PyErr_SetString(PyExc_TypeError,
+ "timeout_add requires at least 2 args");
+ return NULL;
+ }
+ first = PySequence_GetSlice(args, 0, 2);
+ if (!PyArg_ParseTuple(first, "IO:timeout_add", &interval, &callback)) {
+ Py_DECREF(first);
+ return NULL;
+ }
+ Py_DECREF(first);
+ if (!PyCallable_Check(callback)) {
+ PyErr_SetString(PyExc_TypeError, "second argument not callable");
+ return NULL;
+ }
+ if (get_handler_priority(&priority, kwargs) < 0)
+ return NULL;
+
+ cbargs = PySequence_GetSlice(args, 2, len);
+ if (cbargs == NULL)
+ return NULL;
+
+ data = Py_BuildValue("(ON)", callback, cbargs);
+ if (data == NULL)
+ return NULL;
+ handler_id = g_timeout_add_full(priority, interval,
+ _pyglib_handler_marshal, data,
+ _pyglib_destroy_notify);
+ return _PyLong_FromLong(handler_id);
+}
+
+static PyObject *
+pyglib_timeout_add_seconds(PyObject *self, PyObject *args, PyObject *kwargs)
+{
+ PyObject *first, *callback, *cbargs = NULL, *data;
+ gint len, priority = G_PRIORITY_DEFAULT;
+ guint interval, handler_id;
+
+ len = PyTuple_Size(args);
+ if (len < 2) {
+ PyErr_SetString(PyExc_TypeError,
+ "timeout_add_seconds requires at least 2 args");
+ return NULL;
+ }
+ first = PySequence_GetSlice(args, 0, 2);
+ if (!PyArg_ParseTuple(first, "IO:timeout_add_seconds", &interval, &callback)) {
+ Py_DECREF(first);
+ return NULL;
+ }
+ Py_DECREF(first);
+ if (!PyCallable_Check(callback)) {
+ PyErr_SetString(PyExc_TypeError, "second argument not callable");
+ return NULL;
+ }
+ if (get_handler_priority(&priority, kwargs) < 0)
+ return NULL;
+
+ cbargs = PySequence_GetSlice(args, 2, len);
+ if (cbargs == NULL)
+ return NULL;
+
+ data = Py_BuildValue("(ON)", callback, cbargs);
+ if (data == NULL)
+ return NULL;
+ handler_id = g_timeout_add_seconds_full(priority, interval,
+ _pyglib_handler_marshal, data,
+ _pyglib_destroy_notify);
+ return _PyLong_FromLong(handler_id);
+}
+
+static gboolean
+iowatch_marshal(GIOChannel *source,
+ GIOCondition condition,
+ gpointer user_data)
+{
+ PyGILState_STATE state;
+ PyObject *tuple, *func, *firstargs, *args, *ret;
+ gboolean res;
+
+ g_return_val_if_fail(user_data != NULL, FALSE);
+
+ state = pyglib_gil_state_ensure();
+
+ tuple = (PyObject *)user_data;
+ func = PyTuple_GetItem(tuple, 0);
+
+ /* arg vector is (fd, condtion, *args) */
+ firstargs = Py_BuildValue("(Oi)", PyTuple_GetItem(tuple, 1), condition);
+ args = PySequence_Concat(firstargs, PyTuple_GetItem(tuple, 2));
+ Py_DECREF(firstargs);
+
+ ret = PyObject_CallObject(func, args);
+ Py_DECREF(args);
+ if (!ret) {
+ PyErr_Print();
+ res = FALSE;
+ } else {
+ if (ret == Py_None) {
+ if (PyErr_Warn(PyExc_Warning,
+ "glib.io_add_watch callback returned None; "
+ "should return True/False")) {
+ PyErr_Print();
+ }
+ }
+ res = PyObject_IsTrue(ret);
+ Py_DECREF(ret);
+ }
+
+ pyglib_gil_state_release(state);
+
+ return res;
+}
+
+static PyObject *
+pyglib_io_add_watch(PyObject *self, PyObject *args, PyObject *kwargs)
+{
+ PyObject *first, *pyfd, *callback, *cbargs = NULL, *data;
+ gint fd, priority = G_PRIORITY_DEFAULT, condition;
+ Py_ssize_t len;
+ GIOChannel *iochannel;
+ guint handler_id;
+
+ len = PyTuple_Size(args);
+ if (len < 3) {
+ PyErr_SetString(PyExc_TypeError,
+ "io_add_watch requires at least 3 args");
+ return NULL;
+ }
+ first = PySequence_GetSlice(args, 0, 3);
+ if (!PyArg_ParseTuple(first, "OiO:io_add_watch", &pyfd, &condition,
+ &callback)) {
+ Py_DECREF(first);
+ return NULL;
+ }
+ Py_DECREF(first);
+ fd = PyObject_AsFileDescriptor(pyfd);
+ if (fd < 0) {
+ return NULL;
+ }
+ if (!PyCallable_Check(callback)) {
+ PyErr_SetString(PyExc_TypeError, "third argument not callable");
+ return NULL;
+ }
+ if (get_handler_priority(&priority, kwargs) < 0)
+ return NULL;
+
+ cbargs = PySequence_GetSlice(args, 3, len);
+ if (cbargs == NULL)
+ return NULL;
+ data = Py_BuildValue("(OON)", callback, pyfd, cbargs);
+ if (data == NULL)
+ return NULL;
+ iochannel = g_io_channel_unix_new(fd);
+ handler_id = g_io_add_watch_full(iochannel, priority, condition,
+ iowatch_marshal, data,
+ (GDestroyNotify)_pyglib_destroy_notify);
+ g_io_channel_unref(iochannel);
+
+ return _PyLong_FromLong(handler_id);
+}
+
+static PyObject *
+pyglib_source_remove(PyObject *self, PyObject *args)
+{
+ guint tag;
+
+ if (!PyArg_ParseTuple(args, "i:source_remove", &tag))
+ return NULL;
+
+ return PyBool_FromLong(g_source_remove(tag));
+}
+
+static PyObject *
+pyglib_main_context_default(PyObject *unused)
+{
+ return pyglib_main_context_new(g_main_context_default());
+}
+
+static void
+child_watch_func(GPid pid, gint status, gpointer data)
+{
+ struct _PyGChildData *child_data = (struct _PyGChildData *) data;
+ PyObject *retval;
+ PyGILState_STATE gil;
+
+ gil = pyglib_gil_state_ensure();
+ if (child_data->data)
+ retval = PyObject_CallFunction(child_data->func, "iiO", pid, status,
+ child_data->data);
+ else
+ retval = PyObject_CallFunction(child_data->func, "ii", pid, status);
+
+ if (retval)
+ Py_DECREF(retval);
+ else
+ PyErr_Print();
+
+ pyglib_gil_state_release(gil);
+}
+
+static void
+child_watch_dnotify(gpointer data)
+{
+ struct _PyGChildData *child_data = (struct _PyGChildData *) data;
+ Py_DECREF(child_data->func);
+ Py_XDECREF(child_data->data);
+ g_slice_free(struct _PyGChildData, child_data);
+}
+
+
+static PyObject *
+pyglib_child_watch_add(PyObject *unused, PyObject *args, PyObject *kwargs)
+{
+ static char *kwlist[] = { "pid", "function", "data", "priority", NULL };
+ guint id;
+ gint priority = G_PRIORITY_DEFAULT;
+ int pid;
+ PyObject *func, *user_data = NULL;
+ struct _PyGChildData *child_data;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs,
+ "iO|Oi:glib.child_watch_add", kwlist,
+ &pid, &func, &user_data, &priority))
+ return NULL;
+ if (!PyCallable_Check(func)) {
+ PyErr_SetString(PyExc_TypeError,
+ "glib.child_watch_add: second argument must be callable");
+ return NULL;
+ }
+
+ child_data = g_slice_new(struct _PyGChildData);
+ child_data->func = func;
+ child_data->data = user_data;
+ Py_INCREF(child_data->func);
+ if (child_data->data)
+ Py_INCREF(child_data->data);
+ id = g_child_watch_add_full(priority, pid, child_watch_func,
+ child_data, child_watch_dnotify);
+ return _PyLong_FromLong(id);
+}
+
+static PyObject *
+pyglib_markup_escape_text(PyObject *unused, PyObject *args, PyObject *kwargs)
+{
+ static char *kwlist[] = { "text", NULL };
+ char *text_in, *text_out;
+ Py_ssize_t text_size;
+ PyObject *retval;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs,
+ "s#:glib.markup_escape_text", kwlist,
+ &text_in, &text_size))
+ return NULL;
+
+ text_out = g_markup_escape_text(text_in, text_size);
+ retval = _PyUnicode_FromString(text_out);
+ g_free(text_out);
+ return retval;
+}
+
+static PyObject *
+pyglib_get_current_time(PyObject *unused)
+{
+ GTimeVal timeval;
+
+ g_get_current_time(&timeval);
+ return pyglib_float_from_timeval(timeval);
+}
+
+static PyObject*
+pyglib_get_user_cache_dir(PyObject *self)
+{
+ const char *path = g_get_user_cache_dir();
+
+ if (path)
+ return _PyUnicode_FromString(path);
+ else {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+}
+
+static PyObject*
+pyglib_get_user_config_dir(PyObject *self)
+{
+ const char *path = g_get_user_config_dir();
+
+ if (path)
+ return _PyUnicode_FromString(path);
+ else {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+}
+
+static PyObject*
+pyglib_get_user_data_dir(PyObject *self)
+{
+ const char *path = g_get_user_data_dir();
+
+ if (path)
+ return _PyUnicode_FromString(path);
+ else {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+}
+
+static PyObject *
+pyglib_get_user_special_dir(PyObject *unused, PyObject *args, PyObject *kwargs)
+{
+ static char *kwlist[] = { "directory", NULL };
+ guint directory;
+ const char *path;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs,
+ "i:glib.get_user_special_dir", kwlist,
+ &directory))
+ return NULL;
+
+ path = g_get_user_special_dir(directory);
+ if (path)
+ return _PyUnicode_FromString(path);
+ else {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+}
+
+static PyObject *
+pyglib_main_depth(PyObject *unused)
+{
+ return _PyLong_FromLong(g_main_depth());
+}
+
+static PyObject *
+pyglib_filename_display_name(PyObject *self, PyObject *args)
+{
+ PyObject *py_display_name;
+ char *filename, *display_name;
+
+ if (!PyArg_ParseTuple(args, "s:glib.filename_display_name",
+ &filename))
+ return NULL;
+
+ display_name = g_filename_display_name(filename);
+ py_display_name = PyUnicode_DecodeUTF8(display_name,
+ strlen(display_name), NULL);
+ g_free(display_name);
+ return py_display_name;
+}
+
+static PyObject *
+pyglib_filename_display_basename(PyObject *self, PyObject *args)
+{
+ PyObject *py_display_basename;
+ char *filename, *display_basename;
+
+ if (!PyArg_ParseTuple(args, "s:glib.filename_display_basename",
+ &filename))
+ return NULL;
+
+ display_basename = g_filename_display_basename(filename);
+ py_display_basename = PyUnicode_DecodeUTF8(display_basename,
+ strlen(display_basename), NULL);
+ g_free(display_basename);
+ return py_display_basename;
+}
+
+static PyObject *
+pyglib_filename_from_utf8(PyObject *self, PyObject *args)
+{
+ char *filename, *utf8string;
+ Py_ssize_t utf8string_len;
+ gsize bytes_written;
+ GError *error = NULL;
+ PyObject *py_filename;
+
+ if (!PyArg_ParseTuple(args, "s#:glib.filename_from_utf8",
+ &utf8string, &utf8string_len))
+ return NULL;
+
+ filename = g_filename_from_utf8(utf8string, utf8string_len,
+ NULL, &bytes_written, &error);
+ if (pyglib_error_check(&error)) {
+ g_free(filename);
+ return NULL;
+ }
+ py_filename = _PyUnicode_FromStringAndSize(filename, bytes_written);
+ g_free(filename);
+ return py_filename;
+}
+
+
+static PyObject*
+pyglib_get_application_name(PyObject *self)
+{
+ const char *name;
+
+ name = g_get_application_name();
+ if (!name) {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ return _PyUnicode_FromString(name);
+}
+
+static PyObject*
+pyglib_set_application_name(PyObject *self, PyObject *arg)
+{
+ if (!PyString_Check(arg)) {
+ PyErr_Format(PyExc_TypeError,
+ "first argument must be a string, not '%s'",
+ PyString_AS_STRING(PyObject_Repr(arg)));
+ return NULL;
+ }
+ g_set_application_name(PyString_AS_STRING(arg));
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject*
+pyglib_get_prgname(PyObject *self)
+{
+ char *name;
+
+ name = g_get_prgname();
+ if (!name) {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ return _PyUnicode_FromString(name);
+}
+
+static PyObject*
+pyglib_set_prgname(PyObject *self, PyObject *arg)
+{
+ if (!PyString_Check(arg)) {
+ PyErr_Format(PyExc_TypeError,
+ "first argument must be a string, not '%s'",
+ PyString_AS_STRING(PyObject_Repr(arg)));
+ return NULL;
+ }
+ g_set_prgname(PyString_AS_STRING(arg));
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+pyglib_find_program_in_path(PyObject *unused, PyObject *args, PyObject *kwargs)
+{
+ static char *kwlist[] = { "program", NULL };
+ char *program, *ret;
+ PyObject *retval;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs,
+ "s:glib.find_program_in_path", kwlist,
+ &program))
+ return NULL;
+
+ ret = g_find_program_in_path(program);
+ retval = _PyUnicode_FromString(ret);
+ g_free(ret);
+ return retval;
+}
+
+static PyMethodDef _glib_functions[] = {
+ { "threads_init",
+ (PyCFunction) pyglib_threads_init, METH_NOARGS,
+ "threads_init()\n"
+ "Initialize GLib for use from multiple threads. If you also use GTK+\n"
+ "itself (i.e. GUI, not just PyGObject), use gtk.gdk.threads_init()\n"
+ "instead." },
+ { "idle_add",
+ (PyCFunction)pyglib_idle_add, METH_VARARGS|METH_KEYWORDS,
+ "idle_add(callable, user_data=None, priority=None) -> source id\n"
+ " callable receives (user_data)\n"
+ "Adds a callable to be called whenever there are no higher priority\n"
+ "events pending to the default main loop." },
+ { "timeout_add",
+ (PyCFunction)pyglib_timeout_add, METH_VARARGS|METH_KEYWORDS,
+ "timeout_add(interval, callable, user_data=None,\n"
+ " priority=None) -> source id\n"
+ " callable receives (user_data)\n"
+ "Sets a callable be called repeatedly until it returns False." },
+ { "timeout_add_seconds",
+ (PyCFunction)pyglib_timeout_add_seconds, METH_VARARGS|METH_KEYWORDS,
+ "timeout_add(interval, callable, user_data=None,\n"
+ " priority=None) -> source_id\n"
+ " callable receives (user_data)\n"
+ "Sets a callable be called repeatedly until it returns False.\n"
+ "Use this if you want to have a timer in the \"seconds\" range\n"
+ "and do not care about the exact time of the first call of the\n"
+ "timer, use this for more efficient system power usage." },
+ { "io_add_watch",
+ (PyCFunction)pyglib_io_add_watch, METH_VARARGS|METH_KEYWORDS,
+ "io_add_watch(fd, condition, callback, user_data=None) -> source id\n"
+ " callable receives (fd, condition, user_data)\n"
+ "Arranges for the fd to be monitored by the main loop for the\n"
+ "specified condition. Condition is a combination of glib.IO_IN,\n"
+ "glib.IO_OUT, glib.IO_PRI, gio.IO_ERR and gio.IO_HUB.\n" },
+ { "child_watch_add",
+ (PyCFunction)pyglib_child_watch_add, METH_VARARGS|METH_KEYWORDS,
+ "child_watch_add(pid, callable, user_data=None,\n"
+ "priority=None) -> source id\n"
+ " callable receives (pid, condition, user_data)\n"
+ "Sets the function specified by function to be called with the user\n"
+ "data specified by data when the child indicated by pid exits.\n"
+ "Condition is a combination of glib.IO_IN, glib.IO_OUT, glib.IO_PRI,\n"
+ "gio.IO_ERR and gio.IO_HUB." },
+ { "source_remove",
+ (PyCFunction)pyglib_source_remove, METH_VARARGS,
+ "source_remove(source_id) -> True if removed\n"
+ "Removes the event source specified by source id as returned by the\n"
+ "glib.idle_add(), glib.timeout_add() or glib.io_add_watch()\n"
+ "functions." },
+ { "spawn_async",
+ (PyCFunction)pyglib_spawn_async, METH_VARARGS|METH_KEYWORDS,
+ "spawn_async(argv, envp=None, working_directory=None,\n"
+ " flags=0, child_setup=None, user_data=None,\n"
+ " standard_input=None, standard_output=None,\n"
+ " standard_error=None) -> (pid, stdin, stdout, stderr)\n"
+ "Execute a child program asynchronously within a glib.MainLoop()\n"
+ "See the reference manual for a complete reference." },
+ { "main_context_default",
+ (PyCFunction)pyglib_main_context_default, METH_NOARGS,
+ "main_context_default() -> a main context\n"
+ "Returns the default main context. This is the main context used\n"
+ "for main loop functions when a main loop is not explicitly specified." },
+ { "main_depth",
+ (PyCFunction)pyglib_main_depth, METH_NOARGS,
+ "main_depth() -> stack depth\n"
+ "Returns the depth of the stack of calls in the main context." },
+ { "filename_display_name",
+ (PyCFunction)pyglib_filename_display_name, METH_VARARGS },
+ { "filename_display_basename",
+ (PyCFunction)pyglib_filename_display_basename, METH_VARARGS },
+ { "filename_from_utf8",
+ (PyCFunction)pyglib_filename_from_utf8, METH_VARARGS },
+ { "get_application_name",
+ (PyCFunction)pyglib_get_application_name, METH_NOARGS },
+ { "set_application_name",
+ (PyCFunction)pyglib_set_application_name, METH_O },
+ { "get_prgname",
+ (PyCFunction)pyglib_get_prgname, METH_NOARGS },
+ { "set_prgname",
+ (PyCFunction)pyglib_set_prgname, METH_O },
+ { "get_current_time",
+ (PyCFunction)pyglib_get_current_time, METH_NOARGS },
+ { "get_user_cache_dir",
+ (PyCFunction)pyglib_get_user_cache_dir, METH_NOARGS },
+ { "get_user_config_dir",
+ (PyCFunction)pyglib_get_user_config_dir, METH_NOARGS },
+ { "get_user_data_dir",
+ (PyCFunction)pyglib_get_user_data_dir, METH_NOARGS },
+ { "get_user_special_dir",
+ (PyCFunction)pyglib_get_user_special_dir, METH_VARARGS|METH_KEYWORDS },
+ { "markup_escape_text",
+ (PyCFunction)pyglib_markup_escape_text, METH_VARARGS|METH_KEYWORDS },
+ { "find_program_in_path",
+ (PyCFunction)pyglib_find_program_in_path, METH_VARARGS|METH_KEYWORDS },
+ { NULL, NULL, 0 }
+};
+
+/* ----------------- glib module initialisation -------------- */
+
+static struct _PyGLib_Functions pyglib_api = {
+ FALSE, /* threads_enabled */
+ NULL, /* gerror_exception */
+ NULL, /* block_threads */
+ NULL /* unblock_threads */
+};
+
+static void
+pyglib_register_api(PyObject *d)
+{
+ PyObject *o;
+
+ /* for addon libraries ... */
+ PyDict_SetItemString(d, "_PyGLib_API",
+ o=PyCObject_FromVoidPtr(&pyglib_api,NULL));
+ Py_DECREF(o);
+
+ pyglib_init_internal(o);
+}
+
+static void
+pyglib_register_error(PyObject *d)
+{
+ PyObject *dict;
+ PyObject *gerror_class;
+ dict = PyDict_New();
+ /* This is a hack to work around the deprecation warning of
+ * BaseException.message in Python 2.6+.
+ * GError has also an "message" attribute.
+ */
+ PyDict_SetItemString(dict, "message", Py_None);
+ gerror_class = PyErr_NewException("glib.GError", PyExc_RuntimeError, dict);
+ Py_DECREF(dict);
+
+ PyDict_SetItemString(d, "GError", gerror_class);
+ pyglib_api.gerror_exception = gerror_class;
+}
+
+static void
+pyglib_register_version_tuples(PyObject *d)
+{
+ PyObject *o;
+
+ /* glib version */
+ o = Py_BuildValue("(iii)", glib_major_version, glib_minor_version,
+ glib_micro_version);
+ PyDict_SetItemString(d, "glib_version", o);
+ Py_DECREF(o);
+
+ /* pyglib version */
+ o = Py_BuildValue("(iii)",
+ PYGLIB_MAJOR_VERSION,
+ PYGLIB_MINOR_VERSION,
+ PYGLIB_MICRO_VERSION);
+ PyDict_SetItemString(d, "pyglib_version", o);
+ Py_DECREF(o);
+}
+
+static void
+pyglib_register_constants(PyObject *m)
+{
+ PyModule_AddIntConstant(m, "SPAWN_LEAVE_DESCRIPTORS_OPEN",
+ G_SPAWN_LEAVE_DESCRIPTORS_OPEN);
+ PyModule_AddIntConstant(m, "SPAWN_DO_NOT_REAP_CHILD",
+ G_SPAWN_DO_NOT_REAP_CHILD);
+ PyModule_AddIntConstant(m, "SPAWN_SEARCH_PATH",
+ G_SPAWN_SEARCH_PATH);
+ PyModule_AddIntConstant(m, "SPAWN_STDOUT_TO_DEV_NULL",
+ G_SPAWN_STDOUT_TO_DEV_NULL);
+ PyModule_AddIntConstant(m, "SPAWN_STDERR_TO_DEV_NULL",
+ G_SPAWN_STDERR_TO_DEV_NULL);
+ PyModule_AddIntConstant(m, "SPAWN_CHILD_INHERITS_STDIN",
+ G_SPAWN_CHILD_INHERITS_STDIN);
+ PyModule_AddIntConstant(m, "SPAWN_FILE_AND_ARGV_ZERO",
+ G_SPAWN_FILE_AND_ARGV_ZERO);
+
+ PyModule_AddIntConstant(m, "PRIORITY_HIGH",
+ G_PRIORITY_HIGH);
+ PyModule_AddIntConstant(m, "PRIORITY_DEFAULT",
+ G_PRIORITY_DEFAULT);
+ PyModule_AddIntConstant(m, "PRIORITY_HIGH_IDLE",
+ G_PRIORITY_HIGH_IDLE);
+ PyModule_AddIntConstant(m, "PRIORITY_DEFAULT_IDLE",
+ G_PRIORITY_DEFAULT_IDLE);
+ PyModule_AddIntConstant(m, "PRIORITY_LOW",
+ G_PRIORITY_LOW);
+
+ PyModule_AddIntConstant(m, "IO_IN", G_IO_IN);
+ PyModule_AddIntConstant(m, "IO_OUT", G_IO_OUT);
+ PyModule_AddIntConstant(m, "IO_PRI", G_IO_PRI);
+ PyModule_AddIntConstant(m, "IO_ERR", G_IO_ERR);
+ PyModule_AddIntConstant(m, "IO_HUP", G_IO_HUP);
+ PyModule_AddIntConstant(m, "IO_NVAL", G_IO_NVAL);
+
+ PyModule_AddIntConstant(m, "IO_STATUS_ERROR",
+ G_IO_STATUS_ERROR);
+ PyModule_AddIntConstant(m, "IO_STATUS_NORMAL",
+ G_IO_STATUS_NORMAL);
+ PyModule_AddIntConstant(m, "IO_STATUS_EOF",
+ G_IO_STATUS_EOF);
+ PyModule_AddIntConstant(m, "IO_STATUS_AGAIN",
+ G_IO_STATUS_AGAIN);
+ PyModule_AddIntConstant(m, "IO_FLAG_APPEND",
+ G_IO_FLAG_APPEND);
+ PyModule_AddIntConstant(m, "IO_FLAG_NONBLOCK",
+ G_IO_FLAG_NONBLOCK);
+ PyModule_AddIntConstant(m, "IO_FLAG_IS_READABLE",
+ G_IO_FLAG_IS_READABLE);
+ PyModule_AddIntConstant(m, "IO_FLAG_IS_WRITEABLE",
+ G_IO_FLAG_IS_WRITEABLE);
+ PyModule_AddIntConstant(m, "IO_FLAG_IS_SEEKABLE",
+ G_IO_FLAG_IS_SEEKABLE);
+ PyModule_AddIntConstant(m, "IO_FLAG_MASK",
+ G_IO_FLAG_MASK);
+ PyModule_AddIntConstant(m, "IO_FLAG_GET_MASK",
+ G_IO_FLAG_GET_MASK);
+ PyModule_AddIntConstant(m, "IO_FLAG_SET_MASK",
+ G_IO_FLAG_SET_MASK);
+
+ PyModule_AddIntConstant(m, "OPTION_FLAG_HIDDEN",
+ G_OPTION_FLAG_HIDDEN);
+ PyModule_AddIntConstant(m, "OPTION_FLAG_IN_MAIN",
+ G_OPTION_FLAG_IN_MAIN);
+ PyModule_AddIntConstant(m, "OPTION_FLAG_REVERSE",
+ G_OPTION_FLAG_REVERSE);
+ PyModule_AddIntConstant(m, "OPTION_FLAG_NO_ARG",
+ G_OPTION_FLAG_NO_ARG);
+ PyModule_AddIntConstant(m, "OPTION_FLAG_FILENAME",
+ G_OPTION_FLAG_FILENAME);
+ PyModule_AddIntConstant(m, "OPTION_FLAG_OPTIONAL_ARG",
+ G_OPTION_FLAG_OPTIONAL_ARG);
+ PyModule_AddIntConstant(m, "OPTION_FLAG_NOALIAS",
+ G_OPTION_FLAG_NOALIAS);
+
+ PyModule_AddIntConstant(m, "OPTION_ERROR_UNKNOWN_OPTION",
+ G_OPTION_ERROR_UNKNOWN_OPTION);
+ PyModule_AddIntConstant(m, "OPTION_ERROR_BAD_VALUE",
+ G_OPTION_ERROR_BAD_VALUE);
+ PyModule_AddIntConstant(m, "OPTION_ERROR_FAILED",
+ G_OPTION_ERROR_FAILED);
+
+ PyModule_AddIntConstant(m, "USER_DIRECTORY_DESKTOP",
+ G_USER_DIRECTORY_DESKTOP);
+ PyModule_AddIntConstant(m, "USER_DIRECTORY_DOCUMENTS",
+ G_USER_DIRECTORY_DOCUMENTS);
+ PyModule_AddIntConstant(m, "USER_DIRECTORY_DOWNLOAD",
+ G_USER_DIRECTORY_DOWNLOAD);
+ PyModule_AddIntConstant(m, "USER_DIRECTORY_MUSIC",
+ G_USER_DIRECTORY_MUSIC);
+ PyModule_AddIntConstant(m, "USER_DIRECTORY_PICTURES",
+ G_USER_DIRECTORY_PICTURES);
+ PyModule_AddIntConstant(m, "USER_DIRECTORY_PUBLIC_SHARE",
+ G_USER_DIRECTORY_PUBLIC_SHARE);
+ PyModule_AddIntConstant(m, "USER_DIRECTORY_TEMPLATES",
+ G_USER_DIRECTORY_TEMPLATES);
+ PyModule_AddIntConstant(m, "USER_DIRECTORY_VIDEOS",
+ G_USER_DIRECTORY_VIDEOS);
+
+ PyModule_AddStringConstant(m, "OPTION_REMAINING",
+ G_OPTION_REMAINING);
+ PyModule_AddStringConstant(m, "OPTION_ERROR",
+ (char*) g_quark_to_string(G_OPTION_ERROR));
+}
+
+PYGLIB_MODULE_START(_glib, "glib._glib")
+{
+ PyObject *d = PyModule_GetDict(module);
+
+ pyglib_register_constants(module);
+ pyglib_register_api(d);
+ pyglib_register_error(d);
+ pyglib_register_version_tuples(d);
+ pyglib_iochannel_register_types(d);
+ pyglib_mainloop_register_types(d);
+ pyglib_maincontext_register_types(d);
+ pyglib_source_register_types(d);
+ pyglib_spawn_register_types(d);
+ pyglib_option_context_register_types(d);
+ pyglib_option_group_register_types(d);
+}
+PYGLIB_MODULE_END
diff --git a/glib/option.py b/glib/option.py
new file mode 100644
index 0000000..027752f
--- /dev/null
+++ b/glib/option.py
@@ -0,0 +1,350 @@
+# -*- Mode: Python -*-
+# pygobject - Python bindings for the GObject library
+# Copyright (C) 2006 Johannes Hoelzl
+#
+# glib/option.py: GOption command line parser
+#
+# 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
+
+"""GOption command line parser
+
+Extends optparse to use the GOptionGroup, GOptionEntry and GOptionContext
+objects. So it is possible to use the gtk, gnome_program and gstreamer command
+line groups and contexts.
+
+Use this interface instead of the raw wrappers of GOptionContext and
+GOptionGroup in glib.
+"""
+
+import sys
+import optparse
+from optparse import OptParseError, OptionError, OptionValueError, \
+ BadOptionError, OptionConflictError
+
+import glib
+_glib = sys.modules['glib._glib']
+
+__all__ = [
+ "OptParseError",
+ "OptionError",
+ "OptionValueError",
+ "BadOptionError",
+ "OptionConflictError"
+ "Option",
+ "OptionGroup",
+ "OptionParser",
+ "make_option",
+]
+
+class Option(optparse.Option):
+ """Represents a command line option
+
+ To use the extended possibilities of the GOption API Option
+ (and make_option) are extended with new types and attributes.
+
+ Types:
+ filename The supplied arguments are read as filename, GOption
+ parses this type in with the GLib filename encoding.
+
+ Attributes:
+ optional_arg This does not need a arguement, but it can be supplied.
+ hidden The help list does not show this option
+ in_main This option apears in the main group, this should only
+ be used for backwards compatibility.
+
+ Use Option.REMAINING as option name to get all positional arguments.
+
+ NOTE: Every argument to an option is passed as utf-8 coded string, the only
+ exception are options which use the 'filename' type, its arguments
+ are passed as strings in the GLib filename encoding.
+
+ For further help, see optparse.Option.
+ """
+ TYPES = optparse.Option.TYPES + (
+ 'filename',
+ )
+
+ ATTRS = optparse.Option.ATTRS + [
+ 'hidden',
+ 'in_main',
+ 'optional_arg',
+ ]
+
+ REMAINING = '--' + _glib.OPTION_REMAINING
+
+ def __init__(self, *args, **kwargs):
+ optparse.Option.__init__(self, *args, **kwargs)
+ if not self._long_opts:
+ raise ValueError("%s at least one long option name.")
+
+ if len(self._long_opts) < len(self._short_opts):
+ raise ValueError(
+ "%s at least more long option names than short option names.")
+
+ if not self.help:
+ raise ValueError("%s needs a help message.", self._long_opts[0])
+
+
+ def _set_opt_string(self, opts):
+ if self.REMAINING in opts:
+ self._long_opts.append(self.REMAINING)
+ optparse.Option._set_opt_string(self, opts)
+ if len(self._short_opts) > len(self._long_opts):
+ raise OptionError("goption.Option needs more long option names "
+ "than short option names")
+
+ def _to_goptionentries(self):
+ flags = 0
+
+ if self.hidden:
+ self.flags |= _glib.OPTION_FLAG_HIDDEN
+
+ if self.in_main:
+ self.flags |= _glib.OPTION_FLAG_IN_MAIN
+
+ if self.takes_value():
+ if self.optional_arg:
+ flags |= _glib.OPTION_FLAG_OPTIONAL_ARG
+ else:
+ flags |= _glib.OPTION_FLAG_NO_ARG
+
+ if self.type == 'filename':
+ flags |= _glib.OPTION_FLAG_FILENAME
+
+ for (long_name, short_name) in zip(self._long_opts, self._short_opts):
+ yield (long_name[2:], short_name[1], flags, self.help, self.metavar)
+
+ for long_name in self._long_opts[len(self._short_opts):]:
+ yield (long_name[2:], '\0', flags, self.help, self.metavar)
+
+class OptionGroup(optparse.OptionGroup):
+ """A group of command line options.
+
+ Arguements:
+ name: The groups name, used to create the
+ --help-{name} option
+ description: Shown as title of the groups help view
+ help_description: Shown as help to the --help-{name} option
+ option_list: The options used in this group, must be option.Option()
+ defaults: A dicitionary of default values
+ translation_domain: Sets the translation domain for gettext().
+
+ NOTE: This OptionGroup does not exactly map the optparse.OptionGroup
+ interface. There is no parser object to supply, but it is possible
+ to set default values and option_lists. Also the default values and
+ values are not shared with the OptionParser.
+
+ To pass a OptionGroup into a function which expects a GOptionGroup (e.g.
+ gnome_program_init() ). OptionGroup.get_option_group() can be used.
+
+ For further help, see optparse.OptionGroup.
+ """
+ def __init__(self, name, description, help_description="",
+ option_list=None, defaults=None,
+ translation_domain=None):
+ optparse.OptionContainer.__init__(self, Option, 'error', description)
+ self.name = name
+ self.parser = None
+ self.help_description = help_description
+ if defaults:
+ self.defaults = defaults
+
+ self.values = None
+
+ self.translation_domain = translation_domain
+
+ if option_list:
+ for option in option_list:
+ self.add_option(option)
+
+ def _create_option_list(self):
+ self.option_list = []
+ self._create_option_mappings()
+
+ def _to_goptiongroup(self, parser):
+ def callback(option_name, option_value, group):
+ if option_name.startswith('--'):
+ opt = self._long_opt[option_name]
+ else:
+ opt = self._short_opt[option_name]
+
+ try:
+ opt.process(option_name, option_value, self.values, parser)
+ except OptionValueError:
+ error = sys.exc_info()[1]
+ gerror = _glib.GError(str(error))
+ gerror.domain = _glib.OPTION_ERROR
+ gerror.code = _glib.OPTION_ERROR_BAD_VALUE
+ gerror.message = str(error)
+ raise gerror
+
+ group = _glib.OptionGroup(self.name, self.description,
+ self.help_description, callback)
+ if self.translation_domain:
+ group.set_translation_domain(self.translation_domain)
+
+ entries = []
+ for option in self.option_list:
+ entries.extend(option._to_goptionentries())
+ group.add_entries(entries)
+
+ return group
+
+ def get_option_group(self, parser = None):
+ """ Returns the corresponding GOptionGroup object.
+
+ Can be used as parameter for gnome_program_init(), gtk_init().
+ """
+ self.set_values_to_defaults()
+ return self._to_goptiongroup(parser)
+
+ def set_values_to_defaults(self):
+ for option in self.option_list:
+ default = self.defaults.get(option.dest)
+ if isinstance(default, basestring):
+ opt_str = option.get_opt_string()
+ self.defaults[option.dest] = option.check_value(
+ opt_str, default)
+ self.values = optparse.Values(self.defaults)
+
+class OptionParser(optparse.OptionParser):
+ """Command line parser with GOption support.
+
+ NOTE: The OptionParser interface is not the exactly the same as the
+ optparse.OptionParser interface. Especially the usage parameter
+ is only used to show the metavar of the arguements.
+
+ Attribues:
+ help_enabled: The --help, --help-all and --help-{group}
+ options are enabled (default).
+ ignore_unknown_options: Do not throw a exception when a option is not
+ knwon, the option will be in the result list.
+
+ OptionParser.add_option_group() does not only accept OptionGroup instances
+ but also glib.OptionGroup, which is returned by gtk_get_option_group().
+
+ Only glib.option.OptionGroup and glib.option.Option instances should
+ be passed as groups and options.
+
+ For further help, see optparse.OptionParser.
+ """
+
+ def __init__(self, *args, **kwargs):
+ if 'option_class' not in kwargs:
+ kwargs['option_class'] = Option
+ self.help_enabled = kwargs.pop('help_enabled', True)
+ self.ignore_unknown_options = kwargs.pop('ignore_unknown_options',
+ False)
+ optparse.OptionParser.__init__(self, add_help_option=False,
+ *args, **kwargs)
+
+ def set_usage(self, usage):
+ if usage is None:
+ self.usage = ''
+ elif usage.startswith("%prog"):
+ self.usage = usage[len("%prog"):]
+ else:
+ self.usage = usage
+
+ def _to_goptioncontext(self, values):
+ if self.description:
+ parameter_string = self.usage + " - " + self.description
+ else:
+ parameter_string = self.usage
+ context = _glib.OptionContext(parameter_string)
+ context.set_help_enabled(self.help_enabled)
+ context.set_ignore_unknown_options(self.ignore_unknown_options)
+
+ for option_group in self.option_groups:
+ if isinstance(option_group, _glib.OptionGroup):
+ g_group = option_group
+ else:
+ g_group = option_group.get_option_group(self)
+ context.add_group(g_group)
+
+ def callback(option_name, option_value, group):
+ if option_name.startswith('--'):
+ opt = self._long_opt[option_name]
+ else:
+ opt = self._short_opt[option_name]
+ opt.process(option_name, option_value, values, self)
+
+ main_group = _glib.OptionGroup(None, None, None, callback)
+ main_entries = []
+ for option in self.option_list:
+ main_entries.extend(option._to_goptionentries())
+ main_group.add_entries(main_entries)
+ context.set_main_group(main_group)
+
+ return context
+
+ def add_option_group(self, *args, **kwargs):
+ if isinstance(args[0], basestring):
+ optparse.OptionParser.add_option_group(self,
+ OptionGroup(self, *args, **kwargs))
+ return
+ elif len(args) == 1 and not kwargs:
+ if isinstance(args[0], OptionGroup):
+ if not args[0].parser:
+ args[0].parser = self
+ if args[0].parser is not self:
+ raise ValueError("invalid OptionGroup (wrong parser)")
+ if isinstance(args[0], _glib.OptionGroup):
+ self.option_groups.append(args[0])
+ return
+ optparse.OptionParser.add_option_group(self, *args, **kwargs)
+
+ def _get_all_options(self):
+ options = self.option_list[:]
+ for group in self.option_groups:
+ if isinstance(group, optparse.OptionGroup):
+ options.extend(group.option_list)
+ return options
+
+ def _process_args(self, largs, rargs, values):
+ context = self._to_goptioncontext(values)
+
+ # _process_args() returns the remaining parameters in rargs.
+ # The prepended program name is used to all g_set_prgname()
+ # The program name is cut away so it doesn't appear in the result.
+ rargs[:] = context.parse([sys.argv[0]] + rargs)[1:]
+
+ def parse_args(self, args=None, values=None):
+ old_args = args or []
+ try:
+ options, args = optparse.OptionParser.parse_args(
+ self, args, values)
+ except _glib.GError:
+ error = sys.exc_info()[1]
+ if error.domain != _glib.OPTION_ERROR:
+ raise
+ if error.code == _glib.OPTION_ERROR_BAD_VALUE:
+ raise OptionValueError(error.message)
+ elif error.code == _glib.OPTION_ERROR_UNKNOWN_OPTION:
+ raise BadOptionError(error.message)
+ elif error.code == _glib.OPTION_ERROR_FAILED:
+ raise OptParseError(error.message)
+ else:
+ raise
+
+ for group in self.option_groups:
+ for key, value in group.values.__dict__.items():
+ options.ensure_value(key, value)
+
+ args = args[2:-len(old_args)]
+ return options, args
+
+make_option = Option
diff --git a/glib/pygiochannel.c b/glib/pygiochannel.c
new file mode 100644
index 0000000..4c935e8
--- /dev/null
+++ b/glib/pygiochannel.c
@@ -0,0 +1,740 @@
+/* -*- Mode: C; c-basic-offset: 4 -*- */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <Python.h>
+#include <pythread.h>
+#include <structmember.h> /* for PyMemberDef */
+
+#include "pyglib.h"
+#include "pyglib-private.h"
+#include "pygsource.h"
+
+typedef struct {
+ PyObject_HEAD
+ GIOChannel *channel;
+ int softspace; /* to make print >> chan, "foo" ... work */
+} PyGIOChannel;
+
+PYGLIB_DEFINE_TYPE("glib.IOChannel", PyGIOChannel_Type, PyGIOChannel)
+
+static PyObject*
+py_io_channel_next(PyGIOChannel *self)
+{
+ PyObject* ret_obj = NULL;
+ gsize length = 0, terminator_pos;
+ gchar *str_return = NULL;
+ GError *error = NULL;
+ GIOStatus status;
+
+ status = g_io_channel_read_line(self->channel, &str_return, &length,
+ &terminator_pos, &error);
+ if (pyglib_error_check(&error))
+ return NULL;
+
+ if (status == G_IO_STATUS_EOF) {
+ PyErr_SetString(PyExc_StopIteration, "EOF");
+ return NULL;
+ }
+
+ ret_obj = _PyUnicode_FromStringAndSize(str_return, length);
+ g_free(str_return);
+ return ret_obj;
+}
+
+static int
+py_io_channel_compare(PyGIOChannel *self, PyGIOChannel *v)
+{
+ if (self->channel == v->channel) return 0;
+ if (self->channel > v->channel) return -1;
+ return 1;
+}
+
+static PyObject*
+py_io_channel_get_iter(PyObject *self)
+{
+ Py_INCREF(self);
+ return self;
+}
+
+static long
+py_io_channel_hash(PyGIOChannel *self)
+{
+ return (long) self->channel;
+}
+
+static void
+py_io_channel_dealloc(PyGIOChannel *self)
+{
+ if (self->channel)
+ g_io_channel_unref(self->channel);
+ PyObject_DEL(self);
+}
+
+static PyObject*
+py_io_channel_shutdown(PyGIOChannel* self, PyObject *args, PyObject *kwargs)
+{
+ static char *kwlist[] = { "flush", NULL };
+ GIOStatus ret;
+ PyObject* flush = Py_True;
+ GError* error = NULL;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O:glib.IOChannel.shutdown", kwlist, &flush))
+ return NULL;
+
+ ret = g_io_channel_shutdown(self->channel, PyObject_IsTrue(flush), &error);
+ if (pyglib_error_check(&error))
+ return NULL;
+
+ return _PyLong_FromLong(ret);
+}
+
+/* character encoding conversion involved functions.
+ */
+
+static PyObject*
+py_io_channel_set_buffer_size(PyGIOChannel* self, PyObject *args, PyObject *kwargs)
+{
+ static char *kwlist[] = { "size", NULL };
+ int size;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:glib.IOChannel.set_buffer_size", kwlist, &size))
+ return NULL;
+
+ g_io_channel_set_buffer_size(self->channel, size);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject*
+py_io_channel_get_buffer_size(PyGIOChannel* self)
+{
+ return _PyLong_FromLong(g_io_channel_get_buffer_size(self->channel));
+}
+
+static PyObject*
+py_io_channel_set_buffered(PyGIOChannel* self, PyObject *args, PyObject *kwargs)
+{
+ static char *kwlist[] = { "buffered", NULL };
+ int buffered;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:glib.IOChannel.set_buffered", kwlist, &buffered))
+ return NULL;
+
+ g_io_channel_set_buffered(self->channel, buffered);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject*
+py_io_channel_get_buffered(PyGIOChannel* self)
+{
+ return _PyLong_FromLong(g_io_channel_get_buffered(self->channel));
+}
+
+static PyObject*
+py_io_channel_set_encoding(PyGIOChannel* self, PyObject *args, PyObject *kwargs)
+{
+ static char *kwlist[] = { "encoding", NULL };
+ const char* encoding;
+ GError* error = NULL;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "z:glib.IOChannel.set_encoding", kwlist, &encoding))
+ return NULL;
+
+ g_io_channel_set_encoding(self->channel, encoding, &error);
+ if (pyglib_error_check(&error))
+ return NULL;
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject*
+py_io_channel_get_encoding(PyGIOChannel* self)
+{
+ const char* encoding = g_io_channel_get_encoding(self->channel);
+
+ if (encoding == NULL) {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+
+ return _PyUnicode_FromString(encoding);
+}
+
+#define CHUNK_SIZE (8 * 1024)
+
+static PyObject*
+py_io_channel_read_chars(PyGIOChannel* self, PyObject *args, PyObject *kwargs)
+{
+ static char *kwlist[] = { "max_count", NULL };
+ int max_count = -1;
+ PyObject* ret_obj = NULL;
+ gsize total_read = 0;
+ GError* error = NULL;
+ GIOStatus status = G_IO_STATUS_NORMAL;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:glib.IOChannel.read", kwlist, &max_count))
+ return NULL;
+
+ if (max_count == 0)
+ return _PyUnicode_FromString("");
+
+ while (status == G_IO_STATUS_NORMAL
+ && (max_count == -1 || total_read < max_count)) {
+ gsize single_read;
+ char* buf;
+ gsize buf_size;
+
+ if (max_count == -1)
+ buf_size = CHUNK_SIZE;
+ else {
+ buf_size = max_count - total_read;
+ if (buf_size > CHUNK_SIZE)
+ buf_size = CHUNK_SIZE;
+ }
+
+ if ( ret_obj == NULL ) {
+ ret_obj = _PyUnicode_FromStringAndSize((char *)NULL, buf_size);
+ if (ret_obj == NULL)
+ goto failure;
+ }
+ else if (buf_size + total_read > _PyUnicode_GET_SIZE(ret_obj)) {
+ if (_PyUnicode_Resize(&ret_obj, buf_size + total_read) == -1)
+ goto failure;
+ }
+
+ buf = _PyUnicode_AS_STRING(ret_obj) + total_read;
+
+ pyglib_unblock_threads();
+ status = g_io_channel_read_chars(self->channel, buf, buf_size,
+ &single_read, &error);
+ pyglib_block_threads();
+ if (pyglib_error_check(&error))
+ goto failure;
+
+ total_read += single_read;
+ }
+
+ if ( total_read != _PyUnicode_GET_SIZE(ret_obj) ) {
+ if (_PyUnicode_Resize(&ret_obj, total_read) == -1)
+ goto failure;
+ }
+ return ret_obj;
+
+ failure:
+ Py_XDECREF(ret_obj);
+ return NULL;
+}
+
+static PyObject*
+py_io_channel_write_chars(PyGIOChannel* self, PyObject *args, PyObject *kwargs)
+{
+ static char *kwlist[] = { "buf", NULL };
+ const char* buf;
+ Py_ssize_t buf_len;
+ gsize count;
+ GError* error = NULL;
+ GIOStatus status;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s#:glib.IOChannel.write",
+ kwlist, &buf, &buf_len))
+ return NULL;
+
+ pyglib_unblock_threads();
+ status = g_io_channel_write_chars(self->channel, buf, buf_len, &count, &error);
+ pyglib_block_threads();
+ if (pyglib_error_check(&error))
+ return NULL;
+
+ return _PyLong_FromLong(count);
+}
+
+static PyObject*
+py_io_channel_write_lines(PyGIOChannel* self, PyObject *args, PyObject *kwargs)
+{
+ static char *kwlist[] = { "lines", NULL };
+ char *buf;
+ Py_ssize_t buf_len;
+ gsize count;
+ GError* error = NULL;
+ GIOStatus status;
+ PyObject *iter, *value, *pylines;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:glib.IOChannel.writelines",
+ kwlist, &pylines))
+ return NULL;
+
+ iter = PyObject_GetIter(pylines);
+
+ while (1) {
+ value = PyIter_Next(iter);
+ if (PyErr_ExceptionMatches(PyExc_StopIteration)) {
+ PyErr_Clear();
+ goto normal_exit;
+ }
+ if (!_PyUnicode_Check(value)) {
+ PyErr_SetString(PyExc_TypeError, "glib.IOChannel.writelines must"
+ " be sequence/iterator of strings");
+ Py_DECREF(iter);
+ return NULL;
+ }
+ _PyUnicode_AsStringAndSize(value, &buf, &buf_len);
+ pyglib_unblock_threads();
+ status = g_io_channel_write_chars(self->channel, buf, buf_len, &count, &error);
+ pyglib_unblock_threads();
+ Py_DECREF(value);
+ if (pyglib_error_check(&error)) {
+ Py_DECREF(iter);
+ return NULL;
+ }
+ }
+normal_exit:
+ Py_DECREF(iter);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject*
+py_io_channel_flush(PyGIOChannel* self)
+{
+ GError* error = NULL;
+ GIOStatus status;
+
+ pyglib_unblock_threads();
+ status = g_io_channel_flush(self->channel, &error);
+ pyglib_block_threads();
+ if (pyglib_error_check(&error))
+ return NULL;
+
+ return _PyLong_FromLong(status);
+}
+
+static PyObject*
+py_io_channel_set_flags(PyGIOChannel* self, PyObject *args, PyObject *kwargs)
+{
+ static char *kwlist[] = { "flags", NULL };
+ GIOFlags flags;
+ GIOStatus status;
+ GError* error = NULL;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:glib.IOChannel.set_flags",
+ kwlist, &flags))
+ return NULL;
+
+ status = g_io_channel_set_flags(self->channel, flags, &error);
+ if (pyglib_error_check(&error))
+ return NULL;
+
+ return _PyLong_FromLong(status);
+}
+
+static PyObject*
+py_io_channel_get_flags(PyGIOChannel* self)
+{
+ return _PyLong_FromLong(g_io_channel_get_flags(self->channel));
+}
+
+static PyObject*
+py_io_channel_get_buffer_condition(PyGIOChannel* self)
+{
+ return _PyLong_FromLong(g_io_channel_get_buffer_condition(self->channel));
+}
+
+static PyObject*
+py_io_channel_set_close_on_unref(PyGIOChannel* self, PyObject *args, PyObject *kwargs)
+{
+ static char *kwlist[] = { "do_close", NULL };
+ PyObject *do_close;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:glib.IOChannel.set_close_on_unref",
+ kwlist, &do_close))
+ return NULL;
+
+ g_io_channel_set_close_on_unref(self->channel, PyObject_IsTrue(do_close));
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject*
+py_io_channel_get_close_on_unref(PyGIOChannel* self)
+{
+ if (g_io_channel_get_close_on_unref(self->channel)) {
+ Py_INCREF(Py_True);
+ return Py_True;
+ } else {
+ Py_INCREF(Py_False);
+ return Py_False;
+ }
+}
+
+typedef struct {
+ PyObject *callback;
+ PyObject *iochannel;
+ PyObject *user_data;
+} PyGIOWatchData;
+
+static void
+pyg_iowatch_data_free(PyGIOWatchData *data)
+{
+ Py_DECREF(data->callback);
+ Py_XDECREF(data->user_data);
+ Py_DECREF(data->iochannel);
+ g_slice_free(PyGIOWatchData, data);
+}
+
+static gboolean
+pyg_iowatch_marshal(GIOChannel *source,
+ GIOCondition condition,
+ gpointer user_data)
+{
+ PyObject *ret;
+ gboolean res;
+ PyGIOWatchData *data = (PyGIOWatchData *) user_data;
+ PyGILState_STATE state;
+
+ g_return_val_if_fail(user_data != NULL, FALSE);
+ g_return_val_if_fail(((PyGIOChannel *) data->iochannel)->channel == source,
+ FALSE);
+
+ state = pyglib_gil_state_ensure();
+
+ if (data->user_data)
+ ret = PyObject_CallFunction(data->callback, "OiO", data->iochannel,
+ condition, data->user_data);
+ else
+ ret = PyObject_CallFunction(data->callback, "Oi", data->iochannel,
+ condition);
+
+ if (!ret) {
+ PyErr_Print();
+ res = FALSE;
+ } else {
+ res = PyObject_IsTrue(ret);
+ Py_DECREF(ret);
+ }
+ pyglib_gil_state_release(state);
+
+ return res;
+}
+
+
+
+static PyObject *
+py_io_channel_add_watch(PyObject *self, PyObject *args, PyObject *kwargs)
+{
+ static char *kwlist[] = { "condition", "callback", "user_data", "priority", NULL };
+ PyObject *callback, *user_data = NULL;
+ int priority = G_PRIORITY_DEFAULT, condition;
+ GIOChannel *iochannel = NULL;
+ guint handler_id;
+ PyGIOWatchData *data;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs,
+ "iO|Oi:glib.IOChannel.add_watch",
+ kwlist, &condition, &callback,
+ &user_data, &priority))
+ return NULL;
+
+ iochannel = ((PyGIOChannel *) self)->channel;
+
+ if (!PyCallable_Check(callback)) {
+ PyErr_SetString(PyExc_TypeError, "second must be callable");
+ return NULL;
+ }
+
+ data = g_slice_new(PyGIOWatchData);
+ data->callback = callback; Py_INCREF(callback);
+ data->user_data = user_data; Py_XINCREF(user_data);
+ data->iochannel = self; Py_INCREF(self);
+
+ handler_id = g_io_add_watch_full(((PyGIOChannel *) self)->channel,
+ priority, condition,
+ pyg_iowatch_marshal, data,
+ (GDestroyNotify) pyg_iowatch_data_free);
+ return PyLong_FromUnsignedLong(handler_id);
+}
+
+
+#ifdef G_OS_WIN32
+
+static PyObject *
+py_io_channel_win32_poll(PyObject *self, PyObject *args, PyObject *kwargs)
+{
+ static char *kwlist[] = { "fds", "timeout", NULL };
+ GPollFD *pollfd;
+ PyObject *pyfds, *pyfd;
+ guint len, i;
+ gint timeout = -1;
+ gint result;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs,
+ "O!|i:glib.IOChannel.win32_poll",
+ kwlist, &PyList_Type, &pyfds, &timeout))
+ return NULL;
+
+ len = PyList_Size(pyfds);
+ pollfd = g_newa(GPollFD, len);
+ for (i = 0; i < len; ++i) {
+ pyfd = PyList_GET_ITEM(pyfds, i);
+ if (!PyObject_TypeCheck(pyfd, &PyGPollFD_Type)) {
+ PyErr_SetString(PyExc_TypeError, "'fds' must be a list of glib.PollFD objects");
+ return NULL;
+ }
+ pollfd[i] = ((PyGPollFD *) pyfd)->pollfd;
+ }
+
+ result = g_io_channel_win32_poll(pollfd, len, timeout);
+ for (i = 0; i < len; ++i) {
+ pyfd = PyList_GET_ITEM(pyfds, i);
+ ((PyGPollFD *) pyfd)->pollfd = pollfd[i];
+ }
+ return _PyLong_FromLong(result);
+}
+
+static PyObject *
+py_io_channel_win32_make_pollfd(PyObject *self, PyObject *args, PyObject *kwargs)
+{
+ static char *kwlist[] = { "condition", NULL };
+ int condition;
+ GPollFD pollfd;
+ PyGPollFD *pypollfd;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs,
+ "i:glib.IOChannel.win32_make_pollfd",
+ kwlist, &condition))
+ return NULL;
+
+ g_io_channel_win32_make_pollfd(((PyGIOChannel *) self)->channel,
+ condition, &pollfd);
+ pypollfd = PyObject_NEW(PyGPollFD, &PyGPollFD_Type);
+ pypollfd->pollfd = pollfd;
+ return (PyObject *) pypollfd;
+}
+#endif /* def G_OS_WIN32 */
+
+
+static PyObject*
+py_io_channel_read_line(PyGIOChannel* self, PyObject *args, PyObject *kwargs)
+{
+ static char *kwlist[] = { "size", NULL };
+ PyObject* ret_obj = NULL;
+ gsize length = 0, terminator_pos;
+ gchar *str_return = NULL;
+ GError *error = NULL;
+ gint size_hint = -1;
+ GIOStatus status;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:glib.IOChannel.readline", kwlist,
+ &size_hint))
+ return NULL;
+
+ status = g_io_channel_read_line(self->channel, &str_return, &length,
+ &terminator_pos, &error);
+ if (pyglib_error_check(&error))
+ return NULL;
+ ret_obj = _PyUnicode_FromStringAndSize(str_return, length);
+ g_free(str_return);
+ return ret_obj;
+}
+
+static PyObject*
+py_io_channel_read_lines(PyGIOChannel* self, PyObject *args, PyObject *kwargs)
+{
+ static char *kwlist[] = { "size", NULL };
+ PyObject *line = NULL;
+ gsize length = 0, terminator_pos;
+ gchar *str_return = NULL;
+ GError *error = NULL;
+ gint size_hint = -1;
+ GIOStatus status = G_IO_STATUS_NORMAL;
+ PyObject *list;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:glib.IOChannel.readlines", kwlist,
+ &size_hint))
+ return NULL;
+
+ list = PyList_New(0);
+ while (status == G_IO_STATUS_NORMAL) {
+ status = g_io_channel_read_line(self->channel, &str_return, &length,
+ &terminator_pos, &error);
+ if (pyglib_error_check(&error)) {
+ Py_DECREF(line);
+ return NULL;
+ }
+ line = _PyUnicode_FromStringAndSize(str_return, length);
+ g_free(str_return);
+ if (PyList_Append(list, line)) {
+ Py_DECREF(line);
+ Py_DECREF(list);
+ return NULL;
+ }
+ }
+ return list;
+}
+
+
+static PyObject*
+py_io_channel_seek(PyGIOChannel* self, PyObject *args, PyObject *kwargs)
+{
+ static char *kwlist[] = { "offset", "whence", NULL };
+ gint64 offset;
+ int whence = 0;
+ GIOStatus status;
+ GSeekType seek_type;
+ GError* error = NULL;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "L|i:glib.IOChannel.seek",
+ kwlist, &offset, &whence))
+ return NULL;
+
+ switch (whence)
+ {
+ case 0: seek_type = G_SEEK_SET; break;
+ case 1: seek_type = G_SEEK_CUR; break;
+ case 2: seek_type = G_SEEK_END; break;
+ default:
+ PyErr_SetString(PyExc_ValueError, "invalid 'whence' value");
+ return NULL;
+ }
+
+ status = g_io_channel_seek_position(self->channel, offset,
+ seek_type, &error);
+ if (pyglib_error_check(&error))
+ return NULL;
+
+ return _PyLong_FromLong(status);
+}
+
+#if 0 // Not wrapped
+void g_io_channel_set_line_term (GIOChannel *channel,
+ const gchar *line_term,
+ gint length);
+
+G_CONST_RETURN gchar* g_io_channel_get_line_term (GIOChannel *channel,
+ gint *length);
+
+
+
+GIOStatus g_io_channel_read_line_string (GIOChannel *channel,
+ GString *buffer,
+ gsize *terminator_pos,
+ GError **error);
+GIOStatus g_io_channel_read_to_end (GIOChannel *channel,
+ gchar **str_return,
+ gsize *length,
+ GError **error);
+GIOStatus g_io_channel_read_unichar (GIOChannel *channel,
+ gunichar *thechar,
+ GError **error);
+GIOStatus g_io_channel_write_unichar (GIOChannel *channel,
+ gunichar thechar,
+ GError **error);
+#endif // Not wrapped
+
+static PyMemberDef py_io_channel_members[] = {
+ { "softspace", T_INT, offsetof(PyGIOChannel, softspace), 0, NULL },
+ { NULL, 0, 0, 0, NULL }
+};
+
+static PyMethodDef py_io_channel_methods[] = {
+ { "close", (PyCFunction)py_io_channel_shutdown, METH_KEYWORDS },
+ { "flush", (PyCFunction)py_io_channel_flush, METH_NOARGS },
+ { "set_encoding", (PyCFunction)py_io_channel_set_encoding, METH_KEYWORDS },
+ { "get_encoding", (PyCFunction)py_io_channel_get_encoding, METH_NOARGS },
+ { "set_buffered", (PyCFunction)py_io_channel_set_buffered, METH_KEYWORDS },
+ { "get_buffered", (PyCFunction)py_io_channel_get_buffered, METH_NOARGS },
+ { "set_buffer_size", (PyCFunction)py_io_channel_set_buffer_size, METH_KEYWORDS },
+ { "get_buffer_size", (PyCFunction)py_io_channel_get_buffer_size, METH_NOARGS },
+ { "read", (PyCFunction)py_io_channel_read_chars, METH_KEYWORDS },
+ { "readline", (PyCFunction)py_io_channel_read_line, METH_KEYWORDS },
+ { "readlines", (PyCFunction)py_io_channel_read_lines, METH_KEYWORDS },
+ { "write", (PyCFunction)py_io_channel_write_chars, METH_KEYWORDS },
+ { "writelines", (PyCFunction)py_io_channel_write_lines, METH_KEYWORDS },
+ { "set_flags", (PyCFunction)py_io_channel_set_flags, METH_KEYWORDS },
+ { "get_flags", (PyCFunction)py_io_channel_get_flags, METH_NOARGS },
+ { "get_buffer_condition", (PyCFunction)py_io_channel_get_buffer_condition, METH_NOARGS },
+ { "set_close_on_unref", (PyCFunction)py_io_channel_set_close_on_unref, METH_KEYWORDS },
+ { "get_close_on_unref", (PyCFunction)py_io_channel_get_close_on_unref, METH_NOARGS },
+ { "add_watch", (PyCFunction)py_io_channel_add_watch, METH_KEYWORDS },
+ { "seek", (PyCFunction)py_io_channel_seek, METH_KEYWORDS },
+#ifdef G_OS_WIN32
+ { "win32_make_pollfd", (PyCFunction)py_io_channel_win32_make_pollfd, METH_KEYWORDS },
+ { "win32_poll", (PyCFunction)py_io_channel_win32_poll, METH_KEYWORDS|METH_STATIC },
+#endif
+ { NULL, NULL, 0 }
+};
+
+
+static int
+py_io_channel_init(PyGIOChannel *self, PyObject *args, PyObject *kwargs)
+{
+ static char *kwlist[] = { "filedes", "filename", "mode",
+#ifdef G_OS_WIN32
+ "hwnd",
+#endif
+ NULL };
+ int fd = -1;
+ char *mode = "r", *filename = NULL;
+ GError *error = NULL;
+#ifdef G_OS_WIN32
+ guint hwnd = 0;
+#endif
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|iss"
+#ifdef G_OS_WIN32
+ "I"
+#endif
+ ":glib.IOChannel.__init__",
+ kwlist, &fd, &filename, &mode
+#ifdef G_OS_WIN32
+ , &hwnd
+#endif
+ ))
+ return -1;
+
+ if (fd != -1)
+ self->channel = g_io_channel_unix_new(fd);
+ else if (filename != NULL) {
+ self->channel = g_io_channel_new_file(filename, mode, &error);
+ if (pyglib_error_check(&error))
+ return -1;
+ }
+#ifdef G_OS_WIN32
+ else if (hwnd != 0) {
+ self->channel = g_io_channel_win32_new_messages(hwnd);
+ }
+#endif
+ else {
+#ifdef G_OS_WIN32
+ PyErr_SetString(PyExc_TypeError, "either a valid file descriptor, "
+ "file name, or window handle must be supplied");
+#else
+ PyErr_SetString(PyExc_TypeError, "either a valid file descriptor "
+ "or file name must be supplied");
+#endif
+ return -1;
+ }
+ return 0;
+}
+
+void
+pyglib_iochannel_register_types(PyObject *d)
+{
+ PyGIOChannel_Type.tp_init = (initproc)py_io_channel_init;
+ PyGIOChannel_Type.tp_dealloc = (destructor)py_io_channel_dealloc;
+ PyGIOChannel_Type.tp_flags = Py_TPFLAGS_DEFAULT;
+ PyGIOChannel_Type.tp_members = py_io_channel_members;
+ PyGIOChannel_Type.tp_methods = py_io_channel_methods;
+ PyGIOChannel_Type.tp_hash = (hashfunc)py_io_channel_hash;
+ PyGIOChannel_Type.tp_compare = (cmpfunc)py_io_channel_compare;
+ PyGIOChannel_Type.tp_iter = (getiterfunc)py_io_channel_get_iter;
+ PyGIOChannel_Type.tp_iternext = (iternextfunc)py_io_channel_next;
+
+ PYGLIB_REGISTER_TYPE(d, PyGIOChannel_Type, "IOChannel");
+}
diff --git a/glib/pygiochannel.h b/glib/pygiochannel.h
new file mode 100644
index 0000000..9b03edd
--- /dev/null
+++ b/glib/pygiochannel.h
@@ -0,0 +1,29 @@
+/* -*- Mode: C; c-basic-offset: 4 -*-
+ * pyglib - Python bindings for GLib toolkit.
+ * Copyright (C) 1998-2003 James Henstridge
+ * 2004-2008 Johan Dahlin
+ *
+ * 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 __PYG_IOCHANNEL_H__
+#define __PYG_IOCHANNEL_H__
+
+extern PyTypeObject PyGIOChannel_Type;
+
+void pyglib_iochannel_register_types(PyObject *d);
+
+#endif /* __PYG_IOCHANNEL_H__ */
diff --git a/glib/pyglib-private.h b/glib/pyglib-private.h
new file mode 100644
index 0000000..8b033e1
--- /dev/null
+++ b/glib/pyglib-private.h
@@ -0,0 +1,46 @@
+/* -*- Mode: C; c-basic-offset: 4 -*-
+ * pyglib - Python bindings for GLib toolkit.
+ * Copyright (C) 1998-2003 James Henstridge
+ * 2004-2008 Johan Dahlin
+ *
+ * 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 __PYGLIB_PRIVATE_H__
+#define __PYGLIB_PRIVATE_H__
+
+#include <Python.h>
+#include <glib.h>
+
+#include <pyglib-python-compat.h>
+
+G_BEGIN_DECLS
+
+struct _PyGLib_Functions {
+ gboolean threads_enabled;
+ PyObject *gerror_exception;
+ PyGLibThreadBlockFunc block_threads;
+ PyGLibThreadBlockFunc unblock_threads;
+};
+
+gboolean _pyglib_handler_marshal(gpointer user_data);
+void _pyglib_destroy_notify(gpointer user_data);
+
+G_END_DECLS
+
+#endif /* __PYGLIB_PRIVATE_H__ */
+
+
diff --git a/glib/pyglib-python-compat.h b/glib/pyglib-python-compat.h
new file mode 100644
index 0000000..915a912
--- /dev/null
+++ b/glib/pyglib-python-compat.h
@@ -0,0 +1,120 @@
+/* -*- Mode: C; c-basic-offset: 4 -*-
+ * pyglib - Python bindings for GLib toolkit.
+ * Copyright (C) 2008 Johan Dahlin
+ *
+ * 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 __PYGLIB_PYTHON_COMPAT_H__
+#define __PYGLIB_PYTHON_COMPAT_H__
+
+/* Python 2.3 does not define Py_CLEAR */
+#ifndef Py_CLEAR
+#define Py_CLEAR(op) \
+ do { \
+ if (op) { \
+ PyObject *tmp = (PyObject *)(op); \
+ (op) = NULL; \
+ Py_DECREF(tmp); \
+ } \
+ } while (0)
+#endif
+
+/* Compilation on Python 2.4 */
+#if PY_VERSION_HEX < 0x02050000
+typedef int Py_ssize_t;
+#define PY_SSIZE_T_MAX INT_MAX
+#define PY_SSIZE_T_MIN INT_MIN
+typedef inquiry lenfunc;
+#endif
+
+/* Compilation on Python 2.x */
+#if PY_VERSION_HEX < 0x03000000
+#define RO READONLY
+#define _PyUnicode_Check PyString_Check
+#define _PyUnicode_AsString PyString_AsString
+#define _PyUnicode_AsStringAndSize PyString_AsStringAndSize
+#define _PyUnicode_FromString PyString_FromString
+#define _PyUnicode_FromStringAndSize PyString_FromStringAndSize
+#define _PyUnicode_FromFormat PyString_FromFormat
+#define _PyUnicode_AS_STRING PyString_AS_STRING
+#define _PyUnicode_GET_SIZE PyString_GET_SIZE
+#define _PyUnicode_Resize _PyString_Resize
+#define _PyUnicode_Type PyString_Type
+#define _PyLong_Check PyInt_Check
+#define _PyLong_FromLong PyInt_FromLong
+#define _PyLong_AsLong PyInt_AsLong
+#define _PyLongObject PyIntObject
+#define _PyLong_Type PyInt_Type
+#define _PyLong_AS_LONG PyInt_AS_LONG
+#define Py_TYPE(ob) (((PyObject*)(ob))->ob_type)
+#else
+#undef PYGLIB_MODULE_START
+#undef PYGLIB_MODULE_END
+#undef PYGLIB_DEFINE_TYPE
+#undef PYGLIB_REGISTER_TYPE
+
+#define PYGLIB_MODULE_START(symbol, modname) \
+ static struct PyModuleDef _##symbol##module = { \
+ PyModuleDef_HEAD_INIT, \
+ modname, \
+ NULL, \
+ -1, \
+ symbol##_functions, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL \
+}; \
+PyMODINIT_FUNC PyInit_##symbol(void) \
+{ \
+ PyObject *module; \
+ module = PyModule_Create(&_##symbol##module);
+#define PYGLIB_MODULE_END return module; }
+#define PYGLIB_DEFINE_TYPE(typename, symbol, csymbol) \
+PyTypeObject symbol = { \
+ PyVarObject_HEAD_INIT(NULL, 0) \
+ typename, \
+ sizeof(csymbol) \
+};
+#define PYGLIB_REGISTER_TYPE(d, type, name) \
+ if (!type.tp_alloc) \
+ type.tp_alloc = PyType_GenericAlloc; \
+ if (!type.tp_new) \
+ type.tp_new = PyType_GenericNew; \
+ if (PyType_Ready(&type)) \
+ return; \
+ PyDict_SetItemString(d, name, (PyObject *)&type);
+
+#define _PyUnicode_Check PyUnicode_Check
+#define _PyUnicode_AsString PyUnicode_AsString
+#define _PyUnicode_AsStringAndSize(obj, buf, size) PyUnicode_AsStringAndSize(obj, size)
+#define _PyUnicode_FromString PyUnicode_FromString
+#define _PyUnicode_FromStringAndSize PyUnicode_FromStringAndSize
+#define _PyUnicode_FromFormat PyUnicode_FromFormat
+#define _PyUnicode_AS_STRING _PyUnicode_AsString
+#define _PyUnicode_GET_SIZE PyUnicode_GET_SIZE
+#define _PyUnicode_Resize PyUnicode_Resize
+#define _PyUnicode_Type PyUnicode_Type
+#define _PyLong_Check PyLong_Check
+#define _PyLong_FromLong PyLong_FromLong
+#define _PyLong_AsLong PyLong_AsLong
+#define _PyLong_AS_LONG PyLong_AS_LONG
+#define _PyLongObject PyLongObject
+#define _PyLong_Type PyLong_Type
+#endif
+
+#endif /* __PYGLIB_PYTHON_COMPAT_H__ */
diff --git a/glib/pyglib.c b/glib/pyglib.c
new file mode 100644
index 0000000..a1bdbb9
--- /dev/null
+++ b/glib/pyglib.c
@@ -0,0 +1,577 @@
+/* -*- Mode: C; c-set-style: python; c-basic-offset: 4 -*-
+ * pyglib - Python bindings for GLib toolkit.
+ * Copyright (C) 1998-2003 James Henstridge
+ * 2004-2008 Johan Dahlin
+ *
+ * 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
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <Python.h>
+#include <pythread.h>
+#include "pyglib.h"
+#include "pyglib-private.h"
+#include "pygmaincontext.h"
+#include "pygoptioncontext.h"
+#include "pygoptiongroup.h"
+
+static struct _PyGLib_Functions *_PyGLib_API;
+static int pyglib_thread_state_tls_key;
+static PyObject *exception_table = NULL;
+
+static PyTypeObject *_PyGMainContext_Type;
+#define PyGMainContext_Type (*_PyGMainContext_Type)
+
+static PyTypeObject *_PyGOptionGroup_Type;
+#define PyGOptionGroup_Type (*_PyGOptionGroup_Type)
+
+static PyTypeObject *_PyGOptionContext_Type;
+#define PyGOptionContext_Type (*_PyGOptionContext_Type)
+
+void
+pyglib_init(void)
+{
+ PyObject *glib, *cobject;
+
+ glib = PyImport_ImportModule("glib");
+ if (!glib) {
+ if (PyErr_Occurred()) {
+ PyObject *type, *value, *traceback;
+ PyObject *py_orig_exc;
+ PyErr_Fetch(&type, &value, &traceback);
+ py_orig_exc = PyObject_Repr(value);
+ Py_XDECREF(type);
+ Py_XDECREF(value);
+ Py_XDECREF(traceback);
+ PyErr_Format(PyExc_ImportError,
+ "could not import glib (error was: %s)",
+ _PyUnicode_AsString(py_orig_exc));
+ Py_DECREF(py_orig_exc);
+ } else {
+ PyErr_SetString(PyExc_ImportError,
+ "could not import glib (no error given)");
+ }
+ return;
+ }
+
+ cobject = PyObject_GetAttrString(glib, "_PyGLib_API");
+ if (cobject && PyCObject_Check(cobject))
+ _PyGLib_API = (struct _PyGLib_Functions *) PyCObject_AsVoidPtr(cobject);
+ else {
+ PyErr_SetString(PyExc_ImportError,
+ "could not import glib (could not find _PyGLib_API object)");
+ Py_DECREF(glib);
+ return;
+ }
+
+ _PyGMainContext_Type = (PyTypeObject*)PyObject_GetAttrString(glib, "MainContext");
+ _PyGOptionGroup_Type = (PyTypeObject*)PyObject_GetAttrString(glib, "OptionGroup");
+ _PyGOptionContext_Type = (PyTypeObject*)PyObject_GetAttrString(glib, "OptionContext");
+}
+
+void
+pyglib_init_internal(PyObject *api)
+{
+ _PyGLib_API = (struct _PyGLib_Functions *) PyCObject_AsVoidPtr(api);
+}
+
+gboolean
+pyglib_threads_enabled(void)
+{
+ g_return_val_if_fail (_PyGLib_API != NULL, FALSE);
+
+ return _PyGLib_API->threads_enabled;
+}
+
+PyGILState_STATE
+pyglib_gil_state_ensure(void)
+{
+ g_return_val_if_fail (_PyGLib_API != NULL, PyGILState_LOCKED);
+
+ if (!_PyGLib_API->threads_enabled)
+ return PyGILState_LOCKED;
+
+ return PyGILState_Ensure();
+}
+
+void
+pyglib_gil_state_release(PyGILState_STATE state)
+{
+ g_return_if_fail (_PyGLib_API != NULL);
+
+ if (!_PyGLib_API->threads_enabled)
+ return;
+
+ PyGILState_Release(state);
+}
+
+/**
+ * pyglib_enable_threads:
+ *
+ * Returns: TRUE if threading is enabled, FALSE otherwise.
+ *
+ */
+#ifdef DISABLE_THREADING
+gboolean
+pyglib_enable_threads(void)
+{
+ PyErr_SetString(PyExc_RuntimeError,
+ "pyglib threading disabled at compile time");
+ return FALSE;
+}
+
+void
+_pyglib_notify_on_enabling_threads(PyGLibThreadsEnabledFunc callback)
+{
+ /* Ignore, threads cannot be enabled. */
+}
+
+#else
+
+static GSList *thread_enabling_callbacks = NULL;
+
+/* Enable threading; note that the GIL must be held by the current
+ * thread when this function is called
+ */
+gboolean
+pyglib_enable_threads(void)
+{
+ GSList *callback;
+
+ g_return_val_if_fail (_PyGLib_API != NULL, FALSE);
+
+ if (_PyGLib_API->threads_enabled)
+ return TRUE;
+
+ PyEval_InitThreads();
+ if (!g_threads_got_initialized)
+ g_thread_init(NULL);
+
+ _PyGLib_API->threads_enabled = TRUE;
+ pyglib_thread_state_tls_key = PyThread_create_key();
+
+ for (callback = thread_enabling_callbacks; callback; callback = callback->next)
+ ((PyGLibThreadsEnabledFunc) callback->data) ();
+
+ g_slist_free(thread_enabling_callbacks);
+ return TRUE;
+}
+
+void
+_pyglib_notify_on_enabling_threads(PyGLibThreadsEnabledFunc callback)
+{
+ if (callback && !pyglib_threads_enabled())
+ thread_enabling_callbacks = g_slist_append(thread_enabling_callbacks, callback);
+}
+#endif
+
+int
+pyglib_gil_state_ensure_py23 (void)
+{
+ return PyGILState_Ensure();
+}
+
+void
+pyglib_gil_state_release_py23 (int flag)
+{
+ PyGILState_Release(flag);
+}
+
+/**
+ * pyglib_block_threads:
+ *
+ */
+void
+pyglib_block_threads(void)
+{
+ g_return_if_fail (_PyGLib_API != NULL);
+
+ if (_PyGLib_API->block_threads != NULL)
+ (* _PyGLib_API->block_threads)();
+}
+
+/**
+ * pyglib_unblock_threads:
+ *
+ */
+void
+pyglib_unblock_threads(void)
+{
+ g_return_if_fail (_PyGLib_API != NULL);
+ if (_PyGLib_API->unblock_threads != NULL)
+ (* _PyGLib_API->unblock_threads)();
+}
+
+/**
+ * pyglib_set_thread_block_funcs:
+ *
+ * hooks to register handlers for getting GDK threads to cooperate
+ * with python threading
+ */
+void
+pyglib_set_thread_block_funcs (PyGLibThreadBlockFunc block_threads_func,
+ PyGLibThreadBlockFunc unblock_threads_func)
+{
+ g_return_if_fail (_PyGLib_API != NULL);
+
+ _PyGLib_API->block_threads = block_threads_func;
+ _PyGLib_API->unblock_threads = unblock_threads_func;
+}
+
+
+/**
+ * pyglib_error_check:
+ * @error: a pointer to the GError.
+ *
+ * Checks to see if the GError has been set. If the error has been
+ * set, then the glib.GError Python exception will be raised, and
+ * the GError cleared.
+ *
+ * Returns: True if an error was set.
+ */
+gboolean
+pyglib_error_check(GError **error)
+{
+ PyGILState_STATE state;
+ PyObject *exc_type;
+ PyObject *exc_instance;
+ PyObject *d;
+
+ g_return_val_if_fail(error != NULL, FALSE);
+
+ if (*error == NULL)
+ return FALSE;
+
+ state = pyglib_gil_state_ensure();
+
+ exc_type = _PyGLib_API->gerror_exception;
+ if (exception_table != NULL)
+ {
+ PyObject *item;
+ item = PyDict_GetItem(exception_table, _PyLong_FromLong((*error)->domain));
+ if (item != NULL)
+ exc_type = item;
+ }
+
+ exc_instance = PyObject_CallFunction(exc_type, "z", (*error)->message);
+
+ if ((*error)->domain) {
+ PyObject_SetAttrString(exc_instance, "domain",
+ d=_PyUnicode_FromString(g_quark_to_string((*error)->domain)));
+ Py_DECREF(d);
+ }
+ else
+ PyObject_SetAttrString(exc_instance, "domain", Py_None);
+
+ PyObject_SetAttrString(exc_instance, "code",
+ d=_PyLong_FromLong((*error)->code));
+ Py_DECREF(d);
+
+ if ((*error)->message) {
+ PyObject_SetAttrString(exc_instance, "message",
+ d=_PyUnicode_FromString((*error)->message));
+ Py_DECREF(d);
+ } else {
+ PyObject_SetAttrString(exc_instance, "message", Py_None);
+ }
+
+ PyErr_SetObject(_PyGLib_API->gerror_exception, exc_instance);
+ Py_DECREF(exc_instance);
+ g_clear_error(error);
+
+ pyglib_gil_state_release(state);
+
+ return TRUE;
+}
+
+/**
+ * pyglib_gerror_exception_check:
+ * @error: a standard GLib GError ** output parameter
+ *
+ * Checks to see if a GError exception has been raised, and if so
+ * translates the python exception to a standard GLib GError. If the
+ * raised exception is not a GError then PyErr_Print() is called.
+ *
+ * Returns: 0 if no exception has been raised, -1 if it is a
+ * valid glib.GError, -2 otherwise.
+ */
+gboolean
+pyglib_gerror_exception_check(GError **error)
+{
+ PyObject *type, *value, *traceback;
+ PyObject *py_message, *py_domain, *py_code;
+ const char *bad_gerror_message;
+
+ PyErr_Fetch(&type, &value, &traceback);
+ if (type == NULL)
+ return 0;
+ PyErr_NormalizeException(&type, &value, &traceback);
+ if (value == NULL) {
+ PyErr_Restore(type, value, traceback);
+ PyErr_Print();
+ return -2;
+ }
+ if (!value ||
+ !PyErr_GivenExceptionMatches(type,
+ (PyObject *) _PyGLib_API->gerror_exception)) {
+ PyErr_Restore(type, value, traceback);
+ PyErr_Print();
+ return -2;
+ }
+ Py_DECREF(type);
+ Py_XDECREF(traceback);
+
+ py_message = PyObject_GetAttrString(value, "message");
+ if (!py_message || !_PyUnicode_Check(py_message)) {
+ bad_gerror_message = "glib.GError instances must have a 'message' string attribute";
+ goto bad_gerror;
+ }
+
+ py_domain = PyObject_GetAttrString(value, "domain");
+ if (!py_domain || !_PyUnicode_Check(py_domain)) {
+ bad_gerror_message = "glib.GError instances must have a 'domain' string attribute";
+ Py_DECREF(py_message);
+ goto bad_gerror;
+ }
+
+ py_code = PyObject_GetAttrString(value, "code");
+ if (!py_code || !_PyLong_Check(py_code)) {
+ bad_gerror_message = "glib.GError instances must have a 'code' int attribute";
+ Py_DECREF(py_message);
+ Py_DECREF(py_domain);
+ goto bad_gerror;
+ }
+
+ g_set_error(error, g_quark_from_string(_PyUnicode_AsString(py_domain)),
+ _PyLong_AsLong(py_code), _PyUnicode_AsString(py_message));
+
+ Py_DECREF(py_message);
+ Py_DECREF(py_code);
+ Py_DECREF(py_domain);
+ return -1;
+
+bad_gerror:
+ Py_DECREF(value);
+ g_set_error(error, g_quark_from_static_string("pyglib"), 0, bad_gerror_message);
+ PyErr_SetString(PyExc_ValueError, bad_gerror_message);
+ PyErr_Print();
+ return -2;
+}
+
+/**
+ * pyglib_register_exception_for_domain:
+ * @name: name of the exception
+ * @error_domain: error domain
+ *
+ * Registers a new glib.GError exception subclass called #name for
+ * a specific #domain. This exception will be raised when a GError
+ * of the same domain is passed in to pyglib_error_check().
+ *
+ * Returns: the new exception
+ */
+PyObject *
+pyglib_register_exception_for_domain(gchar *name,
+ gint error_domain)
+{
+ PyObject *exception;
+
+ exception = PyErr_NewException(name, _PyGLib_API->gerror_exception, NULL);
+
+ if (exception_table == NULL)
+ exception_table = PyDict_New();
+
+ PyDict_SetItem(exception_table,
+ _PyLong_FromLong(error_domain),
+ exception);
+
+ return exception;
+}
+
+/**
+ * pyglib_main_context_new:
+ * @context: a GMainContext.
+ *
+ * Creates a wrapper for a GMainContext.
+ *
+ * Returns: the GMainContext wrapper.
+ */
+PyObject *
+pyglib_main_context_new(GMainContext *context)
+{
+ PyGMainContext *self;
+
+ self = (PyGMainContext *)PyObject_NEW(PyGMainContext,
+ &PyGMainContext_Type);
+ if (self == NULL)
+ return NULL;
+
+ self->context = g_main_context_ref(context);
+ return (PyObject *)self;
+}
+
+/**
+ * pyg_option_group_transfer_group:
+ * @group: a GOptionGroup wrapper
+ *
+ * This is used to transfer the GOptionGroup to a GOptionContext. After this
+ * is called, the calle must handle the release of the GOptionGroup.
+ *
+ * When #NULL is returned, the GOptionGroup was already transfered.
+ *
+ * Returns: Either #NULL or the wrapped GOptionGroup.
+ */
+GOptionGroup *
+pyglib_option_group_transfer_group(PyObject *obj)
+{
+ PyGOptionGroup *self = (PyGOptionGroup*)obj;
+
+ if (self->is_in_context)
+ return NULL;
+
+ self->is_in_context = TRUE;
+
+ /* Here we increase the reference count of the PyGOptionGroup, because now
+ * the GOptionContext holds an reference to us (it is the userdata passed
+ * to g_option_group_new().
+ *
+ * The GOptionGroup is freed with the GOptionContext.
+ *
+ * We set it here because if we would do this in the init method we would
+ * hold two references and the PyGOptionGroup would never be freed.
+ */
+ Py_INCREF(self);
+
+ return self->group;
+}
+
+/**
+ * pyglib_option_group_new:
+ * @group: a GOptionGroup
+ *
+ * The returned GOptionGroup can't be used to set any hooks, translation domains
+ * or add entries. It's only intend is, to use for GOptionContext.add_group().
+ *
+ * Returns: the GOptionGroup wrapper.
+ */
+PyObject *
+pyglib_option_group_new (GOptionGroup *group)
+{
+ PyGOptionGroup *self;
+
+ self = (PyGOptionGroup *)PyObject_NEW(PyGOptionGroup,
+ &PyGOptionGroup_Type);
+ if (self == NULL)
+ return NULL;
+
+ self->group = group;
+ self->other_owner = TRUE;
+ self->is_in_context = FALSE;
+
+ return (PyObject *)self;
+}
+
+/**
+ * pyglib_option_context_new:
+ * @context: a GOptionContext
+ *
+ * Returns: A new GOptionContext wrapper.
+ */
+PyObject *
+pyglib_option_context_new (GOptionContext *context)
+{
+ PyGOptionContext *self;
+
+ self = (PyGOptionContext *)PyObject_NEW(PyGOptionContext,
+ &PyGOptionContext_Type);
+ if (self == NULL)
+ return NULL;
+
+ self->context = context;
+ self->main_group = NULL;
+
+ return (PyObject *)self;
+}
+
+/**
+ * pyglib_option_context_new:
+ * @context: a GTimeVal struct
+ *
+ * Converts a GTimeVal struct to a python float
+ *
+ * Returns: a float representing the timeval
+ */
+PyObject *
+pyglib_float_from_timeval(GTimeVal timeval)
+{
+ double ret;
+ ret = (double)timeval.tv_sec + (double)timeval.tv_usec * 0.000001;
+ return PyFloat_FromDouble(ret);
+}
+
+
+/****** Private *****/
+
+/**
+ * _pyglib_destroy_notify:
+ * @user_data: a PyObject pointer.
+ *
+ * A function that can be used as a GDestroyNotify callback that will
+ * call Py_DECREF on the data.
+ */
+void
+_pyglib_destroy_notify(gpointer user_data)
+{
+ PyObject *obj = (PyObject *)user_data;
+ PyGILState_STATE state;
+
+ g_return_if_fail (_PyGLib_API != NULL);
+
+ state = pyglib_gil_state_ensure();
+ Py_DECREF(obj);
+ pyglib_gil_state_release(state);
+}
+
+gboolean
+_pyglib_handler_marshal(gpointer user_data)
+{
+ PyObject *tuple, *ret;
+ gboolean res;
+ PyGILState_STATE state;
+
+ g_return_val_if_fail(user_data != NULL, FALSE);
+
+ state = pyglib_gil_state_ensure();
+
+ tuple = (PyObject *)user_data;
+ ret = PyObject_CallObject(PyTuple_GetItem(tuple, 0),
+ PyTuple_GetItem(tuple, 1));
+ if (!ret) {
+ PyErr_Print();
+ res = FALSE;
+ } else {
+ res = PyObject_IsTrue(ret);
+ Py_DECREF(ret);
+ }
+
+ pyglib_gil_state_release(state);
+
+ return res;
+}
+
+
diff --git a/glib/pyglib.h b/glib/pyglib.h
new file mode 100644
index 0000000..84bb36c
--- /dev/null
+++ b/glib/pyglib.h
@@ -0,0 +1,94 @@
+/* -*- Mode: C; c-basic-offset: 4 -*-
+ * pyglib - Python bindings for GLib toolkit.
+ * Copyright (C) 1998-2003 James Henstridge
+ * 2004-2008 Johan Dahlin
+ *
+ * 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 __PYGLIB_H__
+#define __PYGLIB_H__
+
+#include <Python.h>
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+typedef void (*PyGLibThreadsEnabledFunc) (void);
+typedef void (*PyGLibThreadBlockFunc) (void);
+
+void pyglib_init(void);
+void pyglib_init_internal(PyObject *api);
+PyGILState_STATE pyglib_gil_state_ensure(void);
+void pyglib_gil_state_release(PyGILState_STATE state);
+int pyglib_enable_threads(void);
+gboolean pyglib_error_check(GError **error);
+gboolean pyglib_gerror_exception_check(GError **error);
+PyObject *pyglib_register_exception_for_domain(gchar *name,
+ gint error_domain);
+gboolean pyglib_threads_enabled(void);
+PyObject * pyglib_main_context_new(GMainContext *context);
+void pyglib_set_thread_block_funcs(PyGLibThreadBlockFunc block_threads_func,
+ PyGLibThreadBlockFunc unblock_threads_func);
+void pyglib_block_threads(void);
+void pyglib_unblock_threads(void);
+PyObject * pyglib_option_context_new(GOptionContext *context);
+PyObject * pyglib_option_group_new(GOptionGroup *group);
+GOptionGroup * pyglib_option_group_transfer_group(PyObject *self);
+PyObject * pyglib_float_from_timeval(GTimeVal timeval);
+
+/* Private: for gobject <-> glib interaction only. */
+void _pyglib_notify_on_enabling_threads(PyGLibThreadsEnabledFunc callback);
+
+#define pyglib_begin_allow_threads \
+ G_STMT_START { \
+ PyThreadState *_save = NULL; \
+ if (pyglib_threads_enabled()) \
+ _save = PyEval_SaveThread();
+
+#define pyglib_end_allow_threads \
+ if (pyglib_threads_enabled()) \
+ PyEval_RestoreThread(_save); \
+ } G_STMT_END
+
+#define PYGLIB_MODULE_START(symbol, modname) \
+DL_EXPORT(void) init##symbol(void) \
+{ \
+ PyObject *module; \
+ module = Py_InitModule(modname, symbol##_functions);
+#define PYGLIB_MODULE_END }
+#define PYGLIB_DEFINE_TYPE(typename, symbol, csymbol) \
+PyTypeObject symbol = { \
+ PyObject_HEAD_INIT(NULL) \
+ 0, \
+ typename, \
+ sizeof(csymbol), \
+ 0, \
+};
+#define PYGLIB_REGISTER_TYPE(d, type, name) \
+ if (!type.tp_alloc) \
+ type.tp_alloc = PyType_GenericAlloc; \
+ if (!type.tp_new) \
+ type.tp_new = PyType_GenericNew; \
+ if (PyType_Ready(&type)) \
+ return; \
+ PyDict_SetItemString(d, name, (PyObject *)&type);
+
+G_END_DECLS
+
+#endif /* __PYGLIB_H__ */
+
diff --git a/glib/pygmaincontext.c b/glib/pygmaincontext.c
new file mode 100644
index 0000000..186215a
--- /dev/null
+++ b/glib/pygmaincontext.c
@@ -0,0 +1,99 @@
+/* -*- Mode: C; c-basic-offset: 4 -*-
+ * pygtk- Python bindings for the GTK toolkit.
+ * Copyright (C) 1998-2003 James Henstridge
+ *
+ * pygmaincontext.c: GMainContext 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
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <Python.h>
+#include <pythread.h>
+#include <glib.h>
+#include "pygmaincontext.h"
+#include "pyglib.h"
+#include "pyglib-private.h"
+
+PYGLIB_DEFINE_TYPE("glib.MainContext", PyGMainContext_Type, PyGMainContext)
+
+static int
+pyg_main_context_init(PyGMainContext *self)
+{
+ self->context = g_main_context_new();
+ return 0;
+}
+
+static void
+pyg_main_context_dealloc(PyGMainContext *self)
+{
+ if (self->context != NULL) {
+ g_main_context_unref(self->context);
+ self->context = NULL;
+ }
+
+ PyObject_Del(self);
+}
+
+static int
+pyg_main_context_compare(PyGMainContext *self, PyGMainContext *v)
+{
+ if (self->context == v->context) return 0;
+ if (self->context > v->context) return -1;
+ return 1;
+}
+
+static PyObject *
+_wrap_g_main_context_iteration (PyGMainContext *self, PyObject *args)
+{
+ gboolean ret, may_block = TRUE;
+
+ if (!PyArg_ParseTuple(args, "|i:GMainContext.iteration",
+ &may_block))
+ return NULL;
+
+ pyglib_begin_allow_threads;
+ ret = g_main_context_iteration(self->context, may_block);
+ pyglib_end_allow_threads;
+
+ return PyBool_FromLong(ret);
+}
+
+static PyObject *
+_wrap_g_main_context_pending (PyGMainContext *self)
+{
+ return PyBool_FromLong(g_main_context_pending(self->context));
+}
+
+static PyMethodDef _PyGMainContext_methods[] = {
+ { "iteration", (PyCFunction)_wrap_g_main_context_iteration, METH_VARARGS },
+ { "pending", (PyCFunction)_wrap_g_main_context_pending, METH_NOARGS },
+ { NULL, NULL, 0 }
+};
+
+void
+pyglib_maincontext_register_types(PyObject *d)
+{
+ PyGMainContext_Type.tp_dealloc = (destructor)pyg_main_context_dealloc;
+ PyGMainContext_Type.tp_compare = (cmpfunc)pyg_main_context_compare;
+ PyGMainContext_Type.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE;
+ PyGMainContext_Type.tp_methods = _PyGMainContext_methods;
+ PyGMainContext_Type.tp_init = (initproc)pyg_main_context_init;
+ PYGLIB_REGISTER_TYPE(d, PyGMainContext_Type, "MainContext");
+}
diff --git a/glib/pygmaincontext.h b/glib/pygmaincontext.h
new file mode 100644
index 0000000..038cb37
--- /dev/null
+++ b/glib/pygmaincontext.h
@@ -0,0 +1,40 @@
+/* -*- Mode: C; c-basic-offset: 4 -*-
+ * pyglib - Python bindings for GLib toolkit.
+ * Copyright (C) 1998-2003 James Henstridge
+ * 2004-2008 Johan Dahlin
+ *
+ * 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 __PYG_MAINCONTEXT_H__
+#define __PYG_MAINCONTEXT_H__
+
+#include <Python.h>
+#include <glib.h>
+
+typedef struct {
+ PyObject_HEAD
+ GMainContext *context;
+} PyGMainContext;
+
+extern PyTypeObject PyGMainContext_Type;
+
+PyObject * pyglib_main_context_new(GMainContext *context);
+
+void pyglib_maincontext_register_types(PyObject *d);
+
+#endif /* __PYG_MAINCONTEXT_H__ */
+
diff --git a/glib/pygmainloop.c b/glib/pygmainloop.c
new file mode 100644
index 0000000..d9f048c
--- /dev/null
+++ b/glib/pygmainloop.c
@@ -0,0 +1,354 @@
+/* -*- Mode: C; c-basic-offset: 4 -*-
+ * pygtk- Python bindings for the GTK toolkit.
+ * Copyright (C) 1998-2003 James Henstridge
+ * Copyright (C) 2004 Johan Dahlin
+ *
+ * pygmainloop.c: GMainLoop 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
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+#include <fcntl.h>
+
+#include <Python.h>
+#include <pythread.h>
+#include <glib.h>
+
+#include "pygmainloop.h"
+#include "pygmaincontext.h"
+#include "pyglib.h"
+#include "pyglib-private.h"
+
+static int pipe_fds[2];
+
+typedef struct {
+ GSource source;
+ GPollFD fd;
+} PySignalWatchSource;
+
+#ifdef DISABLE_THREADING
+static GMainLoop *pyg_current_main_loop = NULL;;
+
+static inline GMainLoop *
+pyg_save_current_main_loop (GMainLoop *main_loop)
+{
+ GMainLoop *retval = pyg_current_main_loop;
+
+ g_return_val_if_fail(main_loop != NULL, NULL);
+
+ pyg_current_main_loop = g_main_loop_ref(main_loop);
+
+ return retval;
+}
+
+static inline void
+pyg_restore_current_main_loop (GMainLoop *main_loop)
+{
+ if (pyg_current_main_loop != NULL)
+ g_main_loop_unref(pyg_current_main_loop);
+ pyg_current_main_loop = main_loop;
+}
+
+static inline GMainLoop *
+pyg_get_current_main_loop (void)
+{
+ return pyg_current_main_loop;
+}
+#else /* !defined(#ifndef DISABLE_THREADING) */
+
+static int pyg_current_main_loop_key = -1;
+
+static inline GMainLoop *
+pyg_save_current_main_loop (GMainLoop *main_loop)
+{
+ GMainLoop *retval;
+
+ g_return_val_if_fail(main_loop != NULL, NULL);
+
+ if (pyg_current_main_loop_key == -1)
+ pyg_current_main_loop_key = PyThread_create_key();
+
+ retval = PyThread_get_key_value(pyg_current_main_loop_key);
+ PyThread_delete_key_value(pyg_current_main_loop_key);
+ PyThread_set_key_value(pyg_current_main_loop_key,
+ g_main_loop_ref(main_loop));
+
+ return retval;
+}
+
+static inline void
+pyg_restore_current_main_loop (GMainLoop *main_loop)
+{
+ GMainLoop *prev;
+
+ g_return_if_fail (pyg_current_main_loop_key != -1);
+
+ prev = PyThread_get_key_value(pyg_current_main_loop_key);
+ if (prev != NULL)
+ g_main_loop_unref(prev);
+ PyThread_delete_key_value(pyg_current_main_loop_key);
+ if (main_loop != NULL)
+ PyThread_set_key_value(pyg_current_main_loop_key, main_loop);
+}
+
+static inline GMainLoop *
+pyg_get_current_main_loop (void)
+{
+ if (pyg_current_main_loop_key == -1)
+ return NULL;
+ return PyThread_get_key_value(pyg_current_main_loop_key);
+}
+#endif /* DISABLE_THREADING */
+
+static gboolean
+pyg_signal_watch_prepare(GSource *source,
+ int *timeout)
+{
+ /* Python only invokes signal handlers from the main thread,
+ * so if a thread other than the main thread receives the signal
+ * from the kernel, PyErr_CheckSignals() from that thread will
+ * do nothing.
+ */
+
+#ifdef HAVE_PYSIGNAL_SETWAKEUPFD
+ return FALSE;
+#else /* !HAVE_PYSIGNAL_SETWAKEUPFD */
+ /* On Windows g_poll() won't be interrupted by a signal
+ * (AFAIK), so we need the timeout there too, even if there's
+ * only one thread.
+ */
+#ifndef PLATFORM_WIN32
+ if (!pyglib_threads_enabled())
+ return FALSE;
+#endif /* PLATFORM_WIN32 */
+
+ /* If we're using 2.5 or an earlier version of python we
+ * will default to a timeout every second, be aware,
+ * this will cause unnecessary wakeups, see
+ * http://bugzilla.gnome.org/show_bug.cgi?id=481569
+ */
+ *timeout = 1000;
+ return FALSE;
+#endif /* HAVE_PYSIGNAL_SETWAKEUPFD */
+}
+
+static gboolean
+pyg_signal_watch_check(GSource *source)
+{
+ PyGILState_STATE state;
+ GMainLoop *main_loop;
+
+#ifdef HAVE_PYSIGNAL_SETWAKEUPFD
+ PySignalWatchSource *real_source = (PySignalWatchSource *)source;
+ GPollFD *poll_fd = &real_source->fd;
+ unsigned char dummy;
+ if (poll_fd->revents & G_IO_IN)
+ read(poll_fd->fd, &dummy, 1);
+#endif
+
+ state = pyglib_gil_state_ensure();
+
+ main_loop = pyg_get_current_main_loop();
+
+ if (PyErr_CheckSignals() == -1 && main_loop != NULL) {
+ PyErr_SetNone(PyExc_KeyboardInterrupt);
+ g_main_loop_quit(main_loop);
+ }
+
+ pyglib_gil_state_release(state);
+
+ return FALSE;
+}
+
+static gboolean
+pyg_signal_watch_dispatch(GSource *source,
+ GSourceFunc callback,
+ gpointer user_data)
+{
+ /* We should never be dispatched */
+ g_assert_not_reached();
+ return TRUE;
+}
+
+static GSourceFuncs pyg_signal_watch_funcs =
+{
+ pyg_signal_watch_prepare,
+ pyg_signal_watch_check,
+ pyg_signal_watch_dispatch
+};
+
+static GSource *
+pyg_signal_watch_new(void)
+{
+ GSource *source = g_source_new(&pyg_signal_watch_funcs,
+ sizeof(PySignalWatchSource));
+
+#ifdef HAVE_PYSIGNAL_SETWAKEUPFD
+ PySignalWatchSource *real_source = (PySignalWatchSource *)source;
+ int flag;
+
+ /* Unfortunately we need to create a new pipe here instead of
+ * reusing the pipe inside the GMainContext.
+ * Ideally an api should be added to GMainContext which allows us
+ * to reuse that pipe which would suit us perfectly fine.
+ * XXX More efficient than a pipe, we could use an eventfd on Linux
+ * kernels that support it.
+ */
+ gint already_piped = (pipe_fds[0] > 0);
+ if (!already_piped) {
+ if (pipe(pipe_fds) < 0)
+ g_error("Cannot create main loop pipe: %s\n",
+ g_strerror(errno));
+
+ /* Make the write end of the fd non blocking */
+ flag = fcntl(pipe_fds[1], F_GETFL, 0);
+ flag |= O_NONBLOCK;
+ fcntl(pipe_fds[1], F_SETFL, flag);
+ }
+
+ real_source->fd.fd = pipe_fds[0];
+ real_source->fd.events = G_IO_IN | G_IO_HUP | G_IO_ERR;
+ g_source_add_poll(source, &real_source->fd);
+
+ if (!already_piped)
+ PySignal_SetWakeupFd(pipe_fds[1]);
+#endif
+ return source;
+}
+
+PYGLIB_DEFINE_TYPE("glib.MainLoop", PyGMainLoop_Type, PyGMainLoop)
+
+static int
+pyg_main_loop_init(PyGMainLoop *self, PyObject *args, PyObject *kwargs)
+{
+ static char *kwlist[] = { "context", "is_running", NULL };
+ PyObject *py_context = Py_None;
+ int is_running = 0;
+ GMainContext *context;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs,
+ "|Ob:GMainLoop.__init__",
+ kwlist, &py_context, &is_running))
+ return -1;
+
+ if (!PyObject_TypeCheck(py_context, &PyGMainContext_Type) &&
+ py_context != Py_None) {
+ PyErr_SetString(PyExc_TypeError,
+ "context must be a glib.MainContext or None");
+ return -1;
+ }
+
+ if (py_context != Py_None) {
+ context = ((PyGMainContext*)py_context)->context;
+ } else {
+ context = NULL;
+ }
+
+ self->loop = g_main_loop_new(context, is_running);
+
+ self->signal_source = pyg_signal_watch_new();
+ g_source_attach(self->signal_source, context);
+ g_source_unref(self->signal_source);
+
+ return 0;
+}
+
+static void
+pyg_main_loop_dealloc(PyGMainLoop *self)
+{
+ if (self->signal_source != NULL) {
+ g_source_destroy(self->signal_source);
+ self->signal_source = NULL;
+ }
+
+ if (self->loop != NULL) {
+ g_main_loop_unref(self->loop);
+ self->loop = NULL;
+ }
+
+ PyObject_Del(self);
+}
+
+static int
+pyg_main_loop_compare(PyGMainLoop *self, PyGMainLoop *v)
+{
+ if (self->loop == v->loop) return 0;
+ if (self->loop > v->loop) return -1;
+ return 1;
+}
+
+static PyObject *
+_wrap_g_main_loop_get_context (PyGMainLoop *loop)
+{
+ return pyglib_main_context_new(g_main_loop_get_context(loop->loop));
+}
+
+static PyObject *
+_wrap_g_main_loop_is_running (PyGMainLoop *self)
+{
+ return PyBool_FromLong(g_main_loop_is_running(self->loop));
+}
+
+static PyObject *
+_wrap_g_main_loop_quit (PyGMainLoop *self)
+{
+ g_main_loop_quit(self->loop);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+_wrap_g_main_loop_run (PyGMainLoop *self)
+{
+ GMainLoop *prev_loop;
+
+ prev_loop = pyg_save_current_main_loop(self->loop);
+
+ pyglib_begin_allow_threads;
+ g_main_loop_run(self->loop);
+ pyglib_end_allow_threads;
+
+ pyg_restore_current_main_loop(prev_loop);
+
+ if (PyErr_Occurred())
+ return NULL;
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyMethodDef _PyGMainLoop_methods[] = {
+ { "get_context", (PyCFunction)_wrap_g_main_loop_get_context, METH_NOARGS },
+ { "is_running", (PyCFunction)_wrap_g_main_loop_is_running, METH_NOARGS },
+ { "quit", (PyCFunction)_wrap_g_main_loop_quit, METH_NOARGS },
+ { "run", (PyCFunction)_wrap_g_main_loop_run, METH_NOARGS },
+ { NULL, NULL, 0 }
+};
+
+void
+pyglib_mainloop_register_types(PyObject *d)
+{
+ PyGMainLoop_Type.tp_dealloc = (destructor)pyg_main_loop_dealloc;
+ PyGMainLoop_Type.tp_compare = (cmpfunc)pyg_main_loop_compare;
+ PyGMainLoop_Type.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE;
+ PyGMainLoop_Type.tp_methods = _PyGMainLoop_methods;
+ PyGMainLoop_Type.tp_init = (initproc)pyg_main_loop_init;
+ PYGLIB_REGISTER_TYPE(d, PyGMainLoop_Type, "MainLoop");
+}
diff --git a/glib/pygmainloop.h b/glib/pygmainloop.h
new file mode 100644
index 0000000..dec82d8
--- /dev/null
+++ b/glib/pygmainloop.h
@@ -0,0 +1,36 @@
+/* -*- Mode: C; c-basic-offset: 4 -*-
+ * pyglib - Python bindings for GLib toolkit.
+ * Copyright (C) 1998-2003 James Henstridge
+ * 2004-2008 Johan Dahlin
+ *
+ * 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 __PYG_MAINLOOP_H__
+#define __PYG_MAINLOOP_H__
+
+typedef struct {
+ PyObject_HEAD
+ GMainLoop *loop;
+ GSource *signal_source;
+} PyGMainLoop;
+
+extern PyTypeObject PyGMainLoop_Type;
+
+void pyglib_mainloop_register_types(PyObject *d);
+
+#endif /* __PYG_MAINLOOP_H__ */
+
diff --git a/glib/pygoptioncontext.c b/glib/pygoptioncontext.c
new file mode 100644
index 0000000..92ba901
--- /dev/null
+++ b/glib/pygoptioncontext.c
@@ -0,0 +1,312 @@
+/* -*- Mode: C; c-basic-offset: 4 -*-
+ * pygtk- Python bindings for the GTK toolkit.
+ * Copyright (C) 2006 Johannes Hoelzl
+ *
+ * pygoptioncontext.c: GOptionContext 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
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <pyglib.h>
+#include "pyglib-private.h"
+#include "pygoptioncontext.h"
+
+PYGLIB_DEFINE_TYPE("glib.OptionContext", PyGOptionContext_Type, PyGOptionContext)
+
+static int
+pyg_option_context_init(PyGOptionContext *self,
+ PyObject *args,
+ PyObject *kwargs)
+{
+ char *parameter_string;
+
+ if (!PyArg_ParseTuple(args, "s:glib.GOptionContext.__init__",
+ &parameter_string))
+ return -1;
+
+ self->context = g_option_context_new(parameter_string);
+ return 0;
+}
+
+static void
+pyg_option_context_dealloc(PyGOptionContext *self)
+{
+ Py_CLEAR(self->main_group);
+
+ if (self->context != NULL)
+ {
+ GOptionContext *tmp = self->context;
+ self->context = NULL;
+ g_option_context_free(tmp);
+ }
+
+ PyObject_Del(self);
+}
+
+static PyObject *
+pyg_option_context_parse(PyGOptionContext *self,
+ PyObject *args,
+ PyObject *kwargs)
+{
+ static char *kwlist[] = { "argv", NULL };
+ PyObject *arg;
+ PyObject *new_argv, *argv;
+ Py_ssize_t argv_length, pos;
+ gint argv_length_int;
+ char **argv_content, **original;
+ GError *error = NULL;
+ gboolean result;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:GOptionContext.parse",
+ kwlist, &argv))
+ return NULL;
+
+ if (!PyList_Check(argv))
+ {
+ PyErr_SetString(PyExc_TypeError,
+ "GOptionContext.parse expects a list of strings.");
+ return NULL;
+ }
+
+ argv_length = PyList_Size(argv);
+ if (argv_length == -1)
+ {
+ PyErr_SetString(PyExc_TypeError,
+ "GOptionContext.parse expects a list of strings.");
+ return NULL;
+ }
+
+ argv_content = g_new(char*, argv_length + 1);
+ argv_content[argv_length] = NULL;
+ for (pos = 0; pos < argv_length; pos++)
+ {
+ arg = PyList_GetItem(argv, pos);
+ argv_content[pos] = g_strdup(_PyUnicode_AsString(arg));
+ if (argv_content[pos] == NULL)
+ {
+ g_strfreev(argv_content);
+ return NULL;
+ }
+ }
+ original = g_strdupv(argv_content);
+
+ g_assert(argv_length <= G_MAXINT);
+ argv_length_int = argv_length;
+ pyglib_begin_allow_threads;
+ result = g_option_context_parse(self->context, &argv_length_int, &argv_content,
+ &error);
+ pyglib_end_allow_threads;
+ argv_length = argv_length_int;
+
+ if (!result)
+ {
+ g_strfreev(argv_content);
+ g_strfreev(original);
+ pyglib_error_check(&error);
+ return NULL;
+ }
+
+ new_argv = PyList_New(g_strv_length(argv_content));
+ for (pos = 0; pos < argv_length; pos++)
+ {
+ arg = _PyUnicode_FromString(argv_content[pos]);
+ PyList_SetItem(new_argv, pos, arg);
+ }
+
+ g_strfreev(original);
+ g_strfreev(argv_content);
+ return new_argv;
+}
+
+static PyObject *
+pyg_option_context_set_help_enabled(PyGOptionContext *self,
+ PyObject *args,
+ PyObject *kwargs)
+{
+ static char *kwlist[] = { "help_enable", NULL };
+
+ PyObject *help_enabled;
+ if (! PyArg_ParseTupleAndKeywords(args, kwargs,
+ "O:GOptionContext.set_help_enabled",
+ kwlist, &help_enabled))
+ return NULL;
+
+ g_option_context_set_help_enabled(self->context, PyObject_IsTrue(help_enabled));
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+pyg_option_context_get_help_enabled(PyGOptionContext *self)
+{
+ return PyBool_FromLong(g_option_context_get_help_enabled(self->context));
+}
+
+static PyObject *
+pyg_option_context_set_ignore_unknown_options(PyGOptionContext *self,
+ PyObject *args,
+ PyObject *kwargs)
+{
+ static char *kwlist[] = { "ignore_unknown_options", NULL };
+ PyObject *ignore_unknown_options;
+
+ if (! PyArg_ParseTupleAndKeywords(args, kwargs,
+ "O:GOptionContext.set_ignore_unknown_options",
+ kwlist, &ignore_unknown_options))
+ return NULL;
+
+ g_option_context_set_ignore_unknown_options(self->context,
+ PyObject_IsTrue(ignore_unknown_options));
+
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+pyg_option_context_get_ignore_unknown_options(PyGOptionContext *self)
+{
+ return PyBool_FromLong(
+ g_option_context_get_ignore_unknown_options(self->context));
+}
+
+static PyObject *
+pyg_option_context_set_main_group(PyGOptionContext *self,
+ PyObject *args,
+ PyObject *kwargs)
+{
+ static char *kwlist[] = { "group", NULL };
+ GOptionGroup *g_group;
+ PyObject *group;
+
+ if (! PyArg_ParseTupleAndKeywords(args, kwargs,
+ "O:GOptionContext.set_main_group",
+ kwlist, &group))
+ return NULL;
+
+ if (PyObject_IsInstance(group, (PyObject*) &PyGOptionGroup_Type) != 1) {
+ PyErr_SetString(PyExc_TypeError,
+ "GOptionContext.set_main_group expects a GOptionGroup.");
+ return NULL;
+ }
+
+ g_group = pyglib_option_group_transfer_group(group);
+ if (g_group == NULL)
+ {
+ PyErr_SetString(PyExc_RuntimeError,
+ "Group is already in a OptionContext.");
+ return NULL;
+ }
+
+ g_option_context_set_main_group(self->context, g_group);
+
+ Py_INCREF(group);
+ self->main_group = (PyGOptionGroup*) group;
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+pyg_option_context_get_main_group(PyGOptionContext *self)
+{
+ if (self->main_group == NULL)
+ {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ Py_INCREF(self->main_group);
+ return (PyObject*) self->main_group;
+}
+
+static PyObject *
+pyg_option_context_add_group(PyGOptionContext *self,
+ PyObject *args,
+ PyObject *kwargs)
+{
+ static char *kwlist[] = { "group", NULL };
+ GOptionGroup *g_group;
+ PyObject *group;
+
+ if (! PyArg_ParseTupleAndKeywords(args, kwargs,
+ "O:GOptionContext.add_group",
+ kwlist, &group))
+ return NULL;
+
+ if (PyObject_IsInstance(group, (PyObject*) &PyGOptionGroup_Type) != 1) {
+ PyErr_SetString(PyExc_TypeError,
+ "GOptionContext.add_group expects a GOptionGroup.");
+ return NULL;
+ }
+
+ g_group = pyglib_option_group_transfer_group(group);
+ if (g_group == NULL)
+ {
+ PyErr_SetString(PyExc_RuntimeError,
+ "Group is already in a OptionContext.");
+ return NULL;
+ }
+ Py_INCREF(group);
+
+ g_option_context_add_group(self->context, g_group);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static int
+pyg_option_context_compare(PyGOptionContext *self, PyGOptionContext *context)
+{
+ if (self->context == context->context) return 0;
+ if (self->context > context->context)
+ return 1;
+ return -1;
+}
+
+static PyObject *
+pyg_option_get_context(PyGOptionContext *self)
+{
+ return PyCObject_FromVoidPtr(self->context, NULL);
+}
+
+static PyMethodDef pyg_option_context_methods[] = {
+ { "parse", (PyCFunction)pyg_option_context_parse, METH_VARARGS | METH_KEYWORDS },
+ { "set_help_enabled", (PyCFunction)pyg_option_context_set_help_enabled, METH_VARARGS | METH_KEYWORDS },
+ { "get_help_enabled", (PyCFunction)pyg_option_context_get_help_enabled, METH_NOARGS },
+ { "set_ignore_unknown_options", (PyCFunction)pyg_option_context_set_ignore_unknown_options, METH_VARARGS | METH_KEYWORDS },
+ { "get_ignore_unknown_options", (PyCFunction)pyg_option_context_get_ignore_unknown_options, METH_NOARGS },
+ { "set_main_group", (PyCFunction)pyg_option_context_set_main_group, METH_VARARGS | METH_KEYWORDS },
+ { "get_main_group", (PyCFunction)pyg_option_context_get_main_group, METH_NOARGS },
+ { "add_group", (PyCFunction)pyg_option_context_add_group, METH_VARARGS | METH_KEYWORDS },
+ { "_get_context", (PyCFunction)pyg_option_get_context, METH_NOARGS },
+ { NULL, NULL, 0 },
+};
+
+void
+pyglib_option_context_register_types(PyObject *d)
+{
+ PyGOptionContext_Type.tp_dealloc = (destructor)pyg_option_context_dealloc;
+ PyGOptionContext_Type.tp_compare = (cmpfunc)pyg_option_context_compare;
+ PyGOptionContext_Type.tp_flags = Py_TPFLAGS_DEFAULT;
+ PyGOptionContext_Type.tp_methods = pyg_option_context_methods;
+ PyGOptionContext_Type.tp_init = (initproc)pyg_option_context_init;
+ PYGLIB_REGISTER_TYPE(d, PyGOptionContext_Type, "OptionContext");
+}
diff --git a/glib/pygoptioncontext.h b/glib/pygoptioncontext.h
new file mode 100644
index 0000000..85d0a47
--- /dev/null
+++ b/glib/pygoptioncontext.h
@@ -0,0 +1,37 @@
+/* -*- Mode: C; c-basic-offset: 4 -*-
+ * pyglib - Python bindings for GLib toolkit.
+ * Copyright (C) 1998-2003 James Henstridge
+ * 2004-2008 Johan Dahlin
+ *
+ * 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 __PYG_OPTIONCONTEXT_H__
+#define __PYG_OPTIONCONTEXT_H__
+
+#include "pygoptiongroup.h"
+
+extern PyTypeObject PyGOptionContext_Type;
+
+typedef struct {
+ PyObject_HEAD
+ PyGOptionGroup *main_group;
+ GOptionContext *context;
+} PyGOptionContext;
+
+void pyglib_option_context_register_types(PyObject *d);
+
+#endif /* __PYG_OPTIONCONTEXT_H__ */
diff --git a/glib/pygoptiongroup.c b/glib/pygoptiongroup.c
new file mode 100644
index 0000000..70e4529
--- /dev/null
+++ b/glib/pygoptiongroup.c
@@ -0,0 +1,270 @@
+/* -*- Mode: C; c-basic-offset: 4 -*-
+ * pygobject - Python bindings for the GLib, GObject and GIO
+ * Copyright (C) 2006 Johannes Hoelzl
+ *
+ * pygoptiongroup.c: GOptionContext and GOptionGroup 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
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <pyglib.h>
+#include "pyglib-private.h"
+#include "pygoptiongroup.h"
+
+PYGLIB_DEFINE_TYPE("glib.OptionGroup", PyGOptionGroup_Type, PyGOptionGroup)
+
+static gboolean
+check_if_owned(PyGOptionGroup *self)
+{
+ if (self->other_owner)
+ {
+ PyErr_SetString(PyExc_ValueError, "The GOptionGroup was not created by "
+ "glib.OptionGroup(), so operation is not possible.");
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static void
+destroy_g_group(PyGOptionGroup *self)
+{
+ PyGILState_STATE state;
+ state = pyglib_gil_state_ensure();
+
+ self->group = NULL;
+ Py_CLEAR(self->callback);
+ g_slist_foreach(self->strings, (GFunc) g_free, NULL);
+ g_slist_free(self->strings);
+ self->strings = NULL;
+
+ if (self->is_in_context)
+ {
+ Py_DECREF(self);
+ }
+
+ pyglib_gil_state_release(state);
+}
+
+static int
+pyg_option_group_init(PyGOptionGroup *self, PyObject *args, PyObject *kwargs)
+{
+ static char *kwlist[] = { "name", "description", "help_description",
+ "callback", NULL };
+ char *name, *description, *help_description;
+ PyObject *callback;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "zzzO:GOptionGroup.__init__",
+ kwlist, &name, &description,
+ &help_description, &callback))
+ return -1;
+
+ self->group = g_option_group_new(name, description, help_description,
+ self, (GDestroyNotify) destroy_g_group);
+ self->other_owner = FALSE;
+ self->is_in_context = FALSE;
+
+ Py_INCREF(callback);
+ self->callback = callback;
+
+ return 0;
+}
+
+static void
+pyg_option_group_dealloc(PyGOptionGroup *self)
+{
+ if (!self->other_owner && !self->is_in_context)
+ {
+ GOptionGroup *tmp = self->group;
+ self->group = NULL;
+ if (tmp)
+ g_option_group_free(tmp);
+ }
+
+ PyObject_Del(self);
+}
+
+static gboolean
+arg_func(const gchar *option_name,
+ const gchar *value,
+ PyGOptionGroup *self,
+ GError **error)
+{
+ PyObject *ret;
+ PyGILState_STATE state;
+ gboolean no_error;
+
+ state = pyglib_gil_state_ensure();
+
+ if (value == NULL)
+ ret = PyObject_CallFunction(self->callback, "sOO",
+ option_name, Py_None, self);
+ else
+ ret = PyObject_CallFunction(self->callback, "ssO",
+ option_name, value, self);
+
+ if (ret != NULL)
+ {
+ Py_DECREF(ret);
+ no_error = TRUE;
+ } else
+ no_error = pyglib_gerror_exception_check(error) != -1;
+
+ pyglib_gil_state_release(state);
+ return no_error;
+}
+
+static PyObject *
+pyg_option_group_add_entries(PyGOptionGroup *self, PyObject *args,
+ PyObject *kwargs)
+{
+ static char *kwlist[] = { "entries", NULL };
+ gssize entry_count, pos;
+ PyObject *entry_tuple, *list;
+ GOptionEntry *entries;
+
+ if (check_if_owned(self))
+ return NULL;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:GOptionGroup.add_entries",
+ kwlist, &list))
+ return NULL;
+
+ if (!PyList_Check(list))
+ {
+ PyErr_SetString(PyExc_TypeError,
+ "GOptionGroup.add_entries expected a list of entries");
+ return NULL;
+ }
+
+ entry_count = PyList_Size(list);
+ if (entry_count == -1)
+ {
+ PyErr_SetString(PyExc_TypeError,
+ "GOptionGroup.add_entries expected a list of entries");
+ return NULL;
+ }
+
+ entries = g_new0(GOptionEntry, entry_count + 1);
+ for (pos = 0; pos < entry_count; pos++)
+ {
+ gchar *long_name, *description, *arg_description;
+ entry_tuple = PyList_GetItem(list, pos);
+ if (!PyTuple_Check(entry_tuple))
+ {
+ PyErr_SetString(PyExc_TypeError, "GOptionGroup.add_entries "
+ "expected a list of entries");
+ g_free(entries);
+ return NULL;
+ }
+ if (!PyArg_ParseTuple(entry_tuple, "scisz",
+ &long_name,
+ &(entries[pos].short_name),
+ &(entries[pos].flags),
+ &description,
+ &arg_description))
+ {
+ PyErr_SetString(PyExc_TypeError, "GOptionGroup.add_entries "
+ "expected a list of entries");
+ g_free(entries);
+ return NULL;
+ }
+ long_name = g_strdup(long_name);
+ self->strings = g_slist_prepend(self->strings, long_name);
+ entries[pos].long_name = long_name;
+
+ description = g_strdup(description);
+ self->strings = g_slist_prepend(self->strings, description);
+ entries[pos].description = description;
+
+ arg_description = g_strdup(arg_description);
+ self->strings = g_slist_prepend(self->strings, arg_description);
+ entries[pos].arg_description = arg_description;
+
+ entries[pos].arg = G_OPTION_ARG_CALLBACK;
+ entries[pos].arg_data = arg_func;
+ }
+
+ g_option_group_add_entries(self->group, entries);
+
+ g_free(entries);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+
+static PyObject *
+pyg_option_group_set_translation_domain(PyGOptionGroup *self,
+ PyObject *args,
+ PyObject *kwargs)
+{
+ static char *kwlist[] = { "domain", NULL };
+ char *domain;
+
+ if (check_if_owned(self))
+ return NULL;
+
+ if (self->group == NULL)
+ {
+ PyErr_SetString(PyExc_RuntimeError,
+ "The corresponding GOptionGroup was already freed, "
+ "probably through the release of GOptionContext");
+ return NULL;
+ }
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs,
+ "z:GOptionGroup.set_translate_domain",
+ kwlist, &domain))
+ return NULL;
+
+ g_option_group_set_translation_domain(self->group, domain);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static int
+pyg_option_group_compare(PyGOptionGroup *self, PyGOptionGroup *group)
+{
+ if (self->group == group->group)
+ return 0;
+
+ if (self->group > group->group)
+ return 1;
+
+ return -1;
+}
+
+static PyMethodDef pyg_option_group_methods[] = {
+ { "add_entries", (PyCFunction)pyg_option_group_add_entries, METH_VARARGS | METH_KEYWORDS },
+ { "set_translation_domain", (PyCFunction)pyg_option_group_set_translation_domain, METH_VARARGS | METH_KEYWORDS },
+ { NULL, NULL, 0 },
+};
+
+void
+pyglib_option_group_register_types(PyObject *d)
+{
+ PyGOptionGroup_Type.tp_dealloc = (destructor)pyg_option_group_dealloc;
+ PyGOptionGroup_Type.tp_compare = (cmpfunc)pyg_option_group_compare;
+ PyGOptionGroup_Type.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE;
+ PyGOptionGroup_Type.tp_methods = pyg_option_group_methods;
+ PyGOptionGroup_Type.tp_init = (initproc)pyg_option_group_init;
+ PYGLIB_REGISTER_TYPE(d, PyGOptionGroup_Type, "OptionGroup");
+}
diff --git a/glib/pygoptiongroup.h b/glib/pygoptiongroup.h
new file mode 100644
index 0000000..cba6a79
--- /dev/null
+++ b/glib/pygoptiongroup.h
@@ -0,0 +1,40 @@
+/* -*- Mode: C; c-basic-offset: 4 -*-
+ * pyglib - Python bindings for GLib toolkit.
+ * Copyright (C) 1998-2003 James Henstridge
+ * 2004-2008 Johan Dahlin
+ *
+ * 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 __PYG_OPTIONGROUP_H__
+#define __PYG_OPTIONGROUP_H__
+
+extern PyTypeObject PyGOptionGroup_Type;
+
+typedef struct {
+ PyObject_HEAD
+ GOptionGroup *group;
+ gboolean other_owner, is_in_context;
+ PyObject *callback;
+ GSList *strings; /* all strings added with the entries, are freed on
+ GOptionGroup.destroy() */
+} PyGOptionGroup;
+
+void pyglib_option_group_register_types(PyObject *d);
+
+#endif /* __PYG_OPTIONGROUP_H__ */
+
+
diff --git a/glib/pygsource.c b/glib/pygsource.c
new file mode 100644
index 0000000..298b928
--- /dev/null
+++ b/glib/pygsource.c
@@ -0,0 +1,723 @@
+/* -*- Mode: C; c-basic-offset: 4 -*-
+ * pygtk- Python bindings for the GTK toolkit.
+ * Copyright (C) 1998-2003 James Henstridge
+ * Copyright (C) 2005 Oracle
+ *
+ * Author: Manish Singh <manish.singh@oracle.com>
+ *
+ * pygsource.c: GSource 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
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <Python.h>
+#include <pythread.h>
+#include <structmember.h> /* for PyMemberDef */
+#include "pyglib.h"
+#include "pyglib-private.h"
+#include "pygmaincontext.h"
+#include "pygsource.h"
+
+#define CHECK_DESTROYED(self, ret) G_STMT_START { \
+ if ((self)->source == NULL) { \
+ PyErr_SetString(PyExc_RuntimeError, "source is destroyed"); \
+ return (ret); \
+ } \
+} G_STMT_END
+
+
+typedef struct {
+ PyObject_HEAD
+ GSource *source;
+ PyObject *inst_dict;
+ PyObject *weakreflist;
+ gboolean python_source;
+} PyGSource;
+
+typedef struct
+{
+ GSource source;
+ PyObject *obj;
+} PyGRealSource;
+
+/* glib.Source */
+
+PYGLIB_DEFINE_TYPE("glib.Source", PyGSource_Type, PyGSource)
+
+static PyObject *
+source_repr(PyGSource *self, const char *type)
+{
+ gchar buf[256], *desc;
+
+ if (self->source) {
+ if (g_source_get_context(self->source))
+ desc = "attached";
+ else
+ desc = "unattached";
+ } else {
+ desc = "destroyed";
+ }
+
+ if (type)
+ g_snprintf(buf, sizeof(buf), "<%s glib %s source at 0x%lx>",
+ desc, type, (long) self);
+ else
+ g_snprintf(buf, sizeof(buf), "<%s glib source at 0x%lx>",
+ desc, (long) self);
+
+ return _PyUnicode_FromString(buf);
+}
+
+static PyObject *
+pyg_source_attach(PyGSource *self, PyObject *args, PyObject *kwargs)
+{
+ static char *kwlist[] = { "context", NULL };
+ PyGMainContext *py_context = NULL;
+ GMainContext *context = NULL;
+ guint id;
+
+ if (!PyArg_ParseTupleAndKeywords (args, kwargs,
+ "|O!:attach", kwlist,
+ &PyGMainContext_Type, &py_context))
+ return NULL;
+
+ if (py_context)
+ context = py_context->context;
+
+ CHECK_DESTROYED(self, NULL);
+
+ if (self->python_source) {
+ PyGRealSource *pysource = (PyGRealSource *)self->source;
+ Py_INCREF(pysource->obj);
+ }
+
+ id = g_source_attach(self->source, context);
+ return _PyLong_FromLong(id);
+}
+
+static PyObject *
+pyg_source_destroy(PyGSource *self)
+{
+ CHECK_DESTROYED(self, NULL);
+
+ if (self->python_source && self->source->context) {
+ PyGRealSource *pysource = (PyGRealSource *)self->source;
+ Py_DECREF(pysource->obj);
+ }
+
+ g_source_destroy(self->source);
+ self->source = NULL;
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+pyg_source_set_callback(PyGSource *self, PyObject *args)
+{
+ PyObject *first, *callback, *cbargs = NULL, *data;
+ gint len;
+
+ CHECK_DESTROYED(self, NULL);
+
+ len = PyTuple_Size (args);
+ if (len < 1) {
+ PyErr_SetString(PyExc_TypeError,
+ "set_callback requires at least 1 argument");
+ return NULL;
+ }
+
+ first = PySequence_GetSlice(args, 0, 1);
+ if (!PyArg_ParseTuple(first, "O:set_callback", &callback)) {
+ Py_DECREF (first);
+ return NULL;
+ }
+ Py_DECREF(first);
+
+ if (!PyCallable_Check(callback)) {
+ PyErr_SetString(PyExc_TypeError, "first argument not callable");
+ return NULL;
+ }
+
+ cbargs = PySequence_GetSlice(args, 1, len);
+ if (cbargs == NULL)
+ return NULL;
+
+ data = Py_BuildValue("(ON)", callback, cbargs);
+ if (data == NULL)
+ return NULL;
+
+ g_source_set_callback(self->source,
+ _pyglib_handler_marshal, data,
+ _pyglib_destroy_notify);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+pyg_source_get_context(PyGSource *self)
+{
+ GMainContext *context;
+
+ CHECK_DESTROYED(self, NULL);
+
+ context = g_source_get_context(self->source);
+
+ if (context) {
+ return pyglib_main_context_new(context);
+ } else {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+}
+
+static PyObject *
+pyg_source_add_poll(PyGSource *self, PyObject *args, PyObject *kwargs)
+{
+ static char *kwlist[] = { "fd", NULL };
+ PyGPollFD *fd;
+
+ if (!self->python_source) {
+ PyErr_SetString(PyExc_TypeError,
+ "add_poll can only be used with sources "
+ "implemented in python");
+ return NULL;
+ }
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs,
+ "O!:add_poll", kwlist,
+ &PyGPollFD_Type, &fd))
+ return NULL;
+
+ CHECK_DESTROYED(self, NULL);
+
+ g_source_add_poll(self->source, &fd->pollfd);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+pyg_source_remove_poll(PyGSource *self, PyObject *args, PyObject *kwargs)
+{
+ static char *kwlist[] = { "fd", NULL };
+ PyGPollFD *fd;
+
+ if (!self->python_source) {
+ PyErr_SetString(PyExc_TypeError,
+ "remove_poll can only be used with sources "
+ "implemented in python");
+ return NULL;
+ }
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs,
+ "O!:remove_poll", kwlist,
+ &PyGPollFD_Type, &fd))
+ return NULL;
+
+ CHECK_DESTROYED(self, NULL);
+
+ g_source_remove_poll(self->source, &fd->pollfd);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+pyg_source_get_current_time(PyGSource *self)
+{
+ GTimeVal timeval;
+ double ret;
+
+ CHECK_DESTROYED(self, NULL);
+
+ g_source_get_current_time(self->source, &timeval);
+ ret = (double)timeval.tv_sec + (double)timeval.tv_usec * 0.000001;
+ return PyFloat_FromDouble(ret);
+}
+
+static PyMethodDef pyg_source_methods[] = {
+ { "attach", (PyCFunction)pyg_source_attach, METH_KEYWORDS },
+ { "destroy", (PyCFunction)pyg_source_destroy, METH_NOARGS },
+ { "set_callback", (PyCFunction)pyg_source_set_callback, METH_VARARGS },
+ { "get_context", (PyCFunction)pyg_source_get_context, METH_NOARGS },
+ { "add_poll", (PyCFunction)pyg_source_add_poll, METH_KEYWORDS },
+ { "remove_poll", (PyCFunction)pyg_source_remove_poll, METH_KEYWORDS },
+ { "get_current_time", (PyCFunction)pyg_source_get_current_time, METH_NOARGS },
+ { NULL, NULL, 0 }
+};
+
+static PyObject *
+pyg_source_get_dict(PyGSource *self, void *closure)
+{
+ if (self->inst_dict == NULL) {
+ self->inst_dict = PyDict_New();
+ if (self->inst_dict == NULL)
+ return NULL;
+ }
+
+ Py_INCREF(self->inst_dict);
+ return self->inst_dict;
+}
+
+static PyObject *
+pyg_source_get_priority(PyGSource *self, void *closure)
+{
+ CHECK_DESTROYED(self, NULL);
+
+ return _PyLong_FromLong(g_source_get_priority(self->source));
+}
+
+static int
+pyg_source_set_priority(PyGSource *self, PyObject *value, void *closure)
+{
+ CHECK_DESTROYED(self, -1);
+
+ if (value == NULL) {
+ PyErr_SetString(PyExc_TypeError, "cannot delete priority");
+ return -1;
+ }
+
+ if (!_PyLong_Check(value)) {
+ PyErr_SetString(PyExc_TypeError, "type mismatch");
+ return -1;
+ }
+
+ g_source_set_priority(self->source, _PyLong_AsLong(value));
+
+ return 0;
+}
+
+static PyObject *
+pyg_source_get_can_recurse(PyGSource *self, void *closure)
+{
+ CHECK_DESTROYED(self, NULL);
+
+ return PyBool_FromLong(g_source_get_can_recurse(self->source));
+}
+
+static int
+pyg_source_set_can_recurse(PyGSource *self, PyObject *value, void *closure)
+{
+ CHECK_DESTROYED(self, -1);
+
+ if (value == NULL) {
+ PyErr_SetString(PyExc_TypeError, "cannot delete can_recurse");
+ return -1;
+ }
+
+ g_source_set_can_recurse(self->source, PyObject_IsTrue(value));
+
+ return 0;
+}
+
+static PyObject *
+pyg_source_get_id(PyGSource *self, void *closure)
+{
+ CHECK_DESTROYED(self, NULL);
+
+ if (g_source_get_context(self->source) == NULL) {
+ PyErr_SetString(PyExc_RuntimeError, "source is not attached");
+ return NULL;
+ }
+
+ return _PyLong_FromLong(g_source_get_id(self->source));
+}
+
+static PyGetSetDef pyg_source_getsets[] = {
+ { "__dict__", (getter)pyg_source_get_dict, (setter)0 },
+ {"priority", (getter)pyg_source_get_priority, (setter)pyg_source_set_priority },
+ {"can_recurse", (getter)pyg_source_get_can_recurse, (setter)pyg_source_set_can_recurse },
+ {"id", (getter)pyg_source_get_id, (setter)0 },
+ {NULL, 0, 0}
+};
+
+static PyObject *
+pyg_source_repr(PyGSource *self)
+{
+ return source_repr(self, NULL);
+}
+
+static int
+pyg_source_traverse(PyGSource *self, visitproc visit, void *arg)
+{
+ int ret = 0;
+
+ if (self->inst_dict) ret = visit(self->inst_dict, arg);
+ if (ret != 0) return ret;
+
+ return 0;
+}
+
+static int
+pyg_source_clear(PyGSource *self)
+{
+ PyObject *tmp;
+
+ tmp = self->inst_dict;
+ self->inst_dict = NULL;
+ Py_XDECREF(tmp);
+
+ if (self->source) {
+ g_source_unref(self->source);
+ self->source = NULL;
+ }
+
+ return 0;
+}
+
+static void
+pyg_source_dealloc(PyGSource *self)
+{
+ PyObject_ClearWeakRefs((PyObject *)self);
+
+ PyObject_GC_UnTrack((PyObject *)self);
+
+ pyg_source_clear(self);
+
+ PyObject_GC_Del(self);
+}
+
+static gboolean
+pyg_source_prepare(GSource *source, gint *timeout)
+{
+ PyGRealSource *pysource = (PyGRealSource *)source;
+ PyObject *t;
+ gboolean ret = FALSE;
+ gboolean got_err = TRUE;
+ PyGILState_STATE state;
+
+ state = pyglib_gil_state_ensure();
+
+ t = PyObject_CallMethod(pysource->obj, "prepare", NULL);
+
+ if (t == NULL) {
+ goto bail;
+ } else if (!PyObject_IsTrue(t)) {
+ got_err = FALSE;
+ goto bail;
+ } else if (!PyTuple_Check(t)) {
+ PyErr_SetString(PyExc_TypeError,
+ "source prepare function must return a tuple or False");
+ goto bail;
+ } else if (PyTuple_Size(t) != 2) {
+ PyErr_SetString(PyExc_TypeError,
+ "source prepare function return tuple must be exactly "
+ "2 elements long");
+ goto bail;
+ }
+
+ ret = PyObject_IsTrue(PyTuple_GET_ITEM(t, 0));
+ *timeout = _PyLong_AsLong(PyTuple_GET_ITEM(t, 1));
+
+ if (*timeout == -1 && PyErr_Occurred()) {
+ ret = FALSE;
+ goto bail;
+ }
+
+ got_err = FALSE;
+
+bail:
+ if (got_err)
+ PyErr_Print();
+
+ Py_XDECREF(t);
+
+ pyglib_gil_state_release(state);
+
+ return ret;
+}
+
+static gboolean
+pyg_source_check(GSource *source)
+{
+ PyGRealSource *pysource = (PyGRealSource *)source;
+ PyObject *t;
+ gboolean ret;
+ PyGILState_STATE state;
+
+ state = pyglib_gil_state_ensure();
+
+ t = PyObject_CallMethod(pysource->obj, "check", NULL);
+
+ if (t == NULL) {
+ PyErr_Print();
+ ret = FALSE;
+ } else {
+ ret = PyObject_IsTrue(t);
+ Py_DECREF(t);
+ }
+
+ pyglib_gil_state_release(state);
+
+ return ret;
+}
+
+static gboolean
+pyg_source_dispatch(GSource *source, GSourceFunc callback, gpointer user_data)
+{
+ PyGRealSource *pysource = (PyGRealSource *)source;
+ PyObject *func, *args, *tuple, *t;
+ gboolean ret;
+ PyGILState_STATE state;
+
+ state = pyglib_gil_state_ensure();
+
+ if (callback) {
+ tuple = user_data;
+
+ func = PyTuple_GetItem(tuple, 0);
+ args = PyTuple_GetItem(tuple, 1);
+ } else {
+ func = Py_None;
+ args = Py_None;
+ }
+
+ t = PyObject_CallMethod(pysource->obj, "dispatch", "OO", func, args);
+
+ if (t == NULL) {
+ PyErr_Print();
+ ret = FALSE;
+ } else {
+ ret = PyObject_IsTrue(t);
+ Py_DECREF(t);
+ }
+
+ pyglib_gil_state_release(state);
+
+ return ret;
+}
+
+static void
+pyg_source_finalize(GSource *source)
+{
+ PyGRealSource *pysource = (PyGRealSource *)source;
+ PyObject *func, *t;
+ PyGILState_STATE state;
+
+ state = pyglib_gil_state_ensure();
+
+ func = PyObject_GetAttrString(pysource->obj, "finalize");
+ if (func) {
+ t = PyObject_CallObject(func, NULL);
+ Py_DECREF(func);
+
+ if (t == NULL) {
+ PyErr_Print();
+ } else {
+ Py_DECREF(t);
+ }
+ }
+
+ pyglib_gil_state_release(state);
+}
+
+static GSourceFuncs pyg_source_funcs =
+{
+ pyg_source_prepare,
+ pyg_source_check,
+ pyg_source_dispatch,
+ pyg_source_finalize
+};
+
+static int
+pyg_source_init(PyGSource *self, PyObject *args, PyObject *kwargs)
+{
+ PyGRealSource *pysource;
+
+ self->source = g_source_new(&pyg_source_funcs, sizeof(PyGRealSource));
+
+ pysource = (PyGRealSource *)self->source;
+ pysource->obj = (PyObject*)self;
+
+ self->inst_dict = NULL;
+ self->weakreflist = NULL;
+
+ self->python_source = TRUE;
+
+ return 0;
+}
+
+static void
+pyg_source_free(PyObject *op)
+{
+ PyObject_GC_Del(op);
+}
+
+/* glib.Idle */
+
+PYGLIB_DEFINE_TYPE("glib.Idle", PyGIdle_Type, PyGSource)
+
+static PyObject *
+pyg_idle_repr(PyGSource *self)
+{
+ return source_repr(self, "idle");
+}
+
+static int
+pyg_idle_init(PyGSource *self, PyObject *args, PyObject *kwargs)
+{
+ static char *kwlist[] = { "priority", NULL };
+ gint priority = G_PRIORITY_DEFAULT_IDLE;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs,
+ "|i:glib.Idle.__init__", kwlist,
+ &priority))
+ return -1;
+
+ self->source = g_idle_source_new ();
+
+ if (priority != G_PRIORITY_DEFAULT_IDLE)
+ g_source_set_priority(self->source, priority);
+
+ self->inst_dict = NULL;
+ self->weakreflist = NULL;
+
+ self->python_source = FALSE;
+
+ return 0;
+}
+
+/* glib.Timeout */
+
+PYGLIB_DEFINE_TYPE("glib.Timeout", PyGTimeout_Type, PyGSource)
+
+static PyObject *
+pyg_timeout_repr(PyGSource *self)
+{
+ return source_repr(self, "timeout");
+}
+
+static int
+pyg_timeout_init(PyGSource *self, PyObject *args, PyObject *kwargs)
+{
+ static char *kwlist[] = { "interval", "priority", NULL };
+ gint priority = G_PRIORITY_DEFAULT;
+ guint interval;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs,
+ "I|i:glib.Timeout.__init__", kwlist,
+ &interval, &priority))
+ return -1;
+
+ self->source = g_timeout_source_new(interval);
+
+ if (priority != G_PRIORITY_DEFAULT)
+ g_source_set_priority(self->source, priority);
+
+ self->inst_dict = NULL;
+ self->weakreflist = NULL;
+
+ self->python_source = FALSE;
+
+ return 0;
+}
+
+/* glib.PollFD */
+
+PYGLIB_DEFINE_TYPE("glib.PollFD", PyGPollFD_Type, PyGPollFD)
+
+static PyMemberDef pyg_poll_fd_members[] = {
+ { "fd", T_INT, offsetof(PyGPollFD, pollfd.fd), READONLY },
+ { "events", T_USHORT, offsetof(PyGPollFD, pollfd.events), READONLY },
+ { "revents", T_USHORT, offsetof(PyGPollFD, pollfd.revents), READONLY },
+ { NULL, 0, 0, 0 }
+};
+
+static void
+pyg_poll_fd_dealloc(PyGPollFD *self)
+{
+ Py_XDECREF(self->fd_obj);
+ PyObject_DEL(self);
+}
+
+static PyObject *
+pyg_poll_fd_repr(PyGPollFD *self)
+{
+ return _PyUnicode_FromFormat("<GPollFD %d (%d) at 0x%lx>",
+ self->pollfd.fd, self->pollfd.events,
+ (long)self);
+}
+
+static int
+pyg_poll_fd_init(PyGPollFD *self, PyObject *args, PyObject *kwargs)
+{
+ static char *kwlist[] = { "fd", "events", NULL };
+ PyObject *o;
+ gint fd;
+ gushort events;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs,
+ "OH:glib.PollFD.__init__", kwlist,
+ &o, &events))
+ return -1;
+
+ fd = PyObject_AsFileDescriptor(o);
+ if (fd == -1)
+ return -1;
+
+ self->pollfd.fd = fd;
+ self->pollfd.events = events;
+ self->pollfd.revents = 0;
+
+ Py_INCREF(o);
+ self->fd_obj = o;
+
+ return 0;
+}
+
+void
+pyglib_source_register_types(PyObject *d)
+{
+ PyGSource_Type.tp_flags = (Py_TPFLAGS_DEFAULT |
+ Py_TPFLAGS_BASETYPE |
+ Py_TPFLAGS_HAVE_GC);
+ PyGSource_Type.tp_init = (initproc)pyg_source_init;
+ PyGSource_Type.tp_free = (freefunc)pyg_source_free;
+ PyGSource_Type.tp_dealloc = (destructor)pyg_source_dealloc;
+ PyGSource_Type.tp_methods = pyg_source_methods;
+ PyGSource_Type.tp_repr = (reprfunc)pyg_source_repr;
+ PyGSource_Type.tp_traverse = (traverseproc)pyg_source_traverse;
+ PyGSource_Type.tp_clear = (inquiry)pyg_source_clear;
+ PyGSource_Type.tp_getset = pyg_source_getsets;
+ PyGSource_Type.tp_weaklistoffset = offsetof(PyGSource, weakreflist);
+ PyGSource_Type.tp_dictoffset = offsetof(PyGSource, inst_dict);
+ PYGLIB_REGISTER_TYPE(d, PyGSource_Type, "Source");
+
+ PyGIdle_Type.tp_repr = (reprfunc)pyg_idle_repr;
+ PyGIdle_Type.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE;
+ PyGIdle_Type.tp_base = (PyTypeObject *)&PyGSource_Type;
+ PyGIdle_Type.tp_init = (initproc)pyg_idle_init;
+ PYGLIB_REGISTER_TYPE(d, PyGIdle_Type, "Idle");
+
+ PyGTimeout_Type.tp_repr = (reprfunc)pyg_timeout_repr;
+ PyGTimeout_Type.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE;
+ PyGTimeout_Type.tp_base = (PyTypeObject *)&PyGSource_Type;
+ PyGTimeout_Type.tp_init = (initproc)pyg_timeout_init;
+ PYGLIB_REGISTER_TYPE(d, PyGTimeout_Type, "Timeout");
+
+ PyGPollFD_Type.tp_dealloc = (destructor)pyg_poll_fd_dealloc;
+ PyGPollFD_Type.tp_repr = (reprfunc)pyg_poll_fd_repr;
+ PyGPollFD_Type.tp_flags = Py_TPFLAGS_DEFAULT;
+ PyGPollFD_Type.tp_members = pyg_poll_fd_members;
+ PyGPollFD_Type.tp_init = (initproc)pyg_poll_fd_init;
+ PYGLIB_REGISTER_TYPE(d, PyGPollFD_Type, "PollFD");
+}
diff --git a/glib/pygsource.h b/glib/pygsource.h
new file mode 100644
index 0000000..bf2c673
--- /dev/null
+++ b/glib/pygsource.h
@@ -0,0 +1,39 @@
+/* -*- Mode: C; c-basic-offset: 4 -*-
+ * pyglib - Python bindings for GLib toolkit.
+ * Copyright (C) 1998-2003 James Henstridge
+ * 2004-2008 Johan Dahlin
+ *
+ * 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 __PYG_SOURCE_H__
+#define __PYG_SOURCE_H__
+
+extern PyTypeObject PyGSource_Type;
+extern PyTypeObject PyGIdle_Type;
+extern PyTypeObject PyGTimeout_Type;
+extern PyTypeObject PyGPollFD_Type;
+
+typedef struct
+{
+ PyObject_HEAD
+ GPollFD pollfd;
+ PyObject *fd_obj;
+} PyGPollFD;
+
+void pyglib_source_register_types(PyObject *d);
+
+#endif /* __PYG_SOURCE_H__ */
diff --git a/glib/pygspawn.c b/glib/pygspawn.c
new file mode 100644
index 0000000..cded501
--- /dev/null
+++ b/glib/pygspawn.c
@@ -0,0 +1,263 @@
+/* -*- Mode: C; c-basic-offset: 4 -*-
+ * pyglib - Python bindings for GLib toolkit.
+ * Copyright (C) 1998-2003 James Henstridge
+ * 2004-2008 Johan Dahlin
+ *
+ * pygspawn.c: wrapper for the glib 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 Street, Fifth Floor, Boston, MA 02110-1301
+ * USA
+ */
+
+#include <Python.h>
+#include <glib.h>
+
+#include "pyglib.h"
+#include "pyglib-private.h"
+
+struct _PyGChildSetupData {
+ PyObject *func;
+ PyObject *data;
+};
+
+PYGLIB_DEFINE_TYPE("glib.Pid", PyGPid_Type, _PyLongObject)
+
+static PyObject *
+pyg_pid_close(PyObject *self, PyObject *args, PyObject *kwargs)
+{
+ g_spawn_close_pid(_PyLong_AsLong(self));
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyMethodDef pyg_pid_methods[] = {
+ { "close", (PyCFunction)pyg_pid_close, METH_NOARGS },
+ { NULL, NULL, 0 }
+};
+
+static void
+pyg_pid_free(PyObject *gpid)
+{
+ g_spawn_close_pid((GPid) _PyLong_AsLong(gpid));
+ _PyLong_Type.tp_free((void *) gpid);
+}
+
+static int
+pyg_pid_tp_init(PyObject *self, PyObject *args, PyObject *kwargs)
+{
+ PyErr_SetString(PyExc_TypeError, "glib.Pid cannot be manually instantiated");
+ return -1;
+}
+
+PyObject *
+pyg_pid_new(GPid pid)
+{
+ _PyLongObject *pygpid;
+ pygpid = PyObject_NEW(_PyLongObject, &PyGPid_Type);
+
+#if PY_VERSION_HEX >= 0x03000000
+# warning "FIXME: figure out how to subclass long"
+#else
+ pygpid->ob_ival = pid;
+#endif
+ return (PyObject *) pygpid;
+}
+
+static void
+_pyg_spawn_async_callback(gpointer user_data)
+{
+ struct _PyGChildSetupData *data;
+ PyObject *retval;
+ PyGILState_STATE gil;
+
+ data = (struct _PyGChildSetupData *) user_data;
+ gil = pyglib_gil_state_ensure();
+ if (data->data)
+ retval = PyObject_CallFunction(data->func, "O", data->data);
+ else
+ retval = PyObject_CallFunction(data->func, NULL);
+ if (retval)
+ Py_DECREF(retval);
+ else
+ PyErr_Print();
+ Py_DECREF(data->func);
+ Py_XDECREF(data->data);
+ g_slice_free(struct _PyGChildSetupData, data);
+ pyglib_gil_state_release(gil);
+}
+
+PyObject *
+pyglib_spawn_async(PyObject *object, PyObject *args, PyObject *kwargs)
+{
+ static char *kwlist[] = { "argv", "envp", "working_directory", "flags",
+ "child_setup", "user_data", "standard_input",
+ "standard_output", "standard_error", NULL };
+ PyObject *pyargv, *pyenvp = NULL;
+ char **argv, **envp = NULL;
+ PyObject *func = Py_None, *user_data = NULL;
+ char *working_directory = NULL;
+ int flags = 0, _stdin = -1, _stdout = -1, _stderr = -1;
+ PyObject *pystdin = NULL, *pystdout = NULL, *pystderr = NULL;
+ gint *standard_input, *standard_output, *standard_error;
+ struct _PyGChildSetupData *callback_data = NULL;
+ GError *error = NULL;
+ GPid child_pid = -1;
+ Py_ssize_t len, i;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|OsiOOOOO:glib.spawn_async",
+ kwlist,
+ &pyargv, &pyenvp, &working_directory, &flags,
+ &func, &user_data,
+ &pystdin, &pystdout, &pystderr))
+ return NULL;
+
+ if (pystdin && PyObject_IsTrue(pystdin))
+ standard_input = &_stdin;
+ else
+ standard_input = NULL;
+
+ if (pystdout && PyObject_IsTrue(pystdout))
+ standard_output = &_stdout;
+ else
+ standard_output = NULL;
+
+ if (pystderr && PyObject_IsTrue(pystderr))
+ standard_error = &_stderr;
+ else
+ standard_error = NULL;
+
+ /* parse argv */
+ if (!PySequence_Check(pyargv)) {
+ PyErr_SetString(PyExc_TypeError,
+ "glib.spawn_async: "
+ "first argument must be a sequence of strings");
+ return NULL;
+ }
+ len = PySequence_Length(pyargv);
+ argv = g_new0(char *, len + 1);
+ for (i = 0; i < len; ++i) {
+ PyObject *tmp = PySequence_ITEM(pyargv, i);
+ if (!_PyUnicode_Check(tmp)) {
+ PyErr_SetString(PyExc_TypeError,
+ "glib.spawn_async: "
+ "first argument must be a sequence of strings");
+ g_free(argv);
+ Py_XDECREF(tmp);
+ return NULL;
+ }
+ argv[i] = _PyUnicode_AsString(tmp);
+ Py_DECREF(tmp);
+ }
+
+ /* parse envp */
+ if (pyenvp) {
+ if (!PySequence_Check(pyenvp)) {
+ PyErr_SetString(PyExc_TypeError,
+ "glib.spawn_async: "
+ "second argument must be a sequence of strings");
+ g_free(argv);
+ return NULL;
+ }
+ len = PySequence_Length(pyenvp);
+ envp = g_new0(char *, len + 1);
+ for (i = 0; i < len; ++i) {
+ PyObject *tmp = PySequence_ITEM(pyenvp, i);
+ if (!_PyUnicode_Check(tmp)) {
+ PyErr_SetString(PyExc_TypeError,
+ "glib.spawn_async: "
+ "second argument must be a sequence of strings");
+ g_free(envp);
+ Py_XDECREF(tmp);
+ g_free(argv);
+ return NULL;
+ }
+ envp[i] = _PyUnicode_AsString(tmp);
+ Py_DECREF(tmp);
+ }
+ }
+
+ if (func != Py_None) {
+ if (!PyCallable_Check(func)) {
+ PyErr_SetString(PyExc_TypeError, "child_setup parameter must be callable or None");
+ g_free(argv);
+ if (envp)
+ g_free(envp);
+ return NULL;
+ }
+ callback_data = g_slice_new(struct _PyGChildSetupData);
+ callback_data->func = func;
+ callback_data->data = user_data;
+ Py_INCREF(callback_data->func);
+ if (callback_data->data)
+ Py_INCREF(callback_data->data);
+ }
+
+ if (!g_spawn_async_with_pipes(working_directory, argv, envp, flags,
+ (func != Py_None ? _pyg_spawn_async_callback : NULL),
+ callback_data, &child_pid,
+ standard_input,
+ standard_output,
+ standard_error,
+ &error))
+
+
+ {
+ g_free(argv);
+ if (envp) g_free(envp);
+ if (callback_data) {
+ Py_DECREF(callback_data->func);
+ Py_XDECREF(callback_data->data);
+ g_slice_free(struct _PyGChildSetupData, callback_data);
+ }
+ pyglib_error_check(&error);
+ return NULL;
+ }
+ g_free(argv);
+ if (envp) g_free(envp);
+
+ if (standard_input)
+ pystdin = _PyLong_FromLong(*standard_input);
+ else {
+ Py_INCREF(Py_None);
+ pystdin = Py_None;
+ }
+
+ if (standard_output)
+ pystdout = _PyLong_FromLong(*standard_output);
+ else {
+ Py_INCREF(Py_None);
+ pystdout = Py_None;
+ }
+
+ if (standard_error)
+ pystderr = _PyLong_FromLong(*standard_error);
+ else {
+ Py_INCREF(Py_None);
+ pystderr = Py_None;
+ }
+
+ return Py_BuildValue("NNNN", pyg_pid_new(child_pid), pystdin, pystdout, pystderr);
+}
+
+void
+pyglib_spawn_register_types(PyObject *d)
+{
+ PyGPid_Type.tp_base = &_PyLong_Type;
+ PyGPid_Type.tp_flags = Py_TPFLAGS_DEFAULT;
+ PyGPid_Type.tp_methods = pyg_pid_methods;
+ PyGPid_Type.tp_init = pyg_pid_tp_init;
+ PyGPid_Type.tp_free = (freefunc)pyg_pid_free;
+ PYGLIB_REGISTER_TYPE(d, PyGPid_Type, "Pid");
+}
diff --git a/glib/pygspawn.h b/glib/pygspawn.h
new file mode 100644
index 0000000..2e8dd3c
--- /dev/null
+++ b/glib/pygspawn.h
@@ -0,0 +1,32 @@
+/* -*- Mode: C; c-basic-offset: 4 -*-
+ * pyglib - Python bindings for GLib toolkit.
+ * Copyright (C) 1998-2003 James Henstridge
+ * 2004-2008 Johan Dahlin
+ *
+ * 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 __PYG_PID_H__
+#define __PYG_PID_H__
+
+PyObject * pyg_pid_new(GPid pid);
+void pyglib_spawn_register_types(PyObject *d);
+
+PyObject * pyglib_spawn_async(PyObject *self, PyObject *args, PyObject *kwargs);
+
+
+#endif /* __PYG_PID_H__ */
+