xserver: Branch 'master' - 8 commits

Keith Packard keithp at kemper.freedesktop.org
Sun Apr 15 21:29:55 PDT 2012


 Xi/exevents.c                  |   86 ++++++++++++++++++++++++++++++++++++++++-
 Xi/xiquerydevice.c             |    2 
 dix/events.c                   |    3 -
 dix/getevents.c                |    2 
 hw/xfree86/common/xf86Events.c |    8 ++-
 hw/xfree86/common/xf86Xinput.h |    3 +
 6 files changed, 96 insertions(+), 8 deletions(-)

New commits:
commit 80fefc42f5e67e6b4a4b440d8991bee7e5f38359
Merge: 9779b90... 12188c8...
Author: Keith Packard <keithp at keithp.com>
Date:   Sun Apr 15 21:05:30 2012 -0700

    Merge remote-tracking branch 'whot/for-keith'

commit 12188c8a8a537b38b1ca4cf8c0de5447e19c886a
Author: Chase Douglas <chase.douglas at canonical.com>
Date:   Tue Apr 3 17:31:01 2012 -0700

    Use touch state when querying pointer through core protocol
    
    QueryPointer is part of the core protocol. As such, it knows nothing
    about touch devices. Touches are converted to button 1 press, pointer
    motion, and button 1 release for core clients, so we should ensure the
    pointer state mask has button 1 set when XQueryPointer is used.
    
    Signed-off-by: Chase Douglas <chase.douglas at canonical.com>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dix/events.c b/dix/events.c
index 4470947..b9f9cfa 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -5098,8 +5098,7 @@ ProcQueryPointer(ClientPtr client)
     memset(&rep, 0, sizeof(xQueryPointerReply));
     rep.type = X_Reply;
     rep.sequenceNumber = client->sequence;
-    rep.mask = mouse->button ? (mouse->button->state) : 0;
-    rep.mask |= XkbStateFieldFromRec(&keyboard->key->xkbInfo->state);
+    rep.mask = event_get_corestate(mouse, keyboard);
     rep.length = 0;
     rep.root = (GetCurrentRootWindow(mouse))->drawable.id;
     rep.rootX = pSprite->hot.x;
commit 32ece7c09bf0ebc3d99b4078aacebbd44314776a
Author: Chase Douglas <chase.douglas at canonical.com>
Date:   Tue Apr 10 17:12:42 2012 -0700

    Ensure sequential touches are pointer emulated sequentially
    
    Issue:
    * Two sequential touches (i.e. down, up, down, up)
    * Both are grabbed by a touch grab
    * Both have a second listener in the form of a pointer grab or selection
    * The second and first touches are rejected in that order
    
    The first touch must be pointer emulated before the second touch, so the
    second touch must be paused until the first touch is rejected or
    accepted and all events are delivered to pointer clients.
    
    This change ensures all pointer emulated events are emitted
    sequentially. It necessarily imposes a delay on further touch events
    when pointer grabs and selections are used, but there is no way around
    it.
    
    Signed-off-by: Chase Douglas <chase.douglas at canonical.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xi/exevents.c b/Xi/exevents.c
index a843e03..c05c226 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -1111,6 +1111,48 @@ EmitTouchEnd(DeviceIntPtr dev, TouchPointInfoPtr ti, int flags, XID resource)
 }
 
 /**
+ * Find the oldest touch that still has a pointer emulation client.
+ *
+ * Pointer emulation can only be performed for the oldest touch. Otherwise, the
+ * order of events seen by the client will be wrong. This function helps us find
+ * the next touch to be emulated.
+ *
+ * @param dev The device to find touches for.
+ */
+static TouchPointInfoPtr
+FindOldestPointerEmulatedTouch(DeviceIntPtr dev)
+{
+    TouchPointInfoPtr oldest = NULL;
+    int i;
+
+    for (i = 0; i < dev->touch->num_touches; i++) {
+        TouchPointInfoPtr ti = dev->touch->touches + i;
+        int j;
+
+        if (!ti->active || !ti->emulate_pointer)
+            continue;
+
+        for (j = 0; j < ti->num_listeners; j++) {
+            if (ti->listeners[j].type == LISTENER_POINTER_GRAB ||
+                ti->listeners[j].type == LISTENER_POINTER_REGULAR)
+                break;
+        }
+        if (j == ti->num_listeners)
+            continue;
+
+        if (!oldest) {
+            oldest = ti;
+            continue;
+        }
+
+        if (oldest->client_id - ti->client_id < UINT_MAX / 2)
+            oldest = ti;
+    }
+
+    return oldest;
+}
+
+/**
  * If the current owner has rejected the event, deliver the
  * TouchOwnership/TouchBegin to the next item in the sprite stack.
  */
