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: