--- /dev/null
+from ctypes import *
+import sys
+import ctypes
+
+import gobject
+
+# -------------------------------------------------------------------------
+class _PyGObject_Functions(ctypes.Structure):
+ """GObject <-> Python mapping from http://faq.pygtk.org/index.py?req=show&file=faq23.041.htp"""
+ _fields_ = [
+ ('register_class',
+ ctypes.PYFUNCTYPE(ctypes.c_void_p, ctypes.c_char_p,
+ ctypes.c_int, ctypes.py_object,
+ ctypes.py_object)),
+ ('register_wrapper',
+ ctypes.PYFUNCTYPE(ctypes.c_void_p, ctypes.py_object)),
+ ('register_sinkfunc',
+ ctypes.PYFUNCTYPE(ctypes.py_object, ctypes.c_void_p)),
+ ('lookupclass',
+ ctypes.PYFUNCTYPE(ctypes.py_object, ctypes.c_int)),
+ ('newgobj',
+ ctypes.PYFUNCTYPE(ctypes.py_object, ctypes.c_void_p)),
+ ]
+
+
+# -------------------------------------------------------------------------
+class PyGObjectCAPI(object):
+ """GObject <-> Python mapping from http://faq.pygtk.org/index.py?req=show&file=faq23.041.htp"""
+
+ def __init__(self):
+ addr = ctypes.pythonapi.PyCObject_AsVoidPtr(
+ ctypes.py_object(gobject._PyGObject_API))
+ self._api = _PyGObject_Functions.from_address(addr)
+
+ def pygobject_new(self, addr):
+ return self._api.newgobj(addr)
+
+
+# -------------------------------------------------------------------------
+class GList(Structure):
+ """GList representation and convenience functions, based on Java's Iterable.
+
+ Copyright (c) Andrew Flegg <andrew@bleb.org> 2009.
+ Released under the Artistic Licence."""
+
+
+ # -----------------------------------------------------------------------
+ @classmethod
+ def new(clazz, ptr = None):
+ """Return a reference to an empty, or valid, GList at the
+ given pointer address."""
+
+ if ptr:
+ return cast(c_void_p(ptr), POINTER(GList)).contents
+ else:
+ return GList()
+
+
+ # -----------------------------------------------------------------------
+ _fields_ = [('_data', c_void_p),
+ ('_next', c_void_p),
+ ('_prev', c_void_p)]
+
+ _ptr = None # Initialises to before the list for `while(has_next)...'
+
+
+ # -----------------------------------------------------------------------
+ def reset(self):
+ """Rewind the iterable to the start of the list."""
+
+ self._ptr = None
+
+ # -----------------------------------------------------------------------
+ def has_next(self):
+ """Return True if the list has an item on which next can be called."""
+
+ return (not self._ptr and self._data) or (self._ptr and self._ptr._next)
+
+
+ # -----------------------------------------------------------------------
+ def next(self, as_a = None):
+ """Move the pointer on to the next item in the list and return its value, or
+ raise an exception if already on the last."""
+
+ if self._ptr and not self._ptr._next:
+ raise Exception("IndexOutOfBounds")
+
+ self._ptr = self._ptr and cast(self._ptr._next, POINTER(GList)).contents or self
+ if not self._ptr._data:
+ return None
+ elif as_a:
+ return cast(self._ptr._data, POINTER(as_a)).contents
+ else:
+ return self._ptr._data
+
+
+ # -----------------------------------------------------------------------
+ def set(self, value):
+ """Set the data in the current position in the list."""
+
+ if not self._ptr:
+ self._ptr = self
+
+ self._ptr._data = cast(value, c_void_p);
+
+
+
+ # -----------------------------------------------------------------------
+ def add(self):
+ """Add a new entry on to the end of the list, ready to be "set"."""
+
+ self.reset()
+ while self.has_next():
+ self.next()
+
+ if not self._ptr:
+ self._ptr = self
+ else:
+ new = GList()
+ new._prev = addressof(self._ptr)
+ self._ptr._next = addressof(new)
+ self._ptr = new
+
+
+# -------------------------------------------------------------------------
+class EContactPhoto_inlined(Structure):
+ _fields_ = [('mime_type', c_char_p),
+ ('length', c_uint),
+ ('data', c_void_p)]
+
+class EContactPhoto_data(Union):
+ _fields_ = [('inlined', EContactPhoto_inlined),
+ ('uri', c_char_p)]
+
+class EContactPhoto(Structure):
+ _fields_ = [('type', c_int),
+ ('data', EContactPhoto_data)]
+
+class EContactDate(Structure):
+ _fields_ = [('year', c_uint),
+ ('month', c_uint),
+ ('day', c_uint)]
+
+# -------------------------------------------------------------------------
+class EVCardAttribute(Structure):
+ _fields_ = [('group', c_char_p),
+ ('name', c_char_p),
+ ('params', POINTER(GList)),
+ ('values', POINTER(GList)),]
+
+ def value(self):
+ if not self.values:
+ return None
+
+ return self.values.contents
+