From 7842eeba5f0567175c41728d3eaae59fcbdef7a6 Mon Sep 17 00:00:00 2001
From: marha <marha@users.sourceforge.net>
Date: Wed, 2 Sep 2009 19:17:00 +0000
Subject: Switch to libX11-1.2.99.901.tar.gz

---
 libX11/ChangeLog                   | 129 +++++++++++++++++++++
 libX11/aclocal.m4                  |  35 +++---
 libX11/configure                   |  80 ++++++-------
 libX11/configure.ac                |   2 +-
 libX11/include/X11/Xlib-xcb.h      |   5 +
 libX11/include/X11/Xlib.h          |  23 ++++
 libX11/include/X11/Xlibint.h       |  72 ++++++++++++
 libX11/man/Makefile.am             |   9 ++
 libX11/man/Makefile.in             |   9 ++
 libX11/man/XGetEventData.man       | 223 ++++++++++++++++++++++++++++++++++++
 libX11/nls/en_US.UTF-8/Compose.pre |   2 +
 libX11/src/ChkIfEv.c               |   1 +
 libX11/src/ChkMaskEv.c             |   4 +
 libX11/src/ChkTypEv.c              |   4 +
 libX11/src/ChkTypWEv.c             |   4 +
 libX11/src/ChkWinEv.c              |   4 +
 libX11/src/FreeEventData.c         |  42 +++++++
 libX11/src/GetEventData.c          |  42 +++++++
 libX11/src/IfEvent.c               |   1 +
 libX11/src/InitExt.c               |  43 +++++++
 libX11/src/Makefile.am             |   5 +-
 libX11/src/Makefile.in             | 229 +++++++++++++++++++------------------
 libX11/src/MaskEvent.c             |   4 +
 libX11/src/NextEvent.c             |   4 +
 libX11/src/OpenDis.c               |  11 ++
 libX11/src/PeekEvent.c             |   5 +
 libX11/src/PeekIfEv.c              |   5 +
 libX11/src/PutBEvent.c             |  18 ++-
 libX11/src/WinEvent.c              |   4 +
 libX11/src/XlibInt.c               | 183 ++++++++++++++++++++++++++++-
 libX11/src/utlist.h                | 116 +++++++++++++++++++
 31 files changed, 1135 insertions(+), 183 deletions(-)
 create mode 100644 libX11/man/XGetEventData.man
 create mode 100644 libX11/src/FreeEventData.c
 create mode 100644 libX11/src/GetEventData.c
 create mode 100644 libX11/src/utlist.h

diff --git a/libX11/ChangeLog b/libX11/ChangeLog
index c28af9157..2d0b18eba 100644
--- a/libX11/ChangeLog
+++ b/libX11/ChangeLog
@@ -1,3 +1,132 @@
+commit 9da7e230d5320e1556ad2084fcd06ee7994385ea
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Wed Aug 5 14:15:02 2009 +1000
+
+    Bump to 1.2.99.901 (1.3 RC1)
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+
+commit 8f78c7b4e3570cd46c5a220982963c17fe2157b8
+Author: Filippo Giunchedi <filippo@debian.org>
+Date:   Sat Jun 6 16:56:54 2009 +0200
+
+    nls: add {left,right}wards arrow to compose table
+    
+    Debian bug#532117 <http://bugs.debian.org/532117>
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+
+commit 7949bfa00390241d994f32463e50d4bd78920568
+Author: Julien Cristau <jcristau@debian.org>
+Date:   Fri Jul 31 13:33:52 2009 +0200
+
+    Update library version for new symbols
+    
+    Commit 554f755e5545f63d3c8f299297927238da155773 added generic event
+    cookie handling.  Bump libX11 version number accordingly.
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+
+commit 640fec5f4feacd01a00eea3dcd4edb220907d3dc
+Author: Julien Cristau <jcristau@debian.org>
+Date:   Sun Aug 2 17:18:31 2009 +0200
+
+    Add _XFUNCPROTOBEGIN/END to Xlib-xcb.h
+    
+    X.Org bug#22252 <https://bugs.freedesktop.org/show_bug.cgi?id=22252>
+    
+    Reported-by: Riku Salminen <rsalmin2@cc.hut.fi>
+    Signed-off-by: Julien Cristau <jcristau@debian.org>
+
+commit bc06d49e9dac1836d6824769ddb2ac5ba9f14df7
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Wed Jul 29 08:44:09 2009 +1000
+
+    Fix compiler warning 'unused variable qelt'
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+
+commit 03f4907e14f5755e72309f08742977b871e81e33
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Wed Jul 29 08:34:57 2009 +1000
+
+    Add utlist.h to the Makefile.am
+    
+    utlist.h contains the linked list macros, it was added with the recent
+    addition of event cookies but utlist.h wasn't added to the Makefile.am. As a
+    result, make dist failed.
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+
+commit 554f755e5545f63d3c8f299297927238da155773
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Fri Jun 26 11:27:43 2009 +1000
+
+    Add generic event cookie handling to libX11.
+    
+    Generic events require more bytes than Xlib provides in the standard XEvent.
+    Memory allocated by the extension and stored as pointers inside the event is
+    prone to leak by simple 'while (1) { XNextEvent(...); }' loops.
+    
+    This patch adds cookie handling for generic events. Extensions may register
+    a cookie handler in addition to the normal event vectors. If an extension
+    has registered a cookie handler, _all_ generic events for this extensions
+    must be handled through cookies. Otherwise, the default event handler is
+    used.
+    
+    The cookie handler must return an XGenericEventCookie with a pointer to the
+    data.The rest of the event (type, serialNumber, etc.) are to be filled as
+    normal. When a client retrieves such a cookie event, the data is stored in
+    an internal queue (the 'cookiejar'). This data is freed on the next call to
+    XNextEvent().
+    
+    New extension interfaces:
+        XESetWireToEventCookie(display, extension_number, cookie_handler)
+    
+    Where cookie_handler must set cookie->data. The data pointer is of arbitray
+    size and type but must be a single memory block. This memory block
+    represents the actual extension's event.
+    
+    New client interfaces:
+        XGetEventData(display, *cookie);
+        XFreeEventData(display, *cookie);
+    
+    If the client needs the actual event data, it must call XGetEventData() with
+    the cookie. This returns the data pointer (and removes it from the cookie
+    jar) and the client is then responsible for freeing the event with
+    XFreeEventData(). It is safe to call either function with a non-cookie
+    event. Events unclaimed or not handled by the XGetEventData() are cleaned up
+    automatically.
+    
+    Example client code:
+        XEvent event;
+        XGenericEventCookie *cookie = &ev;
+    
+        XNextEvent(display, &event);
+        if (XGetEventData(display, cookie)) {
+            XIEvent *xievent = cookie->data;
+            ...
+        } else if (cookie->type == GenericEvent) {
+            /* handle generic event */
+        } else {
+            /* handle extension/core event */
+        }
+        XFreeEventData(display, cookie);
+    
+    Cookies are not multi-threading safe. Clients that use XGetEventData() must
+    lock between XNextEvent and XGetEventData to avoid other threads freeing
+    cookies.
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+
+commit d7675cb8fa7155e7aff1459636a117a97aa1bf28
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Mon Jul 6 13:17:35 2009 +1000
+
+    Bump to 1.2.99.1
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+
 commit 75fe48e7a42a685d7098e8d7108b9b956c471563
 Author: Peter Hutterer <peter.hutterer@who-t.net>
 Date:   Fri Jul 10 14:07:34 2009 +1000
diff --git a/libX11/aclocal.m4 b/libX11/aclocal.m4
index 6ef603015..52271427a 100644
--- a/libX11/aclocal.m4
+++ b/libX11/aclocal.m4
@@ -8161,27 +8161,24 @@ dnl of the copyright holder.
 # your configure.ac with the minimum required version, such as:
 # XORG_MACROS_VERSION(1.1)
 #
-# To force at least a version with this macro defined, also add:
-# m4_ifndef([XORG_MACROS_VERSION], [AC_FATAL([must install xorg-macros 1.1 or later before running autoconf/autogen])])
+# To ensure that this macro is defined, also add:
+# m4_ifndef([XORG_MACROS_VERSION],
+#     [m4_fatal([must install xorg-macros 1.1 or later before running autoconf/autogen])])
 #
 #
 # See the "minimum version" comment for each macro you use to see what 
 # version you require.
