debian/changelog | 10 debian/patches/202_xf86CoordinationsToWindows.patch | 103 + debian/patches/203_gestures-extension.patch | 1327 ++++++++++++++++++++ debian/patches/series | 2 debian/rules | 3 5 files changed, 1444 insertions(+), 1 deletion(-)
New commits: commit 0033968f8259879bef2a99840a3f6bca98282a31 Author: Robert Hooker <sarv...@ubuntu.com> Date: Thu Aug 12 12:25:55 2010 -0400 Import changes from xorg-server 1.8.99.905-1ubuntu2, adding gesture extension support. diff --git a/debian/changelog b/debian/changelog index 61c03a4..1f383a4 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: + - switch configure option to enable gesture + + -- Chase Douglas <chase.doug...@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.doug...@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.doug...@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.doug...@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.doug...@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.doug...@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.doug...@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; ++ -- To UNSUBSCRIBE, email to debian-x-requ...@lists.debian.org with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org Archive: http://lists.debian.org/e1ojac8-0003qk...@alioth.debian.org