@@ -1123,8 +1165,16 @@ TouchPuntToNextOwner(DeviceIntPtr dev, TouchPointInfoPtr ti,
         ti->listeners[0].state == LISTENER_EARLY_ACCEPT)
         DeliverTouchEvents(dev, ti, (InternalEvent *) ev,
                            ti->listeners[0].listener);
-    else if (ti->listeners[0].state == LISTENER_AWAITING_BEGIN)
+    else if (ti->listeners[0].state == LISTENER_AWAITING_BEGIN) {
+        /* We can't punt to a pointer listener unless all older pointer
+         * emulated touches have been seen already. */
+        if ((ti->listeners[0].type == LISTENER_POINTER_GRAB ||
+             ti->listeners[0].type == LISTENER_POINTER_REGULAR) &&
+            ti != FindOldestPointerEmulatedTouch(dev))
+            return;
+
         TouchEventHistoryReplay(ti, dev, ti->listeners[0].listener);
+    }
 
     /* If we've just removed the last grab and the touch has physically
      * ended, send a TouchEnd event too and finalise the touch. */
@@ -1139,6 +1189,25 @@ TouchPuntToNextOwner(DeviceIntPtr dev, TouchPointInfoPtr ti,
 }
 
 /**
+ * Check the oldest touch to see if it needs to be replayed to its pointer
+ * owner.
+ *
+ * Touch event propagation is paused if it hits a pointer listener while an
+ * older touch with a pointer listener is waiting on accept or reject. This
+ * function will restart propagation of a paused touch if needed.
+ *
+ * @param dev The device to check touches for.
+ */
+static void
+CheckOldestTouch(DeviceIntPtr dev)
+{
+    TouchPointInfoPtr oldest = FindOldestPointerEmulatedTouch(dev);
+
+    if (oldest && oldest->listeners[0].state == LISTENER_AWAITING_BEGIN)
+        TouchPuntToNextOwner(dev, oldest, NULL);
+}
+
+/**
  * Process a touch rejection.
  *
  * @param sourcedev The source device of the touch sequence.
@@ -1169,6 +1238,7 @@ TouchRejected(DeviceIntPtr sourcedev, TouchPointInfoPtr ti, XID resource,
      * finish, then we can just kill it now. */
     if (ti->num_listeners == 1 && ti->pending_finish) {
         TouchEndTouch(sourcedev, ti);
+        CheckOldestTouch(sourcedev);
         return;
     }
 
