[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

xorg-server: Changes to 'ubuntu'



 debian/changelog      |   17 ++++++-----------
 debian/patches/series |    2 +-
 2 files changed, 7 insertions(+), 12 deletions(-)

New commits:
commit ea9024e0e2359df7d7bcddd4f264e36ea0619bce
Author: Christopher James Halse Rogers <christopher.halse.rogers@canonical.com>
Date:   Fri Aug 13 00:36:05 2010 +1000

    Add Gesture support patches

diff --git a/debian/changelog b/debian/changelog
index 5c554c5..20c2ff7 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,13 @@
+xorg-server (2:1.8.99.905-1ubuntu2) maverick; urgency=low
+  
+    * Add in gesture support (LP: #616678)
+      - add debian/patches/203_gestures-extension.patch
+        and debian/patches/202_xf86CoordinationsToWindows.patch
+      - debian/rules:
+        - add configure option to enable gesture
+
+ -- Chase Douglas <chase.douglas@ubuntu.com>  Mon, 09 Aug 2010 14:33:40 +0000
+
 xorg-server (2:1.8.99.905-1ubuntu1) maverick; urgency=low
 
   * Merge from (unreleased) Debian experimental.  Remaining Ubuntu changes:
diff --git a/debian/patches/202_xf86CoordinationsToWindows.patch b/debian/patches/202_xf86CoordinationsToWindows.patch
new file mode 100644
index 0000000..6c2d1f1
--- /dev/null
+++ b/debian/patches/202_xf86CoordinationsToWindows.patch
@@ -0,0 +1,103 @@
+From 0e750eff9ba7987ef31acaabd3ef771bfd2e2ce5 Mon Sep 17 00:00:00 2001
+From: Chase Douglas <chase.douglas@canonical.com>
+Date: Wed, 21 Jul 2010 12:00:04 +0200
+Subject: [PATCH 1/5] Add XFixesCoordinatesToWindow request
+
+---
+ dix/events.c                   |   48 ++++++++++++++++++++++++++++++++++++++++
+ hw/xfree86/common/xf86Xinput.c |    7 +++++
+ hw/xfree86/common/xf86Xinput.h |    2 +
+ include/events.h               |    3 ++
+ 4 files changed, 60 insertions(+), 0 deletions(-)
+
+--- xorg-server-debian.orig/dix/events.c
++++ xorg-server-debian/dix/events.c
+@@ -5840,3 +5840,47 @@
+     return FALSE;
+ }
+ 
++WindowPtr
++CoordinatesToWindow(int x, int y, int screen)
++{
++    WindowPtr pWin;
++    WindowPtr ret = NullWindow;
++    BoxRec box;
++
++    pWin = screenInfo.screens[screen]->root;
++    while (pWin)
++    {
++	if ((pWin->mapped) &&
++	    (x >= pWin->drawable.x - wBorderWidth (pWin)) &&
++	    (x < pWin->drawable.x + (int)pWin->drawable.width +
++	     wBorderWidth(pWin)) &&
++	    (y >= pWin->drawable.y - wBorderWidth (pWin)) &&
++	    (y < pWin->drawable.y + (int)pWin->drawable.height +
++	     wBorderWidth (pWin))
++	    /* When a window is shaped, a further check
++	     * is made to see if the point is inside
++	     * borderSize
++	     */
++	    && (!wBoundingShape(pWin) || PointInBorderSize(pWin, x, y))
++	    && (!wInputShape(pWin) ||
++		RegionContainsPoint(wInputShape(pWin),
++				    x - pWin->drawable.x,
++				    y - pWin->drawable.y, &box))
++#ifdef ROOTLESS
++    /* In rootless mode windows may be offscreen, even when
++     * they're in X's stack. (E.g. if the native window system
++     * implements some form of virtual desktop system).
++     */
++		&& !pWin->rootlessUnhittable
++#endif
++	    )
++	{
++            ret = pWin;
++            pWin = pWin->firstChild;
++        }
++        else
++            pWin = pWin->nextSib;
++    }
++    return ret;
++}
++
+--- xorg-server-debian.orig/hw/xfree86/common/xf86Xinput.c
++++ xorg-server-debian/hw/xfree86/common/xf86Xinput.c
+@@ -1362,4 +1362,10 @@
+     EnableDevice(dev, TRUE);
+ }
+ 
++WindowPtr
++xf86CoordinatesToWindow(int x, int y, int screen)
++{
++    return CoordinatesToWindow(x, y, screen);
++}
++
+ /* end of xf86Xinput.c */
+--- xorg-server-debian.orig/hw/xfree86/common/xf86Xinput.h
++++ xorg-server-debian/hw/xfree86/common/xf86Xinput.h
+@@ -212,6 +212,8 @@
+ extern _X_EXPORT void xf86CollectInputOptions(InputInfoPtr pInfo, const char **defaultOpts,
+ 			     pointer extraOpts);
+ 
++extern _X_EXPORT WindowPtr xf86CoordinatesToWindow(int x, int y, int screen);
++
+ 
+ /* Legacy hatred */
+ #define SendCoreEvents 59
+--- xorg-server-debian.orig/include/events.h
++++ xorg-server-debian/include/events.h
+@@ -24,6 +24,7 @@
+ 
+ #ifndef EVENTS_H
+ #define EVENTS_H
++
+ typedef struct _DeviceEvent DeviceEvent;
+ typedef struct _DeviceChangedEvent DeviceChangedEvent;
+ #if XFreeXDGA
+@@ -35,4 +36,6 @@
+ #endif
+ typedef union _InternalEvent InternalEvent;
+ 
++extern WindowPtr CoordinatesToWindow(int x, int y, int screen);
++
+ #endif
diff --git a/debian/patches/203_gestures-extension.patch b/debian/patches/203_gestures-extension.patch
new file mode 100644
index 0000000..d786914
--- /dev/null
+++ b/debian/patches/203_gestures-extension.patch
@@ -0,0 +1,1327 @@
+From 2b3600e55fdc8270181a1e818ad1c607c7406b16 Mon Sep 17 00:00:00 2001
+From: Chase Douglas <chase.douglas@canonical.com>
+Date: Sat, 24 Jul 2010 06:02:59 -0400
+Subject: [PATCH] Gesture Extension
+
+---
+ Makefile.am                 |    5 +
+ configure.ac                |   26 ++-
+ dix/window.c                |    7 +
+ gesture/Makefile.am         |   10 +
+ gesture/gesture.c           |  421 +++++++++++++++++++++++++++++++++++++++++++
+ gesture/gesture.h           |   77 ++++++++
+ gesture/gestureint.h        |   49 +++++
+ gesture/gestureproto.h      |  141 +++++++++++++++
+ gesture/init.c              |  282 +++++++++++++++++++++++++++++
+ include/dix-config.h.in     |    3 +
+ include/protocol-versions.h |    4 +
+ include/windowstr.h         |   10 +
+ mi/miinitext.c              |   15 ++
+ os/utils.c                  |    3 +
+ 14 files changed, 1045 insertions(+), 8 deletions(-)
+ create mode 100644 gesture/Makefile.am
+ create mode 100644 gesture/gesture.c
+ create mode 100644 gesture/gesture.h
+ create mode 100644 gesture/gestureint.h
+ create mode 100644 gesture/gestureproto.h
+ create mode 100644 gesture/init.c
+
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -17,6 +17,10 @@ if RECORD
+ RECORD_DIR=record
+ endif
+ 
++if GESTURES
++GESTURE_DIR=gesture
++endif
++
+ SUBDIRS = \
+ 	doc \
+ 	include \
+@@ -37,6 +41,7 @@ SUBDIRS = \
+ 	$(COMPOSITE_DIR) \
+ 	$(GLX_DIR) \
+ 	exa \
++	$(GESTURE_DIR) \
+ 	config \
+ 	hw \
+ 	test
+--- a/configure.ac
++++ b/configure.ac
+@@ -602,6 +602,8 @@ AC_ARG_ENABLE(visibility,     AC_HELP_ST
+ AC_ARG_ENABLE(pc98,     	AC_HELP_STRING([--enable-pc98], [Enable PC98 support in Xorg (default: auto)]),
+ 				[SUPPORT_PC98=$enableval],
+ 				[SUPPORT_PC98=auto])
++AC_ARG_ENABLE(gestures,         AC_HELP_STRING([--enable-gestures], [Enable gesture support (default: disabled)]),
++				[GESTURES=$enableval])
+ 
+ dnl GLX build options
+ AC_ARG_WITH(dri-driver-path,  AS_HELP_STRING([--with-dri-driver-path=PATH], [Path to DRI drivers (default: ${libdir}/dri)]),
+@@ -1360,6 +1362,13 @@ MIEXT_SHADOW_INC='-I$(top_srcdir)/miext/
+ MIEXT_SHADOW_LIB='$(top_builddir)/miext/shadow/libshadow.la'
+ CORE_INCS='-I$(top_srcdir)/include -I$(top_builddir)/include'
+ 
++AM_CONDITIONAL(GESTURES, [test "x$GESTURES" = "xyes"])
++if test "x$GESTURES" = xyes; then
++	AC_DEFINE(GESTURES, 1, [Enable gesture support])
++	GESTURE_LIB='$(top_builddir)/gesture/libgesture.la'
++	GESTURE_INC='-I$(top_srcdir)/gesture'
++fi
++
+ # SHA1 hashing
+ AC_ARG_WITH([sha1],
+             [AS_HELP_STRING([--with-sha1=libc|libmd|libgcrypt|libcrypto|libsha1|CommonCrypto|nettle],
+@@ -1507,7 +1516,7 @@ AC_EGREP_CPP([I_AM_SVR4],[
+ AC_DEFINE([SVR4],1,[Define to 1 on systems derived from System V Release 4])
+ AC_MSG_RESULT([yes])], AC_MSG_RESULT([no]))
+ 
+-XSERVER_CFLAGS="$XSERVER_CFLAGS $CORE_INCS $XEXT_INC $COMPOSITE_INC $DAMAGE_INC $FIXES_INC $XI_INC $MI_INC $MIEXT_SHADOW_INC $MIEXT_LAYER_INC $MIEXT_DAMAGE_INC $RENDER_INC $RANDR_INC $FB_INC"
++XSERVER_CFLAGS="$XSERVER_CFLAGS $CORE_INCS $XEXT_INC $COMPOSITE_INC $DAMAGE_INC $FIXES_INC $XI_INC $MI_INC $MIEXT_SHADOW_INC $MIEXT_LAYER_INC $MIEXT_DAMAGE_INC $RENDER_INC $RANDR_INC $FB_INC $GESTURE_INC"
+ 
+ dnl ---------------------------------------------------------------------------
+ dnl DDX section.
+@@ -1520,7 +1529,7 @@ AC_MSG_RESULT([$XVFB])
+ AM_CONDITIONAL(XVFB, [test "x$XVFB" = xyes])
+ 
+ if test "x$XVFB" = xyes; then
+-	XVFB_LIBS="$FB_LIB $FIXES_LIB $XEXT_LIB $DBE_LIB $RECORD_LIB $GLX_LIBS $RANDR_LIB $RENDER_LIB $DAMAGE_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB"
++	XVFB_LIBS="$FB_LIB $FIXES_LIB $XEXT_LIB $DBE_LIB $RECORD_LIB $GLX_LIBS $RANDR_LIB $RENDER_LIB $DAMAGE_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $GESTURE_LIB"
+ 	XVFB_SYS_LIBS="$XVFBMODULES_LIBS $GLX_SYS_LIBS"
+ 	AC_SUBST([XVFB_LIBS])
+ 	AC_SUBST([XVFB_SYS_LIBS])
+@@ -1541,7 +1550,7 @@ if test "x$XNEST" = xyes; then
+ 	if test "x$have_xnest" = xno; then
+ 		AC_MSG_ERROR([Xnest build explicitly requested, but required modules not found.])
+ 	fi
+-	XNEST_LIBS="$FB_LIB $FIXES_LIB $MI_LIB $XEXT_LIB $DBE_LIB $RECORD_LIB $GLX_LIBS $RANDR_LIB $RENDER_LIB $DAMAGE_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $DIX_LIB $MAIN_LIB $OS_LIB"
++	XNEST_LIBS="$FB_LIB $FIXES_LIB $MI_LIB $XEXT_LIB $DBE_LIB $RECORD_LIB $GLX_LIBS $RANDR_LIB $RENDER_LIB $DAMAGE_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $DIX_LIB $MAIN_LIB $OS_LIB $GESTURE_LIB"
+ 	XNEST_SYS_LIBS="$XNESTMODULES_LIBS $GLX_SYS_LIBS"
+ 	AC_SUBST([XNEST_LIBS])
+ 	AC_SUBST([XNEST_SYS_LIBS])
+@@ -1569,7 +1578,7 @@ if test "x$XORG" = xyes; then
+ 	XORG_OSINCS='-I$(top_srcdir)/hw/xfree86/os-support -I$(top_srcdir)/hw/xfree86/os-support/bus -I$(top_srcdir)/os'
+ 	XORG_INCS="$XORG_DDXINCS $XORG_OSINCS"
+ 	XORG_CFLAGS="$XORGSERVER_CFLAGS -DHAVE_XORG_CONFIG_H"
+-	XORG_LIBS="$COMPOSITE_LIB $FIXES_LIB $XEXTXORG_LIB $GLX_LIBS $RANDR_LIB $RENDER_LIB $DAMAGE_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB"
++	XORG_LIBS="$COMPOSITE_LIB $FIXES_LIB $XEXTXORG_LIB $GLX_LIBS $RANDR_LIB $RENDER_LIB $DAMAGE_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $GESTURE_LIB"
+ 
+ 	dnl ==================================================================
+ 	dnl symbol visibility
+@@ -1905,7 +1914,7 @@ if test "x$XWIN" = xyes; then
+ 			XWIN_SYS_LIBS=-lwinsock2
+ 			;;
+ 	esac
+-	XWIN_LIBS="$FB_LIB $MI_LIB $FIXES_LIB $XEXT_LIB $RANDR_LIB $RENDER_LIB $DBE_LIB $RECORD_LIB $GLX_LIBS $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $DAMAGE_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $OS_LIB"
++	XWIN_LIBS="$FB_LIB $MI_LIB $FIXES_LIB $XEXT_LIB $RANDR_LIB $RENDER_LIB $DBE_LIB $RECORD_LIB $GLX_LIBS $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $DAMAGE_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $OS_LIB $GESTURE_LIB"
+ 	XWIN_SYS_LIBS="$XWIN_SYS_LIBS $XWINMODULES_LIBS"
+ 	AC_SUBST(XWIN_LIBS)
+ 	AC_SUBST(XWIN_SERVER_NAME)
+@@ -1935,7 +1944,7 @@ if test "x$XQUARTZ" = xyes; then
+ 	AC_DEFINE(XQUARTZ,1,[Have Quartz])
+ 	AC_DEFINE(ROOTLESS,1,[Build Rootless code])
+ 
+-	DARWIN_LIBS="$MI_LIB $OS_LIB $DIX_LIB $MAIN_LIB $FB_LIB $FIXES_LIB $XEXT_LIB $DBE_LIB $RECORD_LIB $RANDR_LIB $RENDER_LIB $DAMAGE_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $XPSTUBS_LIB"
++	DARWIN_LIBS="$MI_LIB $OS_LIB $DIX_LIB $MAIN_LIB $FB_LIB $FIXES_LIB $XEXT_LIB $DBE_LIB $RECORD_LIB $RANDR_LIB $RENDER_LIB $DAMAGE_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $XPSTUBS_LIB $GESTURE_LIB"
+ 	AC_SUBST([DARWIN_LIBS])
+ 
+ 	AC_CHECK_LIB([Xplugin],[xp_init],[:])
+@@ -1996,7 +2005,7 @@ if test "x$DMX" = xyes; then
+ 	fi
+ 	DMX_INCLUDES="$XEXT_INC $RENDER_INC $RECORD_INC"
+ 	XDMX_CFLAGS="$DMXMODULES_CFLAGS"
+-	XDMX_LIBS="$FB_LIB $MI_LIB $RENDER_LIB $RECORD_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $MIEXT_SHADOW_LIB $MIEXT_DAMAGE_LIB $XEXT_LIB $MAIN_LIB $DIX_LIB $OS_LIB $FIXES_LIB"
++	XDMX_LIBS="$FB_LIB $MI_LIB $RENDER_LIB $RECORD_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $MIEXT_SHADOW_LIB $MIEXT_DAMAGE_LIB $XEXT_LIB $MAIN_LIB $DIX_LIB $OS_LIB $FIXES_LIB $GESTURE_LIB"
+ 	XDMX_SYS_LIBS="$DMXMODULES_LIBS"
+ 	AC_SUBST([XDMX_CFLAGS])
+ 	AC_SUBST([XDMX_LIBS])
+@@ -2104,7 +2113,7 @@ if test "$KDRIVE" = yes; then
+     
+     KDRIVE_CFLAGS="$XSERVER_CFLAGS -DHAVE_KDRIVE_CONFIG_H $TSLIB_CFLAGS"
+ 
+-    KDRIVE_PURE_LIBS="$FB_LIB $MI_LIB $FIXES_LIB $XEXT_LIB $DBE_LIB $RECORD_LIB $GLX_LIBS $RANDR_LIB $RENDER_LIB $DAMAGE_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $OS_LIB"
++    KDRIVE_PURE_LIBS="$FB_LIB $MI_LIB $FIXES_LIB $XEXT_LIB $DBE_LIB $RECORD_LIB $GLX_LIBS $RANDR_LIB $RENDER_LIB $DAMAGE_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $OS_LIB $GESTURE_LIB"
+     KDRIVE_LIB='$(top_builddir)/hw/kdrive/src/libkdrive.la'
+     case $host_os in
+ 	*linux*)
+@@ -2215,6 +2224,7 @@ Xext/Makefile
+ Xi/Makefile
+ xfixes/Makefile
+ exa/Makefile
++gesture/Makefile
+ hw/Makefile
+ hw/xfree86/Makefile
+ hw/xfree86/common/Makefile
+--- a/dix/window.c
++++ b/dix/window.c
+@@ -397,6 +397,9 @@ CreateRootWindow(ScreenPtr pScreen)
+     pWin->optional->deviceCursors = NULL;
+     pWin->optional->colormap = pScreen->defColormap;
+     pWin->optional->visual = pScreen->rootVisual;
++#ifdef GESTURES
++    pWin->optional->gestureMasks = NULL;
++#endif
+ 
+     pWin->nextSib = NullWindow;
+ 
+@@ -3397,6 +3400,10 @@ CheckWindowOptionalNeed (WindowPtr w)
+             pNode = pNode->next;
+         }
+     }
++#ifdef GESTURES
++    if (optional->gestureMasks != NULL)
++        return;
++#endif
+ 
+     parentOptional = FindWindowWithOptional(w)->optional;
+     if (optional->visual != parentOptional->visual)
+@@ -3440,6 +3447,9 @@ MakeWindowOptional (WindowPtr pWin)
+     optional->inputShape = NULL;
+     optional->inputMasks = NULL;
+     optional->deviceCursors = NULL;
++#ifdef GESTURES
++    optional->gestureMasks = NULL;
++#endif
+ 
+     parentOptional = FindWindowWithOptional(pWin)->optional;
+     optional->visual = parentOptional->visual;
+--- /dev/null
++++ b/gesture/Makefile.am
+@@ -0,0 +1,10 @@
++noinst_LTLIBRARIES = libgesture.la
++
++AM_CFLAGS = $(DIX_CFLAGS)
++
++libgesture_la_SOURCES = 	\
++	init.c			\
++	gesture.c		\
++	gesture.h
++
++sdk_HEADERS = gesture.h
+--- /dev/null
++++ b/gesture/gesture.c
+@@ -0,0 +1,430 @@
++/*
++ * Copyright © 2010 Canonical, Ltd.
++ *
++ * 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.
++ *
++ * Authors: Chase Douglas <chase.douglas@canonical.com>
++ *
++ */
++
++#include "windowstr.h"
++#include "gestureint.h"
++
++int
++SProcGestureQueryVersion(ClientPtr client)
++{
++    char n;
++
++    REQUEST(GestureQueryVersionReq);
++    swaps(&stuff->length, n);
++    REQUEST_AT_LEAST_SIZE(GestureQueryVersionReq);
++    swaps(&stuff->major_version, n);
++    swaps(&stuff->minor_version, n);
++    return (ProcGestureQueryVersion(client));
++}
++
++GestureExtensionVersion GestureVersion;
++/**
++ * Return the supported Gesture version.
++ *
++ * Saves the version the client claims to support as well, for future
++ * reference.
++ */
++int
++ProcGestureQueryVersion(ClientPtr client)
++{
++    GestureQueryVersionReply rep;
++    GestureClientPtr gestureClient;
++    int major, minor;
++    unsigned int sversion, cversion;
++
++    REQUEST(GestureQueryVersionReq);
++    REQUEST_SIZE_MATCH(GestureQueryVersionReq);
++
++    gestureClient = dixLookupPrivate(&client->devPrivates,
++                                     &GestureClientPrivateKeyRec);
++
++    sversion = GestureVersion.major_version * 1000 + GestureVersion.minor_version;
++    cversion = stuff->major_version * 1000 + stuff->minor_version;
++
++    if (sversion > cversion)
++    {
++        major = stuff->major_version;
++        minor = stuff->minor_version;
++    } else
++    {
++        major = GestureVersion.major_version;
++        minor = GestureVersion.minor_version;
++    }
++
++    gestureClient->major_version = major;
++    gestureClient->minor_version = minor;
++
++    memset(&rep, 0, sizeof(GestureQueryVersionReply));
++    rep.repType = X_Reply;
++    rep.RepType = X_GestureQueryVersion;
++    rep.length = 0;
++    rep.sequenceNumber = client->sequence;
++    rep.major_version = major;
++    rep.minor_version = minor;
++
++    WriteReplyToClient(client, sizeof(GestureQueryVersionReply), &rep);
++
++    return Success;
++}
++
++void
++SRepGestureQueryVersion(ClientPtr client, int size, GestureQueryVersionReply *rep)
++{
++    char n;
++    swaps(&rep->sequenceNumber, n);
++    swapl(&rep->length, n);
++    swaps(&rep->major_version, n);
++    swaps(&rep->minor_version, n);
++    WriteToClient(client, size, (char *)rep);
++}
++
++static Bool
++MakeGestureMasks(WindowPtr pWin)
++{
++    struct _GestureMasks *masks;
++
++    masks = calloc(1, sizeof(struct _GestureMasks));
++    if (!masks)
++        return FALSE;
++    pWin->optional->gestureMasks = masks;
++    return TRUE;
++}
++
++static int
++AddGestureClient(WindowPtr pWin, ClientPtr client)
++{
++    GestureClientsPtr others;
++
++    if (!pWin->optional && !MakeWindowOptional(pWin))
++        return BadAlloc;
++    others = calloc(1, sizeof(GestureClients));
++    if (!others)
++        return BadAlloc;
++    if (!pWin->optional->gestureMasks && !MakeGestureMasks(pWin))
++        return BadAlloc;
++    others->resource = FakeClientID(client->index);
++    others->next = pWin->optional->gestureMasks->clients;
++    pWin->optional->gestureMasks->clients = others;
++    if (!AddResource(others->resource, RT_GESTURECLIENT, (pointer) pWin))
++        return BadAlloc;
++    return Success;
++}
++
++/**
++ * Check the given mask (in len bytes) for invalid mask bits.
++ * Invalid mask bits are any bits above GestureLastEvent.
++ *
++ * @return BadValue if at least one invalid bit is set or Success otherwise.
++ */
++static int
++GestureCheckInvalidMaskBits(unsigned char *mask, int len)
++{
++    if (len >= GESTUREMASKSIZE)
++    {
++        int i;
++        for (i = GESTURELASTEVENT + 1; i < len * 8; i++)
++            if (BitIsOn(mask, i))
++                return BadValue;
++    }
++
++    return Success;
++}
++
++int
++SProcGestureSelectEvents(ClientPtr client)
++{
++    char n;
++    int i;
++
++    REQUEST(GestureSelectEventsReq);
++    swaps(&stuff->length, n);
++    REQUEST_AT_LEAST_SIZE(GestureSelectEventsReq);
++    swapl(&stuff->window, n);
++    swaps(&stuff->mask.device_id, n);
++    swaps(&stuff->mask.mask_len, n);
++
++    for (i = 0; i < stuff->mask.mask_len; i++)
++        swapl(((uint32_t *)(stuff + 1)) + i, n);
++
++    return (ProcGestureSelectEvents(client));
++}
++
++static void
++RecalculateGestureDeliverableEvents(WindowPtr win)
++{
++    GestureClientsPtr others;
++    int i;
++
++    if (!win->optional || !wGestureMasks(win))
++        return;
++
++    memset(&wGestureMasks(win)->mask, 0, sizeof(wGestureMasks(win)->mask));
++
++    for (others = wGestureMasks(win)->clients; others; others = others->next)
++        for (i = 0; i < sizeof(others->gestureMask) * 8; i++)
++            if (BitIsOn(&others->gestureMask, i))
++                SetBit(wGestureMasks(win)->mask, i % (GESTURELASTEVENT + 1));
++}
++
++static int
++GestureSetEventMask(DeviceIntPtr dev, WindowPtr win, ClientPtr client,
++                    unsigned int len, unsigned char* mask)
++{
++    GestureMasks *masks;
++    GestureClientsPtr others = NULL;
++
++    masks = wGestureMasks(win);
++    if (masks)
++    {
++        for (others = masks->clients; others;
++             others = others->next) {
++            if (SameClient(others, client)) {
++                memset(others->gestureMask[dev->id], 0,
++                       sizeof(others->gestureMask[dev->id]));
++                break;
++            }
++        }
++    }
++
++    len = min(len, sizeof(others->gestureMask[dev->id]));
++
++    if (len && !others)
++    {
++        if (AddGestureClient(win, client) != Success)
++            return BadAlloc;
++        masks = wGestureMasks(win);
++        others = masks->clients;
++    }
++
++    if (others)
++        memset(others->gestureMask[dev->id], 0,
++               sizeof(others->gestureMask[dev->id]));
++
++    if (len)
++        memcpy(others->gestureMask[dev->id], mask, len);
++
++    RecalculateGestureDeliverableEvents(win);
++
++    return Success;
++}
++
++int
++ProcGestureSelectEvents(ClientPtr client)
++{
++    int rc;
++    WindowPtr win;
++    DeviceIntPtr dev;
++    DeviceIntRec dummy;
++
++    REQUEST(GestureSelectEventsReq);
++    REQUEST_AT_LEAST_SIZE(GestureSelectEventsReq);
++
++    if (sizeof(GestureSelectEventsReq) + stuff->mask.mask_len * 4 >
++        stuff->length * 4)
++        return BadLength;
++
++    rc = dixLookupWindow(&win, stuff->window, client, DixReceiveAccess);
++    if (rc != Success)
++        return rc;
++
++    if (GestureCheckInvalidMaskBits((unsigned char*)(stuff + 1),
++                                    stuff->mask.mask_len * 4) != Success)
++        return BadValue;
++
++    if (stuff->mask.device_id == GestureAllDevices)
++    {
++        dummy.id = stuff->mask.device_id;
++        dev = &dummy;
++    } else {
++        rc = dixLookupDevice(&dev, stuff->mask.device_id, client, DixUseAccess);
++        if (rc != Success)
++            return rc;
++    }
++
++    if (GestureSetEventMask(dev, win, client, stuff->mask.mask_len * 4,
++                            (unsigned char*)(stuff + 1)) != Success)
++        return BadAlloc;
++
++    return Success;
++}
++
++int
++SProcGestureGetSelectedEvents(ClientPtr client)
++{
++    char n;
++
++    REQUEST(GestureGetSelectedEventsReq);
++    swaps(&stuff->length, n);
++    REQUEST_SIZE_MATCH(GestureGetSelectedEventsReq);
++    swapl(&stuff->window, n);
++
++    return (ProcGestureGetSelectedEvents(client));
++}
++
++int
++ProcGestureGetSelectedEvents(ClientPtr client)
++{
++    int rc, i;
++    WindowPtr win;
++    char n;
++    char *buffer = NULL;
++    GestureGetSelectedEventsReply reply;
++    GestureMasks *masks;
++    GestureClientsPtr others = NULL;
++    GestureEventMask *evmask = NULL;
++    DeviceIntPtr dev;
++
++    REQUEST(GestureGetSelectedEventsReq);
++    REQUEST_SIZE_MATCH(GestureGetSelectedEventsReq);
++
++    rc = dixLookupWindow(&win, stuff->window, client, DixGetAttrAccess);
++    if (rc != Success)
++        return rc;
++
++    reply.repType = X_Reply;
++    reply.RepType = X_GestureGetSelectedEvents;
++    reply.length = 0;
++    reply.sequenceNumber = client->sequence;
++    reply.num_masks = 0;
++
++    masks = wGestureMasks(win);
++    if (masks)
++    {
++        for (others = masks->clients; others; others = others->next) {
++            if (SameClient(others, client)) {
++                break;
++            }
++        }
++    }
++
++    if (!others)
++    {
++        WriteReplyToClient(client, sizeof(GestureGetSelectedEventsReply), &reply);
++        return Success;
++    }
++
++    buffer = calloc(MAXDEVICES, sizeof(GestureEventMask) + pad_to_int32(GESTUREMASKSIZE));
++    if (!buffer)
++        return BadAlloc;
++
++    evmask = (GestureEventMask*)buffer;
++    for (i = 0; i < MAXDEVICES; i++)
++    {
++        int j;
++        unsigned char *devmask = others->gestureMask[i];
++
++        if (i > 2)
++        {
++            rc = dixLookupDevice(&dev, i, client, DixGetAttrAccess);
++            if (rc != Success)
++                continue;
++        }
++
++
++        for (j = GESTUREMASKSIZE - 1; j >= 0; j--)
++        {
++            if (devmask[j] != 0)
++            {
++                int mask_len = (j + 4)/4; /* j is an index, hence + 4, not + 3 */
++                evmask->device_id = i;
++                evmask->mask_len = mask_len;
++                reply.num_masks++;
++                reply.length += sizeof(GestureEventMask)/4 + evmask->mask_len;
++
++                if (client->swapped)
++                {
++                    swaps(&evmask->device_id, n);
++                    swaps(&evmask->mask_len, n);
++                }
++
++                memcpy(&evmask[1], devmask, j + 1);
++                evmask = (GestureEventMask*)((char*)evmask +
++                           sizeof(GestureEventMask) + mask_len * 4);
++                break;
++            }
++        }
++    }
++
++    WriteReplyToClient(client, sizeof(GestureGetSelectedEventsReply), &reply);
++
++    if (reply.num_masks)
++        WriteToClient(client, reply.length * 4, buffer);
++
++    free(buffer);
++    return Success;
++}
++
++void
++SRepGestureGetSelectedEvents(ClientPtr client,
++                             int len, GestureGetSelectedEventsReply *rep)
++{
++    char n;
++
++    swaps(&rep->sequenceNumber, n);
++    swapl(&rep->length, n);
++    swaps(&rep->num_masks, n);
++    WriteToClient(client, len, (char *)rep);
++}
++
++int
++GestureClientGone(WindowPtr pWin, XID id)
++{
++    GestureClientsPtr other, prev;
++
++    if (!wGestureMasks(pWin))
++        return (Success);
++    prev = 0;
++    for (other = wGestureMasks(pWin)->clients; other;
++         other = other->next) {
++        if (other->resource == id) {
++            if (prev) {
++                prev->next = other->next;
++                free(other);
++            } else if (!(other->next)) {
++                free(wGestureMasks(pWin));
++                pWin->optional->gestureMasks = (GestureMasks *) NULL;
++                CheckWindowOptionalNeed(pWin);
++                free(other);
++            } else {
++                wGestureMasks(pWin)->clients = other->next;
++                free(other);
++            }
++            RecalculateGestureDeliverableEvents(pWin);
++            return (Success);
++        }
++        prev = other;
++    }
++    FatalError("client not on device event list");
++}
++
++void
++DeleteWindowFromGestureEvents(WindowPtr pWin)
++{
++    struct _GestureMasks *gestureMasks;
++
++    while ((gestureMasks = wGestureMasks(pWin)) != 0)
++        FreeResource(gestureMasks->clients->resource, RT_NONE);
++}
+--- /dev/null
++++ b/gesture/gesture.h
+@@ -0,0 +1,78 @@
++/*
++ * Copyright © 2010 Canonical, Ltd.
++ *
++ * 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.
++ *
++ * Authors: Chase Douglas <chase.douglas@canonical.com>
++ *
++ */
++
++#ifndef _GESTURE_H_
++#define _GESTURE_H_
++
++#ifdef HAVE_DIX_CONFIG_H
++#include <dix-config.h>
++#endif
++
++#include "inputstr.h"
++
++/* This is the last Gesture event supported by the server. If you add
++ * events to the protocol, the server will not support these events until
++ * this number here is bumped.
++ */
++#define GESTURELASTEVENT     63
++#define GESTUREMASKSIZE      (GESTURELASTEVENT/8 + 1) /* no of bits for masks */
++
++extern _X_EXPORT int GestureReqCode;
++
++/**
++ * Attached to the devPrivates of each client. Specifies the version number as
++ * supported by the client.
++ */
++typedef struct _GestureClientRec {
++        int major_version;
++        int minor_version;
++} GestureClientRec, *GestureClientPtr;
++
++typedef struct _GestureClients *GestureClientsPtr;
++
++/**
++ * This struct stores the Gesture event mask for each client.
++ *
++ * Each window that has events selected has at least one of these masks. If
++ * multiple client selected for events on the same window, these masks are in
++ * a linked list.
++ */
++typedef struct _GestureClients {
++    GestureClientsPtr  next; /**< Pointer to the next mask */
++    XID                resource; /**< id for putting into resource manager */
++    /** Gesture event masks. One per device, each bit is a mask of (1 << type) */
++    unsigned char      gestureMask[EMASKSIZE][GESTUREMASKSIZE];
++} GestureClients;
++
++typedef struct _GestureMasks {
++    GestureClientsPtr   clients;
++    unsigned char       mask[GESTUREMASKSIZE];
++} GestureMasks;
++
++extern int GestureClientGone(WindowPtr pWin, XID id);
++extern void DeleteWindowFromGestureEvents(WindowPtr pWin);
++
++#endif /* _GESTURE_H_ */
+--- /dev/null
++++ b/gesture/gestureint.h
+@@ -0,0 +1,49 @@
++/*
++ * Copyright © 2010 Canonical, Ltd.
++ *
++ * 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.
++ *
++ * Authors: Chase Douglas <chase.douglas@canonical.com>
++ *
++ */
++
++#ifndef _GESTUREINT_H_
++#define _GESTUREINT_H_
++
++#include "gestureproto.h"
++
++typedef struct {
++        short   major_version;
++        short   minor_version;
++} GestureExtensionVersion;
++
++extern DevPrivateKeyRec GestureClientPrivateKeyRec;
++extern int RT_GESTURECLIENT;
++
++extern int ProcGestureQueryVersion(ClientPtr client);
++extern int ProcGestureSelectEvents(ClientPtr client);
++extern int ProcGestureGetSelectedEvents(ClientPtr client);
++extern int SProcGestureQueryVersion(ClientPtr client);
++extern int SProcGestureSelectEvents(ClientPtr client);
++extern int SProcGestureGetSelectedEvents(ClientPtr client);
++extern void SRepGestureQueryVersion(ClientPtr client, int size, GestureQueryVersionReply *rep);
++extern void SRepGestureGetSelectedEvents(ClientPtr client, int len, GestureGetSelectedEventsReply *rep);
++
++#endif /* _GESTUREINT_H_ */
+--- /dev/null
++++ b/gesture/gestureproto.h
+@@ -0,0 +1,132 @@
++/*
++ * Copyright © 2010 Canonical, Ltd.
++ *
++ * 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.
++ *
++ * Authors: Chase Douglas <chase.douglas@canonical.com>
++ *
++ */
++
++#ifndef _GESTUREPROTO_H_
++#define _GESTUREPROTO_H_
++
++#include <stdint.h>
++#include <X11/X.h>
++
++#define Window  uint32_t
++#define Time    uint32_t
++
++#define X_GestureQueryVersion                1
++#define X_GestureSelectEvents                2
++#define X_GestureGetSelectedEvents           3
++
++#define GESTUREREQUESTS (X_GestureGetSelectedEvents - X_GestureQueryVersion + 1)
++
++#define GestureAllDevices 0
++
++/**
++ * Used to select for events on a given window.
++ * Struct is followed by (mask_len * CARD8), with each bit set representing
++ * the event mask for the given type. A mask bit represents an event type if
++ * (mask == (1 << type)).
++ */
++typedef struct {
++    uint16_t    device_id;       /**< Device id to select for        */
++    uint16_t    mask_len;        /**< Length of mask in 4 byte units */
++} GestureEventMask;
++
++typedef struct {
++    uint8_t     reqType;                /**< Gesture extension major code */
++    uint8_t     ReqType;                /**< Always ::X_GestureQueryVersion */
++    uint16_t    length;                 /**< Length in 4 byte units */
++    uint16_t    major_version;
++    uint16_t    minor_version;
++} GestureQueryVersionReq;
++
++typedef struct {
++    uint8_t     repType;                /**< ::X_Reply */
++    uint8_t     RepType;                /**< Always ::X_GestureQueryVersion */
++    uint16_t    sequenceNumber;
++    uint32_t    length;
++    uint16_t    major_version;
++    uint16_t    minor_version;
++    uint32_t    pad1;
++    uint32_t    pad2;
++    uint32_t    pad3;
++    uint32_t    pad4;
++    uint32_t    pad5;
++} GestureQueryVersionReply;
++
++typedef struct {
++    uint8_t     reqType;                /**< Gesture extension major code */
++    uint8_t     ReqType;                /**< Always ::X_GestureSelectEvents */
++    uint16_t    length;                 /**< Length in 4 byte units */
++    Window      window;
++    GestureEventMask mask;
++} GestureSelectEventsReq;
++
++typedef struct {
++    uint8_t     reqType;                /**< Gesture extension major code */
++    uint8_t     ReqType;                /**< Always ::X_GestureGetSelectedEvents */


Reply to: