xserver: Branch 'server-1.13-branch' - 27 commits

Matt Dew marcoz at kemper.freedesktop.org
Fri Feb 15 23:07:57 PST 2013


 Xi/exevents.c                  |   93 ++++++++++++++++++-----------------------
 Xi/xichangehierarchy.c         |    9 ++-
 dix/events.c                   |   37 ++++++++++------
 dix/getevents.c                |   31 +++++--------
 dix/grabs.c                    |    5 +-
 dix/touch.c                    |   40 ++++++++++-------
 hw/xfree86/common/xf86DGA.c    |   10 +++-
 hw/xfree86/common/xf86Events.c |   11 +++-
 hw/xquartz/GL/capabilities.c   |    4 +
 include/input.h                |    4 -
 include/inputstr.h             |   24 +++++-----
 include/protocol-versions.h    |    2 
 m4/xorg-tls.m4                 |    2 
 mi/mieq.c                      |    6 ++
 os/strndup.c                   |    4 +
 randr/randrstr.h               |    2 
 render/animcur.c               |    3 -
 xkb/xkbUtils.c                 |   10 +++-
 18 files changed, 167 insertions(+), 130 deletions(-)

New commits:
commit b6c59f73d2dabca6348ca5ceae978488c3a4856f
Author: Jeremy Huddleston Sequoia <jeremyhu at apple.com>
Date:   Sat Feb 9 20:53:02 2013 -0800

    XORG_TLS: Pick the first option that works (ie: prefer __thread)
    
    Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu at apple.com>

diff --git a/m4/xorg-tls.m4 b/m4/xorg-tls.m4
index 237fdcd..e04f1ff 100644
--- a/m4/xorg-tls.m4
+++ b/m4/xorg-tls.m4
@@ -28,7 +28,7 @@ AC_DEFUN([XORG_TLS], [
         ac_cv_tls=none
         keywords="__thread __declspec(thread)"
         for kw in $keywords ; do
-            AC_TRY_COMPILE([int $kw test;], [], ac_cv_tls=$kw)
+            AC_TRY_COMPILE([int $kw test;], [], ac_cv_tls=$kw ; break ;)
         done
     ])
     AC_MSG_RESULT($ac_cv_tls)
commit 1c7c7d407edfb68ee5679b059a0cd72a59ac5d67
Author: Jeremy Huddleston Sequoia <jeremyhu at apple.com>
Date:   Sat Feb 9 20:40:10 2013 -0800

    os: Ensure <dix-config.h> is included in strndup.c
    
    Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu at apple.com>
    Reviewed-by: Alan Coopersmith <alan.coopersmith at oracle.com>

diff --git a/os/strndup.c b/os/strndup.c
index b604b9b..e0eddf1 100644
--- a/os/strndup.c
+++ b/os/strndup.c
@@ -27,6 +27,10 @@
  * SUCH DAMAGE.
  */
 
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
 #include <stddef.h>
 #include <stdlib.h>
 #include <string.h>
commit e2f4be5ba55268d8e92c2d7161cb5ff822b29126
Author: Jeremy Huddleston Sequoia <jeremyhu at apple.com>
Date:   Sat Feb 9 20:34:33 2013 -0800

    XQuartz: Ensure <dix-config.h> is included in capabilities.c
    
    Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu at apple.com>
    Reviewed-by: Alan Coopersmith <alan.coopersmith at oracle.com>

diff --git a/hw/xquartz/GL/capabilities.c b/hw/xquartz/GL/capabilities.c
index 4702595..5573629 100644
--- a/hw/xquartz/GL/capabilities.c
+++ b/hw/xquartz/GL/capabilities.c
@@ -20,6 +20,10 @@
  * DEALINGS IN THE SOFTWARE.
  */
 
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <assert.h>
commit a2d9bade3830802ac810a1bd72e516411f1bef35
Author: Dave Airlie <airlied at gmail.com>
Date:   Tue Feb 5 07:46:06 2013 -0800

    randr: bump advertised RandR version to 1.4
    
    Signed-off-by: Dave Airlie <airlied at redhat.com>
    Reviewed-by: Aaron Plattner <aplattner at nvidia.com>
    Tested-by: Aaron Plattner <aplattner at nvidia.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/include/protocol-versions.h b/include/protocol-versions.h
index cb8e213..3128f5f 100644
--- a/include/protocol-versions.h
+++ b/include/protocol-versions.h
@@ -65,7 +65,7 @@
 
 /* RandR */
 #define SERVER_RANDR_MAJOR_VERSION		1
-#define SERVER_RANDR_MINOR_VERSION		3
+#define SERVER_RANDR_MINOR_VERSION		4
 
 /* Record */
 #define SERVER_RECORD_MAJOR_VERSION		1
diff --git a/randr/randrstr.h b/randr/randrstr.h
index 212b0a9..27aa101 100644
--- a/randr/randrstr.h
+++ b/randr/randrstr.h
@@ -57,7 +57,7 @@
 #define RANDR_13_INTERFACE 1    /* requires RANDR_12_INTERFACE */
 #define RANDR_GET_CRTC_INTERFACE 1
 
-#define RANDR_INTERFACE_VERSION 0x0103
+#define RANDR_INTERFACE_VERSION 0x0104
 
 typedef XID RRMode;
 typedef XID RROutput;
commit 3ffa491426f2eb5a5454032676c537c8bb56bb29
Merge: 1000271 dc1c70f
Author: Matt Dew <marcoz at osource.org>
Date:   Fri Jan 25 16:34:29 2013 -0700

    Merge branch 'server-1.13-branch' of git://people.freedesktop.org/~whot/xserver into server-1.13-branch

commit dc1c70f2993ed36284e248e9f22caa62811206ec
Author: Dave Airlie <airlied at gmail.com>
Date:   Tue Jan 22 07:39:53 2013 +1000

    xserver: fix build regression since 91ab237358c6e33da854914d3de493a9cbea7637
    
    inputstr, double defines TouchListener typedef, maybe some gcc handles it,
    but not all.
    
    fixes tinderbox
    
    Reported-by: Jon TURNEY <jon.turney at dronecode.org.uk>
    Signed-off-by: Dave Airlie <airlied at redhat.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Keith Packard <keithp at keithp.com>
    (cherry picked from commit 605dfc6804a05ff2bda5692fec26c37344fd95cb)

diff --git a/include/inputstr.h b/include/inputstr.h
index 3b16e21..9834243 100644
--- a/include/inputstr.h
+++ b/include/inputstr.h
@@ -327,8 +327,6 @@ typedef struct _TouchPointInfo {
     size_t history_size;        /* Size of history in elements */
 } TouchPointInfoRec;
 