@@ -1184,6 +1254,8 @@ TouchRejected(DeviceIntPtr sourcedev, TouchPointInfoPtr ti, XID resource,
      * the TouchOwnership or TouchBegin event to the new owner. */
     if (ev && ti->num_listeners > 0 && was_owner)
         TouchPuntToNextOwner(sourcedev, ti, ev);
+
+    CheckOldestTouch(sourcedev);
 }
 
 /**
@@ -1391,6 +1463,7 @@ DeliverTouchEmulatedEvent(DeviceIntPtr dev, TouchPointInfoPtr ti,
                 !dev->button->buttonsDown &&
                 dev->deviceGrab.fromPassiveGrab && GrabIsPointerGrab(grab)) {
                 (*dev->deviceGrab.DeactivateGrab) (dev);
+                CheckOldestTouch(dev);
                 return Success;
             }
         }
commit 163b0f375d73c05873fb341652de3ed347337828
Author: Chase Douglas <chase.douglas at canonical.com>
Date:   Tue Apr 10 17:12:41 2012 -0700

    Update event type when delivering end event to a pointer listener
    
    Just like when we deliver to a touch listener, we must convert a touch
    end event to an update event for further clients. This also ensures that
    the touch record is not deleted at the end of ProcessTouchEvent().
    
    Signed-off-by: Chase Douglas <chase.douglas at canonical.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xi/exevents.c b/Xi/exevents.c
index 3117123..a843e03 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -1757,6 +1757,13 @@ DeliverTouchEndEvent(DeviceIntPtr dev, TouchPointInfoPtr ti, InternalEvent *ev,
         listener->type == LISTENER_POINTER_GRAB) {
         rc = DeliverTouchEmulatedEvent(dev, ti, ev, listener, client, win,
                                        grab, xi2mask);
+
+        if (ti->num_listeners > 1) {
+            ev->any.type = ET_TouchUpdate;
+            ev->device_event.flags |= TOUCH_PENDING_END;
+            ti->pending_finish = TRUE;
+        }
+
         goto out;
     }
 
commit 210cd12c47d063f97915ff23292b61d09abfd73a
Author: Chase Douglas <chase.douglas at canonical.com>
Date:   Tue Apr 10 17:12:40 2012 -0700

    Don't update listener after deactivating implicit pointer grab
    
    After the pointer grab is deactivated, the touch listener record is
    updated at the end of DeliverTouchEmulatedEvent. However, the touch
    record is ended when the grab is deactivated, so the update to the
    listener record is in an array of memory that has been freed.
    
    Signed-off-by: Chase Douglas <chase.douglas at canonical.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xi/exevents.c b/Xi/exevents.c
index ff22240..3117123 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -1389,8 +1389,10 @@ DeliverTouchEmulatedEvent(DeviceIntPtr dev, TouchPointInfoPtr ti,
 
             if (ev->any.type == ET_TouchEnd &&
                 !dev->button->buttonsDown &&
-                dev->deviceGrab.fromPassiveGrab && GrabIsPointerGrab(grab))
+                dev->deviceGrab.fromPassiveGrab && GrabIsPointerGrab(grab)) {
                 (*dev->deviceGrab.DeactivateGrab) (dev);
+                return Success;
+            }
         }
     }
     else {
commit 82a1ae0af3b136371638659c3e909880a99f721c
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Apr 12 15:54:00 2012 +1000

    xfree86: after VT switching back, only enable previously enabled devices
    
    If a device was enabled before the VT switch, re-enabled it. Otherwise leave
    it as is, there was probably a reason why it was disabled.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Chase Douglas <chase.douglas at canonical.com>
    Reviewed-by: Daniel Stone <daniel at fooishbar.org>

diff --git a/hw/xfree86/common/xf86Events.c b/hw/xfree86/common/xf86Events.c
index 058057e..5896f22 100644
--- a/hw/xfree86/common/xf86Events.c
+++ b/hw/xfree86/common/xf86Events.c
@@ -449,6 +449,8 @@ xf86VTSwitch(void)
             xf86DisableInputHandler(ih);
         for (pInfo = xf86InputDevs; pInfo; pInfo = pInfo->next) {
             if (pInfo->dev) {
+                if (!pInfo->dev->enabled)
+                    pInfo->flags |= XI86_DEVICE_DISABLED;
                 xf86ReleaseKeys(pInfo->dev);
                 ProcessInputEvents();
                 DisableDevice(pInfo->dev, TRUE);
@@ -482,8 +484,9 @@ xf86VTSwitch(void)
 
             pInfo = xf86InputDevs;
             while (pInfo) {
-                if (pInfo->dev)
+                if (pInfo->dev && (pInfo->flags & XI86_DEVICE_DISABLED) == 0)
                     EnableDevice(pInfo->dev, TRUE);
+                pInfo->flags &= ~XI86_DEVICE_DISABLED;
                 pInfo = pInfo->next;
             }
             for (ih = InputHandlers; ih; ih = ih->next)
@@ -537,8 +540,9 @@ xf86VTSwitch(void)
 
         pInfo = xf86InputDevs;
         while (pInfo) {
-            if (pInfo->dev)
+            if (pInfo->dev && (pInfo->flags & XI86_DEVICE_DISABLED) == 0)
                 EnableDevice(pInfo->dev, TRUE);
+            pInfo->flags &= ~XI86_DEVICE_DISABLED;
             pInfo = pInfo->next;
         }
 
diff --git a/hw/xfree86/common/xf86Xinput.h b/hw/xfree86/common/xf86Xinput.h
index 3731a34..1d4363a 100644
--- a/hw/xfree86/common/xf86Xinput.h
+++ b/hw/xfree86/common/xf86Xinput.h
@@ -61,6 +61,9 @@
 #define XI86_ALWAYS_CORE	0x04    /* device always controls the pointer */
 /* the device sends Xinput and core pointer events */
 #define XI86_SEND_CORE_EVENTS	XI86_ALWAYS_CORE
