From dafebc5bb70303f0b5baf0b087cf4d9a64b5c7f0 Mon Sep 17 00:00:00 2001
From: marha <marha@users.sourceforge.net>
Date: Mon, 12 Sep 2011 11:27:51 +0200
Subject: Synchronised line endinge with release branch

---
 libxcb/configure.ac                |  564 ++---
 libxcb/src/c_client.py             | 4654 ++++++++++++++++++------------------
 libxcb/src/xcb.h                   | 1014 ++++----
 libxcb/src/xcb_auth.c              |  746 +++---
 libxcb/src/xcb_in.c                | 1412 +++++------
 libxcb/src/xcb_util.c              |  972 ++++----
 libxcb/src/xcbint.h                |  416 ++--
 libxcb/xcb-proto/src/sync.xml      |  458 ++--
 libxcb/xcb-proto/xcbgen/matcher.py |  226 +-
 libxcb/xcb-proto/xcbgen/state.py   |  332 +--
 libxcb/xcb-proto/xcbgen/xtypes.py  | 1264 +++++-----
 11 files changed, 6029 insertions(+), 6029 deletions(-)

(limited to 'libxcb')

diff --git a/libxcb/configure.ac b/libxcb/configure.ac
index 52ec39cba..cba9dbdad 100644
--- a/libxcb/configure.ac
+++ b/libxcb/configure.ac
@@ -1,282 +1,282 @@
-#                                               -*- Autoconf -*-
-# Process this file with autoconf to produce a configure script.
-
-AC_PREREQ(2.57)
-AC_INIT([libxcb],
-        1.7,
-        [xcb@lists.freedesktop.org])
-AC_CONFIG_SRCDIR([xcb.pc.in])
-AM_INIT_AUTOMAKE([foreign dist-bzip2])
-m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
-
-AM_PATH_PYTHON([2.6])
-
-PKG_CHECK_MODULES(CHECK, [check >= 0.9.4], [HAVE_CHECK=yes], [HAVE_CHECK=no])
-AM_CONDITIONAL(HAVE_CHECK, test x$HAVE_CHECK = xyes)
-
-AC_CONFIG_HEADERS([src/config.h])
-
-AC_LIBTOOL_WIN32_DLL
-AC_PROG_LIBTOOL
-AC_PROG_CC
-
-AC_PATH_PROG(XSLTPROC, xsltproc, no)
-if test "$XSLTPROC" = "no"; then
-   AC_MSG_ERROR([XCB requires xsltproc.])
-fi
-
-HTML_CHECK_RESULT=false
-if test x"$HAVE_CHECK" = xyes; then
-	if test x"$XSLTPROC" != xno; then
-		HTML_CHECK_RESULT=true
-	fi
-fi
-AC_SUBST(HTML_CHECK_RESULT)
-
-# Checks for pkg-config packages
-PKG_CHECK_MODULES(XCBPROTO, xcb-proto >= 1.6)
-NEEDED="pthread-stubs xau >= 0.99.2"
-PKG_CHECK_MODULES(NEEDED, $NEEDED)
-
-have_xdmcp="no"
-PKG_CHECK_MODULES(XDMCP, xdmcp,
-	AC_CHECK_LIB(Xdmcp, XdmcpWrap,
-		[
-		AC_DEFINE(HASXDMAUTH,1,[Has Wraphelp.c needed for XDM AUTH protocols])
-		NEEDED="$NEEDED xdmcp"
-		have_xdmcp="yes"
-		],
-		[
-		XDMCP_CFLAGS=
-		XDMCP_LIBS=
-		], [$XDMCP_LIBS]),
-	[AC_MSG_RESULT(no)])
-
-AC_SUBST(NEEDED)
-
-# Find the xcb-proto protocol descriptions
-AC_MSG_CHECKING(XCBPROTO_XCBINCLUDEDIR)
-XCBPROTO_XCBINCLUDEDIR=`$PKG_CONFIG --variable=xcbincludedir xcb-proto`
-AC_MSG_RESULT($XCBPROTO_XCBINCLUDEDIR)
-AC_SUBST(XCBPROTO_XCBINCLUDEDIR)
-
-# Find the xcb-proto version
-XCBPROTO_VERSION=`$PKG_CONFIG --modversion xcb-proto`
-AC_SUBST(XCBPROTO_VERSION)
-
-# Find the xcbgen Python package
-AC_MSG_CHECKING(XCBPROTO_XCBPYTHONDIR)
-XCBPROTO_XCBPYTHONDIR=`$PKG_CONFIG --variable=pythondir xcb-proto`
-AC_MSG_RESULT($XCBPROTO_XCBPYTHONDIR)
-AC_SUBST(XCBPROTO_XCBPYTHONDIR)
-
-AC_HEADER_STDC
-AC_SEARCH_LIBS(getaddrinfo, socket)
-AC_SEARCH_LIBS(connect, socket)
-
-have_win32="no"
-lt_enable_auto_import=""
-case $host_os in
-mingw*)
-	have_win32="yes"
-	lt_enable_auto_import="-Wl,--enable-auto-import"
- 	;;
-linux*)
-	AC_DEFINE([HAVE_ABSTRACT_SOCKETS], 1, [Define if your platform supports abstract sockets])
-	;;
-esac
-
-AC_SUBST(lt_enable_auto_import)
-AM_CONDITIONAL([XCB_HAVE_WIN32], [test "x${have_win32}" = "xyes"])
-
-dnl define buffer queue size
-AC_ARG_WITH([queue-size],
-            AC_HELP_STRING([--with-queue-size=SIZE],
-            [Set the XCB buffer queue size (default is 16384)]),
-            [xcb_queue_buffer_size="$withval"],
-            [xcb_queue_buffer_size=16384])
-AC_DEFINE_UNQUOTED(XCB_QUEUE_BUFFER_SIZE, [$xcb_queue_buffer_size],
-                   [XCB buffer queue size])
-
-dnl check for the sockaddr_un.sun_len member
-AC_CHECK_MEMBER([struct sockaddr_un.sun_len],
-		[AC_DEFINE(HAVE_SOCKADDR_SUN_LEN,1,[Have the sockaddr_un.sun_len member.])],
-		[],
-		[ #include <sys/types.h>
-		  #include <sys/un.h>
-		])
-
-dnl check for support for Solaris Trusted Extensions
-AC_CHECK_HEADERS([tsol/label.h])
-AC_CHECK_FUNCS([is_system_labeled])
-
-xcbincludedir='${includedir}/xcb'
-AC_SUBST(xcbincludedir)
-
-if  test "x$GCC" = xyes ; then
-    CWARNFLAGS="-Wall -pedantic -Wpointer-arith \
-		-Wstrict-prototypes -Wmissing-declarations -Wnested-externs"
-else
-    AC_CHECK_DECL([__SUNPRO_C], [SUNCC="yes"], [SUNCC="no"])
-    if test "x$SUNCC" = "xyes"; then
-	CWARNFLAGS="-v"
-    fi
-fi
-AC_SUBST(CWARNFLAGS)
-
-XCB_CHECK_VISIBILITY()
-
-# htmldir is not defined prior to autoconf 2.59c, so on earlier versions
-# set an equivalent value.
-AC_PREREQ([2.59c], [], [AC_SUBST([htmldir], [m4_ifset([AC_PACKAGE_TARNAME],
-	  ['${datadir}/doc/${PACKAGE_TARNAME}'],
-	  ['${datadir}/doc/${PACKAGE}'])
-])])
-
-XCB_CHECK_DOXYGEN()
-
-AC_CHECK_FUNC(getaddrinfo, [AC_DEFINE(HAVE_GETADDRINFO, 1, [getaddrinfo() function is available])], )
-
-case $host_os in
-	# darwin through Snow Leopard has poll() but can't be used to poll character devices.
-	darwin@<:@789@:>@*|darwin10*) ;;
-	darwin*)
-		_ac_xorg_macosx_version_min=""
-		if echo $CPPFLAGS $CFLAGS | grep -q mmacosx-version-min ; then
-			_ac_xorg_macosx_version_min=`echo $CPPFLAGS $CFLAGS | sed 's/^.*-mmacosx-version-min=\(@<:@^ @:>@*\).*$/\1/'`
-		else
-			_ac_xorg_macosx_version_min=$MACOSX_DEPLOYMENT_TARGET
-		fi
-		case $_ac_xorg_macosx_version_min in
-			10.@<:@0123456@:>@|10.@<:@0123456@:>@.*) ;;
-			*)
-				AC_CHECK_FUNC(poll, [AC_DEFINE(USE_POLL, 1, [poll() function is available])], )
-			;;
-		esac
-		unset _ac_xorg_macosx_version_min
-		;;
-	*)
-		AC_CHECK_FUNC(poll, [AC_DEFINE(USE_POLL, 1, [poll() function is available])], )
-	;;
-esac
-
-XCB_EXTENSION(Composite, "yes")
-XCB_EXTENSION(Damage, "yes")
-XCB_EXTENSION(DPMS, "yes")
-XCB_EXTENSION(DRI2, "yes")
-XCB_EXTENSION(GLX, "yes")
-XCB_EXTENSION(RandR, "yes")
-XCB_EXTENSION(Record, "yes")
-XCB_EXTENSION(Render, "yes")
-XCB_EXTENSION(Resource, "yes")
-XCB_EXTENSION(Screensaver, "yes")
-XCB_EXTENSION(Shape, "yes")
-XCB_EXTENSION(Shm, "yes")
-XCB_EXTENSION(Sync, "yes")
-XCB_EXTENSION(Xevie, "yes")
-XCB_EXTENSION(XFixes, "yes")
-XCB_EXTENSION(XFree86-DRI, "yes")
-XCB_EXTENSION(Xinerama, "yes")
-XCB_EXTENSION(XInput, "no")
-XCB_EXTENSION(XKB, "no")
-XCB_EXTENSION(Xprint, "yes")
-XCB_EXTENSION(SELinux, "no")
-XCB_EXTENSION(XTest, "yes")
-XCB_EXTENSION(Xv, "yes")
-XCB_EXTENSION(XvMC, "yes")
-
-AC_ARG_WITH(launchd, AS_HELP_STRING([--with-launchd], [Build with support for Apple's launchd (default: auto)]), [LAUNCHD=$withval], [LAUNCHD=auto])
-if test "x$LAUNCHD" = xauto; then
-	unset LAUNCHD
-	AC_CHECK_PROG(LAUNCHD, [launchd], [yes], [no], [$PATH$PATH_SEPARATOR/sbin])
-fi
-
-if test "x$LAUNCHD" = xyes ; then
-	AC_DEFINE(HAVE_LAUNCHD, 1, [launchd support available])
-fi
-
-AC_CONFIG_FILES([
-Makefile
-doc/Makefile
-src/Makefile
-tests/Makefile
-])
-
-AC_CONFIG_FILES([
-xcb.pc
-xcb-composite.pc
-xcb-damage.pc
-xcb-dpms.pc
-xcb-dri2.pc
-xcb-glx.pc
-xcb-randr.pc
-xcb-record.pc
-xcb-render.pc
-xcb-res.pc
-xcb-screensaver.pc
-xcb-shape.pc
-xcb-shm.pc
-xcb-sync.pc
-xcb-xevie.pc
-xcb-xf86dri.pc
-xcb-xfixes.pc
-xcb-xinerama.pc
-xcb-xinput.pc
-xcb-xkb.pc
-xcb-xprint.pc
-xcb-xselinux.pc
-xcb-xtest.pc
-xcb-xv.pc
-xcb-xvmc.pc
-])
-
-AC_CONFIG_FILES([
-doc/xcb.doxygen
-])
-
-AC_OUTPUT
-
-dnl Configuration output
-
-echo ""
-echo "  Package: ${PACKAGE_NAME} ${PACKAGE_VERSION}"
-echo ""
-echo "  Configuration"
-echo "    XDM support.........: ${have_xdmcp}"
-echo "    Build unit tests....: ${HAVE_CHECK}"
-echo "    XCB buffer size.....: ${xcb_queue_buffer_size}"
-echo ""
-echo "  X11 extensions"
-echo "    Composite...........: ${BUILD_COMPOSITE}"
-echo "    Damage..............: ${BUILD_DAMAGE}"
-echo "    Dpms................: ${BUILD_DPMS}"
-echo "    Dri2................: ${BUILD_DRI2}"
-echo "    Glx.................: ${BUILD_GLX}"
-echo "    Randr...............: ${BUILD_RANDR}"
-echo "    Record..............: ${BUILD_RECORD}"
-echo "    Render..............: ${BUILD_RENDER}"
-echo "    Resource............: ${BUILD_RESOURCE}"
-echo "    Screensaver.........: ${BUILD_SCREENSAVER}"
-echo "    selinux.............: ${BUILD_SELINUX}"
-echo "    Shape...............: ${BUILD_SHAPE}"
-echo "    Shm.................: ${BUILD_SHM}"
-echo "    Sync................: ${BUILD_SYNC}"
-echo "    Xevie...............: ${BUILD_XEVIE}"
-echo "    Xfixes..............: ${BUILD_XFIXES}"
-echo "    Xfree86-dri.........: ${BUILD_XFREE86_DRI}"
-echo "    xinerama............: ${BUILD_XINERAMA}"
-echo "    xinput..............: ${BUILD_XINPUT}"
-echo "    xkb.................: ${BUILD_XKB}"
-echo "    xprint..............: ${BUILD_XPRINT}"
-echo "    xtest...............: ${BUILD_XTEST}"
-echo "    xv..................: ${BUILD_XV}"
-echo "    xvmc................: ${BUILD_XVMC}"
-echo ""
-echo "  Used CFLAGS:"
-echo "    CPPFLAGS............: ${CPPFLAGS}"
-echo "    CFLAGS..............: ${CFLAGS}"
-echo "    Warning CFLAGS......: ${CWARNFLAGS}"
-echo ""
-echo "  Installation:"
-echo "    Prefix..............: ${prefix}"
-echo ""
+#                                               -*- Autoconf -*-
+# Process this file with autoconf to produce a configure script.
+
+AC_PREREQ(2.57)
+AC_INIT([libxcb],
+        1.7,
+        [xcb@lists.freedesktop.org])
+AC_CONFIG_SRCDIR([xcb.pc.in])
+AM_INIT_AUTOMAKE([foreign dist-bzip2])
+m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
+
+AM_PATH_PYTHON([2.6])
+
+PKG_CHECK_MODULES(CHECK, [check >= 0.9.4], [HAVE_CHECK=yes], [HAVE_CHECK=no])
+AM_CONDITIONAL(HAVE_CHECK, test x$HAVE_CHECK = xyes)
+
+AC_CONFIG_HEADERS([src/config.h])
+
+AC_LIBTOOL_WIN32_DLL
+AC_PROG_LIBTOOL
+AC_PROG_CC
+
+AC_PATH_PROG(XSLTPROC, xsltproc, no)
+if test "$XSLTPROC" = "no"; then
+   AC_MSG_ERROR([XCB requires xsltproc.])
+fi
+
+HTML_CHECK_RESULT=false
+if test x"$HAVE_CHECK" = xyes; then
+	if test x"$XSLTPROC" != xno; then
+		HTML_CHECK_RESULT=true
+	fi
+fi
+AC_SUBST(HTML_CHECK_RESULT)
+
+# Checks for pkg-config packages
+PKG_CHECK_MODULES(XCBPROTO, xcb-proto >= 1.6)
+NEEDED="pthread-stubs xau >= 0.99.2"
+PKG_CHECK_MODULES(NEEDED, $NEEDED)
+
+have_xdmcp="no"
+PKG_CHECK_MODULES(XDMCP, xdmcp,
+	AC_CHECK_LIB(Xdmcp, XdmcpWrap,
+		[
+		AC_DEFINE(HASXDMAUTH,1,[Has Wraphelp.c needed for XDM AUTH protocols])
+		NEEDED="$NEEDED xdmcp"
+		have_xdmcp="yes"
+		],
+		[
+		XDMCP_CFLAGS=
+		XDMCP_LIBS=
+		], [$XDMCP_LIBS]),
+	[AC_MSG_RESULT(no)])
+
+AC_SUBST(NEEDED)
+
+# Find the xcb-proto protocol descriptions
+AC_MSG_CHECKING(XCBPROTO_XCBINCLUDEDIR)
+XCBPROTO_XCBINCLUDEDIR=`$PKG_CONFIG --variable=xcbincludedir xcb-proto`
+AC_MSG_RESULT($XCBPROTO_XCBINCLUDEDIR)
+AC_SUBST(XCBPROTO_XCBINCLUDEDIR)
+
+# Find the xcb-proto version
+XCBPROTO_VERSION=`$PKG_CONFIG --modversion xcb-proto`
+AC_SUBST(XCBPROTO_VERSION)
+
+# Find the xcbgen Python package
+AC_MSG_CHECKING(XCBPROTO_XCBPYTHONDIR)
+XCBPROTO_XCBPYTHONDIR=`$PKG_CONFIG --variable=pythondir xcb-proto`
+AC_MSG_RESULT($XCBPROTO_XCBPYTHONDIR)
+AC_SUBST(XCBPROTO_XCBPYTHONDIR)
+
+AC_HEADER_STDC
+AC_SEARCH_LIBS(getaddrinfo, socket)
+AC_SEARCH_LIBS(connect, socket)
+
+have_win32="no"
+lt_enable_auto_import=""
+case $host_os in
+mingw*)
+	have_win32="yes"
+	lt_enable_auto_import="-Wl,--enable-auto-import"
+ 	;;
+linux*)
+	AC_DEFINE([HAVE_ABSTRACT_SOCKETS], 1, [Define if your platform supports abstract sockets])
+	;;
+esac
+
+AC_SUBST(lt_enable_auto_import)
+AM_CONDITIONAL([XCB_HAVE_WIN32], [test "x${have_win32}" = "xyes"])
+
+dnl define buffer queue size
+AC_ARG_WITH([queue-size],
+            AC_HELP_STRING([--with-queue-size=SIZE],
+            [Set the XCB buffer queue size (default is 16384)]),
+            [xcb_queue_buffer_size="$withval"],
+            [xcb_queue_buffer_size=16384])
+AC_DEFINE_UNQUOTED(XCB_QUEUE_BUFFER_SIZE, [$xcb_queue_buffer_size],
+                   [XCB buffer queue size])
+
+dnl check for the sockaddr_un.sun_len member
+AC_CHECK_MEMBER([struct sockaddr_un.sun_len],
+		[AC_DEFINE(HAVE_SOCKADDR_SUN_LEN,1,[Have the sockaddr_un.sun_len member.])],
+		[],
+		[ #include <sys/types.h>
+		  #include <sys/un.h>
+		])
+
+dnl check for support for Solaris Trusted Extensions
+AC_CHECK_HEADERS([tsol/label.h])
+AC_CHECK_FUNCS([is_system_labeled])
+
+xcbincludedir='${includedir}/xcb'
+AC_SUBST(xcbincludedir)
+
+if  test "x$GCC" = xyes ; then
+    CWARNFLAGS="-Wall -pedantic -Wpointer-arith \
+		-Wstrict-prototypes -Wmissing-declarations -Wnested-externs"
+else
+    AC_CHECK_DECL([__SUNPRO_C], [SUNCC="yes"], [SUNCC="no"])
+    if test "x$SUNCC" = "xyes"; then
+	CWARNFLAGS="-v"
+    fi
+fi
+AC_SUBST(CWARNFLAGS)
+
+XCB_CHECK_VISIBILITY()
+
+# htmldir is not defined prior to autoconf 2.59c, so on earlier versions
+# set an equivalent value.
+AC_PREREQ([2.59c], [], [AC_SUBST([htmldir], [m4_ifset([AC_PACKAGE_TARNAME],
+	  ['${datadir}/doc/${PACKAGE_TARNAME}'],
+	  ['${datadir}/doc/${PACKAGE}'])
+])])
+
+XCB_CHECK_DOXYGEN()
+
+AC_CHECK_FUNC(getaddrinfo, [AC_DEFINE(HAVE_GETADDRINFO, 1, [getaddrinfo() function is available])], )
+
+case $host_os in
+	# darwin through Snow Leopard has poll() but can't be used to poll character devices.
+	darwin@<:@789@:>@*|darwin10*) ;;
+	darwin*)
+		_ac_xorg_macosx_version_min=""
+		if echo $CPPFLAGS $CFLAGS | grep -q mmacosx-version-min ; then
+			_ac_xorg_macosx_version_min=`echo $CPPFLAGS $CFLAGS | sed 's/^.*-mmacosx-version-min=\(@<:@^ @:>@*\).*$/\1/'`
+		else
+			_ac_xorg_macosx_version_min=$MACOSX_DEPLOYMENT_TARGET
+		fi
+		case $_ac_xorg_macosx_version_min in
+			10.@<:@0123456@:>@|10.@<:@0123456@:>@.*) ;;
+			*)
+				AC_CHECK_FUNC(poll, [AC_DEFINE(USE_POLL, 1, [poll() function is available])], )
+			;;
+		esac
+		unset _ac_xorg_macosx_version_min
+		;;
+	*)
+		AC_CHECK_FUNC(poll, [AC_DEFINE(USE_POLL, 1, [poll() function is available])], )
+	;;
+esac
+
+XCB_EXTENSION(Composite, "yes")
+XCB_EXTENSION(Damage, "yes")
+XCB_EXTENSION(DPMS, "yes")
+XCB_EXTENSION(DRI2, "yes")
+XCB_EXTENSION(GLX, "yes")
+XCB_EXTENSION(RandR, "yes")
+XCB_EXTENSION(Record, "yes")
+XCB_EXTENSION(Render, "yes")
+XCB_EXTENSION(Resource, "yes")
+XCB_EXTENSION(Screensaver, "yes")
+XCB_EXTENSION(Shape, "yes")
+XCB_EXTENSION(Shm, "yes")
+XCB_EXTENSION(Sync, "yes")
+XCB_EXTENSION(Xevie, "yes")
+XCB_EXTENSION(XFixes, "yes")
+XCB_EXTENSION(XFree86-DRI, "yes")
+XCB_EXTENSION(Xinerama, "yes")
+XCB_EXTENSION(XInput, "no")
+XCB_EXTENSION(XKB, "no")
+XCB_EXTENSION(Xprint, "yes")
+XCB_EXTENSION(SELinux, "no")
+XCB_EXTENSION(XTest, "yes")
+XCB_EXTENSION(Xv, "yes")
+XCB_EXTENSION(XvMC, "yes")
+
+AC_ARG_WITH(launchd, AS_HELP_STRING([--with-launchd], [Build with support for Apple's launchd (default: auto)]), [LAUNCHD=$withval], [LAUNCHD=auto])
+if test "x$LAUNCHD" = xauto; then
+	unset LAUNCHD
+	AC_CHECK_PROG(LAUNCHD, [launchd], [yes], [no], [$PATH$PATH_SEPARATOR/sbin])
+fi
+
+if test "x$LAUNCHD" = xyes ; then
+	AC_DEFINE(HAVE_LAUNCHD, 1, [launchd support available])
+fi
+
+AC_CONFIG_FILES([
+Makefile
+doc/Makefile
+src/Makefile
+tests/Makefile
+])
+
+AC_CONFIG_FILES([
+xcb.pc
+xcb-composite.pc
+xcb-damage.pc
+xcb-dpms.pc
+xcb-dri2.pc
+xcb-glx.pc
+xcb-randr.pc
+xcb-record.pc
+xcb-render.pc
+xcb-res.pc
+xcb-screensaver.pc
+xcb-shape.pc
+xcb-shm.pc
+xcb-sync.pc
+xcb-xevie.pc
+xcb-xf86dri.pc
+xcb-xfixes.pc
+xcb-xinerama.pc
+xcb-xinput.pc
+xcb-xkb.pc
+xcb-xprint.pc
+xcb-xselinux.pc
+xcb-xtest.pc
+xcb-xv.pc
+xcb-xvmc.pc
+])
+
+AC_CONFIG_FILES([
+doc/xcb.doxygen
+])
+
+AC_OUTPUT
+
+dnl Configuration output
+
+echo ""
+echo "  Package: ${PACKAGE_NAME} ${PACKAGE_VERSION}"
+echo ""
+echo "  Configuration"
+echo "    XDM support.........: ${have_xdmcp}"
+echo "    Build unit tests....: ${HAVE_CHECK}"
+echo "    XCB buffer size.....: ${xcb_queue_buffer_size}"
+echo ""
+echo "  X11 extensions"
+echo "    Composite...........: ${BUILD_COMPOSITE}"
+echo "    Damage..............: ${BUILD_DAMAGE}"
+echo "    Dpms................: ${BUILD_DPMS}"
+echo "    Dri2................: ${BUILD_DRI2}"
+echo "    Glx.................: ${BUILD_GLX}"
+echo "    Randr...............: ${BUILD_RANDR}"
+echo "    Record..............: ${BUILD_RECORD}"
+echo "    Render..............: ${BUILD_RENDER}"
+echo "    Resource............: ${BUILD_RESOURCE}"
+echo "    Screensaver.........: ${BUILD_SCREENSAVER}"
+echo "    selinux.............: ${BUILD_SELINUX}"
+echo "    Shape...............: ${BUILD_SHAPE}"
+echo "    Shm.................: ${BUILD_SHM}"
+echo "    Sync................: ${BUILD_SYNC}"
+echo "    Xevie...............: ${BUILD_XEVIE}"
+echo "    Xfixes..............: ${BUILD_XFIXES}"
+echo "    Xfree86-dri.........: ${BUILD_XFREE86_DRI}"
+echo "    xinerama............: ${BUILD_XINERAMA}"
+echo "    xinput..............: ${BUILD_XINPUT}"
+echo "    xkb.................: ${BUILD_XKB}"
+echo "    xprint..............: ${BUILD_XPRINT}"
+echo "    xtest...............: ${BUILD_XTEST}"
+echo "    xv..................: ${BUILD_XV}"
+echo "    xvmc................: ${BUILD_XVMC}"
+echo ""
+echo "  Used CFLAGS:"
+echo "    CPPFLAGS............: ${CPPFLAGS}"
+echo "    CFLAGS..............: ${CFLAGS}"
+echo "    Warning CFLAGS......: ${CWARNFLAGS}"
+echo ""
+echo "  Installation:"
+echo "    Prefix..............: ${prefix}"
+echo ""
diff --git a/libxcb/src/c_client.py b/libxcb/src/c_client.py
index 321344190..0f9974899 100644
--- a/libxcb/src/c_client.py
+++ b/libxcb/src/c_client.py
@@ -1,2327 +1,2327 @@
-#!/usr/bin/env python
-from xml.etree.cElementTree import *
-from os.path import basename
-from functools import reduce
-import getopt
-import sys
-import re
-
-# Jump to the bottom of this file for the main routine
-
-# Some hacks to make the API more readable, and to keep backwards compability
-_cname_re = re.compile('([A-Z0-9][a-z]+|[A-Z0-9]+(?![a-z])|[a-z]+)')
-_cname_special_cases = {'DECnet':'decnet'}
-
-_extension_special_cases = ['XPrint', 'XCMisc', 'BigRequests']
-
-_cplusplus_annoyances = {'class' : '_class',
-                         'new'   : '_new',
-                         'delete': '_delete'}
-_c_keywords = {'default' : '_default'}
-
-_hlines = []
-_hlevel = 0
-_clines = []
-_clevel = 0
-_ns = None
-
-# global variable to keep track of serializers and 
-# switch data types due to weird dependencies
-finished_serializers = []
-finished_sizeof = []
-finished_switch = []
-
-def _h(fmt, *args):
-    '''
-    Writes the given line to the header file.
-    '''
-    _hlines[_hlevel].append(fmt % args)
-    
-def _c(fmt, *args):
-    '''
-    Writes the given line to the source file.
-    '''
-    _clines[_clevel].append(fmt % args)
-    
-def _hc(fmt, *args):
-    '''
-    Writes the given line to both the header and source files.
-    '''
-    _h(fmt, *args)
-    _c(fmt, *args)
-
-# XXX See if this level thing is really necessary.
-def _h_setlevel(idx):
-    '''
-    Changes the array that header lines are written to.
-    Supports writing different sections of the header file.
-    '''
-    global _hlevel
-    while len(_hlines) <= idx:
-        _hlines.append([])
-    _hlevel = idx
-    
-def _c_setlevel(idx):
-    '''
-    Changes the array that source lines are written to.
-    Supports writing to different sections of the source file.
-    '''
-    global _clevel
-    while len(_clines) <= idx:
-        _clines.append([])
-    _clevel = idx
-    
-def _n_item(str):
-    '''
-    Does C-name conversion on a single string fragment.
-    Uses a regexp with some hard-coded special cases.
-    '''
-    if str in _cname_special_cases:
-        return _cname_special_cases[str]
-    else:
-        split = _cname_re.finditer(str)
-        name_parts = [match.group(0) for match in split]
-        return '_'.join(name_parts)
-    
-def _cpp(str):
-    '''
-    Checks for certain C++ reserved words and fixes them.
-    '''
-    if str in _cplusplus_annoyances:
-        return _cplusplus_annoyances[str]
-    elif str in _c_keywords:
-        return  _c_keywords[str]
-    else:
-        return str
-
-def _ext(str):
-    '''
-    Does C-name conversion on an extension name.
-    Has some additional special cases on top of _n_item.
-    '''
-    if str in _extension_special_cases:
-        return _n_item(str).lower()
-    else:
-        return str.lower()
-    
-def _n(list):
-    '''
-    Does C-name conversion on a tuple of strings.
-    Different behavior depending on length of tuple, extension/not extension, etc.
-    Basically C-name converts the individual pieces, then joins with underscores.
-    '''
-    if len(list) == 1:
-        parts = list
-    elif len(list) == 2:
-        parts = [list[0], _n_item(list[1])]
-    elif _ns.is_ext:
-        parts = [list[0], _ext(list[1])] + [_n_item(i) for i in list[2:]]
-    else:
-        parts = [list[0]] + [_n_item(i) for i in list[1:]]
-    return '_'.join(parts).lower()
-
-def _t(list):
-    '''
-    Does C-name conversion on a tuple of strings representing a type.
-    Same as _n but adds a "_t" on the end.
-    '''
-    if len(list) == 1:
-        parts = list
-    elif len(list) == 2:
-        parts = [list[0], _n_item(list[1]), 't']
-    elif _ns.is_ext:
-        parts = [list[0], _ext(list[1])] + [_n_item(i) for i in list[2:]] + ['t']
-    else:
-        parts = [list[0]] + [_n_item(i) for i in list[1:]] + ['t']
-    return '_'.join(parts).lower()
-        
-
-def c_open(self):
-    '''
-    Exported function that handles module open.
-    Opens the files and writes out the auto-generated comment, header file includes, etc.
-    '''
-    global _ns
-    _ns = self.namespace
-    _ns.c_ext_global_name = _n(_ns.prefix + ('id',))
-
-    # Build the type-name collision avoidance table used by c_enum
-    build_collision_table()
-
-    _h_setlevel(0)
-    _c_setlevel(0)
-
-    _hc('/*')
-    _hc(' * This file generated automatically from %s by c_client.py.', _ns.file)
-    _hc(' * Edit at your peril.')
-    _hc(' */')
-    _hc('')
-
-    _h('/**')
-    _h(' * @defgroup XCB_%s_API XCB %s API', _ns.ext_name, _ns.ext_name)
-    _h(' * @brief %s XCB Protocol Implementation.', _ns.ext_name)
-    _h(' * @{')
-    _h(' **/')
-    _h('')
-    _h('#ifndef __%s_H', _ns.header.upper())
-    _h('#define __%s_H', _ns.header.upper())
-    _h('')
-    _h('#include "xcb.h"')
-
-    _c('#include <stdlib.h>')
-    _c('#include <string.h>')
-    _c('#include <assert.h>')
-    _c('#include <stddef.h>  /* for offsetof() */')
-    _c('#include "xcbext.h"')
-    _c('#include "%s.h"', _ns.header)
-    _c('#include <X11/Xtrans/Xtrans.h>')
-        
-    _c('')
-    _c('#define ALIGNOF(type) offsetof(struct { char dummy; type member; }, member)')
-
-    if _ns.is_ext:
-        for (n, h) in self.imports:
-            _hc('#include "%s.h"', h)
-
-    _h('')
-    _h('#ifdef __cplusplus')
-    _h('extern "C" {')
-    _h('#endif')
-
-    if _ns.is_ext:
-        _h('')
-        _h('#define XCB_%s_MAJOR_VERSION %s', _ns.ext_name.upper(), _ns.major_version)
-        _h('#define XCB_%s_MINOR_VERSION %s', _ns.ext_name.upper(), _ns.minor_version)
-        _h('  ') #XXX
-        _h('extern xcb_extension_t %s;', _ns.c_ext_global_name)
-
-        _c('')
-        _c('xcb_extension_t %s = { "%s", 0 };', _ns.c_ext_global_name, _ns.ext_xname)
-
-def c_close(self):
-    '''
-    Exported function that handles module close.
-    Writes out all the stored content lines, then closes the files.
-    '''
-    _h_setlevel(2)
-    _c_setlevel(2)
-    _hc('')
-
-    _h('')
-    _h('#ifdef __cplusplus')
-    _h('}')
-    _h('#endif')
-
-    _h('')
-    _h('#endif')
-    _h('')
-    _h('/**')
-    _h(' * @}')
-    _h(' */')
-
-    # Write header file
-    hfile = open('%s.h' % _ns.header, 'w')
-    for list in _hlines:
-        for line in list:
-            hfile.write(line)
-            hfile.write('\n')
-    hfile.close()
-
-    # Write source file
-    cfile = open('%s.c' % _ns.header, 'w')
-    for list in _clines:
-        for line in list:
-            cfile.write(line)
-            cfile.write('\n')
-    cfile.close()
-
-def build_collision_table():
-    global namecount
-    namecount = {}
-
-    for v in module.types.values():
-        name = _t(v[0])
-        namecount[name] = (namecount.get(name) or 0) + 1
-
-def c_enum(self, name):
-    '''
-    Exported function that handles enum declarations.
-    '''
-
-    tname = _t(name)
-    if namecount[tname] > 1:
-        tname = _t(name + ('enum',))
-
-    _h_setlevel(0)
-    _h('')
-    _h('typedef enum %s {', tname)
-
-    count = len(self.values)
-
-    for (enam, eval) in self.values:
-        count = count - 1
-        equals = ' = ' if eval != '' else ''
-        comma = ',' if count > 0 else ''
-        _h('    %s%s%s%s', _n(name + (enam,)).upper(), equals, eval, comma)
-
-    _h('} %s;', tname)
-
-def _c_type_setup(self, name, postfix):
-    '''
-    Sets up all the C-related state by adding additional data fields to
-    all Field and Type objects.  Here is where we figure out most of our
-    variable and function names.
-
-    Recurses into child fields and list member types.
-    '''
-    # Do all the various names in advance
-    self.c_type = _t(name + postfix)
-    self.c_wiretype = 'char' if self.c_type == 'void' else self.c_type
-
-    self.c_iterator_type = _t(name + ('iterator',))
-    self.c_next_name = _n(name + ('next',))
-    self.c_end_name = _n(name + ('end',))
-
-    self.c_request_name = _n(name)
-    self.c_checked_name = _n(name + ('checked',))
-    self.c_unchecked_name = _n(name + ('unchecked',))
-    self.c_reply_name = _n(name + ('reply',))
-    self.c_reply_type = _t(name + ('reply',))
-    self.c_cookie_type = _t(name + ('cookie',))
-
-    self.need_aux = False
-    self.need_serialize = False
-    self.need_sizeof = False
-
-    self.c_aux_name = _n(name + ('aux',))
-    self.c_aux_checked_name = _n(name + ('aux', 'checked'))
-    self.c_aux_unchecked_name = _n(name + ('aux', 'unchecked'))
-    self.c_serialize_name = _n(name + ('serialize',))
-    self.c_unserialize_name = _n(name + ('unserialize',))
-    self.c_unpack_name = _n(name + ('unpack',))
-    self.c_sizeof_name = _n(name + ('sizeof',))
-
-    # special case: structs where variable size fields are followed by fixed size fields
-    self.var_followed_by_fixed_fields = False
-
-    if self.is_switch:
-        self.need_serialize = True
-        self.c_container = 'struct'
-        for bitcase in self.bitcases:
-            bitcase.c_field_name = _cpp(bitcase.field_name)
-            bitcase_name = bitcase.field_type if bitcase.type.has_name else name
-            _c_type_setup(bitcase.type, bitcase_name, ())
-
-    elif self.is_container:
-
-        self.c_container = 'union' if self.is_union else 'struct'
-        prev_varsized_field = None
-        prev_varsized_offset = 0
-        first_field_after_varsized = None
-
-        for field in self.fields:
-            _c_type_setup(field.type, field.field_type, ())
-            if field.type.is_list:
-                _c_type_setup(field.type.member, field.field_type, ())
-                if (field.type.nmemb is None): 
-                    self.need_sizeof = True
-
-            field.c_field_type = _t(field.field_type)
-            field.c_field_const_type = ('' if field.type.nmemb == 1 else 'const ') + field.c_field_type
-            field.c_field_name = _cpp(field.field_name)
-            field.c_subscript = '[%d]' % field.type.nmemb if (field.type.nmemb and field.type.nmemb > 1) else ''
-            field.c_pointer = ' ' if field.type.nmemb == 1 else '*'
-
-            # correct the c_pointer field for variable size non-list types
-            if not field.type.fixed_size() and field.c_pointer == ' ':
-                field.c_pointer = '*'
-            if field.type.is_list and not field.type.member.fixed_size():
-                field.c_pointer = '*'
-
-            if field.type.is_switch:
-                field.c_pointer = '*'
-                field.c_field_const_type = 'const ' + field.c_field_type
-                self.need_aux = True
-            elif not field.type.fixed_size() and not field.type.is_bitcase:
-                self.need_sizeof = True
-
-            field.c_iterator_type = _t(field.field_type + ('iterator',))      # xcb_fieldtype_iterator_t
-            field.c_iterator_name = _n(name + (field.field_name, 'iterator')) # xcb_container_field_iterator
-            field.c_accessor_name = _n(name + (field.field_name,))            # xcb_container_field
-            field.c_length_name = _n(name + (field.field_name, 'length'))     # xcb_container_field_length
-            field.c_end_name = _n(name + (field.field_name, 'end'))           # xcb_container_field_end
-
-            field.prev_varsized_field = prev_varsized_field
-            field.prev_varsized_offset = prev_varsized_offset
-
-            if prev_varsized_offset == 0:
-                first_field_after_varsized = field
-            field.first_field_after_varsized = first_field_after_varsized
-
-            if field.type.fixed_size():
-                prev_varsized_offset += field.type.size
-                # special case: intermixed fixed and variable size fields
-                if prev_varsized_field is not None and not field.type.is_pad and field.wire:
-                    if not self.is_union:
-                        self.need_serialize = True
-                        self.var_followed_by_fixed_fields = True
-            else:
-                self.last_varsized_field = field
-                prev_varsized_field = field
-                prev_varsized_offset = 0                    
-
-            if self.var_followed_by_fixed_fields:
-                if field.type.fixed_size():
-                    field.prev_varsized_field = None
-                            
-    if self.need_serialize:
-        # when _unserialize() is wanted, create _sizeof() as well for consistency reasons 
-        self.need_sizeof = True
-
-    # as switch does never appear at toplevel, 
-    # continue here with type construction
-    if self.is_switch:
-        if self.c_type not in finished_switch:
-            finished_switch.append(self.c_type)
-            # special: switch C structs get pointer fields for variable-sized members
-            _c_complex(self)
-            for bitcase in self.bitcases:
-                bitcase_name = bitcase.type.name if bitcase.type.has_name else name
-                _c_accessors(bitcase.type, bitcase_name, bitcase_name)
-                # no list with switch as element, so no call to 
-                # _c_iterator(field.type, field_name) necessary
-
-    if not self.is_bitcase:
-        if self.need_serialize:
-            if self.c_serialize_name not in finished_serializers:
-                finished_serializers.append(self.c_serialize_name)
-                _c_serialize('serialize', self)
-
-                # _unpack() and _unserialize() are only needed for special cases:
-                #   switch -> unpack
-                #   special cases -> unserialize
-                if self.is_switch or self.var_followed_by_fixed_fields:
-                    _c_serialize('unserialize', self)
-                    
-        if self.need_sizeof:
-            if self.c_sizeof_name not in finished_sizeof:
-                if not module.namespace.is_ext or self.name[:2] == module.namespace.prefix:
-                    finished_sizeof.append(self.c_sizeof_name)
-                    _c_serialize('sizeof', self)
-# _c_type_setup()
-
-def _c_helper_absolute_name(prefix, field=None):
-    """
-    turn prefix, which is a list of tuples (name, separator, Type obj) into a string
-    representing a valid name in C (based on the context)
-    if field is not None, append the field name as well
-    """
-    prefix_str = ''
-    for name, sep, obj in prefix:
-        prefix_str += name
-        if '' == sep:
-            sep = '->'
-            if ((obj.is_bitcase and obj.has_name) or     # named bitcase
-                (obj.is_switch and len(obj.parents)>1)):
-                sep = '.'
-        prefix_str += sep
-    if field is not None:
-        prefix_str += _cpp(field.field_name)
-    return prefix_str
-# _c_absolute_name
-    
-def _c_helper_field_mapping(complex_type, prefix, flat=False):
-    """
-    generate absolute names, based on prefix, for all fields starting from complex_type
-    if flat == True, nested complex types are not taken into account
-    """
-    all_fields = {}
-    if complex_type.is_switch:
-        for b in complex_type.bitcases:
-            if b.type.has_name:
-                switch_name, switch_sep, switch_type = prefix[-1]
-                bitcase_prefix = prefix + [(b.type.name[-1], '.', b.type)]
-            else:
-                bitcase_prefix = prefix 
-
-            if (True==flat and not b.type.has_name) or False==flat:
-                all_fields.update(_c_helper_field_mapping(b.type, bitcase_prefix, flat))
-    else:
-        for f in complex_type.fields:
-            fname = _c_helper_absolute_name(prefix, f)
-            if f.field_name in all_fields:
-                raise Exception("field name %s has been registered before" % f.field_name)
-
-            all_fields[f.field_name] = (fname, f)
-            if f.type.is_container and flat==False:
-                if f.type.is_bitcase and not f.type.has_name:
-                    new_prefix = prefix
-                elif f.type.is_switch and len(f.type.parents)>1:
-                    # nested switch gets another separator
-                    new_prefix = prefix+[(f.c_field_name, '.', f.type)]
-                else:
-                    new_prefix = prefix+[(f.c_field_name, '->', f.type)]
-                all_fields.update(_c_helper_field_mapping(f.type, new_prefix, flat))
-
-    return all_fields
-# _c_field_mapping()
-
-def _c_helper_resolve_field_names (prefix):
-    """
-    get field names for all objects in the prefix array
-    """
-    all_fields = {}
-    tmp_prefix = []
-    # look for fields in the remaining containers
-    for idx, p in enumerate(prefix):
-        name, sep, obj = p
-        if ''==sep:
-            # sep can be preset in prefix, if not, make a sensible guess
-            sep = '.' if (obj.is_switch or obj.is_bitcase) else '->'
-            # exception: 'toplevel' object (switch as well!) always have sep '->'
-            sep = '->' if idx<1 else sep
-        if not obj.is_bitcase or (obj.is_bitcase and obj.has_name):
-            tmp_prefix.append((name, sep, obj))
-        all_fields.update(_c_helper_field_mapping(obj, tmp_prefix, flat=True))
-
-    return all_fields
-# _c_helper_resolve_field_names
-
-def get_expr_fields(self):
-    """
-    get the Fields referenced by switch or list expression 
-    """
-    def get_expr_field_names(expr):
-        if expr.op is None:
-            if expr.lenfield_name is not None:
-                return [expr.lenfield_name]
-            else:
-                # constant value expr
-                return []
-        else:
-            if expr.op == '~':
-                return get_expr_field_names(expr.rhs)
-            elif expr.op == 'popcount':
-                return get_expr_field_names(expr.rhs)
-            elif expr.op == 'sumof':
-                # sumof expr references another list, 
-                # we need that list's length field here
-                field = None
-                for f in expr.lenfield_parent.fields:
-                    if f.field_name == expr.lenfield_name:
-                        field = f
-                        break
-                if field is None:
-                    raise Exception("list field '%s' referenced by sumof not found" % expr.lenfield_name)
-                # referenced list + its length field
-                return [expr.lenfield_name] + get_expr_field_names(field.type.expr)
-            elif expr.op == 'enumref':
-                return []
-            else:
-                return get_expr_field_names(expr.lhs) + get_expr_field_names(expr.rhs)
-    # get_expr_field_names()
-    
-    # resolve the field names with the parent structure(s)
-    unresolved_fields_names = get_expr_field_names(self.expr)
-
-    # construct prefix from self
-    prefix = [('', '', p) for p in self.parents]
-    if self.is_container:
-        prefix.append(('', '', self))
-
-    all_fields = _c_helper_resolve_field_names (prefix)
-    resolved_fields_names = list(filter(lambda x: x in all_fields.keys(), unresolved_fields_names))
-    if len(unresolved_fields_names) != len(resolved_fields_names):
-        raise Exception("could not resolve all fields for %s" % self.name)
-    
-    resolved_fields = [all_fields[n][1] for n in resolved_fields_names]
-    return resolved_fields
-# get_expr_fields()
-
-def resolve_expr_fields(complex_obj):
-    """
-    find expr fields appearing in complex_obj and descendents that cannot be resolved within complex_obj
-    these are normally fields that need to be given as function parameters
-    """
-    all_fields = []
-    expr_fields = []
-    unresolved = []
-
-    for field in complex_obj.fields:
-        all_fields.append(field)
-        if field.type.is_switch or field.type.is_list:
-            expr_fields += get_expr_fields(field.type)
-        if field.type.is_container:
-            expr_fields += resolve_expr_fields(field.type)
-
-    # try to resolve expr fields
-    for e in expr_fields:
-        if e not in all_fields and e not in unresolved:
-            unresolved.append(e)
-    return unresolved
-# resolve_expr_fields()
-            
-def get_serialize_params(context, self, buffer_var='_buffer', aux_var='_aux'):
-    """
-    functions like _serialize(), _unserialize(), and _unpack() sometimes need additional parameters:
-    E.g. in order to unpack switch, extra parameters might be needed to evaluate the switch 
-    expression. This function tries to resolve all fields within a structure, and returns the 
-    unresolved fields as the list of external parameters. 
-    """
-    def add_param(params, param):
-        if param not in params:
-            params.append(param)
-
-    # collect all fields into param_fields
-    param_fields = []
-    wire_fields = []
-
-    for field in self.fields:
-        if field.visible:
-            # the field should appear as a parameter in the function call
-            param_fields.append(field)
-        if field.wire and not field.auto:
-            if field.type.fixed_size() and not self.is_switch:
-                # field in the xcb_out structure
-                wire_fields.append(field)
-        # fields like 'pad0' are skipped!
-               
-    # in case of switch, parameters always contain any fields referenced in the switch expr
-    # we do not need any variable size fields here, as the switch data type contains both 
-    # fixed and variable size fields
-    if self.is_switch:
-        param_fields = get_expr_fields(self)
-
-    # _serialize()/_unserialize()/_unpack() function parameters
-    # note: don't use set() for params, it is unsorted
-    params = []
-    
-    # 1. the parameter for the void * buffer
-    if  'serialize' == context:
-        params.append(('void', '**', buffer_var))
-    elif context in ('unserialize', 'unpack', 'sizeof'):
-        params.append(('const void', '*', buffer_var))
-
-    # 2. any expr fields that cannot be resolved within self and descendants
-    unresolved_fields = resolve_expr_fields(self)
-    for f in unresolved_fields:
-        add_param(params, (f.c_field_type, '', f.c_field_name))
-
-    # 3. param_fields contain the fields necessary to evaluate the switch expr or any other fields
-    #    that do not appear in the data type struct
-    for p in param_fields:
-        if self.is_switch:
-            typespec = p.c_field_const_type
-            pointerspec = p.c_pointer 
-            add_param(params, (typespec, pointerspec, p.c_field_name))
-        else:
-            if p.visible and not p.wire and not p.auto:
-                typespec = p.c_field_type
-                pointerspec = ''
-                add_param(params, (typespec, pointerspec, p.c_field_name))
-  
-    # 4. aux argument
-    if 'serialize' == context:
-        add_param(params, ('const %s' % self.c_type, '*', aux_var))
-    elif 'unserialize' == context: 
-        add_param(params, ('%s' % self.c_type, '**', aux_var))
-    elif 'unpack' == context:
-        add_param(params, ('%s' % self.c_type, '*', aux_var))
-
-    # 5. switch contains all variable size fields as struct members
-    #    for other data types though, these have to be supplied separately
-    #    this is important for the special case of intermixed fixed and 
-    #    variable size fields
-    if not self.is_switch and 'serialize' == context:
-        for p in param_fields:
-            if not p.type.fixed_size():
-                add_param(params, (p.c_field_const_type, '*', p.c_field_name))
-
-    return (param_fields, wire_fields, params)
-# get_serialize_params()
-
-def _c_serialize_helper_insert_padding(context, code_lines, space, postpone):
-    code_lines.append('%s    /* insert padding */' % space)
-    code_lines.append('%s    xcb_pad = -xcb_block_len & (xcb_align_to - 1);' % space)
-#    code_lines.append('%s    printf("automatically inserting padding: %%%%d\\n", xcb_pad);' % space)
-    code_lines.append('%s    xcb_buffer_len += xcb_block_len + xcb_pad;' % space)
-
-    if not postpone:
-        code_lines.append('%s    if (0 != xcb_pad) {' % space)
-
-        if 'serialize' == context:
-            code_lines.append('%s        xcb_parts[xcb_parts_idx].iov_base = xcb_pad0;' % space)
-            code_lines.append('%s        xcb_parts[xcb_parts_idx].iov_len = xcb_pad;' % space)
-            code_lines.append('%s        xcb_parts_idx++;' % space)
-        elif context in ('unserialize', 'unpack', 'sizeof'):
-            code_lines.append('%s        xcb_tmp += xcb_pad;' % space)
-
-        code_lines.append('%s        xcb_pad = 0;' % space)
-        code_lines.append('%s    }' % space)
-        
-    code_lines.append('%s    xcb_block_len = 0;' % space)
-
-    # keep tracking of xcb_parts entries for serialize
-    return 1
-# _c_serialize_helper_insert_padding()
-
-def _c_serialize_helper_switch(context, self, complex_name, 
-                               code_lines, temp_vars, 
-                               space, prefix):
-    count = 0
-    switch_expr = _c_accessor_get_expr(self.expr, None)
-
-    for b in self.bitcases:            
-        bitcase_expr = _c_accessor_get_expr(b.type.expr, None)
-        code_lines.append('    if(%s & %s) {' % (switch_expr, bitcase_expr))
-#        code_lines.append('        printf("switch %s: entering bitcase section %s (mask=%%%%d)...\\n", %s);' % 
-#                          (self.name[-1], b.type.name[-1], bitcase_expr))
-        b_prefix = prefix
-        if b.type.has_name:
-            b_prefix = prefix + [(b.c_field_name, '.', b.type)]
-            
-        count += _c_serialize_helper_fields(context, b.type, 
-                                            code_lines, temp_vars, 
-                                            "%s    " % space, 
-                                            b_prefix, 
-                                            is_bitcase = True)
-        code_lines.append('    }')
-
-#    if 'serialize' == context:
-#        count += _c_serialize_helper_insert_padding(context, code_lines, space, False)
-#    elif context in ('unserialize', 'unpack', 'sizeof'):
-#        # padding
-#        code_lines.append('%s    xcb_pad = -xcb_block_len & 3;' % space)
-#        code_lines.append('%s    xcb_buffer_len += xcb_block_len + xcb_pad;' % space)
-   
-    return count
-# _c_serialize_helper_switch
-
-def _c_serialize_helper_switch_field(context, self, field, c_switch_variable, prefix):
-    """
-    handle switch by calling _serialize() or _unpack(), depending on context
-    """
-    # switch is handled by this function as a special case
-    param_fields, wire_fields, params = get_serialize_params(context, self)
-    field_mapping = _c_helper_field_mapping(self, prefix)
-    prefix_str = _c_helper_absolute_name(prefix)
-
-    # find the parameters that need to be passed to _serialize()/_unpack():
-    # all switch expr fields must be given as parameters
-    args = get_expr_fields(field.type)
-    # length fields for variable size types in switch, normally only some of need 
-    # need to be passed as parameters
-    switch_len_fields = resolve_expr_fields(field.type)
-
-    # a switch field at this point _must_ be a bitcase field
-    # we require that bitcases are "self-contiguous"
-    bitcase_unresolved = resolve_expr_fields(self)
-    if len(bitcase_unresolved) != 0:
-        raise Exception('unresolved fields within bitcase is not supported at this point')
-
-    # get the C names for the parameters  
-    c_field_names = ''
-    for a in switch_len_fields:
-        c_field_names += "%s, " % field_mapping[a.c_field_name][0]
-    for a in args:
-        c_field_names += "%s, " % field_mapping[a.c_field_name][0]
-
-    # call _serialize()/_unpack() to determine the actual size
-    if 'serialize' == context:
-        length = "%s(&%s, %s&%s%s)" % (field.type.c_serialize_name, c_switch_variable,
-                                       c_field_names, prefix_str, field.c_field_name) 
-    elif context in ('unserialize', 'unpack'):
-        length = "%s(xcb_tmp, %s&%s%s)" % (field.type.c_unpack_name, 
-                                           c_field_names, prefix_str, field.c_field_name)
-
-    return length
-# _c_serialize_helper_switch_field()
-
-def _c_serialize_helper_list_field(context, self, field, 
-                                   code_lines, temp_vars, 
-                                   space, prefix):
-    """
-    helper function to cope with lists of variable length
-    """
-    expr = field.type.expr
-    prefix_str = _c_helper_absolute_name(prefix)
-    param_fields, wire_fields, params = get_serialize_params('sizeof', self)
-    param_names = [p[2] for p in params]
-    
-    expr_fields_names = [f.field_name for f in get_expr_fields(field.type)]
-    resolved = list(filter(lambda x: x in param_names, expr_fields_names))
-    unresolved = list(filter(lambda x: x not in param_names, expr_fields_names))
-    
-    field_mapping = {}
-    for r in resolved:
-        field_mapping[r] = (r, None)
-    
-    if len(unresolved)>0:
-        tmp_prefix = prefix
-        if len(tmp_prefix)==0:
-            raise Exception("found an empty prefix while resolving expr field names for list %s", 
-                            field.c_field_name)        
-        
-        field_mapping.update(_c_helper_resolve_field_names(prefix))
-        resolved += list(filter(lambda x: x in field_mapping, unresolved))
-        unresolved = list(filter(lambda x: x not in field_mapping, unresolved))
-        if len(unresolved)>0:
-            raise Exception('could not resolve the length fields required for list %s' % field.c_field_name)
-
-    list_length = _c_accessor_get_expr(expr, field_mapping)
-
-    # default: list with fixed size elements
-    length = '%s * sizeof(%s)' % (list_length, field.type.member.c_wiretype)
-
-    # list with variable-sized elements 
-    if not field.type.member.fixed_size():
-        length = ''
-        if context in ('unserialize', 'sizeof', 'unpack'):
-            int_i = '    unsigned int i;'
-            xcb_tmp_len = '    unsigned int xcb_tmp_len;'
-            if int_i not in temp_vars:
-                temp_vars.append(int_i)
-            if xcb_tmp_len not in temp_vars:
-                temp_vars.append(xcb_tmp_len)
-            # loop over all list elements and call sizeof repeatedly
-            # this should be a bit faster than using the iterators
-            code_lines.append("%s    for(i=0; i<%s; i++) {" % (space, list_length))
-            code_lines.append("%s        xcb_tmp_len = %s(xcb_tmp);" % 
-                              (space, field.type.c_sizeof_name))
-            code_lines.append("%s        xcb_block_len += xcb_tmp_len;" % space)
-            code_lines.append("%s        xcb_tmp += xcb_tmp_len;" % space)
-            code_lines.append("%s    }" % space)                  
-      
-        elif 'serialize' == context:
-            code_lines.append('%s    xcb_parts[xcb_parts_idx].iov_len = 0;' % space)
-            code_lines.append('%s    xcb_tmp = (char *) %s%s;' % (space, prefix_str, field.c_field_name))
-            code_lines.append('%s    for(i=0; i<%s; i++) { ' % (space, list_length))
-            code_lines.append('%s        xcb_block_len = %s(xcb_tmp);' % (space, field.type.c_sizeof_name))
-            code_lines.append('%s        xcb_parts[xcb_parts_idx].iov_len += xcb_block_len;' % space)
-            code_lines.append('%s    }' % space)
-            code_lines.append('%s    xcb_block_len = xcb_parts[xcb_parts_idx].iov_len;' % space)
-            
-    return length
-# _c_serialize_helper_list_field()
-
-def _c_serialize_helper_fields_fixed_size(context, self, field, 
-                                          code_lines, temp_vars, 
-                                          space, prefix):
-    # keep the C code a bit more readable by giving the field name
-    if not self.is_bitcase:
-        code_lines.append('%s    /* %s.%s */' % (space, self.c_type, field.c_field_name))
-    else:
-        scoped_name = [p[2].c_type if idx==0 else p[0] for idx, p in enumerate(prefix)]
-        typename = reduce(lambda x,y: "%s.%s" % (x, y), scoped_name)
-        code_lines.append('%s    /* %s.%s */' % (space, typename, field.c_field_name))
-
-    abs_field_name = _c_helper_absolute_name(prefix, field)
-    # default for simple cases: call sizeof()
-    length = "sizeof(%s)" % field.c_field_type
-
-    if context in ('unserialize', 'unpack', 'sizeof'):
-        # default: simple cast
-        value = '    %s = *(%s *)xcb_tmp;' % (abs_field_name, field.c_field_type) 
-        
-        # padding - we could probably just ignore it
-        if field.type.is_pad and field.type.nmemb > 1:
-            value = ''
-            for i in range(field.type.nmemb):
-                code_lines.append('%s    %s[%d] = *(%s *)xcb_tmp;' % 
-                                  (space, abs_field_name, i, field.c_field_type)) 
-            # total padding = sizeof(pad0) * nmemb
-            length += " * %d" % field.type.nmemb
-
-        if field.type.is_list:
-            # no such case in the protocol, cannot be tested and therefore ignored for now
-            raise Exception('list with fixed number of elemens unhandled in _unserialize()')
-
-    elif 'serialize' == context:
-        value = '    xcb_parts[xcb_parts_idx].iov_base = (char *) ' 
-
-        if field.type.is_expr:
-            # need to register a temporary variable for the expression in case we know its type
-            if field.type.c_type is None:
-                raise Exception("type for field '%s' (expression '%s') unkown" % 
-                                (field.field_name, _c_accessor_get_expr(field.type.expr)))
-            
-            temp_vars.append('    %s xcb_expr_%s = %s;' % (field.type.c_type, _cpp(field.field_name), 
-                                                           _c_accessor_get_expr(field.type.expr, prefix)))
-            value += "&xcb_expr_%s;" % _cpp(field.field_name)
-
-        elif field.type.is_pad:
-            if field.type.nmemb == 1:
-                value += "&xcb_pad;"
-            else:
-                # we could also set it to 0, see definition of xcb_send_request()
-                value = '    xcb_parts[xcb_parts_idx].iov_base = xcb_pad0;'
-                length += "*%d" % field.type.nmemb
-
-        else:
-            # non-list type with fixed size
-            if field.type.nmemb == 1:
-                value += "&%s;" % (abs_field_name)
-
-            # list with nmemb (fixed size) elements
-            else:
-                value += '%s;' % (abs_field_name)
-                length = '%d' % field.type.nmemb
-
-    return (value, length)
-# _c_serialize_helper_fields_fixed_size()
-
-def _c_serialize_helper_fields_variable_size(context, self, field, 
-                                             code_lines, temp_vars, 
-                                             space, prefix):
-    prefix_str = _c_helper_absolute_name(prefix)
-
-    if context in ('unserialize', 'unpack', 'sizeof'):
-        value = ''
-        var_field_name = 'xcb_tmp'
-        
-        # special case: intermixed fixed and variable size fields
-        if self.var_followed_by_fixed_fields and 'unserialize' == context:
-            value = '    %s = (%s *)xcb_tmp;' % (field.c_field_name, field.c_field_type)
-            temp_vars.append('    %s *%s;' % (field.type.c_type, field.c_field_name))
-        # special case: switch
-        if 'unpack' == context:
-            value = '    %s%s = (%s *)xcb_tmp;' % (prefix_str, field.c_field_name, field.c_field_type)
-            
-    elif 'serialize' == context:
-        # variable size fields appear as parameters to _serialize() if the 
-        # 'toplevel' container is not a switch
-        prefix_string = prefix_str if prefix[0][2].is_switch else ''
-        var_field_name = "%s%s" % (prefix_string, field.c_field_name)
-        value = '    xcb_parts[xcb_parts_idx].iov_base = (char *) %s;' % var_field_name
-
-    length = ''
-
-    code_lines.append('%s    /* %s */' % (space, field.c_field_name))
-
-    if field.type.is_list:
-        if value != '':
-            # in any context, list is already a pointer, so the default assignment is ok
-            code_lines.append("%s%s" % (space, value))
-            value = ''
-        length = _c_serialize_helper_list_field(context, self, field, 
-                                                code_lines, temp_vars, 
-                                                space, prefix)
-        
-    elif field.type.is_switch:
-        value = ''
-        if context == 'serialize':
-            # the _serialize() function allocates the correct amount memory if given a NULL pointer
-            value = '    xcb_parts[xcb_parts_idx].iov_base = (char *)0;'
-        length = _c_serialize_helper_switch_field(context, self, field, 
-                                                  'xcb_parts[xcb_parts_idx].iov_base', 
-                                                  prefix)
-        
-    else:
-        # in all remaining special cases - call _sizeof()
-        length = "%s(%s)" % (field.type.c_sizeof_name, var_field_name)
-
-    return (value, length)
-# _c_serialize_helper_fields_variable_size
-
-def _c_serialize_helper_fields(context, self, 
-                               code_lines, temp_vars, 
-                               space, prefix, is_bitcase):
-    count = 0
-    need_padding = False
-    prev_field_was_variable = False
-
-    for field in self.fields:
-        if not field.visible:
-            if not ((field.wire and not field.auto) or 'unserialize' == context):
-                continue
-
-        # switch/bitcase: fixed size fields must be considered explicitly 
-        if field.type.fixed_size():
-            if self.is_bitcase or self.var_followed_by_fixed_fields:
-                if prev_field_was_variable and need_padding:
-                    # insert padding
-#                    count += _c_serialize_helper_insert_padding(context, code_lines, space, 
-#                                                                self.var_followed_by_fixed_fields)
-                    prev_field_was_variable = False
-
-                # prefix for fixed size fields
-                fixed_prefix = prefix
-
-                value, length = _c_serialize_helper_fields_fixed_size(context, self, field, 
-                                                                      code_lines, temp_vars, 
-                                                                      space, fixed_prefix)
-            else:
-                continue
-
-        # fields with variable size
-        else:
-            # switch/bitcase: always calculate padding before and after variable sized fields
-            if need_padding or is_bitcase:
-                count += _c_serialize_helper_insert_padding(context, code_lines, space, 
-                                                            self.var_followed_by_fixed_fields)
-
-            value, length = _c_serialize_helper_fields_variable_size(context, self, field, 
-                                                                     code_lines, temp_vars, 
-                                                                     space, prefix)
-            prev_field_was_variable = True
-        
-        # save (un)serialization C code
-        if '' != value:
-            code_lines.append('%s%s' % (space, value))    
-        
-        if field.type.fixed_size():
-            if is_bitcase or self.var_followed_by_fixed_fields:
-                # keep track of (un)serialized object's size
-                code_lines.append('%s    xcb_block_len += %s;' % (space, length))
-                if context in ('unserialize', 'unpack', 'sizeof'):
-                    code_lines.append('%s    xcb_tmp += %s;' % (space, length))
-        else: 
-            # variable size objects or bitcase:
-            #   value & length might have been inserted earlier for special cases
-            if '' != length:
-                # special case: intermixed fixed and variable size fields
-                if (not field.type.fixed_size() and 
-                    self.var_followed_by_fixed_fields and 'unserialize' == context):
-                    temp_vars.append('    int %s_len;' % field.c_field_name)
-                    code_lines.append('%s    %s_len = %s;' % (space, field.c_field_name, length))
-                    code_lines.append('%s    xcb_block_len += %s_len;' % (space, field.c_field_name))
-                    code_lines.append('%s    xcb_tmp += %s_len;' % (space, field.c_field_name))
-                else:
-                    code_lines.append('%s    xcb_block_len += %s;' % (space, length))
-                    # increase pointer into the byte stream accordingly
-                    if context in ('unserialize', 'sizeof', 'unpack'):
-                        code_lines.append('%s    xcb_tmp += xcb_block_len;' % space)
-                        
-        if 'serialize' == context:
-            if '' != length:
-                code_lines.append('%s    xcb_parts[xcb_parts_idx].iov_len = %s;' % (space, length))
-            code_lines.append('%s    xcb_parts_idx++;' % space)
-            count += 1
-
-        code_lines.append('%s    xcb_align_to = ALIGNOF(%s);' % (space, 'char' if field.c_field_type == 'void' else field.c_field_type))
-
-        need_padding = True
-        if self.var_followed_by_fixed_fields:
-            need_padding = False
-        
-    return count
-# _c_serialize_helper_fields()    
-
-def _c_serialize_helper(context, complex_type, 
-                        code_lines, temp_vars, 
-                        space='', prefix=[]):
-    # count tracks the number of fields to serialize
-    count = 0
-
-    if hasattr(complex_type, 'type'):
-        self = complex_type.type
-        complex_name = complex_type.name
-    else:
-        self = complex_type
-        if self.var_followed_by_fixed_fields and 'unserialize' == context:
-            complex_name = 'xcb_out'
-        else:
-            complex_name = '_aux'
-    
-    # special case: switch is serialized by evaluating each bitcase separately
-    if self.is_switch:
-        count += _c_serialize_helper_switch(context, self, complex_name, 
-                                            code_lines, temp_vars, 
-                                            space, prefix)
-
-    # all other data types can be evaluated one field a time
-    else: 
-        # unserialize & fixed size fields: simply cast the buffer to the respective xcb_out type
-        if context in ('unserialize', 'unpack', 'sizeof') and not self.var_followed_by_fixed_fields:
-            code_lines.append('%s    xcb_block_len += sizeof(%s);' % (space, self.c_type))
-            code_lines.append('%s    xcb_tmp += xcb_block_len;' % space)
-            # probably not needed
-            #_c_serialize_helper_insert_padding(context, code_lines, space, False)
-
-        count += _c_serialize_helper_fields(context, self, 
-                                            code_lines, temp_vars, 
-                                            space, prefix, False)
-    # "final padding"
-    count += _c_serialize_helper_insert_padding(context, code_lines, space, False)
-
-    return count    
-# _c_serialize_helper()
-
-def _c_serialize(context, self):
-    """
-    depending on the context variable, generate _serialize(), _unserialize(), _unpack(), or _sizeof() 
-    for the ComplexType variable self
-    """
-    _h_setlevel(1)
-    _c_setlevel(1)
-
-    _hc('')
-    # _serialize() returns the buffer size
-    _hc('int')
-
-    if self.is_switch and 'unserialize' == context:
-        context = 'unpack'
-
-    cases = { 'serialize'   : self.c_serialize_name, 
-              'unserialize' : self.c_unserialize_name, 
-              'unpack'      : self.c_unpack_name, 
-              'sizeof'      : self.c_sizeof_name }
-    func_name = cases[context]
-            
-    param_fields, wire_fields, params = get_serialize_params(context, self)
-    variable_size_fields = 0
-    # maximum space required for type definition of function arguments
-    maxtypelen = 0
-
-    # determine N(variable_fields) 
-    for field in param_fields:
-        # if self.is_switch, treat all fields as if they are variable sized
-        if not field.type.fixed_size() or self.is_switch:
-            variable_size_fields += 1
-    # determine maxtypelen
-    for p in params:
-        maxtypelen = max(maxtypelen, len(p[0]) + len(p[1]))    
-
-    # write to .c/.h
-    indent = ' '*(len(func_name)+2)
-    param_str = []
-    for p in params:
-        typespec, pointerspec, field_name = p
-        spacing = ' '*(maxtypelen-len(typespec)-len(pointerspec))
-        param_str.append("%s%s%s  %s%s  /**< */" % (indent, typespec, spacing, pointerspec, field_name))
-    # insert function name
-    param_str[0] = "%s (%s" % (func_name, param_str[0].strip())
-    param_str = list(map(lambda x: "%s," % x, param_str))
-    for s in param_str[:-1]:
-        _hc(s)
-    _h("%s);" % param_str[-1].rstrip(','))
-    _c("%s)" % param_str[-1].rstrip(','))
-    _c('{')
-
-    code_lines = []
-    temp_vars = []
-    prefix = []
-
-    if 'serialize' == context:
-        if not self.is_switch and not self.var_followed_by_fixed_fields:
-            _c('    %s *xcb_out = *_buffer;', self.c_type)
-            _c('    unsigned int xcb_out_pad = -sizeof(%s) & 3;', self.c_type)
-            _c('    unsigned int xcb_buffer_len = sizeof(%s) + xcb_out_pad;', self.c_type)
-            _c('    unsigned int xcb_align_to;')
-        else:
-            _c('    char *xcb_out = *_buffer;')
-            _c('    unsigned int xcb_buffer_len = 0;')
-            _c('    unsigned int xcb_align_to;')
-        prefix = [('_aux', '->', self)]
-        aux_ptr = 'xcb_out'
-
-    elif context in ('unserialize', 'unpack'):
-        _c('    char *xcb_tmp = (char *)_buffer;')
-        if not self.is_switch:
-            if not self.var_followed_by_fixed_fields:
-                _c('    const %s *_aux = (%s *)_buffer;', self.c_type, self.c_type)
-                prefix = [('_aux', '->', self)]
-            else:
-                _c('    %s xcb_out;', self.c_type)
-                prefix = [('xcb_out', '.', self)]
-        else:
-            aux_var = '_aux' # default for unpack: single pointer
-            # note: unserialize not generated for switch
-            if 'unserialize' == context:
-                aux_var = '(*_aux)' # unserialize: double pointer (!)
-            prefix = [(aux_var, '->', self)]
-        aux_ptr = '*_aux'
-        _c('    unsigned int xcb_buffer_len = 0;')
-        _c('    unsigned int xcb_block_len = 0;')
-        _c('    unsigned int xcb_pad = 0;')
-        _c('    unsigned int xcb_align_to;')
-
-    elif 'sizeof' == context:
-        param_names = [p[2] for p in params]
-        if self.is_switch:
-            # switch: call _unpack()
-            _c('    %s _aux;', self.c_type)
-            _c('    return %s(%s, &_aux);', self.c_unpack_name, reduce(lambda x,y: "%s, %s" % (x, y), param_names))
-            _c('}')
-            return
-        elif self.var_followed_by_fixed_fields:
-            # special case: call _unserialize()
-            _c('    return %s(%s, NULL);', self.c_unserialize_name, reduce(lambda x,y: "%s, %s" % (x, y), param_names))
-            _c('}')
-            return
-        else:
-            _c('    char *xcb_tmp = (char *)_buffer;')
-            prefix = [('_aux', '->', self)]
-
-    count = _c_serialize_helper(context, self, code_lines, temp_vars, prefix=prefix)
-    # update variable size fields (only important for context=='serialize'
-    variable_size_fields = count
-    if 'serialize' == context:
-        temp_vars.append('    unsigned int xcb_pad = 0;')
-        temp_vars.append('    char xcb_pad0[3] = {0, 0, 0};') 
-        temp_vars.append('    struct iovec xcb_parts[%d];' % count)
-        temp_vars.append('    unsigned int xcb_parts_idx = 0;')
-        temp_vars.append('    unsigned int xcb_block_len = 0;')
-        temp_vars.append('    unsigned int i;')
-        temp_vars.append('    char *xcb_tmp;')
-    elif 'sizeof' == context:
-        # neither switch nor intermixed fixed and variable size fields:
-        # evaluate parameters directly
-        if not (self.is_switch or self.var_followed_by_fixed_fields):
-
-            # look if we have to declare an '_aux' variable at all
-            if len(list(filter(lambda x: x.find('_aux')!=-1, code_lines)))>0:
-                if not self.var_followed_by_fixed_fields:
-                    _c('    const %s *_aux = (%s *)_buffer;', self.c_type, self.c_type)
-                else:
-                    _c('    %s *_aux = malloc(sizeof(%s));', self.c_type, self.c_type)
-
-            _c('    unsigned int xcb_buffer_len = 0;')
-            _c('    unsigned int xcb_block_len = 0;')
-            _c('    unsigned int xcb_pad = 0;')        
-            _c('    unsigned int xcb_align_to;')
-
-    _c('')
-    for t in temp_vars:
-        _c(t)
-    _c('')
-    for l in code_lines:
-        _c(l)
-
-    # variable sized fields have been collected, now
-    # allocate memory and copy everything into a continuous memory area 
-    # note: this is not necessary in case of unpack
-    if context in ('serialize', 'unserialize'):
-        # unserialize: check for sizeof-only invocation
-        if 'unserialize' == context:
-            _c('')
-            _c('    if (NULL == _aux)')
-            _c('        return xcb_buffer_len;')
-
-        _c('')
-        _c('    if (NULL == %s) {', aux_ptr)
-        _c('        /* allocate memory */')
-        _c('        %s = malloc(xcb_buffer_len);', aux_ptr)
-        if 'serialize' == context:
-            _c('        *_buffer = xcb_out;')
-        _c('    }')
-        _c('')
-
-        # serialize: handle variable size fields in a loop
-        if 'serialize' == context:
-            if not self.is_switch and not self.var_followed_by_fixed_fields:
-                if len(wire_fields)>0:
-                    _c('    *xcb_out = *_aux;')
-            # copy variable size fields into the buffer
-            if variable_size_fields > 0:
-                # xcb_out padding
-                if not self.is_switch and not self.var_followed_by_fixed_fields:
-                    _c('    xcb_tmp = (char*)++xcb_out;')
-                    _c('    xcb_tmp += xcb_out_pad;')
-                else:
-                    _c('    xcb_tmp = xcb_out;')
-
-                # variable sized fields
-                _c('    for(i=0; i<xcb_parts_idx; i++) {')
-                _c('        if (0 != xcb_parts[i].iov_base && 0 != xcb_parts[i].iov_len)')
-                _c('            memcpy(xcb_tmp, xcb_parts[i].iov_base, xcb_parts[i].iov_len);')
-                _c('        if (0 != xcb_parts[i].iov_len)')
-                _c('            xcb_tmp += xcb_parts[i].iov_len;')
-                _c('    }')
-            
-        # unserialize: assign variable size fields individually
-        if 'unserialize' == context:
-            _c('    xcb_tmp = ((char *)*_aux)+xcb_buffer_len;')
-            param_fields.reverse()
-            for field in param_fields:
-                if not field.type.fixed_size():
-                    _c('    xcb_tmp -= %s_len;', field.c_field_name)
-                    _c('    memmove(xcb_tmp, %s, %s_len);', field.c_field_name, field.c_field_name)
-            _c('    *%s = xcb_out;', aux_ptr)
- 
-    _c('')
-    _c('    return xcb_buffer_len;')
-    _c('}')
-# _c_serialize()
-
-def _c_iterator_get_end(field, accum):
-    '''
-    Figures out what C code is needed to find the end of a variable-length structure field.
-    For nested structures, recurses into its last variable-sized field.
-    For lists, calls the end function
-    '''
-    if field.type.is_container:
-        accum = field.c_accessor_name + '(' + accum + ')'
-        return _c_iterator_get_end(field.type.last_varsized_field, accum)
-    if field.type.is_list:
-        # XXX we can always use the first way
-        if field.type.member.is_simple:
-            return field.c_end_name + '(' + accum + ')'
-        else:
-            return field.type.member.c_end_name + '(' + field.c_iterator_name + '(' + accum + '))'
-
-def _c_iterator(self, name):
-    '''
-    Declares the iterator structure and next/end functions for a given type.
-    '''
-    _h_setlevel(0)
-    _h('')
-    _h('/**')
-    _h(' * @brief %s', self.c_iterator_type)
-    _h(' **/')
-    _h('typedef struct %s {', self.c_iterator_type)
-    _h('    %s *data; /**<  */', self.c_type)
-    _h('    int%s rem; /**<  */', ' ' * (len(self.c_type) - 2))
-    _h('    int%s index; /**<  */', ' ' * (len(self.c_type) - 2))
-    _h('} %s;', self.c_iterator_type)
-
-    _h_setlevel(1)
-    _c_setlevel(1)
-    _h('')
-    _h('/**')
-    _h(' * Get the next element of the iterator')
-    _h(' * @param i Pointer to a %s', self.c_iterator_type)
-    _h(' *')
-    _h(' * Get the next element in the iterator. The member rem is')
-    _h(' * decreased by one. The member data points to the next')
-    _h(' * element. The member index is increased by sizeof(%s)', self.c_type)
-    _h(' */')
-    _c('')
-    _hc('')
-    _hc('/*****************************************************************************')
-    _hc(' **')
-    _hc(' ** void %s', self.c_next_name)
-    _hc(' ** ')
-    _hc(' ** @param %s *i', self.c_iterator_type)
-    _hc(' ** @returns void')
-    _hc(' **')
-    _hc(' *****************************************************************************/')
-    _hc(' ')
-    _hc('void')
-    _h('%s (%s *i  /**< */);', self.c_next_name, self.c_iterator_type)
-    _c('%s (%s *i  /**< */)', self.c_next_name, self.c_iterator_type)
-    _c('{')
-
-    if not self.fixed_size():
-        _c('    %s *R = i->data;', self.c_type)
-
-        if self.is_union:
-            # FIXME - how to determine the size of a variable size union??
-            _c('    /* FIXME - determine the size of the union %s */', self.c_type)            
-        else:
-            if self.need_sizeof:
-                _c('    xcb_generic_iterator_t child;')
-                _c('    child.data = (%s *)(((char *)R) + %s(R));', 
-                   self.c_type, self.c_sizeof_name)
-                _c('    i->index = (char *) child.data - (char *) i->data;')
-            else:
-                _c('    xcb_generic_iterator_t child = %s;', _c_iterator_get_end(self.last_varsized_field, 'R'))
-                _c('    i->index = child.index;')
-            _c('    --i->rem;')
-            _c('    i->data = (%s *) child.data;', self.c_type)
-
-    else:
-        _c('    --i->rem;')
-        _c('    ++i->data;')
-        _c('    i->index += sizeof(%s);', self.c_type)
-
-    _c('}')
-
-    _h('')
-    _h('/**')
-    _h(' * Return the iterator pointing to the last element')
-    _h(' * @param i An %s', self.c_iterator_type)
-    _h(' * @return  The iterator pointing to the last element')
-    _h(' *')
-    _h(' * Set the current element in the iterator to the last element.')
-    _h(' * The member rem is set to 0. The member data points to the')
-    _h(' * last element.')
-    _h(' */')
-    _c('')
-    _hc('')
-    _hc('/*****************************************************************************')
-    _hc(' **')
-    _hc(' ** xcb_generic_iterator_t %s', self.c_end_name)
-    _hc(' ** ')
-    _hc(' ** @param %s i', self.c_iterator_type)
-    _hc(' ** @returns xcb_generic_iterator_t')
-    _hc(' **')
-    _hc(' *****************************************************************************/')
-    _hc(' ')
-    _hc('xcb_generic_iterator_t')
-    _h('%s (%s i  /**< */);', self.c_end_name, self.c_iterator_type)
-    _c('%s (%s i  /**< */)', self.c_end_name, self.c_iterator_type)
-    _c('{')
-    _c('    xcb_generic_iterator_t ret;')
-
-    if self.fixed_size():
-        _c('    ret.data = i.data + i.rem;')
-        _c('    ret.index = i.index + ((char *) ret.data - (char *) i.data);')
-        _c('    ret.rem = 0;')
-    else:
-        _c('    while(i.rem > 0)')
-        _c('        %s(&i);', self.c_next_name)
-        _c('    ret.data = i.data;')
-        _c('    ret.rem = i.rem;')
-        _c('    ret.index = i.index;')
-
-    _c('    return ret;')
-    _c('}')
-
-def _c_accessor_get_length(expr, field_mapping=None):
-    '''
-    Figures out what C code is needed to get a length field.
-    The field_mapping parameter can be used to change the absolute name of a length field. 
-    For fields that follow a variable-length field, use the accessor.
-    Otherwise, just reference the structure field directly.
-    '''
-
-    lenfield_name = expr.lenfield_name
-    if lenfield_name is not None:
-        if field_mapping is not None:
-            lenfield_name = field_mapping[lenfield_name][0]
- 
-    if expr.lenfield is not None and expr.lenfield.prev_varsized_field is not None:
-        # special case: variable and fixed size fields are intermixed
-        # if the lenfield is among the fixed size fields, there is no need
-        # to call a special accessor function like <expr.lenfield.c_accessor_name + '(' + prefix + ')'>
-        return field_mapping(expr.lenfield_name)
-    elif expr.lenfield_name is not None:
-        return lenfield_name
-    else:
-        return str(expr.nmemb)
-
-def _c_accessor_get_expr(expr, field_mapping):
-    '''
-    Figures out what C code is needed to get the length of a list field.
-    The field_mapping parameter can be used to change the absolute name of a length field. 
-    Recurses for math operations.
-    Returns bitcount for value-mask fields.
-    Otherwise, uses the value of the length field.
-    '''
-    lenexp = _c_accessor_get_length(expr, field_mapping)
-
-    if expr.op == '~':
-        return '(' + '~' + _c_accessor_get_expr(expr.rhs, field_mapping) + ')'
-    elif expr.op == 'popcount':
-        return 'xcb_popcount(' + _c_accessor_get_expr(expr.rhs, field_mapping) + ')'
-    elif expr.op == 'enumref':
-        enum_name = expr.lenfield_type.name
-        constant_name = expr.lenfield_name
-        c_name = _n(enum_name + (constant_name,)).upper()
-        return c_name
-    elif expr.op == 'sumof':
-        # locate the referenced list object
-        list_obj = expr.lenfield_type
-        field = None
-        for f in expr.lenfield_parent.fields:
-            if f.field_name == expr.lenfield_name:
-                field = f
-                break
-
-        if field is None:
-            raise Exception("list field '%s' referenced by sumof not found" % expr.lenfield_name)
-        list_name = field_mapping[field.c_field_name][0]
-        c_length_func = "%s(%s)" % (field.c_length_name, list_name)
-        # note: xcb_sumof() has only been defined for integers
-        c_length_func = _c_accessor_get_expr(field.type.expr, field_mapping)
-        return 'xcb_sumof(%s, %s)' % (list_name, c_length_func)
-    elif expr.op != None:
-        return ('(' + _c_accessor_get_expr(expr.lhs, field_mapping) + 
-                ' ' + expr.op + ' ' + 
-                _c_accessor_get_expr(expr.rhs, field_mapping) + ')')
-    elif expr.bitfield:
-        return 'xcb_popcount(' + lenexp + ')'
-    else:
-        return lenexp
-
-def type_pad_type(type):
-    if type == 'void':
-        return 'char'
-    return type
-
-def _c_accessors_field(self, field):
-    '''
-    Declares the accessor functions for a non-list field that follows a variable-length field.
-    '''
-    c_type = self.c_type
-
-    # special case: switch
-    switch_obj = self if self.is_switch else None
-    if self.is_bitcase:
-        switch_obj = self.parents[-1]
-    if switch_obj is not None:
-        c_type = switch_obj.c_type
-
-    if field.type.is_simple:
-        _hc('')
-        _hc('')
-        _hc('/*****************************************************************************')
-        _hc(' ** ')
-        _hc(' ** %s %s', field.c_field_type, field.c_accessor_name)
-        _hc(' ** ')
-        _hc(' ** @param const %s *R', c_type)
-        _hc(' ** @returns %s', field.c_field_type)
-        _hc(' **')
-        _hc(' *****************************************************************************/')
-        _hc(' ')
-        _hc('%s', field.c_field_type)
-        _h('%s (const %s *R  /**< */);', field.c_accessor_name, c_type)
-        _c('%s (const %s *R  /**< */)', field.c_accessor_name, c_type)
-        _c('{')
-        if field.prev_varsized_field is None:
-            _c('    return (%s *) (R + 1);', field.c_field_type)
-        else:
-            _c('    xcb_generic_iterator_t prev = %s;', _c_iterator_get_end(field.prev_varsized_field, 'R'))
-            _c('    return * (%s *) ((char *) prev.data + XCB_TYPE_PAD(%s, prev.index) + %d);', 
-               field.c_field_type, type_pad_type(field.first_field_after_varsized.type.c_type), field.prev_varsized_offset)
-        _c('}')
-    else:
-        _hc('')
-        _hc('')
-        _hc('/*****************************************************************************')
-        _hc(' **')
-        _hc(' ** %s * %s', field.c_field_type, field.c_accessor_name)
-        _hc(' ** ')
-        _hc(' ** @param const %s *R', c_type)
-        _hc(' ** @returns %s *', field.c_field_type)
-        _hc(' **')
-        _hc(' *****************************************************************************/')
-        _hc(' ')
-        if field.type.is_switch and switch_obj is None:
-            return_type = 'void *'
-        else:
-            return_type = '%s *' % field.c_field_type
-
-        _hc(return_type)
-        _h('%s (const %s *R  /**< */);', field.c_accessor_name, c_type)
-        _c('%s (const %s *R  /**< */)', field.c_accessor_name, c_type)
-        _c('{')
-        if field.prev_varsized_field is None:
-            _c('    return (%s) (R + 1);', return_type)
-            # note: the special case 'variable fields followed by fixed size fields'
-            #       is not of any consequence here, since the ordering gets 
-            #       'corrected' in the reply function
-        else:
-            _c('    xcb_generic_iterator_t prev = %s;', _c_iterator_get_end(field.prev_varsized_field, 'R'))
-            _c('    return (%s) ((char *) prev.data + XCB_TYPE_PAD(%s, prev.index) + %d);', 
-               return_type, type_pad_type(field.first_field_after_varsized.type.c_type), field.prev_varsized_offset)
-        _c('}')
-
-    
-def _c_accessors_list(self, field):
-    '''
-    Declares the accessor functions for a list field.
-    Declares a direct-accessor function only if the list members are fixed size.
-    Declares length and get-iterator functions always.
-    '''
-    list = field.type
-    c_type = self.c_type
-
-    # special case: switch
-    # in case of switch, 2 params have to be supplied to certain accessor functions:
-    #   1. the anchestor object (request or reply)
-    #   2. the (anchestor) switch object
-    # the reason is that switch is either a child of a request/reply or nested in another switch, 
-    # so whenever we need to access a length field, we might need to refer to some anchestor type
-    switch_obj = self if self.is_switch else None
-    if self.is_bitcase:
-        switch_obj = self.parents[-1]
-    if switch_obj is not None:
-        c_type = switch_obj.c_type
-
-    params = []
-    fields = {}
-    parents = self.parents if hasattr(self, 'parents') else [self]
-    # 'R': parents[0] is always the 'toplevel' container type 
-    params.append(('const %s *R' % parents[0].c_type, parents[0]))
-    fields.update(_c_helper_field_mapping(parents[0], [('R', '->', parents[0])], flat=True))
-    # auxiliary object for 'R' parameters
-    R_obj = parents[0]
-
-    if switch_obj is not None:
-        # now look where the fields are defined that are needed to evaluate 
-        # the switch expr, and store the parent objects in accessor_params and
-        # the fields in switch_fields
-
-        # 'S': name for the 'toplevel' switch
-        toplevel_switch = parents[1]
-        params.append(('const %s *S' % toplevel_switch.c_type, toplevel_switch))
-        fields.update(_c_helper_field_mapping(toplevel_switch, [('S', '->', toplevel_switch)], flat=True))
-
-        # initialize prefix for everything "below" S
-        prefix_str = '/* %s */ S' % toplevel_switch.name[-1]
-        prefix = [(prefix_str, '->', toplevel_switch)]
-
-        # look for fields in the remaining containers
-        for p in parents[2:] + [self]:
-            # the separator between parent and child is always '.' here, 
-            # because of nested switch statements
-            if not p.is_bitcase or (p.is_bitcase and p.has_name):
-                prefix.append((p.name[-1], '.', p))
-            fields.update(_c_helper_field_mapping(p, prefix, flat=True))
-
-        # auxiliary object for 'S' parameter
-        S_obj = parents[1]
-
-    _h_setlevel(1)
-    _c_setlevel(1)
-    if list.member.fixed_size():
-        idx = 1 if switch_obj is not None else 0
-        _hc('')
-        _hc('')
-        _hc('/*****************************************************************************')
-        _hc(' **')
-        _hc(' ** %s * %s', field.c_field_type, field.c_accessor_name)
-        _hc(' ** ')
-        _hc(' ** @param %s', params[idx][0])
-        _hc(' ** @returns %s *', field.c_field_type)
-        _hc(' **')
-        _hc(' *****************************************************************************/')
-        _hc(' ')
-        _hc('%s *', field.c_field_type)
-
-        _h('%s (%s  /**< */);', field.c_accessor_name, params[idx][0])
-        _c('%s (%s  /**< */)', field.c_accessor_name, params[idx][0])
-
-        _c('{')
-        if switch_obj is not None:
-            _c('    return %s;', fields[field.c_field_name][0])
-        elif field.prev_varsized_field is None:
-            _c('    return (%s *) (R + 1);', field.c_field_type)
-        else:
-            _c('    xcb_generic_iterator_t prev = %s;', _c_iterator_get_end(field.prev_varsized_field, 'R'))
-            _c('    return (%s *) ((char *) prev.data + XCB_TYPE_PAD(%s, prev.index) + %d);', 
-               field.c_field_type, type_pad_type(field.first_field_after_varsized.type.c_type), field.prev_varsized_offset)
-        _c('}')
-
-    _hc('')
-    _hc('')
-    _hc('/*****************************************************************************')
-    _hc(' **')
-    _hc(' ** int %s', field.c_length_name)
-    _hc(' ** ')
-    _hc(' ** @param const %s *R', c_type)
-    _hc(' ** @returns int')
-    _hc(' **')
-    _hc(' *****************************************************************************/')
-    _hc(' ')
-    _hc('int')
-    if switch_obj is not None:
-        _hc('%s (const %s *R  /**< */,', field.c_length_name, R_obj.c_type)
-        spacing = ' '*(len(field.c_length_name)+2)
-        _h('%sconst %s *S /**< */);', spacing, S_obj.c_type)
-        _c('%sconst %s *S  /**< */)', spacing, S_obj.c_type)
-        length = _c_accessor_get_expr(field.type.expr, fields)
-    else:
-        _h('%s (const %s *R  /**< */);', field.c_length_name, c_type)
-        _c('%s (const %s *R  /**< */)', field.c_length_name, c_type)
-        length = _c_accessor_get_expr(field.type.expr, fields)
-    _c('{')
-    _c('    return %s;', length)
-    _c('}')
-
-    if field.type.member.is_simple:
-        _hc('')
-        _hc('')
-        _hc('/*****************************************************************************')
-        _hc(' **')
-        _hc(' ** xcb_generic_iterator_t %s', field.c_end_name)
-        _hc(' ** ')
-        _hc(' ** @param const %s *R', c_type)
-        _hc(' ** @returns xcb_generic_iterator_t')
-        _hc(' **')
-        _hc(' *****************************************************************************/')
-        _hc(' ')
-        _hc('xcb_generic_iterator_t')
-        if switch_obj is not None:
-            _hc('%s (const %s *R  /**< */,', field.c_end_name, R_obj.c_type)
-            spacing = ' '*(len(field.c_end_name)+2)
-            _h('%sconst %s *S /**< */);', spacing, S_obj.c_type)
-            _c('%sconst %s *S  /**< */)', spacing, S_obj.c_type)
-        else:
-            _h('%s (const %s *R  /**< */);', field.c_end_name, c_type)
-            _c('%s (const %s *R  /**< */)', field.c_end_name, c_type)
-        _c('{')
-        _c('    xcb_generic_iterator_t i;')
-        
-        param = 'R' if switch_obj is None else 'S'
-        if switch_obj is not None:
-            _c('    i.data = %s + %s;', fields[field.c_field_name][0], 
-               _c_accessor_get_expr(field.type.expr, fields))
-        elif field.prev_varsized_field == None:
-            _c('    i.data = ((%s *) (R + 1)) + (%s);', field.type.c_wiretype, 
-               _c_accessor_get_expr(field.type.expr, fields))
-        else:
-            _c('    xcb_generic_iterator_t child = %s;', 
-               _c_iterator_get_end(field.prev_varsized_field, 'R'))
-            _c('    i.data = ((%s *) child.data) + (%s);', field.type.c_wiretype, 
-               _c_accessor_get_expr(field.type.expr, fields))
-
-        _c('    i.rem = 0;')
-        _c('    i.index = (char *) i.data - (char *) %s;', param)
-        _c('    return i;')
-        _c('}')
-
-    else:
-        _hc('')
-        _hc('')
-        _hc('/*****************************************************************************')
-        _hc(' **')
-        _hc(' ** %s %s', field.c_iterator_type, field.c_iterator_name)
-        _hc(' ** ')
-        _hc(' ** @param const %s *R', c_type)
-        _hc(' ** @returns %s', field.c_iterator_type)
-        _hc(' **')
-        _hc(' *****************************************************************************/')
-        _hc(' ')
-
-        _hc('%s', field.c_iterator_type)
-        if switch_obj is not None:
-            _hc('%s (const %s *R  /**< */,', field.c_iterator_name, R_obj.c_type)
-            spacing = ' '*(len(field.c_iterator_name)+2)
-            _h('%sconst %s *S /**< */);', spacing, S_obj.c_type)
-            _c('%sconst %s *S  /**< */)', spacing, S_obj.c_type)
-        else:
-            _h('%s (const %s *R  /**< */);', field.c_iterator_name, c_type)
-            _c('%s (const %s *R  /**< */)', field.c_iterator_name, c_type)
-        _c('{')
-        _c('    %s i;', field.c_iterator_type)
-
-        if switch_obj is not None:
-            _c('    i.data = %s;', fields[field.c_field_name][0])
-            _c('    i.rem = %s;', _c_accessor_get_expr(field.type.expr, fields))
-        elif field.prev_varsized_field == None:
-            _c('    i.data = (%s *) (R + 1);', field.c_field_type)
-        else:
-            _c('    xcb_generic_iterator_t prev = %s;', _c_iterator_get_end(field.prev_varsized_field, 'R'))
-            _c('    i.data = (%s *) ((char *) prev.data + XCB_TYPE_PAD(%s, prev.index));', 
-               field.c_field_type, type_pad_type(field.c_field_type))
-        if switch_obj is None:
-            _c('    i.rem = %s;', _c_accessor_get_expr(field.type.expr, fields))
-        _c('    i.index = (char *) i.data - (char *) %s;', 'R' if switch_obj is None else 'S' )
-        _c('    return i;')
-        _c('}')
-
-def _c_accessors(self, name, base):
-    '''
-    Declares the accessor functions for the fields of a structure.
-    '''
-    # no accessors for switch itself - 
-    # switch always needs to be unpacked explicitly
-#    if self.is_switch:
-#        pass
-#    else:
-    if True:
-        for field in self.fields:
-            if field.type.is_list and not field.type.fixed_size():
-                _c_accessors_list(self, field)
-            elif field.prev_varsized_field is not None or not field.type.fixed_size():
-                _c_accessors_field(self, field)
-
-def c_simple(self, name):
-    '''
-    Exported function that handles cardinal type declarations.
-    These are types which are typedef'd to one of the CARDx's, char, float, etc.
-    '''
-    _c_type_setup(self, name, ())
-
-    if (self.name != name):
-        # Typedef
-        _h_setlevel(0)
-        my_name = _t(name)
-        _h('')
-        _h('typedef %s %s;', _t(self.name), my_name)
-
-        # Iterator
-        _c_iterator(self, name)
-
-def _c_complex(self):
-    '''
-    Helper function for handling all structure types.
-    Called for all structs, requests, replies, events, errors.
-    '''
-    _h_setlevel(0)
-    _h('')
-    _h('/**')
-    _h(' * @brief %s', self.c_type)
-    _h(' **/')
-    _h('typedef %s %s {', self.c_container, self.c_type)
-
-    struct_fields = []
-    maxtypelen = 0
-
-    varfield = None
-    for field in self.fields:
-        if not field.type.fixed_size() and not self.is_switch and not self.is_union:
-            varfield = field.c_field_name
-            continue
-        if field.wire:
-            struct_fields.append(field)
-    
-    for field in struct_fields:
-        length = len(field.c_field_type)
-        # account for '*' pointer_spec
-        if not field.type.fixed_size():
-            length += 1
-        maxtypelen = max(maxtypelen, length)
-
-    def _c_complex_field(self, field, space=''):
-        if (field.type.fixed_size() or 
-            # in case of switch with switch children, don't make the field a pointer
-            # necessary for unserialize to work
-            (self.is_switch and field.type.is_switch)):
-            spacing = ' ' * (maxtypelen - len(field.c_field_type))
-            _h('%s    %s%s %s%s; /**<  */', space, field.c_field_type, spacing, field.c_field_name, field.c_subscript)
-        else:
-            spacing = ' ' * (maxtypelen - (len(field.c_field_type) + 1))
-            _h('%s    %s%s *%s%s; /**<  */', space, field.c_field_type, spacing, field.c_field_name, field.c_subscript)
-
-    if not self.is_switch:
-        for field in struct_fields:
-            _c_complex_field(self, field)
-    else:
-        for b in self.bitcases:
-            space = ''
-            if b.type.has_name:
-                _h('    struct _%s {', b.c_field_name)
-                space = '    '
-            for field in b.type.fields:
-                _c_complex_field(self, field, space)
-            if b.type.has_name:
-                _h('    } %s;', b.c_field_name)
-
-    _h('} %s;', self.c_type)
-
-def c_struct(self, name):
-    '''
-    Exported function that handles structure declarations.
-    '''
-    _c_type_setup(self, name, ())
-    _c_complex(self)
-    _c_accessors(self, name, name)
-    _c_iterator(self, name)
-
-def c_union(self, name):
-    '''
-    Exported function that handles union declarations.
-    '''
-    _c_type_setup(self, name, ())
-    _c_complex(self)
-    _c_iterator(self, name)
-
-def _c_request_helper(self, name, cookie_type, void, regular, aux=False):
-    '''
-    Declares a request function.
-    '''
-
-    # Four stunningly confusing possibilities here:
-    #
-    #   Void            Non-void
-    # ------------------------------
-    # "req"            "req"
-    # 0 flag           CHECKED flag   Normal Mode
-    # void_cookie      req_cookie
-    # ------------------------------
-    # "req_checked"    "req_unchecked"
-    # CHECKED flag     0 flag         Abnormal Mode
-    # void_cookie      req_cookie
-    # ------------------------------
-
-
-    # Whether we are _checked or _unchecked
-    checked = void and not regular
-    unchecked = not void and not regular
-
-    # What kind of cookie we return
-    func_cookie = 'xcb_void_cookie_t' if void else self.c_cookie_type
-
-    # What flag is passed to xcb_request
-    func_flags = '0' if (void and regular) or (not void and not regular) else 'XCB_REQUEST_CHECKED'
-
-    # Global extension id variable or NULL for xproto
-    func_ext_global = '&' + _ns.c_ext_global_name if _ns.is_ext else '0'
-
-    # What our function name is
-    func_name = self.c_request_name if not aux else self.c_aux_name
-    if checked:
-        func_name = self.c_checked_name if not aux else self.c_aux_checked_name
-    if unchecked:
-        func_name = self.c_unchecked_name if not aux else self.c_aux_unchecked_name
-
-    param_fields = []
-    wire_fields = []
-    maxtypelen = len('xcb_connection_t')
-    serial_fields = []
-    # special case: list with variable size elements
-    list_with_var_size_elems = False
-
-    for field in self.fields:
-        if field.visible:
-            # The field should appear as a call parameter
-            param_fields.append(field)
-        if field.wire and not field.auto:
-            # We need to set the field up in the structure
-            wire_fields.append(field)
-        if field.type.need_serialize or field.type.need_sizeof:
-            serial_fields.append(field)
-        
-    for field in param_fields:
-        c_field_const_type = field.c_field_const_type 
-        if field.type.need_serialize and not aux:
-            c_field_const_type = "const void"
-        if len(c_field_const_type) > maxtypelen:
-            maxtypelen = len(c_field_const_type)
-        if field.type.is_list and not field.type.member.fixed_size():
-            list_with_var_size_elems = True
-
-    _h_setlevel(1)
-    _c_setlevel(1)
-    _h('')
-    _h('/**')
-    _h(' * Delivers a request to the X server')
-    _h(' * @param c The connection')
-    _h(' * @return A cookie')
-    _h(' *')
-    _h(' * Delivers a request to the X server.')
-    _h(' * ')
-    if checked:
-        _h(' * This form can be used only if the request will not cause')
-        _h(' * a reply to be generated. Any returned error will be')
-        _h(' * saved for handling by xcb_request_check().')
-    if unchecked:
-        _h(' * This form can be used only if the request will cause')
-        _h(' * a reply to be generated. Any returned error will be')
-        _h(' * placed in the event queue.')
-    _h(' */')
-    _c('')
-    _hc('')
-    _hc('/*****************************************************************************')
-    _hc(' **')
-    _hc(' ** %s %s', cookie_type, func_name)
-    _hc(' ** ')
-
-    spacing = ' ' * (maxtypelen - len('xcb_connection_t'))
-    _hc(' ** @param xcb_connection_t%s *c', spacing)
-
-    for field in param_fields:
-        c_field_const_type = field.c_field_const_type 
-        if field.type.need_serialize and not aux:
-            c_field_const_type = "const void"
-        spacing = ' ' * (maxtypelen - len(c_field_const_type))
-        _hc(' ** @param %s%s %s%s', c_field_const_type, spacing, field.c_pointer, field.c_field_name)
-
-    _hc(' ** @returns %s', cookie_type)
-    _hc(' **')
-    _hc(' *****************************************************************************/')
-    _hc(' ')
-    _hc('%s', cookie_type)
-
-    spacing = ' ' * (maxtypelen - len('xcb_connection_t'))
-    comma = ',' if len(param_fields) else ');'
-    _h('%s (xcb_connection_t%s *c  /**< */%s', func_name, spacing, comma)
-    comma = ',' if len(param_fields) else ')'
-    _c('%s (xcb_connection_t%s *c  /**< */%s', func_name, spacing, comma)
-
-    func_spacing = ' ' * (len(func_name) + 2)
-    count = len(param_fields)
-    for field in param_fields:
-        count = count - 1
-        c_field_const_type = field.c_field_const_type 
-        c_pointer = field.c_pointer
-        if field.type.need_serialize and not aux:
-            c_field_const_type = "const void"
-            c_pointer = '*'
-        spacing = ' ' * (maxtypelen - len(c_field_const_type))
-        comma = ',' if count else ');'
-        _h('%s%s%s %s%s  /**< */%s', func_spacing, c_field_const_type, 
-           spacing, c_pointer, field.c_field_name, comma)
-        comma = ',' if count else ')'
-        _c('%s%s%s %s%s  /**< */%s', func_spacing, c_field_const_type, 
-           spacing, c_pointer, field.c_field_name, comma)
-
-    count = 2
-    if not self.var_followed_by_fixed_fields:
-        for field in param_fields:
-            if not field.type.fixed_size():
-                count = count + 2
-                if field.type.need_serialize:
-                    # _serialize() keeps track of padding automatically
-                    count -= 1
-    dimension = count + 2
-
-    _c('{')
-    _c('    static const xcb_protocol_request_t xcb_req = {')
-    _c('        /* count */ %d,', count)
-    _c('        /* ext */ %s,', func_ext_global)
-    _c('        /* opcode */ %s,', self.c_request_name.upper())
-    _c('        /* isvoid */ %d', 1 if void else 0)
-    _c('    };')
-    _c('    ')
-
-    _c('    struct iovec xcb_parts[%d];', dimension)
-    _c('    %s xcb_ret;', func_cookie)
-    _c('    %s xcb_out;', self.c_type)
-    if self.var_followed_by_fixed_fields:
-        _c('    /* in the protocol description, variable size fields are followed by fixed size fields */')
-        _c('    void *xcb_aux = 0;')
-        
-
-    for idx, f in enumerate(serial_fields):
-        if aux:
-            _c('    void *xcb_aux%d = 0;' % (idx))
-    if list_with_var_size_elems:
-        _c('    unsigned int i;')
-        _c('    unsigned int xcb_tmp_len;')
-        _c('    char *xcb_tmp;')
-    _c('    ')
-    # simple request call tracing
-#    _c('    printf("in function %s\\n");' % func_name)     
- 
-    # fixed size fields
-    for field in wire_fields:
-        if field.type.fixed_size():
-            if field.type.is_expr:
-                _c('    xcb_out.%s = %s;', field.c_field_name, _c_accessor_get_expr(field.type.expr, None))
-            elif field.type.is_pad:
-                if field.type.nmemb == 1:
-                    _c('    xcb_out.%s = 0;', field.c_field_name)
-                else:
-                    _c('    memset(xcb_out.%s, 0, %d);', field.c_field_name, field.type.nmemb)
-            else:
-                if field.type.nmemb == 1:
-                    _c('    xcb_out.%s = %s;', field.c_field_name, field.c_field_name)
-                else:
-                    _c('    memcpy(xcb_out.%s, %s, %d);', field.c_field_name, field.c_field_name, field.type.nmemb)
-
-    def get_serialize_args(type_obj, c_field_name, aux_var, context='serialize'):
-        serialize_args = get_serialize_params(context, type_obj, 
-                                              c_field_name, 
-                                              aux_var)[2]
-        return reduce(lambda x,y: "%s, %s" % (x,y), [a[2] for a in serialize_args])
-
-    # calls in order to free dyn. all. memory
-    free_calls = []
-
-    _c('    ')
-    if not self.var_followed_by_fixed_fields:
-        _c('    xcb_parts[2].iov_base = (char *) &xcb_out;')
-        _c('    xcb_parts[2].iov_len = sizeof(xcb_out);')
-        _c('    xcb_parts[3].iov_base = 0;')
-        _c('    xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;')
-
-        count = 4
-
-        for field in param_fields:
-            if not field.type.fixed_size():
-                _c('    /* %s %s */', field.type.c_type, field.c_field_name)
-                # default: simple cast to char *
-                if not field.type.need_serialize and not field.type.need_sizeof:
-                    _c('    xcb_parts[%d].iov_base = (char *) %s;', count, field.c_field_name)
-                    if field.type.is_list:
-                        if field.type.member.fixed_size():
-                            _c('    xcb_parts[%d].iov_len = %s * sizeof(%s);', count, 
-                               _c_accessor_get_expr(field.type.expr, None), 
-                               field.type.member.c_wiretype)
-                        else:
-                            list_length = _c_accessor_get_expr(field.type.expr, None)
-    
-                            length = ''
-                            _c("    xcb_parts[%d].iov_len = 0;" % count)
-                            _c("    xcb_tmp = (char *)%s;", field.c_field_name)
-                            _c("    for(i=0; i<%s; i++) {" % list_length)
-                            _c("        xcb_tmp_len = %s(xcb_tmp);" % 
-                                              (field.type.c_sizeof_name))
-                            _c("        xcb_parts[%d].iov_len += xcb_tmp_len;" % count)
-                            _c("        xcb_tmp += xcb_tmp_len;")
-                            _c("    }")                        
-                    else:
-                        # not supposed to happen
-                        raise Exception("unhandled variable size field %s" % field.c_field_name)
-                else:
-                    if not aux:
-                        _c('    xcb_parts[%d].iov_base = (char *) %s;', count, field.c_field_name)
-                    idx = serial_fields.index(field)
-                    aux_var = '&xcb_aux%d' % idx
-                    context = 'serialize' if aux else 'sizeof'
-                    _c('    xcb_parts[%d].iov_len = ', count)
-                    if aux:
-                        serialize_args = get_serialize_args(field.type, aux_var, field.c_field_name, context)
-                        _c('      %s (%s);', field.type.c_serialize_name, serialize_args)
-                        _c('    xcb_parts[%d].iov_base = xcb_aux%d;' % (count, idx))
-                        free_calls.append('    free(xcb_aux%d);' % idx)
-                    else:
-                        serialize_args = get_serialize_args(field.type, field.c_field_name, aux_var, context)
-                        func_name = field.type.c_sizeof_name
-                        _c('      %s (%s);', func_name, serialize_args)
-
-                count += 1
-                if not (field.type.need_serialize or field.type.need_sizeof):
-                    # the _serialize() function keeps track of padding automatically
-                    _c('    xcb_parts[%d].iov_base = 0;', count)
-                    _c('    xcb_parts[%d].iov_len = -xcb_parts[%d].iov_len & 3;', count, count-1)
-                    count += 1
-
-    # elif self.var_followed_by_fixed_fields:
-    else:
-        _c('    xcb_parts[2].iov_base = (char *) &xcb_out;')
-        # request header: opcodes + length
-        _c('    xcb_parts[2].iov_len = 2*sizeof(uint8_t) + sizeof(uint16_t);') 
-        count += 1
-        # call _serialize()
-        buffer_var = '&xcb_aux'
-        serialize_args = get_serialize_args(self, buffer_var, '&xcb_out', 'serialize')
-        _c('    xcb_parts[%d].iov_len = %s (%s);', count, self.c_serialize_name, serialize_args)
-        _c('    xcb_parts[%d].iov_base = (char *) xcb_aux;', count)
-        free_calls.append('    free(xcb_aux);')
-        # no padding necessary - _serialize() keeps track of padding automatically
-
-    _c('    ')
-    _c('    xcb_ret.sequence = xcb_send_request(c, %s, xcb_parts + 2, &xcb_req);', func_flags)
-    
-    # free dyn. all. data, if any
-    for f in free_calls:
-        _c(f)
-    _c('    return xcb_ret;')
-    _c('}')
-
-def _c_reply(self, name):
-    '''
-    Declares the function that returns the reply structure.
-    '''
-    spacing1 = ' ' * (len(self.c_cookie_type) - len('xcb_connection_t'))
-    spacing2 = ' ' * (len(self.c_cookie_type) - len('xcb_generic_error_t'))
-    spacing3 = ' ' * (len(self.c_reply_name) + 2)
-    
-    # check if _unserialize() has to be called for any field
-    def look_for_special_cases(complex_obj):
-        unserialize_fields = []
-        # no unserialize call in case of switch
-        if not complex_obj.is_switch:
-            for field in complex_obj.fields:
-                # three cases: 1. field with special case
-                #              2. container that contains special case field
-                #              3. list with special case elements
-                if field.type.var_followed_by_fixed_fields:
-                    unserialize_fields.append(field)
-                elif field.type.is_container:
-                    unserialize_fields += look_for_special_cases(field.type)
-                elif field.type.is_list:
-                    if field.type.member.var_followed_by_fixed_fields:
-                        unserialize_fields.append(field)
-                    if field.type.member.is_container:
-                        unserialize_fields += look_for_special_cases(field.type.member)
-        return unserialize_fields
-    
-    unserialize_fields = look_for_special_cases(self.reply)
-    
-    _h('')
-    _h('/**')
-    _h(' * Return the reply')
-    _h(' * @param c      The connection')
-    _h(' * @param cookie The cookie')
-    _h(' * @param e      The xcb_generic_error_t supplied')
-    _h(' *')
-    _h(' * Returns the reply of the request asked by')
-    _h(' * ')
-    _h(' * The parameter @p e supplied to this function must be NULL if')
-    _h(' * %s(). is used.', self.c_unchecked_name)
-    _h(' * Otherwise, it stores the error if any.')
-    _h(' *')
-    _h(' * The returned value must be freed by the caller using free().')
-    _h(' */')
-    _c('')
-    _hc('')
-    _hc('/*****************************************************************************')
-    _hc(' **')
-    _hc(' ** %s * %s', self.c_reply_type, self.c_reply_name)
-    _hc(' ** ')
-    _hc(' ** @param xcb_connection_t%s  *c', spacing1)
-    _hc(' ** @param %s   cookie', self.c_cookie_type)
-    _hc(' ** @param xcb_generic_error_t%s **e', spacing2)
-    _hc(' ** @returns %s *', self.c_reply_type)
-    _hc(' **')
-    _hc(' *****************************************************************************/')
-    _hc(' ')
-    _hc('%s *', self.c_reply_type)
-    _hc('%s (xcb_connection_t%s  *c  /**< */,', self.c_reply_name, spacing1)
-    _hc('%s%s   cookie  /**< */,', spacing3, self.c_cookie_type)
-    _h('%sxcb_generic_error_t%s **e  /**< */);', spacing3, spacing2)
-    _c('%sxcb_generic_error_t%s **e  /**< */)', spacing3, spacing2)
-    _c('{')
-    
-    if len(unserialize_fields)>0:
-        # certain variable size fields need to be unserialized explicitly
-        _c('    %s *reply = (%s *) xcb_wait_for_reply(c, cookie.sequence, e);', 
-           self.c_reply_type, self.c_reply_type)
-        _c('    int i;')
-        for field in unserialize_fields:
-            if field.type.is_list:
-                _c('    %s %s_iter = %s(reply);', field.c_iterator_type, field.c_field_name, field.c_iterator_name)
-                _c('    int %s_len = %s(reply);', field.c_field_name, field.c_length_name)
-                _c('    %s *%s_data;', field.c_field_type, field.c_field_name)
-            else:
-                raise Exception('not implemented: call _unserialize() in reply for non-list type %s', field.c_field_type)
-        # call _unserialize(), using the reply as source and target buffer
-        _c('    /* special cases: transform parts of the reply to match XCB data structures */')
-        for field in unserialize_fields:
-            if field.type.is_list:
-                _c('    for(i=0; i<%s_len; i++) {', field.c_field_name)
-                _c('        %s_data = %s_iter.data;', field.c_field_name, field.c_field_name)
-                _c('        %s((const void *)%s_data, &%s_data);', field.type.c_unserialize_name, 
-                   field.c_field_name, field.c_field_name)
-                _c('        %s(&%s_iter);', field.type.c_next_name, field.c_field_name)
-                _c('    }')
-        # return the transformed reply
-        _c('    return reply;')
-    
-    else:
-        _c('    return (%s *) xcb_wait_for_reply(c, cookie.sequence, e);', self.c_reply_type)
-
-    _c('}')
-
-def _c_opcode(name, opcode):
-    '''
-    Declares the opcode define for requests, events, and errors.
-    '''
-    _h_setlevel(0)
-    _h('')
-    _h('/** Opcode for %s. */', _n(name))
-    _h('#define %s %s', _n(name).upper(), opcode)
-    
-def _c_cookie(self, name):
-    '''
-    Declares the cookie type for a non-void request.
-    '''
-    _h_setlevel(0)
-    _h('')
-    _h('/**')
-    _h(' * @brief %s', self.c_cookie_type)
-    _h(' **/')
-    _h('typedef struct %s {', self.c_cookie_type)
-    _h('    unsigned int sequence; /**<  */')
-    _h('} %s;', self.c_cookie_type)
-
-def c_request(self, name):
-    '''
-    Exported function that handles request declarations.
-    '''
-    _c_type_setup(self, name, ('request',))
-
-    if self.reply:
-        # Cookie type declaration
-        _c_cookie(self, name)
-
-    # Opcode define
-    _c_opcode(name, self.opcode)
-
-    # Request structure declaration
-    _c_complex(self)
-
-    if self.reply:
-        _c_type_setup(self.reply, name, ('reply',))
-        # Reply structure definition
-        _c_complex(self.reply)
-        # Request prototypes
-        _c_request_helper(self, name, self.c_cookie_type, False, True)
-        _c_request_helper(self, name, self.c_cookie_type, False, False)
-        if self.need_aux:
-            _c_request_helper(self, name, self.c_cookie_type, False, True, True)
-            _c_request_helper(self, name, self.c_cookie_type, False, False, True)
-        # Reply accessors
-        _c_accessors(self.reply, name + ('reply',), name)
-        _c_reply(self, name)
-    else:
-        # Request prototypes
-        _c_request_helper(self, name, 'xcb_void_cookie_t', True, False)
-        _c_request_helper(self, name, 'xcb_void_cookie_t', True, True)
-        if self.need_aux:
-            _c_request_helper(self, name, 'xcb_void_cookie_t', True, False, True)
-            _c_request_helper(self, name, 'xcb_void_cookie_t', True, True, True)
-
-
-def c_event(self, name):
-    '''
-    Exported function that handles event declarations.
-    '''
-    _c_type_setup(self, name, ('event',))
-
-    # Opcode define
-    _c_opcode(name, self.opcodes[name])
-
-    if self.name == name:
-        # Structure definition
-        _c_complex(self)
-    else:
-        # Typedef
-        _h('')
-        _h('typedef %s %s;', _t(self.name + ('event',)), _t(name + ('event',)))
-
-def c_error(self, name):
-    '''
-    Exported function that handles error declarations.
-    '''
-    _c_type_setup(self, name, ('error',))
-
-    # Opcode define
-    _c_opcode(name, self.opcodes[name])
-
-    if self.name == name:
-        # Structure definition
-        _c_complex(self)
-    else:
-        # Typedef
-        _h('')
-        _h('typedef %s %s;', _t(self.name + ('error',)), _t(name + ('error',)))
-
-
-# Main routine starts here
-
-# Must create an "output" dictionary before any xcbgen imports.
-output = {'open'    : c_open,
-          'close'   : c_close,
-          'simple'  : c_simple,
-          'enum'    : c_enum,
-          'struct'  : c_struct,
-          'union'   : c_union,
-          'request' : c_request,
-          'event'   : c_event,
-          'error'   : c_error, 
-          }
-
-# Boilerplate below this point
-
-# Check for the argument that specifies path to the xcbgen python package.
-try:
-    opts, args = getopt.getopt(sys.argv[1:], 'p:')
-except getopt.GetoptError as err:
-    print(err)
-    print('Usage: c_client.py [-p path] file.xml')
-    sys.exit(1)
-
-for (opt, arg) in opts:
-    if opt == '-p':
-        sys.path.insert(1, arg)
-
-# Import the module class
-try:
-    from xcbgen.state import Module
-except ImportError:
-    print('''
-Failed to load the xcbgen Python package!
-Make sure that xcb/proto installed it on your Python path.
-If not, you will need to create a .pth file or define $PYTHONPATH
-to extend the path.
-Refer to the README file in xcb/proto for more info.
-''')
-    raise
-
-# Parse the xml header
-module = Module(args[0], output)
-
-# Build type-registry and resolve type dependencies
-module.register()
-module.resolve()
-
-# Output the code
-module.generate()
+#!/usr/bin/env python
+from xml.etree.cElementTree import *
+from os.path import basename
+from functools import reduce
+import getopt
+import sys
+import re
+
+# Jump to the bottom of this file for the main routine
+
+# Some hacks to make the API more readable, and to keep backwards compability
+_cname_re = re.compile('([A-Z0-9][a-z]+|[A-Z0-9]+(?![a-z])|[a-z]+)')
+_cname_special_cases = {'DECnet':'decnet'}
+
+_extension_special_cases = ['XPrint', 'XCMisc', 'BigRequests']
+
+_cplusplus_annoyances = {'class' : '_class',
+                         'new'   : '_new',
+                         'delete': '_delete'}
+_c_keywords = {'default' : '_default'}
+
+_hlines = []
+_hlevel = 0
+_clines = []
+_clevel = 0
+_ns = None
+
+# global variable to keep track of serializers and 
+# switch data types due to weird dependencies
+finished_serializers = []
+finished_sizeof = []
+finished_switch = []
+
+def _h(fmt, *args):
+    '''
+    Writes the given line to the header file.
+    '''
+    _hlines[_hlevel].append(fmt % args)
+    
+def _c(fmt, *args):
+    '''
+    Writes the given line to the source file.
+    '''
+    _clines[_clevel].append(fmt % args)
+    
+def _hc(fmt, *args):
+    '''
+    Writes the given line to both the header and source files.
+    '''
+    _h(fmt, *args)
+    _c(fmt, *args)
+
+# XXX See if this level thing is really necessary.
+def _h_setlevel(idx):
+    '''
+    Changes the array that header lines are written to.
+    Supports writing different sections of the header file.
+    '''
+    global _hlevel
+    while len(_hlines) <= idx:
+        _hlines.append([])
+    _hlevel = idx
+    
+def _c_setlevel(idx):
+    '''
+    Changes the array that source lines are written to.
+    Supports writing to different sections of the source file.
+    '''
+    global _clevel
+    while len(_clines) <= idx:
+        _clines.append([])
+    _clevel = idx
+    
+def _n_item(str):
+    '''
+    Does C-name conversion on a single string fragment.
+    Uses a regexp with some hard-coded special cases.
+    '''
+    if str in _cname_special_cases:
+        return _cname_special_cases[str]
+    else:
+        split = _cname_re.finditer(str)
+        name_parts = [match.group(0) for match in split]
+        return '_'.join(name_parts)
+    
+def _cpp(str):
+    '''
+    Checks for certain C++ reserved words and fixes them.
+    '''
+    if str in _cplusplus_annoyances:
+        return _cplusplus_annoyances[str]
+    elif str in _c_keywords:
+        return  _c_keywords[str]
+    else:
+        return str
+
+def _ext(str):
+    '''
+    Does C-name conversion on an extension name.
+    Has some additional special cases on top of _n_item.
+    '''
+    if str in _extension_special_cases:
+        return _n_item(str).lower()
+    else:
+        return str.lower()
+    
+def _n(list):
+    '''
+    Does C-name conversion on a tuple of strings.
+    Different behavior depending on length of tuple, extension/not extension, etc.
+    Basically C-name converts the individual pieces, then joins with underscores.
+    '''
+    if len(list) == 1:
+        parts = list
+    elif len(list) == 2:
+        parts = [list[0], _n_item(list[1])]
+    elif _ns.is_ext:
+        parts = [list[0], _ext(list[1])] + [_n_item(i) for i in list[2:]]
+    else:
+        parts = [list[0]] + [_n_item(i) for i in list[1:]]
+    return '_'.join(parts).lower()
+
+def _t(list):
+    '''
+    Does C-name conversion on a tuple of strings representing a type.
+    Same as _n but adds a "_t" on the end.
+    '''
+    if len(list) == 1:
+        parts = list
+    elif len(list) == 2:
+        parts = [list[0], _n_item(list[1]), 't']
+    elif _ns.is_ext:
+        parts = [list[0], _ext(list[1])] + [_n_item(i) for i in list[2:]] + ['t']
+    else:
+        parts = [list[0]] + [_n_item(i) for i in list[1:]] + ['t']
+    return '_'.join(parts).lower()
+        
+
+def c_open(self):
+    '''
+    Exported function that handles module open.
+    Opens the files and writes out the auto-generated comment, header file includes, etc.
+    '''
+    global _ns
+    _ns = self.namespace
+    _ns.c_ext_global_name = _n(_ns.prefix + ('id',))
+
+    # Build the type-name collision avoidance table used by c_enum
+    build_collision_table()
+
+    _h_setlevel(0)
+    _c_setlevel(0)
+
+    _hc('/*')
+    _hc(' * This file generated automatically from %s by c_client.py.', _ns.file)
+    _hc(' * Edit at your peril.')
+    _hc(' */')
+    _hc('')
+
+    _h('/**')
+    _h(' * @defgroup XCB_%s_API XCB %s API', _ns.ext_name, _ns.ext_name)
+    _h(' * @brief %s XCB Protocol Implementation.', _ns.ext_name)
+    _h(' * @{')
+    _h(' **/')
+    _h('')
+    _h('#ifndef __%s_H', _ns.header.upper())
+    _h('#define __%s_H', _ns.header.upper())
+    _h('')
+    _h('#include "xcb.h"')
+
+    _c('#include <stdlib.h>')
+    _c('#include <string.h>')
+    _c('#include <assert.h>')
+    _c('#include <stddef.h>  /* for offsetof() */')
+    _c('#include "xcbext.h"')
+    _c('#include "%s.h"', _ns.header)
+    _c('#include <X11/Xtrans/Xtrans.h>')
+        
+    _c('')
+    _c('#define ALIGNOF(type) offsetof(struct { char dummy; type member; }, member)')
+
+    if _ns.is_ext:
+        for (n, h) in self.imports:
+            _hc('#include "%s.h"', h)
+
+    _h('')
+    _h('#ifdef __cplusplus')
+    _h('extern "C" {')
+    _h('#endif')
+
+    if _ns.is_ext:
+        _h('')
+        _h('#define XCB_%s_MAJOR_VERSION %s', _ns.ext_name.upper(), _ns.major_version)
+        _h('#define XCB_%s_MINOR_VERSION %s', _ns.ext_name.upper(), _ns.minor_version)
+        _h('  ') #XXX
+        _h('extern xcb_extension_t %s;', _ns.c_ext_global_name)
+
+        _c('')
+        _c('xcb_extension_t %s = { "%s", 0 };', _ns.c_ext_global_name, _ns.ext_xname)
+
+def c_close(self):
+    '''
+    Exported function that handles module close.
+    Writes out all the stored content lines, then closes the files.
+    '''
+    _h_setlevel(2)
+    _c_setlevel(2)
+    _hc('')
+
+    _h('')
+    _h('#ifdef __cplusplus')
+    _h('}')
+    _h('#endif')
+
+    _h('')
+    _h('#endif')
+    _h('')
+    _h('/**')
+    _h(' * @}')
+    _h(' */')
+
+    # Write header file
+    hfile = open('%s.h' % _ns.header, 'w')
+    for list in _hlines:
+        for line in list:
+            hfile.write(line)
+            hfile.write('\n')
+    hfile.close()
+
+    # Write source file
+    cfile = open('%s.c' % _ns.header, 'w')
+    for list in _clines:
+        for line in list:
+            cfile.write(line)
+            cfile.write('\n')
+    cfile.close()
+
+def build_collision_table():
+    global namecount
+    namecount = {}
+
+    for v in module.types.values():
+        name = _t(v[0])
+        namecount[name] = (namecount.get(name) or 0) + 1
+
+def c_enum(self, name):
+    '''
+    Exported function that handles enum declarations.
+    '''
+
+    tname = _t(name)
+    if namecount[tname] > 1:
+        tname = _t(name + ('enum',))
+
+    _h_setlevel(0)
+    _h('')
+    _h('typedef enum %s {', tname)
+
+    count = len(self.values)
+
+    for (enam, eval) in self.values:
+        count = count - 1
+        equals = ' = ' if eval != '' else ''
+        comma = ',' if count > 0 else ''
+        _h('    %s%s%s%s', _n(name + (enam,)).upper(), equals, eval, comma)
+
+    _h('} %s;', tname)
+
+def _c_type_setup(self, name, postfix):
+    '''
+    Sets up all the C-related state by adding additional data fields to
+    all Field and Type objects.  Here is where we figure out most of our
+    variable and function names.
+
+    Recurses into child fields and list member types.
+    '''
+    # Do all the various names in advance
+    self.c_type = _t(name + postfix)
+    self.c_wiretype = 'char' if self.c_type == 'void' else self.c_type
+
+    self.c_iterator_type = _t(name + ('iterator',))
+    self.c_next_name = _n(name + ('next',))
+    self.c_end_name = _n(name + ('end',))
+
+    self.c_request_name = _n(name)
+    self.c_checked_name = _n(name + ('checked',))
+    self.c_unchecked_name = _n(name + ('unchecked',))
+    self.c_reply_name = _n(name + ('reply',))
+    self.c_reply_type = _t(name + ('reply',))
+    self.c_cookie_type = _t(name + ('cookie',))
+
+    self.need_aux = False
+    self.need_serialize = False
+    self.need_sizeof = False
+
+    self.c_aux_name = _n(name + ('aux',))
+    self.c_aux_checked_name = _n(name + ('aux', 'checked'))
+    self.c_aux_unchecked_name = _n(name + ('aux', 'unchecked'))
+    self.c_serialize_name = _n(name + ('serialize',))
+    self.c_unserialize_name = _n(name + ('unserialize',))
+    self.c_unpack_name = _n(name + ('unpack',))
+    self.c_sizeof_name = _n(name + ('sizeof',))
+
+    # special case: structs where variable size fields are followed by fixed size fields
+    self.var_followed_by_fixed_fields = False
+
+    if self.is_switch:
+        self.need_serialize = True
+        self.c_container = 'struct'
+        for bitcase in self.bitcases:
+            bitcase.c_field_name = _cpp(bitcase.field_name)
+            bitcase_name = bitcase.field_type if bitcase.type.has_name else name
+            _c_type_setup(bitcase.type, bitcase_name, ())
+
+    elif self.is_container:
+
+        self.c_container = 'union' if self.is_union else 'struct'
+        prev_varsized_field = None
+        prev_varsized_offset = 0
+        first_field_after_varsized = None
+
+        for field in self.fields:
+            _c_type_setup(field.type, field.field_type, ())
+            if field.type.is_list:
+                _c_type_setup(field.type.member, field.field_type, ())
+                if (field.type.nmemb is None): 
+                    self.need_sizeof = True
+
+            field.c_field_type = _t(field.field_type)
+            field.c_field_const_type = ('' if field.type.nmemb == 1 else 'const ') + field.c_field_type
+            field.c_field_name = _cpp(field.field_name)
+            field.c_subscript = '[%d]' % field.type.nmemb if (field.type.nmemb and field.type.nmemb > 1) else ''
+            field.c_pointer = ' ' if field.type.nmemb == 1 else '*'
+
+            # correct the c_pointer field for variable size non-list types
+            if not field.type.fixed_size() and field.c_pointer == ' ':
+                field.c_pointer = '*'
+            if field.type.is_list and not field.type.member.fixed_size():
+                field.c_pointer = '*'
+
+            if field.type.is_switch:
+                field.c_pointer = '*'
+                field.c_field_const_type = 'const ' + field.c_field_type
+                self.need_aux = True
+            elif not field.type.fixed_size() and not field.type.is_bitcase:
+                self.need_sizeof = True
+
+            field.c_iterator_type = _t(field.field_type + ('iterator',))      # xcb_fieldtype_iterator_t
+            field.c_iterator_name = _n(name + (field.field_name, 'iterator')) # xcb_container_field_iterator
+            field.c_accessor_name = _n(name + (field.field_name,))            # xcb_container_field
+            field.c_length_name = _n(name + (field.field_name, 'length'))     # xcb_container_field_length
+            field.c_end_name = _n(name + (field.field_name, 'end'))           # xcb_container_field_end
+
+            field.prev_varsized_field = prev_varsized_field
+            field.prev_varsized_offset = prev_varsized_offset
+
+            if prev_varsized_offset == 0:
+                first_field_after_varsized = field
+            field.first_field_after_varsized = first_field_after_varsized
+
+            if field.type.fixed_size():
+                prev_varsized_offset += field.type.size
+                # special case: intermixed fixed and variable size fields
+                if prev_varsized_field is not None and not field.type.is_pad and field.wire:
+                    if not self.is_union:
+                        self.need_serialize = True
+                        self.var_followed_by_fixed_fields = True
+            else:
+                self.last_varsized_field = field
+                prev_varsized_field = field
+                prev_varsized_offset = 0                    
+
+            if self.var_followed_by_fixed_fields:
+                if field.type.fixed_size():
+                    field.prev_varsized_field = None
+                            
+    if self.need_serialize:
+        # when _unserialize() is wanted, create _sizeof() as well for consistency reasons 
+        self.need_sizeof = True
+
+    # as switch does never appear at toplevel, 
+    # continue here with type construction
+    if self.is_switch:
+        if self.c_type not in finished_switch:
+            finished_switch.append(self.c_type)
+            # special: switch C structs get pointer fields for variable-sized members
+            _c_complex(self)
+            for bitcase in self.bitcases:
+                bitcase_name = bitcase.type.name if bitcase.type.has_name else name
+                _c_accessors(bitcase.type, bitcase_name, bitcase_name)
+                # no list with switch as element, so no call to 
+                # _c_iterator(field.type, field_name) necessary
+
+    if not self.is_bitcase:
+        if self.need_serialize:
+            if self.c_serialize_name not in finished_serializers:
+                finished_serializers.append(self.c_serialize_name)
+                _c_serialize('serialize', self)
+
+                # _unpack() and _unserialize() are only needed for special cases:
+                #   switch -> unpack
+                #   special cases -> unserialize
+                if self.is_switch or self.var_followed_by_fixed_fields:
+                    _c_serialize('unserialize', self)
+                    
+        if self.need_sizeof:
+            if self.c_sizeof_name not in finished_sizeof:
+                if not module.namespace.is_ext or self.name[:2] == module.namespace.prefix:
+                    finished_sizeof.append(self.c_sizeof_name)
+                    _c_serialize('sizeof', self)
+# _c_type_setup()
+
+def _c_helper_absolute_name(prefix, field=None):
+    """
+    turn prefix, which is a list of tuples (name, separator, Type obj) into a string
+    representing a valid name in C (based on the context)
+    if field is not None, append the field name as well
+    """
+    prefix_str = ''
+    for name, sep, obj in prefix:
+        prefix_str += name
+        if '' == sep:
+            sep = '->'
+            if ((obj.is_bitcase and obj.has_name) or     # named bitcase
+                (obj.is_switch and len(obj.parents)>1)):
+                sep = '.'
+        prefix_str += sep
+    if field is not None:
+        prefix_str += _cpp(field.field_name)
+    return prefix_str
+# _c_absolute_name
+    
+def _c_helper_field_mapping(complex_type, prefix, flat=False):
+    """
+    generate absolute names, based on prefix, for all fields starting from complex_type
+    if flat == True, nested complex types are not taken into account
+    """
+    all_fields = {}
+    if complex_type.is_switch:
+        for b in complex_type.bitcases:
+            if b.type.has_name:
+                switch_name, switch_sep, switch_type = prefix[-1]
+                bitcase_prefix = prefix + [(b.type.name[-1], '.', b.type)]
+            else:
+                bitcase_prefix = prefix 
+
+            if (True==flat and not b.type.has_name) or False==flat:
+                all_fields.update(_c_helper_field_mapping(b.type, bitcase_prefix, flat))
+    else:
+        for f in complex_type.fields:
+            fname = _c_helper_absolute_name(prefix, f)
+            if f.field_name in all_fields:
+                raise Exception("field name %s has been registered before" % f.field_name)
+
+            all_fields[f.field_name] = (fname, f)
+            if f.type.is_container and flat==False:
+                if f.type.is_bitcase and not f.type.has_name:
+                    new_prefix = prefix
+                elif f.type.is_switch and len(f.type.parents)>1:
+                    # nested switch gets another separator
+                    new_prefix = prefix+[(f.c_field_name, '.', f.type)]
+                else:
+                    new_prefix = prefix+[(f.c_field_name, '->', f.type)]
+                all_fields.update(_c_helper_field_mapping(f.type, new_prefix, flat))
+
+    return all_fields
+# _c_field_mapping()
+
+def _c_helper_resolve_field_names (prefix):
+    """
+    get field names for all objects in the prefix array
+    """
+    all_fields = {}
+    tmp_prefix = []
+    # look for fields in the remaining containers
+    for idx, p in enumerate(prefix):
+        name, sep, obj = p
+        if ''==sep:
+            # sep can be preset in prefix, if not, make a sensible guess
+            sep = '.' if (obj.is_switch or obj.is_bitcase) else '->'
+            # exception: 'toplevel' object (switch as well!) always have sep '->'
+            sep = '->' if idx<1 else sep
+        if not obj.is_bitcase or (obj.is_bitcase and obj.has_name):
+            tmp_prefix.append((name, sep, obj))
+        all_fields.update(_c_helper_field_mapping(obj, tmp_prefix, flat=True))
+
+    return all_fields
+# _c_helper_resolve_field_names
+
+def get_expr_fields(self):
+    """
+    get the Fields referenced by switch or list expression 
+    """
+    def get_expr_field_names(expr):
+        if expr.op is None:
+            if expr.lenfield_name is not None:
+                return [expr.lenfield_name]
+            else:
+                # constant value expr
+                return []
+        else:
+            if expr.op == '~':
+                return get_expr_field_names(expr.rhs)
+            elif expr.op == 'popcount':
+                return get_expr_field_names(expr.rhs)
+            elif expr.op == 'sumof':
+                # sumof expr references another list, 
+                # we need that list's length field here
+                field = None
+                for f in expr.lenfield_parent.fields:
+                    if f.field_name == expr.lenfield_name:
+                        field = f
+                        break
+                if field is None:
+                    raise Exception("list field '%s' referenced by sumof not found" % expr.lenfield_name)
+                # referenced list + its length field
+                return [expr.lenfield_name] + get_expr_field_names(field.type.expr)
+            elif expr.op == 'enumref':
+                return []
+            else:
+                return get_expr_field_names(expr.lhs) + get_expr_field_names(expr.rhs)
+    # get_expr_field_names()
+    
+    # resolve the field names with the parent structure(s)
+    unresolved_fields_names = get_expr_field_names(self.expr)
+
+    # construct prefix from self
+    prefix = [('', '', p) for p in self.parents]
+    if self.is_container:
+        prefix.append(('', '', self))
+
+    all_fields = _c_helper_resolve_field_names (prefix)
+    resolved_fields_names = list(filter(lambda x: x in all_fields.keys(), unresolved_fields_names))
+    if len(unresolved_fields_names) != len(resolved_fields_names):
+        raise Exception("could not resolve all fields for %s" % self.name)
+    
+    resolved_fields = [all_fields[n][1] for n in resolved_fields_names]
+    return resolved_fields
+# get_expr_fields()
+
+def resolve_expr_fields(complex_obj):
+    """
+    find expr fields appearing in complex_obj and descendents that cannot be resolved within complex_obj
+    these are normally fields that need to be given as function parameters
+    """
+    all_fields = []
+    expr_fields = []
+    unresolved = []
+
+    for field in complex_obj.fields:
+        all_fields.append(field)
+        if field.type.is_switch or field.type.is_list:
+            expr_fields += get_expr_fields(field.type)
+        if field.type.is_container:
+            expr_fields += resolve_expr_fields(field.type)
+
+    # try to resolve expr fields
+    for e in expr_fields:
+        if e not in all_fields and e not in unresolved:
+            unresolved.append(e)
+    return unresolved
+# resolve_expr_fields()
+            
+def get_serialize_params(context, self, buffer_var='_buffer', aux_var='_aux'):
+    """
+    functions like _serialize(), _unserialize(), and _unpack() sometimes need additional parameters:
+    E.g. in order to unpack switch, extra parameters might be needed to evaluate the switch 
+    expression. This function tries to resolve all fields within a structure, and returns the 
+    unresolved fields as the list of external parameters. 
+    """
+    def add_param(params, param):
+        if param not in params:
+            params.append(param)
+
+    # collect all fields into param_fields
+    param_fields = []
+    wire_fields = []
+
+    for field in self.fields:
+        if field.visible:
+            # the field should appear as a parameter in the function call
+            param_fields.append(field)
+        if field.wire and not field.auto:
+            if field.type.fixed_size() and not self.is_switch:
+                # field in the xcb_out structure
+                wire_fields.append(field)
+        # fields like 'pad0' are skipped!
+               
+    # in case of switch, parameters always contain any fields referenced in the switch expr
+    # we do not need any variable size fields here, as the switch data type contains both 
+    # fixed and variable size fields
+    if self.is_switch:
+        param_fields = get_expr_fields(self)
+
+    # _serialize()/_unserialize()/_unpack() function parameters
+    # note: don't use set() for params, it is unsorted
+    params = []
+    
+    # 1. the parameter for the void * buffer
+    if  'serialize' == context:
+        params.append(('void', '**', buffer_var))
+    elif context in ('unserialize', 'unpack', 'sizeof'):
+        params.append(('const void', '*', buffer_var))
+
+    # 2. any expr fields that cannot be resolved within self and descendants
+    unresolved_fields = resolve_expr_fields(self)
+    for f in unresolved_fields:
+        add_param(params, (f.c_field_type, '', f.c_field_name))
+
+    # 3. param_fields contain the fields necessary to evaluate the switch expr or any other fields
+    #    that do not appear in the data type struct
+    for p in param_fields:
+        if self.is_switch:
+            typespec = p.c_field_const_type
+            pointerspec = p.c_pointer 
+            add_param(params, (typespec, pointerspec, p.c_field_name))
+        else:
+            if p.visible and not p.wire and not p.auto:
+                typespec = p.c_field_type
+                pointerspec = ''
+                add_param(params, (typespec, pointerspec, p.c_field_name))
+  
+    # 4. aux argument
+    if 'serialize' == context:
+        add_param(params, ('const %s' % self.c_type, '*', aux_var))
+    elif 'unserialize' == context: 
+        add_param(params, ('%s' % self.c_type, '**', aux_var))
+    elif 'unpack' == context:
+        add_param(params, ('%s' % self.c_type, '*', aux_var))
+
+    # 5. switch contains all variable size fields as struct members
+    #    for other data types though, these have to be supplied separately
+    #    this is important for the special case of intermixed fixed and 
+    #    variable size fields
+    if not self.is_switch and 'serialize' == context:
+        for p in param_fields:
+            if not p.type.fixed_size():
+                add_param(params, (p.c_field_const_type, '*', p.c_field_name))
+
+    return (param_fields, wire_fields, params)
+# get_serialize_params()
+
+def _c_serialize_helper_insert_padding(context, code_lines, space, postpone):
+    code_lines.append('%s    /* insert padding */' % space)
+    code_lines.append('%s    xcb_pad = -xcb_block_len & (xcb_align_to - 1);' % space)
+#    code_lines.append('%s    printf("automatically inserting padding: %%%%d\\n", xcb_pad);' % space)
+    code_lines.append('%s    xcb_buffer_len += xcb_block_len + xcb_pad;' % space)
+
+    if not postpone:
+        code_lines.append('%s    if (0 != xcb_pad) {' % space)
+
+        if 'serialize' == context:
+            code_lines.append('%s        xcb_parts[xcb_parts_idx].iov_base = xcb_pad0;' % space)
+            code_lines.append('%s        xcb_parts[xcb_parts_idx].iov_len = xcb_pad;' % space)
+            code_lines.append('%s        xcb_parts_idx++;' % space)
+        elif context in ('unserialize', 'unpack', 'sizeof'):
+            code_lines.append('%s        xcb_tmp += xcb_pad;' % space)
+
+        code_lines.append('%s        xcb_pad = 0;' % space)
+        code_lines.append('%s    }' % space)
+        
+    code_lines.append('%s    xcb_block_len = 0;' % space)
+
+    # keep tracking of xcb_parts entries for serialize
+    return 1
+# _c_serialize_helper_insert_padding()
+
+def _c_serialize_helper_switch(context, self, complex_name, 
+                               code_lines, temp_vars, 
+                               space, prefix):
+    count = 0
+    switch_expr = _c_accessor_get_expr(self.expr, None)
+
+    for b in self.bitcases:            
+        bitcase_expr = _c_accessor_get_expr(b.type.expr, None)
+        code_lines.append('    if(%s & %s) {' % (switch_expr, bitcase_expr))
+#        code_lines.append('        printf("switch %s: entering bitcase section %s (mask=%%%%d)...\\n", %s);' % 
+#                          (self.name[-1], b.type.name[-1], bitcase_expr))
+        b_prefix = prefix
+        if b.type.has_name:
+            b_prefix = prefix + [(b.c_field_name, '.', b.type)]
+            
+        count += _c_serialize_helper_fields(context, b.type, 
+                                            code_lines, temp_vars, 
+                                            "%s    " % space, 
+                                            b_prefix, 
+                                            is_bitcase = True)
+        code_lines.append('    }')
+
+#    if 'serialize' == context:
+#        count += _c_serialize_helper_insert_padding(context, code_lines, space, False)
+#    elif context in ('unserialize', 'unpack', 'sizeof'):
+#        # padding
+#        code_lines.append('%s    xcb_pad = -xcb_block_len & 3;' % space)
+#        code_lines.append('%s    xcb_buffer_len += xcb_block_len + xcb_pad;' % space)
+   
+    return count
+# _c_serialize_helper_switch
+
+def _c_serialize_helper_switch_field(context, self, field, c_switch_variable, prefix):
+    """
+    handle switch by calling _serialize() or _unpack(), depending on context
+    """
+    # switch is handled by this function as a special case
+    param_fields, wire_fields, params = get_serialize_params(context, self)
+    field_mapping = _c_helper_field_mapping(self, prefix)
+    prefix_str = _c_helper_absolute_name(prefix)
+
+    # find the parameters that need to be passed to _serialize()/_unpack():
+    # all switch expr fields must be given as parameters
+    args = get_expr_fields(field.type)
+    # length fields for variable size types in switch, normally only some of need 
+    # need to be passed as parameters
+    switch_len_fields = resolve_expr_fields(field.type)
+
+    # a switch field at this point _must_ be a bitcase field
+    # we require that bitcases are "self-contiguous"
+    bitcase_unresolved = resolve_expr_fields(self)
+    if len(bitcase_unresolved) != 0:
+        raise Exception('unresolved fields within bitcase is not supported at this point')
+
+    # get the C names for the parameters  
+    c_field_names = ''
+    for a in switch_len_fields:
+        c_field_names += "%s, " % field_mapping[a.c_field_name][0]
+    for a in args:
+        c_field_names += "%s, " % field_mapping[a.c_field_name][0]
+
+    # call _serialize()/_unpack() to determine the actual size
+    if 'serialize' == context:
+        length = "%s(&%s, %s&%s%s)" % (field.type.c_serialize_name, c_switch_variable,
+                                       c_field_names, prefix_str, field.c_field_name) 
+    elif context in ('unserialize', 'unpack'):
+        length = "%s(xcb_tmp, %s&%s%s)" % (field.type.c_unpack_name, 
+                                           c_field_names, prefix_str, field.c_field_name)
+
+    return length
+# _c_serialize_helper_switch_field()
+
+def _c_serialize_helper_list_field(context, self, field, 
+                                   code_lines, temp_vars, 
+                                   space, prefix):
+    """
+    helper function to cope with lists of variable length
+    """
+    expr = field.type.expr
+    prefix_str = _c_helper_absolute_name(prefix)
+    param_fields, wire_fields, params = get_serialize_params('sizeof', self)
+    param_names = [p[2] for p in params]
+    
+    expr_fields_names = [f.field_name for f in get_expr_fields(field.type)]
+    resolved = list(filter(lambda x: x in param_names, expr_fields_names))
+    unresolved = list(filter(lambda x: x not in param_names, expr_fields_names))
+    
+    field_mapping = {}
+    for r in resolved:
+        field_mapping[r] = (r, None)
+    
+    if len(unresolved)>0:
+        tmp_prefix = prefix
+        if len(tmp_prefix)==0:
+            raise Exception("found an empty prefix while resolving expr field names for list %s", 
+                            field.c_field_name)        
+        
+        field_mapping.update(_c_helper_resolve_field_names(prefix))
+        resolved += list(filter(lambda x: x in field_mapping, unresolved))
+        unresolved = list(filter(lambda x: x not in field_mapping, unresolved))
+        if len(unresolved)>0:
+            raise Exception('could not resolve the length fields required for list %s' % field.c_field_name)
+
+    list_length = _c_accessor_get_expr(expr, field_mapping)
+
+    # default: list with fixed size elements
+    length = '%s * sizeof(%s)' % (list_length, field.type.member.c_wiretype)
+
+    # list with variable-sized elements 
+    if not field.type.member.fixed_size():
+        length = ''
+        if context in ('unserialize', 'sizeof', 'unpack'):
+            int_i = '    unsigned int i;'
+            xcb_tmp_len = '    unsigned int xcb_tmp_len;'
+            if int_i not in temp_vars:
+                temp_vars.append(int_i)
+            if xcb_tmp_len not in temp_vars:
+                temp_vars.append(xcb_tmp_len)
+            # loop over all list elements and call sizeof repeatedly
+            # this should be a bit faster than using the iterators
+            code_lines.append("%s    for(i=0; i<%s; i++) {" % (space, list_length))
+            code_lines.append("%s        xcb_tmp_len = %s(xcb_tmp);" % 
+                              (space, field.type.c_sizeof_name))
+            code_lines.append("%s        xcb_block_len += xcb_tmp_len;" % space)
+            code_lines.append("%s        xcb_tmp += xcb_tmp_len;" % space)
+            code_lines.append("%s    }" % space)                  
+      
+        elif 'serialize' == context:
+            code_lines.append('%s    xcb_parts[xcb_parts_idx].iov_len = 0;' % space)
+            code_lines.append('%s    xcb_tmp = (char *) %s%s;' % (space, prefix_str, field.c_field_name))
+            code_lines.append('%s    for(i=0; i<%s; i++) { ' % (space, list_length))
+            code_lines.append('%s        xcb_block_len = %s(xcb_tmp);' % (space, field.type.c_sizeof_name))
+            code_lines.append('%s        xcb_parts[xcb_parts_idx].iov_len += xcb_block_len;' % space)
+            code_lines.append('%s    }' % space)
+            code_lines.append('%s    xcb_block_len = xcb_parts[xcb_parts_idx].iov_len;' % space)
+            
+    return length
+# _c_serialize_helper_list_field()
+
+def _c_serialize_helper_fields_fixed_size(context, self, field, 
+                                          code_lines, temp_vars, 
+                                          space, prefix):
+    # keep the C code a bit more readable by giving the field name
+    if not self.is_bitcase:
+        code_lines.append('%s    /* %s.%s */' % (space, self.c_type, field.c_field_name))
+    else:
+        scoped_name = [p[2].c_type if idx==0 else p[0] for idx, p in enumerate(prefix)]
+        typename = reduce(lambda x,y: "%s.%s" % (x, y), scoped_name)
+        code_lines.append('%s    /* %s.%s */' % (space, typename, field.c_field_name))
+
+    abs_field_name = _c_helper_absolute_name(prefix, field)
+    # default for simple cases: call sizeof()
+    length = "sizeof(%s)" % field.c_field_type
+
+    if context in ('unserialize', 'unpack', 'sizeof'):
+        # default: simple cast
+        value = '    %s = *(%s *)xcb_tmp;' % (abs_field_name, field.c_field_type) 
+        
+        # padding - we could probably just ignore it
+        if field.type.is_pad and field.type.nmemb > 1:
+            value = ''
+            for i in range(field.type.nmemb):
+                code_lines.append('%s    %s[%d] = *(%s *)xcb_tmp;' % 
+                                  (space, abs_field_name, i, field.c_field_type)) 
+            # total padding = sizeof(pad0) * nmemb
+            length += " * %d" % field.type.nmemb
+
+        if field.type.is_list:
+            # no such case in the protocol, cannot be tested and therefore ignored for now
+            raise Exception('list with fixed number of elemens unhandled in _unserialize()')
+
+    elif 'serialize' == context:
+        value = '    xcb_parts[xcb_parts_idx].iov_base = (char *) ' 
+
+        if field.type.is_expr:
+            # need to register a temporary variable for the expression in case we know its type
+            if field.type.c_type is None:
+                raise Exception("type for field '%s' (expression '%s') unkown" % 
+                                (field.field_name, _c_accessor_get_expr(field.type.expr)))
+            
+            temp_vars.append('    %s xcb_expr_%s = %s;' % (field.type.c_type, _cpp(field.field_name), 
+                                                           _c_accessor_get_expr(field.type.expr, prefix)))
+            value += "&xcb_expr_%s;" % _cpp(field.field_name)
+
+        elif field.type.is_pad:
+            if field.type.nmemb == 1:
+                value += "&xcb_pad;"
+            else:
+                # we could also set it to 0, see definition of xcb_send_request()
+                value = '    xcb_parts[xcb_parts_idx].iov_base = xcb_pad0;'
+                length += "*%d" % field.type.nmemb
+
+        else:
+            # non-list type with fixed size
+            if field.type.nmemb == 1:
+                value += "&%s;" % (abs_field_name)
+
+            # list with nmemb (fixed size) elements
+            else:
+                value += '%s;' % (abs_field_name)
+                length = '%d' % field.type.nmemb
+
+    return (value, length)
+# _c_serialize_helper_fields_fixed_size()
+
+def _c_serialize_helper_fields_variable_size(context, self, field, 
+                                             code_lines, temp_vars, 
+                                             space, prefix):
+    prefix_str = _c_helper_absolute_name(prefix)
+
+    if context in ('unserialize', 'unpack', 'sizeof'):
+        value = ''
+        var_field_name = 'xcb_tmp'
+        
+        # special case: intermixed fixed and variable size fields
+        if self.var_followed_by_fixed_fields and 'unserialize' == context:
+            value = '    %s = (%s *)xcb_tmp;' % (field.c_field_name, field.c_field_type)
+            temp_vars.append('    %s *%s;' % (field.type.c_type, field.c_field_name))
+        # special case: switch
+        if 'unpack' == context:
+            value = '    %s%s = (%s *)xcb_tmp;' % (prefix_str, field.c_field_name, field.c_field_type)
+            
+    elif 'serialize' == context:
+        # variable size fields appear as parameters to _serialize() if the 
+        # 'toplevel' container is not a switch
+        prefix_string = prefix_str if prefix[0][2].is_switch else ''
+        var_field_name = "%s%s" % (prefix_string, field.c_field_name)
+        value = '    xcb_parts[xcb_parts_idx].iov_base = (char *) %s;' % var_field_name
+
+    length = ''
+
+    code_lines.append('%s    /* %s */' % (space, field.c_field_name))
+
+    if field.type.is_list:
+        if value != '':
+            # in any context, list is already a pointer, so the default assignment is ok
+            code_lines.append("%s%s" % (space, value))
+            value = ''
+        length = _c_serialize_helper_list_field(context, self, field, 
+                                                code_lines, temp_vars, 
+                                                space, prefix)
+        
+    elif field.type.is_switch:
+        value = ''
+        if context == 'serialize':
+            # the _serialize() function allocates the correct amount memory if given a NULL pointer
+            value = '    xcb_parts[xcb_parts_idx].iov_base = (char *)0;'
+        length = _c_serialize_helper_switch_field(context, self, field, 
+                                                  'xcb_parts[xcb_parts_idx].iov_base', 
+                                                  prefix)
+        
+    else:
+        # in all remaining special cases - call _sizeof()
+        length = "%s(%s)" % (field.type.c_sizeof_name, var_field_name)
+
+    return (value, length)
+# _c_serialize_helper_fields_variable_size
+
+def _c_serialize_helper_fields(context, self, 
+                               code_lines, temp_vars, 
+                               space, prefix, is_bitcase):
+    count = 0
+    need_padding = False
+    prev_field_was_variable = False
+
+    for field in self.fields:
+        if not field.visible:
+            if not ((field.wire and not field.auto) or 'unserialize' == context):
+                continue
+
+        # switch/bitcase: fixed size fields must be considered explicitly 
+        if field.type.fixed_size():
+            if self.is_bitcase or self.var_followed_by_fixed_fields:
+                if prev_field_was_variable and need_padding:
+                    # insert padding
+#                    count += _c_serialize_helper_insert_padding(context, code_lines, space, 
+#                                                                self.var_followed_by_fixed_fields)
+                    prev_field_was_variable = False
+
+                # prefix for fixed size fields
+                fixed_prefix = prefix
+
+                value, length = _c_serialize_helper_fields_fixed_size(context, self, field, 
+                                                                      code_lines, temp_vars, 
+                                                                      space, fixed_prefix)
+            else:
+                continue
+
+        # fields with variable size
+        else:
+            # switch/bitcase: always calculate padding before and after variable sized fields
+            if need_padding or is_bitcase:
+                count += _c_serialize_helper_insert_padding(context, code_lines, space, 
+                                                            self.var_followed_by_fixed_fields)
+
+            value, length = _c_serialize_helper_fields_variable_size(context, self, field, 
+                                                                     code_lines, temp_vars, 
+                                                                     space, prefix)
+            prev_field_was_variable = True
+        
+        # save (un)serialization C code
+        if '' != value:
+            code_lines.append('%s%s' % (space, value))    
+        
+        if field.type.fixed_size():
+            if is_bitcase or self.var_followed_by_fixed_fields:
+                # keep track of (un)serialized object's size
+                code_lines.append('%s    xcb_block_len += %s;' % (space, length))
+                if context in ('unserialize', 'unpack', 'sizeof'):
+                    code_lines.append('%s    xcb_tmp += %s;' % (space, length))
+        else: 
+            # variable size objects or bitcase:
+            #   value & length might have been inserted earlier for special cases
+            if '' != length:
+                # special case: intermixed fixed and variable size fields
+                if (not field.type.fixed_size() and 
+                    self.var_followed_by_fixed_fields and 'unserialize' == context):
+                    temp_vars.append('    int %s_len;' % field.c_field_name)
+                    code_lines.append('%s    %s_len = %s;' % (space, field.c_field_name, length))
+                    code_lines.append('%s    xcb_block_len += %s_len;' % (space, field.c_field_name))
+                    code_lines.append('%s    xcb_tmp += %s_len;' % (space, field.c_field_name))
+                else:
+                    code_lines.append('%s    xcb_block_len += %s;' % (space, length))
+                    # increase pointer into the byte stream accordingly
+                    if context in ('unserialize', 'sizeof', 'unpack'):
+                        code_lines.append('%s    xcb_tmp += xcb_block_len;' % space)
+                        
+        if 'serialize' == context:
+            if '' != length:
+                code_lines.append('%s    xcb_parts[xcb_parts_idx].iov_len = %s;' % (space, length))
+            code_lines.append('%s    xcb_parts_idx++;' % space)
+            count += 1
+
+        code_lines.append('%s    xcb_align_to = ALIGNOF(%s);' % (space, 'char' if field.c_field_type == 'void' else field.c_field_type))
+
+        need_padding = True
+        if self.var_followed_by_fixed_fields:
+            need_padding = False
+        
+    return count
+# _c_serialize_helper_fields()    
+
+def _c_serialize_helper(context, complex_type, 
+                        code_lines, temp_vars, 
+                        space='', prefix=[]):
+    # count tracks the number of fields to serialize
+    count = 0
+
+    if hasattr(complex_type, 'type'):
+        self = complex_type.type
+        complex_name = complex_type.name
+    else:
+        self = complex_type
+        if self.var_followed_by_fixed_fields and 'unserialize' == context:
+            complex_name = 'xcb_out'
+        else:
+            complex_name = '_aux'
+    
+    # special case: switch is serialized by evaluating each bitcase separately
+    if self.is_switch:
+        count += _c_serialize_helper_switch(context, self, complex_name, 
+                                            code_lines, temp_vars, 
+                                            space, prefix)
+
+    # all other data types can be evaluated one field a time
+    else: 
+        # unserialize & fixed size fields: simply cast the buffer to the respective xcb_out type
+        if context in ('unserialize', 'unpack', 'sizeof') and not self.var_followed_by_fixed_fields:
+            code_lines.append('%s    xcb_block_len += sizeof(%s);' % (space, self.c_type))
+            code_lines.append('%s    xcb_tmp += xcb_block_len;' % space)
+            # probably not needed
+            #_c_serialize_helper_insert_padding(context, code_lines, space, False)
+
+        count += _c_serialize_helper_fields(context, self, 
+                                            code_lines, temp_vars, 
+                                            space, prefix, False)
+    # "final padding"
+    count += _c_serialize_helper_insert_padding(context, code_lines, space, False)
+
+    return count    
+# _c_serialize_helper()
+
+def _c_serialize(context, self):
+    """
+    depending on the context variable, generate _serialize(), _unserialize(), _unpack(), or _sizeof() 
+    for the ComplexType variable self
+    """
+    _h_setlevel(1)
+    _c_setlevel(1)
+
+    _hc('')
+    # _serialize() returns the buffer size
+    _hc('int')
+
+    if self.is_switch and 'unserialize' == context:
+        context = 'unpack'
+
+    cases = { 'serialize'   : self.c_serialize_name, 
+              'unserialize' : self.c_unserialize_name, 
+              'unpack'      : self.c_unpack_name, 
+              'sizeof'      : self.c_sizeof_name }
+    func_name = cases[context]
+            
+    param_fields, wire_fields, params = get_serialize_params(context, self)
+    variable_size_fields = 0
+    # maximum space required for type definition of function arguments
+    maxtypelen = 0
+
+    # determine N(variable_fields) 
+    for field in param_fields:
+        # if self.is_switch, treat all fields as if they are variable sized
+        if not field.type.fixed_size() or self.is_switch:
+            variable_size_fields += 1
+    # determine maxtypelen
+    for p in params:
+        maxtypelen = max(maxtypelen, len(p[0]) + len(p[1]))    
+
+    # write to .c/.h
+    indent = ' '*(len(func_name)+2)
+    param_str = []
+    for p in params:
+        typespec, pointerspec, field_name = p
+        spacing = ' '*(maxtypelen-len(typespec)-len(pointerspec))
+        param_str.append("%s%s%s  %s%s  /**< */" % (indent, typespec, spacing, pointerspec, field_name))
+    # insert function name
+    param_str[0] = "%s (%s" % (func_name, param_str[0].strip())
+    param_str = list(map(lambda x: "%s," % x, param_str))
+    for s in param_str[:-1]:
+        _hc(s)
+    _h("%s);" % param_str[-1].rstrip(','))
+    _c("%s)" % param_str[-1].rstrip(','))
+    _c('{')
+
+    code_lines = []
+    temp_vars = []
+    prefix = []
+
+    if 'serialize' == context:
+        if not self.is_switch and not self.var_followed_by_fixed_fields:
+            _c('    %s *xcb_out = *_buffer;', self.c_type)
+            _c('    unsigned int xcb_out_pad = -sizeof(%s) & 3;', self.c_type)
+            _c('    unsigned int xcb_buffer_len = sizeof(%s) + xcb_out_pad;', self.c_type)
+            _c('    unsigned int xcb_align_to;')
+        else:
+            _c('    char *xcb_out = *_buffer;')
+            _c('    unsigned int xcb_buffer_len = 0;')
+            _c('    unsigned int xcb_align_to;')
+        prefix = [('_aux', '->', self)]
+        aux_ptr = 'xcb_out'
+
+    elif context in ('unserialize', 'unpack'):
+        _c('    char *xcb_tmp = (char *)_buffer;')
+        if not self.is_switch:
+            if not self.var_followed_by_fixed_fields:
+                _c('    const %s *_aux = (%s *)_buffer;', self.c_type, self.c_type)
+                prefix = [('_aux', '->', self)]
+            else:
+                _c('    %s xcb_out;', self.c_type)
+                prefix = [('xcb_out', '.', self)]
+        else:
+            aux_var = '_aux' # default for unpack: single pointer
+            # note: unserialize not generated for switch
+            if 'unserialize' == context:
+                aux_var = '(*_aux)' # unserialize: double pointer (!)
+            prefix = [(aux_var, '->', self)]
+        aux_ptr = '*_aux'
+        _c('    unsigned int xcb_buffer_len = 0;')
+        _c('    unsigned int xcb_block_len = 0;')
+        _c('    unsigned int xcb_pad = 0;')
+        _c('    unsigned int xcb_align_to;')
+
+    elif 'sizeof' == context:
+        param_names = [p[2] for p in params]
+        if self.is_switch:
+            # switch: call _unpack()
+            _c('    %s _aux;', self.c_type)
+            _c('    return %s(%s, &_aux);', self.c_unpack_name, reduce(lambda x,y: "%s, %s" % (x, y), param_names))
+            _c('}')
+            return
+        elif self.var_followed_by_fixed_fields:
+            # special case: call _unserialize()
+            _c('    return %s(%s, NULL);', self.c_unserialize_name, reduce(lambda x,y: "%s, %s" % (x, y), param_names))
+            _c('}')
+            return
+        else:
+            _c('    char *xcb_tmp = (char *)_buffer;')
+            prefix = [('_aux', '->', self)]
+
+    count = _c_serialize_helper(context, self, code_lines, temp_vars, prefix=prefix)
+    # update variable size fields (only important for context=='serialize'
+    variable_size_fields = count
+    if 'serialize' == context:
+        temp_vars.append('    unsigned int xcb_pad = 0;')
+        temp_vars.append('    char xcb_pad0[3] = {0, 0, 0};') 
+        temp_vars.append('    struct iovec xcb_parts[%d];' % count)
+        temp_vars.append('    unsigned int xcb_parts_idx = 0;')
+        temp_vars.append('    unsigned int xcb_block_len = 0;')
+        temp_vars.append('    unsigned int i;')
+        temp_vars.append('    char *xcb_tmp;')
+    elif 'sizeof' == context:
+        # neither switch nor intermixed fixed and variable size fields:
+        # evaluate parameters directly
+        if not (self.is_switch or self.var_followed_by_fixed_fields):
+
+            # look if we have to declare an '_aux' variable at all
+            if len(list(filter(lambda x: x.find('_aux')!=-1, code_lines)))>0:
+                if not self.var_followed_by_fixed_fields:
+                    _c('    const %s *_aux = (%s *)_buffer;', self.c_type, self.c_type)
+                else:
+                    _c('    %s *_aux = malloc(sizeof(%s));', self.c_type, self.c_type)
+
+            _c('    unsigned int xcb_buffer_len = 0;')
+            _c('    unsigned int xcb_block_len = 0;')
+            _c('    unsigned int xcb_pad = 0;')        
+            _c('    unsigned int xcb_align_to;')
+
+    _c('')
+    for t in temp_vars:
+        _c(t)
+    _c('')
+    for l in code_lines:
+        _c(l)
+
+    # variable sized fields have been collected, now
+    # allocate memory and copy everything into a continuous memory area 
+    # note: this is not necessary in case of unpack
+    if context in ('serialize', 'unserialize'):
+        # unserialize: check for sizeof-only invocation
+        if 'unserialize' == context:
+            _c('')
+            _c('    if (NULL == _aux)')
+            _c('        return xcb_buffer_len;')
+
+        _c('')
+        _c('    if (NULL == %s) {', aux_ptr)
+        _c('        /* allocate memory */')
+        _c('        %s = malloc(xcb_buffer_len);', aux_ptr)
+        if 'serialize' == context:
+            _c('        *_buffer = xcb_out;')
+        _c('    }')
+        _c('')
+
+        # serialize: handle variable size fields in a loop
+        if 'serialize' == context:
+            if not self.is_switch and not self.var_followed_by_fixed_fields:
+                if len(wire_fields)>0:
+                    _c('    *xcb_out = *_aux;')
+            # copy variable size fields into the buffer
+            if variable_size_fields > 0:
+                # xcb_out padding
+                if not self.is_switch and not self.var_followed_by_fixed_fields:
+                    _c('    xcb_tmp = (char*)++xcb_out;')
+                    _c('    xcb_tmp += xcb_out_pad;')
+                else:
+                    _c('    xcb_tmp = xcb_out;')
+
+                # variable sized fields
+                _c('    for(i=0; i<xcb_parts_idx; i++) {')
+                _c('        if (0 != xcb_parts[i].iov_base && 0 != xcb_parts[i].iov_len)')
+                _c('            memcpy(xcb_tmp, xcb_parts[i].iov_base, xcb_parts[i].iov_len);')
+                _c('        if (0 != xcb_parts[i].iov_len)')
+                _c('            xcb_tmp += xcb_parts[i].iov_len;')
+                _c('    }')
+            
+        # unserialize: assign variable size fields individually
+        if 'unserialize' == context:
+            _c('    xcb_tmp = ((char *)*_aux)+xcb_buffer_len;')
+            param_fields.reverse()
+            for field in param_fields:
+                if not field.type.fixed_size():
+                    _c('    xcb_tmp -= %s_len;', field.c_field_name)
+                    _c('    memmove(xcb_tmp, %s, %s_len);', field.c_field_name, field.c_field_name)
+            _c('    *%s = xcb_out;', aux_ptr)
+ 
+    _c('')
+    _c('    return xcb_buffer_len;')
+    _c('}')
+# _c_serialize()
+
+def _c_iterator_get_end(field, accum):
+    '''
+    Figures out what C code is needed to find the end of a variable-length structure field.
+    For nested structures, recurses into its last variable-sized field.
+    For lists, calls the end function
+    '''
+    if field.type.is_container:
+        accum = field.c_accessor_name + '(' + accum + ')'
+        return _c_iterator_get_end(field.type.last_varsized_field, accum)
+    if field.type.is_list:
+        # XXX we can always use the first way
+        if field.type.member.is_simple:
+            return field.c_end_name + '(' + accum + ')'
+        else:
+            return field.type.member.c_end_name + '(' + field.c_iterator_name + '(' + accum + '))'
+
+def _c_iterator(self, name):
+    '''
+    Declares the iterator structure and next/end functions for a given type.
+    '''
+    _h_setlevel(0)
+    _h('')
+    _h('/**')
+    _h(' * @brief %s', self.c_iterator_type)
+    _h(' **/')
+    _h('typedef struct %s {', self.c_iterator_type)
+    _h('    %s *data; /**<  */', self.c_type)
+    _h('    int%s rem; /**<  */', ' ' * (len(self.c_type) - 2))
+    _h('    int%s index; /**<  */', ' ' * (len(self.c_type) - 2))
+    _h('} %s;', self.c_iterator_type)
+
+    _h_setlevel(1)
+    _c_setlevel(1)
+    _h('')
+    _h('/**')
+    _h(' * Get the next element of the iterator')
+    _h(' * @param i Pointer to a %s', self.c_iterator_type)
+    _h(' *')
+    _h(' * Get the next element in the iterator. The member rem is')
+    _h(' * decreased by one. The member data points to the next')
+    _h(' * element. The member index is increased by sizeof(%s)', self.c_type)
+    _h(' */')
+    _c('')
+    _hc('')
+    _hc('/*****************************************************************************')
+    _hc(' **')
+    _hc(' ** void %s', self.c_next_name)
+    _hc(' ** ')
+    _hc(' ** @param %s *i', self.c_iterator_type)
+    _hc(' ** @returns void')
+    _hc(' **')
+    _hc(' *****************************************************************************/')
+    _hc(' ')
+    _hc('void')
+    _h('%s (%s *i  /**< */);', self.c_next_name, self.c_iterator_type)
+    _c('%s (%s *i  /**< */)', self.c_next_name, self.c_iterator_type)
+    _c('{')
+
+    if not self.fixed_size():
+        _c('    %s *R = i->data;', self.c_type)
+
+        if self.is_union:
+            # FIXME - how to determine the size of a variable size union??
+            _c('    /* FIXME - determine the size of the union %s */', self.c_type)            
+        else:
+            if self.need_sizeof:
+                _c('    xcb_generic_iterator_t child;')
+                _c('    child.data = (%s *)(((char *)R) + %s(R));', 
+                   self.c_type, self.c_sizeof_name)
+                _c('    i->index = (char *) child.data - (char *) i->data;')
+            else:
+                _c('    xcb_generic_iterator_t child = %s;', _c_iterator_get_end(self.last_varsized_field, 'R'))
+                _c('    i->index = child.index;')
+            _c('    --i->rem;')
+            _c('    i->data = (%s *) child.data;', self.c_type)
+
+    else:
+        _c('    --i->rem;')
+        _c('    ++i->data;')
+        _c('    i->index += sizeof(%s);', self.c_type)
+
+    _c('}')
+
+    _h('')
+    _h('/**')
+    _h(' * Return the iterator pointing to the last element')
+    _h(' * @param i An %s', self.c_iterator_type)
+    _h(' * @return  The iterator pointing to the last element')
+    _h(' *')
+    _h(' * Set the current element in the iterator to the last element.')
+    _h(' * The member rem is set to 0. The member data points to the')
+    _h(' * last element.')
+    _h(' */')
+    _c('')
+    _hc('')
+    _hc('/*****************************************************************************')
+    _hc(' **')
+    _hc(' ** xcb_generic_iterator_t %s', self.c_end_name)
+    _hc(' ** ')
+    _hc(' ** @param %s i', self.c_iterator_type)
+    _hc(' ** @returns xcb_generic_iterator_t')
+    _hc(' **')
+    _hc(' *****************************************************************************/')
+    _hc(' ')
+    _hc('xcb_generic_iterator_t')
+    _h('%s (%s i  /**< */);', self.c_end_name, self.c_iterator_type)
+    _c('%s (%s i  /**< */)', self.c_end_name, self.c_iterator_type)
+    _c('{')
+    _c('    xcb_generic_iterator_t ret;')
+
+    if self.fixed_size():
+        _c('    ret.data = i.data + i.rem;')
+        _c('    ret.index = i.index + ((char *) ret.data - (char *) i.data);')
+        _c('    ret.rem = 0;')
+    else:
+        _c('    while(i.rem > 0)')
+        _c('        %s(&i);', self.c_next_name)
+        _c('    ret.data = i.data;')
+        _c('    ret.rem = i.rem;')
+        _c('    ret.index = i.index;')
+
+    _c('    return ret;')
+    _c('}')
+
+def _c_accessor_get_length(expr, field_mapping=None):
+    '''
+    Figures out what C code is needed to get a length field.
+    The field_mapping parameter can be used to change the absolute name of a length field. 
+    For fields that follow a variable-length field, use the accessor.
+    Otherwise, just reference the structure field directly.
+    '''
+
+    lenfield_name = expr.lenfield_name
+    if lenfield_name is not None:
+        if field_mapping is not None:
+            lenfield_name = field_mapping[lenfield_name][0]
+ 
+    if expr.lenfield is not None and expr.lenfield.prev_varsized_field is not None:
+        # special case: variable and fixed size fields are intermixed
+        # if the lenfield is among the fixed size fields, there is no need
+        # to call a special accessor function like <expr.lenfield.c_accessor_name + '(' + prefix + ')'>
+        return field_mapping(expr.lenfield_name)
+    elif expr.lenfield_name is not None:
+        return lenfield_name
+    else:
+        return str(expr.nmemb)
+
+def _c_accessor_get_expr(expr, field_mapping):
+    '''
+    Figures out what C code is needed to get the length of a list field.
+    The field_mapping parameter can be used to change the absolute name of a length field. 
+    Recurses for math operations.
+    Returns bitcount for value-mask fields.
+    Otherwise, uses the value of the length field.
+    '''
+    lenexp = _c_accessor_get_length(expr, field_mapping)
+
+    if expr.op == '~':
+        return '(' + '~' + _c_accessor_get_expr(expr.rhs, field_mapping) + ')'
+    elif expr.op == 'popcount':
+        return 'xcb_popcount(' + _c_accessor_get_expr(expr.rhs, field_mapping) + ')'
+    elif expr.op == 'enumref':
+        enum_name = expr.lenfield_type.name
+        constant_name = expr.lenfield_name
+        c_name = _n(enum_name + (constant_name,)).upper()
+        return c_name
+    elif expr.op == 'sumof':
+        # locate the referenced list object
+        list_obj = expr.lenfield_type
+        field = None
+        for f in expr.lenfield_parent.fields:
+            if f.field_name == expr.lenfield_name:
+                field = f
+                break
+
+        if field is None:
+            raise Exception("list field '%s' referenced by sumof not found" % expr.lenfield_name)
+        list_name = field_mapping[field.c_field_name][0]
+        c_length_func = "%s(%s)" % (field.c_length_name, list_name)
+        # note: xcb_sumof() has only been defined for integers
+        c_length_func = _c_accessor_get_expr(field.type.expr, field_mapping)
+        return 'xcb_sumof(%s, %s)' % (list_name, c_length_func)
+    elif expr.op != None:
+        return ('(' + _c_accessor_get_expr(expr.lhs, field_mapping) + 
+                ' ' + expr.op + ' ' + 
+                _c_accessor_get_expr(expr.rhs, field_mapping) + ')')
+    elif expr.bitfield:
+        return 'xcb_popcount(' + lenexp + ')'
+    else:
+        return lenexp
+
+def type_pad_type(type):
+    if type == 'void':
+        return 'char'
+    return type
+
+def _c_accessors_field(self, field):
+    '''
+    Declares the accessor functions for a non-list field that follows a variable-length field.
+    '''
+    c_type = self.c_type
+
+    # special case: switch
+    switch_obj = self if self.is_switch else None
+    if self.is_bitcase:
+        switch_obj = self.parents[-1]
+    if switch_obj is not None:
+        c_type = switch_obj.c_type
+
+    if field.type.is_simple:
+        _hc('')
+        _hc('')
+        _hc('/*****************************************************************************')
+        _hc(' ** ')
+        _hc(' ** %s %s', field.c_field_type, field.c_accessor_name)
+        _hc(' ** ')
+        _hc(' ** @param const %s *R', c_type)
+        _hc(' ** @returns %s', field.c_field_type)
+        _hc(' **')
+        _hc(' *****************************************************************************/')
+        _hc(' ')
+        _hc('%s', field.c_field_type)
+        _h('%s (const %s *R  /**< */);', field.c_accessor_name, c_type)
+        _c('%s (const %s *R  /**< */)', field.c_accessor_name, c_type)
+        _c('{')
+        if field.prev_varsized_field is None:
+            _c('    return (%s *) (R + 1);', field.c_field_type)
+        else:
+            _c('    xcb_generic_iterator_t prev = %s;', _c_iterator_get_end(field.prev_varsized_field, 'R'))
+            _c('    return * (%s *) ((char *) prev.data + XCB_TYPE_PAD(%s, prev.index) + %d);', 
+               field.c_field_type, type_pad_type(field.first_field_after_varsized.type.c_type), field.prev_varsized_offset)
+        _c('}')
+    else:
+        _hc('')
+        _hc('')
+        _hc('/*****************************************************************************')
+        _hc(' **')
+        _hc(' ** %s * %s', field.c_field_type, field.c_accessor_name)
+        _hc(' ** ')
+        _hc(' ** @param const %s *R', c_type)
+        _hc(' ** @returns %s *', field.c_field_type)
+        _hc(' **')
+        _hc(' *****************************************************************************/')
+        _hc(' ')
+        if field.type.is_switch and switch_obj is None:
+            return_type = 'void *'
+        else:
+            return_type = '%s *' % field.c_field_type
+
+        _hc(return_type)
+        _h('%s (const %s *R  /**< */);', field.c_accessor_name, c_type)
+        _c('%s (const %s *R  /**< */)', field.c_accessor_name, c_type)
+        _c('{')
+        if field.prev_varsized_field is None:
+            _c('    return (%s) (R + 1);', return_type)
+            # note: the special case 'variable fields followed by fixed size fields'
+            #       is not of any consequence here, since the ordering gets 
+            #       'corrected' in the reply function
+        else:
+            _c('    xcb_generic_iterator_t prev = %s;', _c_iterator_get_end(field.prev_varsized_field, 'R'))
+            _c('    return (%s) ((char *) prev.data + XCB_TYPE_PAD(%s, prev.index) + %d);', 
+               return_type, type_pad_type(field.first_field_after_varsized.type.c_type), field.prev_varsized_offset)
+        _c('}')
+
+    
+def _c_accessors_list(self, field):
+    '''
+    Declares the accessor functions for a list field.
+    Declares a direct-accessor function only if the list members are fixed size.
+    Declares length and get-iterator functions always.
+    '''
+    list = field.type
+    c_type = self.c_type
+
+    # special case: switch
+    # in case of switch, 2 params have to be supplied to certain accessor functions:
+    #   1. the anchestor object (request or reply)
+    #   2. the (anchestor) switch object
+    # the reason is that switch is either a child of a request/reply or nested in another switch, 
+    # so whenever we need to access a length field, we might need to refer to some anchestor type
+    switch_obj = self if self.is_switch else None
+    if self.is_bitcase:
+        switch_obj = self.parents[-1]
+    if switch_obj is not None:
+        c_type = switch_obj.c_type
+
+    params = []
+    fields = {}
+    parents = self.parents if hasattr(self, 'parents') else [self]
+    # 'R': parents[0] is always the 'toplevel' container type 
+    params.append(('const %s *R' % parents[0].c_type, parents[0]))
+    fields.update(_c_helper_field_mapping(parents[0], [('R', '->', parents[0])], flat=True))
+    # auxiliary object for 'R' parameters
+    R_obj = parents[0]
+
+    if switch_obj is not None:
+        # now look where the fields are defined that are needed to evaluate 
+        # the switch expr, and store the parent objects in accessor_params and
+        # the fields in switch_fields
+
+        # 'S': name for the 'toplevel' switch
+        toplevel_switch = parents[1]
+        params.append(('const %s *S' % toplevel_switch.c_type, toplevel_switch))
+        fields.update(_c_helper_field_mapping(toplevel_switch, [('S', '->', toplevel_switch)], flat=True))
+
+        # initialize prefix for everything "below" S
+        prefix_str = '/* %s */ S' % toplevel_switch.name[-1]
+        prefix = [(prefix_str, '->', toplevel_switch)]
+
+        # look for fields in the remaining containers
+        for p in parents[2:] + [self]:
+            # the separator between parent and child is always '.' here, 
+            # because of nested switch statements
+            if not p.is_bitcase or (p.is_bitcase and p.has_name):
+                prefix.append((p.name[-1], '.', p))
+            fields.update(_c_helper_field_mapping(p, prefix, flat=True))
+
+        # auxiliary object for 'S' parameter
+        S_obj = parents[1]
+
+    _h_setlevel(1)
+    _c_setlevel(1)
+    if list.member.fixed_size():
+        idx = 1 if switch_obj is not None else 0
+        _hc('')
+        _hc('')
+        _hc('/*****************************************************************************')
+        _hc(' **')
+        _hc(' ** %s * %s', field.c_field_type, field.c_accessor_name)
+        _hc(' ** ')
+        _hc(' ** @param %s', params[idx][0])
+        _hc(' ** @returns %s *', field.c_field_type)
+        _hc(' **')
+        _hc(' *****************************************************************************/')
+        _hc(' ')
+        _hc('%s *', field.c_field_type)
+
+        _h('%s (%s  /**< */);', field.c_accessor_name, params[idx][0])
+        _c('%s (%s  /**< */)', field.c_accessor_name, params[idx][0])
+
+        _c('{')
+        if switch_obj is not None:
+            _c('    return %s;', fields[field.c_field_name][0])
+        elif field.prev_varsized_field is None:
+            _c('    return (%s *) (R + 1);', field.c_field_type)
+        else:
+            _c('    xcb_generic_iterator_t prev = %s;', _c_iterator_get_end(field.prev_varsized_field, 'R'))
+            _c('    return (%s *) ((char *) prev.data + XCB_TYPE_PAD(%s, prev.index) + %d);', 
+               field.c_field_type, type_pad_type(field.first_field_after_varsized.type.c_type), field.prev_varsized_offset)
+        _c('}')
+
+    _hc('')
+    _hc('')
+    _hc('/*****************************************************************************')
+    _hc(' **')
+    _hc(' ** int %s', field.c_length_name)
+    _hc(' ** ')
+    _hc(' ** @param const %s *R', c_type)
+    _hc(' ** @returns int')
+    _hc(' **')
+    _hc(' *****************************************************************************/')
+    _hc(' ')
+    _hc('int')
+    if switch_obj is not None:
+        _hc('%s (const %s *R  /**< */,', field.c_length_name, R_obj.c_type)
+        spacing = ' '*(len(field.c_length_name)+2)
+        _h('%sconst %s *S /**< */);', spacing, S_obj.c_type)
+        _c('%sconst %s *S  /**< */)', spacing, S_obj.c_type)
+        length = _c_accessor_get_expr(field.type.expr, fields)
+    else:
+        _h('%s (const %s *R  /**< */);', field.c_length_name, c_type)
+        _c('%s (const %s *R  /**< */)', field.c_length_name, c_type)
+        length = _c_accessor_get_expr(field.type.expr, fields)
+    _c('{')
+    _c('    return %s;', length)
+    _c('}')
+
+    if field.type.member.is_simple:
+        _hc('')
+        _hc('')
+        _hc('/*****************************************************************************')
+        _hc(' **')
+        _hc(' ** xcb_generic_iterator_t %s', field.c_end_name)
+        _hc(' ** ')
+        _hc(' ** @param const %s *R', c_type)
+        _hc(' ** @returns xcb_generic_iterator_t')
+        _hc(' **')
+        _hc(' *****************************************************************************/')
+        _hc(' ')
+        _hc('xcb_generic_iterator_t')
+        if switch_obj is not None:
+            _hc('%s (const %s *R  /**< */,', field.c_end_name, R_obj.c_type)
+            spacing = ' '*(len(field.c_end_name)+2)
+            _h('%sconst %s *S /**< */);', spacing, S_obj.c_type)
+            _c('%sconst %s *S  /**< */)', spacing, S_obj.c_type)
+        else:
+            _h('%s (const %s *R  /**< */);', field.c_end_name, c_type)
+            _c('%s (const %s *R  /**< */)', field.c_end_name, c_type)
+        _c('{')
+        _c('    xcb_generic_iterator_t i;')
+        
+        param = 'R' if switch_obj is None else 'S'
+        if switch_obj is not None:
+            _c('    i.data = %s + %s;', fields[field.c_field_name][0], 
+               _c_accessor_get_expr(field.type.expr, fields))
+        elif field.prev_varsized_field == None:
+            _c('    i.data = ((%s *) (R + 1)) + (%s);', field.type.c_wiretype, 
+               _c_accessor_get_expr(field.type.expr, fields))
+        else:
+            _c('    xcb_generic_iterator_t child = %s;', 
+               _c_iterator_get_end(field.prev_varsized_field, 'R'))
+            _c('    i.data = ((%s *) child.data) + (%s);', field.type.c_wiretype, 
+               _c_accessor_get_expr(field.type.expr, fields))
+
+        _c('    i.rem = 0;')
+        _c('    i.index = (char *) i.data - (char *) %s;', param)
+        _c('    return i;')
+        _c('}')
+
+    else:
+        _hc('')
+        _hc('')
+        _hc('/*****************************************************************************')
+        _hc(' **')
+        _hc(' ** %s %s', field.c_iterator_type, field.c_iterator_name)
+        _hc(' ** ')
+        _hc(' ** @param const %s *R', c_type)
+        _hc(' ** @returns %s', field.c_iterator_type)
+        _hc(' **')
+        _hc(' *****************************************************************************/')
+        _hc(' ')
+
+        _hc('%s', field.c_iterator_type)
+        if switch_obj is not None:
+            _hc('%s (const %s *R  /**< */,', field.c_iterator_name, R_obj.c_type)
+            spacing = ' '*(len(field.c_iterator_name)+2)
+            _h('%sconst %s *S /**< */);', spacing, S_obj.c_type)
+            _c('%sconst %s *S  /**< */)', spacing, S_obj.c_type)
+        else:
+            _h('%s (const %s *R  /**< */);', field.c_iterator_name, c_type)
+            _c('%s (const %s *R  /**< */)', field.c_iterator_name, c_type)
+        _c('{')
+        _c('    %s i;', field.c_iterator_type)
+
+        if switch_obj is not None:
+            _c('    i.data = %s;', fields[field.c_field_name][0])
+            _c('    i.rem = %s;', _c_accessor_get_expr(field.type.expr, fields))
+        elif field.prev_varsized_field == None:
+            _c('    i.data = (%s *) (R + 1);', field.c_field_type)
+        else:
+            _c('    xcb_generic_iterator_t prev = %s;', _c_iterator_get_end(field.prev_varsized_field, 'R'))
+            _c('    i.data = (%s *) ((char *) prev.data + XCB_TYPE_PAD(%s, prev.index));', 
+               field.c_field_type, type_pad_type(field.c_field_type))
+        if switch_obj is None:
+            _c('    i.rem = %s;', _c_accessor_get_expr(field.type.expr, fields))
+        _c('    i.index = (char *) i.data - (char *) %s;', 'R' if switch_obj is None else 'S' )
+        _c('    return i;')
+        _c('}')
+
+def _c_accessors(self, name, base):
+    '''
+    Declares the accessor functions for the fields of a structure.
+    '''
+    # no accessors for switch itself - 
+    # switch always needs to be unpacked explicitly
+#    if self.is_switch:
+#        pass
+#    else:
+    if True:
+        for field in self.fields:
+            if field.type.is_list and not field.type.fixed_size():
+                _c_accessors_list(self, field)
+            elif field.prev_varsized_field is not None or not field.type.fixed_size():
+                _c_accessors_field(self, field)
+
+def c_simple(self, name):
+    '''
+    Exported function that handles cardinal type declarations.
+    These are types which are typedef'd to one of the CARDx's, char, float, etc.
+    '''
+    _c_type_setup(self, name, ())
+
+    if (self.name != name):
+        # Typedef
+        _h_setlevel(0)
+        my_name = _t(name)
+        _h('')
+        _h('typedef %s %s;', _t(self.name), my_name)
+
+        # Iterator
+        _c_iterator(self, name)
+
+def _c_complex(self):
+    '''
+    Helper function for handling all structure types.
+    Called for all structs, requests, replies, events, errors.
+    '''
+    _h_setlevel(0)
+    _h('')
+    _h('/**')
+    _h(' * @brief %s', self.c_type)
+    _h(' **/')
+    _h('typedef %s %s {', self.c_container, self.c_type)
+
+    struct_fields = []
+    maxtypelen = 0
+
+    varfield = None
+    for field in self.fields:
+        if not field.type.fixed_size() and not self.is_switch and not self.is_union:
+            varfield = field.c_field_name
+            continue
+        if field.wire:
+            struct_fields.append(field)
+    
+    for field in struct_fields:
+        length = len(field.c_field_type)
+        # account for '*' pointer_spec
+        if not field.type.fixed_size():
+            length += 1
+        maxtypelen = max(maxtypelen, length)
+
+    def _c_complex_field(self, field, space=''):
+        if (field.type.fixed_size() or 
+            # in case of switch with switch children, don't make the field a pointer
+            # necessary for unserialize to work
+            (self.is_switch and field.type.is_switch)):
+            spacing = ' ' * (maxtypelen - len(field.c_field_type))
+            _h('%s    %s%s %s%s; /**<  */', space, field.c_field_type, spacing, field.c_field_name, field.c_subscript)
+        else:
+            spacing = ' ' * (maxtypelen - (len(field.c_field_type) + 1))
+            _h('%s    %s%s *%s%s; /**<  */', space, field.c_field_type, spacing, field.c_field_name, field.c_subscript)
+
+    if not self.is_switch:
+        for field in struct_fields:
+            _c_complex_field(self, field)
+    else:
+        for b in self.bitcases:
+            space = ''
+            if b.type.has_name:
+                _h('    struct _%s {', b.c_field_name)
+                space = '    '
+            for field in b.type.fields:
+                _c_complex_field(self, field, space)
+            if b.type.has_name:
+                _h('    } %s;', b.c_field_name)
+
+    _h('} %s;', self.c_type)
+
+def c_struct(self, name):
+    '''
+    Exported function that handles structure declarations.
+    '''
+    _c_type_setup(self, name, ())
+    _c_complex(self)
+    _c_accessors(self, name, name)
+    _c_iterator(self, name)
+
+def c_union(self, name):
+    '''
+    Exported function that handles union declarations.
+    '''
+    _c_type_setup(self, name, ())
+    _c_complex(self)
+    _c_iterator(self, name)
+
+def _c_request_helper(self, name, cookie_type, void, regular, aux=False):
+    '''
+    Declares a request function.
+    '''
+
+    # Four stunningly confusing possibilities here:
+    #
+    #   Void            Non-void
+    # ------------------------------
+    # "req"            "req"
+    # 0 flag           CHECKED flag   Normal Mode
+    # void_cookie      req_cookie
+    # ------------------------------
+    # "req_checked"    "req_unchecked"
+    # CHECKED flag     0 flag         Abnormal Mode
+    # void_cookie      req_cookie
+    # ------------------------------
+
+
+    # Whether we are _checked or _unchecked
+    checked = void and not regular
+    unchecked = not void and not regular
+
+    # What kind of cookie we return
+    func_cookie = 'xcb_void_cookie_t' if void else self.c_cookie_type
+
+    # What flag is passed to xcb_request
+    func_flags = '0' if (void and regular) or (not void and not regular) else 'XCB_REQUEST_CHECKED'
+
+    # Global extension id variable or NULL for xproto
+    func_ext_global = '&' + _ns.c_ext_global_name if _ns.is_ext else '0'
+
+    # What our function name is
+    func_name = self.c_request_name if not aux else self.c_aux_name
+    if checked:
+        func_name = self.c_checked_name if not aux else self.c_aux_checked_name
+    if unchecked:
+        func_name = self.c_unchecked_name if not aux else self.c_aux_unchecked_name
+
+    param_fields = []
+    wire_fields = []
+    maxtypelen = len('xcb_connection_t')
+    serial_fields = []
+    # special case: list with variable size elements
+    list_with_var_size_elems = False
+
+    for field in self.fields:
+        if field.visible:
+            # The field should appear as a call parameter
+            param_fields.append(field)
+        if field.wire and not field.auto:
+            # We need to set the field up in the structure
+            wire_fields.append(field)
+        if field.type.need_serialize or field.type.need_sizeof:
+            serial_fields.append(field)
+        
+    for field in param_fields:
+        c_field_const_type = field.c_field_const_type 
+        if field.type.need_serialize and not aux:
+            c_field_const_type = "const void"
+        if len(c_field_const_type) > maxtypelen:
+            maxtypelen = len(c_field_const_type)
+        if field.type.is_list and not field.type.member.fixed_size():
+            list_with_var_size_elems = True
+
+    _h_setlevel(1)
+    _c_setlevel(1)
+    _h('')
+    _h('/**')
+    _h(' * Delivers a request to the X server')
+    _h(' * @param c The connection')
+    _h(' * @return A cookie')
+    _h(' *')
+    _h(' * Delivers a request to the X server.')
+    _h(' * ')
+    if checked:
+        _h(' * This form can be used only if the request will not cause')
+        _h(' * a reply to be generated. Any returned error will be')
+        _h(' * saved for handling by xcb_request_check().')
+    if unchecked:
+        _h(' * This form can be used only if the request will cause')
+        _h(' * a reply to be generated. Any returned error will be')
+        _h(' * placed in the event queue.')
+    _h(' */')
+    _c('')
+    _hc('')
+    _hc('/*****************************************************************************')
+    _hc(' **')
+    _hc(' ** %s %s', cookie_type, func_name)
+    _hc(' ** ')
+
+    spacing = ' ' * (maxtypelen - len('xcb_connection_t'))
+    _hc(' ** @param xcb_connection_t%s *c', spacing)
+
+    for field in param_fields:
+        c_field_const_type = field.c_field_const_type 
+        if field.type.need_serialize and not aux:
+            c_field_const_type = "const void"
+        spacing = ' ' * (maxtypelen - len(c_field_const_type))
+        _hc(' ** @param %s%s %s%s', c_field_const_type, spacing, field.c_pointer, field.c_field_name)
+
+    _hc(' ** @returns %s', cookie_type)
+    _hc(' **')
+    _hc(' *****************************************************************************/')
+    _hc(' ')
+    _hc('%s', cookie_type)
+
+    spacing = ' ' * (maxtypelen - len('xcb_connection_t'))
+    comma = ',' if len(param_fields) else ');'
+    _h('%s (xcb_connection_t%s *c  /**< */%s', func_name, spacing, comma)
+    comma = ',' if len(param_fields) else ')'
+    _c('%s (xcb_connection_t%s *c  /**< */%s', func_name, spacing, comma)
+
+    func_spacing = ' ' * (len(func_name) + 2)
+    count = len(param_fields)
+    for field in param_fields:
+        count = count - 1
+        c_field_const_type = field.c_field_const_type 
+        c_pointer = field.c_pointer
+        if field.type.need_serialize and not aux:
+            c_field_const_type = "const void"
+            c_pointer = '*'
+        spacing = ' ' * (maxtypelen - len(c_field_const_type))
+        comma = ',' if count else ');'
+        _h('%s%s%s %s%s  /**< */%s', func_spacing, c_field_const_type, 
+           spacing, c_pointer, field.c_field_name, comma)
+        comma = ',' if count else ')'
+        _c('%s%s%s %s%s  /**< */%s', func_spacing, c_field_const_type, 
+           spacing, c_pointer, field.c_field_name, comma)
+
+    count = 2
+    if not self.var_followed_by_fixed_fields:
+        for field in param_fields:
+            if not field.type.fixed_size():
+                count = count + 2
+                if field.type.need_serialize:
+                    # _serialize() keeps track of padding automatically
+                    count -= 1
+    dimension = count + 2
+
+    _c('{')
+    _c('    static const xcb_protocol_request_t xcb_req = {')
+    _c('        /* count */ %d,', count)
+    _c('        /* ext */ %s,', func_ext_global)
+    _c('        /* opcode */ %s,', self.c_request_name.upper())
+    _c('        /* isvoid */ %d', 1 if void else 0)
+    _c('    };')
+    _c('    ')
+
+    _c('    struct iovec xcb_parts[%d];', dimension)
+    _c('    %s xcb_ret;', func_cookie)
+    _c('    %s xcb_out;', self.c_type)
+    if self.var_followed_by_fixed_fields:
+        _c('    /* in the protocol description, variable size fields are followed by fixed size fields */')
+        _c('    void *xcb_aux = 0;')
+        
+
+    for idx, f in enumerate(serial_fields):
+        if aux:
+            _c('    void *xcb_aux%d = 0;' % (idx))
+    if list_with_var_size_elems:
+        _c('    unsigned int i;')
+        _c('    unsigned int xcb_tmp_len;')
+        _c('    char *xcb_tmp;')
+    _c('    ')
+    # simple request call tracing
+#    _c('    printf("in function %s\\n");' % func_name)     
+ 
+    # fixed size fields
+    for field in wire_fields:
+        if field.type.fixed_size():
+            if field.type.is_expr:
+                _c('    xcb_out.%s = %s;', field.c_field_name, _c_accessor_get_expr(field.type.expr, None))
+            elif field.type.is_pad:
+                if field.type.nmemb == 1:
+                    _c('    xcb_out.%s = 0;', field.c_field_name)
+                else:
+                    _c('    memset(xcb_out.%s, 0, %d);', field.c_field_name, field.type.nmemb)
+            else:
+                if field.type.nmemb == 1:
+                    _c('    xcb_out.%s = %s;', field.c_field_name, field.c_field_name)
+                else:
+                    _c('    memcpy(xcb_out.%s, %s, %d);', field.c_field_name, field.c_field_name, field.type.nmemb)
+
+    def get_serialize_args(type_obj, c_field_name, aux_var, context='serialize'):
+        serialize_args = get_serialize_params(context, type_obj, 
+                                              c_field_name, 
+                                              aux_var)[2]
+        return reduce(lambda x,y: "%s, %s" % (x,y), [a[2] for a in serialize_args])
+
+    # calls in order to free dyn. all. memory
+    free_calls = []
+
+    _c('    ')
+    if not self.var_followed_by_fixed_fields:
+        _c('    xcb_parts[2].iov_base = (char *) &xcb_out;')
+        _c('    xcb_parts[2].iov_len = sizeof(xcb_out);')
+        _c('    xcb_parts[3].iov_base = 0;')
+        _c('    xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;')
+
+        count = 4
+
+        for field in param_fields:
+            if not field.type.fixed_size():
+                _c('    /* %s %s */', field.type.c_type, field.c_field_name)
+                # default: simple cast to char *
+                if not field.type.need_serialize and not field.type.need_sizeof:
+                    _c('    xcb_parts[%d].iov_base = (char *) %s;', count, field.c_field_name)
+                    if field.type.is_list:
+                        if field.type.member.fixed_size():
+                            _c('    xcb_parts[%d].iov_len = %s * sizeof(%s);', count, 
+                               _c_accessor_get_expr(field.type.expr, None), 
+                               field.type.member.c_wiretype)
+                        else:
+                            list_length = _c_accessor_get_expr(field.type.expr, None)
+    
+                            length = ''
+                            _c("    xcb_parts[%d].iov_len = 0;" % count)
+                            _c("    xcb_tmp = (char *)%s;", field.c_field_name)
+                            _c("    for(i=0; i<%s; i++) {" % list_length)
+                            _c("        xcb_tmp_len = %s(xcb_tmp);" % 
+                                              (field.type.c_sizeof_name))
+                            _c("        xcb_parts[%d].iov_len += xcb_tmp_len;" % count)
+                            _c("        xcb_tmp += xcb_tmp_len;")
+                            _c("    }")                        
+                    else:
+                        # not supposed to happen
+                        raise Exception("unhandled variable size field %s" % field.c_field_name)
+                else:
+                    if not aux:
+                        _c('    xcb_parts[%d].iov_base = (char *) %s;', count, field.c_field_name)
+                    idx = serial_fields.index(field)
+                    aux_var = '&xcb_aux%d' % idx
+                    context = 'serialize' if aux else 'sizeof'
+                    _c('    xcb_parts[%d].iov_len = ', count)
+                    if aux:
+                        serialize_args = get_serialize_args(field.type, aux_var, field.c_field_name, context)
+                        _c('      %s (%s);', field.type.c_serialize_name, serialize_args)
+                        _c('    xcb_parts[%d].iov_base = xcb_aux%d;' % (count, idx))
+                        free_calls.append('    free(xcb_aux%d);' % idx)
+                    else:
+                        serialize_args = get_serialize_args(field.type, field.c_field_name, aux_var, context)
+                        func_name = field.type.c_sizeof_name
+                        _c('      %s (%s);', func_name, serialize_args)
+
+                count += 1
+                if not (field.type.need_serialize or field.type.need_sizeof):
+                    # the _serialize() function keeps track of padding automatically
+                    _c('    xcb_parts[%d].iov_base = 0;', count)
+                    _c('    xcb_parts[%d].iov_len = -xcb_parts[%d].iov_len & 3;', count, count-1)
+                    count += 1
+
+    # elif self.var_followed_by_fixed_fields:
+    else:
+        _c('    xcb_parts[2].iov_base = (char *) &xcb_out;')
+        # request header: opcodes + length
+        _c('    xcb_parts[2].iov_len = 2*sizeof(uint8_t) + sizeof(uint16_t);') 
+        count += 1
+        # call _serialize()
+        buffer_var = '&xcb_aux'
+        serialize_args = get_serialize_args(self, buffer_var, '&xcb_out', 'serialize')
+        _c('    xcb_parts[%d].iov_len = %s (%s);', count, self.c_serialize_name, serialize_args)
+        _c('    xcb_parts[%d].iov_base = (char *) xcb_aux;', count)
+        free_calls.append('    free(xcb_aux);')
+        # no padding necessary - _serialize() keeps track of padding automatically
+
+    _c('    ')
+    _c('    xcb_ret.sequence = xcb_send_request(c, %s, xcb_parts + 2, &xcb_req);', func_flags)
+    
+    # free dyn. all. data, if any
+    for f in free_calls:
+        _c(f)
+    _c('    return xcb_ret;')
+    _c('}')
+
+def _c_reply(self, name):
+    '''
+    Declares the function that returns the reply structure.
+    '''
+    spacing1 = ' ' * (len(self.c_cookie_type) - len('xcb_connection_t'))
+    spacing2 = ' ' * (len(self.c_cookie_type) - len('xcb_generic_error_t'))
+    spacing3 = ' ' * (len(self.c_reply_name) + 2)
+    
+    # check if _unserialize() has to be called for any field
+    def look_for_special_cases(complex_obj):
+        unserialize_fields = []
+        # no unserialize call in case of switch
+        if not complex_obj.is_switch:
+            for field in complex_obj.fields:
+                # three cases: 1. field with special case
+                #              2. container that contains special case field
+                #              3. list with special case elements
+                if field.type.var_followed_by_fixed_fields:
+                    unserialize_fields.append(field)
+                elif field.type.is_container:
+                    unserialize_fields += look_for_special_cases(field.type)
+                elif field.type.is_list:
+                    if field.type.member.var_followed_by_fixed_fields:
+                        unserialize_fields.append(field)
+                    if field.type.member.is_container:
+                        unserialize_fields += look_for_special_cases(field.type.member)
+        return unserialize_fields
+    
+    unserialize_fields = look_for_special_cases(self.reply)
+    
+    _h('')
+    _h('/**')
+    _h(' * Return the reply')
+    _h(' * @param c      The connection')
+    _h(' * @param cookie The cookie')
+    _h(' * @param e      The xcb_generic_error_t supplied')
+    _h(' *')
+    _h(' * Returns the reply of the request asked by')
+    _h(' * ')
+    _h(' * The parameter @p e supplied to this function must be NULL if')
+    _h(' * %s(). is used.', self.c_unchecked_name)
+    _h(' * Otherwise, it stores the error if any.')
+    _h(' *')
+    _h(' * The returned value must be freed by the caller using free().')
+    _h(' */')
+    _c('')
+    _hc('')
+    _hc('/*****************************************************************************')
+    _hc(' **')
+    _hc(' ** %s * %s', self.c_reply_type, self.c_reply_name)
+    _hc(' ** ')
+    _hc(' ** @param xcb_connection_t%s  *c', spacing1)
+    _hc(' ** @param %s   cookie', self.c_cookie_type)
+    _hc(' ** @param xcb_generic_error_t%s **e', spacing2)
+    _hc(' ** @returns %s *', self.c_reply_type)
+    _hc(' **')
+    _hc(' *****************************************************************************/')
+    _hc(' ')
+    _hc('%s *', self.c_reply_type)
+    _hc('%s (xcb_connection_t%s  *c  /**< */,', self.c_reply_name, spacing1)
+    _hc('%s%s   cookie  /**< */,', spacing3, self.c_cookie_type)
+    _h('%sxcb_generic_error_t%s **e  /**< */);', spacing3, spacing2)
+    _c('%sxcb_generic_error_t%s **e  /**< */)', spacing3, spacing2)
+    _c('{')
+    
+    if len(unserialize_fields)>0:
+        # certain variable size fields need to be unserialized explicitly
+        _c('    %s *reply = (%s *) xcb_wait_for_reply(c, cookie.sequence, e);', 
+           self.c_reply_type, self.c_reply_type)
+        _c('    int i;')
+        for field in unserialize_fields:
+            if field.type.is_list:
+                _c('    %s %s_iter = %s(reply);', field.c_iterator_type, field.c_field_name, field.c_iterator_name)
+                _c('    int %s_len = %s(reply);', field.c_field_name, field.c_length_name)
+                _c('    %s *%s_data;', field.c_field_type, field.c_field_name)
+            else:
+                raise Exception('not implemented: call _unserialize() in reply for non-list type %s', field.c_field_type)
+        # call _unserialize(), using the reply as source and target buffer
+        _c('    /* special cases: transform parts of the reply to match XCB data structures */')
+        for field in unserialize_fields:
+            if field.type.is_list:
+                _c('    for(i=0; i<%s_len; i++) {', field.c_field_name)
+                _c('        %s_data = %s_iter.data;', field.c_field_name, field.c_field_name)
+                _c('        %s((const void *)%s_data, &%s_data);', field.type.c_unserialize_name, 
+                   field.c_field_name, field.c_field_name)
+                _c('        %s(&%s_iter);', field.type.c_next_name, field.c_field_name)
+                _c('    }')
+        # return the transformed reply
+        _c('    return reply;')
+    
+    else:
+        _c('    return (%s *) xcb_wait_for_reply(c, cookie.sequence, e);', self.c_reply_type)
+
+    _c('}')
+
+def _c_opcode(name, opcode):
+    '''
+    Declares the opcode define for requests, events, and errors.
+    '''
+    _h_setlevel(0)
+    _h('')
+    _h('/** Opcode for %s. */', _n(name))
+    _h('#define %s %s', _n(name).upper(), opcode)
+    
+def _c_cookie(self, name):
+    '''
+    Declares the cookie type for a non-void request.
+    '''
+    _h_setlevel(0)
+    _h('')
+    _h('/**')
+    _h(' * @brief %s', self.c_cookie_type)
+    _h(' **/')
+    _h('typedef struct %s {', self.c_cookie_type)
+    _h('    unsigned int sequence; /**<  */')
+    _h('} %s;', self.c_cookie_type)
+
+def c_request(self, name):
+    '''
+    Exported function that handles request declarations.
+    '''
+    _c_type_setup(self, name, ('request',))
+
+    if self.reply:
+        # Cookie type declaration
+        _c_cookie(self, name)
+
+    # Opcode define
+    _c_opcode(name, self.opcode)
+
+    # Request structure declaration
+    _c_complex(self)
+
+    if self.reply:
+        _c_type_setup(self.reply, name, ('reply',))
+        # Reply structure definition
+        _c_complex(self.reply)
+        # Request prototypes
+        _c_request_helper(self, name, self.c_cookie_type, False, True)
+        _c_request_helper(self, name, self.c_cookie_type, False, False)
+        if self.need_aux:
+            _c_request_helper(self, name, self.c_cookie_type, False, True, True)
+            _c_request_helper(self, name, self.c_cookie_type, False, False, True)
+        # Reply accessors
+        _c_accessors(self.reply, name + ('reply',), name)
+        _c_reply(self, name)
+    else:
+        # Request prototypes
+        _c_request_helper(self, name, 'xcb_void_cookie_t', True, False)
+        _c_request_helper(self, name, 'xcb_void_cookie_t', True, True)
+        if self.need_aux:
+            _c_request_helper(self, name, 'xcb_void_cookie_t', True, False, True)
+            _c_request_helper(self, name, 'xcb_void_cookie_t', True, True, True)
+
+
+def c_event(self, name):
+    '''
+    Exported function that handles event declarations.
+    '''
+    _c_type_setup(self, name, ('event',))
+
+    # Opcode define
+    _c_opcode(name, self.opcodes[name])
+
+    if self.name == name:
+        # Structure definition
+        _c_complex(self)
+    else:
+        # Typedef
+        _h('')
+        _h('typedef %s %s;', _t(self.name + ('event',)), _t(name + ('event',)))
+
+def c_error(self, name):
+    '''
+    Exported function that handles error declarations.
+    '''
+    _c_type_setup(self, name, ('error',))
+
+    # Opcode define
+    _c_opcode(name, self.opcodes[name])
+
+    if self.name == name:
+        # Structure definition
+        _c_complex(self)
+    else:
+        # Typedef
+        _h('')
+        _h('typedef %s %s;', _t(self.name + ('error',)), _t(name + ('error',)))
+
+
+# Main routine starts here
+
+# Must create an "output" dictionary before any xcbgen imports.
+output = {'open'    : c_open,
+          'close'   : c_close,
+          'simple'  : c_simple,
+          'enum'    : c_enum,
+          'struct'  : c_struct,
+          'union'   : c_union,
+          'request' : c_request,
+          'event'   : c_event,
+          'error'   : c_error, 
+          }
+
+# Boilerplate below this point
+
+# Check for the argument that specifies path to the xcbgen python package.
+try:
+    opts, args = getopt.getopt(sys.argv[1:], 'p:')
+except getopt.GetoptError as err:
+    print(err)
+    print('Usage: c_client.py [-p path] file.xml')
+    sys.exit(1)
+
+for (opt, arg) in opts:
+    if opt == '-p':
+        sys.path.insert(1, arg)
+
+# Import the module class
+try:
+    from xcbgen.state import Module
+except ImportError:
+    print('''
+Failed to load the xcbgen Python package!
+Make sure that xcb/proto installed it on your Python path.
+If not, you will need to create a .pth file or define $PYTHONPATH
+to extend the path.
+Refer to the README file in xcb/proto for more info.
+''')
+    raise
+
+# Parse the xml header
+module = Module(args[0], output)
+
+# Build type-registry and resolve type dependencies
+module.register()
+module.resolve()
+
+# Output the code
+module.generate()
diff --git a/libxcb/src/xcb.h b/libxcb/src/xcb.h
index cfe311ecf..3ee7965d2 100644
--- a/libxcb/src/xcb.h
+++ b/libxcb/src/xcb.h
@@ -1,507 +1,507 @@
-/*
- * Copyright (C) 2001-2006 Bart Massey, Jamey Sharp, and Josh Triplett.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * Except as contained in this notice, the names of the authors or their
- * institutions shall not be used in advertising or otherwise to promote the
- * sale, use or other dealings in this Software without prior written
- * authorization from the authors.
- */
-
-#ifndef __XCB_H__
-#define __XCB_H__
-#include <sys/types.h>
-
-#if defined(__solaris__)
-#include <inttypes.h>
-#else
-#include <stdint.h>
-#endif
-
-#ifndef _WIN32
-#include <sys/uio.h>
-#else
-#include "xcb_windefs.h"
-#endif
-#include <pthread.h>
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * @file xcb.h
- */
-
-/**
- * @defgroup XCB_Core_API XCB Core API
- * @brief Core API of the XCB library.
- *
- * @{
- */
-
-/* Pre-defined constants */
-
-/** Current protocol version */
-#define X_PROTOCOL 11
-
-/** Current minor version */
-#define X_PROTOCOL_REVISION 0
-
-/** X_TCP_PORT + display number = server port for TCP transport */
-#define X_TCP_PORT 6000
-
-#define XCB_TYPE_PAD(T,I) (-(I) & (sizeof(T) > 4 ? 3 : sizeof(T) - 1))
-
-/* Opaque structures */
-
-/**
- * @brief XCB Connection structure.
- *
- * A structure that contain all data that  XCB needs to communicate with an X server.
- */
-typedef struct xcb_connection_t xcb_connection_t;  /**< Opaque structure containing all data that  XCB needs to communicate with an X server. */
-
-
-/* Other types */
-
-/**
- * @brief Generic iterator.
- *
- * A generic iterator structure.
- */
-typedef struct {
-    void *data;   /**< Data of the current iterator */
-    int rem;    /**< remaining elements */
-    int index;  /**< index of the current iterator */
-} xcb_generic_iterator_t;
-
-/**
- * @brief Generic reply.
- *
- * A generic reply structure.
- */
-typedef struct {
-    uint8_t   response_type;  /**< Type of the response */
-    uint8_t  pad0;           /**< Padding */
-    uint16_t sequence;       /**< Sequence number */
-    uint32_t length;         /**< Length of the response */
-} xcb_generic_reply_t;
-
-/**
- * @brief Generic event.
- *
- * A generic event structure.
- */
-typedef struct {
-    uint8_t   response_type;  /**< Type of the response */
-    uint8_t  pad0;           /**< Padding */
-    uint16_t sequence;       /**< Sequence number */
-    uint32_t pad[7];         /**< Padding */
-    uint32_t full_sequence;  /**< full sequence */
-} xcb_generic_event_t;
-
-/**
- * @brief GE event
- *
- * An event as sent by the XGE extension. The length field specifies the
- * number of 4-byte blocks trailing the struct.
- */
-typedef struct {
-    uint8_t  response_type;  /**< Type of the response */
-    uint8_t  pad0;           /**< Padding */
-    uint16_t sequence;       /**< Sequence number */
-    uint32_t length;
-    uint16_t event_type;
-    uint16_t pad1;
-    uint32_t pad[5];         /**< Padding */
-    uint32_t full_sequence;  /**< full sequence */
-} xcb_ge_event_t;
-
-/**
- * @brief Generic error.
- *
- * A generic error structure.
- */
-typedef struct {
-    uint8_t   response_type;  /**< Type of the response */
-    uint8_t   error_code;     /**< Error code */
-    uint16_t sequence;       /**< Sequence number */
-    uint32_t resource_id;     /** < Resource ID for requests with side effects only */
-    uint16_t minor_code;      /** < Minor opcode of the failed request */
-    uint8_t major_code;       /** < Major opcode of the failed request */
-    uint8_t pad0;
-    uint32_t pad[5];         /**< Padding */
-    uint32_t full_sequence;  /**< full sequence */
-} xcb_generic_error_t;
-
-/**
- * @brief Generic cookie.
- *
- * A generic cookie structure.
- */
-typedef struct {
-    unsigned int sequence;  /**< Sequence number */
-} xcb_void_cookie_t;
-
-
-/* Include the generated xproto header. */
-#include "xproto.h"
-
-
-/** XCB_NONE is the universal null resource or null atom parameter value for many core X requests */
-#define XCB_NONE 0L
-
-/** XCB_COPY_FROM_PARENT can be used for many xcb_create_window parameters */
-#define XCB_COPY_FROM_PARENT 0L
-
-/** XCB_CURRENT_TIME can be used in most requests that take an xcb_timestamp_t */
-#define XCB_CURRENT_TIME 0L
-
-/** XCB_NO_SYMBOL fills in unused entries in xcb_keysym_t tables */
-#define XCB_NO_SYMBOL 0L
-
-
-/* xcb_auth.c */
-
-/**
- * @brief Container for authorization information.
- *
- * A container for authorization information to be sent to the X server.
- */
-typedef struct xcb_auth_info_t {
-    int   namelen;  /**< Length of the string name (as returned by strlen). */
-    char *name;     /**< String containing the authentication protocol name, such as "MIT-MAGIC-COOKIE-1" or "XDM-AUTHORIZATION-1". */
-    int   datalen;  /**< Length of the data member. */
-    char *data;   /**< Data interpreted in a protocol-specific manner. */
-} xcb_auth_info_t;
-
-
-/* xcb_out.c */
-
-/**
- * @brief Forces any buffered output to be written to the server.
- * @param c: The connection to the X server.
- * @return > @c 0 on success, <= @c 0 otherwise.
- *
- * Forces any buffered output to be written to the server. Blocks
- * until the write is complete.
- */
-int xcb_flush(xcb_connection_t *c);
-
-/**
- * @brief Returns the maximum request length that this server accepts.
- * @param c: The connection to the X server.
- * @return The maximum request length field.
- *
- * In the absence of the BIG-REQUESTS extension, returns the
- * maximum request length field from the connection setup data, which
- * may be as much as 65535. If the server supports BIG-REQUESTS, then
- * the maximum request length field from the reply to the
- * BigRequestsEnable request will be returned instead.
- *
- * Note that this length is measured in four-byte units, making the
- * theoretical maximum lengths roughly 256kB without BIG-REQUESTS and
- * 16GB with.
- */
-uint32_t xcb_get_maximum_request_length(xcb_connection_t *c);
-
-/**
- * @brief Prefetch the maximum request length without blocking.
- * @param c: The connection to the X server.
- *
- * Without blocking, does as much work as possible toward computing
- * the maximum request length accepted by the X server.
- *
- * Invoking this function may cause a call to xcb_big_requests_enable,
- * but will not block waiting for the reply.
- * xcb_get_maximum_request_length will return the prefetched data
- * after possibly blocking while the reply is retrieved.
- *
- * Note that in order for this function to be fully non-blocking, the
- * application must previously have called
- * xcb_prefetch_extension_data(c, &xcb_big_requests_id) and the reply
- * must have already arrived.
- */
-void xcb_prefetch_maximum_request_length(xcb_connection_t *c);
-
-
-/* xcb_in.c */
-
-/**
- * @brief Returns the next event or error from the server.
- * @param c: The connection to the X server.
- * @return The next event from the server.
- *
- * Returns the next event or error from the server, or returns null in
- * the event of an I/O error. Blocks until either an event or error
- * arrive, or an I/O error occurs.
- */
-xcb_generic_event_t *xcb_wait_for_event(xcb_connection_t *c);
-
-/**
- * @brief Returns the next event or error from the server.
- * @param c: The connection to the X server.
- * error status of the operation.
- * @return The next event from the server.
- *
- * Returns the next event or error from the server, if one is
- * available, or returns @c NULL otherwise. If no event is available, that
- * might be because an I/O error like connection close occurred while
- * attempting to read the next event, in which case the connection is
- * shut down when this function returns.
- */
-xcb_generic_event_t *xcb_poll_for_event(xcb_connection_t *c);
-
-/**
- * @brief Returns the next event without reading from the connection.
- * @param c: The connection to the X server.
- * @return The next already queued event from the server.
- *
- * This is a version of xcb_poll_for_event that only examines the
- * event queue for new events. The function doesn't try to read new
- * events from the connection if no queued events are found.
- *
- * This function is useful for callers that know in advance that all
- * interesting events have already been read from the connection. For
- * example, callers might use xcb_wait_for_reply and be interested
- * only of events that preceded a specific reply.
- */
-xcb_generic_event_t *xcb_poll_for_queued_event(xcb_connection_t *c);
-
-/**
- * @brief Return the error for a request, or NULL if none can ever arrive.
- * @param c: The connection to the X server.
- * @param cookie: The request cookie.
- * @return The error for the request, or NULL if none can ever arrive.
- *
- * The xcb_void_cookie_t cookie supplied to this function must have resulted
- * from a call to xcb_[request_name]_checked().  This function will block
- * until one of two conditions happens.  If an error is received, it will be
- * returned.  If a reply to a subsequent request has already arrived, no error
- * can arrive for this request, so this function will return NULL.
- *
- * Note that this function will perform a sync if needed to ensure that the
- * sequence number will advance beyond that provided in cookie; this is a
- * convenience to avoid races in determining whether the sync is needed.
- */
-xcb_generic_error_t *xcb_request_check(xcb_connection_t *c, xcb_void_cookie_t cookie);
-
-/**
- * @brief Discards the reply for a request.
- * @param c: The connection to the X server.
- * @param sequence: The request sequence number from a cookie.
- *
- * Discards the reply for a request. Additionally, any error generated
- * by the request is also discarded (unless it was an _unchecked request
- * and the error has already arrived).
- *
- * This function will not block even if the reply is not yet available.
- *
- * Note that the sequence really does have to come from an xcb cookie;
- * this function is not designed to operate on socket-handoff replies.
- */
-void xcb_discard_reply(xcb_connection_t *c, unsigned int sequence);
-
-
-/* xcb_ext.c */
-
-/**
- * @typedef typedef struct xcb_extension_t xcb_extension_t
- */
-typedef struct xcb_extension_t xcb_extension_t;  /**< Opaque structure used as key for xcb_get_extension_data_t. */
-
-/**
- * @brief Caches reply information from QueryExtension requests.
- * @param c: The connection.
- * @param ext: The extension data.
- * @return A pointer to the xcb_query_extension_reply_t for the extension.
- *
- * This function is the primary interface to the "extension cache",
- * which caches reply information from QueryExtension
- * requests. Invoking this function may cause a call to
- * xcb_query_extension to retrieve extension information from the
- * server, and may block until extension data is received from the
- * server.
- *
- * The result must not be freed. This storage is managed by the cache
- * itself.
- */
-const xcb_query_extension_reply_t *xcb_get_extension_data(xcb_connection_t *c, xcb_extension_t *ext);
-
-/**
- * @brief Prefetch of extension data into the extension cache
- * @param c: The connection.
- * @param ext: The extension data.
- *
- * This function allows a "prefetch" of extension data into the
- * extension cache. Invoking the function may cause a call to
- * xcb_query_extension, but will not block waiting for the
- * reply. xcb_get_extension_data will return the prefetched data after
- * possibly blocking while it is retrieved.
- */
-void xcb_prefetch_extension_data(xcb_connection_t *c, xcb_extension_t *ext);
-
-
-/* xcb_conn.c */
-
-/**
- * @brief Access the data returned by the server.
- * @param c: The connection.
- * @return A pointer to an xcb_setup_t structure.
- *
- * Accessor for the data returned by the server when the xcb_connection_t
- * was initialized. This data includes
- * - the server's required format for images,
- * - a list of available visuals,
- * - a list of available screens,
- * - the server's maximum request length (in the absence of the
- * BIG-REQUESTS extension),
- * - and other assorted information.
- *
- * See the X protocol specification for more details.
- *
- * The result must not be freed.
- */
-const xcb_setup_t *xcb_get_setup(xcb_connection_t *c);
-
-/**
- * @brief Access the file descriptor of the connection.
- * @param c: The connection.
- * @return The file descriptor.
- *
- * Accessor for the file descriptor that was passed to the
- * xcb_connect_to_fd call that returned @p c.
- */
-int xcb_get_file_descriptor(xcb_connection_t *c);
-
-/**
- * @brief Test whether the connection has shut down due to a fatal error.
- * @param c: The connection.
- * @return 1 if the connection is in an error state; 0 otherwise.
- *
- * Some errors that occur in the context of an xcb_connection_t
- * are unrecoverable. When such an error occurs, the
- * connection is shut down and further operations on the
- * xcb_connection_t have no effect.
- *
- * @todo Other functions should document the conditions in
- * which they shut down the connection.
- */
-int xcb_connection_has_error(xcb_connection_t *c);
-
-/**
- * @brief Connects to the X server.
- * @param fd: The file descriptor.
- * @param auth_info: Authentication data.
- * @return A newly allocated xcb_connection_t structure.
- *
- * Connects to an X server, given the open socket @p fd and the
- * xcb_auth_info_t @p auth_info. The file descriptor @p fd is
- * bidirectionally connected to an X server. If the connection
- * should be unauthenticated, @p auth_info must be @c
- * NULL.
- */
-xcb_connection_t *xcb_connect_to_fd(int fd, xcb_auth_info_t *auth_info);
-
-/**
- * @brief Closes the connection.
- * @param c: The connection.
- *
- * Closes the file descriptor and frees all memory associated with the
- * connection @c c.
- */
-void xcb_disconnect(xcb_connection_t *c);
-
-
-/* xcb_util.c */
-
-/**
- * @brief Parses a display string name in the form documented by X(7x).
- * @param name: The name of the display.
- * @param host: A pointer to a malloc'd copy of the hostname.
- * @param display: A pointer to the display number.
- * @param screen: A pointer to the screen number.
- * @return 0 on failure, non 0 otherwise.
- *
- * Parses the display string name @p display_name in the form
- * documented by X(7x). Has no side effects on failure. If
- * @p displayname is @c NULL or empty, it uses the environment
- * variable DISPLAY. @p hostp is a pointer to a newly allocated string
- * that contain the host name. @p displayp is set to the display
- * number and @p screenp to the preferred screen number. @p screenp
- * can be @c NULL. If @p displayname does not contain a screen number,
- * it is set to @c 0.
- */
-int xcb_parse_display(const char *name, char **host, int *display, int *screen);
-
-/**
- * @brief Connects to the X server.
- * @param displayname: The name of the display.
- * @param screenp: A pointer to a preferred screen number.
- * @return A newly allocated xcb_connection_t structure.
- *
- * Connects to the X server specified by @p displayname. If @p
- * displayname is @c NULL, uses the value of the DISPLAY environment
- * variable. If a particular screen on that server is preferred, the
- * int pointed to by @p screenp (if not @c NULL) will be set to that
- * screen; otherwise the screen will be set to 0.
- */
-xcb_connection_t *xcb_connect(const char *displayname, int *screenp);
-
-/**
- * @brief Connects to the X server, using an authorization information.
- * @param display: The name of the display.
- * @param auth: The authorization information.
- * @param screen: A pointer to a preferred screen number.
- * @return A newly allocated xcb_connection_t structure.
- *
- * Connects to the X server specified by @p displayname, using the
- * authorization @p auth. If a particular screen on that server is
- * preferred, the int pointed to by @p screenp (if not @c NULL) will
- * be set to that screen; otherwise @p screenp will be set to 0.
- */
-xcb_connection_t *xcb_connect_to_display_with_auth_info(const char *display, xcb_auth_info_t *auth, int *screen);
-
-
-/* xcb_xid.c */
-
-/**
- * @brief Allocates an XID for a new object.
- * @param c: The connection.
- * @return A newly allocated XID.
- *
- * Allocates an XID for a new object. Typically used just prior to
- * various object creation functions, such as xcb_create_window.
- */
-uint32_t xcb_generate_id(xcb_connection_t *c);
-
-
-/**
- * @}
- */
-
-#ifdef __cplusplus
-}
-#endif
-
-
-#endif /* __XCB_H__ */
+/*
+ * Copyright (C) 2001-2006 Bart Massey, Jamey Sharp, and Josh Triplett.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the names of the authors or their
+ * institutions shall not be used in advertising or otherwise to promote the
+ * sale, use or other dealings in this Software without prior written
+ * authorization from the authors.
+ */
+
+#ifndef __XCB_H__
+#define __XCB_H__
+#include <sys/types.h>
+
+#if defined(__solaris__)
+#include <inttypes.h>
+#else
+#include <stdint.h>
+#endif
+
+#ifndef _WIN32
+#include <sys/uio.h>
+#else
+#include "xcb_windefs.h"
+#endif
+#include <pthread.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @file xcb.h
+ */
+
+/**
+ * @defgroup XCB_Core_API XCB Core API
+ * @brief Core API of the XCB library.
+ *
+ * @{
+ */
+
+/* Pre-defined constants */
+
+/** Current protocol version */
+#define X_PROTOCOL 11
+
+/** Current minor version */
+#define X_PROTOCOL_REVISION 0
+
+/** X_TCP_PORT + display number = server port for TCP transport */
+#define X_TCP_PORT 6000
+
+#define XCB_TYPE_PAD(T,I) (-(I) & (sizeof(T) > 4 ? 3 : sizeof(T) - 1))
+
+/* Opaque structures */
+
+/**
+ * @brief XCB Connection structure.
+ *
+ * A structure that contain all data that  XCB needs to communicate with an X server.
+ */
+typedef struct xcb_connection_t xcb_connection_t;  /**< Opaque structure containing all data that  XCB needs to communicate with an X server. */
+
+
+/* Other types */
+
+/**
+ * @brief Generic iterator.
+ *
+ * A generic iterator structure.
+ */
+typedef struct {
+    void *data;   /**< Data of the current iterator */
+    int rem;    /**< remaining elements */
+    int index;  /**< index of the current iterator */
+} xcb_generic_iterator_t;
+
+/**
+ * @brief Generic reply.
+ *
+ * A generic reply structure.
+ */
+typedef struct {
+    uint8_t   response_type;  /**< Type of the response */
+    uint8_t  pad0;           /**< Padding */
+    uint16_t sequence;       /**< Sequence number */
+    uint32_t length;         /**< Length of the response */
+} xcb_generic_reply_t;
+
+/**
+ * @brief Generic event.
+ *
+ * A generic event structure.
+ */
+typedef struct {
+    uint8_t   response_type;  /**< Type of the response */
+    uint8_t  pad0;           /**< Padding */
+    uint16_t sequence;       /**< Sequence number */
+    uint32_t pad[7];         /**< Padding */
+    uint32_t full_sequence;  /**< full sequence */
+} xcb_generic_event_t;
+
+/**
+ * @brief GE event
+ *
+ * An event as sent by the XGE extension. The length field specifies the
+ * number of 4-byte blocks trailing the struct.
+ */
+typedef struct {
+    uint8_t  response_type;  /**< Type of the response */
+    uint8_t  pad0;           /**< Padding */
+    uint16_t sequence;       /**< Sequence number */
+    uint32_t length;
+    uint16_t event_type;
+    uint16_t pad1;
+    uint32_t pad[5];         /**< Padding */
+    uint32_t full_sequence;  /**< full sequence */
+} xcb_ge_event_t;
+
+/**
+ * @brief Generic error.
+ *
+ * A generic error structure.
+ */
+typedef struct {
+    uint8_t   response_type;  /**< Type of the response */
+    uint8_t   error_code;     /**< Error code */
+    uint16_t sequence;       /**< Sequence number */
+    uint32_t resource_id;     /** < Resource ID for requests with side effects only */
+    uint16_t minor_code;      /** < Minor opcode of the failed request */
+    uint8_t major_code;       /** < Major opcode of the failed request */
+    uint8_t pad0;
+    uint32_t pad[5];         /**< Padding */
+    uint32_t full_sequence;  /**< full sequence */
+} xcb_generic_error_t;
+
+/**
+ * @brief Generic cookie.
+ *
+ * A generic cookie structure.
+ */
+typedef struct {
+    unsigned int sequence;  /**< Sequence number */
+} xcb_void_cookie_t;
+
+
+/* Include the generated xproto header. */
+#include "xproto.h"
+
+
+/** XCB_NONE is the universal null resource or null atom parameter value for many core X requests */
+#define XCB_NONE 0L
+
+/** XCB_COPY_FROM_PARENT can be used for many xcb_create_window parameters */
+#define XCB_COPY_FROM_PARENT 0L
+
+/** XCB_CURRENT_TIME can be used in most requests that take an xcb_timestamp_t */
+#define XCB_CURRENT_TIME 0L
+
+/** XCB_NO_SYMBOL fills in unused entries in xcb_keysym_t tables */
+#define XCB_NO_SYMBOL 0L
+
+
+/* xcb_auth.c */
+
+/**
+ * @brief Container for authorization information.
+ *
+ * A container for authorization information to be sent to the X server.
+ */
+typedef struct xcb_auth_info_t {
+    int   namelen;  /**< Length of the string name (as returned by strlen). */
+    char *name;     /**< String containing the authentication protocol name, such as "MIT-MAGIC-COOKIE-1" or "XDM-AUTHORIZATION-1". */
+    int   datalen;  /**< Length of the data member. */
+    char *data;   /**< Data interpreted in a protocol-specific manner. */
+} xcb_auth_info_t;
+
+
+/* xcb_out.c */
+
+/**
+ * @brief Forces any buffered output to be written to the server.
+ * @param c: The connection to the X server.
+ * @return > @c 0 on success, <= @c 0 otherwise.
+ *
+ * Forces any buffered output to be written to the server. Blocks
+ * until the write is complete.
+ */
+int xcb_flush(xcb_connection_t *c);
+
+/**
+ * @brief Returns the maximum request length that this server accepts.
+ * @param c: The connection to the X server.
+ * @return The maximum request length field.
+ *
+ * In the absence of the BIG-REQUESTS extension, returns the
+ * maximum request length field from the connection setup data, which
+ * may be as much as 65535. If the server supports BIG-REQUESTS, then
+ * the maximum request length field from the reply to the
+ * BigRequestsEnable request will be returned instead.
+ *
+ * Note that this length is measured in four-byte units, making the
+ * theoretical maximum lengths roughly 256kB without BIG-REQUESTS and
+ * 16GB with.
+ */
+uint32_t xcb_get_maximum_request_length(xcb_connection_t *c);
+
+/**
+ * @brief Prefetch the maximum request length without blocking.
+ * @param c: The connection to the X server.
+ *
+ * Without blocking, does as much work as possible toward computing
+ * the maximum request length accepted by the X server.
+ *
+ * Invoking this function may cause a call to xcb_big_requests_enable,
+ * but will not block waiting for the reply.
+ * xcb_get_maximum_request_length will return the prefetched data
+ * after possibly blocking while the reply is retrieved.
+ *
+ * Note that in order for this function to be fully non-blocking, the
+ * application must previously have called
+ * xcb_prefetch_extension_data(c, &xcb_big_requests_id) and the reply
+ * must have already arrived.
+ */
+void xcb_prefetch_maximum_request_length(xcb_connection_t *c);
+
+
+/* xcb_in.c */
+
+/**
+ * @brief Returns the next event or error from the server.
+ * @param c: The connection to the X server.
+ * @return The next event from the server.
+ *
+ * Returns the next event or error from the server, or returns null in
+ * the event of an I/O error. Blocks until either an event or error
+ * arrive, or an I/O error occurs.
+ */
+xcb_generic_event_t *xcb_wait_for_event(xcb_connection_t *c);
+
+/**
+ * @brief Returns the next event or error from the server.
+ * @param c: The connection to the X server.
+ * error status of the operation.
+ * @return The next event from the server.
+ *
+ * Returns the next event or error from the server, if one is
+ * available, or returns @c NULL otherwise. If no event is available, that
+ * might be because an I/O error like connection close occurred while
+ * attempting to read the next event, in which case the connection is
+ * shut down when this function returns.
+ */
+xcb_generic_event_t *xcb_poll_for_event(xcb_connection_t *c);
+
+/**
+ * @brief Returns the next event without reading from the connection.
+ * @param c: The connection to the X server.
+ * @return The next already queued event from the server.
+ *
+ * This is a version of xcb_poll_for_event that only examines the
+ * event queue for new events. The function doesn't try to read new
+ * events from the connection if no queued events are found.
+ *
+ * This function is useful for callers that know in advance that all
+ * interesting events have already been read from the connection. For
+ * example, callers might use xcb_wait_for_reply and be interested
+ * only of events that preceded a specific reply.
+ */
+xcb_generic_event_t *xcb_poll_for_queued_event(xcb_connection_t *c);
+
+/**
+ * @brief Return the error for a request, or NULL if none can ever arrive.
+ * @param c: The connection to the X server.
+ * @param cookie: The request cookie.
+ * @return The error for the request, or NULL if none can ever arrive.
+ *
+ * The xcb_void_cookie_t cookie supplied to this function must have resulted
+ * from a call to xcb_[request_name]_checked().  This function will block
+ * until one of two conditions happens.  If an error is received, it will be
+ * returned.  If a reply to a subsequent request has already arrived, no error
+ * can arrive for this request, so this function will return NULL.
+ *
+ * Note that this function will perform a sync if needed to ensure that the
+ * sequence number will advance beyond that provided in cookie; this is a
+ * convenience to avoid races in determining whether the sync is needed.
+ */
+xcb_generic_error_t *xcb_request_check(xcb_connection_t *c, xcb_void_cookie_t cookie);
+
+/**
+ * @brief Discards the reply for a request.
+ * @param c: The connection to the X server.
+ * @param sequence: The request sequence number from a cookie.
+ *
+ * Discards the reply for a request. Additionally, any error generated
+ * by the request is also discarded (unless it was an _unchecked request
+ * and the error has already arrived).
+ *
+ * This function will not block even if the reply is not yet available.
+ *
+ * Note that the sequence really does have to come from an xcb cookie;
+ * this function is not designed to operate on socket-handoff replies.
+ */
+void xcb_discard_reply(xcb_connection_t *c, unsigned int sequence);
+
+
+/* xcb_ext.c */
+
+/**
+ * @typedef typedef struct xcb_extension_t xcb_extension_t
+ */
+typedef struct xcb_extension_t xcb_extension_t;  /**< Opaque structure used as key for xcb_get_extension_data_t. */
+
+/**
+ * @brief Caches reply information from QueryExtension requests.
+ * @param c: The connection.
+ * @param ext: The extension data.
+ * @return A pointer to the xcb_query_extension_reply_t for the extension.
+ *
+ * This function is the primary interface to the "extension cache",
+ * which caches reply information from QueryExtension
+ * requests. Invoking this function may cause a call to
+ * xcb_query_extension to retrieve extension information from the
+ * server, and may block until extension data is received from the
+ * server.
+ *
+ * The result must not be freed. This storage is managed by the cache
+ * itself.
+ */
+const xcb_query_extension_reply_t *xcb_get_extension_data(xcb_connection_t *c, xcb_extension_t *ext);
+
+/**
+ * @brief Prefetch of extension data into the extension cache
+ * @param c: The connection.
+ * @param ext: The extension data.
+ *
+ * This function allows a "prefetch" of extension data into the
+ * extension cache. Invoking the function may cause a call to
+ * xcb_query_extension, but will not block waiting for the
+ * reply. xcb_get_extension_data will return the prefetched data after
+ * possibly blocking while it is retrieved.
+ */
+void xcb_prefetch_extension_data(xcb_connection_t *c, xcb_extension_t *ext);
+
+
+/* xcb_conn.c */
+
+/**
+ * @brief Access the data returned by the server.
+ * @param c: The connection.
+ * @return A pointer to an xcb_setup_t structure.
+ *
+ * Accessor for the data returned by the server when the xcb_connection_t
+ * was initialized. This data includes
+ * - the server's required format for images,
+ * - a list of available visuals,
+ * - a list of available screens,
+ * - the server's maximum request length (in the absence of the
+ * BIG-REQUESTS extension),
+ * - and other assorted information.
+ *
+ * See the X protocol specification for more details.
+ *
+ * The result must not be freed.
+ */
+const xcb_setup_t *xcb_get_setup(xcb_connection_t *c);
+
+/**
+ * @brief Access the file descriptor of the connection.
+ * @param c: The connection.
+ * @return The file descriptor.
+ *
+ * Accessor for the file descriptor that was passed to the
+ * xcb_connect_to_fd call that returned @p c.
+ */
+int xcb_get_file_descriptor(xcb_connection_t *c);
+
+/**
+ * @brief Test whether the connection has shut down due to a fatal error.
+ * @param c: The connection.
+ * @return 1 if the connection is in an error state; 0 otherwise.
+ *
+ * Some errors that occur in the context of an xcb_connection_t
+ * are unrecoverable. When such an error occurs, the
+ * connection is shut down and further operations on the
+ * xcb_connection_t have no effect.
+ *
+ * @todo Other functions should document the conditions in
+ * which they shut down the connection.
+ */
+int xcb_connection_has_error(xcb_connection_t *c);
+
+/**
+ * @brief Connects to the X server.
+ * @param fd: The file descriptor.
+ * @param auth_info: Authentication data.
+ * @return A newly allocated xcb_connection_t structure.
+ *
+ * Connects to an X server, given the open socket @p fd and the
+ * xcb_auth_info_t @p auth_info. The file descriptor @p fd is
+ * bidirectionally connected to an X server. If the connection
+ * should be unauthenticated, @p auth_info must be @c
+ * NULL.
+ */
+xcb_connection_t *xcb_connect_to_fd(int fd, xcb_auth_info_t *auth_info);
+
+/**
+ * @brief Closes the connection.
+ * @param c: The connection.
+ *
+ * Closes the file descriptor and frees all memory associated with the
+ * connection @c c.
+ */
+void xcb_disconnect(xcb_connection_t *c);
+
+
+/* xcb_util.c */
+
+/**
+ * @brief Parses a display string name in the form documented by X(7x).
+ * @param name: The name of the display.
+ * @param host: A pointer to a malloc'd copy of the hostname.
+ * @param display: A pointer to the display number.
+ * @param screen: A pointer to the screen number.
+ * @return 0 on failure, non 0 otherwise.
+ *
+ * Parses the display string name @p display_name in the form
+ * documented by X(7x). Has no side effects on failure. If
+ * @p displayname is @c NULL or empty, it uses the environment
+ * variable DISPLAY. @p hostp is a pointer to a newly allocated string
+ * that contain the host name. @p displayp is set to the display
+ * number and @p screenp to the preferred screen number. @p screenp
+ * can be @c NULL. If @p displayname does not contain a screen number,
+ * it is set to @c 0.
+ */
+int xcb_parse_display(const char *name, char **host, int *display, int *screen);
+
+/**
+ * @brief Connects to the X server.
+ * @param displayname: The name of the display.
+ * @param screenp: A pointer to a preferred screen number.
+ * @return A newly allocated xcb_connection_t structure.
+ *
+ * Connects to the X server specified by @p displayname. If @p
+ * displayname is @c NULL, uses the value of the DISPLAY environment
+ * variable. If a particular screen on that server is preferred, the
+ * int pointed to by @p screenp (if not @c NULL) will be set to that
+ * screen; otherwise the screen will be set to 0.
+ */
+xcb_connection_t *xcb_connect(const char *displayname, int *screenp);
+
+/**
+ * @brief Connects to the X server, using an authorization information.
+ * @param display: The name of the display.
+ * @param auth: The authorization information.
+ * @param screen: A pointer to a preferred screen number.
+ * @return A newly allocated xcb_connection_t structure.
+ *
+ * Connects to the X server specified by @p displayname, using the
+ * authorization @p auth. If a particular screen on that server is
+ * preferred, the int pointed to by @p screenp (if not @c NULL) will
+ * be set to that screen; otherwise @p screenp will be set to 0.
+ */
+xcb_connection_t *xcb_connect_to_display_with_auth_info(const char *display, xcb_auth_info_t *auth, int *screen);
+
+
+/* xcb_xid.c */
+
+/**
+ * @brief Allocates an XID for a new object.
+ * @param c: The connection.
+ * @return A newly allocated XID.
+ *
+ * Allocates an XID for a new object. Typically used just prior to
+ * various object creation functions, such as xcb_create_window.
+ */
+uint32_t xcb_generate_id(xcb_connection_t *c);
+
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* __XCB_H__ */
diff --git a/libxcb/src/xcb_auth.c b/libxcb/src/xcb_auth.c
index f2a3ab610..aeb2374ed 100644
--- a/libxcb/src/xcb_auth.c
+++ b/libxcb/src/xcb_auth.c
@@ -1,373 +1,373 @@
-/* Copyright (C) 2001-2004 Bart Massey and Jamey Sharp.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- * 
- * Except as contained in this notice, the names of the authors or their
- * institutions shall not be used in advertising or otherwise to promote the
- * sale, use or other dealings in this Software without prior written
- * authorization from the authors.
- */
-
-/* Authorization systems for the X protocol. */
-
-#include <assert.h>
-#include <X11/Xauth.h>
-#include <sys/param.h>
-#include <unistd.h>
-#include <stdlib.h>
-#ifndef _MSC_VER
-#include <arpa/inet.h>
-#endif
-
-#ifdef __INTERIX
-/* _don't_ ask. interix has INADDR_LOOPBACK in here. */
-#include <rpc/types.h>
-#endif
-
-#ifdef _WIN32
-#include "xcb_windefs.h"
-#else
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <sys/un.h>
-#endif /* _WIN32 */
-
-#include "xcb.h"
-#include "xcbint.h"
-
-#ifdef HASXDMAUTH
-#include <X11/Xdmcp.h>
-#endif
-
-enum auth_protos {
-#ifdef HASXDMAUTH
-    AUTH_XA1,
-#endif
-    AUTH_MC1,
-    N_AUTH_PROTOS
-};
-
-#define AUTH_PROTO_XDM_AUTHORIZATION "XDM-AUTHORIZATION-1"
-#define AUTH_PROTO_MIT_MAGIC_COOKIE "MIT-MAGIC-COOKIE-1"
-
-static char *authnames[N_AUTH_PROTOS] = {
-#ifdef HASXDMAUTH
-    AUTH_PROTO_XDM_AUTHORIZATION,
-#endif
-    AUTH_PROTO_MIT_MAGIC_COOKIE,
-};
-
-static int authnameslen[N_AUTH_PROTOS] = {
-#ifdef HASXDMAUTH
-    sizeof(AUTH_PROTO_XDM_AUTHORIZATION) - 1,
-#endif
-    sizeof(AUTH_PROTO_MIT_MAGIC_COOKIE) - 1,
-};
-
-static size_t memdup(char **dst, void *src, size_t len)
-{
-    if(len)
-	*dst = malloc(len);
-    else
-	*dst = 0;
-    if(!*dst)
-	return 0;
-    memcpy(*dst, src, len);
-    return len;
-}
-
-static int authname_match(enum auth_protos kind, char *name, size_t namelen)
-{
-    if(authnameslen[kind] != namelen)
-	return 0;
-    if(memcmp(authnames[kind], name, namelen))
-	return 0;
-    return 1;
-}
-
-#define SIN6_ADDR(s) (&((struct sockaddr_in6 *)s)->sin6_addr)
-
-static Xauth *get_authptr(struct sockaddr *sockname, int display)
-{
-    char *addr = 0;
-    int addrlen = 0;
-    unsigned short family;
-    char hostnamebuf[256];   /* big enough for max hostname */
-    char dispbuf[40];   /* big enough to hold more than 2^64 base 10 */
-    int dispbuflen;
-
-    family = FamilyLocal; /* 256 */
-    switch(sockname->sa_family)
-    {
-#ifdef AF_INET6
-    case AF_INET6:
-        addr = (char *) SIN6_ADDR(sockname);
-        addrlen = sizeof(*SIN6_ADDR(sockname));
-        if(!IN6_IS_ADDR_V4MAPPED(SIN6_ADDR(sockname)))
-        {
-            if(!IN6_IS_ADDR_LOOPBACK(SIN6_ADDR(sockname)))
-                family = XCB_FAMILY_INTERNET_6;
-            break;
-        }
-        addr += 12;
-        /* if v4-mapped, fall through. */
-#endif
-    case AF_INET:
-        if(!addr)
-            addr = (char *) &((struct sockaddr_in *)sockname)->sin_addr;
-        addrlen = sizeof(((struct sockaddr_in *)sockname)->sin_addr);
-        if(*(in_addr_t *) addr != htonl(INADDR_LOOPBACK))
-            family = XCB_FAMILY_INTERNET;
-        break;
-    case AF_UNIX:
-        break;
-    default:
-        return 0;   /* cannot authenticate this family */
-    }
-
-    dispbuflen = snprintf(dispbuf, sizeof(dispbuf), "%d", display);
-    if(dispbuflen < 0)
-        return 0;
-    /* snprintf may have truncate our text */
-    dispbuflen = MIN(dispbuflen, sizeof(dispbuf) - 1);
-
-    if (family == FamilyLocal) {
-        if (gethostname(hostnamebuf, sizeof(hostnamebuf)) == -1)
-            return 0;   /* do not know own hostname */
-        addr = hostnamebuf;
-        addrlen = strlen(addr);
-    }
-
-    return XauGetBestAuthByAddr (family,
-                                 (unsigned short) addrlen, addr,
-                                 (unsigned short) dispbuflen, dispbuf,
-                                 N_AUTH_PROTOS, authnames, authnameslen);
-}
-
-#ifdef HASXDMAUTH
-static int next_nonce(void)
-{
-    static int nonce = 0;
-    static pthread_mutex_t nonce_mutex = PTHREAD_MUTEX_INITIALIZER;
-    int ret;
-    pthread_mutex_lock(&nonce_mutex);
-    ret = nonce++;
-    pthread_mutex_unlock(&nonce_mutex);
-    return ret;
-}
-
-static void do_append(char *buf, int *idxp, void *val, size_t valsize) {
-    memcpy(buf + *idxp, val, valsize);
-    *idxp += valsize;
-}
-#endif
-     
-static int compute_auth(xcb_auth_info_t *info, Xauth *authptr, struct sockaddr *sockname)
-{
-    if (authname_match(AUTH_MC1, authptr->name, authptr->name_length)) {
-        info->datalen = memdup(&info->data, authptr->data, authptr->data_length);
-        if(!info->datalen)
-            return 0;
-        return 1;
-    }
-#ifdef HASXDMAUTH
-#define APPEND(buf,idx,val) do_append((buf),&(idx),&(val),sizeof(val))
-    if (authname_match(AUTH_XA1, authptr->name, authptr->name_length)) {
-	int j;
-
-	info->data = malloc(192 / 8);
-	if(!info->data)
-	    return 0;
-
-	for (j = 0; j < 8; j++)
-	    info->data[j] = authptr->data[j];
-	switch(sockname->sa_family) {
-        case AF_INET:
-            /*block*/ {
-	    struct sockaddr_in *si = (struct sockaddr_in *) sockname;
-	    APPEND(info->data, j, si->sin_addr.s_addr);
-	    APPEND(info->data, j, si->sin_port);
-	}
-	break;
-#ifdef AF_INET6
-        case AF_INET6:
-            /*block*/ {
-            struct sockaddr_in6 *si6 = (struct sockaddr_in6 *) sockname;
-            if(IN6_IS_ADDR_V4MAPPED(SIN6_ADDR(sockname)))
-            {
-                do_append(info->data, &j, &si6->sin6_addr.s6_addr[12], 4);
-                APPEND(info->data, j, si6->sin6_port);
-            }
-            else
-            {
-                /* XDM-AUTHORIZATION-1 does not handle IPv6 correctly.  Do the
-                   same thing Xlib does: use all zeroes for the 4-byte address
-                   and 2-byte port number. */
-                uint32_t fakeaddr = 0;
-                uint16_t fakeport = 0;
-                APPEND(info->data, j, fakeaddr);
-                APPEND(info->data, j, fakeport);
-            }
-        }
-        break;
-#endif
-        case AF_UNIX:
-            /*block*/ {
-	    uint32_t fakeaddr = htonl(0xffffffff - next_nonce());
-	    uint16_t fakeport = htons(getpid());
-	    APPEND(info->data, j, fakeaddr);
-	    APPEND(info->data, j, fakeport);
-	}
-	break;
-        default:
-            free(info->data);
-            return 0;   /* do not know how to build this */
-	}
-	{
-	    uint32_t now = htonl(time(0));
-	    APPEND(info->data, j, now);
-	}
-	assert(j <= 192 / 8);
-	while (j < 192 / 8)
-	    info->data[j++] = 0;
-	info->datalen = j;
-	XdmcpWrap ((unsigned char *) info->data, (unsigned char *) authptr->data + 8, (unsigned char *) info->data, info->datalen);
-	return 1;
-    }
-#undef APPEND
-#endif
-
-    return 0;   /* Unknown authorization type */
-}
-
-/* `sockaddr_un.sun_path' typical size usually ranges between 92 and 108 */
-#define INITIAL_SOCKNAME_SLACK 108
-
-#ifndef WIN32
-typedef int (*LPFN_GETPEERNAME)(int,struct sockaddr *,socklen_t *);
-#endif
-/* Return a dynamically allocated socket address structure according
-   to the value returned by either getpeername() or getsockname()
-   (according to POSIX, applications should not assume a particular
-   length for `sockaddr_un.sun_path') */
-static struct sockaddr *get_peer_sock_name(LPFN_GETPEERNAME socket_func,
-					   int fd)
-{
-    socklen_t socknamelen = sizeof(struct sockaddr) + INITIAL_SOCKNAME_SLACK;
-    socklen_t actual_socknamelen = socknamelen;
-    struct sockaddr *sockname = malloc(socknamelen);
-
-    if (sockname == NULL)
-        return NULL;
-
-    /* Both getpeername() and getsockname() truncates sockname if
-       there is not enough space and set the required length in
-       actual_socknamelen */
-    if (socket_func(fd, sockname, &actual_socknamelen) == -1)
-        goto sock_or_realloc_error;
-
-    if (actual_socknamelen > socknamelen)
-    {
-        struct sockaddr *new_sockname = NULL;
-        socknamelen = actual_socknamelen;
-
-        if ((new_sockname = realloc(sockname, actual_socknamelen)) == NULL)
-            goto sock_or_realloc_error;
-
-        sockname = new_sockname;
-
-        if (socket_func(fd, sockname, &actual_socknamelen) == -1 ||
-            actual_socknamelen > socknamelen)
-            goto sock_or_realloc_error;
-    }
-
-    return sockname;
-
- sock_or_realloc_error:
-    free(sockname);
-    return NULL;
-}
-
-int _xcb_get_auth_info(int fd, xcb_auth_info_t *info, int display)
-{
-    /* code adapted from Xlib/ConnDis.c, xtrans/Xtranssocket.c,
-       xtrans/Xtransutils.c */
-    struct sockaddr *sockname = NULL;
-    int gotsockname = 0;
-    Xauth *authptr = 0;
-    int ret = 1;
-
-    /* Some systems like hpux or Hurd do not expose peer names
-     * for UNIX Domain Sockets, but this is irrelevant,
-     * since compute_auth() ignores the peer name in this
-     * case anyway.*/
-    if ((sockname = get_peer_sock_name(getpeername, fd)) == NULL)
-    {
-        if ((sockname = get_peer_sock_name(getsockname, fd)) == NULL)
-            return 0;   /* can only authenticate sockets */
-        if (sockname->sa_family != AF_UNIX)
-        {
-            free(sockname);
-            return 0;   /* except for AF_UNIX, sockets should have peernames */
-        }
-        gotsockname = 1;
-    }
-
-    authptr = get_authptr(sockname, display);
-    if (authptr == 0)
-    {
-        free(sockname);
-        return 0;   /* cannot find good auth data */
-    }
-
-    info->namelen = memdup(&info->name, authptr->name, authptr->name_length);
-    if (!info->namelen)
-        goto no_auth;   /* out of memory */
-
-    if (!gotsockname)
-    {
-        free(sockname);
-
-        if ((sockname = get_peer_sock_name(getsockname, fd)) == NULL)
-        {
-            free(info->name);
-            goto no_auth;   /* can only authenticate sockets */
-        }
-    }
-
-    ret = compute_auth(info, authptr, sockname);
-    if(!ret)
-    {
-        free(info->name);
-        goto no_auth;   /* cannot build auth record */
-    }
-
-    free(sockname);
-    sockname = NULL;
-
-    XauDisposeAuth(authptr);
-    return ret;
-
- no_auth:
-    free(sockname);
-
-    info->name = 0;
-    info->namelen = 0;
-    XauDisposeAuth(authptr);
-    return 0;
-}
+/* Copyright (C) 2001-2004 Bart Massey and Jamey Sharp.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 
+ * Except as contained in this notice, the names of the authors or their
+ * institutions shall not be used in advertising or otherwise to promote the
+ * sale, use or other dealings in this Software without prior written
+ * authorization from the authors.
+ */
+
+/* Authorization systems for the X protocol. */
+
+#include <assert.h>
+#include <X11/Xauth.h>
+#include <sys/param.h>
+#include <unistd.h>
+#include <stdlib.h>
+#ifndef _MSC_VER
+#include <arpa/inet.h>
+#endif
+
+#ifdef __INTERIX
+/* _don't_ ask. interix has INADDR_LOOPBACK in here. */
+#include <rpc/types.h>
+#endif
+
+#ifdef _WIN32
+#include "xcb_windefs.h"
+#else
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <sys/un.h>
+#endif /* _WIN32 */
+
+#include "xcb.h"
+#include "xcbint.h"
+
+#ifdef HASXDMAUTH
+#include <X11/Xdmcp.h>
+#endif
+
+enum auth_protos {
+#ifdef HASXDMAUTH
+    AUTH_XA1,
+#endif
+    AUTH_MC1,
+    N_AUTH_PROTOS
+};
+
+#define AUTH_PROTO_XDM_AUTHORIZATION "XDM-AUTHORIZATION-1"
+#define AUTH_PROTO_MIT_MAGIC_COOKIE "MIT-MAGIC-COOKIE-1"
+
+static char *authnames[N_AUTH_PROTOS] = {
+#ifdef HASXDMAUTH
+    AUTH_PROTO_XDM_AUTHORIZATION,
+#endif
+    AUTH_PROTO_MIT_MAGIC_COOKIE,
+};
+
+static int authnameslen[N_AUTH_PROTOS] = {
+#ifdef HASXDMAUTH
+    sizeof(AUTH_PROTO_XDM_AUTHORIZATION) - 1,
+#endif
+    sizeof(AUTH_PROTO_MIT_MAGIC_COOKIE) - 1,
+};
+
+static size_t memdup(char **dst, void *src, size_t len)
+{
+    if(len)
+	*dst = malloc(len);
+    else
+	*dst = 0;
+    if(!*dst)
+	return 0;
+    memcpy(*dst, src, len);
+    return len;
+}
+
+static int authname_match(enum auth_protos kind, char *name, size_t namelen)
+{
+    if(authnameslen[kind] != namelen)
+	return 0;
+    if(memcmp(authnames[kind], name, namelen))
+	return 0;
+    return 1;
+}
+
+#define SIN6_ADDR(s) (&((struct sockaddr_in6 *)s)->sin6_addr)
+
+static Xauth *get_authptr(struct sockaddr *sockname, int display)
+{
+    char *addr = 0;
+    int addrlen = 0;
+    unsigned short family;
+    char hostnamebuf[256];   /* big enough for max hostname */
+    char dispbuf[40];   /* big enough to hold more than 2^64 base 10 */
+    int dispbuflen;
+
+    family = FamilyLocal; /* 256 */
+    switch(sockname->sa_family)
+    {
+#ifdef AF_INET6
+    case AF_INET6:
+        addr = (char *) SIN6_ADDR(sockname);
+        addrlen = sizeof(*SIN6_ADDR(sockname));
+        if(!IN6_IS_ADDR_V4MAPPED(SIN6_ADDR(sockname)))
+        {
+            if(!IN6_IS_ADDR_LOOPBACK(SIN6_ADDR(sockname)))
+                family = XCB_FAMILY_INTERNET_6;
+            break;
+        }
+        addr += 12;
+        /* if v4-mapped, fall through. */
+#endif
+    case AF_INET:
+        if(!addr)
+            addr = (char *) &((struct sockaddr_in *)sockname)->sin_addr;
+        addrlen = sizeof(((struct sockaddr_in *)sockname)->sin_addr);
+        if(*(in_addr_t *) addr != htonl(INADDR_LOOPBACK))
+            family = XCB_FAMILY_INTERNET;
+        break;
+    case AF_UNIX:
+        break;
+    default:
+        return 0;   /* cannot authenticate this family */
+    }
+
+    dispbuflen = snprintf(dispbuf, sizeof(dispbuf), "%d", display);
+    if(dispbuflen < 0)
+        return 0;
+    /* snprintf may have truncate our text */
+    dispbuflen = MIN(dispbuflen, sizeof(dispbuf) - 1);
+
+    if (family == FamilyLocal) {
+        if (gethostname(hostnamebuf, sizeof(hostnamebuf)) == -1)
+            return 0;   /* do not know own hostname */
+        addr = hostnamebuf;
+        addrlen = strlen(addr);
+    }
+
+    return XauGetBestAuthByAddr (family,
+                                 (unsigned short) addrlen, addr,
+                                 (unsigned short) dispbuflen, dispbuf,
+                                 N_AUTH_PROTOS, authnames, authnameslen);
+}
+
+#ifdef HASXDMAUTH
+static int next_nonce(void)
+{
+    static int nonce = 0;
+    static pthread_mutex_t nonce_mutex = PTHREAD_MUTEX_INITIALIZER;
+    int ret;
+    pthread_mutex_lock(&nonce_mutex);
+    ret = nonce++;
+    pthread_mutex_unlock(&nonce_mutex);
+    return ret;
+}
+
+static void do_append(char *buf, int *idxp, void *val, size_t valsize) {
+    memcpy(buf + *idxp, val, valsize);
+    *idxp += valsize;
+}
+#endif
+     
+static int compute_auth(xcb_auth_info_t *info, Xauth *authptr, struct sockaddr *sockname)
+{
+    if (authname_match(AUTH_MC1, authptr->name, authptr->name_length)) {
+        info->datalen = memdup(&info->data, authptr->data, authptr->data_length);
+        if(!info->datalen)
+            return 0;
+        return 1;
+    }
+#ifdef HASXDMAUTH
+#define APPEND(buf,idx,val) do_append((buf),&(idx),&(val),sizeof(val))
+    if (authname_match(AUTH_XA1, authptr->name, authptr->name_length)) {
+	int j;
+
+	info->data = malloc(192 / 8);
+	if(!info->data)
+	    return 0;
+
+	for (j = 0; j < 8; j++)
+	    info->data[j] = authptr->data[j];
+	switch(sockname->sa_family) {
+        case AF_INET:
+            /*block*/ {
+	    struct sockaddr_in *si = (struct sockaddr_in *) sockname;
+	    APPEND(info->data, j, si->sin_addr.s_addr);
+	    APPEND(info->data, j, si->sin_port);
+	}
+	break;
+#ifdef AF_INET6
+        case AF_INET6:
+            /*block*/ {
+            struct sockaddr_in6 *si6 = (struct sockaddr_in6 *) sockname;
+            if(IN6_IS_ADDR_V4MAPPED(SIN6_ADDR(sockname)))
+            {
+                do_append(info->data, &j, &si6->sin6_addr.s6_addr[12], 4);
+                APPEND(info->data, j, si6->sin6_port);
+            }
+            else
+            {
+                /* XDM-AUTHORIZATION-1 does not handle IPv6 correctly.  Do the
+                   same thing Xlib does: use all zeroes for the 4-byte address
+                   and 2-byte port number. */
+                uint32_t fakeaddr = 0;
+                uint16_t fakeport = 0;
+                APPEND(info->data, j, fakeaddr);
+                APPEND(info->data, j, fakeport);
+            }
+        }
+        break;
+#endif
+        case AF_UNIX:
+            /*block*/ {
+	    uint32_t fakeaddr = htonl(0xffffffff - next_nonce());
+	    uint16_t fakeport = htons(getpid());
+	    APPEND(info->data, j, fakeaddr);
+	    APPEND(info->data, j, fakeport);
+	}
+	break;
+        default:
+            free(info->data);
+            return 0;   /* do not know how to build this */
+	}
+	{
+	    uint32_t now = htonl(time(0));
+	    APPEND(info->data, j, now);
+	}
+	assert(j <= 192 / 8);
+	while (j < 192 / 8)
+	    info->data[j++] = 0;
+	info->datalen = j;
+	XdmcpWrap ((unsigned char *) info->data, (unsigned char *) authptr->data + 8, (unsigned char *) info->data, info->datalen);
+	return 1;
+    }
+#undef APPEND
+#endif
+
+    return 0;   /* Unknown authorization type */
+}
+
+/* `sockaddr_un.sun_path' typical size usually ranges between 92 and 108 */
+#define INITIAL_SOCKNAME_SLACK 108
+
+#ifndef WIN32
+typedef int (*LPFN_GETPEERNAME)(int,struct sockaddr *,socklen_t *);
+#endif
+/* Return a dynamically allocated socket address structure according
+   to the value returned by either getpeername() or getsockname()
+   (according to POSIX, applications should not assume a particular
+   length for `sockaddr_un.sun_path') */
+static struct sockaddr *get_peer_sock_name(LPFN_GETPEERNAME socket_func,
+					   int fd)
+{
+    socklen_t socknamelen = sizeof(struct sockaddr) + INITIAL_SOCKNAME_SLACK;
+    socklen_t actual_socknamelen = socknamelen;
+    struct sockaddr *sockname = malloc(socknamelen);
+
+    if (sockname == NULL)
+        return NULL;
+
+    /* Both getpeername() and getsockname() truncates sockname if
+       there is not enough space and set the required length in
+       actual_socknamelen */
+    if (socket_func(fd, sockname, &actual_socknamelen) == -1)
+        goto sock_or_realloc_error;
+
+    if (actual_socknamelen > socknamelen)
+    {
+        struct sockaddr *new_sockname = NULL;
+        socknamelen = actual_socknamelen;
+
+        if ((new_sockname = realloc(sockname, actual_socknamelen)) == NULL)
+            goto sock_or_realloc_error;
+
+        sockname = new_sockname;
+
+        if (socket_func(fd, sockname, &actual_socknamelen) == -1 ||
+            actual_socknamelen > socknamelen)
+            goto sock_or_realloc_error;
+    }
+
+    return sockname;
+
+ sock_or_realloc_error:
+    free(sockname);
+    return NULL;
+}
+
+int _xcb_get_auth_info(int fd, xcb_auth_info_t *info, int display)
+{
+    /* code adapted from Xlib/ConnDis.c, xtrans/Xtranssocket.c,
+       xtrans/Xtransutils.c */
+    struct sockaddr *sockname = NULL;
+    int gotsockname = 0;
+    Xauth *authptr = 0;
+    int ret = 1;
+
+    /* Some systems like hpux or Hurd do not expose peer names
+     * for UNIX Domain Sockets, but this is irrelevant,
+     * since compute_auth() ignores the peer name in this
+     * case anyway.*/
+    if ((sockname = get_peer_sock_name(getpeername, fd)) == NULL)
+    {
+        if ((sockname = get_peer_sock_name(getsockname, fd)) == NULL)
+            return 0;   /* can only authenticate sockets */
+        if (sockname->sa_family != AF_UNIX)
+        {
+            free(sockname);
+            return 0;   /* except for AF_UNIX, sockets should have peernames */
+        }
+        gotsockname = 1;
+    }
+
+    authptr = get_authptr(sockname, display);
+    if (authptr == 0)
+    {
+        free(sockname);
+        return 0;   /* cannot find good auth data */
+    }
+
+    info->namelen = memdup(&info->name, authptr->name, authptr->name_length);
+    if (!info->namelen)
+        goto no_auth;   /* out of memory */
+
+    if (!gotsockname)
+    {
+        free(sockname);
+
+        if ((sockname = get_peer_sock_name(getsockname, fd)) == NULL)
+        {
+            free(info->name);
+            goto no_auth;   /* can only authenticate sockets */
+        }
+    }
+
+    ret = compute_auth(info, authptr, sockname);
+    if(!ret)
+    {
+        free(info->name);
+        goto no_auth;   /* cannot build auth record */
+    }
+
+    free(sockname);
+    sockname = NULL;
+
+    XauDisposeAuth(authptr);
+    return ret;
+
+ no_auth:
+    free(sockname);
+
+    info->name = 0;
+    info->namelen = 0;
+    XauDisposeAuth(authptr);
+    return 0;
+}
diff --git a/libxcb/src/xcb_in.c b/libxcb/src/xcb_in.c
index ccfb3e0f4..2825c25c3 100644
--- a/libxcb/src/xcb_in.c
+++ b/libxcb/src/xcb_in.c
@@ -1,706 +1,706 @@
-/* Copyright (C) 2001-2004 Bart Massey and Jamey Sharp.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- * 
- * Except as contained in this notice, the names of the authors or their
- * institutions shall not be used in advertising or otherwise to promote the
- * sale, use or other dealings in this Software without prior written
- * authorization from the authors.
- */
-
-/* Stuff that reads stuff from the server. */
-
-#include <assert.h>
-#include <string.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <errno.h>
-
-#include "xcb.h"
-#include "xcbext.h"
-#include "xcbint.h"
-#if USE_POLL
-#include <poll.h>
-#endif
-#ifndef _WIN32
-#include <sys/select.h>
-#include <sys/socket.h>
-#endif
-
-#ifdef _WIN32
-#include "xcb_windefs.h"
-#endif /* _WIN32 */
-
-#define XCB_ERROR 0
-#define XCB_REPLY 1
-#define XCB_XGE_EVENT 35
-
-#ifdef _MSC_VER
-#ifdef MSG_WAITALL
-#undef MSG_WAITALL
-#endif
-#endif
-
-/* required for compiling for Win32 using MinGW */
-#ifndef MSG_WAITALL
-#define MSG_WAITALL 0
-#endif
-
-struct event_list {
-    xcb_generic_event_t *event;
-    struct event_list *next;
-};
-
-struct reply_list {
-    void *reply;
-    struct reply_list *next;
-};
-
-typedef struct pending_reply {
-    uint64_t first_request;
-    uint64_t last_request;
-    enum workarounds workaround;
-    int flags;
-    struct pending_reply *next;
-} pending_reply;
-
-typedef struct reader_list {
-    uint64_t request;
-    pthread_cond_t *data;
-    struct reader_list *next;
-} reader_list;
-
-static void remove_finished_readers(reader_list **prev_reader, uint64_t completed)
-{
-    while(*prev_reader && XCB_SEQUENCE_COMPARE((*prev_reader)->request, <=, completed))
-    {
-        /* If you don't have what you're looking for now, you never
-         * will. Wake up and leave me alone. */
-        pthread_cond_signal((*prev_reader)->data);
-        *prev_reader = (*prev_reader)->next;
-    }
-}
-
-static int read_packet(xcb_connection_t *c)
-{
-    xcb_generic_reply_t genrep;
-    int length = 32;
-    int eventlength = 0; /* length after first 32 bytes for GenericEvents */
-    void *buf;
-    pending_reply *pend = 0;
-    struct event_list *event;
-
-    /* Wait for there to be enough data for us to read a whole packet */
-    if(c->in.queue_len < length)
-        return 0;
-
-    /* Get the response type, length, and sequence number. */
-    memcpy(&genrep, c->in.queue, sizeof(genrep));
-
-    /* Compute 32-bit sequence number of this packet. */
-    if((genrep.response_type & 0x7f) != XCB_KEYMAP_NOTIFY)
-    {
-        uint64_t lastread = c->in.request_read;
-        c->in.request_read = (lastread & UINT64_C(0xffffffffffff0000)) | genrep.sequence;
-        if(XCB_SEQUENCE_COMPARE(c->in.request_read, <, lastread))
-            c->in.request_read += 0x10000;
-        if(XCB_SEQUENCE_COMPARE(c->in.request_read, >, c->in.request_expected))
-            c->in.request_expected = c->in.request_read;
-
-        if(c->in.request_read != lastread)
-        {
-            if(c->in.current_reply)
-            {
-                _xcb_map_put(c->in.replies, lastread, c->in.current_reply);
-                c->in.current_reply = 0;
-                c->in.current_reply_tail = &c->in.current_reply;
-            }
-            c->in.request_completed = c->in.request_read - 1;
-        }
-
-        while(c->in.pending_replies && 
-              c->in.pending_replies->workaround != WORKAROUND_EXTERNAL_SOCKET_OWNER &&
-	      XCB_SEQUENCE_COMPARE (c->in.pending_replies->last_request, <=, c->in.request_completed))
-        {
-            pending_reply *oldpend = c->in.pending_replies;
-            c->in.pending_replies = oldpend->next;
-            if(!oldpend->next)
-                c->in.pending_replies_tail = &c->in.pending_replies;
-            free(oldpend);
-        }
-
-        if(genrep.response_type == XCB_ERROR)
-            c->in.request_completed = c->in.request_read;
-
-        remove_finished_readers(&c->in.readers, c->in.request_completed);
-    }
-
-    if(genrep.response_type == XCB_ERROR || genrep.response_type == XCB_REPLY)
-    {
-        pend = c->in.pending_replies;
-        if(pend &&
-           !(XCB_SEQUENCE_COMPARE(pend->first_request, <=, c->in.request_read) &&
-             (pend->workaround == WORKAROUND_EXTERNAL_SOCKET_OWNER ||
-              XCB_SEQUENCE_COMPARE(c->in.request_read, <=, pend->last_request))))
-            pend = 0;
-    }
-
-    /* For reply packets, check that the entire packet is available. */
-    if(genrep.response_type == XCB_REPLY)
-    {
-        if(pend && pend->workaround == WORKAROUND_GLX_GET_FB_CONFIGS_BUG)
-        {
-            uint32_t *p = (uint32_t *) c->in.queue;
-            genrep.length = p[2] * p[3] * 2;
-        }
-        length += genrep.length * 4;
-    }
-
-    /* XGE events may have sizes > 32 */
-    if ((genrep.response_type & 0x7f) == XCB_XGE_EVENT)
-        eventlength = genrep.length * 4;
-
-    buf = malloc(length + eventlength +
-            (genrep.response_type == XCB_REPLY ? 0 : sizeof(uint32_t)));
-    if(!buf)
-    {
-        _xcb_conn_shutdown(c);
-        return 0;
-    }
-
-    if(_xcb_in_read_block(c, buf, length) <= 0)
-    {
-        free(buf);
-        return 0;
-    }
-
-    /* pull in XGE event data if available, append after event struct */
-    if (eventlength)
-    {
-        if(_xcb_in_read_block(c, &((xcb_generic_event_t*)buf)[1], eventlength) <= 0)
-        {
-            free(buf);
-            return 0;
-        }
-    }
-
-    if(pend && (pend->flags & XCB_REQUEST_DISCARD_REPLY))
-    {
-        free(buf);
-        return 1;
-    }
-
-    if(genrep.response_type != XCB_REPLY)
-        ((xcb_generic_event_t *) buf)->full_sequence = c->in.request_read;
-
-    /* reply, or checked error */
-    if( genrep.response_type == XCB_REPLY ||
-       (genrep.response_type == XCB_ERROR && pend && (pend->flags & XCB_REQUEST_CHECKED)))
-    {
-        struct reply_list *cur = malloc(sizeof(struct reply_list));
-        if(!cur)
-        {
-            _xcb_conn_shutdown(c);
-            free(buf);
-            return 0;
-        }
-        cur->reply = buf;
-        cur->next = 0;
-        *c->in.current_reply_tail = cur;
-        c->in.current_reply_tail = &cur->next;
-        if(c->in.readers && c->in.readers->request == c->in.request_read)
-            pthread_cond_signal(c->in.readers->data);
-        return 1;
-    }
-
-    /* event, or unchecked error */
-    event = malloc(sizeof(struct event_list));
-    if(!event)
-    {
-        _xcb_conn_shutdown(c);
-        free(buf);
-        return 0;
-    }
-    event->event = buf;
-    event->next = 0;
-    *c->in.events_tail = event;
-    c->in.events_tail = &event->next;
-    pthread_cond_signal(&c->in.event_cond);
-    return 1; /* I have something for you... */
-}
-
-static xcb_generic_event_t *get_event(xcb_connection_t *c)
-{
-    struct event_list *cur = c->in.events;
-    xcb_generic_event_t *ret;
-    if(!c->in.events)
-        return 0;
-    ret = cur->event;
-    c->in.events = cur->next;
-    if(!cur->next)
-        c->in.events_tail = &c->in.events;
-    free(cur);
-    return ret;
-}
-
-static void free_reply_list(struct reply_list *head)
-{
-    while(head)
-    {
-        struct reply_list *cur = head;
-        head = cur->next;
-        free(cur->reply);
-        free(cur);
-    }
-}
-
-static int read_block(const int fd, void *buf, const ssize_t len)
-{
-    int done = 0;
-    while(done < len)
-    {
-        int ret = recv(fd, ((char *) buf) + done, len - done,MSG_WAITALL);
-        if(ret > 0)
-            done += ret;
-#ifndef _WIN32
-        if(ret < 0 && errno == EAGAIN)
-#else
-        if(ret == SOCKET_ERROR && WSAGetLastError() == WSAEWOULDBLOCK)
-#endif /* !_Win32 */
-        {
-#if USE_POLL
-            struct pollfd pfd;
-            pfd.fd = fd;
-            pfd.events = POLLIN;
-            pfd.revents = 0;
-            do {
-                ret = poll(&pfd, 1, -1);
-            } while (ret == -1 && errno == EINTR);
-#else
-            fd_set fds;
-            FD_ZERO(&fds);
-            FD_SET(fd, &fds);
-
-	    /* Initializing errno here makes sure that for Win32 this loop will execute only once */
-	    errno = 0;  
-	    do {
-		ret = select(fd + 1, &fds, 0, 0, 0);
-	    } while (ret == -1 && errno == EINTR);
-#endif /* USE_POLL */
-        }
-        if(ret <= 0)
-            return ret;
-    }
-    return len;
-}
-
-static int poll_for_reply(xcb_connection_t *c, uint64_t request, void **reply, xcb_generic_error_t **error)
-{
-    struct reply_list *head;
-
-    /* If an error occurred when issuing the request, fail immediately. */
-    if(!request)
-        head = 0;
-    /* We've read requests past the one we want, so if it has replies we have
-     * them all and they're in the replies map. */
-    else if(XCB_SEQUENCE_COMPARE(request, <, c->in.request_read))
-    {
-        head = _xcb_map_remove(c->in.replies, request);
-        if(head && head->next)
-            _xcb_map_put(c->in.replies, request, head->next);
-    }
-    /* We're currently processing the responses to the request we want, and we
-     * have a reply ready to return. So just return it without blocking. */
-    else if(request == c->in.request_read && c->in.current_reply)
-    {
-        head = c->in.current_reply;
-        c->in.current_reply = head->next;
-        if(!head->next)
-            c->in.current_reply_tail = &c->in.current_reply;
-    }
-    /* We know this request can't have any more replies, and we've already
-     * established it doesn't have a reply now. Don't bother blocking. */
-    else if(request == c->in.request_completed)
-        head = 0;
-    /* We may have more replies on the way for this request: block until we're
-     * sure. */
-    else
-        return 0;
-
-    if(error)
-        *error = 0;
-    *reply = 0;
-
-    if(head)
-    {
-        if(((xcb_generic_reply_t *) head->reply)->response_type == XCB_ERROR)
-        {
-            if(error)
-                *error = head->reply;
-            else
-                free(head->reply);
-        }
-        else
-            *reply = head->reply;
-
-        free(head);
-    }
-
-    return 1;
-}
-
-static void insert_reader(reader_list **prev_reader, reader_list *reader, uint64_t request, pthread_cond_t *cond)
-{
-    while(*prev_reader && XCB_SEQUENCE_COMPARE((*prev_reader)->request, <=, request))
-        prev_reader = &(*prev_reader)->next;
-    reader->request = request;
-    reader->data = cond;
-    reader->next = *prev_reader;
-    *prev_reader = reader;
-}
-
-static void remove_reader(reader_list **prev_reader, reader_list *reader)
-{
-    while(*prev_reader && XCB_SEQUENCE_COMPARE((*prev_reader)->request, <=, reader->request))
-        if(*prev_reader == reader)
-        {
-            *prev_reader = (*prev_reader)->next;
-            break;
-        }
-}
-
-static void *wait_for_reply(xcb_connection_t *c, uint64_t request, xcb_generic_error_t **e)
-{
-    void *ret = 0;
-
-    /* If this request has not been written yet, write it. */
-    if(c->out.return_socket || _xcb_out_flush_to(c, request))
-    {
-        pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
-        reader_list reader;
-
-        insert_reader(&c->in.readers, &reader, request, &cond);
-
-        while(!poll_for_reply(c, request, &ret, e))
-            if(!_xcb_conn_wait(c, &cond, 0, 0))
-                break;
-
-        remove_reader(&c->in.readers, &reader);
-        pthread_cond_destroy(&cond);
-    }
-
-    _xcb_in_wake_up_next_reader(c);
-    return ret;
-}
-
-static uint64_t widen(xcb_connection_t *c, unsigned int request)
-{
-    uint64_t widened_request = (c->out.request & UINT64_C(0xffffffff00000000)) | request;
-    if(widened_request > c->out.request)
-        widened_request -= UINT64_C(1) << 32;
-    return widened_request;
-}
-
-/* Public interface */
-
-void *xcb_wait_for_reply(xcb_connection_t *c, unsigned int request, xcb_generic_error_t **e)
-{
-    void *ret;
-    if(e)
-        *e = 0;
-    if(c->has_error)
-        return 0;
-
-    pthread_mutex_lock(&c->iolock);
-    ret = wait_for_reply(c, widen(c, request), e);
-    pthread_mutex_unlock(&c->iolock);
-    return ret;
-}
-
-static void insert_pending_discard(xcb_connection_t *c, pending_reply **prev_next, uint64_t seq)
-{
-    pending_reply *pend;
-    pend = malloc(sizeof(*pend));
-    if(!pend)
-    {
-        _xcb_conn_shutdown(c);
-        return;
-    }
-
-    pend->first_request = seq;
-    pend->last_request = seq;
-    pend->workaround = 0;
-    pend->flags = XCB_REQUEST_DISCARD_REPLY;
-    pend->next = *prev_next;
-    *prev_next = pend;
-
-    if(!pend->next)
-        c->in.pending_replies_tail = &pend->next;
-}
-
-static void discard_reply(xcb_connection_t *c, uint64_t request)
-{
-    void *reply;
-    pending_reply **prev_pend;
-
-    /* Free any replies or errors that we've already read. Stop if
-     * xcb_wait_for_reply would block or we've run out of replies. */
-    while(poll_for_reply(c, request, &reply, 0) && reply)
-        free(reply);
-
-    /* If we've proven there are no more responses coming, we're done. */
-    if(XCB_SEQUENCE_COMPARE(request, <=, c->in.request_completed))
-        return;
-
-    /* Walk the list of pending requests. Mark the first match for deletion. */
-    for(prev_pend = &c->in.pending_replies; *prev_pend; prev_pend = &(*prev_pend)->next)
-    {
-        if(XCB_SEQUENCE_COMPARE((*prev_pend)->first_request, >, request))
-            break;
-
-        if((*prev_pend)->first_request == request)
-        {
-            /* Pending reply found. Mark for discard: */
-            (*prev_pend)->flags |= XCB_REQUEST_DISCARD_REPLY;
-            return;
-        }
-    }
-
-    /* Pending reply not found (likely due to _unchecked request). Create one: */
-    insert_pending_discard(c, prev_pend, request);
-}
-
-void xcb_discard_reply(xcb_connection_t *c, unsigned int sequence)
-{
-    if(c->has_error)
-        return;
-
-    /* If an error occurred when issuing the request, fail immediately. */
-    if(!sequence)
-        return;
-
-    pthread_mutex_lock(&c->iolock);
-    discard_reply(c, widen(c, sequence));
-    pthread_mutex_unlock(&c->iolock);
-}
-
-int xcb_poll_for_reply(xcb_connection_t *c, unsigned int request, void **reply, xcb_generic_error_t **error)
-{
-    int ret;
-    if(c->has_error)
-    {
-        *reply = 0;
-        if(error)
-            *error = 0;
-        return 1; /* would not block */
-    }
-    assert(reply != 0);
-    pthread_mutex_lock(&c->iolock);
-    ret = poll_for_reply(c, widen(c, request), reply, error);
-    pthread_mutex_unlock(&c->iolock);
-    return ret;
-}
-
-xcb_generic_event_t *xcb_wait_for_event(xcb_connection_t *c)
-{
-    xcb_generic_event_t *ret;
-    if(c->has_error)
-        return 0;
-    pthread_mutex_lock(&c->iolock);
-    /* get_event returns 0 on empty list. */
-    while(!(ret = get_event(c)))
-        if(!_xcb_conn_wait(c, &c->in.event_cond, 0, 0))
-            break;
-
-    _xcb_in_wake_up_next_reader(c);
-    pthread_mutex_unlock(&c->iolock);
-    return ret;
-}
-
-static xcb_generic_event_t *poll_for_next_event(xcb_connection_t *c, int queued)
-{
-    xcb_generic_event_t *ret = 0;
-    if(!c->has_error)
-    {
-        pthread_mutex_lock(&c->iolock);
-        /* FIXME: follow X meets Z architecture changes. */
-        ret = get_event(c);
-        if(!ret && !queued && c->in.reading == 0 && _xcb_in_read(c)) /* _xcb_in_read shuts down the connection on error */
-            ret = get_event(c);
-        pthread_mutex_unlock(&c->iolock);
-    }
-    return ret;
-}
-
-xcb_generic_event_t *xcb_poll_for_event(xcb_connection_t *c)
-{
-    return poll_for_next_event(c, 0);
-}
-
-xcb_generic_event_t *xcb_poll_for_queued_event(xcb_connection_t *c)
-{
-    return poll_for_next_event(c, 1);
-}
-
-xcb_generic_error_t *xcb_request_check(xcb_connection_t *c, xcb_void_cookie_t cookie)
-{
-    uint64_t request;
-    xcb_generic_error_t *ret = 0;
-    void *reply;
-    if(c->has_error)
-        return 0;
-    pthread_mutex_lock(&c->iolock);
-    request = widen(c, cookie.sequence);
-    if(XCB_SEQUENCE_COMPARE(request, >=, c->in.request_expected)
-       && XCB_SEQUENCE_COMPARE(request, >, c->in.request_completed))
-    {
-        _xcb_out_send_sync(c);
-        _xcb_out_flush_to(c, c->out.request);
-    }
-    reply = wait_for_reply(c, request, &ret);
-    assert(!reply);
-    pthread_mutex_unlock(&c->iolock);
-    return ret;
-}
-
-/* Private interface */
-
-int _xcb_in_init(_xcb_in *in)
-{
-    if(pthread_cond_init(&in->event_cond, 0))
-        return 0;
-    in->reading = 0;
-
-    in->queue_len = 0;
-
-    in->request_read = 0;
-    in->request_completed = 0;
-
-    in->replies = _xcb_map_new();
-    if(!in->replies)
-        return 0;
-
-    in->current_reply_tail = &in->current_reply;
-    in->events_tail = &in->events;
-    in->pending_replies_tail = &in->pending_replies;
-
-    return 1;
-}
-
-void _xcb_in_destroy(_xcb_in *in)
-{
-    pthread_cond_destroy(&in->event_cond);
-    free_reply_list(in->current_reply);
-    _xcb_map_delete(in->replies, (void (*)(void *)) free_reply_list);
-    while(in->events)
-    {
-        struct event_list *e = in->events;
-        in->events = e->next;
-        free(e->event);
-        free(e);
-    }
-    while(in->pending_replies)
-    {
-        pending_reply *pend = in->pending_replies;
-        in->pending_replies = pend->next;
-        free(pend);
-    }
-}
-
-void _xcb_in_wake_up_next_reader(xcb_connection_t *c)
-{
-    int pthreadret;
-    if(c->in.readers)
-        pthreadret = pthread_cond_signal(c->in.readers->data);
-    else
-        pthreadret = pthread_cond_signal(&c->in.event_cond);
-    assert(pthreadret == 0);
-}
-
-int _xcb_in_expect_reply(xcb_connection_t *c, uint64_t request, enum workarounds workaround, int flags)
-{
-    pending_reply *pend = malloc(sizeof(pending_reply));
-    assert(workaround != WORKAROUND_NONE || flags != 0);
-    if(!pend)
-    {
-        _xcb_conn_shutdown(c);
-        return 0;
-    }
-    pend->first_request = pend->last_request = request;
-    pend->workaround = workaround;
-    pend->flags = flags;
-    pend->next = 0;
-    *c->in.pending_replies_tail = pend;
-    c->in.pending_replies_tail = &pend->next;
-    return 1;
-}
-
-void _xcb_in_replies_done(xcb_connection_t *c)
-{
-    struct pending_reply *pend;
-    if (c->in.pending_replies_tail != &c->in.pending_replies)
-    {
-        pend = container_of(c->in.pending_replies_tail, struct pending_reply, next);
-        if(pend->workaround == WORKAROUND_EXTERNAL_SOCKET_OWNER)
-        {
-            pend->last_request = c->out.request;
-            pend->workaround = WORKAROUND_NONE;
-        }
-    }
-}
-
-int _xcb_in_read(xcb_connection_t *c)
-{
-    int n = recv(c->fd, c->in.queue + c->in.queue_len, sizeof(c->in.queue) - c->in.queue_len,MSG_WAITALL);
-    if(n > 0)
-        c->in.queue_len += n;
-    while(read_packet(c))
-        /* empty */;
-#ifndef _WIN32
-    if((n > 0) || (n < 0 && errno == EAGAIN))
-#else
-    if((n > 0) || (n < 0 && WSAGetLastError() == WSAEWOULDBLOCK))
-#endif /* !_WIN32 */
-        return 1;
-    _xcb_conn_shutdown(c);
-    return 0;
-}
-
-int _xcb_in_read_block(xcb_connection_t *c, void *buf, int len)
-{
-    int done = c->in.queue_len;
-    if(len < done)
-        done = len;
-
-    memcpy(buf, c->in.queue, done);
-    c->in.queue_len -= done;
-    memmove(c->in.queue, c->in.queue + done, c->in.queue_len);
-
-    if(len > done)
-    {
-        int ret = read_block(c->fd, (char *) buf + done, len - done);
-        if(ret <= 0)
-        {
-            _xcb_conn_shutdown(c);
-            return ret;
-        }
-    }
-
-    return len;
-}
+/* Copyright (C) 2001-2004 Bart Massey and Jamey Sharp.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 
+ * Except as contained in this notice, the names of the authors or their
+ * institutions shall not be used in advertising or otherwise to promote the
+ * sale, use or other dealings in this Software without prior written
+ * authorization from the authors.
+ */
+
+/* Stuff that reads stuff from the server. */
+
+#include <assert.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <errno.h>
+
+#include "xcb.h"
+#include "xcbext.h"
+#include "xcbint.h"
+#if USE_POLL
+#include <poll.h>
+#endif
+#ifndef _WIN32
+#include <sys/select.h>
+#include <sys/socket.h>
+#endif
+
+#ifdef _WIN32
+#include "xcb_windefs.h"
+#endif /* _WIN32 */
+
+#define XCB_ERROR 0
+#define XCB_REPLY 1
+#define XCB_XGE_EVENT 35
+
+#ifdef _MSC_VER
+#ifdef MSG_WAITALL
+#undef MSG_WAITALL
+#endif
+#endif
+
+/* required for compiling for Win32 using MinGW */
+#ifndef MSG_WAITALL
+#define MSG_WAITALL 0
+#endif
+
+struct event_list {
+    xcb_generic_event_t *event;
+    struct event_list *next;
+};
+
+struct reply_list {
+    void *reply;
+    struct reply_list *next;
+};
+
+typedef struct pending_reply {
+    uint64_t first_request;
+    uint64_t last_request;
+    enum workarounds workaround;
+    int flags;
+    struct pending_reply *next;
+} pending_reply;
+
+typedef struct reader_list {
+    uint64_t request;
+    pthread_cond_t *data;
+    struct reader_list *next;
+} reader_list;
+
+static void remove_finished_readers(reader_list **prev_reader, uint64_t completed)
+{
+    while(*prev_reader && XCB_SEQUENCE_COMPARE((*prev_reader)->request, <=, completed))
+    {
+        /* If you don't have what you're looking for now, you never
+         * will. Wake up and leave me alone. */
+        pthread_cond_signal((*prev_reader)->data);
+        *prev_reader = (*prev_reader)->next;
+    }
+}
+
+static int read_packet(xcb_connection_t *c)
+{
+    xcb_generic_reply_t genrep;
+    int length = 32;
+    int eventlength = 0; /* length after first 32 bytes for GenericEvents */
+    void *buf;
+    pending_reply *pend = 0;
+    struct event_list *event;
+
+    /* Wait for there to be enough data for us to read a whole packet */
+    if(c->in.queue_len < length)
+        return 0;
+
+    /* Get the response type, length, and sequence number. */
+    memcpy(&genrep, c->in.queue, sizeof(genrep));
+
+    /* Compute 32-bit sequence number of this packet. */
+    if((genrep.response_type & 0x7f) != XCB_KEYMAP_NOTIFY)
+    {
+        uint64_t lastread = c->in.request_read;
+        c->in.request_read = (lastread & UINT64_C(0xffffffffffff0000)) | genrep.sequence;
+        if(XCB_SEQUENCE_COMPARE(c->in.request_read, <, lastread))
+            c->in.request_read += 0x10000;
+        if(XCB_SEQUENCE_COMPARE(c->in.request_read, >, c->in.request_expected))
+            c->in.request_expected = c->in.request_read;
+
+        if(c->in.request_read != lastread)
+        {
+            if(c->in.current_reply)
+            {
+                _xcb_map_put(c->in.replies, lastread, c->in.current_reply);
+                c->in.current_reply = 0;
+                c->in.current_reply_tail = &c->in.current_reply;
+            }
+            c->in.request_completed = c->in.request_read - 1;
+        }
+
+        while(c->in.pending_replies && 
+              c->in.pending_replies->workaround != WORKAROUND_EXTERNAL_SOCKET_OWNER &&
+	      XCB_SEQUENCE_COMPARE (c->in.pending_replies->last_request, <=, c->in.request_completed))
+        {
+            pending_reply *oldpend = c->in.pending_replies;
+            c->in.pending_replies = oldpend->next;
+            if(!oldpend->next)
+                c->in.pending_replies_tail = &c->in.pending_replies;
+            free(oldpend);
+        }
+
+        if(genrep.response_type == XCB_ERROR)
+            c->in.request_completed = c->in.request_read;
+
+        remove_finished_readers(&c->in.readers, c->in.request_completed);
+    }
+
+    if(genrep.response_type == XCB_ERROR || genrep.response_type == XCB_REPLY)
+    {
+        pend = c->in.pending_replies;
+        if(pend &&
+           !(XCB_SEQUENCE_COMPARE(pend->first_request, <=, c->in.request_read) &&
+             (pend->workaround == WORKAROUND_EXTERNAL_SOCKET_OWNER ||
+              XCB_SEQUENCE_COMPARE(c->in.request_read, <=, pend->last_request))))
+            pend = 0;
+    }
+
+    /* For reply packets, check that the entire packet is available. */
+    if(genrep.response_type == XCB_REPLY)
+    {
+        if(pend && pend->workaround == WORKAROUND_GLX_GET_FB_CONFIGS_BUG)
+        {
+            uint32_t *p = (uint32_t *) c->in.queue;
+            genrep.length = p[2] * p[3] * 2;
+        }
+        length += genrep.length * 4;
+    }
+
+    /* XGE events may have sizes > 32 */
+    if ((genrep.response_type & 0x7f) == XCB_XGE_EVENT)
+        eventlength = genrep.length * 4;
+
+    buf = malloc(length + eventlength +
+            (genrep.response_type == XCB_REPLY ? 0 : sizeof(uint32_t)));
+    if(!buf)
+    {
+        _xcb_conn_shutdown(c);
+        return 0;
+    }
+
+    if(_xcb_in_read_block(c, buf, length) <= 0)
+    {
+        free(buf);
+        return 0;
+    }
+
+    /* pull in XGE event data if available, append after event struct */
+    if (eventlength)
+    {
+        if(_xcb_in_read_block(c, &((xcb_generic_event_t*)buf)[1], eventlength) <= 0)
+        {
+            free(buf);
+            return 0;
+        }
+    }
+
+    if(pend && (pend->flags & XCB_REQUEST_DISCARD_REPLY))
+    {
+        free(buf);
+        return 1;
+    }
+
+    if(genrep.response_type != XCB_REPLY)
+        ((xcb_generic_event_t *) buf)->full_sequence = c->in.request_read;
+
+    /* reply, or checked error */
+    if( genrep.response_type == XCB_REPLY ||
+       (genrep.response_type == XCB_ERROR && pend && (pend->flags & XCB_REQUEST_CHECKED)))
+    {
+        struct reply_list *cur = malloc(sizeof(struct reply_list));
+        if(!cur)
+        {
+            _xcb_conn_shutdown(c);
+            free(buf);
+            return 0;
+        }
+        cur->reply = buf;
+        cur->next = 0;
+        *c->in.current_reply_tail = cur;
+        c->in.current_reply_tail = &cur->next;
+        if(c->in.readers && c->in.readers->request == c->in.request_read)
+            pthread_cond_signal(c->in.readers->data);
+        return 1;
+    }
+
+    /* event, or unchecked error */
+    event = malloc(sizeof(struct event_list));
+    if(!event)
+    {
+        _xcb_conn_shutdown(c);
+        free(buf);
+        return 0;
+    }
+    event->event = buf;
+    event->next = 0;
+    *c->in.events_tail = event;
+    c->in.events_tail = &event->next;
+    pthread_cond_signal(&c->in.event_cond);
+    return 1; /* I have something for you... */
+}
+
+static xcb_generic_event_t *get_event(xcb_connection_t *c)
+{
+    struct event_list *cur = c->in.events;
+    xcb_generic_event_t *ret;
+    if(!c->in.events)
+        return 0;
+    ret = cur->event;
+    c->in.events = cur->next;
+    if(!cur->next)
+        c->in.events_tail = &c->in.events;
+    free(cur);
+    return ret;
+}
+
+static void free_reply_list(struct reply_list *head)
+{
+    while(head)
+    {
+        struct reply_list *cur = head;
+        head = cur->next;
+        free(cur->reply);
+        free(cur);
+    }
+}
+
+static int read_block(const int fd, void *buf, const ssize_t len)
+{
+    int done = 0;
+    while(done < len)
+    {
+        int ret = recv(fd, ((char *) buf) + done, len - done,MSG_WAITALL);
+        if(ret > 0)
+            done += ret;
+#ifndef _WIN32
+        if(ret < 0 && errno == EAGAIN)
+#else
+        if(ret == SOCKET_ERROR && WSAGetLastError() == WSAEWOULDBLOCK)
+#endif /* !_Win32 */
+        {
+#if USE_POLL
+            struct pollfd pfd;
+            pfd.fd = fd;
+            pfd.events = POLLIN;
+            pfd.revents = 0;
+            do {
+                ret = poll(&pfd, 1, -1);
+            } while (ret == -1 && errno == EINTR);
+#else
+            fd_set fds;
+            FD_ZERO(&fds);
+            FD_SET(fd, &fds);
+
+	    /* Initializing errno here makes sure that for Win32 this loop will execute only once */
+	    errno = 0;  
+	    do {
+		ret = select(fd + 1, &fds, 0, 0, 0);
+	    } while (ret == -1 && errno == EINTR);
+#endif /* USE_POLL */
+        }
+        if(ret <= 0)
+            return ret;
+    }
+    return len;
+}
+
+static int poll_for_reply(xcb_connection_t *c, uint64_t request, void **reply, xcb_generic_error_t **error)
+{
+    struct reply_list *head;
+
+    /* If an error occurred when issuing the request, fail immediately. */
+    if(!request)
+        head = 0;
+    /* We've read requests past the one we want, so if it has replies we have
+     * them all and they're in the replies map. */
+    else if(XCB_SEQUENCE_COMPARE(request, <, c->in.request_read))
+    {
+        head = _xcb_map_remove(c->in.replies, request);
+        if(head && head->next)
+            _xcb_map_put(c->in.replies, request, head->next);
+    }
+    /* We're currently processing the responses to the request we want, and we
+     * have a reply ready to return. So just return it without blocking. */
+    else if(request == c->in.request_read && c->in.current_reply)
+    {
+        head = c->in.current_reply;
+        c->in.current_reply = head->next;
+        if(!head->next)
+            c->in.current_reply_tail = &c->in.current_reply;
+    }
+    /* We know this request can't have any more replies, and we've already
+     * established it doesn't have a reply now. Don't bother blocking. */
+    else if(request == c->in.request_completed)
+        head = 0;
+    /* We may have more replies on the way for this request: block until we're
+     * sure. */
+    else
+        return 0;
+
+    if(error)
+        *error = 0;
+    *reply = 0;
+
+    if(head)
+    {
+        if(((xcb_generic_reply_t *) head->reply)->response_type == XCB_ERROR)
+        {
+            if(error)
+                *error = head->reply;
+            else
+                free(head->reply);
+        }
+        else
+            *reply = head->reply;
+
+        free(head);
+    }
+
+    return 1;
+}
+
+static void insert_reader(reader_list **prev_reader, reader_list *reader, uint64_t request, pthread_cond_t *cond)
+{
+    while(*prev_reader && XCB_SEQUENCE_COMPARE((*prev_reader)->request, <=, request))
+        prev_reader = &(*prev_reader)->next;
+    reader->request = request;
+    reader->data = cond;
+    reader->next = *prev_reader;
+    *prev_reader = reader;
+}
+
+static void remove_reader(reader_list **prev_reader, reader_list *reader)
+{
+    while(*prev_reader && XCB_SEQUENCE_COMPARE((*prev_reader)->request, <=, reader->request))
+        if(*prev_reader == reader)
+        {
+            *prev_reader = (*prev_reader)->next;
+            break;
+        }
+}
+
+static void *wait_for_reply(xcb_connection_t *c, uint64_t request, xcb_generic_error_t **e)
+{
+    void *ret = 0;
+
+    /* If this request has not been written yet, write it. */
+    if(c->out.return_socket || _xcb_out_flush_to(c, request))
+    {
+        pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
+        reader_list reader;
+
+        insert_reader(&c->in.readers, &reader, request, &cond);
+
+        while(!poll_for_reply(c, request, &ret, e))
+            if(!_xcb_conn_wait(c, &cond, 0, 0))
+                break;
+
+        remove_reader(&c->in.readers, &reader);
+        pthread_cond_destroy(&cond);
+    }
+
+    _xcb_in_wake_up_next_reader(c);
+    return ret;
+}
+
+static uint64_t widen(xcb_connection_t *c, unsigned int request)
+{
+    uint64_t widened_request = (c->out.request & UINT64_C(0xffffffff00000000)) | request;
+    if(widened_request > c->out.request)
+        widened_request -= UINT64_C(1) << 32;
+    return widened_request;
+}
+
+/* Public interface */
+
+void *xcb_wait_for_reply(xcb_connection_t *c, unsigned int request, xcb_generic_error_t **e)
+{
+    void *ret;
+    if(e)
+        *e = 0;
+    if(c->has_error)
+        return 0;
+
+    pthread_mutex_lock(&c->iolock);
+    ret = wait_for_reply(c, widen(c, request), e);
+    pthread_mutex_unlock(&c->iolock);
+    return ret;
+}
+
+static void insert_pending_discard(xcb_connection_t *c, pending_reply **prev_next, uint64_t seq)
+{
+    pending_reply *pend;
+    pend = malloc(sizeof(*pend));
+    if(!pend)
+    {
+        _xcb_conn_shutdown(c);
+        return;
+    }
+
+    pend->first_request = seq;
+    pend->last_request = seq;
+    pend->workaround = 0;
+    pend->flags = XCB_REQUEST_DISCARD_REPLY;
+    pend->next = *prev_next;
+    *prev_next = pend;
+
+    if(!pend->next)
+        c->in.pending_replies_tail = &pend->next;
+}
+
+static void discard_reply(xcb_connection_t *c, uint64_t request)
+{
+    void *reply;
+    pending_reply **prev_pend;
+
+    /* Free any replies or errors that we've already read. Stop if
+     * xcb_wait_for_reply would block or we've run out of replies. */
+    while(poll_for_reply(c, request, &reply, 0) && reply)
+        free(reply);
+
+    /* If we've proven there are no more responses coming, we're done. */
+    if(XCB_SEQUENCE_COMPARE(request, <=, c->in.request_completed))
+        return;
+
+    /* Walk the list of pending requests. Mark the first match for deletion. */
+    for(prev_pend = &c->in.pending_replies; *prev_pend; prev_pend = &(*prev_pend)->next)
+    {
+        if(XCB_SEQUENCE_COMPARE((*prev_pend)->first_request, >, request))
+            break;
+
+        if((*prev_pend)->first_request == request)
+        {
+            /* Pending reply found. Mark for discard: */
+            (*prev_pend)->flags |= XCB_REQUEST_DISCARD_REPLY;
+            return;
+        }
+    }
+
+    /* Pending reply not found (likely due to _unchecked request). Create one: */
+    insert_pending_discard(c, prev_pend, request);
+}
+
+void xcb_discard_reply(xcb_connection_t *c, unsigned int sequence)
+{
+    if(c->has_error)
+        return;
+
+    /* If an error occurred when issuing the request, fail immediately. */
+    if(!sequence)
+        return;
+
+    pthread_mutex_lock(&c->iolock);
+    discard_reply(c, widen(c, sequence));
+    pthread_mutex_unlock(&c->iolock);
+}
+
+int xcb_poll_for_reply(xcb_connection_t *c, unsigned int request, void **reply, xcb_generic_error_t **error)
+{
+    int ret;
+    if(c->has_error)
+    {
+        *reply = 0;
+        if(error)
+            *error = 0;
+        return 1; /* would not block */
+    }
+    assert(reply != 0);
+    pthread_mutex_lock(&c->iolock);
+    ret = poll_for_reply(c, widen(c, request), reply, error);
+    pthread_mutex_unlock(&c->iolock);
+    return ret;
+}
+
+xcb_generic_event_t *xcb_wait_for_event(xcb_connection_t *c)
+{
+    xcb_generic_event_t *ret;
+    if(c->has_error)
+        return 0;
+    pthread_mutex_lock(&c->iolock);
+    /* get_event returns 0 on empty list. */
+    while(!(ret = get_event(c)))
+        if(!_xcb_conn_wait(c, &c->in.event_cond, 0, 0))
+            break;
+
+    _xcb_in_wake_up_next_reader(c);
+    pthread_mutex_unlock(&c->iolock);
+    return ret;
+}
+
+static xcb_generic_event_t *poll_for_next_event(xcb_connection_t *c, int queued)
+{
+    xcb_generic_event_t *ret = 0;
+    if(!c->has_error)
+    {
+        pthread_mutex_lock(&c->iolock);
+        /* FIXME: follow X meets Z architecture changes. */
+        ret = get_event(c);
+        if(!ret && !queued && c->in.reading == 0 && _xcb_in_read(c)) /* _xcb_in_read shuts down the connection on error */
+            ret = get_event(c);
+        pthread_mutex_unlock(&c->iolock);
+    }
+    return ret;
+}
+
+xcb_generic_event_t *xcb_poll_for_event(xcb_connection_t *c)
+{
+    return poll_for_next_event(c, 0);
+}
+
+xcb_generic_event_t *xcb_poll_for_queued_event(xcb_connection_t *c)
+{
+    return poll_for_next_event(c, 1);
+}
+
+xcb_generic_error_t *xcb_request_check(xcb_connection_t *c, xcb_void_cookie_t cookie)
+{
+    uint64_t request;
+    xcb_generic_error_t *ret = 0;
+    void *reply;
+    if(c->has_error)
+        return 0;
+    pthread_mutex_lock(&c->iolock);
+    request = widen(c, cookie.sequence);
+    if(XCB_SEQUENCE_COMPARE(request, >=, c->in.request_expected)
+       && XCB_SEQUENCE_COMPARE(request, >, c->in.request_completed))
+    {
+        _xcb_out_send_sync(c);
+        _xcb_out_flush_to(c, c->out.request);
+    }
+    reply = wait_for_reply(c, request, &ret);
+    assert(!reply);
+    pthread_mutex_unlock(&c->iolock);
+    return ret;
+}
+
+/* Private interface */
+
+int _xcb_in_init(_xcb_in *in)
+{
+    if(pthread_cond_init(&in->event_cond, 0))
+        return 0;
+    in->reading = 0;
+
+    in->queue_len = 0;
+
+    in->request_read = 0;
+    in->request_completed = 0;
+
+    in->replies = _xcb_map_new();
+    if(!in->replies)
+        return 0;
+
+    in->current_reply_tail = &in->current_reply;
+    in->events_tail = &in->events;
+    in->pending_replies_tail = &in->pending_replies;
+
+    return 1;
+}
+
+void _xcb_in_destroy(_xcb_in *in)
+{
+    pthread_cond_destroy(&in->event_cond);
+    free_reply_list(in->current_reply);
+    _xcb_map_delete(in->replies, (void (*)(void *)) free_reply_list);
+    while(in->events)
+    {
+        struct event_list *e = in->events;
+        in->events = e->next;
+        free(e->event);
+        free(e);
+    }
+    while(in->pending_replies)
+    {
+        pending_reply *pend = in->pending_replies;
+        in->pending_replies = pend->next;
+        free(pend);
+    }
+}
+
+void _xcb_in_wake_up_next_reader(xcb_connection_t *c)
+{
+    int pthreadret;
+    if(c->in.readers)
+        pthreadret = pthread_cond_signal(c->in.readers->data);
+    else
+        pthreadret = pthread_cond_signal(&c->in.event_cond);
+    assert(pthreadret == 0);
+}
+
+int _xcb_in_expect_reply(xcb_connection_t *c, uint64_t request, enum workarounds workaround, int flags)
+{
+    pending_reply *pend = malloc(sizeof(pending_reply));
+    assert(workaround != WORKAROUND_NONE || flags != 0);
+    if(!pend)
+    {
+        _xcb_conn_shutdown(c);
+        return 0;
+    }
+    pend->first_request = pend->last_request = request;
+    pend->workaround = workaround;
+    pend->flags = flags;
+    pend->next = 0;
+    *c->in.pending_replies_tail = pend;
+    c->in.pending_replies_tail = &pend->next;
+    return 1;
+}
+
+void _xcb_in_replies_done(xcb_connection_t *c)
+{
+    struct pending_reply *pend;
+    if (c->in.pending_replies_tail != &c->in.pending_replies)
+    {
+        pend = container_of(c->in.pending_replies_tail, struct pending_reply, next);
+        if(pend->workaround == WORKAROUND_EXTERNAL_SOCKET_OWNER)
+        {
+            pend->last_request = c->out.request;
+            pend->workaround = WORKAROUND_NONE;
+        }
+    }
+}
+
+int _xcb_in_read(xcb_connection_t *c)
+{
+    int n = recv(c->fd, c->in.queue + c->in.queue_len, sizeof(c->in.queue) - c->in.queue_len,MSG_WAITALL);
+    if(n > 0)
+        c->in.queue_len += n;
+    while(read_packet(c))
+        /* empty */;
+#ifndef _WIN32
+    if((n > 0) || (n < 0 && errno == EAGAIN))
+#else
+    if((n > 0) || (n < 0 && WSAGetLastError() == WSAEWOULDBLOCK))
+#endif /* !_WIN32 */
+        return 1;
+    _xcb_conn_shutdown(c);
+    return 0;
+}
+
+int _xcb_in_read_block(xcb_connection_t *c, void *buf, int len)
+{
+    int done = c->in.queue_len;
+    if(len < done)
+        done = len;
+
+    memcpy(buf, c->in.queue, done);
+    c->in.queue_len -= done;
+    memmove(c->in.queue, c->in.queue + done, c->in.queue_len);
+
+    if(len > done)
+    {
+        int ret = read_block(c->fd, (char *) buf + done, len - done);
+        if(ret <= 0)
+        {
+            _xcb_conn_shutdown(c);
+            return ret;
+        }
+    }
+
+    return len;
+}
diff --git a/libxcb/src/xcb_util.c b/libxcb/src/xcb_util.c
index 647096ce6..4fc8797c5 100644
--- a/libxcb/src/xcb_util.c
+++ b/libxcb/src/xcb_util.c
@@ -1,486 +1,486 @@
-/* Copyright (C) 2001-2004 Bart Massey and Jamey Sharp.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- * 
- * Except as contained in this notice, the names of the authors or their
- * institutions shall not be used in advertising or otherwise to promote the
- * sale, use or other dealings in this Software without prior written
- * authorization from the authors.
- */
-
-/* Utility functions implementable using only public APIs. */
-
-#include <assert.h>
-#include <sys/types.h>
-#include <limits.h>
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stddef.h>
-#include <unistd.h>
-#include <string.h>
-#ifndef _MSC_VER
-#include <arpa/inet.h>
-#endif
-
-#ifdef _WIN32
-#include "xcb_windefs.h"
-#else
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#include <fcntl.h>
-#include <netdb.h>
-#endif /* _WIN32 */
-
-#include "xcb.h"
-#include "xcbext.h"
-#include "xcbint.h"
-
-/* must be after "xcbint.h" to get autoconf #defines */
-#if defined(HAVE_TSOL_LABEL_H) && defined(HAVE_IS_SYSTEM_LABELED)
-# include <tsol/label.h>
-# include <sys/stat.h>
-#endif
-
-#ifdef _MSC_VER
-#ifdef close
-#undef close
-#endif
-#define close(fd) closesocket(fd)
-#endif
-
-int xcb_popcount(uint32_t mask)
-{
-    uint32_t y;
-    y = (mask >> 1) & 033333333333;
-    y = mask - y - ((y >> 1) & 033333333333);
-    return ((y + (y >> 3)) & 030707070707) % 077;
-}
-
-int xcb_sumof(uint8_t *list, int len)
-{
-  int i, s = 0;
-  for(i=0; i<len; i++) {
-    s += *list;
-    list++;
-  }
-  return s;
-}
-
-static int _xcb_parse_display(const char *name, char **host, char **protocol,
-                      int *displayp, int *screenp)
-{
-    int len, display, screen;
-    char *slash, *colon, *dot, *end;
-
-    if(!name || !*name)
-        name = getenv("DISPLAY");
-    if(!name)
-        return 0;
-
-#ifdef HAVE_LAUNCHD
-    if(strncmp(name, "/tmp/launch", 11) == 0)
-        slash = NULL;
-    else
-#endif
-    slash = strrchr(name, '/');
-
-    if (slash) {
-        len = slash - name;
-        if (protocol) {
-            *protocol = malloc(len + 1);
-            if(!*protocol)
-                return 0;
-            memcpy(*protocol, name, len);
-            (*protocol)[len] = '\0';
-        }
-        name = slash + 1;
-    } else
-        if (protocol)
-            *protocol = NULL;
-
-    colon = strrchr(name, ':');
-    if(!colon)
-        goto error_out;
-    len = colon - name;
-    ++colon;
-    display = strtoul(colon, &dot, 10);
-    if(dot == colon)
-        goto error_out;
-    if(*dot == '\0')
-        screen = 0;
-    else
-    {
-        if(*dot != '.')
-            goto error_out;
-        ++dot;
-        screen = strtoul(dot, &end, 10);
-        if(end == dot || *end != '\0')
-            goto error_out;
-    }
-    /* At this point, the display string is fully parsed and valid, but
-     * the caller's memory is untouched. */
-
-    *host = malloc(len + 1);
-    if(!*host)
-        goto error_out;
-    memcpy(*host, name, len);
-    (*host)[len] = '\0';
-    *displayp = display;
-    if(screenp)
-        *screenp = screen;
-    return 1;
-
-error_out:
-    if (protocol) {
-        free(*protocol);
-        *protocol = NULL;
-    }
-
-    return 0;
-}
-
-int xcb_parse_display(const char *name, char **host, int *displayp,
-                             int *screenp)
-{
-    return _xcb_parse_display(name, host, NULL, displayp, screenp);
-}
-
-static int _xcb_open_tcp(const char *host, char *protocol, const unsigned short port);
-#ifndef _WIN32
-static int _xcb_open_unix(char *protocol, const char *file);
-#endif /* !WIN32 */
-#ifdef HAVE_ABSTRACT_SOCKETS
-static int _xcb_open_abstract(char *protocol, const char *file, size_t filelen);
-#endif
-
-static int _xcb_open(const char *host, char *protocol, const int display)
-{
-    int fd;
-    static const char unix_base[] = "/tmp/.X11-unix/X";
-    const char *base = unix_base;
-    size_t filelen;
-    char *file = NULL;
-    int actual_filelen;
-
-#ifdef HAVE_LAUNCHD
-    if(strncmp(host, "/tmp/launch", 11) == 0) {
-        base = host;
-        host = "";
-        protocol = NULL;
-    }
-#endif
-
-    /* If protocol or host is "unix", fall through to Unix socket code below */
-    if ((!protocol || (strcmp("unix",protocol) != 0)) &&
-        (*host != '\0') && (strcmp("unix",host) != 0))
-    {
-        /* display specifies TCP */
-        unsigned short port = X_TCP_PORT + display;
-        return _xcb_open_tcp(host, protocol, port);
-    }
-
-#ifndef _WIN32
-#if defined(HAVE_TSOL_LABEL_H) && defined(HAVE_IS_SYSTEM_LABELED)
-    /* Check special path for Unix sockets under Solaris Trusted Extensions */
-    if (is_system_labeled())
-    {
-        struct stat sbuf;
-        const char *tsol_base = "/var/tsol/doors/.X11-unix/X";
-        char tsol_socket[PATH_MAX];
-
-        snprintf(tsol_socket, sizeof(tsol_socket), "%s%d", tsol_base, display);
-
-        if (stat(tsol_socket, &sbuf) == 0)
-            base = tsol_base;
-    }
-#endif
-
-    filelen = strlen(base) + 1 + sizeof(display) * 3 + 1;
-    file = malloc(filelen);
-    if(file == NULL)
-        return -1;
-
-    /* display specifies Unix socket */
-#ifdef HAVE_LAUNCHD
-    if(strncmp(base, "/tmp/launch", 11) == 0)
-        actual_filelen = snprintf(file, filelen, "%s:%d", base, display);
-    else
-#endif
-        actual_filelen = snprintf(file, filelen, "%s%d", base, display);
-    if(actual_filelen < 0)
-    {
-        free(file);
-        return -1;
-    }
-    /* snprintf may truncate the file */
-    filelen = MIN(actual_filelen, filelen - 1);
-#ifdef HAVE_ABSTRACT_SOCKETS
-    fd = _xcb_open_abstract(protocol, file, filelen);
-    if (fd >= 0 || (errno != ENOENT && errno != ECONNREFUSED))
-    {
-        free(file);
-        return fd;
-    }
-
-#endif
-    fd = _xcb_open_unix(protocol, file);
-    free(file);
-
-    return fd;
-#endif /* !_WIN32 */
-    return -1; /* if control reaches here then something has gone wrong */
-}
-
-static int _xcb_socket(int family, int type, int proto)
-{
-    int fd;
-
-#ifdef SOCK_CLOEXEC
-    fd = socket(family, type | SOCK_CLOEXEC, proto);
-    if (fd == -1 && errno == EINVAL)
-#endif
-    {
-	fd = socket(family, type, proto);
-#ifndef _WIN32
-	if (fd >= 0)
-	    fcntl(fd, F_SETFD, FD_CLOEXEC);
-#endif
-    }
-    return fd;
-}
-
-
-static int _xcb_do_connect(int fd, const struct sockaddr* addr, int addrlen) {
-	char on = 1;
-
-	if(fd < 0)
-		return -1;
-
-	setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on));
-	setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on));
-
-	return connect(fd, addr, addrlen);
-}
-
-#ifdef WIN32
-int InitWSA(void)
-{
-  static WSADATA wsadata;
-
-  if (!wsadata.wVersion)
-  {
-    ptw32_processInitialize();
-    if (WSAStartup(0x0202, &wsadata))
-      return -1;
-  }
-  return 0;
-}
-#else
-#define InitWSA()
-#endif
-
-static int _xcb_open_tcp(const char *host, char *protocol, const unsigned short port)
-{
-    int fd = -1;
-#if HAVE_GETADDRINFO
-    struct addrinfo hints;
-    char service[6]; /* "65535" with the trailing '\0' */
-    struct addrinfo *results, *addr;
-    char *bracket;
-#endif
-
-    if (protocol && strcmp("tcp",protocol) && strcmp("inet",protocol)
-#ifdef AF_INET6
-	         && strcmp("inet6",protocol)
-#endif
-	)
-        return -1;
-	
-    if (*host == '\0')
-	host = "localhost";
-
-#if HAVE_GETADDRINFO
-    memset(&hints, 0, sizeof(hints));
-#ifdef AI_NUMERICSERV
-    hints.ai_flags |= AI_NUMERICSERV;
-#endif
-    hints.ai_family = AF_UNSPEC;
-    hints.ai_socktype = SOCK_STREAM;
-
-#ifdef AF_INET6
-    /* Allow IPv6 addresses enclosed in brackets. */
-    if(host[0] == '[' && (bracket = strrchr(host, ']')) && bracket[1] == '\0')
-    {
-        *bracket = '\0';
-        ++host;
-        hints.ai_flags |= AI_NUMERICHOST;
-        hints.ai_family = AF_INET6;
-    }
-#endif
-
-#ifdef WIN32
-    if (InitWSA()<0)
-      return -1;
-#endif
-
-    snprintf(service, sizeof(service), "%hu", port);
-    if(getaddrinfo(host, service, &hints, &results))
-        /* FIXME: use gai_strerror, and fill in error connection */
-        return -1;
-
-    for(addr = results; addr; addr = addr->ai_next)
-    {
-        fd = _xcb_socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
-        if (_xcb_do_connect(fd, addr->ai_addr, addr->ai_addrlen) >= 0)
-            break;
-        close(fd);
-        fd = -1;
-    }
-    freeaddrinfo(results);
-    return fd;
-#else
-    {
-        struct hostent* _h;
-        struct sockaddr_in _s;
-        struct in_addr ** _c;
-
-        if((_h = gethostbyname(host)) == NULL)
-            return -1;
-
-        _c = (struct in_addr**)_h->h_addr_list;
-        fd = -1;
-
-        while(*_c) {
-            _s.sin_family = AF_INET;
-            _s.sin_port = htons(port);
-            _s.sin_addr = *(*_c);
-
-            fd = _xcb_socket(_s.sin_family, SOCK_STREAM, 0);
-            if(_xcb_do_connect(fd, (struct sockaddr*)&_s, sizeof(_s)) >= 0)
-                break;
-
-            close(fd);
-            fd = -1;
-            ++_c;
-        }
-
-        return fd;
-    }
-#endif
-}
-
-#ifndef _WIN32
-static int _xcb_open_unix(char *protocol, const char *file)
-{
-    int fd;
-    struct sockaddr_un addr;
-
-    if (protocol && strcmp("unix",protocol))
-        return -1;
-
-    strcpy(addr.sun_path, file);
-    addr.sun_family = AF_UNIX;
-#ifdef HAVE_SOCKADDR_SUN_LEN
-    addr.sun_len = SUN_LEN(&addr);
-#endif
-    fd = _xcb_socket(AF_UNIX, SOCK_STREAM, 0);
-    if(fd == -1)
-        return -1;
-    if(connect(fd, (struct sockaddr *) &addr, sizeof(addr)) == -1) {
-        close(fd);
-        return -1;
-    }
-    return fd;
-}
-#endif /* !_WIN32 */
-
-#ifdef HAVE_ABSTRACT_SOCKETS
-static int _xcb_open_abstract(char *protocol, const char *file, size_t filelen)
-{
-    int fd;
-    struct sockaddr_un addr = {0};
-    socklen_t namelen;
-
-    if (protocol && strcmp("unix",protocol))
-        return -1;
-
-    strcpy(addr.sun_path + 1, file);
-    addr.sun_family = AF_UNIX;
-    namelen = offsetof(struct sockaddr_un, sun_path) + 1 + filelen;
-#ifdef HAVE_SOCKADDR_SUN_LEN
-    addr.sun_len = 1 + filelen;
-#endif
-    fd = _xcb_socket(AF_UNIX, SOCK_STREAM, 0);
-    if (fd == -1)
-        return -1;
-    if (connect(fd, (struct sockaddr *) &addr, namelen) == -1) {
-        close(fd);
-        return -1;
-    }
-    return fd;
-}
-#endif
-
-xcb_connection_t *xcb_connect(const char *displayname, int *screenp)
-{
-    return xcb_connect_to_display_with_auth_info(displayname, NULL, screenp);
-}
-
-xcb_connection_t *xcb_connect_to_display_with_auth_info(const char *displayname, xcb_auth_info_t *auth, int *screenp)
-{
-    int fd, display = 0;
-    char *host = NULL;
-    char *protocol = NULL;
-    xcb_auth_info_t ourauth;
-    xcb_connection_t *c;
-
-    int parsed = _xcb_parse_display(displayname, &host, &protocol, &display, screenp);
-    
-    if(!parsed) {
-        c = (xcb_connection_t *) &error_connection;
-        goto out;
-    } else
-        fd = _xcb_open(host, protocol, display);
-
-    if(fd == -1) {
-        c = (xcb_connection_t *) &error_connection;
-        goto out;
-    }
-
-    if(auth) {
-        c = xcb_connect_to_fd(fd, auth);
-        goto out;
-    }
-
-    if(_xcb_get_auth_info(fd, &ourauth, display))
-    {
-        c = xcb_connect_to_fd(fd, &ourauth);
-        free(ourauth.name);
-        free(ourauth.data);
-    }
-    else
-        c = xcb_connect_to_fd(fd, 0);
-
-out:
-    free(host);
-    free(protocol);
-    return c;
-}
+/* Copyright (C) 2001-2004 Bart Massey and Jamey Sharp.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 
+ * Except as contained in this notice, the names of the authors or their
+ * institutions shall not be used in advertising or otherwise to promote the
+ * sale, use or other dealings in this Software without prior written
+ * authorization from the authors.
+ */
+
+/* Utility functions implementable using only public APIs. */
+
+#include <assert.h>
+#include <sys/types.h>
+#include <limits.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <string.h>
+#ifndef _MSC_VER
+#include <arpa/inet.h>
+#endif
+
+#ifdef _WIN32
+#include "xcb_windefs.h"
+#else
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <fcntl.h>
+#include <netdb.h>
+#endif /* _WIN32 */
+
+#include "xcb.h"
+#include "xcbext.h"
+#include "xcbint.h"
+
+/* must be after "xcbint.h" to get autoconf #defines */
+#if defined(HAVE_TSOL_LABEL_H) && defined(HAVE_IS_SYSTEM_LABELED)
+# include <tsol/label.h>
+# include <sys/stat.h>
+#endif
+
+#ifdef _MSC_VER
+#ifdef close
+#undef close
+#endif
+#define close(fd) closesocket(fd)
+#endif
+
+int xcb_popcount(uint32_t mask)
+{
+    uint32_t y;
+    y = (mask >> 1) & 033333333333;
+    y = mask - y - ((y >> 1) & 033333333333);
+    return ((y + (y >> 3)) & 030707070707) % 077;
+}
+
+int xcb_sumof(uint8_t *list, int len)
+{
+  int i, s = 0;
+  for(i=0; i<len; i++) {
+    s += *list;
+    list++;
+  }
+  return s;
+}
+
+static int _xcb_parse_display(const char *name, char **host, char **protocol,
+                      int *displayp, int *screenp)
+{
+    int len, display, screen;
+    char *slash, *colon, *dot, *end;
+
+    if(!name || !*name)
+        name = getenv("DISPLAY");
+    if(!name)
+        return 0;
+
+#ifdef HAVE_LAUNCHD
+    if(strncmp(name, "/tmp/launch", 11) == 0)
+        slash = NULL;
+    else
+#endif
+    slash = strrchr(name, '/');
+
+    if (slash) {
+        len = slash - name;
+        if (protocol) {
+            *protocol = malloc(len + 1);
+            if(!*protocol)
+                return 0;
+            memcpy(*protocol, name, len);
+            (*protocol)[len] = '\0';
+        }
+        name = slash + 1;
+    } else
+        if (protocol)
+            *protocol = NULL;
+
+    colon = strrchr(name, ':');
+    if(!colon)
+        goto error_out;
+    len = colon - name;
+    ++colon;
+    display = strtoul(colon, &dot, 10);
+    if(dot == colon)
+        goto error_out;
+    if(*dot == '\0')
+        screen = 0;
+    else
+    {
+        if(*dot != '.')
+            goto error_out;
+        ++dot;
+        screen = strtoul(dot, &end, 10);
+        if(end == dot || *end != '\0')
+            goto error_out;
+    }
+    /* At this point, the display string is fully parsed and valid, but
+     * the caller's memory is untouched. */
+
+    *host = malloc(len + 1);
+    if(!*host)
+        goto error_out;
+    memcpy(*host, name, len);
+    (*host)[len] = '\0';
+    *displayp = display;
+    if(screenp)
+        *screenp = screen;
+    return 1;
+
+error_out:
+    if (protocol) {
+        free(*protocol);
+        *protocol = NULL;
+    }
+
+    return 0;
+}
+
+int xcb_parse_display(const char *name, char **host, int *displayp,
+                             int *screenp)
+{
+    return _xcb_parse_display(name, host, NULL, displayp, screenp);
+}
+
+static int _xcb_open_tcp(const char *host, char *protocol, const unsigned short port);
+#ifndef _WIN32
+static int _xcb_open_unix(char *protocol, const char *file);
+#endif /* !WIN32 */
+#ifdef HAVE_ABSTRACT_SOCKETS
+static int _xcb_open_abstract(char *protocol, const char *file, size_t filelen);
+#endif
+
+static int _xcb_open(const char *host, char *protocol, const int display)
+{
+    int fd;
+    static const char unix_base[] = "/tmp/.X11-unix/X";
+    const char *base = unix_base;
+    size_t filelen;
+    char *file = NULL;
+    int actual_filelen;
+
+#ifdef HAVE_LAUNCHD
+    if(strncmp(host, "/tmp/launch", 11) == 0) {
+        base = host;
+        host = "";
+        protocol = NULL;
+    }
+#endif
+
+    /* If protocol or host is "unix", fall through to Unix socket code below */
+    if ((!protocol || (strcmp("unix",protocol) != 0)) &&
+        (*host != '\0') && (strcmp("unix",host) != 0))
+    {
+        /* display specifies TCP */
+        unsigned short port = X_TCP_PORT + display;
+        return _xcb_open_tcp(host, protocol, port);
+    }
+
+#ifndef _WIN32
+#if defined(HAVE_TSOL_LABEL_H) && defined(HAVE_IS_SYSTEM_LABELED)
+    /* Check special path for Unix sockets under Solaris Trusted Extensions */
+    if (is_system_labeled())
+    {
+        struct stat sbuf;
+        const char *tsol_base = "/var/tsol/doors/.X11-unix/X";
+        char tsol_socket[PATH_MAX];
+
+        snprintf(tsol_socket, sizeof(tsol_socket), "%s%d", tsol_base, display);
+
+        if (stat(tsol_socket, &sbuf) == 0)
+            base = tsol_base;
+    }
+#endif
+
+    filelen = strlen(base) + 1 + sizeof(display) * 3 + 1;
+    file = malloc(filelen);
+    if(file == NULL)
+        return -1;
+
+    /* display specifies Unix socket */
+#ifdef HAVE_LAUNCHD
+    if(strncmp(base, "/tmp/launch", 11) == 0)
+        actual_filelen = snprintf(file, filelen, "%s:%d", base, display);
+    else
+#endif
+        actual_filelen = snprintf(file, filelen, "%s%d", base, display);
+    if(actual_filelen < 0)
+    {
+        free(file);
+        return -1;
+    }
+    /* snprintf may truncate the file */
+    filelen = MIN(actual_filelen, filelen - 1);
+#ifdef HAVE_ABSTRACT_SOCKETS
+    fd = _xcb_open_abstract(protocol, file, filelen);
+    if (fd >= 0 || (errno != ENOENT && errno != ECONNREFUSED))
+    {
+        free(file);
+        return fd;
+    }
+
+#endif
+    fd = _xcb_open_unix(protocol, file);
+    free(file);
+
+    return fd;
+#endif /* !_WIN32 */
+    return -1; /* if control reaches here then something has gone wrong */
+}
+
+static int _xcb_socket(int family, int type, int proto)
+{
+    int fd;
+
+#ifdef SOCK_CLOEXEC
+    fd = socket(family, type | SOCK_CLOEXEC, proto);
+    if (fd == -1 && errno == EINVAL)
+#endif
+    {
+	fd = socket(family, type, proto);
+#ifndef _WIN32
+	if (fd >= 0)
+	    fcntl(fd, F_SETFD, FD_CLOEXEC);
+#endif
+    }
+    return fd;
+}
+
+
+static int _xcb_do_connect(int fd, const struct sockaddr* addr, int addrlen) {
+	char on = 1;
+
+	if(fd < 0)
+		return -1;
+
+	setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on));
+	setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on));
+
+	return connect(fd, addr, addrlen);
+}
+
+#ifdef WIN32
+int InitWSA(void)
+{
+  static WSADATA wsadata;
+
+  if (!wsadata.wVersion)
+  {
+    ptw32_processInitialize();
+    if (WSAStartup(0x0202, &wsadata))
+      return -1;
+  }
+  return 0;
+}
+#else
+#define InitWSA()
+#endif
+
+static int _xcb_open_tcp(const char *host, char *protocol, const unsigned short port)
+{
+    int fd = -1;
+#if HAVE_GETADDRINFO
+    struct addrinfo hints;
+    char service[6]; /* "65535" with the trailing '\0' */
+    struct addrinfo *results, *addr;
+    char *bracket;
+#endif
+
+    if (protocol && strcmp("tcp",protocol) && strcmp("inet",protocol)
+#ifdef AF_INET6
+	         && strcmp("inet6",protocol)
+#endif
+	)
+        return -1;
+	
+    if (*host == '\0')
+	host = "localhost";
+
+#if HAVE_GETADDRINFO
+    memset(&hints, 0, sizeof(hints));
+#ifdef AI_NUMERICSERV
+    hints.ai_flags |= AI_NUMERICSERV;
+#endif
+    hints.ai_family = AF_UNSPEC;
+    hints.ai_socktype = SOCK_STREAM;
+
+#ifdef AF_INET6
+    /* Allow IPv6 addresses enclosed in brackets. */
+    if(host[0] == '[' && (bracket = strrchr(host, ']')) && bracket[1] == '\0')
+    {
+        *bracket = '\0';
+        ++host;
+        hints.ai_flags |= AI_NUMERICHOST;
+        hints.ai_family = AF_INET6;
+    }
+#endif
+
+#ifdef WIN32
+    if (InitWSA()<0)
+      return -1;
+#endif
+
+    snprintf(service, sizeof(service), "%hu", port);
+    if(getaddrinfo(host, service, &hints, &results))
+        /* FIXME: use gai_strerror, and fill in error connection */
+        return -1;
+
+    for(addr = results; addr; addr = addr->ai_next)
+    {
+        fd = _xcb_socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
+        if (_xcb_do_connect(fd, addr->ai_addr, addr->ai_addrlen) >= 0)
+            break;
+        close(fd);
+        fd = -1;
+    }
+    freeaddrinfo(results);
+    return fd;
+#else
+    {
+        struct hostent* _h;
+        struct sockaddr_in _s;
+        struct in_addr ** _c;
+
+        if((_h = gethostbyname(host)) == NULL)
+            return -1;
+
+        _c = (struct in_addr**)_h->h_addr_list;
+        fd = -1;
+
+        while(*_c) {
+            _s.sin_family = AF_INET;
+            _s.sin_port = htons(port);
+            _s.sin_addr = *(*_c);
+
+            fd = _xcb_socket(_s.sin_family, SOCK_STREAM, 0);
+            if(_xcb_do_connect(fd, (struct sockaddr*)&_s, sizeof(_s)) >= 0)
+                break;
+
+            close(fd);
+            fd = -1;
+            ++_c;
+        }
+
+        return fd;
+    }
+#endif
+}
+
+#ifndef _WIN32
+static int _xcb_open_unix(char *protocol, const char *file)
+{
+    int fd;
+    struct sockaddr_un addr;
+
+    if (protocol && strcmp("unix",protocol))
+        return -1;
+
+    strcpy(addr.sun_path, file);
+    addr.sun_family = AF_UNIX;
+#ifdef HAVE_SOCKADDR_SUN_LEN
+    addr.sun_len = SUN_LEN(&addr);
+#endif
+    fd = _xcb_socket(AF_UNIX, SOCK_STREAM, 0);
+    if(fd == -1)
+        return -1;
+    if(connect(fd, (struct sockaddr *) &addr, sizeof(addr)) == -1) {
+        close(fd);
+        return -1;
+    }
+    return fd;
+}
+#endif /* !_WIN32 */
+
+#ifdef HAVE_ABSTRACT_SOCKETS
+static int _xcb_open_abstract(char *protocol, const char *file, size_t filelen)
+{
+    int fd;
+    struct sockaddr_un addr = {0};
+    socklen_t namelen;
+
+    if (protocol && strcmp("unix",protocol))
+        return -1;
+
+    strcpy(addr.sun_path + 1, file);
+    addr.sun_family = AF_UNIX;
+    namelen = offsetof(struct sockaddr_un, sun_path) + 1 + filelen;
+#ifdef HAVE_SOCKADDR_SUN_LEN
+    addr.sun_len = 1 + filelen;
+#endif
+    fd = _xcb_socket(AF_UNIX, SOCK_STREAM, 0);
+    if (fd == -1)
+        return -1;
+    if (connect(fd, (struct sockaddr *) &addr, namelen) == -1) {
+        close(fd);
+        return -1;
+    }
+    return fd;
+}
+#endif
+
+xcb_connection_t *xcb_connect(const char *displayname, int *screenp)
+{
+    return xcb_connect_to_display_with_auth_info(displayname, NULL, screenp);
+}
+
+xcb_connection_t *xcb_connect_to_display_with_auth_info(const char *displayname, xcb_auth_info_t *auth, int *screenp)
+{
+    int fd, display = 0;
+    char *host = NULL;
+    char *protocol = NULL;
+    xcb_auth_info_t ourauth;
+    xcb_connection_t *c;
+
+    int parsed = _xcb_parse_display(displayname, &host, &protocol, &display, screenp);
+    
+    if(!parsed) {
+        c = (xcb_connection_t *) &error_connection;
+        goto out;
+    } else
+        fd = _xcb_open(host, protocol, display);
+
+    if(fd == -1) {
+        c = (xcb_connection_t *) &error_connection;
+        goto out;
+    }
+
+    if(auth) {
+        c = xcb_connect_to_fd(fd, auth);
+        goto out;
+    }
+
+    if(_xcb_get_auth_info(fd, &ourauth, display))
+    {
+        c = xcb_connect_to_fd(fd, &ourauth);
+        free(ourauth.name);
+        free(ourauth.data);
+    }
+    else
+        c = xcb_connect_to_fd(fd, 0);
+
+out:
+    free(host);
+    free(protocol);
+    return c;
+}
diff --git a/libxcb/src/xcbint.h b/libxcb/src/xcbint.h
index 5950823f0..096576c4a 100644
--- a/libxcb/src/xcbint.h
+++ b/libxcb/src/xcbint.h
@@ -1,208 +1,208 @@
-/*
- * Copyright (C) 2001-2004 Bart Massey and Jamey Sharp.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- * 
- * Except as contained in this notice, the names of the authors or their
- * institutions shall not be used in advertising or otherwise to promote the
- * sale, use or other dealings in this Software without prior written
- * authorization from the authors.
- */
-
-#ifndef __XCBINT_H
-#define __XCBINT_H
-
-#include "bigreq.h"
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#ifdef GCC_HAS_VISIBILITY
-#pragma GCC visibility push(hidden)
-#endif
-
-enum workarounds {
-    WORKAROUND_NONE,
-    WORKAROUND_GLX_GET_FB_CONFIGS_BUG,
-    WORKAROUND_EXTERNAL_SOCKET_OWNER
-};
-
-enum lazy_reply_tag
-{
-    LAZY_NONE = 0,
-    LAZY_COOKIE,
-    LAZY_FORCED
-};
-
-#define XCB_PAD(i) (-(i) & 3)
-
-#define XCB_SEQUENCE_COMPARE(a,op,b)	((int64_t) ((a) - (b)) op 0)
-
-#ifndef offsetof
-#define offsetof(type,member) ((size_t) &((type *)0)->member)
-#endif
-
-#ifndef MIN
-#define MIN(x,y) ((x) < (y) ? (x) : (y))
-#endif
-
-#define container_of(pointer,type,member) ((type *)(((char *)(pointer)) - offsetof(type, member)))
-
-/* xcb_list.c */
-
-typedef void (*xcb_list_free_func_t)(void *);
-
-typedef struct _xcb_map _xcb_map;
-
-_xcb_map *_xcb_map_new(void);
-void _xcb_map_delete(_xcb_map *q, xcb_list_free_func_t do_free);
-int _xcb_map_put(_xcb_map *q, unsigned int key, void *data);
-void *_xcb_map_remove(_xcb_map *q, unsigned int key);
-
-
-/* xcb_out.c */
-
-typedef struct _xcb_out {
-    pthread_cond_t cond;
-    int writing;
-
-    pthread_cond_t socket_cond;
-    void (*return_socket)(void *closure);
-    void *socket_closure;
-    int socket_moving;
-
-    char queue[XCB_QUEUE_BUFFER_SIZE];
-    int queue_len;
-
-    uint64_t request;
-    uint64_t request_written;
-
-    pthread_mutex_t reqlenlock;
-    enum lazy_reply_tag maximum_request_length_tag;
-    union {
-        xcb_big_requests_enable_cookie_t cookie;
-        uint32_t value;
-    } maximum_request_length;
-} _xcb_out;
-
-int _xcb_out_init(_xcb_out *out);
-void _xcb_out_destroy(_xcb_out *out);
-
-int _xcb_out_send(xcb_connection_t *c, struct iovec *vector, int count);
-void _xcb_out_send_sync(xcb_connection_t *c);
-int _xcb_out_flush_to(xcb_connection_t *c, uint64_t request);
-
-
-/* xcb_in.c */
-
-typedef struct _xcb_in {
-    pthread_cond_t event_cond;
-    int reading;
-
-    char queue[4096];
-    int queue_len;
-
-    uint64_t request_expected;
-    uint64_t request_read;
-    uint64_t request_completed;
-    struct reply_list *current_reply;
-    struct reply_list **current_reply_tail;
-
-    _xcb_map *replies;
-    struct event_list *events;
-    struct event_list **events_tail;
-    struct reader_list *readers;
-
-    struct pending_reply *pending_replies;
-    struct pending_reply **pending_replies_tail;
-} _xcb_in;
-
-int _xcb_in_init(_xcb_in *in);
-void _xcb_in_destroy(_xcb_in *in);
-
-void _xcb_in_wake_up_next_reader(xcb_connection_t *c);
-
-int _xcb_in_expect_reply(xcb_connection_t *c, uint64_t request, enum workarounds workaround, int flags);
-void _xcb_in_replies_done(xcb_connection_t *c);
-
-int _xcb_in_read(xcb_connection_t *c);
-int _xcb_in_read_block(xcb_connection_t *c, void *buf, int nread);
-
-
-/* xcb_xid.c */
-
-typedef struct _xcb_xid {
-    pthread_mutex_t lock;
-    uint32_t last;
-    uint32_t base;
-    uint32_t max;
-    uint32_t inc;
-} _xcb_xid;
-
-int _xcb_xid_init(xcb_connection_t *c);
-void _xcb_xid_destroy(xcb_connection_t *c);
-
-
-/* xcb_ext.c */
-
-typedef struct _xcb_ext {
-    pthread_mutex_t lock;
-    struct lazyreply *extensions;
-    int extensions_size;
-} _xcb_ext;
-
-int _xcb_ext_init(xcb_connection_t *c);
-void _xcb_ext_destroy(xcb_connection_t *c);
-
-
-/* xcb_conn.c */
-
-extern const int error_connection;
-
-struct xcb_connection_t {
-    int has_error;
-
-    /* constant data */
-    xcb_setup_t *setup;
-    int fd;
-
-    /* I/O data */
-    pthread_mutex_t iolock;
-    _xcb_in in;
-    _xcb_out out;
-
-    /* misc data */
-    _xcb_ext ext;
-    _xcb_xid xid;
-};
-
-void _xcb_conn_shutdown(xcb_connection_t *c);
-int _xcb_conn_wait(xcb_connection_t *c, pthread_cond_t *cond, struct iovec **vector, int *count);
-
-
-/* xcb_auth.c */
-
-int _xcb_get_auth_info(int fd, xcb_auth_info_t *info, int display);
-
-#ifdef GCC_HAS_VISIBILITY
-#pragma GCC visibility pop
-#endif
-
-#endif
+/*
+ * Copyright (C) 2001-2004 Bart Massey and Jamey Sharp.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 
+ * Except as contained in this notice, the names of the authors or their
+ * institutions shall not be used in advertising or otherwise to promote the
+ * sale, use or other dealings in this Software without prior written
+ * authorization from the authors.
+ */
+
+#ifndef __XCBINT_H
+#define __XCBINT_H
+
+#include "bigreq.h"
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef GCC_HAS_VISIBILITY
+#pragma GCC visibility push(hidden)
+#endif
+
+enum workarounds {
+    WORKAROUND_NONE,
+    WORKAROUND_GLX_GET_FB_CONFIGS_BUG,
+    WORKAROUND_EXTERNAL_SOCKET_OWNER
+};
+
+enum lazy_reply_tag
+{
+    LAZY_NONE = 0,
+    LAZY_COOKIE,
+    LAZY_FORCED
+};
+
+#define XCB_PAD(i) (-(i) & 3)
+
+#define XCB_SEQUENCE_COMPARE(a,op,b)	((int64_t) ((a) - (b)) op 0)
+
+#ifndef offsetof
+#define offsetof(type,member) ((size_t) &((type *)0)->member)
+#endif
+
+#ifndef MIN
+#define MIN(x,y) ((x) < (y) ? (x) : (y))
+#endif
+
+#define container_of(pointer,type,member) ((type *)(((char *)(pointer)) - offsetof(type, member)))
+
+/* xcb_list.c */
+
+typedef void (*xcb_list_free_func_t)(void *);
+
+typedef struct _xcb_map _xcb_map;
+
+_xcb_map *_xcb_map_new(void);
+void _xcb_map_delete(_xcb_map *q, xcb_list_free_func_t do_free);
+int _xcb_map_put(_xcb_map *q, unsigned int key, void *data);
+void *_xcb_map_remove(_xcb_map *q, unsigned int key);
+
+
+/* xcb_out.c */
+
+typedef struct _xcb_out {
+    pthread_cond_t cond;
+    int writing;
+
+    pthread_cond_t socket_cond;
+    void (*return_socket)(void *closure);
+    void *socket_closure;
+    int socket_moving;
+
+    char queue[XCB_QUEUE_BUFFER_SIZE];
+    int queue_len;
+
+    uint64_t request;
+    uint64_t request_written;
+
+    pthread_mutex_t reqlenlock;
+    enum lazy_reply_tag maximum_request_length_tag;
+    union {
+        xcb_big_requests_enable_cookie_t cookie;
+        uint32_t value;
+    } maximum_request_length;
+} _xcb_out;
+
+int _xcb_out_init(_xcb_out *out);
+void _xcb_out_destroy(_xcb_out *out);
+
+int _xcb_out_send(xcb_connection_t *c, struct iovec *vector, int count);
+void _xcb_out_send_sync(xcb_connection_t *c);
+int _xcb_out_flush_to(xcb_connection_t *c, uint64_t request);
+
+
+/* xcb_in.c */
+
+typedef struct _xcb_in {
+    pthread_cond_t event_cond;
+    int reading;
+
+    char queue[4096];
+    int queue_len;
+
+    uint64_t request_expected;
+    uint64_t request_read;
+    uint64_t request_completed;
+    struct reply_list *current_reply;
+    struct reply_list **current_reply_tail;
+
+    _xcb_map *replies;
+    struct event_list *events;
+    struct event_list **events_tail;
+    struct reader_list *readers;
+
+    struct pending_reply *pending_replies;
+    struct pending_reply **pending_replies_tail;
+} _xcb_in;
+
+int _xcb_in_init(_xcb_in *in);
+void _xcb_in_destroy(_xcb_in *in);
+
+void _xcb_in_wake_up_next_reader(xcb_connection_t *c);
+
+int _xcb_in_expect_reply(xcb_connection_t *c, uint64_t request, enum workarounds workaround, int flags);
+void _xcb_in_replies_done(xcb_connection_t *c);
+
+int _xcb_in_read(xcb_connection_t *c);
+int _xcb_in_read_block(xcb_connection_t *c, void *buf, int nread);
+
+
+/* xcb_xid.c */
+
+typedef struct _xcb_xid {
+    pthread_mutex_t lock;
+    uint32_t last;
+    uint32_t base;
+    uint32_t max;
+    uint32_t inc;
+} _xcb_xid;
+
+int _xcb_xid_init(xcb_connection_t *c);
+void _xcb_xid_destroy(xcb_connection_t *c);
+
+
+/* xcb_ext.c */
+
+typedef struct _xcb_ext {
+    pthread_mutex_t lock;
+    struct lazyreply *extensions;
+    int extensions_size;
+} _xcb_ext;
+
+int _xcb_ext_init(xcb_connection_t *c);
+void _xcb_ext_destroy(xcb_connection_t *c);
+
+
+/* xcb_conn.c */
+
+extern const int error_connection;
+
+struct xcb_connection_t {
+    int has_error;
+
+    /* constant data */
+    xcb_setup_t *setup;
+    int fd;
+
+    /* I/O data */
+    pthread_mutex_t iolock;
+    _xcb_in in;
+    _xcb_out out;
+
+    /* misc data */
+    _xcb_ext ext;
+    _xcb_xid xid;
+};
+
+void _xcb_conn_shutdown(xcb_connection_t *c);
+int _xcb_conn_wait(xcb_connection_t *c, pthread_cond_t *cond, struct iovec **vector, int *count);
+
+
+/* xcb_auth.c */
+
+int _xcb_get_auth_info(int fd, xcb_auth_info_t *info, int display);
+
+#ifdef GCC_HAS_VISIBILITY
+#pragma GCC visibility pop
+#endif
+
+#endif
diff --git a/libxcb/xcb-proto/src/sync.xml b/libxcb/xcb-proto/src/sync.xml
index f690cca04..516d149ab 100644
--- a/libxcb/xcb-proto/src/sync.xml
+++ b/libxcb/xcb-proto/src/sync.xml
@@ -1,229 +1,229 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-Copyright (C) 2004 Mikko Torni and Josh Triplett.
-All Rights Reserved.  See the file COPYING in this directory
-for licensing information.
--->
-<xcb header="sync" extension-xname="SYNC" extension-name="Sync"
-    major-version="3" minor-version="1">
-  <import>xproto</import>
-
-  <xidtype name="ALARM" />
-
-  <enum name="ALARMSTATE">
-    <item name="Active" />
-    <item name="Inactive" />
-    <item name="Destroyed" />
-  </enum>
-
-  <xidtype name="COUNTER" />
-
-  <xidtype name="FENCE" />
-
-  <enum name="TESTTYPE">
-    <item name="PositiveTransition" />
-    <item name="NegativeTransition" />
-    <item name="PositiveComparison" />
-    <item name="NegativeComparison" />
-  </enum>
-
-  <enum name="VALUETYPE">
-    <item name="Absolute" />
-    <item name="Relative" />
-  </enum>
-
-  <enum name="CA">
-    <item name="Counter">  <bit>0</bit></item>
-    <item name="ValueType"><bit>1</bit></item>
-    <item name="Value">    <bit>2</bit></item>
-    <item name="TestType"> <bit>3</bit></item>
-    <item name="Delta">    <bit>4</bit></item>
-    <item name="Events">   <bit>5</bit></item>
-  </enum>
-
-  <struct name="INT64">
-    <field type="INT32" name="hi" />
-    <field type="CARD32" name="lo" />
-  </struct>
-
-  <struct name="SYSTEMCOUNTER">
-    <field type="COUNTER" name="counter" />
-    <field type="INT64" name="resolution" />
-    <field type="CARD16" name="name_len" />
-    <list type="char" name="name">
-      <fieldref>name_len</fieldref>
-    </list>
-  </struct>
-
-  <struct name="TRIGGER">
-    <field type="COUNTER" name="counter" />
-    <field type="CARD32" name="wait_type" enum="VALUETYPE" />
-    <field type="INT64" name="wait_value" />
-    <field type="CARD32" name="test_type" enum="TESTTYPE" />
-  </struct>
-
-  <struct name="WAITCONDITION">
-    <field type="TRIGGER" name="trigger" />
-    <field type="INT64" name="event_threshold" />
-  </struct>
-
-  <error name="Counter" number="0">
-    <field type="CARD32" name="bad_counter" />
-    <field type="CARD16" name="minor_opcode" />
-    <field type="CARD8" name="major_opcode" />
-  </error>
-
-  <error name="Alarm" number="1">
-    <field type="CARD32" name="bad_alarm" />
-    <field type="CARD16" name="minor_opcode" />
-    <field type="CARD8" name="major_opcode" />
-  </error>
-    
-  <request name="Initialize" opcode="0">
-    <field type="CARD8" name="desired_major_version" />
-    <field type="CARD8" name="desired_minor_version" />
-    <reply>
-      <pad bytes="1" />
-      <field type="CARD8" name="major_version" />
-      <field type="CARD8" name="minor_version" />
-      <pad bytes="22" />
-    </reply>
-  </request>
-
-  <request name="ListSystemCounters" opcode="1">
-    <reply>
-      <pad bytes="1" />
-      <field type="CARD32" name="counters_len" />
-      <pad bytes="20" />
-      <list type="SYSTEMCOUNTER" name="counters">
-        <fieldref>counters_len</fieldref>
-      </list>
-    </reply>
-  </request>
-
-  <request name="CreateCounter" opcode="2">
-    <field type="COUNTER" name="id" />
-    <field type="INT64" name="initial_value" />
-  </request>
-
-  <request name="DestroyCounter" opcode="6">
-    <field type="COUNTER" name="counter" />
-  </request>
-
-  <request name="QueryCounter" opcode="5">
-    <field type="COUNTER" name="counter" />
-    <reply>
-      <pad bytes="1" />
-      <field type="INT64" name="counter_value" />
-    </reply>
-  </request>
-
-  <request name="Await" opcode="7">
-    <list type="WAITCONDITION" name="wait_list" />
-  </request>
-
-  <request name="ChangeCounter" opcode="4">
-    <field type="COUNTER" name="counter" />
-    <field type="INT64" name="amount" />
-  </request>
-
-  <request name="SetCounter" opcode="3">
-    <field type="COUNTER" name="counter" />
-    <field type="INT64" name="value" />
-  </request>
-
-  <request name="CreateAlarm" opcode="8">
-    <field type="ALARM" name="id" />
-    <valueparam value-mask-type="CARD32"
-                value-mask-name="value_mask"
-                value-list-name="value_list" />
-  </request>
-
-  <request name="ChangeAlarm" opcode="9">
-    <field type="ALARM" name="id" />
-    <valueparam value-mask-type="CARD32"
-                value-mask-name="value_mask"
-                value-list-name="value_list" />
-  </request>
-
-  <request name="DestroyAlarm" opcode="11">
-    <field type="ALARM" name="alarm" />
-  </request>
-
-  <request name="QueryAlarm" opcode="10">
-    <field type="ALARM" name="alarm" />
-    <reply>
-      <pad bytes="1" />
-      <field type="TRIGGER" name="trigger" />
-      <field type="INT64" name="delta" />
-      <field type="BOOL" name="events" />
-      <field type="CARD8" name="state" enum="ALARMSTATE" />
-      <pad bytes="2" />
-    </reply>
-  </request>
-
-  <request name="SetPriority" opcode="12">
-    <field type="CARD32" name="id" />
-    <field type="INT32" name="priority" />
-  </request>
-    
-  <request name="GetPriority" opcode="13">
-    <field type="CARD32" name="id" />
-    <reply>
-      <pad bytes="1" />
-      <field type="INT32" name="priority" />
-    </reply>
-  </request>
-
-  <request name="CreateFence" opcode="14">
-    <field type="DRAWABLE" name="drawable" />
-    <field type="FENCE" name="fence" />
-    <field type="BOOL" name="initially_triggered" />
-  </request>
-
-  <request name="TriggerFence" opcode="15">
-    <field type="FENCE" name="fence" />
-  </request>
-
-  <request name="ResetFence" opcode="16">
-    <field type="FENCE" name="fence" />
-  </request>
-
-  <request name="DestroyFence" opcode="17">
-    <field type="FENCE" name="fence" />
-  </request>
-
-  <request name="QueryFence" opcode="18">
-    <field type="FENCE" name="fence" />
-    <reply>
-      <pad bytes="1" />
-      <field type="BOOL" name="triggered" />
-      <pad bytes="23" />
-    </reply>
-  </request>
-
-  <request name="AwaitFence" opcode="19">
-    <list type="FENCE" name="fence_list" />
-  </request>
-
-  <event name="CounterNotify" number="0">
-    <field type="CARD8" name="kind" />
-    <field type="COUNTER" name="counter" />
-    <field type="INT64" name="wait_value" />
-    <field type="INT64" name="counter_value" />
-    <field type="TIMESTAMP" name="timestamp" />
-    <field type="CARD16" name="count" />
-    <field type="BOOL" name="destroyed" />
-    <pad bytes="1" />
-  </event>
-
-  <event name="AlarmNotify" number="1">
-    <field type="CARD8" name="kind" />
-    <field type="ALARM" name="alarm" />
-    <field type="INT64" name="counter_value" />
-    <field type="INT64" name="alarm_value" />
-    <field type="TIMESTAMP" name="timestamp" />
-    <field type="CARD8" name="state" enum="ALARMSTATE" />
-    <pad bytes="3" />
-  </event>
-</xcb>
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright (C) 2004 Mikko Torni and Josh Triplett.
+All Rights Reserved.  See the file COPYING in this directory
+for licensing information.
+-->
+<xcb header="sync" extension-xname="SYNC" extension-name="Sync"
+    major-version="3" minor-version="1">
+  <import>xproto</import>
+
+  <xidtype name="ALARM" />
+
+  <enum name="ALARMSTATE">
+    <item name="Active" />
+    <item name="Inactive" />
+    <item name="Destroyed" />
+  </enum>
+
+  <xidtype name="COUNTER" />
+
+  <xidtype name="FENCE" />
+
+  <enum name="TESTTYPE">
+    <item name="PositiveTransition" />
+    <item name="NegativeTransition" />
+    <item name="PositiveComparison" />
+    <item name="NegativeComparison" />
+  </enum>
+
+  <enum name="VALUETYPE">
+    <item name="Absolute" />
+    <item name="Relative" />
+  </enum>
+
+  <enum name="CA">
+    <item name="Counter">  <bit>0</bit></item>
+    <item name="ValueType"><bit>1</bit></item>
+    <item name="Value">    <bit>2</bit></item>
+    <item name="TestType"> <bit>3</bit></item>
+    <item name="Delta">    <bit>4</bit></item>
+    <item name="Events">   <bit>5</bit></item>
+  </enum>
+
+  <struct name="INT64">
+    <field type="INT32" name="hi" />
+    <field type="CARD32" name="lo" />
+  </struct>
+
+  <struct name="SYSTEMCOUNTER">
+    <field type="COUNTER" name="counter" />
+    <field type="INT64" name="resolution" />
+    <field type="CARD16" name="name_len" />
+    <list type="char" name="name">
+      <fieldref>name_len</fieldref>
+    </list>
+  </struct>
+
+  <struct name="TRIGGER">
+    <field type="COUNTER" name="counter" />
+    <field type="CARD32" name="wait_type" enum="VALUETYPE" />
+    <field type="INT64" name="wait_value" />
+    <field type="CARD32" name="test_type" enum="TESTTYPE" />
+  </struct>
+
+  <struct name="WAITCONDITION">
+    <field type="TRIGGER" name="trigger" />
+    <field type="INT64" name="event_threshold" />
+  </struct>
+
+  <error name="Counter" number="0">
+    <field type="CARD32" name="bad_counter" />
+    <field type="CARD16" name="minor_opcode" />
+    <field type="CARD8" name="major_opcode" />
+  </error>
+
+  <error name="Alarm" number="1">
+    <field type="CARD32" name="bad_alarm" />
+    <field type="CARD16" name="minor_opcode" />
+    <field type="CARD8" name="major_opcode" />
+  </error>
+    
+  <request name="Initialize" opcode="0">
+    <field type="CARD8" name="desired_major_version" />
+    <field type="CARD8" name="desired_minor_version" />
+    <reply>
+      <pad bytes="1" />
+      <field type="CARD8" name="major_version" />
+      <field type="CARD8" name="minor_version" />
+      <pad bytes="22" />
+    </reply>
+  </request>
+
+  <request name="ListSystemCounters" opcode="1">
+    <reply>
+      <pad bytes="1" />
+      <field type="CARD32" name="counters_len" />
+      <pad bytes="20" />
+      <list type="SYSTEMCOUNTER" name="counters">
+        <fieldref>counters_len</fieldref>
+      </list>
+    </reply>
+  </request>
+
+  <request name="CreateCounter" opcode="2">
+    <field type="COUNTER" name="id" />
+    <field type="INT64" name="initial_value" />
+  </request>
+
+  <request name="DestroyCounter" opcode="6">
+    <field type="COUNTER" name="counter" />
+  </request>
+
+  <request name="QueryCounter" opcode="5">
+    <field type="COUNTER" name="counter" />
+    <reply>
+      <pad bytes="1" />
+      <field type="INT64" name="counter_value" />
+    </reply>
+  </request>
+
+  <request name="Await" opcode="7">
+    <list type="WAITCONDITION" name="wait_list" />
+  </request>
+
+  <request name="ChangeCounter" opcode="4">
+    <field type="COUNTER" name="counter" />
+    <field type="INT64" name="amount" />
+  </request>
+
+  <request name="SetCounter" opcode="3">
+    <field type="COUNTER" name="counter" />
+    <field type="INT64" name="value" />
+  </request>
+
+  <request name="CreateAlarm" opcode="8">
+    <field type="ALARM" name="id" />
+    <valueparam value-mask-type="CARD32"
+                value-mask-name="value_mask"
+                value-list-name="value_list" />
+  </request>
+
+  <request name="ChangeAlarm" opcode="9">
+    <field type="ALARM" name="id" />
+    <valueparam value-mask-type="CARD32"
+                value-mask-name="value_mask"
+                value-list-name="value_list" />
+  </request>
+
+  <request name="DestroyAlarm" opcode="11">
+    <field type="ALARM" name="alarm" />
+  </request>
+
+  <request name="QueryAlarm" opcode="10">
+    <field type="ALARM" name="alarm" />
+    <reply>
+      <pad bytes="1" />
+      <field type="TRIGGER" name="trigger" />
+      <field type="INT64" name="delta" />
+      <field type="BOOL" name="events" />
+      <field type="CARD8" name="state" enum="ALARMSTATE" />
+      <pad bytes="2" />
+    </reply>
+  </request>
+
+  <request name="SetPriority" opcode="12">
+    <field type="CARD32" name="id" />
+    <field type="INT32" name="priority" />
+  </request>
+    
+  <request name="GetPriority" opcode="13">
+    <field type="CARD32" name="id" />
+    <reply>
+      <pad bytes="1" />
+      <field type="INT32" name="priority" />
+    </reply>
+  </request>
+
+  <request name="CreateFence" opcode="14">
+    <field type="DRAWABLE" name="drawable" />
+    <field type="FENCE" name="fence" />
+    <field type="BOOL" name="initially_triggered" />
+  </request>
+
+  <request name="TriggerFence" opcode="15">
+    <field type="FENCE" name="fence" />
+  </request>
+
+  <request name="ResetFence" opcode="16">
+    <field type="FENCE" name="fence" />
+  </request>
+
+  <request name="DestroyFence" opcode="17">
+    <field type="FENCE" name="fence" />
+  </request>
+
+  <request name="QueryFence" opcode="18">
+    <field type="FENCE" name="fence" />
+    <reply>
+      <pad bytes="1" />
+      <field type="BOOL" name="triggered" />
+      <pad bytes="23" />
+    </reply>
+  </request>
+
+  <request name="AwaitFence" opcode="19">
+    <list type="FENCE" name="fence_list" />
+  </request>
+
+  <event name="CounterNotify" number="0">
+    <field type="CARD8" name="kind" />
+    <field type="COUNTER" name="counter" />
+    <field type="INT64" name="wait_value" />
+    <field type="INT64" name="counter_value" />
+    <field type="TIMESTAMP" name="timestamp" />
+    <field type="CARD16" name="count" />
+    <field type="BOOL" name="destroyed" />
+    <pad bytes="1" />
+  </event>
+
+  <event name="AlarmNotify" number="1">
+    <field type="CARD8" name="kind" />
+    <field type="ALARM" name="alarm" />
+    <field type="INT64" name="counter_value" />
+    <field type="INT64" name="alarm_value" />
+    <field type="TIMESTAMP" name="timestamp" />
+    <field type="CARD8" name="state" enum="ALARMSTATE" />
+    <pad bytes="3" />
+  </event>
+</xcb>
diff --git a/libxcb/xcb-proto/xcbgen/matcher.py b/libxcb/xcb-proto/xcbgen/matcher.py
index c4d99fc57..6e45b236c 100644
--- a/libxcb/xcb-proto/xcbgen/matcher.py
+++ b/libxcb/xcb-proto/xcbgen/matcher.py
@@ -1,113 +1,113 @@
-'''
-XML parser.  One function for each top-level element in the schema.
-
-Most functions just declare a new object and add it to the module.
-For typedefs, eventcopies, xidtypes, and other aliases though,
-we do not create a new type object, we just record the existing one under a new name.
-'''
-
-from os.path import join
-from xml.etree.cElementTree import parse
-
-from xcbgen.xtypes import *
-
-def import_(node, module, namespace):
-    '''
-    For imports, we load the file, create a new namespace object,
-    execute recursively, then record the import (for header files, etc.)
-    '''
-    # To avoid circular import error
-    from xcbgen import state
-    new_file = join(namespace.dir, '%s.xml' % node.text)
-    new_root = parse(new_file).getroot()
-    new_namespace = state.Namespace(new_file)
-    execute(module, new_namespace)
-    if not module.has_import(node.text):
-        module.add_import(node.text, new_namespace)
-
-def typedef(node, module, namespace):
-    id = node.get('newname')
-    name = namespace.prefix + (id,)
-    type = module.get_type(node.get('oldname'))
-    module.add_type(id, namespace.ns, name, type)
-
-def xidtype(node, module, namespace):
-    id = node.get('name')
-    name = namespace.prefix + (id,)
-    type = module.get_type('CARD32')
-    module.add_type(id, namespace.ns, name, type)
-
-def xidunion(node, module, namespace):
-    id = node.get('name')
-    name = namespace.prefix + (id,)
-    type = module.get_type('CARD32')
-    module.add_type(id, namespace.ns, name, type)
-
-def enum(node, module, namespace):
-    id = node.get('name')
-    name = namespace.prefix + (id,)
-    type = Enum(name, node)
-    module.add_type(id, namespace.ns, name, type)
-
-def struct(node, module, namespace):
-    id = node.get('name')
-    name = namespace.prefix + (id,)
-    type = Struct(name, node)
-    module.add_type(id, namespace.ns, name, type)
-
-def union(node, module, namespace):
-    id = node.get('name')
-    name = namespace.prefix + (id,)
-    type = Union(name, node)
-    module.add_type(id, namespace.ns, name, type)
-
-def request(node, module, namespace):
-    id = node.get('name')
-    name = namespace.prefix + (id,)
-    type = Request(name, node)
-    module.add_request(id, name, type)
-
-def event(node, module, namespace):
-    id = node.get('name')
-    name = namespace.prefix + (id,)
-    event = Event(name, node)
-    event.add_opcode(node.get('number'), name, True)
-    module.add_event(id, name, event)
-
-def eventcopy(node, module, namespace):
-    id = node.get('name')
-    name = namespace.prefix + (id,)
-    event = module.get_event(node.get('ref'))
-    event.add_opcode(node.get('number'), name, False)
-    module.add_event(id, name, event)
-
-def error(node, module, namespace):
-    id = node.get('name')
-    name = namespace.prefix + (id,)
-    error = Error(name, node)
-    error.add_opcode(node.get('number'), name, True)
-    module.add_error(id, name, error)
-
-def errorcopy(node, module, namespace):
-    id = node.get('name')
-    name = namespace.prefix + (id,)
-    error = module.get_error(node.get('ref'))
-    error.add_opcode(node.get('number'), name, False)
-    module.add_error(id, name, error)
-
-funcs = {'import' : import_,
-         'typedef' : typedef,
-         'xidtype' : xidtype,
-         'xidunion' : xidunion,
-         'enum' : enum,
-         'struct' : struct,
-         'union' : union,
-         'request' : request,
-         'event' : event,
-         'eventcopy' : eventcopy,
-         'error' : error,
-         'errorcopy' : errorcopy}
-
-def execute(module, namespace):
-    for elt in list(namespace.root):
-        funcs[elt.tag](elt, module, namespace)
+'''
+XML parser.  One function for each top-level element in the schema.
+
+Most functions just declare a new object and add it to the module.
+For typedefs, eventcopies, xidtypes, and other aliases though,
+we do not create a new type object, we just record the existing one under a new name.
+'''
+
+from os.path import join
+from xml.etree.cElementTree import parse
+
+from xcbgen.xtypes import *
+
+def import_(node, module, namespace):
+    '''
+    For imports, we load the file, create a new namespace object,
+    execute recursively, then record the import (for header files, etc.)
+    '''
+    # To avoid circular import error
+    from xcbgen import state
+    new_file = join(namespace.dir, '%s.xml' % node.text)
+    new_root = parse(new_file).getroot()
+    new_namespace = state.Namespace(new_file)
+    execute(module, new_namespace)
+    if not module.has_import(node.text):
+        module.add_import(node.text, new_namespace)
+
+def typedef(node, module, namespace):
+    id = node.get('newname')
+    name = namespace.prefix + (id,)
+    type = module.get_type(node.get('oldname'))
+    module.add_type(id, namespace.ns, name, type)
+
+def xidtype(node, module, namespace):
+    id = node.get('name')
+    name = namespace.prefix + (id,)
+    type = module.get_type('CARD32')
+    module.add_type(id, namespace.ns, name, type)
+
+def xidunion(node, module, namespace):
+    id = node.get('name')
+    name = namespace.prefix + (id,)
+    type = module.get_type('CARD32')
+    module.add_type(id, namespace.ns, name, type)
+
+def enum(node, module, namespace):
+    id = node.get('name')
+    name = namespace.prefix + (id,)
+    type = Enum(name, node)
+    module.add_type(id, namespace.ns, name, type)
+
+def struct(node, module, namespace):
+    id = node.get('name')
+    name = namespace.prefix + (id,)
+    type = Struct(name, node)
+    module.add_type(id, namespace.ns, name, type)
+
+def union(node, module, namespace):
+    id = node.get('name')
+    name = namespace.prefix + (id,)
+    type = Union(name, node)
+    module.add_type(id, namespace.ns, name, type)
+
+def request(node, module, namespace):
+    id = node.get('name')
+    name = namespace.prefix + (id,)
+    type = Request(name, node)
+    module.add_request(id, name, type)
+
+def event(node, module, namespace):
+    id = node.get('name')
+    name = namespace.prefix + (id,)
+    event = Event(name, node)
+    event.add_opcode(node.get('number'), name, True)
+    module.add_event(id, name, event)
+
+def eventcopy(node, module, namespace):
+    id = node.get('name')
+    name = namespace.prefix + (id,)
+    event = module.get_event(node.get('ref'))
+    event.add_opcode(node.get('number'), name, False)
+    module.add_event(id, name, event)
+
+def error(node, module, namespace):
+    id = node.get('name')
+    name = namespace.prefix + (id,)
+    error = Error(name, node)
+    error.add_opcode(node.get('number'), name, True)
+    module.add_error(id, name, error)
+
+def errorcopy(node, module, namespace):
+    id = node.get('name')
+    name = namespace.prefix + (id,)
+    error = module.get_error(node.get('ref'))
+    error.add_opcode(node.get('number'), name, False)
+    module.add_error(id, name, error)
+
+funcs = {'import' : import_,
+         'typedef' : typedef,
+         'xidtype' : xidtype,
+         'xidunion' : xidunion,
+         'enum' : enum,
+         'struct' : struct,
+         'union' : union,
+         'request' : request,
+         'event' : event,
+         'eventcopy' : eventcopy,
+         'error' : error,
+         'errorcopy' : errorcopy}
+
+def execute(module, namespace):
+    for elt in list(namespace.root):
+        funcs[elt.tag](elt, module, namespace)
diff --git a/libxcb/xcb-proto/xcbgen/state.py b/libxcb/xcb-proto/xcbgen/state.py
index 902a86341..ae3d2d45f 100644
--- a/libxcb/xcb-proto/xcbgen/state.py
+++ b/libxcb/xcb-proto/xcbgen/state.py
@@ -1,166 +1,166 @@
-'''
-This module contains the namespace class and the singleton module class.
-'''
-from os.path import dirname, basename
-from xml.etree.cElementTree import parse
-
-from xcbgen import matcher
-from xcbgen.error import *
-from xcbgen.xtypes import *
-
-import __main__
-
-class Namespace(object):
-    '''
-    Contains the naming information for an extension.
-
-    Public fields:
-
-    header is the header attribute ("header file" name).
-    is_ext is true for extensions, false for xproto.
-    major_version and minor_version are extension version info.
-    ext_xname is the X extension name string.
-    ext_name is the XCB extension name prefix.
-    '''
-    def __init__(self, filename):
-        # Path info
-        self.path = filename
-        self.dir = dirname(filename)
-        self.file = basename(filename)
-
-        # Parse XML
-        self.root = parse(filename).getroot()
-        self.header = self.root.get('header')
-        self.ns = self.header + ':'
-        
-        # Get root element attributes
-        if self.root.get('extension-xname', False): 
-            self.is_ext = True
-            self.major_version = self.root.get('major-version')
-            self.minor_version = self.root.get('minor-version')
-            self.ext_xname = self.root.get('extension-xname')
-            self.ext_name = self.root.get('extension-name')
-            self.prefix = ('xcb', self.ext_name)
-        else:
-            self.is_ext = False
-            self.ext_name = ''
-            self.prefix = ('xcb',)
-
-
-class Module(object):
-    '''
-    This is the grand, encompassing class that represents an entire XCB specification.
-    Only gets instantiated once, in the main() routine.
-
-    Don't need to worry about this much except to declare it and to get the namespace.
-
-    Public fields:
-    namespace contains the namespace info for the spec.
-    '''
-    open = __main__.output['open']
-    close = __main__.output['close']
-
-    def __init__(self, filename, output):
-        self.namespace = Namespace(filename)
-        self.output = output
-
-        self.imports = []
-        self.types = {}
-        self.events = {}
-        self.errors = {}
-        self.all = []
-
-        # Register some common types
-        self.add_type('CARD8', '', ('uint8_t',), tcard8)
-        self.add_type('CARD16', '', ('uint16_t',), tcard16)
-        self.add_type('CARD32', '', ('uint32_t',), tcard32)
-        self.add_type('INT8', '', ('int8_t',), tint8)
-        self.add_type('INT16', '', ('int16_t',), tint16)
-        self.add_type('INT32', '', ('int32_t',), tint32)
-        self.add_type('BYTE', '', ('uint8_t',), tcard8)
-        self.add_type('BOOL', '', ('uint8_t',), tcard8)
-        self.add_type('char', '', ('char',), tchar)
-        self.add_type('float', '', ('float',), tfloat)
-        self.add_type('double', '', ('double',), tdouble)
-        self.add_type('void', '', ('void',), tcard8)
-
-    # This goes out and parses the rest of the XML
-    def register(self):
-        matcher.execute(self, self.namespace)
-
-    # Recursively resolve all types
-    def resolve(self):
-        for (name, item) in self.all:
-            item.resolve(self)
-
-    # Call all the output methods
-    def generate(self):
-        self.open()
-
-        for (name, item) in self.all:
-            item.out(name)
-
-        self.close()
-
-    # Keeps track of what's been imported so far.
-    def add_import(self, name, namespace):
-        self.imports.append((name, namespace.header))
-
-    def has_import(self, name):
-        for (name_, header) in self.imports:
-            if name_ == name:
-                return True
-        return False
-
-    # Keeps track of non-request/event/error datatypes
-    def add_type(self, id, ns, name, item):
-        key = ns + id
-        if key in self.types:
-            return
-        self.types[key] = (name, item)
-        if name[:-1] == self.namespace.prefix:
-            self.all.append((name, item))
-
-    def get_type_impl(self, id, idx):
-        key = id
-        if key in self.types:
-            return self.types[key][idx]
-
-        key = self.namespace.ns + id
-        if key in self.types:
-            return self.types[key][idx]
-
-        for key in self.types.keys():
-            if key.rpartition(':')[2] == id:
-                return self.types[key][idx]
-
-        raise ResolveException('Type %s not found' % id)
-
-    def get_type(self, id):
-        return self.get_type_impl(id, 1)
-
-    def get_type_name(self, id):
-        return self.get_type_impl(id, 0)
-
-    # Keeps track of request datatypes
-    def add_request(self, id, name, item):
-        if name[:-1] == self.namespace.prefix:
-            self.all.append((name, item))
-
-    # Keeps track of event datatypes
-    def add_event(self, id, name, item):
-        self.events[id] = (name, item)
-        if name[:-1] == self.namespace.prefix:
-            self.all.append((name, item))
-
-    def get_event(self, id):
-        return self.events[id][1]
-
-    # Keeps track of error datatypes
-    def add_error(self, id, name, item):
-        self.errors[id] = (name, item)
-        if name[:-1] == self.namespace.prefix:
-            self.all.append((name, item))
-
-    def get_error(self, id):
-        return self.errors[id][1]
+'''
+This module contains the namespace class and the singleton module class.
+'''
+from os.path import dirname, basename
+from xml.etree.cElementTree import parse
+
+from xcbgen import matcher
+from xcbgen.error import *
+from xcbgen.xtypes import *
+
+import __main__
+
+class Namespace(object):
+    '''
+    Contains the naming information for an extension.
+
+    Public fields:
+
+    header is the header attribute ("header file" name).
+    is_ext is true for extensions, false for xproto.
+    major_version and minor_version are extension version info.
+    ext_xname is the X extension name string.
+    ext_name is the XCB extension name prefix.
+    '''
+    def __init__(self, filename):
+        # Path info
+        self.path = filename
+        self.dir = dirname(filename)
+        self.file = basename(filename)
+
+        # Parse XML
+        self.root = parse(filename).getroot()
+        self.header = self.root.get('header')
+        self.ns = self.header + ':'
+        
+        # Get root element attributes
+        if self.root.get('extension-xname', False): 
+            self.is_ext = True
+            self.major_version = self.root.get('major-version')
+            self.minor_version = self.root.get('minor-version')
+            self.ext_xname = self.root.get('extension-xname')
+            self.ext_name = self.root.get('extension-name')
+            self.prefix = ('xcb', self.ext_name)
+        else:
+            self.is_ext = False
+            self.ext_name = ''
+            self.prefix = ('xcb',)
+
+
+class Module(object):
+    '''
+    This is the grand, encompassing class that represents an entire XCB specification.
+    Only gets instantiated once, in the main() routine.
+
+    Don't need to worry about this much except to declare it and to get the namespace.
+
+    Public fields:
+    namespace contains the namespace info for the spec.
+    '''
+    open = __main__.output['open']
+    close = __main__.output['close']
+
+    def __init__(self, filename, output):
+        self.namespace = Namespace(filename)
+        self.output = output
+
+        self.imports = []
+        self.types = {}
+        self.events = {}
+        self.errors = {}
+        self.all = []
+
+        # Register some common types
+        self.add_type('CARD8', '', ('uint8_t',), tcard8)
+        self.add_type('CARD16', '', ('uint16_t',), tcard16)
+        self.add_type('CARD32', '', ('uint32_t',), tcard32)
+        self.add_type('INT8', '', ('int8_t',), tint8)
+        self.add_type('INT16', '', ('int16_t',), tint16)
+        self.add_type('INT32', '', ('int32_t',), tint32)
+        self.add_type('BYTE', '', ('uint8_t',), tcard8)
+        self.add_type('BOOL', '', ('uint8_t',), tcard8)
+        self.add_type('char', '', ('char',), tchar)
+        self.add_type('float', '', ('float',), tfloat)
+        self.add_type('double', '', ('double',), tdouble)
+        self.add_type('void', '', ('void',), tcard8)
+
+    # This goes out and parses the rest of the XML
+    def register(self):
+        matcher.execute(self, self.namespace)
+
+    # Recursively resolve all types
+    def resolve(self):
+        for (name, item) in self.all:
+            item.resolve(self)
+
+    # Call all the output methods
+    def generate(self):
+        self.open()
+
+        for (name, item) in self.all:
+            item.out(name)
+
+        self.close()
+
+    # Keeps track of what's been imported so far.
+    def add_import(self, name, namespace):
+        self.imports.append((name, namespace.header))
+
+    def has_import(self, name):
+        for (name_, header) in self.imports:
+            if name_ == name:
+                return True
+        return False
+
+    # Keeps track of non-request/event/error datatypes
+    def add_type(self, id, ns, name, item):
+        key = ns + id
+        if key in self.types:
+            return
+        self.types[key] = (name, item)
+        if name[:-1] == self.namespace.prefix:
+            self.all.append((name, item))
+
+    def get_type_impl(self, id, idx):
+        key = id
+        if key in self.types:
+            return self.types[key][idx]
+
+        key = self.namespace.ns + id
+        if key in self.types:
+            return self.types[key][idx]
+
+        for key in self.types.keys():
+            if key.rpartition(':')[2] == id:
+                return self.types[key][idx]
+
+        raise ResolveException('Type %s not found' % id)
+
+    def get_type(self, id):
+        return self.get_type_impl(id, 1)
+
+    def get_type_name(self, id):
+        return self.get_type_impl(id, 0)
+
+    # Keeps track of request datatypes
+    def add_request(self, id, name, item):
+        if name[:-1] == self.namespace.prefix:
+            self.all.append((name, item))
+
+    # Keeps track of event datatypes
+    def add_event(self, id, name, item):
+        self.events[id] = (name, item)
+        if name[:-1] == self.namespace.prefix:
+            self.all.append((name, item))
+
+    def get_event(self, id):
+        return self.events[id][1]
+
+    # Keeps track of error datatypes
+    def add_error(self, id, name, item):
+        self.errors[id] = (name, item)
+        if name[:-1] == self.namespace.prefix:
+            self.all.append((name, item))
+
+    def get_error(self, id):
+        return self.errors[id][1]
diff --git a/libxcb/xcb-proto/xcbgen/xtypes.py b/libxcb/xcb-proto/xcbgen/xtypes.py
index 882acc9b8..14c318ac3 100644
--- a/libxcb/xcb-proto/xcbgen/xtypes.py
+++ b/libxcb/xcb-proto/xcbgen/xtypes.py
@@ -1,632 +1,632 @@
-'''
-This module contains the classes which represent XCB data types.
-'''
-from xcbgen.expr import Field, Expression
-import __main__
-
-class Type(object):
-    '''
-    Abstract base class for all XCB data types.
-    Contains default fields, and some abstract methods.
-    '''
-    def __init__(self, name):
-        '''
-        Default structure initializer.  Sets up default fields.
-
-        Public fields:
-        name is a tuple of strings specifying the full type name.
-        size is the size of the datatype in bytes, or None if variable-sized.
-        nmemb is 1 for non-list types, None for variable-sized lists, otherwise number of elts.
-        booleans for identifying subclasses, because I can't figure out isinstance().
-        '''
-        self.name = name
-        self.size = None
-        self.nmemb = None
-        self.resolved = False
-
-        # Screw isinstance().
-        self.is_simple = False
-        self.is_list = False
-        self.is_expr = False
-        self.is_container = False
-        self.is_reply = False
-        self.is_union = False
-        self.is_pad = False
-        self.is_switch = False
-        self.is_bitcase = False
-
-    def resolve(self, module):
-        '''
-        Abstract method for resolving a type.
-        This should make sure any referenced types are already declared.
-        '''
-        raise Exception('abstract resolve method not overridden!')
-
-    def out(self, name):
-        '''
-        Abstract method for outputting code.
-        These are declared in the language-specific modules, and
-        there must be a dictionary containing them declared when this module is imported!
-        '''
-        raise Exception('abstract out method not overridden!')
-
-    def fixed_size(self):
-        '''
-        Abstract method for determining if the data type is fixed-size.
-        '''
-        raise Exception('abstract fixed_size method not overridden!')
-
-    def make_member_of(self, module, complex_type, field_type, field_name, visible, wire, auto):
-        '''
-        Default method for making a data type a member of a structure.
-        Extend this if the data type needs to add an additional length field or something.
-
-        module is the global module object.
-        complex_type is the structure object.
-        see Field for the meaning of the other parameters.
-        '''
-        new_field = Field(self, field_type, field_name, visible, wire, auto)
-
-        # We dump the _placeholder_byte if any fields are added.
-        for (idx, field) in enumerate(complex_type.fields):
-            if field == _placeholder_byte:
-                complex_type.fields[idx] = new_field
-                return
-
-        complex_type.fields.append(new_field)
-
-
-class SimpleType(Type):
-    '''
-    Derived class which represents a cardinal type like CARD32 or char.
-    Any type which is typedef'ed to cardinal will be one of these.
-
-    Public fields added:
-    none
-    '''
-    def __init__(self, name, size):
-        Type.__init__(self, name)
-        self.is_simple = True
-        self.size = size
-        self.nmemb = 1
-
-    def resolve(self, module):
-        self.resolved = True
-
-    def fixed_size(self):
-        return True
-
-    out = __main__.output['simple']
-
-
-# Cardinal datatype globals.  See module __init__ method.
-tcard8 = SimpleType(('uint8_t',), 1)
-tcard16 = SimpleType(('uint16_t',), 2)
-tcard32 = SimpleType(('uint32_t',), 4)
-tint8 =  SimpleType(('int8_t',), 1)
-tint16 = SimpleType(('int16_t',), 2)
-tint32 = SimpleType(('int32_t',), 4)
-tchar =  SimpleType(('char',), 1)
-tfloat = SimpleType(('float',), 4)
-tdouble = SimpleType(('double',), 8)
-
-
-class Enum(SimpleType):
-    '''
-    Derived class which represents an enum.  Fixed-size.
-
-    Public fields added:
-    values contains a list of (name, value) tuples.  value is empty, or a number.
-    bits contains a list of (name, bitnum) tuples.  items only appear if specified as a bit. bitnum is a number.
-    '''
-    def __init__(self, name, elt):
-        SimpleType.__init__(self, name, 4)
-        self.values = []
-        self.bits = []
-        for item in list(elt):
-            # First check if we're using a default value
-            if len(list(item)) == 0:
-                self.values.append((item.get('name'), ''))
-                continue
-
-            # An explicit value or bit was specified.
-            value = list(item)[0]
-            if value.tag == 'value':
-                self.values.append((item.get('name'), value.text))
-            elif value.tag == 'bit':
-                self.values.append((item.get('name'), '%u' % (1 << int(value.text, 0))))
-                self.bits.append((item.get('name'), value.text))
-
-    def resolve(self, module):
-        self.resolved = True
-
-    def fixed_size(self):
-        return True
-
-    out = __main__.output['enum']
-
-
-class ListType(Type):
-    '''
-    Derived class which represents a list of some other datatype.  Fixed- or variable-sized.
-
-    Public fields added:
-    member is the datatype of the list elements.
-    parent is the structure type containing the list.
-    expr is an Expression object containing the length information, for variable-sized lists.
-    '''
-    def __init__(self, elt, member, *parent):
-        Type.__init__(self, member.name)
-        self.is_list = True
-        self.member = member
-        self.parents = list(parent)
-
-        if elt.tag == 'list':
-            elts = list(elt)
-            self.expr = Expression(elts[0] if len(elts) else elt, self)
-        elif elt.tag == 'valueparam':
-            self.expr = Expression(elt, self)
-
-        self.size = member.size if member.fixed_size() else None
-        self.nmemb = self.expr.nmemb if self.expr.fixed_size() else None
-
-    def make_member_of(self, module, complex_type, field_type, field_name, visible, wire, auto):
-        if not self.fixed_size():
-            # We need a length field.
-            # Ask our Expression object for it's name, type, and whether it's on the wire.
-            lenfid = self.expr.lenfield_type
-            lenfield_name = self.expr.lenfield_name
-            lenwire = self.expr.lenwire
-            needlen = True
-
-            # See if the length field is already in the structure.
-            for parent in self.parents:
-                for field in parent.fields:
-                    if field.field_name == lenfield_name:
-                        needlen = False
-
-            # It isn't, so we need to add it to the structure ourself.
-            if needlen:
-                type = module.get_type(lenfid)
-                lenfield_type = module.get_type_name(lenfid)
-                type.make_member_of(module, complex_type, lenfield_type, lenfield_name, True, lenwire, False)
-
-        # Add ourself to the structure by calling our original method.
-        Type.make_member_of(self, module, complex_type, field_type, field_name, visible, wire, auto)
-
-    def resolve(self, module):
-        if self.resolved:
-            return
-        self.member.resolve(module)
-        self.expr.resolve(module, self.parents)
-
-        # Find my length field again.  We need the actual Field object in the expr.
-        # This is needed because we might have added it ourself above.
-        if not self.fixed_size():
-            for parent in self.parents:
-                for field in parent.fields:
-                    if field.field_name == self.expr.lenfield_name and field.wire:
-                        self.expr.lenfield = field
-                        break
-
-        self.resolved = True
-
-    def fixed_size(self):
-        return self.member.fixed_size() and self.expr.fixed_size()
-
-class ExprType(Type):
-    '''
-    Derived class which represents an exprfield.  Fixed size.
-
-    Public fields added:
-    expr is an Expression object containing the value of the field.
-    '''
-    def __init__(self, elt, member, *parent):
-        Type.__init__(self, member.name)
-        self.is_expr = True
-        self.member = member
-        self.parent = parent
-
-        self.expr = Expression(list(elt)[0], self)
-
-        self.size = member.size
-        self.nmemb = 1
-
-    def resolve(self, module):
-        if self.resolved:
-            return
-        self.member.resolve(module)
-        self.resolved = True
-
-    def fixed_size(self):
-        return True
-
-class PadType(Type):
-    '''
-    Derived class which represents a padding field.
-    '''
-    def __init__(self, elt):
-        Type.__init__(self, tcard8.name)
-        self.is_pad = True
-        self.size = 1
-        self.nmemb = 1 if (elt == None) else int(elt.get('bytes'), 0)
-
-    def resolve(self, module):
-        self.resolved = True
-
-    def fixed_size(self):
-        return True
-
-    
-class ComplexType(Type):
-    '''
-    Derived class which represents a structure.  Base type for all structure types.
-
-    Public fields added:
-    fields is an array of Field objects describing the structure fields.
-    '''
-    def __init__(self, name, elt):
-        Type.__init__(self, name)
-        self.is_container = True
-        self.elt = elt
-        self.fields = []
-        self.nmemb = 1
-        self.size = 0
-        self.lenfield_parent = [self]
-
-    def resolve(self, module):
-        if self.resolved:
-            return
-        pads = 0
-
-        # Resolve all of our field datatypes.
-        for child in list(self.elt):
-            if child.tag == 'pad':
-                field_name = 'pad' + str(pads)
-                fkey = 'CARD8'
-                type = PadType(child)
-                pads = pads + 1
-                visible = False
-            elif child.tag == 'field':
-                field_name = child.get('name')
-                fkey = child.get('type')
-                type = module.get_type(fkey)
-                visible = True
-            elif child.tag == 'exprfield':
-                field_name = child.get('name')
-                fkey = child.get('type')
-                type = ExprType(child, module.get_type(fkey), *self.lenfield_parent)
-                visible = False
-            elif child.tag == 'list':
-                field_name = child.get('name')
-                fkey = child.get('type')
-                type = ListType(child, module.get_type(fkey), *self.lenfield_parent)
-                visible = True
-            elif child.tag == 'valueparam':
-                field_name = child.get('value-list-name')
-                fkey = 'CARD32'
-                type = ListType(child, module.get_type(fkey), *self.lenfield_parent)
-                visible = True
-            elif child.tag == 'switch':
-                field_name = child.get('name')
-                # construct the switch type name from the parent type and the field name
-                field_type = self.name + (field_name,)
-                type = SwitchType(field_type, child, *self.lenfield_parent)
-                visible = True
-                type.make_member_of(module, self, field_type, field_name, visible, True, False)
-                type.resolve(module)
-                continue
-            else:
-                # Hit this on Reply
-                continue 
-
-            # Get the full type name for the field
-            field_type = module.get_type_name(fkey)
-            # Add the field to ourself
-            type.make_member_of(module, self, field_type, field_name, visible, True, False)
-            # Recursively resolve the type (could be another structure, list)
-            type.resolve(module)
-
-        self.calc_size() # Figure out how big we are
-        self.resolved = True
-
-    def calc_size(self):
-        self.size = 0
-        for m in self.fields:
-            if not m.wire:
-                continue
-            if m.type.fixed_size():
-                self.size = self.size + (m.type.size * m.type.nmemb)
-            else:
-                self.size = None
-                break
-
-    def fixed_size(self):
-        for m in self.fields:
-            if not m.type.fixed_size():
-                return False
-        return True
-
-class SwitchType(ComplexType):
-    '''
-    Derived class which represents a List of Items.  
-
-    Public fields added:
-    bitcases is an array of Bitcase objects describing the list items
-    '''
-
-    def __init__(self, name, elt, *parents):
-        ComplexType.__init__(self, name, elt)
-        self.parents = parents
-        # FIXME: switch cannot store lenfields, so it should just delegate the parents
-        self.lenfield_parent = list(parents) + [self]
-        # self.fields contains all possible fields collected from the Bitcase objects, 
-        # whereas self.items contains the Bitcase objects themselves
-        self.bitcases = []
-
-        self.is_switch = True
-        elts = list(elt)
-        self.expr = Expression(elts[0] if len(elts) else elt, self)
-
-    def resolve(self, module):
-        if self.resolved:
-            return
-#        pads = 0
-
-        parents = list(self.parents) + [self]
-
-        # Resolve all of our field datatypes.
-        for index, child in enumerate(list(self.elt)):
-            if child.tag == 'bitcase':
-                field_name = child.get('name')
-                if field_name is None:
-                    field_type = self.name + ('bitcase%d' % index,)
-                else:
-                    field_type = self.name + (field_name,)
-
-                # use self.parent to indicate anchestor, 
-                # as switch does not contain named fields itself
-                type = BitcaseType(index, field_type, child, *parents)
-                # construct the switch type name from the parent type and the field name
-                if field_name is None:
-                    type.has_name = False
-                    # Get the full type name for the field
-                    field_type = type.name               
-                visible = True
-
-                # add the field to ourself
-                type.make_member_of(module, self, field_type, field_name, visible, True, False)
-
-                # recursively resolve the type (could be another structure, list)
-                type.resolve(module)
-                inserted = False
-                for new_field in type.fields:
-                    # We dump the _placeholder_byte if any fields are added.
-                    for (idx, field) in enumerate(self.fields):
-                        if field == _placeholder_byte:
-                            self.fields[idx] = new_field
-                            inserted = True
-                            break
-                    if False == inserted:
-                        self.fields.append(new_field)
-
-        self.calc_size() # Figure out how big we are
-        self.resolved = True
-
-    def make_member_of(self, module, complex_type, field_type, field_name, visible, wire, auto):
-        if not self.fixed_size():
-            # We need a length field.
-            # Ask our Expression object for it's name, type, and whether it's on the wire.
-            lenfid = self.expr.lenfield_type
-            lenfield_name = self.expr.lenfield_name
-            lenwire = self.expr.lenwire
-            needlen = True
-
-            # See if the length field is already in the structure.
-            for parent in self.parents:
-                for field in parent.fields:
-                    if field.field_name == lenfield_name:
-                        needlen = False
-
-            # It isn't, so we need to add it to the structure ourself.
-            if needlen:
-                type = module.get_type(lenfid)
-                lenfield_type = module.get_type_name(lenfid)
-                type.make_member_of(module, complex_type, lenfield_type, lenfield_name, True, lenwire, False)
-
-        # Add ourself to the structure by calling our original method.
-        Type.make_member_of(self, module, complex_type, field_type, field_name, visible, wire, auto)
-
-    # size for switch can only be calculated at runtime
-    def calc_size(self):
-        pass
-
-    # note: switch is _always_ of variable size, but we indicate here wether 
-    # it contains elements that are variable-sized themselves
-    def fixed_size(self):
-        return False
-#        for m in self.fields:
-#            if not m.type.fixed_size():
-#                return False
-#        return True
-
-
-class Struct(ComplexType):
-    '''
-    Derived class representing a struct data type.
-    '''
-    out = __main__.output['struct']
-
-
-class Union(ComplexType):
-    '''
-    Derived class representing a union data type.
-    '''
-    def __init__(self, name, elt):
-        ComplexType.__init__(self, name, elt)
-        self.is_union = True
-
-    out = __main__.output['union']
-
-
-class BitcaseType(ComplexType):
-    '''
-    Derived class representing a struct data type.
-    '''
-    def __init__(self, index, name, elt, *parent):
-        elts = list(elt)
-        self.expr = Expression(elts[0] if len(elts) else elt, self)
-        ComplexType.__init__(self, name, elts[1:])        
-        self.has_name = True
-        self.index = 1
-        self.lenfield_parent = list(parent) + [self]
-        self.parents = list(parent)
-        self.is_bitcase = True
-
-    def make_member_of(self, module, switch_type, field_type, field_name, visible, wire, auto):
-        '''
-        register BitcaseType with the corresponding SwitchType
-
-        module is the global module object.
-        complex_type is the structure object.
-        see Field for the meaning of the other parameters.
-        '''
-        new_field = Field(self, field_type, field_name, visible, wire, auto)
-
-        # We dump the _placeholder_byte if any bitcases are added.
-        for (idx, field) in enumerate(switch_type.bitcases):
-            if field == _placeholder_byte:
-                switch_type.bitcases[idx] = new_field
-                return
-
-        switch_type.bitcases.append(new_field)
-
-    def resolve(self, module):
-        if self.resolved:
-            return
-        
-        self.expr.resolve(module, self.parents+[self])
-
-        # Resolve the bitcase expression
-        ComplexType.resolve(self, module)
-
-
-class Reply(ComplexType):
-    '''
-    Derived class representing a reply.  Only found as a field of Request.
-    '''
-    def __init__(self, name, elt):
-        ComplexType.__init__(self, name, elt)
-        self.is_reply = True
-
-    def resolve(self, module):
-        if self.resolved:
-            return
-        # Add the automatic protocol fields
-        self.fields.append(Field(tcard8, tcard8.name, 'response_type', False, True, True))
-        self.fields.append(_placeholder_byte)
-        self.fields.append(Field(tcard16, tcard16.name, 'sequence', False, True, True))
-        self.fields.append(Field(tcard32, tcard32.name, 'length', False, True, True))
-        ComplexType.resolve(self, module)
-        
-
-class Request(ComplexType):
-    '''
-    Derived class representing a request.
-
-    Public fields added:
-    reply contains the reply datatype or None for void requests.
-    opcode contains the request number.
-    '''
-    def __init__(self, name, elt):
-        ComplexType.__init__(self, name, elt)
-        self.reply = None
-        self.opcode = elt.get('opcode')
-
-        for child in list(elt):
-            if child.tag == 'reply':
-                self.reply = Reply(name, child)
-
-    def resolve(self, module):
-        if self.resolved:
-            return
-        # Add the automatic protocol fields
-        if module.namespace.is_ext:
-            self.fields.append(Field(tcard8, tcard8.name, 'major_opcode', False, True, True))
-            self.fields.append(Field(tcard8, tcard8.name, 'minor_opcode', False, True, True))
-            self.fields.append(Field(tcard16, tcard16.name, 'length', False, True, True))
-            ComplexType.resolve(self, module)
-        else:
-            self.fields.append(Field(tcard8, tcard8.name, 'major_opcode', False, True, True))
-            self.fields.append(_placeholder_byte)
-            self.fields.append(Field(tcard16, tcard16.name, 'length', False, True, True))
-            ComplexType.resolve(self, module)
-
-        if self.reply:
-            self.reply.resolve(module)
-
-    out = __main__.output['request']
-
-
-class Event(ComplexType):
-    '''
-    Derived class representing an event data type.
-
-    Public fields added:
-    opcodes is a dictionary of name -> opcode number, for eventcopies.
-    '''
-    def __init__(self, name, elt):
-        ComplexType.__init__(self, name, elt)
-        self.opcodes = {}
-
-        tmp = elt.get('no-sequence-number')
-        self.has_seq = (tmp == None or tmp.lower() == 'false' or tmp == '0')
-            
-    def add_opcode(self, opcode, name, main):
-        self.opcodes[name] = opcode
-        if main:
-            self.name = name
-
-    def resolve(self, module):
-        if self.resolved:
-            return
-
-        # Add the automatic protocol fields
-        self.fields.append(Field(tcard8, tcard8.name, 'response_type', False, True, True))
-        if self.has_seq:
-            self.fields.append(_placeholder_byte)
-            self.fields.append(Field(tcard16, tcard16.name, 'sequence', False, True, True))
-        ComplexType.resolve(self, module)
-
-    out = __main__.output['event']
-
-
-class Error(ComplexType):
-    '''
-    Derived class representing an error data type.
-
-    Public fields added:
-    opcodes is a dictionary of name -> opcode number, for errorcopies.
-    '''
-    def __init__(self, name, elt):
-        ComplexType.__init__(self, name, elt)
-        self.opcodes = {}
-
-    def add_opcode(self, opcode, name, main):
-        self.opcodes[name] = opcode
-        if main:
-            self.name = name
-
-    def resolve(self, module):
-        if self.resolved:
-            return
-
-        # Add the automatic protocol fields
-        self.fields.append(Field(tcard8, tcard8.name, 'response_type', False, True, True))
-        self.fields.append(Field(tcard8, tcard8.name, 'error_code', False, True, True))
-        self.fields.append(Field(tcard16, tcard16.name, 'sequence', False, True, True))
-        ComplexType.resolve(self, module)
-
-    out = __main__.output['error']
-
-_placeholder_byte = Field(PadType(None), tcard8.name, 'pad0', False, True, False)
+'''
+This module contains the classes which represent XCB data types.
+'''
+from xcbgen.expr import Field, Expression
+import __main__
+
+class Type(object):
+    '''
+    Abstract base class for all XCB data types.
+    Contains default fields, and some abstract methods.
+    '''
+    def __init__(self, name):
+        '''
+        Default structure initializer.  Sets up default fields.
+
+        Public fields:
+        name is a tuple of strings specifying the full type name.
+        size is the size of the datatype in bytes, or None if variable-sized.
+        nmemb is 1 for non-list types, None for variable-sized lists, otherwise number of elts.
+        booleans for identifying subclasses, because I can't figure out isinstance().
+        '''
+        self.name = name
+        self.size = None
+        self.nmemb = None
+        self.resolved = False
+
+        # Screw isinstance().
+        self.is_simple = False
+        self.is_list = False
+        self.is_expr = False
+        self.is_container = False
+        self.is_reply = False
+        self.is_union = False
+        self.is_pad = False
+        self.is_switch = False
+        self.is_bitcase = False
+
+    def resolve(self, module):
+        '''
+        Abstract method for resolving a type.
+        This should make sure any referenced types are already declared.
+        '''
+        raise Exception('abstract resolve method not overridden!')
+
+    def out(self, name):
+        '''
+        Abstract method for outputting code.
+        These are declared in the language-specific modules, and
+        there must be a dictionary containing them declared when this module is imported!
+        '''
+        raise Exception('abstract out method not overridden!')
+
+    def fixed_size(self):
+        '''
+        Abstract method for determining if the data type is fixed-size.
+        '''
+        raise Exception('abstract fixed_size method not overridden!')
+
+    def make_member_of(self, module, complex_type, field_type, field_name, visible, wire, auto):
+        '''
+        Default method for making a data type a member of a structure.
+        Extend this if the data type needs to add an additional length field or something.
+
+        module is the global module object.
+        complex_type is the structure object.
+        see Field for the meaning of the other parameters.
+        '''
+        new_field = Field(self, field_type, field_name, visible, wire, auto)
+
+        # We dump the _placeholder_byte if any fields are added.
+        for (idx, field) in enumerate(complex_type.fields):
+            if field == _placeholder_byte:
+                complex_type.fields[idx] = new_field
+                return
+
+        complex_type.fields.append(new_field)
+
+
+class SimpleType(Type):
+    '''
+    Derived class which represents a cardinal type like CARD32 or char.
+    Any type which is typedef'ed to cardinal will be one of these.
+
+    Public fields added:
+    none
+    '''
+    def __init__(self, name, size):
+        Type.__init__(self, name)
+        self.is_simple = True
+        self.size = size
+        self.nmemb = 1
+
+    def resolve(self, module):
+        self.resolved = True
+
+    def fixed_size(self):
+        return True
+
+    out = __main__.output['simple']
+
+
+# Cardinal datatype globals.  See module __init__ method.
+tcard8 = SimpleType(('uint8_t',), 1)
+tcard16 = SimpleType(('uint16_t',), 2)
+tcard32 = SimpleType(('uint32_t',), 4)
+tint8 =  SimpleType(('int8_t',), 1)
+tint16 = SimpleType(('int16_t',), 2)
+tint32 = SimpleType(('int32_t',), 4)
+tchar =  SimpleType(('char',), 1)
+tfloat = SimpleType(('float',), 4)
+tdouble = SimpleType(('double',), 8)
+
+
+class Enum(SimpleType):
+    '''
+    Derived class which represents an enum.  Fixed-size.
+
+    Public fields added:
+    values contains a list of (name, value) tuples.  value is empty, or a number.
+    bits contains a list of (name, bitnum) tuples.  items only appear if specified as a bit. bitnum is a number.
+    '''
+    def __init__(self, name, elt):
+        SimpleType.__init__(self, name, 4)
+        self.values = []
+        self.bits = []
+        for item in list(elt):
+            # First check if we're using a default value
+            if len(list(item)) == 0:
+                self.values.append((item.get('name'), ''))
+                continue
+
+            # An explicit value or bit was specified.
+            value = list(item)[0]
+            if value.tag == 'value':
+                self.values.append((item.get('name'), value.text))
+            elif value.tag == 'bit':
+                self.values.append((item.get('name'), '%u' % (1 << int(value.text, 0))))
+                self.bits.append((item.get('name'), value.text))
+
+    def resolve(self, module):
+        self.resolved = True
+
+    def fixed_size(self):
+        return True
+
+    out = __main__.output['enum']
+
+
+class ListType(Type):
+    '''
+    Derived class which represents a list of some other datatype.  Fixed- or variable-sized.
+
+    Public fields added:
+    member is the datatype of the list elements.
+    parent is the structure type containing the list.
+    expr is an Expression object containing the length information, for variable-sized lists.
+    '''
+    def __init__(self, elt, member, *parent):
+        Type.__init__(self, member.name)
+        self.is_list = True
+        self.member = member
+        self.parents = list(parent)
+
+        if elt.tag == 'list':
+            elts = list(elt)
+            self.expr = Expression(elts[0] if len(elts) else elt, self)
+        elif elt.tag == 'valueparam':
+            self.expr = Expression(elt, self)
+
+        self.size = member.size if member.fixed_size() else None
+        self.nmemb = self.expr.nmemb if self.expr.fixed_size() else None
+
+    def make_member_of(self, module, complex_type, field_type, field_name, visible, wire, auto):
+        if not self.fixed_size():
+            # We need a length field.
+            # Ask our Expression object for it's name, type, and whether it's on the wire.
+            lenfid = self.expr.lenfield_type
+            lenfield_name = self.expr.lenfield_name
+            lenwire = self.expr.lenwire
+            needlen = True
+
+            # See if the length field is already in the structure.
+            for parent in self.parents:
+                for field in parent.fields:
+                    if field.field_name == lenfield_name:
+                        needlen = False
+
+            # It isn't, so we need to add it to the structure ourself.
+            if needlen:
+                type = module.get_type(lenfid)
+                lenfield_type = module.get_type_name(lenfid)
+                type.make_member_of(module, complex_type, lenfield_type, lenfield_name, True, lenwire, False)
+
+        # Add ourself to the structure by calling our original method.
+        Type.make_member_of(self, module, complex_type, field_type, field_name, visible, wire, auto)
+
+    def resolve(self, module):
+        if self.resolved:
+            return
+        self.member.resolve(module)
+        self.expr.resolve(module, self.parents)
+
+        # Find my length field again.  We need the actual Field object in the expr.
+        # This is needed because we might have added it ourself above.
+        if not self.fixed_size():
+            for parent in self.parents:
+                for field in parent.fields:
+                    if field.field_name == self.expr.lenfield_name and field.wire:
+                        self.expr.lenfield = field
+                        break
+
+        self.resolved = True
+
+    def fixed_size(self):
+        return self.member.fixed_size() and self.expr.fixed_size()
+
+class ExprType(Type):
+    '''
+    Derived class which represents an exprfield.  Fixed size.
+
+    Public fields added:
+    expr is an Expression object containing the value of the field.
+    '''
+    def __init__(self, elt, member, *parent):
+        Type.__init__(self, member.name)
+        self.is_expr = True
+        self.member = member
+        self.parent = parent
+
+        self.expr = Expression(list(elt)[0], self)
+
+        self.size = member.size
+        self.nmemb = 1
+
+    def resolve(self, module):
+        if self.resolved:
+            return
+        self.member.resolve(module)
+        self.resolved = True
+
+    def fixed_size(self):
+        return True
+
+class PadType(Type):
+    '''
+    Derived class which represents a padding field.
+    '''
+    def __init__(self, elt):
+        Type.__init__(self, tcard8.name)
+        self.is_pad = True
+        self.size = 1
+        self.nmemb = 1 if (elt == None) else int(elt.get('bytes'), 0)
+
+    def resolve(self, module):
+        self.resolved = True
+
+    def fixed_size(self):
+        return True
+
+    
+class ComplexType(Type):
+    '''
+    Derived class which represents a structure.  Base type for all structure types.
+
+    Public fields added:
+    fields is an array of Field objects describing the structure fields.
+    '''
+    def __init__(self, name, elt):
+        Type.__init__(self, name)
+        self.is_container = True
+        self.elt = elt
+        self.fields = []
+        self.nmemb = 1
+        self.size = 0
+        self.lenfield_parent = [self]
+
+    def resolve(self, module):
+        if self.resolved:
+            return
+        pads = 0
+
+        # Resolve all of our field datatypes.
+        for child in list(self.elt):
+            if child.tag == 'pad':
+                field_name = 'pad' + str(pads)
+                fkey = 'CARD8'
+                type = PadType(child)
+                pads = pads + 1
+                visible = False
+            elif child.tag == 'field':
+                field_name = child.get('name')
+                fkey = child.get('type')
+                type = module.get_type(fkey)
+                visible = True
+            elif child.tag == 'exprfield':
+                field_name = child.get('name')
+                fkey = child.get('type')
+                type = ExprType(child, module.get_type(fkey), *self.lenfield_parent)
+                visible = False
+            elif child.tag == 'list':
+                field_name = child.get('name')
+                fkey = child.get('type')
+                type = ListType(child, module.get_type(fkey), *self.lenfield_parent)
+                visible = True
+            elif child.tag == 'valueparam':
+                field_name = child.get('value-list-name')
+                fkey = 'CARD32'
+                type = ListType(child, module.get_type(fkey), *self.lenfield_parent)
+                visible = True
+            elif child.tag == 'switch':
+                field_name = child.get('name')
+                # construct the switch type name from the parent type and the field name
+                field_type = self.name + (field_name,)
+                type = SwitchType(field_type, child, *self.lenfield_parent)
+                visible = True
+                type.make_member_of(module, self, field_type, field_name, visible, True, False)
+                type.resolve(module)
+                continue
+            else:
+                # Hit this on Reply
+                continue 
+
+            # Get the full type name for the field
+            field_type = module.get_type_name(fkey)
+            # Add the field to ourself
+            type.make_member_of(module, self, field_type, field_name, visible, True, False)
+            # Recursively resolve the type (could be another structure, list)
+            type.resolve(module)
+
+        self.calc_size() # Figure out how big we are
+        self.resolved = True
+
+    def calc_size(self):
+        self.size = 0
+        for m in self.fields:
+            if not m.wire:
+                continue
+            if m.type.fixed_size():
+                self.size = self.size + (m.type.size * m.type.nmemb)
+            else:
+                self.size = None
+                break
+
+    def fixed_size(self):
+        for m in self.fields:
+            if not m.type.fixed_size():
+                return False
+        return True
+
+class SwitchType(ComplexType):
+    '''
+    Derived class which represents a List of Items.  
+
+    Public fields added:
+    bitcases is an array of Bitcase objects describing the list items
+    '''
+
+    def __init__(self, name, elt, *parents):
+        ComplexType.__init__(self, name, elt)
+        self.parents = parents
+        # FIXME: switch cannot store lenfields, so it should just delegate the parents
+        self.lenfield_parent = list(parents) + [self]
+        # self.fields contains all possible fields collected from the Bitcase objects, 
+        # whereas self.items contains the Bitcase objects themselves
+        self.bitcases = []
+
+        self.is_switch = True
+        elts = list(elt)
+        self.expr = Expression(elts[0] if len(elts) else elt, self)
+
+    def resolve(self, module):
+        if self.resolved:
+            return
+#        pads = 0
+
+        parents = list(self.parents) + [self]
+
+        # Resolve all of our field datatypes.
+        for index, child in enumerate(list(self.elt)):
+            if child.tag == 'bitcase':
+                field_name = child.get('name')
+                if field_name is None:
+                    field_type = self.name + ('bitcase%d' % index,)
+                else:
+                    field_type = self.name + (field_name,)
+
+                # use self.parent to indicate anchestor, 
+                # as switch does not contain named fields itself
+                type = BitcaseType(index, field_type, child, *parents)
+                # construct the switch type name from the parent type and the field name
+                if field_name is None:
+                    type.has_name = False
+                    # Get the full type name for the field
+                    field_type = type.name               
+                visible = True
+
+                # add the field to ourself
+                type.make_member_of(module, self, field_type, field_name, visible, True, False)
+
+                # recursively resolve the type (could be another structure, list)
+                type.resolve(module)
+                inserted = False
+                for new_field in type.fields:
+                    # We dump the _placeholder_byte if any fields are added.
+                    for (idx, field) in enumerate(self.fields):
+                        if field == _placeholder_byte:
+                            self.fields[idx] = new_field
+                            inserted = True
+                            break
+                    if False == inserted:
+                        self.fields.append(new_field)
+
+        self.calc_size() # Figure out how big we are
+        self.resolved = True
+
+    def make_member_of(self, module, complex_type, field_type, field_name, visible, wire, auto):
+        if not self.fixed_size():
+            # We need a length field.
+            # Ask our Expression object for it's name, type, and whether it's on the wire.
+            lenfid = self.expr.lenfield_type
+            lenfield_name = self.expr.lenfield_name
+            lenwire = self.expr.lenwire
+            needlen = True
+
+            # See if the length field is already in the structure.
+            for parent in self.parents:
+                for field in parent.fields:
+                    if field.field_name == lenfield_name:
+                        needlen = False
+
+            # It isn't, so we need to add it to the structure ourself.
+            if needlen:
+                type = module.get_type(lenfid)
+                lenfield_type = module.get_type_name(lenfid)
+                type.make_member_of(module, complex_type, lenfield_type, lenfield_name, True, lenwire, False)
+
+        # Add ourself to the structure by calling our original method.
+        Type.make_member_of(self, module, complex_type, field_type, field_name, visible, wire, auto)
+
+    # size for switch can only be calculated at runtime
+    def calc_size(self):
+        pass
+
+    # note: switch is _always_ of variable size, but we indicate here wether 
+    # it contains elements that are variable-sized themselves
+    def fixed_size(self):
+        return False
+#        for m in self.fields:
+#            if not m.type.fixed_size():
+#                return False
+#        return True
+
+
+class Struct(ComplexType):
+    '''
+    Derived class representing a struct data type.
+    '''
+    out = __main__.output['struct']
+
+
+class Union(ComplexType):
+    '''
+    Derived class representing a union data type.
+    '''
+    def __init__(self, name, elt):
+        ComplexType.__init__(self, name, elt)
+        self.is_union = True
+
+    out = __main__.output['union']
+
+
+class BitcaseType(ComplexType):
+    '''
+    Derived class representing a struct data type.
+    '''
+    def __init__(self, index, name, elt, *parent):
+        elts = list(elt)
+        self.expr = Expression(elts[0] if len(elts) else elt, self)
+        ComplexType.__init__(self, name, elts[1:])        
+        self.has_name = True
+        self.index = 1
+        self.lenfield_parent = list(parent) + [self]
+        self.parents = list(parent)
+        self.is_bitcase = True
+
+    def make_member_of(self, module, switch_type, field_type, field_name, visible, wire, auto):
+        '''
+        register BitcaseType with the corresponding SwitchType
+
+        module is the global module object.
+        complex_type is the structure object.
+        see Field for the meaning of the other parameters.
+        '''
+        new_field = Field(self, field_type, field_name, visible, wire, auto)
+
+        # We dump the _placeholder_byte if any bitcases are added.
+        for (idx, field) in enumerate(switch_type.bitcases):
+            if field == _placeholder_byte:
+                switch_type.bitcases[idx] = new_field
+                return
+
+        switch_type.bitcases.append(new_field)
+
+    def resolve(self, module):
+        if self.resolved:
+            return
+        
+        self.expr.resolve(module, self.parents+[self])
+
+        # Resolve the bitcase expression
+        ComplexType.resolve(self, module)
+
+
+class Reply(ComplexType):
+    '''
+    Derived class representing a reply.  Only found as a field of Request.
+    '''
+    def __init__(self, name, elt):
+        ComplexType.__init__(self, name, elt)
+        self.is_reply = True
+
+    def resolve(self, module):
+        if self.resolved:
+            return
+        # Add the automatic protocol fields
+        self.fields.append(Field(tcard8, tcard8.name, 'response_type', False, True, True))
+        self.fields.append(_placeholder_byte)
+        self.fields.append(Field(tcard16, tcard16.name, 'sequence', False, True, True))
+        self.fields.append(Field(tcard32, tcard32.name, 'length', False, True, True))
+        ComplexType.resolve(self, module)
+        
+
+class Request(ComplexType):
+    '''
+    Derived class representing a request.
+
+    Public fields added:
+    reply contains the reply datatype or None for void requests.
+    opcode contains the request number.
+    '''
+    def __init__(self, name, elt):
+        ComplexType.__init__(self, name, elt)
+        self.reply = None
+        self.opcode = elt.get('opcode')
+
+        for child in list(elt):
+            if child.tag == 'reply':
+                self.reply = Reply(name, child)
+
+    def resolve(self, module):
+        if self.resolved:
+            return
+        # Add the automatic protocol fields
+        if module.namespace.is_ext:
+            self.fields.append(Field(tcard8, tcard8.name, 'major_opcode', False, True, True))
+            self.fields.append(Field(tcard8, tcard8.name, 'minor_opcode', False, True, True))
+            self.fields.append(Field(tcard16, tcard16.name, 'length', False, True, True))
+            ComplexType.resolve(self, module)
+        else:
+            self.fields.append(Field(tcard8, tcard8.name, 'major_opcode', False, True, True))
+            self.fields.append(_placeholder_byte)
+            self.fields.append(Field(tcard16, tcard16.name, 'length', False, True, True))
+            ComplexType.resolve(self, module)
+
+        if self.reply:
+            self.reply.resolve(module)
+
+    out = __main__.output['request']
+
+
+class Event(ComplexType):
+    '''
+    Derived class representing an event data type.
+
+    Public fields added:
+    opcodes is a dictionary of name -> opcode number, for eventcopies.
+    '''
+    def __init__(self, name, elt):
+        ComplexType.__init__(self, name, elt)
+        self.opcodes = {}
+
+        tmp = elt.get('no-sequence-number')
+        self.has_seq = (tmp == None or tmp.lower() == 'false' or tmp == '0')
+            
+    def add_opcode(self, opcode, name, main):
+        self.opcodes[name] = opcode
+        if main:
+            self.name = name
+
+    def resolve(self, module):
+        if self.resolved:
+            return
+
+        # Add the automatic protocol fields
+        self.fields.append(Field(tcard8, tcard8.name, 'response_type', False, True, True))
+        if self.has_seq:
+            self.fields.append(_placeholder_byte)
+            self.fields.append(Field(tcard16, tcard16.name, 'sequence', False, True, True))
+        ComplexType.resolve(self, module)
+
+    out = __main__.output['event']
+
+
+class Error(ComplexType):
+    '''
+    Derived class representing an error data type.
+
+    Public fields added:
+    opcodes is a dictionary of name -> opcode number, for errorcopies.
+    '''
+    def __init__(self, name, elt):
+        ComplexType.__init__(self, name, elt)
+        self.opcodes = {}
+
+    def add_opcode(self, opcode, name, main):
+        self.opcodes[name] = opcode
+        if main:
+            self.name = name
+
+    def resolve(self, module):
+        if self.resolved:
+            return
+
+        # Add the automatic protocol fields
+        self.fields.append(Field(tcard8, tcard8.name, 'response_type', False, True, True))
+        self.fields.append(Field(tcard8, tcard8.name, 'error_code', False, True, True))
+        self.fields.append(Field(tcard16, tcard16.name, 'sequence', False, True, True))
+        ComplexType.resolve(self, module)
+
+    out = __main__.output['error']
+
+_placeholder_byte = Field(PadType(None), tcard8.name, 'pad0', False, True, False)
-- 
cgit v1.2.3