-typedef struct _TouchListener TouchListener;
-
 typedef struct _DDXTouchPointInfo {
     uint32_t client_id;         /* touch ID as seen in client events */
     Bool active;                /* whether or not the touch is active */
commit 310ac850805364c39c8f36a6a1d4fc54b952ad9d
Author: Yuly Novikov <ynovikov at chromium.org>
Date:   Mon Nov 19 21:04:57 2012 -0500

    dix: Save touchpoint last coordinates before transform. #49347
    
    DDXTouchPointInfoRec.valuators used to store axis values after transform.
    This resulted in Coordinate Transformation Matrix
    being applied multiple times to the last coordinates,
    in the case when only pressure changes in the last touch event.
    
    Changed DDXTouchPointInfoRec.valuators to store values before transform.
    
    Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=49347
    
    Signed-off-by: Yuly Novikov <ynovikov at chromium.org>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    (cherry picked from commit 3b9f1c701787965246638c1a6fd99fb2b6078114)
    
    Conflicts:
    	dix/getevents.c

diff --git a/dix/getevents.c b/dix/getevents.c
index 8b4379d..241fcfd 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -1951,32 +1951,27 @@ GetTouchEvents(InternalEvent *events, DeviceIntPtr dev, uint32_t ddx_touchid,
     default:
         return 0;
     }
-    if (t->mode == XIDirectTouch && !(flags & TOUCH_CLIENT_ID)) {
-        if (!valuator_mask_isset(&mask, 0))
-            valuator_mask_set_double(&mask, 0,
-                                     valuator_mask_get_double(touchpoint.ti->
-                                                              valuators, 0));
-        if (!valuator_mask_isset(&mask, 1))
-            valuator_mask_set_double(&mask, 1,
-                                     valuator_mask_get_double(touchpoint.ti->
-                                                              valuators, 1));
-    }
 
     /* Get our screen event co-ordinates (root_x/root_y/event_x/event_y):
      * these come from the touchpoint in Absolute mode, or the sprite in
      * Relative. */
     if (t->mode == XIDirectTouch) {
-        transformAbsolute(dev, &mask);
-
         if (!(flags & TOUCH_CLIENT_ID)) {
-            for (i = 0; i < valuator_mask_size(&mask); i++) {
-                double val;
-
-                if (valuator_mask_fetch_double(&mask, i, &val))
-                    valuator_mask_set_double(touchpoint.ti->valuators, i, val);
-            }
+        for (i = 0; i < max(valuator_mask_size(&mask), 2); i++) {
+            double val;
+
+            if (valuator_mask_fetch_double(&mask, i, &val))
+                valuator_mask_set_double(touchpoint.ti->valuators, i, val);
+            /* If the device doesn't post new X and Y axis values,
+             * use the last values posted.
+             */
+            else if (i < 2 &&
+                valuator_mask_fetch_double(touchpoint.ti->valuators, i, &val))
+                valuator_mask_set_double(&mask, i, val);
+        }
         }
 
+        transformAbsolute(dev, &mask);
         clipAbsolute(dev, &mask);
     }
     else {
diff --git a/include/inputstr.h b/include/inputstr.h
index 227ad7a..3b16e21 100644
--- a/include/inputstr.h
+++ b/include/inputstr.h
@@ -335,7 +335,7 @@ typedef struct _DDXTouchPointInfo {
     uint32_t ddx_id;            /* touch ID given by the DDX */
     Bool emulate_pointer;
 
-    ValuatorMask *valuators;    /* last recorded axis values */
+    ValuatorMask *valuators;    /* last axis values as posted, pre-transform */
 } DDXTouchPointInfoRec;
 
 typedef struct _TouchClassRec {
commit d07dfb11c29172df12f8c86213e8c1488aa2d527
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Jan 9 13:58:56 2013 +1000

    xfree86: don't access the old input handler after freeing it
    
    Introduced in 323869f3298cbbfe864af9404a8aed1bf7995d79
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Dave Airlie <airlied at redhat.com>
    (cherry picked from commit f4a58469a298c226668fd8dce375bf22331c902d)

diff --git a/hw/xfree86/common/xf86Events.c b/hw/xfree86/common/xf86Events.c
index 9e53361..7e80fa9 100644
--- a/hw/xfree86/common/xf86Events.c
+++ b/hw/xfree86/common/xf86Events.c
@@ -619,14 +619,16 @@ InputHandlerProc
 xf86SetConsoleHandler(InputHandlerProc proc, pointer data)
 {
     static IHPtr handler = NULL;
-    IHPtr old_handler = handler;
+    InputHandlerProc old_proc = NULL;
 
-    if (old_handler)
-        xf86RemoveGeneralHandler(old_handler);
+    if (handler) {
+        old_proc = handler->ihproc;
+        xf86RemoveGeneralHandler(handler);
+    }
 
     handler = xf86AddGeneralHandler(xf86Info.consoleFd, proc, data);
 
-    return (old_handler) ? old_handler->ihproc : NULL;
+    return old_proc;
 }
 
 static void
commit f7f566f9e3aa357d367ffc2c8b62b39c7d03f1e0
Author: Andreas Wettstein <wettstein509 at solnet.ch>
Date:   Wed Dec 19 18:13:21 2012 +0100

    xkb: Do not use base group as an array index.
    
    The base group is not brought into range and, therefore, using it as an array
    index crashed the X server.  Also, at this place, we should ignore locked
    groups, but not latched groups.  Therefore, use sum of base and latched groups,
    brought into range.
    
    Reproducible with:
    key <FK07> {
        type= "ONE_LEVEL",
        symbols[Group1]= [              NoSymbol ],
        actions[Group1]= [ LatchGroup(group=-1, clearLocks) ]
    };
    
    And hitting F7 will exceed the group level and access arbitrary memory.
    
    Signed-off-by: Andreas Wettstein <wettstein509 at solnet.ch>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    (cherry picked from commit 3578cc3c2e1b5cb8eb191e2d12ad88e1bc9e6e1e)

diff --git a/xkb/xkbUtils.c b/xkb/xkbUtils.c
index c23cd77..6c6af60 100644
--- a/xkb/xkbUtils.c
+++ b/xkb/xkbUtils.c
@@ -642,6 +642,7 @@ XkbComputeCompatState(XkbSrvInfoPtr xkbi)
     CARD16 grp_mask;
     XkbStatePtr state = &xkbi->state;
     XkbCompatMapPtr map;
+    XkbControlsPtr ctrls;
 
     if (!state || !xkbi->desc || !xkbi->desc->ctrls || !xkbi->desc->compat)
         return;
@@ -650,9 +651,14 @@ XkbComputeCompatState(XkbSrvInfoPtr xkbi)
     grp_mask = map->groups[state->group].mask;
     state->compat_state = state->mods | grp_mask;
     state->compat_lookup_mods = state->lookup_mods | grp_mask;
+    ctrls= xkbi->desc->ctrls;
 
-    if (xkbi->desc->ctrls->enabled_ctrls & XkbIgnoreGroupLockMask)
-        grp_mask = map->groups[state->base_group].mask;
+    if (ctrls->enabled_ctrls & XkbIgnoreGroupLockMask) {
+	unsigned char grp = state->base_group+state->latched_group;
+	if (grp >= ctrls->num_groups)
+	    grp = XkbAdjustGroup(XkbCharToInt(grp), ctrls);
+        grp_mask = map->groups[grp].mask;
+    }
     state->compat_grab_mods = state->grab_mods | grp_mask;
     return;
 }
commit da0c913da8d12bebb442e32313afb141d563cf05
Author: Carlos Garnacho <carlosg at gnome.org>
Date:   Wed Dec 19 18:42:39 2012 +0100

    render: Unwrap early on the animated cursor BlockHandler
    
    The loop above the previous call may end up triggering other
    handlers attaching to the same function slot, so unwrapping
    the handler after that could leave the just attached handler
    in a dangling but not unset state.
    
    This issue was most visible on the XO, where destroying a
    window with an animated cursor set and running  would trigger
    this inconsistent state, never calling the miSpriteBlockHandler
    again after the animated cursor is unset.
    
    Signed-off-by: Carlos Garnacho <carlosg at gnome.org>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    (cherry picked from commit df746a73410b892a4d41a2934cf9cd2e8ad7ba51)

diff --git a/render/animcur.c b/render/animcur.c
index ebc5b8e..9cbba83 100644
--- a/render/animcur.c
+++ b/render/animcur.c
@@ -143,6 +143,8 @@ AnimCurScreenBlockHandler(ScreenPtr pScreen,
     Bool activeDevice = FALSE;
     CARD32 now = 0, soonest = ~0;       /* earliest time to wakeup again */
 
+    Unwrap(as, pScreen, BlockHandler);
+
     for (dev = inputInfo.devices; dev; dev = dev->next) {
         if (IsPointerDevice(dev) && pScreen == dev->spriteInfo->anim.pScreen) {
             if (!activeDevice) {
@@ -180,7 +182,6 @@ AnimCurScreenBlockHandler(ScreenPtr pScreen,
     if (activeDevice)
         AdjustWaitForDelay(pTimeout, soonest - now);
 
-    Unwrap(as, pScreen, BlockHandler);
     (*pScreen->BlockHandler) (pScreen, pTimeout, pReadmask);
     if (activeDevice)
         Wrap(as, pScreen, BlockHandler, AnimCurScreenBlockHandler);
commit 4cdd3bfc00e6077b5d41761e3b7ae823b277b382
Author: Carlos Garnacho <carlosg at gnome.org>
Date:   Wed Dec 19 18:42:38 2012 +0100

    mi: Ensure pointer emulating touch events update the sprite
    
    Different miPointerSpriteFuncRec implementations do a varying
    business at ultimately calling miPointerUpdateSprite(), this
    particularly fails when using the plain mi sprite on touch events,
    where the sprite is just moved/updated on cursor changes.
    
    So, ensure miPointerUpdateSprite() is called generically for
    pointer emulating touch events as with regular motion events.
    
    Signed-off-by: Carlos Garnacho <carlosg at gnome.org>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    (cherry picked from commit 0fbd779a82919d5dbf8776be9b57a76c0eae6b14)

diff --git a/mi/mieq.c b/mi/mieq.c
index b2c7769..67d3928 100644
--- a/mi/mieq.c
+++ b/mi/mieq.c
@@ -623,7 +623,11 @@ mieqProcessInputEvents(void)
         mieqProcessDeviceEvent(dev, &event, screen);
 
         /* Update the sprite now. Next event may be from different device. */
-        if (event.any.type == ET_Motion && master)
+        if (master &&
+            (event.any.type == ET_Motion ||
+             ((event.any.type == ET_TouchBegin ||
+               event.any.type == ET_TouchUpdate) &&
+              event.device_event.flags & TOUCH_POINTER_EMULATED)))
             miPointerUpdateSprite(dev);
 
 #ifdef XQUARTZ
commit 7b5b7b14678747976b4309dc435a8b3ac30553da
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Jan 4 12:26:58 2013 +1000

    dix: remove already-moved hunk
    
    Should've been removed in bc1f90a615018c05994fae3e678dd2341256cd82a, but got
    left here due to a botched rebase.
    
    Fixes stray button events sent to clients after deactivating an async
    pointer grab on a pointer-emulating-touch.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    (cherry picked from commit 0e1ab433f4048b3367bb2f01d16cd00502538e4d)

diff --git a/dix/events.c b/dix/events.c
index 47ba166..904f0ba 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -1548,15 +1548,6 @@ DeactivatePointerGrab(DeviceIntPtr mouse)
         ReattachToOldMaster(mouse);
 
     ComputeFreezes();
-
-    /* If an explicit grab was deactivated, we must remove it from the head of
-     * all the touches' listener lists. */
-    for (i = 0; mouse->touch && i < mouse->touch->num_touches; i++) {
-        TouchPointInfoPtr ti = mouse->touch->touches + i;
-
-        if (ti->active && TouchResourceIsOwner(ti, grab_resource))
-            TouchListenerAcceptReject(mouse, ti, 0, XIRejectTouch);
-    }
 }
 
 /**
commit 66299cb7b850bc9260ad4b5c03e8720e3baeea98
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Dec 20 16:25:43 2012 +1000

    dix: check for the right device's xi2 mask
    
    events.c: In function 'DeactivatePointerGrab':
    events.c:1524:51: warning: 'dev' may be used uninitialized in this function
    [-Wuninitialized
    
    dev is unset when we get here, the device to check is "mouse".
    Introduced in ece8157a59751b3ed492fb2e1eb8d5f20221e195.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    (cherry picked from commit 32a6d8a6b59c42f8d65002d7ca1cafb1957b656f)

diff --git a/dix/events.c b/dix/events.c
index f45e0fb..47ba166 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -1519,7 +1519,7 @@ DeactivatePointerGrab(DeviceIntPtr mouse)
                emulate a ButtonRelease here. So pretend the listener
                already has the end event */
             if (grab->grabtype == CORE || grab->grabtype == XI ||
-                    !xi2mask_isset(dev->deviceGrab.grab->xi2mask, dev, XI_TouchBegin))
+                    !xi2mask_isset(mouse->deviceGrab.grab->xi2mask, mouse, XI_TouchBegin))
                 ti->listeners[0].state = LISTENER_HAS_END;
             TouchListenerAcceptReject(mouse, ti, 0, XIRejectTouch);
         }
commit 7c859fd5d1528fd5ea6816224cb9e22f0df0ee25
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Tue Oct 30 12:44:08 2012 +1000

    dix: add resource type to touch listeners
    
    Instead of guessing what resource type the listener is and what property to
    retrieve, store the resource type in the listener directly.
    
    Breaks XIT test cases:
    TouchGrabTestMultipleTaps.PassiveGrabPointerEmulationMultipleTouchesFastSuccession
    
    Fixes https://bugs.freedesktop.org/show_bug.cgi?id=56557
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Chase Douglas <chase.douglas at ubuntu.com>
    (cherry picked from commit f59499b5d05fde83813709e9848152951592120d)

diff --git a/Xi/exevents.c b/Xi/exevents.c
index d3bcbb1..20038a6 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -1315,13 +1315,9 @@ RetrieveTouchDeliveryData(DeviceIntPtr dev, TouchPointInfoPtr ti,
         *mask = (*grab)->xi2mask;
     }
     else {
-        if (listener->level == CORE)
-            rc = dixLookupWindow(win, listener->listener,
-                                 serverClient, DixSendAccess);
-        else
-            rc = dixLookupResourceByType((pointer *) win, listener->listener,
-                                         RT_INPUTCLIENT,
-                                         serverClient, DixSendAccess);
+        rc = dixLookupResourceByType((pointer *) win, listener->listener,
+                                     listener->resource_type,
+                                     serverClient, DixSendAccess);
         if (rc != Success)
             return FALSE;
 
@@ -1462,6 +1458,7 @@ DeliverTouchEmulatedEvent(DeviceIntPtr dev, TouchPointInfoPtr ti,
             l = &ti->listeners[ti->num_listeners - 1];
             l->listener = devgrab->resource;
             l->grab = devgrab;
+            //l->resource_type = RT_NONE;
 
             if (devgrab->grabtype != XI2 || devgrab->type != XI_TouchBegin)
                 l->type = LISTENER_POINTER_GRAB;
diff --git a/dix/touch.c b/dix/touch.c
index 17d99b8..2b30b7d 100644
--- a/dix/touch.c
+++ b/dix/touch.c
@@ -682,12 +682,13 @@ TouchResourceIsOwner(TouchPointInfoPtr ti, XID resource)
  * Add the resource to this touch's listeners.
  */
 void
-TouchAddListener(TouchPointInfoPtr ti, XID resource, enum InputLevel level,
-                 enum TouchListenerType type, enum TouchListenerState state,
-                 WindowPtr window,
+TouchAddListener(TouchPointInfoPtr ti, XID resource, int resource_type,
+                 enum InputLevel level, enum TouchListenerType type,
+                 enum TouchListenerState state, WindowPtr window,
                  GrabPtr grab)
 {
     ti->listeners[ti->num_listeners].listener = resource;
+    ti->listeners[ti->num_listeners].resource_type = resource_type;
     ti->listeners[ti->num_listeners].level = level;
     ti->listeners[ti->num_listeners].state = state;
     ti->listeners[ti->num_listeners].type = type;
@@ -748,7 +749,8 @@ TouchAddGrabListener(DeviceIntPtr dev, TouchPointInfoPtr ti,
         type = LISTENER_POINTER_GRAB;
     }
 
-    TouchAddListener(ti, grab->resource, grab->grabtype,
+    /* grab listeners are always RT_NONE since we keep the grab pointer */
+    TouchAddListener(ti, grab->resource, RT_NONE, grab->grabtype,
                      type, LISTENER_AWAITING_BEGIN, grab->window, grab);
 }
 
@@ -804,7 +806,7 @@ TouchAddRegularListener(DeviceIntPtr dev, TouchPointInfoPtr ti,
             if (!xi2mask_isset(iclients->xi2mask, dev, XI_TouchOwnership))
                 TouchEventHistoryAllocate(ti);
 
-            TouchAddListener(ti, iclients->resource, XI2,
+            TouchAddListener(ti, iclients->resource, RT_INPUTCLIENT, XI2,
                              type, LISTENER_AWAITING_BEGIN, win, NULL);
             return TRUE;
         }
@@ -819,7 +821,7 @@ TouchAddRegularListener(DeviceIntPtr dev, TouchPointInfoPtr ti,
                 continue;
 
             TouchEventHistoryAllocate(ti);
-            TouchAddListener(ti, iclients->resource, XI,
+            TouchAddListener(ti, iclients->resource, RT_INPUTCLIENT, XI,
                              LISTENER_POINTER_REGULAR, LISTENER_AWAITING_BEGIN,
                              win, NULL);
             return TRUE;
@@ -834,7 +836,7 @@ TouchAddRegularListener(DeviceIntPtr dev, TouchPointInfoPtr ti,
         /* window owner */
         if (IsMaster(dev) && (win->eventMask & core_filter)) {
             TouchEventHistoryAllocate(ti);
-            TouchAddListener(ti, win->drawable.id, CORE,
+            TouchAddListener(ti, win->drawable.id, RT_WINDOW, CORE,
                              LISTENER_POINTER_REGULAR, LISTENER_AWAITING_BEGIN,
                              win, NULL);
             return TRUE;
@@ -846,7 +848,7 @@ TouchAddRegularListener(DeviceIntPtr dev, TouchPointInfoPtr ti,
                 continue;
 
             TouchEventHistoryAllocate(ti);
-            TouchAddListener(ti, oclients->resource, CORE,
+            TouchAddListener(ti, oclients->resource, RT_OTHERCLIENT, CORE,
                              type, LISTENER_AWAITING_BEGIN, win, NULL);
             return TRUE;
         }
diff --git a/include/input.h b/include/input.h
index d83e426..f0196f5 100644
--- a/include/input.h
+++ b/include/input.h
@@ -560,7 +560,7 @@ extern void TouchEventHistoryPush(TouchPointInfoPtr ti, const DeviceEvent *ev);
 extern void TouchEventHistoryReplay(TouchPointInfoPtr ti, DeviceIntPtr dev,
                                     XID resource);
 extern Bool TouchResourceIsOwner(TouchPointInfoPtr ti, XID resource);
-extern void TouchAddListener(TouchPointInfoPtr ti, XID resource,
+extern void TouchAddListener(TouchPointInfoPtr ti, XID resource, int resource_type,
                              enum InputLevel level, enum TouchListenerType type,
                              enum TouchListenerState state, WindowPtr window, GrabPtr grab);
 extern Bool TouchRemoveListener(TouchPointInfoPtr ti, XID resource);
diff --git a/include/inputstr.h b/include/inputstr.h
index e21484b..227ad7a 100644
--- a/include/inputstr.h
+++ b/include/inputstr.h
@@ -301,6 +301,7 @@ typedef struct _ValuatorClassRec {
 typedef struct _TouchListener {
     XID listener;           /* grabs/event selection IDs receiving
                              * events for this touch */
+    int resource_type;      /* listener's resource type */
     enum TouchListenerType type;
     enum TouchListenerState state;
     enum InputLevel level;  /* matters only for emulating touches */
commit df12c4daa7236702ef52aa121705826e58bf6783
Author: Keith Packard <keithp at keithp.com>
Date:   Tue Nov 27 11:21:17 2012 -0800

    input: Record grab pointer in TouchListener
    
    This places a pointer to the grab related to a TouchListener directly
    in the TouchListener structure rather than hoping to find the grab
    later on using the resource ID.
    
    Passive grabs have resource ID in the resource DB so they can be
    removed when a client exits, and those resource IDs get copied when
    activated, but implicit grabs are constructed on-the-fly and have no
    resource DB entry.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    (cherry picked from commit 9ad0fdb135a1c336771aee1f6eab75a6ad874aff)

diff --git a/Xi/exevents.c b/Xi/exevents.c
index b691d20..d3bcbb1 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -1197,7 +1197,6 @@ TouchRejected(DeviceIntPtr sourcedev, TouchPointInfoPtr ti, XID resource,
               TouchOwnershipEvent *ev)
 {
     Bool was_owner = (resource == ti->listeners[0].listener);
-    void *grab;
     int i;
 
     /* Send a TouchEnd event to the resource being removed, but only if they
@@ -1212,11 +1211,7 @@ TouchRejected(DeviceIntPtr sourcedev, TouchPointInfoPtr ti, XID resource,
 
     /* Remove the resource from the listener list, updating
      * ti->num_listeners, as well as ti->num_grabs if it was a grab. */
-    if (TouchRemoveListener(ti, resource)) {
-        if (dixLookupResourceByType(&grab, resource, RT_PASSIVEGRAB,
-                                    serverClient, DixGetAttrAccess) == Success)
-            ti->num_grabs--;
-    }
+    TouchRemoveListener(ti, resource);
 
     /* If the current owner was removed and there are further listeners, deliver
      * the TouchOwnership or TouchBegin event to the new owner. */
@@ -1310,21 +1305,10 @@ RetrieveTouchDeliveryData(DeviceIntPtr dev, TouchPointInfoPtr ti,
 
     if (listener->type == LISTENER_GRAB ||
         listener->type == LISTENER_POINTER_GRAB) {
-        rc = dixLookupResourceByType((pointer *) grab, listener->listener,
-                                     RT_PASSIVEGRAB,
-                                     serverClient, DixSendAccess);
-        if (rc != Success) {
-            /* the grab doesn't exist but we have a grabbing listener - this
-             * is an implicit/active grab */
-            rc = dixLookupClient(client, listener->listener, serverClient,
-                                 DixSendAccess);
-            if (rc != Success)
-                return FALSE;
-
-            *grab = dev->deviceGrab.grab;
-            if (!*grab)
-                return FALSE;
-        }
+
+        *grab = listener->grab;
+
+        BUG_RETURN_VAL(!*grab, FALSE);
 
         *client = rClient(*grab);
         *win = (*grab)->window;
@@ -1477,6 +1461,7 @@ DeliverTouchEmulatedEvent(DeviceIntPtr dev, TouchPointInfoPtr ti,
              */
             l = &ti->listeners[ti->num_listeners - 1];
             l->listener = devgrab->resource;
+            l->grab = devgrab;
 
             if (devgrab->grabtype != XI2 || devgrab->type != XI_TouchBegin)
                 l->type = LISTENER_POINTER_GRAB;
diff --git a/dix/events.c b/dix/events.c
index 3f75a91..f45e0fb 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -1435,6 +1435,7 @@ UpdateTouchesForGrab(DeviceIntPtr mouse)
                 ti->listeners[0].type = LISTENER_POINTER_GRAB;
             else
                 ti->listeners[0].type = LISTENER_GRAB;
+            ti->listeners[0].grab = grab;
         }
     }
 }
diff --git a/dix/touch.c b/dix/touch.c
index f51f46d..17d99b8 100644
--- a/dix/touch.c
+++ b/dix/touch.c
@@ -684,13 +684,17 @@ TouchResourceIsOwner(TouchPointInfoPtr ti, XID resource)
 void
 TouchAddListener(TouchPointInfoPtr ti, XID resource, enum InputLevel level,
                  enum TouchListenerType type, enum TouchListenerState state,
-                 WindowPtr window)
+                 WindowPtr window,
+                 GrabPtr grab)
 {
     ti->listeners[ti->num_listeners].listener = resource;
     ti->listeners[ti->num_listeners].level = level;
     ti->listeners[ti->num_listeners].state = state;
     ti->listeners[ti->num_listeners].type = type;
     ti->listeners[ti->num_listeners].window = window;
+    ti->listeners[ti->num_listeners].grab = grab;
+    if (grab)
+        ti->num_grabs++;
     ti->num_listeners++;
 }
 
@@ -709,6 +713,11 @@ TouchRemoveListener(TouchPointInfoPtr ti, XID resource)
         if (ti->listeners[i].listener == resource) {
             int j;
 
+            if (ti->listeners[i].grab) {
+                ti->listeners[i].grab = NULL;
+                ti->num_grabs--;
+            }
+
             for (j = i; j < ti->num_listeners - 1; j++)
                 ti->listeners[j] = ti->listeners[j + 1];
             ti->num_listeners--;
@@ -740,8 +749,7 @@ TouchAddGrabListener(DeviceIntPtr dev, TouchPointInfoPtr ti,
     }
 
     TouchAddListener(ti, grab->resource, grab->grabtype,
-                     type, LISTENER_AWAITING_BEGIN, grab->window);
-    ti->num_grabs++;
+                     type, LISTENER_AWAITING_BEGIN, grab->window, grab);
 }
 
 /**
@@ -797,7 +805,7 @@ TouchAddRegularListener(DeviceIntPtr dev, TouchPointInfoPtr ti,
                 TouchEventHistoryAllocate(ti);
 
             TouchAddListener(ti, iclients->resource, XI2,
-                             type, LISTENER_AWAITING_BEGIN, win);
+                             type, LISTENER_AWAITING_BEGIN, win, NULL);
             return TRUE;
         }
     }
@@ -813,7 +821,7 @@ TouchAddRegularListener(DeviceIntPtr dev, TouchPointInfoPtr ti,
             TouchEventHistoryAllocate(ti);
             TouchAddListener(ti, iclients->resource, XI,
                              LISTENER_POINTER_REGULAR, LISTENER_AWAITING_BEGIN,
-                             win);
+                             win, NULL);
             return TRUE;
         }
     }
@@ -828,7 +836,7 @@ TouchAddRegularListener(DeviceIntPtr dev, TouchPointInfoPtr ti,
             TouchEventHistoryAllocate(ti);
             TouchAddListener(ti, win->drawable.id, CORE,
                              LISTENER_POINTER_REGULAR, LISTENER_AWAITING_BEGIN,
-                             win);
+                             win, NULL);
             return TRUE;
         }
 
@@ -839,7 +847,7 @@ TouchAddRegularListener(DeviceIntPtr dev, TouchPointInfoPtr ti,
 
             TouchEventHistoryAllocate(ti);
             TouchAddListener(ti, oclients->resource, CORE,
-                             type, LISTENER_AWAITING_BEGIN, win);
+                             type, LISTENER_AWAITING_BEGIN, win, NULL);
             return TRUE;
         }
     }
diff --git a/include/input.h b/include/input.h
index f8459b8..d83e426 100644
--- a/include/input.h
+++ b/include/input.h
@@ -562,7 +562,7 @@ extern void TouchEventHistoryReplay(TouchPointInfoPtr ti, DeviceIntPtr dev,
 extern Bool TouchResourceIsOwner(TouchPointInfoPtr ti, XID resource);
 extern void TouchAddListener(TouchPointInfoPtr ti, XID resource,
                              enum InputLevel level, enum TouchListenerType type,
-                             enum TouchListenerState state, WindowPtr window);
+                             enum TouchListenerState state, WindowPtr window, GrabPtr grab);
 extern Bool TouchRemoveListener(TouchPointInfoPtr ti, XID resource);
 extern void TouchSetupListeners(DeviceIntPtr dev, TouchPointInfoPtr ti,
                                 InternalEvent *ev);
diff --git a/include/inputstr.h b/include/inputstr.h
index 8d9dd71..e21484b 100644
--- a/include/inputstr.h
+++ b/include/inputstr.h
@@ -305,6 +305,7 @@ typedef struct _TouchListener {
     enum TouchListenerState state;
     enum InputLevel level;  /* matters only for emulating touches */
     WindowPtr window;
+    GrabPtr grab;
 } TouchListener;
 
 typedef struct _TouchPointInfo {
commit 5272f71cf8387efe87a19827a01daf2b0bbdfbf6
Author: Keith Packard <keithp at keithp.com>
Date:   Tue Nov 27 11:21:16 2012 -0800

    input: Pull TouchListener declaration to top-level
    
    No reason to have a struct declared inside another struct
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    (cherry picked from commit 91ab237358c6e33da854914d3de493a9cbea7637)

diff --git a/include/inputstr.h b/include/inputstr.h
index 5a38924..8d9dd71 100644
--- a/include/inputstr.h
+++ b/include/inputstr.h
@@ -298,6 +298,15 @@ typedef struct _ValuatorClassRec {
     int v_scroll_axis;          /* vert smooth-scrolling axis */
 } ValuatorClassRec;
 
+typedef struct _TouchListener {
+    XID listener;           /* grabs/event selection IDs receiving
+                             * events for this touch */
+    enum TouchListenerType type;
+    enum TouchListenerState state;
+    enum InputLevel level;  /* matters only for emulating touches */
+    WindowPtr window;
+} TouchListener;
+
 typedef struct _TouchPointInfo {
     uint32_t client_id;         /* touch ID as seen in client events */
     int sourceid;               /* Source device's ID for this touchpoint */
@@ -306,14 +315,7 @@ typedef struct _TouchPointInfo {
                                  * but still owned by a grab */
     SpriteRec sprite;           /* window trace for delivery */
     ValuatorMask *valuators;    /* last recorded axis values */
-    struct _TouchListener {
-        XID listener;           /* grabs/event selection IDs receiving
-                                 * events for this touch */
-        enum TouchListenerType type;
-        enum TouchListenerState state;
-        enum InputLevel level;  /* matters only for emulating touches */
-        WindowPtr window;
-    } *listeners;
+    TouchListener *listeners;   /* set of listeners */
     int num_listeners;
     int num_grabs;              /* number of open grabs on this touch
                                  * which have not accepted or rejected */
commit 041ab46aba357689484f91fc408725677d6dc2d4
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Tue Jan 8 11:19:09 2013 +1000

    xfree86: update the device state for all DGA events (#59100)
    
    DGA only handles master devices but it does intercept slave device events as
    well (since the event handlers are per event type, not per device).
    
    The DGA code must thus call into UpdateDeviceState to reset the button/key
    state on the slave device before it discards the remainder of the event.
    
    Test case:
    - Passive GrabModeSync on VCP
    - Press button
    - Enable DGA after ButtonPress
    - AllowEvents(SyncPointer)
    - Release button
    
    The button release is handled by DGAProcessPointerEvent but the device state
    is never updated, so the slave ends up with the button permanently down.
    And since the master's button state is the union of the slave states, the
    master has the button permanently down.
    
    X.Org Bug 59100 <http://bugs.freedesktop.org/show_bug.cgi?id=59100>
    
    Reported-by: Steven Elliott <selliott4 at austin.rr.com>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Dave Airlie <airlied at redhat.com>
    (cherry picked from commit ad3bc571348a7007a2960bf87ae739397c5511ee)

diff --git a/hw/xfree86/common/xf86DGA.c b/hw/xfree86/common/xf86DGA.c
index 38ee6f1..7f1a0c6 100644
--- a/hw/xfree86/common/xf86DGA.c
+++ b/hw/xfree86/common/xf86DGA.c
@@ -1033,6 +1033,9 @@ DGAProcessKeyboardEvent(ScreenPtr pScreen, DGAEvent * event, DeviceIntPtr keybd)
 
     UpdateDeviceState(keybd, &ev);
 
+    if (!IsMaster(keybd))
+        return;
+
     /*
      * Deliver the DGA event
      */
@@ -1084,6 +1087,9 @@ DGAProcessPointerEvent(ScreenPtr pScreen, DGAEvent * event, DeviceIntPtr mouse)
 
     UpdateDeviceState(mouse, &ev);
 
+    if (!IsMaster(mouse))
+        return;
+
     /*
      * Deliver the DGA event
      */
@@ -1191,9 +1197,6 @@ DGAHandleEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
     if (!pScreenPriv)
         return;
 
-    if (!IsMaster(device))
-        return;
-
     switch (event->subtype) {
     case KeyPress:
     case KeyRelease:
commit c201d00014c505055915eefbc1702dd1e84cbce7
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Tue Jan 8 10:13:53 2013 +1000

    xfree86: set event->detail for DGA pointer events
    
    Reported-by: Steven Elliott <selliott4 at austin.rr.com>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Dave Airlie <airlied at redhat.com>
    (cherry picked from commit c5f2818edbec2f87383baa6c6be5c389b73ca6f9)

diff --git a/hw/xfree86/common/xf86DGA.c b/hw/xfree86/common/xf86DGA.c
index a441dee..38ee6f1 100644
--- a/hw/xfree86/common/xf86DGA.c
+++ b/hw/xfree86/common/xf86DGA.c
@@ -1074,6 +1074,7 @@ DGAProcessPointerEvent(ScreenPtr pScreen, DGAEvent * event, DeviceIntPtr mouse)
     DeviceEvent ev = {
         .header = ET_Internal,
         .length = sizeof(ev),
+        .detail.key = event->detail,
         .type = event->subtype,
         .corestate = butc ? butc->state : 0
     };
commit de0ea3544f57ea1d940726a6dfac19f21d74d090
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Aug 22 10:34:07 2012 +1000

    dix: don't filter RawEvents if the grab window is not the root window (#53897)
    
    If a XI2.1+ client has a grab on a non-root window, it  must still receive
    raw events on the root window.
    
    Test case: register for XI_ButtonPress on window and XI_RawMotion on root.
    No raw events are received once the press activates an implicit grab on the
    window.
    
    X.Org Bug 53897 <http://bugs.freedesktop.org/show_bug.cgi?id=53897>
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    (cherry picked from commit 4e13dd90144dde47550aceea4db4b4329e531279)

diff --git a/dix/events.c b/dix/events.c
index e52dc54..3f75a91 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -2240,7 +2240,7 @@ DeliverEventsToWindow(DeviceIntPtr pDev, WindowPtr pWin, xEvent
  * @return TRUE if the event should be discarded, FALSE otherwise.
  */
 static BOOL
-FilterRawEvents(const ClientPtr client, const GrabPtr grab)
+FilterRawEvents(const ClientPtr client, const GrabPtr grab, WindowPtr root)
 {
     XIClientPtr client_xi_version;
     int cmp;
@@ -2256,7 +2256,10 @@ FilterRawEvents(const ClientPtr client, const GrabPtr grab)
                           client_xi_version->minor_version, 2, 0);
     /* XI 2.0: if device is grabbed, skip
        XI 2.1: if device is grabbed by us, skip, we've already delivered */
-    return (cmp == 0) ? TRUE : SameClient(grab, client);
+    if (cmp == 0)
+        return TRUE;
+
+    return (grab->window != root) ? FALSE : SameClient(grab, client);
 }
 
 /**
@@ -2309,7 +2312,7 @@ DeliverRawEvent(RawDeviceEvent *ev, DeviceIntPtr device)
              */
             ic.next = NULL;
 
-            if (!FilterRawEvents(rClient(&ic), grab))
+            if (!FilterRawEvents(rClient(&ic), grab, root))
                 DeliverEventToInputClients(device, &ic, root, xi, 1,
                                            filter, NULL, &c, &m);
         }
commit 5ed2523f4dc6c471908c2d940cc40e4ad26aa84d
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Dec 12 11:02:19 2012 +1000

    xfree86: print message to the log when zapping the server
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Aaron Plattner <aplattner at nvidia.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>
    (cherry picked from commit 3420a7778c7d5eaa638327f31dd460554c257bb1)

diff --git a/hw/xfree86/common/xf86Events.c b/hw/xfree86/common/xf86Events.c
index 3ad34b5..9e53361 100644
--- a/hw/xfree86/common/xf86Events.c
+++ b/hw/xfree86/common/xf86Events.c
@@ -180,6 +180,7 @@ xf86ProcessActionEvent(ActionEvent action, void *arg)
     switch (action) {
     case ACTION_TERMINATE:
         if (!xf86Info.dontZap) {
+            xf86Msg(X_INFO, "Server zapped. Shutting down.\n");
 #ifdef XFreeXDGA
             DGAShutdown();
 #endif
commit 956700d14d01a6d8a1bb8b8f9b910ef044ad154b
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Mon Nov 26 14:55:13 2012 +1000

    Xi: if a TouchEnd appears on a actively grabbing client, always accept
    
    Once the TouchEnd appears on the device, the touch is done. If the client
    still has a pointer grab, accept it to avoid clients with TouchOwnership
    selections to wait indefinitely for the actual touch event.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    (cherry picked from commit 00def5144557cfe8bf535f926212a8e084dc7cf6)
    
    Conflicts:
    	Xi/exevents.c

diff --git a/Xi/exevents.c b/Xi/exevents.c
index 106da3a..b691d20 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -1576,32 +1576,41 @@ ProcessTouchEvent(InternalEvent *ev, DeviceIntPtr dev)
     else
         ti = TouchFindByClientID(dev, touchid);
 
-    /* Under the following circumstances we create a new touch record for an
-     * existing touch:
-     *
-     * - The touch may be pointer emulated
-     * - An explicit grab is active on the device
-     * - The grab is a pointer grab
-     *
-     * This allows for an explicit grab to receive pointer events for an already
-     * active touch.
-     */
-    if (!ti && type != ET_TouchBegin && emulate_pointer &&
-        dev->deviceGrab.grab && !dev->deviceGrab.fromPassiveGrab &&
+    /* Active pointer grab */
+    if (emulate_pointer && dev->deviceGrab.grab && !dev->deviceGrab.fromPassiveGrab &&
         (dev->deviceGrab.grab->grabtype == CORE ||
          dev->deviceGrab.grab->grabtype == XI ||
-         !xi2mask_isset(dev->deviceGrab.grab->xi2mask, dev, XI_TouchBegin))) {
-        ti = TouchBeginTouch(dev, ev->device_event.sourceid, touchid,
-                             emulate_pointer);
-        if (!ti) {
-            DebugF("[Xi] %s: Failed to create new dix record for explicitly "
-                   "grabbed touchpoint %d\n",
-                   dev->name, type, touchid);
-            return;
-        }
+         !xi2mask_isset(dev->deviceGrab.grab->xi2mask, dev, XI_TouchBegin)))
+    {
+        /* Active pointer grab on touch point and we get a TouchEnd - claim this
+         * touchpoint accepted, otherwise clients waiting for ownership will
+         * wait on this touchpoint until this client ungrabs, or the cows come
+         * home, whichever is earlier */
+        if (ti && type == ET_TouchEnd)
+            TouchListenerAcceptReject(dev, ti, 0, XIAcceptTouch);
+        else if (!ti && type != ET_TouchBegin) {
+            /* Under the following circumstances we create a new touch record for an
+             * existing touch:
+             *
+             * - The touch may be pointer emulated
+             * - An explicit grab is active on the device
+             * - The grab is a pointer grab
+             *
+             * This allows for an explicit grab to receive pointer events for an already
+             * active touch.
+             */
+            ti = TouchBeginTouch(dev, ev->device_event.sourceid, touchid,
+                                 emulate_pointer);
+            if (!ti) {
+                DebugF("[Xi] %s: Failed to create new dix record for explicitly "
+                       "grabbed touchpoint %d\n",
+                       dev->name, touchid);
+                return;
+            }
 
-        TouchBuildSprite(dev, ti, ev);
-        TouchSetupListeners(dev, ti, ev);
+            TouchBuildSprite(dev, ti, ev);
+            TouchSetupListeners(dev, ti, ev);
+        }
     }
 
     if (!ti) {
commit 39157fd2405ad855d0f60578b57e193a744bb075
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Mon Nov 26 15:14:19 2012 +1000

    dix: when deactivating pointer-only grabs, don't emulate TouchEnd events
    
    A client with a pointer grab on a touch device must reject the touch when
    detactivating the grab while the touch is active. However, such a rejecting
    must not trigger a ButtonRelease event to be emulated and sent to the
    client.
    Set the grabbing listener's state to HAS_END, so we simply skip delivery to
    that client.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    (cherry picked from commit ece8157a59751b3ed492fb2e1eb8d5f20221e195)

diff --git a/dix/events.c b/dix/events.c
index 9e0bbb3..e52dc54 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -1513,8 +1513,15 @@ DeactivatePointerGrab(DeviceIntPtr mouse)
      * all the touches' listener lists. */
     for (i = 0; !wasPassive && mouse->touch && i < mouse->touch->num_touches; i++) {
         TouchPointInfoPtr ti = mouse->touch->touches + i;
-        if (ti->active && TouchResourceIsOwner(ti, grab_resource))
+        if (ti->active && TouchResourceIsOwner(ti, grab_resource)) {
+            /* Rejecting will generate a TouchEnd, but we must not
+               emulate a ButtonRelease here. So pretend the listener
+               already has the end event */
+            if (grab->grabtype == CORE || grab->grabtype == XI ||
+                    !xi2mask_isset(dev->deviceGrab.grab->xi2mask, dev, XI_TouchBegin))
+                ti->listeners[0].state = LISTENER_HAS_END;
             TouchListenerAcceptReject(mouse, ti, 0, XIRejectTouch);
+        }
     }
 
     TouchRemovePointerGrab(mouse);
commit e1626674333ef4d67f97d9960f58486c9f6cb11d
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Mon Nov 26 12:23:54 2012 +1000

    dix: only reject active grabs on ungrab and do it before actually ungrabbing
    
    An active grab ungrabbing is the same as rejecting the grab, since the
    client is no longer interested in those events. So reject any touch grab,
    but do so before actually deactivating since we're interested in the
    TouchEnd for the current grabbing client.
    
    A passive grab otoh is _not_ like rejecting a grab, since it deactivates
    automatically when the touch ends.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    (cherry picked from commit bc1f90a615018c05994fae3e678dd2341256cd82)

diff --git a/dix/events.c b/dix/events.c
index bf6eef2..9e0bbb3 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -1503,11 +1503,20 @@ DeactivatePointerGrab(DeviceIntPtr mouse)
 {
     GrabPtr grab = mouse->deviceGrab.grab;
     DeviceIntPtr dev;
+    Bool wasPassive = mouse->deviceGrab.fromPassiveGrab;
     Bool wasImplicit = (mouse->deviceGrab.fromPassiveGrab &&
                         mouse->deviceGrab.implicitGrab);
     XID grab_resource = grab->resource;
     int i;
 
+    /* If an explicit grab was deactivated, we must remove it from the head of
+     * all the touches' listener lists. */
+    for (i = 0; !wasPassive && mouse->touch && i < mouse->touch->num_touches; i++) {
+        TouchPointInfoPtr ti = mouse->touch->touches + i;
+        if (ti->active && TouchResourceIsOwner(ti, grab_resource))
+            TouchListenerAcceptReject(mouse, ti, 0, XIRejectTouch);
+    }
+
     TouchRemovePointerGrab(mouse);
 
     mouse->valuator->motionHintWindow = NullWindow;
commit b72ffcf6ae146feaa08df80e65d293bc3a62331f
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Nov 22 13:49:34 2012 +1000

    dix: don't call ProcessInputEvents() when accepting/rejecting touches
    
    TouchListenerAcceptReject may be called during normal event processing, but
    ProcessInputEvents is not reentrant and calling it here smashes the event
    queue.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    (cherry picked from commit 146f48c2934fc85ec095496da5c8f0102bc7f5b5)

diff --git a/dix/touch.c b/dix/touch.c
index 5f77be5..f51f46d 100644
--- a/dix/touch.c
+++ b/dix/touch.c
@@ -994,8 +994,6 @@ TouchListenerAcceptReject(DeviceIntPtr dev, TouchPointInfoPtr ti, int listener,
     for (i = 0; i < nev; i++)
         mieqProcessDeviceEvent(dev, events + i, NULL);
 
-    ProcessInputEvents();
-
     FreeEventList(events, GetMaximumEventsNum());
 
     return nev ? Success : BadMatch;
commit d5142c4e9db6175c5258749acc314833c40ac2fb
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Dec 14 11:34:15 2012 +1000

    dix: don't allow overriding a grab with a different type of grab (#58255)
    
    If a client has a core grab, don't allow re-grabbing with type XI2, etc.
    This was the intent of the original commit
    xorg-server-1.5.99.1-782-g09f9a86, but ineffective.
    
    X.Org Bug 58255 <http://bugs.freedesktop.org/show_bug.cgi?id=58255>
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    (cherry picked from commit dd3242c87a0a58cba055eb99c0c3fcf03153e4b8)

diff --git a/dix/events.c b/dix/events.c
index ddb5b34..bf6eef2 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -5027,7 +5027,7 @@ GrabDevice(ClientPtr client, DeviceIntPtr dev,
     grab = grabInfo->grab;
     if (grab && grab->grabtype != grabtype)
         *status = AlreadyGrabbed;
-    if (grab && !SameClient(grab, client))
+    else if (grab && !SameClient(grab, client))
         *status = AlreadyGrabbed;
     else if ((!pWin->realized) ||
              (confineTo &&
commit 7800cf99f52081b7f6b8870d430730c595ffca60
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Tue Dec 11 13:36:02 2012 +1000

    dix: don't copy the wrong event mask when activating a passive grab
    
    GrabMask is a union of core, XI1 and XI2 masks. If a XI2 grab is activated,
    the value is a random pointer value, using it as mask has unpredictable
    effects.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Jasper St. Pierre <jstpierre at mecheye.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    (cherry picked from commit f793b5fd3eb16a2ada130367c2ffebeede69a322)

diff --git a/dix/grabs.c b/dix/grabs.c
index 55bf64f..d55a69c 100644
--- a/dix/grabs.c
+++ b/dix/grabs.c
@@ -219,7 +219,10 @@ CreateGrab(int client, DeviceIntPtr device, DeviceIntPtr modDevice,
     grab->resource = FakeClientID(client);
     grab->device = device;
     grab->window = window;
-    grab->eventMask = mask->core;       /* same for XI */
+    if (grabtype == CORE || grabtype == XI)
+        grab->eventMask = mask->core;       /* same for XI */
+    else
+        grab->eventMask = 0;
     grab->deviceMask = 0;
     grab->ownerEvents = param->ownerEvents;
     grab->keyboardMode = param->this_device_mode;
commit c15bdf316386dad275dd4f691e7a6a3b306f9327
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Dec 13 11:49:54 2012 +1000

    Xi: don't use devices after removing them
    
    RemoveDevice() frees the DeviceIntPtr, we shouldn't use the pointer after
    that
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    (cherry picked from commit 58bff17e43a80eb21b3ff6d4bb1596230e61f707)

diff --git a/Xi/xichangehierarchy.c b/Xi/xichangehierarchy.c
index 89f16d8..4dc3d76 100644
--- a/Xi/xichangehierarchy.c
+++ b/Xi/xichangehierarchy.c
@@ -304,15 +304,16 @@ remove_master(ClientPtr client, xXIRemoveMasterInfo * r, int flags[MAXDEVICES])
     flags[keybd->id] |= XIDeviceDisabled;
     flags[ptr->id] |= XIDeviceDisabled;
 
-    RemoveDevice(XTestptr, FALSE);
-    RemoveDevice(XTestkeybd, FALSE);
-    RemoveDevice(keybd, FALSE);
-    RemoveDevice(ptr, FALSE);
     flags[XTestptr->id] |= XISlaveRemoved;
     flags[XTestkeybd->id] |= XISlaveRemoved;
     flags[keybd->id] |= XIMasterRemoved;
     flags[ptr->id] |= XIMasterRemoved;
 
+    RemoveDevice(XTestptr, FALSE);
+    RemoveDevice(XTestkeybd, FALSE);
+    RemoveDevice(keybd, FALSE);
+    RemoveDevice(ptr, FALSE);
+
  unwind:
     return rc;
 }


More information about the xorg-commit mailing list