+/* 0x08 is reserved for legacy XI86_SEND_DRAG_EVENTS, do not use for now */
+/* server-internal only */
+#define XI86_DEVICE_DISABLED    0x10    /* device was disabled before vt switch */
 
 /* This holds the input driver entry and module information. */
 typedef struct _InputDriverRec {
commit c5a45b0f7658c77725adce2b64a0fbd62f208328
Author: Daniel Kurtz <djkurtz at chromium.org>
Date:   Thu Apr 12 10:11:10 2012 +1000

    dix: don't BUG_WARN for button events from button-only device
    
    Events from button-only devices still need coordinates, and they get them
    from scale_to_desktop().  Therefore, a dev without valuators is not a bug.
    However, a dev with valuators, but less than two of them still is a bug.
    
    This was noticed when unplugging a "Creative Technology SB Arena Headset",
    which has some BTNs and some KEYs, but no REL or ABS valuators.
    It emits [BTN_3] = 0 on unplug, which would trigger the BUG_WARN.
    
    Signed-off-by: Daniel Kurtz <djkurtz at chromium.org>
    Reviewed-by: Chase Douglas <chase.douglas at canonical.com>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dix/getevents.c b/dix/getevents.c
index 3093786..23bbe06 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -848,7 +848,7 @@ scale_to_desktop(DeviceIntPtr dev, ValuatorMask *mask,
     ScreenPtr scr = miPointerGetScreen(dev);
     double x, y;
 
-    BUG_WARN(!dev->valuator || dev->valuator->numAxes < 2);
+    BUG_WARN(dev->valuator && dev->valuator->numAxes < 2);
     if (!dev->valuator || dev->valuator->numAxes < 2) {
         /* if we have no axes, last.valuators must be in screen coords
          * anyway */
commit 72cfc1a097dc1e09d2cd9415ef7855a2cef92351
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Apr 11 09:43:23 2012 +1000

    Xi: fix XITouchClass sourceid assignment
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Chase Douglas <chase.douglas at canonical.com>

diff --git a/Xi/xiquerydevice.c b/Xi/xiquerydevice.c
index 749bc24..15c8b2a 100644
--- a/Xi/xiquerydevice.c
+++ b/Xi/xiquerydevice.c
@@ -430,7 +430,7 @@ ListTouchInfo(DeviceIntPtr dev, xXITouchInfo * touch)
 {
     touch->type = XITouchClass;
     touch->length = sizeof(xXITouchInfo) >> 2;
-    touch->sourceid = touch->sourceid;
+    touch->sourceid = dev->touch->sourceid;
     touch->mode = dev->touch->mode;
     touch->num_touches = dev->touch->num_touches;
 


More information about the xorg-commit mailing list