-AC_DEFUN([XORG_MACROS_VERSION],[
-	[XORG_MACROS_needed_version=$1
-	XORG_MACROS_needed_major=`echo $XORG_MACROS_needed_version | sed 's/\..*$//'`
-	XORG_MACROS_needed_minor=`echo $XORG_MACROS_needed_version | sed -e 's/^[0-9]*\.//' -e 's/\..*$//'`]
-	AC_MSG_CHECKING([if xorg-macros used to generate configure is at least ${XORG_MACROS_needed_major}.${XORG_MACROS_needed_minor}])
-	[XORG_MACROS_version=1.2.1
-	XORG_MACROS_major=`echo $XORG_MACROS_version | sed 's/\..*$//'`
-	XORG_MACROS_minor=`echo $XORG_MACROS_version | sed -e 's/^[0-9]*\.//' -e 's/\..*$//'`]
-	if test $XORG_MACROS_major -ne $XORG_MACROS_needed_major ; then
-		AC_MSG_ERROR([configure built with incompatible version of xorg-macros.m4 - requires version ${XORG_MACROS_major}.x])
-	fi
-	if test $XORG_MACROS_minor -lt $XORG_MACROS_needed_minor ; then
-		AC_MSG_ERROR([configure built with too old of a version of xorg-macros.m4 - requires version ${XORG_MACROS_major}.${XORG_MACROS_minor}.0 or newer])
-	fi
-	AC_MSG_RESULT([yes, $XORG_MACROS_version])
+m4_defun([XORG_MACROS_VERSION],[
+m4_define([vers_have], [1.2.2])
+m4_define([maj_have], m4_substr(vers_have, 0, m4_index(vers_have, [.])))
+m4_define([maj_needed], m4_substr([$1], 0, m4_index([$1], [.])))
+m4_if(m4_cmp(maj_have, maj_needed), 0,,
+    [m4_fatal([xorg-macros major version ]maj_needed[ is required but ]vers_have[ found])])
+m4_if(m4_version_compare(vers_have, [$1]), -1,
+    [m4_fatal([xorg-macros version $1 or higher is required but ]vers_have[ found])])
+m4_undefine([vers_have])
+m4_undefine([maj_have])
+m4_undefine([maj_needed])
 ]) # XORG_MACROS_VERSION
 
 # XORG_PROG_RAWCPP()
@@ -8571,9 +8568,9 @@ if  test "x$GCC" = xyes ; then
     CWARNFLAGS="-Wall -Wpointer-arith -Wstrict-prototypes -Wmissing-prototypes \
 -Wmissing-declarations -Wnested-externs -fno-strict-aliasing \
 -Wbad-function-cast"
-    case `gcc -dumpversion` in
+    case `$CC -dumpversion` in
     3.4.* | 4.*)
-	CWARNFLAGS+=" -Wold-style-definition -Wdeclaration-after-statement"
+	CWARNFLAGS="$CWARNFLAGS -Wold-style-definition -Wdeclaration-after-statement"
 	;;
     esac
 else
diff --git a/libX11/configure b/libX11/configure
index 40002f063..e991244da 100644
--- a/libX11/configure
+++ b/libX11/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.63 for libX11 1.2.2.
+# Generated by GNU Autoconf 2.63 for libX11 1.2.99.901.
 #
 # Report bugs to <https://bugs.freedesktop.org/enter_bug.cgi?product=xorg>.
 #
@@ -745,8 +745,8 @@ SHELL=${CONFIG_SHELL-/bin/sh}
 # Identity of this package.
 PACKAGE_NAME='libX11'
 PACKAGE_TARNAME='libX11'
-PACKAGE_VERSION='1.2.2'
-PACKAGE_STRING='libX11 1.2.2'
+PACKAGE_VERSION='1.2.99.901'
+PACKAGE_STRING='libX11 1.2.99.901'
 PACKAGE_BUGREPORT='https://bugs.freedesktop.org/enter_bug.cgi?product=xorg'
 
 ac_unique_file="Makefile.am"
@@ -1582,7 +1582,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures libX11 1.2.2 to adapt to many kinds of systems.
+\`configure' configures libX11 1.2.99.901 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1652,7 +1652,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of libX11 1.2.2:";;
+     short | recursive ) echo "Configuration of libX11 1.2.99.901:";;
    esac
   cat <<\_ACEOF
 
@@ -1799,7 +1799,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-libX11 configure 1.2.2
+libX11 configure 1.2.99.901
 generated by GNU Autoconf 2.63
 
 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
@@ -1813,7 +1813,7 @@ cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by libX11 $as_me 1.2.2, which was
+It was created by libX11 $as_me 1.2.99.901, which was
 generated by GNU Autoconf 2.63.  Invocation command line was
 
   $ $0 $@
@@ -2663,7 +2663,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='libX11'
- VERSION='1.2.2'
+ VERSION='1.2.99.901'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -2736,26 +2736,14 @@ ac_config_headers="$ac_config_headers include/X11/XlibConf.h"
 # Require xorg-macros: XORG_CWARNFLAGS, XORG_CHANGELOG, XORG_WITH_LINT
 
 
-	XORG_MACROS_needed_version=1.2
-	XORG_MACROS_needed_major=`echo $XORG_MACROS_needed_version | sed 's/\..*$//'`
-	XORG_MACROS_needed_minor=`echo $XORG_MACROS_needed_version | sed -e 's/^[0-9]*\.//' -e 's/\..*$//'`
-	{ $as_echo "$as_me:$LINENO: checking if xorg-macros used to generate configure is at least ${XORG_MACROS_needed_major}.${XORG_MACROS_needed_minor}" >&5
-$as_echo_n "checking if xorg-macros used to generate configure is at least ${XORG_MACROS_needed_major}.${XORG_MACROS_needed_minor}... " >&6; }
-	XORG_MACROS_version=1.2.1
-	XORG_MACROS_major=`echo $XORG_MACROS_version | sed 's/\..*$//'`
-	XORG_MACROS_minor=`echo $XORG_MACROS_version | sed -e 's/^[0-9]*\.//' -e 's/\..*$//'`
-	if test $XORG_MACROS_major -ne $XORG_MACROS_needed_major ; then
-		{ { $as_echo "$as_me:$LINENO: error: configure built with incompatible version of xorg-macros.m4 - requires version ${XORG_MACROS_major}.x" >&5
-$as_echo "$as_me: error: configure built with incompatible version of xorg-macros.m4 - requires version ${XORG_MACROS_major}.x" >&2;}
-   { (exit 1); exit 1; }; }
-	fi
-	if test $XORG_MACROS_minor -lt $XORG_MACROS_needed_minor ; then
-		{ { $as_echo "$as_me:$LINENO: error: configure built with too old of a version of xorg-macros.m4 - requires version ${XORG_MACROS_major}.${XORG_MACROS_minor}.0 or newer" >&5
-$as_echo "$as_me: error: configure built with too old of a version of xorg-macros.m4 - requires version ${XORG_MACROS_major}.${XORG_MACROS_minor}.0 or newer" >&2;}
-   { (exit 1); exit 1; }; }
-	fi
-	{ $as_echo "$as_me:$LINENO: result: yes, $XORG_MACROS_version" >&5
-$as_echo "yes, $XORG_MACROS_version" >&6; }
+
+
+
+
+
+
+
+
 
 
 # Set common system defines for POSIX extensions, such as _GNU_SOURCE
@@ -5310,13 +5298,13 @@ if test "${lt_cv_nm_interface+set}" = set; then
 else
   lt_cv_nm_interface="BSD nm"
   echo "int some_variable = 0;" > conftest.$ac_ext
-  (eval echo "\"\$as_me:5313: $ac_compile\"" >&5)
+  (eval echo "\"\$as_me:5301: $ac_compile\"" >&5)
   (eval "$ac_compile" 2>conftest.err)
   cat conftest.err >&5
-  (eval echo "\"\$as_me:5316: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
+  (eval echo "\"\$as_me:5304: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
   (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
   cat conftest.err >&5
-  (eval echo "\"\$as_me:5319: output\"" >&5)
+  (eval echo "\"\$as_me:5307: output\"" >&5)
   cat conftest.out >&5
   if $GREP 'External.*some_variable' conftest.out > /dev/null; then
     lt_cv_nm_interface="MS dumpbin"
@@ -6521,7 +6509,7 @@ ia64-*-hpux*)
   ;;
 *-*-irix6*)
   # Find out which ABI we are using.
-  echo '#line 6524 "configure"' > conftest.$ac_ext
+  echo '#line 6512 "configure"' > conftest.$ac_ext
   if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   (eval $ac_compile) 2>&5
   ac_status=$?
@@ -7886,11 +7874,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:7889: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:7877: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:7893: \$? = $ac_status" >&5
+   echo "$as_me:7881: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
@@ -8225,11 +8213,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:8228: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:8216: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:8232: \$? = $ac_status" >&5
+   echo "$as_me:8220: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
@@ -8330,11 +8318,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:8333: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:8321: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:8337: \$? = $ac_status" >&5
+   echo "$as_me:8325: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
@@ -8385,11 +8373,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:8388: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:8376: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:8392: \$? = $ac_status" >&5
+   echo "$as_me:8380: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
@@ -11188,7 +11176,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11191 "configure"
+#line 11179 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -11284,7 +11272,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11287 "configure"
+#line 11275 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -12524,9 +12512,9 @@ if  test "x$GCC" = xyes ; then
     CWARNFLAGS="-Wall -Wpointer-arith -Wstrict-prototypes -Wmissing-prototypes \
 -Wmissing-declarations -Wnested-externs -fno-strict-aliasing \
 -Wbad-function-cast"
-    case `gcc -dumpversion` in
+    case `$CC -dumpversion` in
     3.4.* | 4.*)
-	CWARNFLAGS+=" -Wold-style-definition -Wdeclaration-after-statement"
+	CWARNFLAGS="$CWARNFLAGS -Wold-style-definition -Wdeclaration-after-statement"
 	;;
     esac
 else
@@ -17542,7 +17530,7 @@ exec 6>&1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by libX11 $as_me 1.2.2, which was
+This file was extended by libX11 $as_me 1.2.99.901, which was
 generated by GNU Autoconf 2.63.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -17605,7 +17593,7 @@ Report bugs to <bug-autoconf@gnu.org>."
 _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_version="\\
-libX11 config.status 1.2.2
+libX11 config.status 1.2.99.901
 configured by $0, generated by GNU Autoconf 2.63,
   with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
 
diff --git a/libX11/configure.ac b/libX11/configure.ac
index ab6d5a368..45e9d74ce 100644
--- a/libX11/configure.ac
+++ b/libX11/configure.ac
@@ -3,7 +3,7 @@
 
 AC_PREREQ(2.60)
 AC_INIT([libX11],
-        1.2.2,
+        1.2.99.901,
         [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg],
         libX11)
 AC_CONFIG_SRCDIR([Makefile.am])
diff --git a/libX11/include/X11/Xlib-xcb.h b/libX11/include/X11/Xlib-xcb.h
index b88e2e7a9..03d8f9867 100644
--- a/libX11/include/X11/Xlib-xcb.h
+++ b/libX11/include/X11/Xlib-xcb.h
@@ -6,10 +6,15 @@
 
 #include <xcb/xcb.h>
 #include <X11/Xlib.h>
+#include <X11/Xfuncproto.h>
+
+_XFUNCPROTOBEGIN
 
 xcb_connection_t *XGetXCBConnection(Display *dpy);
 
 enum XEventQueueOwner { XlibOwnsEventQueue = 0, XCBOwnsEventQueue };
 void XSetEventQueueOwner(Display *dpy, enum XEventQueueOwner owner);
 
+_XFUNCPROTOEND
+
 #endif /* XLIB_XCB_H */
diff --git a/libX11/include/X11/Xlib.h b/libX11/include/X11/Xlib.h
index 682988cf2..2c30bc09e 100644
--- a/libX11/include/X11/Xlib.h
+++ b/libX11/include/X11/Xlib.h
@@ -966,6 +966,17 @@ typedef struct
     int            evtype;       /* actual event type. */
     } XGenericEvent;
 
+typedef struct {
+    int            type;         /* of event. Always GenericEvent */
+    unsigned long  serial;       /* # of last request processed */
+    Bool           send_event;   /* true if from SendEvent request */
+    Display        *display;     /* Display the event was read from */
+    int            extension;    /* major opcode of extension that caused the event */
+    int            evtype;       /* actual event type. */
+    unsigned int   cookie;
+    void           *data;
+} XGenericEventCookie;
+
 /*
  * this union is defined so Xlib can always use the same sized
  * event structure internally, to avoid memory fragmentation.
@@ -1003,6 +1014,8 @@ typedef union _XEvent {
 	XMappingEvent xmapping;
 	XErrorEvent xerror;
 	XKeymapEvent xkeymap;
+	XGenericEvent xgeneric;
+	XGenericEventCookie xcookie;
 	long pad[24];
 } XEvent;
 #endif
@@ -3998,6 +4011,16 @@ extern int _Xwctomb(
     wchar_t			/* wc */
 );
 
+extern Bool XGetEventData(
+    Display*			/* dpy */,
+    XGenericEventCookie*	/* cookie*/
+);
+
+extern void XFreeEventData(
+    Display*			/* dpy */,
+    XGenericEventCookie*	/* cookie*/
+);
+
 _XFUNCPROTOEND
 
 #endif /* _XLIB_H_ */
diff --git a/libX11/include/X11/Xlibint.h b/libX11/include/X11/Xlibint.h
index 4f3755fae..2acfc7690 100644
--- a/libX11/include/X11/Xlibint.h
+++ b/libX11/include/X11/Xlibint.h
@@ -185,6 +185,20 @@ struct _XDisplay
 	struct _XkbInfoRec *xkb_info; /* XKB info */
 	struct _XtransConnInfo *trans_conn; /* transport connection object */
 	struct _X11XCBPrivate *xcb; /* XCB glue private data */
+
+	/* Generic event cookie handling */
+	unsigned int next_cookie; /* next event cookie */
+	/* vector for wire to generic event, index is (extension - 128) */
+	Bool (*generic_event_vec[128])(
+		Display *	/* dpy */,
+		XGenericEventCookie *	/* Xlib event */,
+		xEvent *	/* wire event */);
+	/* vector for event copy, index is (extension - 128) */
+	Bool (*generic_event_copy_vec[128])(
+		Display *	/* dpy */,
+		XGenericEventCookie *	/* in */,
+		XGenericEventCookie *   /* out*/);
+	void *cookiejar;  /* cookie events returned but not claimed */
 };
 
 #define XAllocIDs(dpy,ids,n) (*(dpy)->idlist_alloc)(dpy,ids,n)
@@ -1005,6 +1019,19 @@ extern Bool _XUnknownWireEvent(
     XEvent*	/* re */,
     xEvent*	/* event */
 );
+
+extern Bool _XUnknownWireEventCookie(
+    Display*	/* dpy */,
+    XGenericEventCookie*	/* re */,
+    xEvent*	/* event */
+);
+
+extern Bool _XUnknownCopyEventCookie(
+    Display*	/* dpy */,
+    XGenericEventCookie*	/* in */,
+    XGenericEventCookie*	/* out */
+);
+
 extern Status _XUnknownNativeEvent(
     Display*	/* dpy */,
     XEvent*	/* re */,
@@ -1157,6 +1184,31 @@ extern Bool (*XESetWireToEvent(
     Display*, XEvent*, xEvent*
 );
 
+extern Bool (*XESetWireToEventCookie(
+    Display*		/* display */,
+    int			/* extension */,
+    Bool (*) (
+	       Display*			/* display */,
+               XGenericEventCookie*	/* re */,
+               xEvent*			/* event */
+             )		/* proc */
+))(
+    Display*, XGenericEventCookie*, xEvent*
+);
+
+extern Bool (*XESetCopyEventCookie(
+    Display*		/* display */,
+    int			/* extension */,
+    Bool (*) (
+	       Display*			/* display */,
+               XGenericEventCookie*	/* in */,
+               XGenericEventCookie*	/* out */
+             )		/* proc */
+))(
+    Display*, XGenericEventCookie*, XGenericEventCookie*
+);
+
+
 extern Status (*XESetEventToWire(
     Display*		/* display */,
     int			/* event_number */,
@@ -1321,6 +1373,26 @@ int _XPutBackEvent (
     register Display *dpy,
     register XEvent *event);
 
+extern Bool _XIsEventCookie(
+        Display *dpy,
+        XEvent *ev);
+
+extern void _XFreeEventCookies(
+        Display *dpy);
+
+extern void _XStoreEventCookie(
+        Display *dpy,
+        XEvent *ev);
+
+extern Bool _XFetchEventCookie(
+        Display *dpy,
+        XGenericEventCookie *ev);
+
+extern Bool _XCopyEventCookie(
+        Display *dpy,
+        XGenericEventCookie *in,
+        XGenericEventCookie *out);
+
 _XFUNCPROTOEND
 
 #endif /* _XLIBINT_H_ */
diff --git a/libX11/man/Makefile.am b/libX11/man/Makefile.am
index b19c5d39a..b21d8fb9a 100644
--- a/libX11/man/Makefile.am
+++ b/libX11/man/Makefile.am
@@ -75,6 +75,7 @@ libman_PRE = \
 	XGravityEvent.man \
 	XrmGetFileDatabase.man \
 	XrmGetResource.man \
+	XGetEventData.man \
 	XGetVisualInfo.man \
 	XGetWindowAttributes.man \
 	XGetWindowProperty.man \
@@ -271,6 +272,7 @@ all_shadows =                                \
     $(XGraphicsExposeEvent_shadows)          \
     $(XrmGetFileDatabase_shadows)            \
     $(XrmGetResource_shadows)                \
+    $(XGetEventData_shadows)                 \
     $(XGetVisualInfo_shadows)                \
     $(XGetWindowAttributes_shadows)          \
     $(XGetWindowProperty_shadows)            \
@@ -658,6 +660,10 @@ XrmGetResource_shadows =                    \
     XrmQGetSearchList                       \
     XrmQGetSearchResource
 
+XGetEventData_shadows =                     \
+    XFreeEventData                          \
+    XGenericEventCookie
+
 XGetVisualInfo_shadows =                    \
     XMatchVisualInfo                        \
     XVisualIDFromVisual                     \
@@ -1223,6 +1229,9 @@ shadows.DONE:
 	(for i in $(XrmGetResource_shadows:=.@LIB_MAN_SUFFIX@) ; do \
 	 echo .so man$(LIB_MAN_DIR_SUFFIX)/XrmGetResource.$(LIB_MAN_SUFFIX) > $$i; \
 	 done)
+	(for i in $(XGetEventData_shadows:=.@LIB_MAN_SUFFIX@) ; do \
+	 echo .so man$(LIB_MAN_DIR_SUFFIX)/XGetEventData.$(LIB_MAN_SUFFIX) > $$i; \
+	 done)
 	(for i in $(XGetVisualInfo_shadows:=.@LIB_MAN_SUFFIX@) ; do \
 	 echo .so man$(LIB_MAN_DIR_SUFFIX)/XGetVisualInfo.$(LIB_MAN_SUFFIX) > $$i; \
 	 done)
diff --git a/libX11/man/Makefile.in b/libX11/man/Makefile.in
index effbc173e..64f44af7f 100644
--- a/libX11/man/Makefile.in
+++ b/libX11/man/Makefile.in
@@ -358,6 +358,7 @@ libman_PRE = \
 	XGravityEvent.man \
 	XrmGetFileDatabase.man \
 	XrmGetResource.man \
+	XGetEventData.man \
 	XGetVisualInfo.man \
 	XGetWindowAttributes.man \
 	XGetWindowProperty.man \
@@ -559,6 +560,7 @@ all_shadows = \
     $(XGraphicsExposeEvent_shadows)          \
     $(XrmGetFileDatabase_shadows)            \
     $(XrmGetResource_shadows)                \
+    $(XGetEventData_shadows)                 \
     $(XGetVisualInfo_shadows)                \
     $(XGetWindowAttributes_shadows)          \
     $(XGetWindowProperty_shadows)            \
@@ -945,6 +947,10 @@ XrmGetResource_shadows = \
     XrmQGetSearchList                       \
     XrmQGetSearchResource
 
+XGetEventData_shadows = \
+    XFreeEventData                          \
+    XGenericEventCookie
+
 XGetVisualInfo_shadows = \
     XMatchVisualInfo                        \
     XVisualIDFromVisual                     \
@@ -1894,6 +1900,9 @@ shadows.DONE:
 	(for i in $(XrmGetResource_shadows:=.@LIB_MAN_SUFFIX@) ; do \
 	 echo .so man$(LIB_MAN_DIR_SUFFIX)/XrmGetResource.$(LIB_MAN_SUFFIX) > $$i; \
 	 done)
+	(for i in $(XGetEventData_shadows:=.@LIB_MAN_SUFFIX@) ; do \
+	 echo .so man$(LIB_MAN_DIR_SUFFIX)/XGetEventData.$(LIB_MAN_SUFFIX) > $$i; \
+	 done)
 	(for i in $(XGetVisualInfo_shadows:=.@LIB_MAN_SUFFIX@) ; do \
 	 echo .so man$(LIB_MAN_DIR_SUFFIX)/XGetVisualInfo.$(LIB_MAN_SUFFIX) > $$i; \
 	 done)
diff --git a/libX11/man/XGetEventData.man b/libX11/man/XGetEventData.man
new file mode 100644
index 000000000..10008edc4
--- /dev/null
+++ b/libX11/man/XGetEventData.man
@@ -0,0 +1,223 @@
+.\" Copyright \(co 2009 Red Hat, Inc.
+.\"
+.\" 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 (including the next
+.\" paragraph) shall be included in all copies or substantial portions of the
+.\" Software.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+.\" IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+.\" FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+.\" THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+.\" LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+.\" FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+.\" DEALINGS IN THE SOFTWARE.
+.\"
+.ds xT X Toolkit Intrinsics \- C Language Interface
+.ds xW Athena X Widgets \- C Language X Toolkit Interface
+.ds xL Xlib \- C Language X Interface
+.ds xC Inter-Client Communication Conventions Manual
+.na
+.de Ds
+.nf
+.\\$1D \\$2 \\$1
+.ft 1
+.\".ps \\n(PS
+.\".if \\n(VS>=40 .vs \\n(VSu
+.\".if \\n(VS<=39 .vs \\n(VSp
+..
+.de De
+.ce 0
+.if \\n(BD .DF
+.nr BD 0
+.in \\n(OIu
+.if \\n(TM .ls 2
+.sp \\n(DDu
+.fi
+..
+.de FD
+.LP
+.KS
+.TA .5i 3i
+.ta .5i 3i
+.nf
+..
+.de FN
+.fi
+.KE
+.LP
+..
+.de IN		\" send an index entry to the stderr
+..
+.de C{
+.KS
+.nf
+.D
+.\"
+.\"	choose appropriate monospace font
+.\"	the imagen conditional, 480,
+.\"	may be changed to L if LB is too
+.\"	heavy for your eyes...
+.\"
+.ie "\\*(.T"480" .ft L
+.el .ie "\\*(.T"300" .ft L
+.el .ie "\\*(.T"202" .ft PO
+.el .ie "\\*(.T"aps" .ft CW
+.el .ft R
+.ps \\n(PS
+.ie \\n(VS>40 .vs \\n(VSu
+.el .vs \\n(VSp
+..
+.de C}
+.DE
+.R
+..
+.de Pn
+.ie t \\$1\fB\^\\$2\^\fR\\$3
+.el \\$1\fI\^\\$2\^\fP\\$3
+..
+.de ZN
+.ie t \fB\^\\$1\^\fR\\$2
+.el \fI\^\\$1\^\fP\\$2
+..
+.de hN
+.ie t <\fB\\$1\fR>\\$2
+.el <\fI\\$1\fP>\\$2
+..
+.de NT
+.ne 7
+.ds NO Note
+.if \\n(.$>$1 .if !'\\$2'C' .ds NO \\$2
+.if \\n(.$ .if !'\\$1'C' .ds NO \\$1
+.ie n .sp
+.el .sp 10p
+.TB
+.ce
+\\*(NO
+.ie n .sp
+.el .sp 5p
+.if '\\$1'C' .ce 99
+.if '\\$2'C' .ce 99
+.in +5n
+.ll -5n
+.R
+..
+.		\" Note End -- doug kraft 3/85
+.de NE
+.ce 0
+.in -5n
+.ll +5n
+.ie n .sp
+.el .sp 10p
+..
+.ny0
+.TH XGetEventData __libmansuffix__ __xorgversion__ "XLIB FUNCTIONS"
+.SH NAME
+XGetEventData, XFreeEventData, XGenericEventCookie \- retrieve and free additional event data through cookies.
+.SH SYNTAX
+.HP
+Bool XGetEventData\^(\^Display *\fIdisplay\fP\^, XGenericEventCookie *\fIcookie\fP\^);
+.HP
+void XFreeEventData\^(\^Display *\fIdisplay\fP\^, XGenericEventCookie *\fIcookie\fP\^);
+.HP
+.SH ARGUMENTS
+.IP \fIdisplay\fP 1i
+Specifies the connection to the X server.
+.IP \fIcookie\fP 1i
+Specifies the cookie to free or retrieve the data for.
+
+.SH STRUCTURES
+.Ds 0
+.TA .5i 3i
+.ta .5i 3i
+typedef struct {
+	int type;
+	unsigned long serial;
+	Bool send_event;
+	Display *display;
+	int extension;
+	int evtype;
+	unsigned int cookie;
+	void *data;
+} XGenericEventCookie;
+.De
+
+.SH DESCRIPTION
+Some extension
+.ZN XGenericEvents
+require additional memory to store information.
+For these events, the library returns a
+.ZN XGenericEventCookie
+with a token ('cookie') unique to this event. The
+.ZN XGenericEventCookie 's
+data pointer is undefined until
+.ZN XGetEventData
+is called.
+
+The
+.ZN XGetEventData
+function retrieves this extra data for the given cookie. No round-trip to
+the server is required. If the cookie is invalid or the
+event is not an event handled by cookie handlers,
+.ZN False
+is returned. If
+.ZN XGetEventData
+returns
+.ZN True ,
+the cookie's data pointer points to the memory containing the event
+information. A client must call
+.ZN XFreeEventData
+to free this memory.
+.ZN XGetEventData
+returns
+.ZN False
+for multiple calls for the same event cookie.
+
+The
+.ZN XFreeEventData
+function frees the data associated with a cookie. A client must call
+.ZN XFreeEventData
+for each cookie claimed with
+.ZN XGetEventData .
+
+.SH EXAMPLE CODE
+.Ds 0
+.TA .5i 3i
+.ta .5i 3i
+XEvent event;
+XGenericEventCookie *cookie = &ev;
+
+XNextEvent(display, &event);
+if (XGetEventData(display, cookie)) {
+    handle_cookie_event(cookie->data);
+} else
+    handle_event(&event);
+}
+XFreeEventData(display, cookie);
+.De
+
+.SH NOTES
+A cookie is defined as unclaimed if it has been returned to the client
+through
+.ZN XNextEvent
+but its data has not been retrieved via
+.ZN XGetEventData .
+Subsequent calls to
+.ZN XNextEvent
+may free memory associated with unclaimed cookies.
+Multi-threaded X clients must ensure that
+.ZN XGetEventData
+is called before the next call to
+.ZN XNextEvent .
+
+.SH "SEE ALSO"
+XNextEvent(3X11),
+.br
+\fI\*(xL\fP
+
diff --git a/libX11/nls/en_US.UTF-8/Compose.pre b/libX11/nls/en_US.UTF-8/Compose.pre
index 26084b906..a4174bbe3 100644
--- a/libX11/nls/en_US.UTF-8/Compose.pre
+++ b/libX11/nls/en_US.UTF-8/Compose.pre
@@ -4150,6 +4150,8 @@ XCOMM Part 3
 <Multi_key> <KP_Divide> <rightarrow> 	: "↛"   U219B # RIGHTWARDS ARROW WITH STROKE
 <Multi_key> <slash> <U2194>  	: "↮"   U21AE # LEFT RIGHT ARROW WITH STROKE
 <Multi_key> <KP_Divide> <U2194> 	: "↮"   U21AE # LEFT RIGHT ARROW WITH STROKE
+<Multi_key> <less> <minus> 	: "←" U2190 # LEFTWARDS ARROW
+<Multi_key> <minus> <greater> 	: "→" U2192 # RIGHTWARDS ARROW
 <Multi_key> <U2203> <U0338> 	: "∄"   U2204 # THERE DOES NOT EXIST
 <Multi_key> <U2208> <U0338> 	: "∉"   U2209 # NOT AN ELEMENT OF
 <Multi_key> <U220B> <U0338> 	: "∌"   U220C # DOES NOT CONTAIN AS MEMBER
diff --git a/libX11/src/ChkIfEv.c b/libX11/src/ChkIfEv.c
index 9bef64f89..66f0c3c98 100644
--- a/libX11/src/ChkIfEv.c
+++ b/libX11/src/ChkIfEv.c
@@ -62,6 +62,7 @@ Bool XCheckIfEvent (
 		   && (*predicate)(dpy, &qelt->event, arg)) {
 		    *event = qelt->event;
 		    _XDeq(dpy, prev, qelt);
+		    _XStoreEventCookie(dpy, event);
 		    UnlockDisplay(dpy);
 		    return True;
 		}
diff --git a/libX11/src/ChkMaskEv.c b/libX11/src/ChkMaskEv.c
index bc1a279f1..6fb71c9e0 100644
--- a/libX11/src/ChkMaskEv.c
+++ b/libX11/src/ChkMaskEv.c
@@ -54,6 +54,10 @@ Bool XCheckMaskEvent (
 	int n;			/* time through count */
 
         LockDisplay(dpy);
+
+	/* Delete unclaimed cookies */
+	_XFreeEventCookies(dpy);
+
 	prev = NULL;
 	for (n = 3; --n >= 0;) {
 	    for (qelt = prev ? prev->next : dpy->head;
diff --git a/libX11/src/ChkTypEv.c b/libX11/src/ChkTypEv.c
index fc4c7d187..f64ebd335 100644
--- a/libX11/src/ChkTypEv.c
+++ b/libX11/src/ChkTypEv.c
@@ -48,6 +48,10 @@ Bool XCheckTypedEvent (
 	int n;			/* time through count */
 
         LockDisplay(dpy);
+
+	/* Delete unclaimed cookies */
+	_XFreeEventCookies(dpy);
+
 	prev = NULL;
 	for (n = 3; --n >= 0;) {
 	    for (qelt = prev ? prev->next : dpy->head;
diff --git a/libX11/src/ChkTypWEv.c b/libX11/src/ChkTypWEv.c
index 6214c3654..d791eb255 100644
--- a/libX11/src/ChkTypWEv.c
+++ b/libX11/src/ChkTypWEv.c
@@ -49,6 +49,10 @@ Bool XCheckTypedWindowEvent (
 	int n;			/* time through count */
 
         LockDisplay(dpy);
+
+	/* Delete unclaimed cookies */
+	_XFreeEventCookies(dpy);
+
 	prev = NULL;
 	for (n = 3; --n >= 0;) {
 	    for (qelt = prev ? prev->next : dpy->head;
diff --git a/libX11/src/ChkWinEv.c b/libX11/src/ChkWinEv.c
index 1fd975cda..b753c5fd8 100644
--- a/libX11/src/ChkWinEv.c
+++ b/libX11/src/ChkWinEv.c
@@ -54,6 +54,10 @@ Bool XCheckWindowEvent (
 	int n;			/* time through count */
 
         LockDisplay(dpy);
+
+	/* Delete unclaimed cookies */
+	_XFreeEventCookies(dpy);
+
 	prev = NULL;
 	for (n = 3; --n >= 0;) {
 	    for (qelt = prev ? prev->next : dpy->head;
diff --git a/libX11/src/FreeEventData.c b/libX11/src/FreeEventData.c
new file mode 100644
index 000000000..e2d40b0db
--- /dev/null
+++ b/libX11/src/FreeEventData.c
@@ -0,0 +1,42 @@
+/*
+ * Copyright © 2009 Red Hat, Inc.
+ *
+ * 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 (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Xlibint.h"
+
+void
+XFreeEventData(Display *dpy, XGenericEventCookie *event)
+{
+
+    if (_XIsEventCookie(dpy, (XEvent*)event) && event->data)
+    {
+        XFree(event->data);
+        event->data = NULL;
+        event->cookie = 0;
+    }
+    return;
+}
+
diff --git a/libX11/src/GetEventData.c b/libX11/src/GetEventData.c
new file mode 100644
index 000000000..b93dee6cd
--- /dev/null
+++ b/libX11/src/GetEventData.c
@@ -0,0 +1,42 @@
+/*
+ * Copyright © 2009 Red Hat, Inc.
+ *
+ * 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 (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "Xlibint.h"
+
+Bool
+XGetEventData(Display *dpy, XGenericEventCookie *event)
+{
+    Bool rc;
+    LockDisplay(dpy);
+
+    rc = _XFetchEventCookie(dpy, event);
+
+    UnlockDisplay(dpy);
+
+    return rc;
+}
+
diff --git a/libX11/src/IfEvent.c b/libX11/src/IfEvent.c
index 05a2b82cb..64c8f465b 100644
--- a/libX11/src/IfEvent.c
+++ b/libX11/src/IfEvent.c
@@ -61,6 +61,7 @@ XIfEvent (
 		   && (*predicate)(dpy, &qelt->event, arg)) {
 		    *event = qelt->event;
 		    _XDeq(dpy, prev, qelt);
+		    _XStoreEventCookie(dpy, event);
 		    UnlockDisplay(dpy);
 		    return 0;
 		}
diff --git a/libX11/src/InitExt.c b/libX11/src/InitExt.c
index 92fc44afa..0e6c94ee6 100644
--- a/libX11/src/InitExt.c
+++ b/libX11/src/InitExt.c
@@ -253,6 +253,49 @@ WireToEventType XESetWireToEvent(
 	return (WireToEventType)oldproc;
 }
 
+typedef Bool (*WireToEventCookieType) (
+    Display*	/* display */,
+    XGenericEventCookie*	/* re */,
+    xEvent*	/* event */
+);
+
+WireToEventCookieType XESetWireToEventCookie(
+    Display *dpy,       /* display */
+    int extension,      /* extension major opcode */
+    WireToEventCookieType proc /* routine to call for generic events */
+    )
+{
+	WireToEventCookieType oldproc;
+	if (proc == NULL) proc = (WireToEventCookieType)_XUnknownWireEventCookie;
+	LockDisplay (dpy);
+	oldproc = dpy->generic_event_vec[extension & 0x7F];
+	dpy->generic_event_vec[extension & 0x7F] = proc;
+	UnlockDisplay (dpy);
+	return (WireToEventCookieType)oldproc;
+}
+
+typedef Bool (*CopyEventCookieType) (
+    Display*	/* display */,
+    XGenericEventCookie*	/* in */,
+    XGenericEventCookie*	/* out */
+);
+
+CopyEventCookieType XESetCopyEventCookie(
+    Display *dpy,       /* display */
+    int extension,      /* extension major opcode */
+    CopyEventCookieType proc /* routine to copy generic events */
+    )
+{
+	CopyEventCookieType oldproc;
+	if (proc == NULL) proc = (CopyEventCookieType)_XUnknownCopyEventCookie;
+	LockDisplay (dpy);
+	oldproc = dpy->generic_event_copy_vec[extension & 0x7F];
+	dpy->generic_event_copy_vec[extension & 0x7F] = proc;
+	UnlockDisplay (dpy);
+	return (CopyEventCookieType)oldproc;
+}
+
+
 typedef Status (*EventToWireType) (
     Display*	/* display */,
     XEvent*	/* re */,
diff --git a/libX11/src/Makefile.am b/libX11/src/Makefile.am
index 86a846e41..26d8e277f 100644
--- a/libX11/src/Makefile.am
+++ b/libX11/src/Makefile.am
@@ -130,6 +130,7 @@ libX11_la_SOURCES = \
                   FreeCols.c \
                   FreeCurs.c \
                   FreeEData.c \
+                  FreeEventData.c \
                   FreeGC.c \
                   FreePix.c \
                   FSSaver.c \
@@ -139,6 +140,7 @@ libX11_la_SOURCES = \
                   GetAtomNm.c \
                   GetColor.c \
                   GetDflt.c \
+                  GetEventData.c \
                   GetFPath.c \
                   GetFProp.c \
                   GetGCVals.c \
@@ -297,6 +299,7 @@ libX11_la_SOURCES = \
                   UnldFont.c \
                   UnmapSubs.c \
                   UnmapWin.c \
+                  utlist.h \
                   VisUtil.c \
                   WarpPtr.c \
                   Window.c \
@@ -373,7 +376,7 @@ if XKB
 USE_XKB_LIBS = $(XKB_LIBS)
 endif
 
-libX11_la_LDFLAGS = -version-number 6:2:0 -no-undefined
+libX11_la_LDFLAGS = -version-number 6:3:0 -no-undefined
 
 libX11_la_LIBADD = \
 	$(USE_I18N_LIBS) \
diff --git a/libX11/src/Makefile.in b/libX11/src/Makefile.in
index ef4df0a71..1d377c9e0 100644
--- a/libX11/src/Makefile.in
+++ b/libX11/src/Makefile.in
@@ -114,43 +114,43 @@ am__libX11_la_SOURCES_DIST = AllCells.c AllowEv.c AllPlanes.c \
 	DrRects.c DrSegs.c ErrDes.c ErrHndlr.c evtomask.c EvToWire.c \
 	FetchName.c FillArc.c FillArcs.c FillPoly.c FillRct.c \
 	FillRcts.c FilterEv.c Flush.c Font.c FontInfo.c FontNames.c \
-	FreeCmap.c FreeCols.c FreeCurs.c FreeEData.c FreeGC.c \
-	FreePix.c FSSaver.c FSWrap.c GCMisc.c Geom.c GetAtomNm.c \
-	GetColor.c GetDflt.c GetFPath.c GetFProp.c GetGCVals.c \
-	GetGeom.c GetHColor.c GetHints.c GetIFocus.c GetImage.c \
-	GetKCnt.c GetMoEv.c GetNrmHint.c GetPCnt.c GetPntMap.c \
-	GetProp.c GetRGBCMap.c GetSOwner.c GetSSaver.c GetStCmap.c \
-	GetTxtProp.c GetWAttrs.c GetWMCMapW.c GetWMProto.c globals.c \
-	GrButton.c GrKeybd.c GrKey.c GrPointer.c GrServer.c Host.c \
-	Iconify.c IfEvent.c imConv.c ImText16.c ImText.c ImUtil.c \
-	InitExt.c InsCmap.c IntAtom.c KeyBind.c Key.h KeysymStr.c \
-	KillCl.c LiHosts.c LiICmaps.c LiProps.c ListExt.c LoadFont.c \
-	LockDis.c locking.c locking.h LookupCol.c LowerWin.c Macros.c \
-	MapRaised.c MapSubs.c MapWindow.c MaskEvent.c Misc.c ModMap.c \
-	MoveWin.c NextEvent.c OCWrap.c OMWrap.c OpenDis.c ParseCmd.c \
-	ParseCol.c ParseGeom.c PeekEvent.c PeekIfEv.c Pending.c \
-	PixFormats.c PmapBgnd.c PmapBord.c poly.h PolyReg.c \
-	PolyTxt16.c PolyTxt.c PropAlloc.c PutBEvent.c PutImage.c \
-	Quarks.c QuBest.c QuColor.c QuColors.c QuCurShp.c QuExt.c \
-	QuKeybd.c QuPntr.c QuStipShp.c QuTextE16.c QuTextExt.c \
-	QuTileShp.c QuTree.c RaiseWin.c RdBitF.c RecolorC.c \
-	ReconfWin.c ReconfWM.c Region.c RegstFlt.c RepWindow.c \
-	RestackWs.c RotProp.c ScrResStr.c SelInput.c SendEvent.c \
-	SetBack.c SetClMask.c SetClOrig.c SetCRects.c SetDashes.c \
-	SetFont.c SetFore.c SetFPath.c SetFunc.c SetHints.c \
-	SetIFocus.c SetLocale.c SetLStyle.c SetNrmHint.c SetPMask.c \
-	SetPntMap.c SetRGBCMap.c SetSOwner.c SetSSaver.c SetState.c \
-	SetStCmap.c SetStip.c SetTile.c SetTSOrig.c SetTxtProp.c \
-	SetWMCMapW.c SetWMProto.c StBytes.c StColor.c StColors.c \
-	StName.c StNColor.c StrKeysym.c StrToText.c Sync.c Synchro.c \
-	Text16.c Text.c TextExt16.c TextExt.c TextToStr.c TrCoords.c \
-	UndefCurs.c UngrabBut.c UngrabKbd.c UngrabKey.c UngrabPtr.c \
-	UngrabSvr.c UninsCmap.c UnldFont.c UnmapSubs.c UnmapWin.c \
-	VisUtil.c WarpPtr.c Window.c WinEvent.c Withdraw.c WMGeom.c \
-	WMProps.c WrBitF.c Xatomtype.h Xintatom.h Xintconn.h \
-	XlibAsync.c XlibInt.c Xprivate.h XomGeneric.h Xresinternal.h \
-	Xrm.c XrmI.h os2Stubs.c udcInf.c UIThrStubs.c xcb_disp.c \
-	xcb_io.c Xxcbint.h ConnDis.c x11_trans.c
+	FreeCmap.c FreeCols.c FreeCurs.c FreeEData.c FreeEventData.c \
+	FreeGC.c FreePix.c FSSaver.c FSWrap.c GCMisc.c Geom.c \
+	GetAtomNm.c GetColor.c GetDflt.c GetEventData.c GetFPath.c \
+	GetFProp.c GetGCVals.c GetGeom.c GetHColor.c GetHints.c \
+	GetIFocus.c GetImage.c GetKCnt.c GetMoEv.c GetNrmHint.c \
+	GetPCnt.c GetPntMap.c GetProp.c GetRGBCMap.c GetSOwner.c \
+	GetSSaver.c GetStCmap.c GetTxtProp.c GetWAttrs.c GetWMCMapW.c \
+	GetWMProto.c globals.c GrButton.c GrKeybd.c GrKey.c \
+	GrPointer.c GrServer.c Host.c Iconify.c IfEvent.c imConv.c \
+	ImText16.c ImText.c ImUtil.c InitExt.c InsCmap.c IntAtom.c \
+	KeyBind.c Key.h KeysymStr.c KillCl.c LiHosts.c LiICmaps.c \
+	LiProps.c ListExt.c LoadFont.c LockDis.c locking.c locking.h \
+	LookupCol.c LowerWin.c Macros.c MapRaised.c MapSubs.c \
+	MapWindow.c MaskEvent.c Misc.c ModMap.c MoveWin.c NextEvent.c \
+	OCWrap.c OMWrap.c OpenDis.c ParseCmd.c ParseCol.c ParseGeom.c \
+	PeekEvent.c PeekIfEv.c Pending.c PixFormats.c PmapBgnd.c \
+	PmapBord.c poly.h PolyReg.c PolyTxt16.c PolyTxt.c PropAlloc.c \
+	PutBEvent.c PutImage.c Quarks.c QuBest.c QuColor.c QuColors.c \
+	QuCurShp.c QuExt.c QuKeybd.c QuPntr.c QuStipShp.c QuTextE16.c \
+	QuTextExt.c QuTileShp.c QuTree.c RaiseWin.c RdBitF.c \
+	RecolorC.c ReconfWin.c ReconfWM.c Region.c RegstFlt.c \
+	RepWindow.c RestackWs.c RotProp.c ScrResStr.c SelInput.c \
+	SendEvent.c SetBack.c SetClMask.c SetClOrig.c SetCRects.c \
+	SetDashes.c SetFont.c SetFore.c SetFPath.c SetFunc.c \
+	SetHints.c SetIFocus.c SetLocale.c SetLStyle.c SetNrmHint.c \
+	SetPMask.c SetPntMap.c SetRGBCMap.c SetSOwner.c SetSSaver.c \
+	SetState.c SetStCmap.c SetStip.c SetTile.c SetTSOrig.c \
+	SetTxtProp.c SetWMCMapW.c SetWMProto.c StBytes.c StColor.c \
+	StColors.c StName.c StNColor.c StrKeysym.c StrToText.c Sync.c \
+	Synchro.c Text16.c Text.c TextExt16.c TextExt.c TextToStr.c \
+	TrCoords.c UndefCurs.c UngrabBut.c UngrabKbd.c UngrabKey.c \
+	UngrabPtr.c UngrabSvr.c UninsCmap.c UnldFont.c UnmapSubs.c \
+	UnmapWin.c utlist.h VisUtil.c WarpPtr.c Window.c WinEvent.c \
+	Withdraw.c WMGeom.c WMProps.c WrBitF.c Xatomtype.h Xintatom.h \
+	Xintconn.h XlibAsync.c XlibInt.c Xprivate.h XomGeneric.h \
+	Xresinternal.h Xrm.c XrmI.h os2Stubs.c udcInf.c UIThrStubs.c \
+	xcb_disp.c xcb_io.c Xxcbint.h ConnDis.c x11_trans.c
 @OS2_TRUE@am__objects_1 = os2Stubs.lo
 @UDC_TRUE@am__objects_2 = udcInf.lo
 @THRSTUBS_TRUE@am__objects_3 = UIThrStubs.lo
@@ -172,44 +172,45 @@ am_libX11_la_OBJECTS = AllCells.lo AllowEv.lo AllPlanes.lo AutoRep.lo \
 	EvToWire.lo FetchName.lo FillArc.lo FillArcs.lo FillPoly.lo \
 	FillRct.lo FillRcts.lo FilterEv.lo Flush.lo Font.lo \
 	FontInfo.lo FontNames.lo FreeCmap.lo FreeCols.lo FreeCurs.lo \
-	FreeEData.lo FreeGC.lo FreePix.lo FSSaver.lo FSWrap.lo \
-	GCMisc.lo Geom.lo GetAtomNm.lo GetColor.lo GetDflt.lo \
-	GetFPath.lo GetFProp.lo GetGCVals.lo GetGeom.lo GetHColor.lo \
-	GetHints.lo GetIFocus.lo GetImage.lo GetKCnt.lo GetMoEv.lo \
-	GetNrmHint.lo GetPCnt.lo GetPntMap.lo GetProp.lo GetRGBCMap.lo \
-	GetSOwner.lo GetSSaver.lo GetStCmap.lo GetTxtProp.lo \
-	GetWAttrs.lo GetWMCMapW.lo GetWMProto.lo globals.lo \
-	GrButton.lo GrKeybd.lo GrKey.lo GrPointer.lo GrServer.lo \
-	Host.lo Iconify.lo IfEvent.lo imConv.lo ImText16.lo ImText.lo \
-	ImUtil.lo InitExt.lo InsCmap.lo IntAtom.lo KeyBind.lo \
-	KeysymStr.lo KillCl.lo LiHosts.lo LiICmaps.lo LiProps.lo \
-	ListExt.lo LoadFont.lo LockDis.lo locking.lo LookupCol.lo \
-	LowerWin.lo Macros.lo MapRaised.lo MapSubs.lo MapWindow.lo \
-	MaskEvent.lo Misc.lo ModMap.lo MoveWin.lo NextEvent.lo \
-	OCWrap.lo OMWrap.lo OpenDis.lo ParseCmd.lo ParseCol.lo \
-	ParseGeom.lo PeekEvent.lo PeekIfEv.lo Pending.lo PixFormats.lo \
-	PmapBgnd.lo PmapBord.lo PolyReg.lo PolyTxt16.lo PolyTxt.lo \
-	PropAlloc.lo PutBEvent.lo PutImage.lo Quarks.lo QuBest.lo \
-	QuColor.lo QuColors.lo QuCurShp.lo QuExt.lo QuKeybd.lo \
-	QuPntr.lo QuStipShp.lo QuTextE16.lo QuTextExt.lo QuTileShp.lo \
-	QuTree.lo RaiseWin.lo RdBitF.lo RecolorC.lo ReconfWin.lo \
-	ReconfWM.lo Region.lo RegstFlt.lo RepWindow.lo RestackWs.lo \
-	RotProp.lo ScrResStr.lo SelInput.lo SendEvent.lo SetBack.lo \
-	SetClMask.lo SetClOrig.lo SetCRects.lo SetDashes.lo SetFont.lo \
-	SetFore.lo SetFPath.lo SetFunc.lo SetHints.lo SetIFocus.lo \
-	SetLocale.lo SetLStyle.lo SetNrmHint.lo SetPMask.lo \
-	SetPntMap.lo SetRGBCMap.lo SetSOwner.lo SetSSaver.lo \
-	SetState.lo SetStCmap.lo SetStip.lo SetTile.lo SetTSOrig.lo \
-	SetTxtProp.lo SetWMCMapW.lo SetWMProto.lo StBytes.lo \
-	StColor.lo StColors.lo StName.lo StNColor.lo StrKeysym.lo \
-	StrToText.lo Sync.lo Synchro.lo Text16.lo Text.lo TextExt16.lo \
-	TextExt.lo TextToStr.lo TrCoords.lo UndefCurs.lo UngrabBut.lo \
-	UngrabKbd.lo UngrabKey.lo UngrabPtr.lo UngrabSvr.lo \
-	UninsCmap.lo UnldFont.lo UnmapSubs.lo UnmapWin.lo VisUtil.lo \
-	WarpPtr.lo Window.lo WinEvent.lo Withdraw.lo WMGeom.lo \
-	WMProps.lo WrBitF.lo XlibAsync.lo XlibInt.lo Xrm.lo \
-	$(am__objects_1) $(am__objects_2) $(am__objects_3) \
-	$(am__objects_4) $(am__objects_5)
+	FreeEData.lo FreeEventData.lo FreeGC.lo FreePix.lo FSSaver.lo \
+	FSWrap.lo GCMisc.lo Geom.lo GetAtomNm.lo GetColor.lo \
+	GetDflt.lo GetEventData.lo GetFPath.lo GetFProp.lo \
+	GetGCVals.lo GetGeom.lo GetHColor.lo GetHints.lo GetIFocus.lo \
+	GetImage.lo GetKCnt.lo GetMoEv.lo GetNrmHint.lo GetPCnt.lo \
+	GetPntMap.lo GetProp.lo GetRGBCMap.lo GetSOwner.lo \
+	GetSSaver.lo GetStCmap.lo GetTxtProp.lo GetWAttrs.lo \
+	GetWMCMapW.lo GetWMProto.lo globals.lo GrButton.lo GrKeybd.lo \
+	GrKey.lo GrPointer.lo GrServer.lo Host.lo Iconify.lo \
+	IfEvent.lo imConv.lo ImText16.lo ImText.lo ImUtil.lo \
+	InitExt.lo InsCmap.lo IntAtom.lo KeyBind.lo KeysymStr.lo \
+	KillCl.lo LiHosts.lo LiICmaps.lo LiProps.lo ListExt.lo \
+	LoadFont.lo LockDis.lo locking.lo LookupCol.lo LowerWin.lo \
+	Macros.lo MapRaised.lo MapSubs.lo MapWindow.lo MaskEvent.lo \
+	Misc.lo ModMap.lo MoveWin.lo NextEvent.lo OCWrap.lo OMWrap.lo \
+	OpenDis.lo ParseCmd.lo ParseCol.lo ParseGeom.lo PeekEvent.lo \
+	PeekIfEv.lo Pending.lo PixFormats.lo PmapBgnd.lo PmapBord.lo \
+	PolyReg.lo PolyTxt16.lo PolyTxt.lo PropAlloc.lo PutBEvent.lo \
+	PutImage.lo Quarks.lo QuBest.lo QuColor.lo QuColors.lo \
+	QuCurShp.lo QuExt.lo QuKeybd.lo QuPntr.lo QuStipShp.lo \
+	QuTextE16.lo QuTextExt.lo QuTileShp.lo QuTree.lo RaiseWin.lo \
+	RdBitF.lo RecolorC.lo ReconfWin.lo ReconfWM.lo Region.lo \
+	RegstFlt.lo RepWindow.lo RestackWs.lo RotProp.lo ScrResStr.lo \
+	SelInput.lo SendEvent.lo SetBack.lo SetClMask.lo SetClOrig.lo \
+	SetCRects.lo SetDashes.lo SetFont.lo SetFore.lo SetFPath.lo \
+	SetFunc.lo SetHints.lo SetIFocus.lo SetLocale.lo SetLStyle.lo \
+	SetNrmHint.lo SetPMask.lo SetPntMap.lo SetRGBCMap.lo \
+	SetSOwner.lo SetSSaver.lo SetState.lo SetStCmap.lo SetStip.lo \
+	SetTile.lo SetTSOrig.lo SetTxtProp.lo SetWMCMapW.lo \
+	SetWMProto.lo StBytes.lo StColor.lo StColors.lo StName.lo \
+	StNColor.lo StrKeysym.lo StrToText.lo Sync.lo Synchro.lo \
+	Text16.lo Text.lo TextExt16.lo TextExt.lo TextToStr.lo \
+	TrCoords.lo UndefCurs.lo UngrabBut.lo UngrabKbd.lo \
+	UngrabKey.lo UngrabPtr.lo UngrabSvr.lo UninsCmap.lo \
+	UnldFont.lo UnmapSubs.lo UnmapWin.lo VisUtil.lo WarpPtr.lo \
+	Window.lo WinEvent.lo Withdraw.lo WMGeom.lo WMProps.lo \
+	WrBitF.lo XlibAsync.lo XlibInt.lo Xrm.lo $(am__objects_1) \
+	$(am__objects_2) $(am__objects_3) $(am__objects_4) \
+	$(am__objects_5)
 libX11_la_OBJECTS = $(am_libX11_la_OBJECTS)
 libX11_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
 	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
@@ -498,43 +499,43 @@ libX11_la_SOURCES = AllCells.c AllowEv.c AllPlanes.c AutoRep.c \
 	DrRects.c DrSegs.c ErrDes.c ErrHndlr.c evtomask.c EvToWire.c \
 	FetchName.c FillArc.c FillArcs.c FillPoly.c FillRct.c \
 	FillRcts.c FilterEv.c Flush.c Font.c FontInfo.c FontNames.c \
-	FreeCmap.c FreeCols.c FreeCurs.c FreeEData.c FreeGC.c \
-	FreePix.c FSSaver.c FSWrap.c GCMisc.c Geom.c GetAtomNm.c \
-	GetColor.c GetDflt.c GetFPath.c GetFProp.c GetGCVals.c \
-	GetGeom.c GetHColor.c GetHints.c GetIFocus.c GetImage.c \
-	GetKCnt.c GetMoEv.c GetNrmHint.c GetPCnt.c GetPntMap.c \
-	GetProp.c GetRGBCMap.c GetSOwner.c GetSSaver.c GetStCmap.c \
-	GetTxtProp.c GetWAttrs.c GetWMCMapW.c GetWMProto.c globals.c \
-	GrButton.c GrKeybd.c GrKey.c GrPointer.c GrServer.c Host.c \
-	Iconify.c IfEvent.c imConv.c ImText16.c ImText.c ImUtil.c \
-	InitExt.c InsCmap.c IntAtom.c KeyBind.c Key.h KeysymStr.c \
-	KillCl.c LiHosts.c LiICmaps.c LiProps.c ListExt.c LoadFont.c \
-	LockDis.c locking.c locking.h LookupCol.c LowerWin.c Macros.c \
-	MapRaised.c MapSubs.c MapWindow.c MaskEvent.c Misc.c ModMap.c \
-	MoveWin.c NextEvent.c OCWrap.c OMWrap.c OpenDis.c ParseCmd.c \
-	ParseCol.c ParseGeom.c PeekEvent.c PeekIfEv.c Pending.c \
-	PixFormats.c PmapBgnd.c PmapBord.c poly.h PolyReg.c \
-	PolyTxt16.c PolyTxt.c PropAlloc.c PutBEvent.c PutImage.c \
-	Quarks.c QuBest.c QuColor.c QuColors.c QuCurShp.c QuExt.c \
-	QuKeybd.c QuPntr.c QuStipShp.c QuTextE16.c QuTextExt.c \
-	QuTileShp.c QuTree.c RaiseWin.c RdBitF.c RecolorC.c \
-	ReconfWin.c ReconfWM.c Region.c RegstFlt.c RepWindow.c \
-	RestackWs.c RotProp.c ScrResStr.c SelInput.c SendEvent.c \
-	SetBack.c SetClMask.c SetClOrig.c SetCRects.c SetDashes.c \
-	SetFont.c SetFore.c SetFPath.c SetFunc.c SetHints.c \
-	SetIFocus.c SetLocale.c SetLStyle.c SetNrmHint.c SetPMask.c \
-	SetPntMap.c SetRGBCMap.c SetSOwner.c SetSSaver.c SetState.c \
-	SetStCmap.c SetStip.c SetTile.c SetTSOrig.c SetTxtProp.c \
-	SetWMCMapW.c SetWMProto.c StBytes.c StColor.c StColors.c \
-	StName.c StNColor.c StrKeysym.c StrToText.c Sync.c Synchro.c \
-	Text16.c Text.c TextExt16.c TextExt.c TextToStr.c TrCoords.c \
-	UndefCurs.c UngrabBut.c UngrabKbd.c UngrabKey.c UngrabPtr.c \
-	UngrabSvr.c UninsCmap.c UnldFont.c UnmapSubs.c UnmapWin.c \
-	VisUtil.c WarpPtr.c Window.c WinEvent.c Withdraw.c WMGeom.c \
-	WMProps.c WrBitF.c Xatomtype.h Xintatom.h Xintconn.h \
-	XlibAsync.c XlibInt.c Xprivate.h XomGeneric.h Xresinternal.h \
-	Xrm.c XrmI.h $(am__append_1) $(am__append_2) $(am__append_3) \
-	$(am__append_4) $(am__append_6)
+	FreeCmap.c FreeCols.c FreeCurs.c FreeEData.c FreeEventData.c \
+	FreeGC.c FreePix.c FSSaver.c FSWrap.c GCMisc.c Geom.c \
+	GetAtomNm.c GetColor.c GetDflt.c GetEventData.c GetFPath.c \
+	GetFProp.c GetGCVals.c GetGeom.c GetHColor.c GetHints.c \
+	GetIFocus.c GetImage.c GetKCnt.c GetMoEv.c GetNrmHint.c \
+	GetPCnt.c GetPntMap.c GetProp.c GetRGBCMap.c GetSOwner.c \
+	GetSSaver.c GetStCmap.c GetTxtProp.c GetWAttrs.c GetWMCMapW.c \
+	GetWMProto.c globals.c GrButton.c GrKeybd.c GrKey.c \
+	GrPointer.c GrServer.c Host.c Iconify.c IfEvent.c imConv.c \
+	ImText16.c ImText.c ImUtil.c InitExt.c InsCmap.c IntAtom.c \
+	KeyBind.c Key.h KeysymStr.c KillCl.c LiHosts.c LiICmaps.c \
+	LiProps.c ListExt.c LoadFont.c LockDis.c locking.c locking.h \
+	LookupCol.c LowerWin.c Macros.c MapRaised.c MapSubs.c \
+	MapWindow.c MaskEvent.c Misc.c ModMap.c MoveWin.c NextEvent.c \
+	OCWrap.c OMWrap.c OpenDis.c ParseCmd.c ParseCol.c ParseGeom.c \
+	PeekEvent.c PeekIfEv.c Pending.c PixFormats.c PmapBgnd.c \
+	PmapBord.c poly.h PolyReg.c PolyTxt16.c PolyTxt.c PropAlloc.c \
+	PutBEvent.c PutImage.c Quarks.c QuBest.c QuColor.c QuColors.c \
+	QuCurShp.c QuExt.c QuKeybd.c QuPntr.c QuStipShp.c QuTextE16.c \
+	QuTextExt.c QuTileShp.c QuTree.c RaiseWin.c RdBitF.c \
+	RecolorC.c ReconfWin.c ReconfWM.c Region.c RegstFlt.c \
+	RepWindow.c RestackWs.c RotProp.c ScrResStr.c SelInput.c \
+	SendEvent.c SetBack.c SetClMask.c SetClOrig.c SetCRects.c \
+	SetDashes.c SetFont.c SetFore.c SetFPath.c SetFunc.c \
+	SetHints.c SetIFocus.c SetLocale.c SetLStyle.c SetNrmHint.c \
+	SetPMask.c SetPntMap.c SetRGBCMap.c SetSOwner.c SetSSaver.c \
+	SetState.c SetStCmap.c SetStip.c SetTile.c SetTSOrig.c \
+	SetTxtProp.c SetWMCMapW.c SetWMProto.c StBytes.c StColor.c \
+	StColors.c StName.c StNColor.c StrKeysym.c StrToText.c Sync.c \
+	Synchro.c Text16.c Text.c TextExt16.c TextExt.c TextToStr.c \
+	TrCoords.c UndefCurs.c UngrabBut.c UngrabKbd.c UngrabKey.c \
+	UngrabPtr.c UngrabSvr.c UninsCmap.c UnldFont.c UnmapSubs.c \
+	UnmapWin.c utlist.h VisUtil.c WarpPtr.c Window.c WinEvent.c \
+	Withdraw.c WMGeom.c WMProps.c WrBitF.c Xatomtype.h Xintatom.h \
+	Xintconn.h XlibAsync.c XlibInt.c Xprivate.h XomGeneric.h \
+	Xresinternal.h Xrm.c XrmI.h $(am__append_1) $(am__append_2) \
+	$(am__append_3) $(am__append_4) $(am__append_6)
 x11datadir = @X11_DATADIR@
 x11data_DATA = XKeysymDB XErrorDB
 EXTRA_DIST = \
@@ -553,7 +554,7 @@ EXTRA_DIST = \
 @XLOCALE_TRUE@USE_I18N_LIBS = $(I18N_LIBS)
 @XCMS_TRUE@USE_XCMS_LIBS = $(XCMS_LIBS)
 @XKB_TRUE@USE_XKB_LIBS = $(XKB_LIBS)
-libX11_la_LDFLAGS = -version-number 6:2:0 -no-undefined
+libX11_la_LDFLAGS = -version-number 6:3:0 -no-undefined
 libX11_la_LIBADD = \
 	$(USE_I18N_LIBS) \
 	$(USE_XCMS_LIBS) \
@@ -745,6 +746,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FreeCols.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FreeCurs.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FreeEData.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FreeEventData.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FreeGC.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FreePix.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/GCMisc.Plo@am__quote@
@@ -752,6 +754,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/GetAtomNm.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/GetColor.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/GetDflt.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/GetEventData.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/GetFPath.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/GetFProp.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/GetGCVals.Plo@am__quote@
diff --git a/libX11/src/MaskEvent.c b/libX11/src/MaskEvent.c
index acd903f9e..14af00cc0 100644
--- a/libX11/src/MaskEvent.c
+++ b/libX11/src/MaskEvent.c
@@ -53,6 +53,10 @@ XMaskEvent (
 	unsigned long qe_serial = 0;
 
         LockDisplay(dpy);
+
+	/* Delete unclaimed cookies */
+	_XFreeEventCookies(dpy);
+
 	prev = NULL;
 	while (1) {
 	    for (qelt = prev ? prev->next : dpy->head;
diff --git a/libX11/src/NextEvent.c b/libX11/src/NextEvent.c
index d4f72e773..1dc8384e4 100644
--- a/libX11/src/NextEvent.c
+++ b/libX11/src/NextEvent.c
@@ -46,11 +46,15 @@ XNextEvent (
 
 	LockDisplay(dpy);
 
+	/* Delete unclaimed cookies */
+	_XFreeEventCookies(dpy);
+
 	if (dpy->head == NULL)
 	    _XReadEvents(dpy);
 	qelt = dpy->head;
 	*event = qelt->event;
 	_XDeq(dpy, NULL, qelt);
+	_XStoreEventCookie(dpy, event);
 	UnlockDisplay(dpy);
 	return 0;
 }
diff --git a/libX11/src/OpenDis.c b/libX11/src/OpenDis.c
index 29ac65c6a..230ae561f 100644
--- a/libX11/src/OpenDis.c
+++ b/libX11/src/OpenDis.c
@@ -790,6 +790,17 @@ _XBigReqHandler(
 
 void _XFreeDisplayStructure(Display *dpy)
 {
+	/* move all cookies in the EQ to the jar, then free them. */
+	if (dpy->qfree) {
+	    _XQEvent *qelt = dpy->qfree;
+	    while (qelt) {
+		if (_XIsEventCookie(dpy, &qelt->event))
+		    _XStoreEventCookie(dpy, &qelt->event);
+		qelt = qelt->next;
+	    }
+        }
+	if (dpy->cookiejar)
+	    _XFreeEventCookies(dpy);
 	while (dpy->ext_procs) {
 	    _XExtension *ext = dpy->ext_procs;
 	    dpy->ext_procs = ext->next;
diff --git a/libX11/src/PeekEvent.c b/libX11/src/PeekEvent.c
index 6eec4a04d..344fe02b2 100644
--- a/libX11/src/PeekEvent.c
+++ b/libX11/src/PeekEvent.c
@@ -43,10 +43,15 @@ XPeekEvent (
 	register Display *dpy,
 	register XEvent *event)
 {
+	XEvent copy;
 	LockDisplay(dpy);
 	if (dpy->head == NULL)
 	    _XReadEvents(dpy);
 	*event = (dpy->head)->event;
+	if (_XCopyEventCookie(dpy, &event->xcookie, &copy.xcookie)) {
+	    _XStoreEventCookie(dpy, &copy);
+	    *event = copy;
+	}
 	UnlockDisplay(dpy);
 	return 1;
 }
diff --git a/libX11/src/PeekIfEv.c b/libX11/src/PeekIfEv.c
index 1d5b1ab9c..5105b6a58 100644
--- a/libX11/src/PeekIfEv.c
+++ b/libX11/src/PeekIfEv.c
@@ -60,7 +60,12 @@ XPeekIfEvent (
 		 prev = qelt, qelt = qelt->next) {
 		if(qelt->qserial_num > qe_serial
 		   && (*predicate)(dpy, &qelt->event, arg)) {
+		    XEvent copy;
 		    *event = qelt->event;
+		    if (_XCopyEventCookie(dpy, &event->xcookie, &copy.xcookie)) {
+			_XStoreEventCookie(dpy, &copy);
+			*event = copy;
+		    }
 		    UnlockDisplay(dpy);
 		    return 0;
 		}
diff --git a/libX11/src/PutBEvent.c b/libX11/src/PutBEvent.c
index eca44f3af..03a9cd266 100644
--- a/libX11/src/PutBEvent.c
+++ b/libX11/src/PutBEvent.c
@@ -41,6 +41,7 @@ _XPutBackEvent (
     register XEvent *event)
 	{
 	register _XQEvent *qelt;
+	XEvent store = *event;
 
 	if (!dpy->qfree) {
     	    if ((dpy->qfree = (_XQEvent *) Xmalloc (sizeof (_XQEvent))) == NULL) {
@@ -48,11 +49,26 @@ _XPutBackEvent (
 	    }
 	    dpy->qfree->next = NULL;
 	}
+
+	/* unclaimed cookie? */
+	if (_XIsEventCookie(dpy, event))
+	{
+	    XEvent copy = {0};
+            /* if not claimed, then just fetch and store again */
+	    if (!event->xcookie.data) {
+		_XFetchEventCookie(dpy, &event->xcookie);
+		store = *event;
+	    } else { /* if claimed, copy, client must free */
+		_XCopyEventCookie(dpy, &event->xcookie, &copy.xcookie);
+		store = copy;
+	    }
+	}
+
 	qelt = dpy->qfree;
 	dpy->qfree = qelt->next;
 	qelt->qserial_num = dpy->next_event_serial_num++;
 	qelt->next = dpy->head;
-	qelt->event = *event;
+	qelt->event = store;
 	dpy->head = qelt;
 	if (dpy->tail == NULL)
 	    dpy->tail = qelt;
diff --git a/libX11/src/WinEvent.c b/libX11/src/WinEvent.c
index c6daf2a81..bcdf98148 100644
--- a/libX11/src/WinEvent.c
+++ b/libX11/src/WinEvent.c
@@ -56,6 +56,10 @@ XWindowEvent (
 	unsigned long qe_serial = 0;
 
         LockDisplay(dpy);
+
+	/* Delete unclaimed cookies */
+	_XFreeEventCookies(dpy);
+
 	prev = NULL;
 	while (1) {
 	    for (qelt = prev ? prev->next : dpy->head;
diff --git a/libX11/src/XlibInt.c b/libX11/src/XlibInt.c
index 320e80800..9505b3f18 100644
--- a/libX11/src/XlibInt.c
+++ b/libX11/src/XlibInt.c
@@ -2258,6 +2258,128 @@ void _XEatData(
 }
 #endif /* !USE_XCB */
 
+/* Cookie jar implementation
+   dpy->cookiejar is a linked list. _XEnq receives the events but leaves
+   them in the normal EQ. _XStoreEvent returns the cookie event (minus
+   data pointer) and adds it to the cookiejar. _XDeq just removes
+   the entry like any other event but resets the data pointer for
+   cookie events (to avoid double-free, the memory is re-used by Xlib).
+
+   _XFetchEventCookie (called from XGetEventData) removes a cookie from the
+   jar. _XFreeEventCookies removes all unclaimed cookies from the jar
+   (called by XNextEvent).
+
+   _XFreeDisplayStructure calls _XFreeEventCookies for each cookie in the
+   normal EQ.
+ */
+
+#include "utlist.h"
+struct stored_event {
+    XGenericEventCookie ev;
+    struct stored_event *prev;
+    struct stored_event *next;
+};
+
+Bool
+_XIsEventCookie(Display *dpy, XEvent *ev)
+{
+    return (ev->xcookie.type == GenericEvent &&
+	    dpy->generic_event_vec[ev->xcookie.extension & 0x7F] != NULL);
+}
+
+/**
+ * Free all events in the event list.
+ */
+void
+_XFreeEventCookies(Display *dpy)
+{
+    struct stored_event **head, *e, *tmp;
+
+    if (!dpy->cookiejar)
+        return;
+
+    head = (struct stored_event**)&dpy->cookiejar;
+
+    DL_FOREACH_SAFE(*head, e, tmp) {
+        XFree(e->ev.data);
+        XFree(e);
+        if (dpy->cookiejar == e)
+            dpy->cookiejar = NULL;
+    }
+}
+
+/**
+ * Add an event to the display's event list. This event must be freed on the
+ * next call to XNextEvent().
+ */
+void
+_XStoreEventCookie(Display *dpy, XEvent *event)
+{
+    XGenericEventCookie* cookie = &event->xcookie;
+    struct stored_event **head, *add;
+
+    if (!_XIsEventCookie(dpy, event))
+        return;
+
+    head = (struct stored_event**)(&dpy->cookiejar);
+
+    add = Xmalloc(sizeof(struct stored_event));
+    if (!add) {
+        ESET(ENOMEM);
+        _XIOError(dpy);
+    }
+    add->ev = *cookie;
+    DL_APPEND(*head, add);
+    cookie->data = NULL; /* don't return data yet, must be claimed */
+}
+
+/**
+ * Return the event with the given cookie and remove it from the list.
+ */
+Bool
+_XFetchEventCookie(Display *dpy, XGenericEventCookie* ev)
+{
+    Bool ret = False;
+    struct stored_event **head, *event;
+    head = (struct stored_event**)&dpy->cookiejar;
+
+    if (!_XIsEventCookie(dpy, (XEvent*)ev))
+        return ret;
+
+    DL_FOREACH(*head, event) {
+        if (event->ev.cookie == ev->cookie &&
+            event->ev.extension == ev->extension &&
+            event->ev.evtype == ev->evtype) {
+            *ev = event->ev;
+            DL_DELETE(*head, event);
+            Xfree(event);
+            ret = True;
+            break;
+        }
+    }
+
+    return ret;
+}
+
+Bool
+_XCopyEventCookie(Display *dpy, XGenericEventCookie *in, XGenericEventCookie *out)
+{
+    Bool ret = False;
+    int extension;
+
+    if (!_XIsEventCookie(dpy, (XEvent*)in) || !out)
+        return ret;
+
+    extension = in->extension & 0x7F;
+
+    if (!dpy->generic_event_copy_vec[extension])
+        return ret;
+
+    ret = ((*dpy->generic_event_copy_vec[extension])(dpy, in, out));
+    out->cookie = ret ? ++dpy->next_cookie  : 0;
+    return ret;
+}
+
 
 /*
  * _XEnq - Place event packets on the display's queue.
@@ -2269,6 +2391,7 @@ void _XEnq(
 	register xEvent *event)
 {
 	register _XQEvent *qelt;
+	int type, extension;
 
 	if ((qelt = dpy->qfree)) {
 		/* If dpy->qfree is non-NULL do this, else malloc a new one. */
@@ -2281,8 +2404,29 @@ void _XEnq(
 		_XIOError(dpy);
 	}
 	qelt->next = NULL;
-	/* go call through display to find proper event reformatter */
-	if ((*dpy->event_vec[event->u.u.type & 0177])(dpy, &qelt->event, event)) {
+
+	type = event->u.u.type & 0177;
+	extension = ((xGenericEvent*)event)->extension;
+	/* If an extension has registerd a generic_event_vec handler, then
+	 * it can handle event cookies. Otherwise, proceed with the normal
+	 * event handlers.
+	 *
+	 * If the generic_event_vec is called, qelt->event is a event cookie
+	 * with the data pointer and the "free" pointer set. Data pointer is
+	 * some memory allocated by the extension.
+	 */
+        if (type == GenericEvent && dpy->generic_event_vec[extension & 0x7F]) {
+	    XGenericEventCookie *cookie = &qelt->event.xcookie;
+	    (*dpy->generic_event_vec[extension & 0x7F])(dpy, cookie, event);
+	    cookie->cookie = ++dpy->next_cookie;
+
+	    qelt->qserial_num = dpy->next_event_serial_num++;
+	    if (dpy->tail)	dpy->tail->next = qelt;
+	    else		dpy->head = qelt;
+
+	    dpy->tail = qelt;
+	    dpy->qlen++;
+	} else if ((*dpy->event_vec[type])(dpy, &qelt->event, event)) {
 	    qelt->qserial_num = dpy->next_event_serial_num++;
 	    if (dpy->tail)	dpy->tail->next = qelt;
 	    else 		dpy->head = qelt;
@@ -2316,6 +2460,13 @@ void _XDeq(
     qelt->next = dpy->qfree;
     dpy->qfree = qelt;
     dpy->qlen--;
+
+    if (_XIsEventCookie(dpy, &qelt->event)) {
+	XGenericEventCookie* cookie = &qelt->event.xcookie;
+	/* dpy->qfree is re-used, reset memory to avoid double free on
+	 * _XFreeDisplayStructure */
+	cookie->data = NULL;
+    }
 }
 
 /*
@@ -2337,6 +2488,34 @@ _XUnknownWireEvent(
 	return(False);
 }
 
+Bool
+_XUnknownWireEventCookie(
+    Display *dpy,	/* pointer to display structure */
+    XGenericEventCookie *re,	/* pointer to where event should be reformatted */
+    xEvent *event)	/* wire protocol event */
+{
+#ifdef notdef
+	fprintf(stderr,
+	    "Xlib: unhandled wire cookie event! extension number = %d, display = %x\n.",
+			((xGenericEvent*)event)->extension, dpy);
+#endif
+	return(False);
+}
+
+Bool
+_XUnknownCopyEventCookie(
+    Display *dpy,	/* pointer to display structure */
+    XGenericEventCookie *in,	/* source */
+    XGenericEventCookie *out)	/* destination */
+{
+#ifdef notdef
+	fprintf(stderr,
+	    "Xlib: unhandled cookie event copy! extension number = %d, display = %x\n.",
+			in->extension, dpy);
+#endif
+	return(False);
+}
+
 /*ARGSUSED*/
 Status
 _XUnknownNativeEvent(
diff --git a/libX11/src/utlist.h b/libX11/src/utlist.h
new file mode 100644
index 000000000..215c2c62e
--- /dev/null
+++ b/libX11/src/utlist.h
@@ -0,0 +1,116 @@
+/*
+Copyright (c) 2007-2009, Troy D. Hanson
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef UTLIST_H
+#define UTLIST_H
+
+#define UTLIST_VERSION 1.7
+
+/* From: http://uthash.sourceforge.net/utlist.html */
+/*
+ * This file contains macros to manipulate singly and doubly-linked lists.
+ *
+ * 1. LL_ macros:  singly-linked lists.
+ * 2. DL_ macros:  doubly-linked lists.
+ * 3. CDL_ macros: circular doubly-linked lists.
+ *
+ * To use singly-linked lists, your structure must have a "next" pointer.
+ * To use doubly-linked lists, your structure must "prev" and "next" pointers.
+ * Either way, the pointer to the head of the list must be initialized to NULL.
+ *
+ * ----------------.EXAMPLE -------------------------
+ * struct item {
+ *      int id;
+ *      struct item *prev, *next;
+ * }
+ *
+ * struct item *list = NULL:
+ *
+ * int main() {
+ *      struct item *item;
+ *      ... allocate and populate item ...
+ *      DL_APPEND(list, item);
+ * }
+ * --------------------------------------------------
+ *
+ * For doubly-linked lists, the append and delete macros are O(1)
+ * For singly-linked lists, append and delete are O(n) but prepend is O(1)
+ * The sort macro is O(n log(n)) for all types of single/double/circular lists.
+ */
+
+
+/******************************************************************************
+ * doubly linked list macros (non-circular)                                   *
+ *****************************************************************************/
+#define DL_PREPEND(head,add)                                                     \
+do {                                                                             \
+ (add)->next = head;                                                             \
+ if (head) {                                                                     \
+   (add)->prev = (head)->prev;                                                   \
+   (head)->prev = (add);                                                         \
+ } else {                                                                        \
+   (add)->prev = (add);                                                          \
+ }                                                                               \
+ (head) = (add);                                                                 \
+} while (0)
+
+#define DL_APPEND(head,add)                                                      \
+do {                                                                             \
+  if (head) {                                                                    \
+      (add)->prev = (head)->prev;                                                \
+      (head)->prev->next = (add);                                                \
+      (head)->prev = (add);                                                      \
+      (add)->next = NULL;                                                        \
+  } else {                                                                       \
+      (head)=(add);                                                              \
+      (head)->prev = (head);                                                     \
+      (head)->next = NULL;                                                       \
+  }                                                                              \
+} while (0);
+
+#define DL_DELETE(head,del)                                                      \
+do {                                                                             \
+  if ((del)->prev == (del)) {                                                    \
+      (head)=NULL;                                                               \
+  } else if ((del)==(head)) {                                                    \
+      (del)->next->prev = (del)->prev;                                           \
+      (head) = (del)->next;                                                      \
+  } else {                                                                       \
+      (del)->prev->next = (del)->next;                                           \
+      if ((del)->next) {                                                         \
+          (del)->next->prev = (del)->prev;                                       \
+      } else {                                                                   \
+          (head)->prev = (del)->prev;                                            \
+      }                                                                          \
+  }                                                                              \
+} while (0);
+
+
+#define DL_FOREACH(head,el)                                                      \
+    for(el=head;el;el=el->next)
+
+#define DL_FOREACH_SAFE(head,el,tmp)                                             \
+    for(el=head,tmp=el->next;el;el=tmp,tmp=(el) ? (el->next) : NULL)
+
+#endif /* UTLIST_H */
+
-- 
cgit v1.2.3