summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: d7be0c1)
raw | patch | inline | side by side (parent: d7be0c1)
author | Chase Douglas <chase.douglas@ubuntu.com> | |
Thu, 19 Apr 2012 19:34:54 +0000 (12:34 -0700) | ||
committer | Xavier Boudet <x-boudet@ti.com> | |
Wed, 2 May 2012 08:53:23 +0000 (08:53 +0000) |
14 files changed:
Xext/xtest.c | patch | blob | history | |
Xi/exevents.c | patch | blob | history | |
Xi/xipassivegrab.c | patch | blob | history | |
debian/changelog | patch | blob | history | |
debian/patches/501_touch_accept_end.patch | [deleted file] | patch | blob | history |
debian/patches/502_indirect_touch_window_set.patch | [deleted file] | patch | blob | history |
debian/patches/503_fix_mouse_warp.patch | [deleted file] | patch | blob | history |
debian/patches/504_implement_passive_touch_ungrab.patch | [deleted file] | patch | blob | history |
debian/patches/506_touchscreen_pointer_emulation_checks.patch | patch | blob | history | |
debian/patches/507_touchscreen_fixes.patch | [new file with mode: 0644] | patch | blob |
debian/patches/series | patch | blob | history | |
dix/getevents.c | patch | blob | history | |
dix/touch.c | patch | blob | history | |
include/input.h | patch | blob | history |
diff --git a/Xext/xtest.c b/Xext/xtest.c
index cc675c1161c7d80b553a8456a6b757710c6eea2d..9f0701666211546b7b7469458065d93519adf89e 100644 (file)
--- a/Xext/xtest.c
+++ b/Xext/xtest.c
rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
if (rc != Success)
return rc;
+
+ if (!ptr)
+ return BadAccess;
+
if (stuff->cursor == None)
pCursor = NullCursor;
else if (stuff->cursor == XTestCurrentCursor)
return BadValue;
}
+ /* Technically the protocol doesn't allow for BadAccess here but
+ * this can only happen when all MDs are disabled. */
+ if (!dev)
+ return BadAccess;
+
dev = GetXTestDevice(dev);
}
+
/* If the event has a time set, wait for it to pass */
if (ev->u.keyButtonPointer.time)
{
diff --git a/Xi/exevents.c b/Xi/exevents.c
index f390f67393b2965d6a5ae3da44ebefff245534dc..d71e604350beb307f6814b4f7655f319c24c1638 100644 (file)
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
/* Owner accepted after receiving end */
if (ti->listeners[0].state == LISTENER_HAS_END)
TouchEndTouch(dev, ti);
+ else
+ ti->listeners[0].state = LISTENER_HAS_ACCEPTED;
} else { /* this is the very first ownership event for a grab */
DeliverTouchEvents(dev, ti, (InternalEvent*)ev, ev->resource);
}
@@ -1781,7 +1783,11 @@ DeliverTouchBeginEvent(DeviceIntPtr dev, TouchPointInfoPtr ti, InternalEvent *ev
{
if (has_ownershipmask)
TouchSendOwnershipEvent(dev, ti, 0, listener->listener);
- state = LISTENER_IS_OWNER;
+
+ if (!has_ownershipmask || listener->type == LISTENER_REGULAR)
+ state = LISTENER_HAS_ACCEPTED;
+ else
+ state = LISTENER_IS_OWNER;
}
listener->state = state;
@@ -1812,22 +1818,23 @@ DeliverTouchEndEvent(DeviceIntPtr dev, TouchPointInfoPtr ti, InternalEvent *ev,
listener->state = LISTENER_HAS_END;
} else if (TouchResourceIsOwner(ti, listener->listener))
{
+ Bool normal_end = !(ev->device_event.flags & TOUCH_ACCEPT);
+
/* FIXME: what about early acceptance */
- if (!(ev->device_event.flags & TOUCH_ACCEPT))
- {
- if (listener->state != LISTENER_HAS_END)
- rc = DeliverOneTouchEvent(client, dev, ti, grab, win, ev);
- listener->state = LISTENER_HAS_END;
- }
+ if (normal_end && listener->state != LISTENER_HAS_END)
+ rc = DeliverOneTouchEvent(client, dev, ti, grab, win, ev);
+
if ((ti->num_listeners > 1 ||
- (listener->type == LISTENER_GRAB &&
- xi2mask_isset(xi2mask, dev, XI_TouchOwnership))) &&
+ listener->state != LISTENER_HAS_ACCEPTED) &&
(ev->device_event.flags & (TOUCH_ACCEPT|TOUCH_REJECT)) == 0)
{
ev->any.type = ET_TouchUpdate;
ev->device_event.flags |= TOUCH_PENDING_END;
ti->pending_finish = TRUE;
}
+
+ if (normal_end)
+ listener->state = LISTENER_HAS_END;
}
out:
diff --git a/Xi/xipassivegrab.c b/Xi/xipassivegrab.c
index d91170241e34cb78f65cd344c8234ff37b934d31..89a285f6196508abb6c85db7a616bc60cc3f207e 100644 (file)
--- a/Xi/xipassivegrab.c
+++ b/Xi/xipassivegrab.c
if (stuff->grab_type != XIGrabtypeButton &&
stuff->grab_type != XIGrabtypeKeycode &&
stuff->grab_type != XIGrabtypeEnter &&
- stuff->grab_type != XIGrabtypeFocusIn)
+ stuff->grab_type != XIGrabtypeFocusIn &&
+ stuff->grab_type != XIGrabtypeTouchBegin)
{
client->errorValue = stuff->grab_type;
return BadValue;
}
if ((stuff->grab_type == XIGrabtypeEnter ||
- stuff->grab_type == XIGrabtypeFocusIn) && stuff->detail != 0)
+ stuff->grab_type == XIGrabtypeFocusIn ||
+ stuff->grab_type == XIGrabtypeTouchBegin) && stuff->detail != 0)
{
client->errorValue = stuff->detail;
return BadValue;
case XIGrabtypeKeycode: tempGrab->type = XI_KeyPress; break;
case XIGrabtypeEnter: tempGrab->type = XI_Enter; break;
case XIGrabtypeFocusIn: tempGrab->type = XI_FocusIn; break;
+ case XIGrabtypeTouchBegin: tempGrab->type = XI_TouchBegin; break;
}
tempGrab->grabtype = XI2;
tempGrab->modifierDevice = mod_dev;
diff --git a/debian/changelog b/debian/changelog
index 8abf057d102bb55fc78ad0dc7a4b766ba18e90e2..58183750a3a7d1cd215e81ee676629efe2d4cbc1 100644 (file)
--- a/debian/changelog
+++ b/debian/changelog
+xorg-server (2:1.11.4-0ubuntu10.1) precise-proposed; urgency=low
+
+ [ Bryce Harrington ]
+ * Enable 227_null_ptr_midispcur.patch to apply
+
+ [ Chase Douglas ]
+ * Update to xserver 1.12.1 for the input stack
+ * Drop patches merged upstream in 1.12.1:
+ - 501_touch_accept_end.patch
+ - 502_indirect_touch_window_set.patch
+ - 503_fix_mouse_warp.patch
+ - 504_implement_passive_touch_ungrab.patch
+ * Fix patch 506_touchscreen_pointer_emulation_checks.patch after upstream
+ review
+ * Fix various touchscreen issues (LP: #974887)
+ - Add temporary patch 506_touchscreen_fixes.patch, which is a combination of
+ multiple upstream patches
+
+ -- Chase Douglas <chase.douglas@ubuntu.com> Thu, 19 Apr 2012 12:34:54 -0700
+
xorg-server (2:1.11.4-0ubuntu10) precise; urgency=low
* Fix touchscreen pointer emulation (LP: #949791)
diff --git a/debian/patches/501_touch_accept_end.patch b/debian/patches/501_touch_accept_end.patch
+++ /dev/null
@@ -1,95 +0,0 @@
-From 40cd6abb66787c79465cda03c17297a06d1cd848 Mon Sep 17 00:00:00 2001
-From: Chase Douglas <chase.douglas@canonical.com>
-Date: Fri, 2 Mar 2012 14:40:07 -0800
-Subject: [PATCH 1/2] Xi: Fix TouchEnd to TouchUpdate change for one accepted
- grab
-
-If there is only one listener of a touch, the listener is a grab, and is
-accepted before the touch has ended, the current code will not end the
-touch record when the touch does end.
-
-This change adds a listener state for when a touch is accepted but has
-not yet ended. We now keep the touch record alive in this state, but end
-it when the touch ends.
-
-Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
----
- Xi/exevents.c | 25 ++++++++++++++++---------
- include/input.h | 3 ++-
- 2 files changed, 18 insertions(+), 10 deletions(-)
-
-diff --git a/Xi/exevents.c b/Xi/exevents.c
-index f390f67..d71e604 100644
---- a/Xi/exevents.c
-+++ b/Xi/exevents.c
-@@ -1252,6 +1252,8 @@ ProcessTouchOwnershipEvent(DeviceIntPtr dev, TouchPointInfoPtr ti,
- /* Owner accepted after receiving end */
- if (ti->listeners[0].state == LISTENER_HAS_END)
- TouchEndTouch(dev, ti);
-+ else
-+ ti->listeners[0].state = LISTENER_HAS_ACCEPTED;
- } else { /* this is the very first ownership event for a grab */
- DeliverTouchEvents(dev, ti, (InternalEvent*)ev, ev->resource);
- }
-@@ -1781,7 +1783,11 @@ DeliverTouchBeginEvent(DeviceIntPtr dev, TouchPointInfoPtr ti, InternalEvent *ev
- {
- if (has_ownershipmask)
- TouchSendOwnershipEvent(dev, ti, 0, listener->listener);
-- state = LISTENER_IS_OWNER;
-+
-+ if (!has_ownershipmask || listener->type == LISTENER_REGULAR)
-+ state = LISTENER_HAS_ACCEPTED;
-+ else
-+ state = LISTENER_IS_OWNER;
- }
- listener->state = state;
-
-@@ -1812,22 +1818,23 @@ DeliverTouchEndEvent(DeviceIntPtr dev, TouchPointInfoPtr ti, InternalEvent *ev,
- listener->state = LISTENER_HAS_END;
- } else if (TouchResourceIsOwner(ti, listener->listener))
- {
-+ Bool normal_end = !(ev->device_event.flags & TOUCH_ACCEPT);
-+
- /* FIXME: what about early acceptance */
-- if (!(ev->device_event.flags & TOUCH_ACCEPT))
-- {
-- if (listener->state != LISTENER_HAS_END)
-- rc = DeliverOneTouchEvent(client, dev, ti, grab, win, ev);
-- listener->state = LISTENER_HAS_END;
-- }
-+ if (normal_end && listener->state != LISTENER_HAS_END)
-+ rc = DeliverOneTouchEvent(client, dev, ti, grab, win, ev);
-+
- if ((ti->num_listeners > 1 ||
-- (listener->type == LISTENER_GRAB &&
-- xi2mask_isset(xi2mask, dev, XI_TouchOwnership))) &&
-+ listener->state != LISTENER_HAS_ACCEPTED) &&
- (ev->device_event.flags & (TOUCH_ACCEPT|TOUCH_REJECT)) == 0)
- {
- ev->any.type = ET_TouchUpdate;
- ev->device_event.flags |= TOUCH_PENDING_END;
- ti->pending_finish = TRUE;
- }
-+
-+ if (normal_end)
-+ listener->state = LISTENER_HAS_END;
- }
-
- out:
-diff --git a/include/input.h b/include/input.h
-index b7825a7..1e9e0fd 100644
---- a/include/input.h
-+++ b/include/input.h
-@@ -585,7 +585,8 @@ enum TouchListenerState{
- LISTENER_AWAITING_OWNER, /**< Waiting for a TouchOwnership event */
- LISTENER_EARLY_ACCEPT, /**< Waiting for ownership, has already
- accepted */
-- LISTENER_IS_OWNER, /**< Is the current owner */
-+ LISTENER_IS_OWNER, /**< Is the current owner, hasn't accepted */
-+ LISTENER_HAS_ACCEPTED, /**< Is the current owner, has accepted */
- LISTENER_HAS_END, /**< Has already received the end event */
- };
-
---
-1.7.9
-
diff --git a/debian/patches/502_indirect_touch_window_set.patch b/debian/patches/502_indirect_touch_window_set.patch
+++ /dev/null
@@ -1,40 +0,0 @@
-From d128edad09452246e18b38cef151cad226f1c5f5 Mon Sep 17 00:00:00 2001
-From: Chase Douglas <chase.douglas@canonical.com>
-Date: Wed, 7 Mar 2012 15:20:12 -0800
-Subject: [PATCH 2/2] Use a new sprite trace for indirect touches when all
- touches have physically ended
-
-All touches of an indirect device, such as a trackpad, are sent to the
-same window set. When there are no active touches, a new window set is
-created; otherwise, the window set of an existing touch is copied.
-
-The current code checks for any logically active touches. This includes
-touches that have physically ended but are still logically active due to
-unhandled touch grabs. Instead, we want a new window set whenever there
-are no physically active touches.
-
-This change skips over logically active but pending end touches, which
-are touches that have physically ended.
-
-Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
----
- dix/touch.c | 3 ++-
- 1 files changed, 2 insertions(+), 1 deletions(-)
-
-diff --git a/dix/touch.c b/dix/touch.c
-index d04801c..0aa24f2 100644
---- a/dix/touch.c
-+++ b/dix/touch.c
-@@ -524,7 +524,8 @@ TouchBuildDependentSpriteTrace(DeviceIntPtr dev, SpritePtr sprite)
- /* All touches should have the same sprite trace, so find and reuse an
- * existing touch's sprite if possible, else use the device's sprite. */
- for (i = 0; i < t->num_touches; i++)
-- if (t->touches[i].sprite.spriteTraceGood > 0)
-+ if (!t->touches[i].pending_finish &&
-+ t->touches[i].sprite.spriteTraceGood > 0)
- break;
- if (i < t->num_touches)
- srcsprite = &t->touches[i].sprite;
---
-1.7.9
-
diff --git a/debian/patches/503_fix_mouse_warp.patch b/debian/patches/503_fix_mouse_warp.patch
+++ /dev/null
@@ -1,52 +0,0 @@
-Subject: dix: set raw event values before adding up relative values (#46976)
-Date: Wed, 21 Mar 2012 04:09:18 -0000
-From: Peter Hutterer <peter.hutterer@who-t.net>
-
-Regression introduced in 4e52cc0ef48145134cd58d357fb7289e6f8bb709
-
-Raw event values are values as-is from the driver, modified only be
-transformation or acceleration. 4e52cc caused the mask to be updated from
-driver-submitted relative to device-absolute coordinates, and that mask was
-then written into the raw events.
-
-Move the raw event update into the respective branches for absolute/relative
-events.
-
-X.Org Bug 46976 <http://bugs.freedesktop.org/show_bug.cgi?id=46976>
-
-Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
-Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
-Reviewed-by: Daniel Stone <daniel@fooishbar.org>
-Reviewed-by: Simon Thum <simon.thum@gmx.de>
-
----
-dix/getevents.c | 9 +++++----
- 1 files changed, 5 insertions(+), 4 deletions(-)
-
-diff --git a/dix/getevents.c b/dix/getevents.c
-index 5b9cef3..fd5998d 100644
---- a/dix/getevents.c
-+++ b/dix/getevents.c
-@@ -1311,17 +1311,18 @@ fill_pointer_events(InternalEvent *events, DeviceIntPtr pDev, int type,
-
- transformAbsolute(pDev, &mask);
- clipAbsolute(pDev, &mask);
-+ if ((flags & POINTER_NORAW) == 0)
-+ set_raw_valuators(raw, &mask, raw->valuators.data);
- } else {
- if (flags & POINTER_ACCELERATE)
- accelPointer(pDev, &mask, ms);
-+ if ((flags & POINTER_NORAW) == 0)
-+ set_raw_valuators(raw, &mask, raw->valuators.data);
-+
- moveRelative(pDev, &mask);
- }
-
- /* valuators are in device coordinate system in absolute coordinates */
--
-- if ((flags & POINTER_NORAW) == 0)
-- set_raw_valuators(raw, &mask, raw->valuators.data);
--
- scale_to_desktop(pDev, &mask, &devx, &devy, &screenx, &screeny);
- scr = positionSprite(pDev, (flags & POINTER_ABSOLUTE) ? Absolute : Relative,
- &mask, &devx, &devy, &screenx, &screeny);
diff --git a/debian/patches/504_implement_passive_touch_ungrab.patch b/debian/patches/504_implement_passive_touch_ungrab.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-Implement passive touch ungrabbing. (LP: #968726)
-
-diff --git a/Xi/xipassivegrab.c b/Xi/xipassivegrab.c
-index d911702..89a285f 100644
---- a/Xi/xipassivegrab.c
-+++ b/Xi/xipassivegrab.c
-@@ -303,14 +303,16 @@ ProcXIPassiveUngrabDevice(ClientPtr client)
- if (stuff->grab_type != XIGrabtypeButton &&
- stuff->grab_type != XIGrabtypeKeycode &&
- stuff->grab_type != XIGrabtypeEnter &&
-- stuff->grab_type != XIGrabtypeFocusIn)
-+ stuff->grab_type != XIGrabtypeFocusIn &&
-+ stuff->grab_type != XIGrabtypeTouchBegin)
- {
- client->errorValue = stuff->grab_type;
- return BadValue;
- }
-
- if ((stuff->grab_type == XIGrabtypeEnter ||
-- stuff->grab_type == XIGrabtypeFocusIn) && stuff->detail != 0)
-+ stuff->grab_type == XIGrabtypeFocusIn ||
-+ stuff->grab_type == XIGrabtypeTouchBegin) && stuff->detail != 0)
- {
- client->errorValue = stuff->detail;
- return BadValue;
-@@ -336,6 +338,7 @@ ProcXIPassiveUngrabDevice(ClientPtr client)
- case XIGrabtypeKeycode: tempGrab->type = XI_KeyPress; break;
- case XIGrabtypeEnter: tempGrab->type = XI_Enter; break;
- case XIGrabtypeFocusIn: tempGrab->type = XI_FocusIn; break;
-+ case XIGrabtypeTouchBegin: tempGrab->type = XI_TouchBegin; break;
- }
- tempGrab->grabtype = XI2;
- tempGrab->modifierDevice = mod_dev;
---
-1.7.9.1
-
diff --git a/debian/patches/506_touchscreen_pointer_emulation_checks.patch b/debian/patches/506_touchscreen_pointer_emulation_checks.patch
index 11a9ea203cf2cf339a361b83d9dafee6fa6178f1..c6fcac8db809983dade30ba5671487a64ae14cca 100644 (file)
-From c149cf06d1966d134073d4b33f2ec028fbf7bbd1 Mon Sep 17 00:00:00 2001
+From ec9c4295830c3de610e65aca17f4da4a7af3c4c5 Mon Sep 17 00:00:00 2001
From: Chase Douglas <chase.douglas@canonical.com>
-Date: Wed, 4 Apr 2012 12:41:59 -0700
-Subject: [PATCH 1/3] Don't attempt to add non-master core touch pointer
- emulation listeners
+Date: Wed, 18 Apr 2012 12:04:58 -0700
+Subject: [PATCH] Check other clients' core masks properly when adding touch
+ listener
-Core events aren't generated for slave devices, so this is just wrong.
-On top of that, the mask being checked in the removed hunk is wrong as
-well. It is dereferencing a pointer of type OtherClients as though it
-were a pointer to type InputClients.
+The current code checks the core event mask as though it were an XI
+mask. This change fixes the checks so the proper client and event masks
+are used.
Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
-
-Conflicts:
-
- dix/touch.c
+Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
---
- dix/touch.c | 12 ------------
- 1 files changed, 0 insertions(+), 12 deletions(-)
+ dix/touch.c | 8 ++++----
+ 1 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/dix/touch.c b/dix/touch.c
-index d04801c..87b0f15 100644
+index 572bdfb..f8f26c8 100644
--- a/dix/touch.c
+++ b/dix/touch.c
-@@ -853,18 +853,6 @@ TouchAddRegularListener(DeviceIntPtr dev, TouchPointInfoPtr ti,
- win);
- return TRUE;
+@@ -811,6 +811,7 @@ TouchAddRegularListener(DeviceIntPtr dev, TouchPointInfoPtr ti,
+ if (mask & EVENT_CORE_MASK) {
+ int coretype = GetCoreType(TouchGetPointerEventType(ev));
+ Mask core_filter = event_get_filter_from_type(dev, coretype);
++ OtherClients *oclients;
+
+ /* window owner */
+ if (IsMaster(dev) && (win->eventMask & core_filter)) {
+@@ -822,13 +823,12 @@ TouchAddRegularListener(DeviceIntPtr dev, TouchPointInfoPtr ti,
}
--
-- /* all others */
+
+ /* all others */
- nt_list_for_each_entry(iclients, (InputClients*)wOtherClients(win), next)
- {
- if (!(iclients->mask[XIAllDevices] & core_filter))
-- continue;
--
-- TouchEventHistoryAllocate(ti);
-- TouchAddListener(ti, iclients->resource, CORE,
-- type, LISTENER_AWAITING_BEGIN, win);
-- return TRUE;
-- }
- }
++ nt_list_for_each_entry(oclients, wOtherClients(win), next) {
++ if (!(oclients->mask & core_filter))
+ continue;
- return FALSE;
+ TouchEventHistoryAllocate(ti);
+- TouchAddListener(ti, iclients->resource, CORE,
++ TouchAddListener(ti, oclients->resource, CORE,
+ type, LISTENER_AWAITING_BEGIN, win);
+ return TRUE;
+ }
--
1.7.9.1
diff --git a/debian/patches/507_touchscreen_fixes.patch b/debian/patches/507_touchscreen_fixes.patch
--- /dev/null
@@ -0,0 +1,540 @@
+--- a/Xi/exevents.c
++++ b/Xi/exevents.c
+@@ -1148,6 +1148,48 @@ EmitTouchEnd(DeviceIntPtr dev, TouchPoin
+ }
+
+ /**
++ * 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.
+ */
+@@ -1159,8 +1201,16 @@ TouchPuntToNextOwner(DeviceIntPtr dev, T
+ if (ti->listeners[0].state == LISTENER_AWAITING_OWNER ||
+ 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. */
+@@ -1177,6 +1227,25 @@ TouchPuntToNextOwner(DeviceIntPtr dev, T
+ }
+
+ /**
++ * 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.
+@@ -1205,14 +1274,6 @@ TouchRejected(DeviceIntPtr sourcedev, To
+ }
+ }
+
+- /* If there are no other listeners left, and the touchpoint is pending
+- * finish, then we can just kill it now. */
+- if (ti->num_listeners == 1 && ti->pending_finish)
+- {
+- TouchEndTouch(sourcedev, ti);
+- return;
+- }
+-
+ /* 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))
+@@ -1226,6 +1287,10 @@ TouchRejected(DeviceIntPtr sourcedev, To
+ * the TouchOwnership or TouchBegin event to the new owner. */
+ if (ev && ti->num_listeners > 0 && was_owner)
+ TouchPuntToNextOwner(sourcedev, ti, ev);
++ else if (ti->num_listeners == 0)
++ TouchEndTouch(sourcedev, ti);
++
++ CheckOldestTouch(sourcedev);
+ }
+
+ /**
+@@ -1243,9 +1308,18 @@ ProcessTouchOwnershipEvent(DeviceIntPtr
+ if (ev->reason == XIRejectTouch)
+ TouchRejected(dev, ti, ev->resource, ev);
+ else if (ev->reason == XIAcceptTouch) {
++ int i;
++
++ /* Go through the motions of ending the touch if the listener has
++ * already seen the end. This ensures that the touch record is ended in
++ * the server. */
++ if (ti->listeners[0].state == LISTENER_HAS_END)
++ EmitTouchEnd(dev, ti, TOUCH_ACCEPT, ti->listeners[0].listener);
++
+ /* The touch owner has accepted the touch. Send TouchEnd events to
+ * everyone else, and truncate the list of listeners. */
+- EmitTouchEnd(dev, ti, TOUCH_ACCEPT, 0);
++ for (i = 1; i < ti->num_listeners; i++)
++ EmitTouchEnd(dev, ti, TOUCH_ACCEPT, ti->listeners[i].listener);
+
+ while (ti->num_listeners > 1)
+ TouchRemoveListener(ti, ti->listeners[1].listener);
+@@ -1428,11 +1502,21 @@ DeliverTouchEmulatedEvent(DeviceIntPtr d
+ if (!deliveries)
+ DeliverOneGrabbedEvent(ptrev, dev, grab->grabtype);
+
++ /* We must accept the touch sequence once a pointer listener has
++ * received one event past ButtonPress. */
++ if (deliveries && ev->any.type != ET_TouchBegin &&
++ !(ev->device_event.flags & TOUCH_CLIENT_ID))
++ TouchListenerAcceptReject(dev, ti, 0, XIAcceptTouch);
++
+ if (ev->any.type == ET_TouchEnd &&
++ !(ev->device_event.flags & TOUCH_CLIENT_ID) &&
+ !dev->button->buttonsDown &&
+ dev->deviceGrab.fromPassiveGrab &&
+- GrabIsPointerGrab(grab))
++ GrabIsPointerGrab(grab)) {
+ (*dev->deviceGrab.DeactivateGrab)(dev);
++ CheckOldestTouch(dev);
++ return Success;
++ }
+ }
+ } else
+ {
+@@ -1552,12 +1636,43 @@ ProcessTouchEvent(InternalEvent *ev, Dev
+ else
+ touchid = ev->device_event.touchid;
+
++ if (emulate_pointer)
++ UpdateDeviceState(dev, &ev->device_event);
++
+ if (type == ET_TouchBegin) {
+ ti = TouchBeginTouch(dev, ev->device_event.sourceid, touchid,
+ emulate_pointer);
+ } 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 &&
++ (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;
++ }
++
++ TouchBuildSprite(dev, ti, ev);
++ TouchSetupListeners(dev, ti, ev);
++ }
++
+ if (!ti)
+ {
+ DebugF("[Xi] %s: Failed to get event %d for touchpoint %d\n",
+@@ -1575,9 +1690,11 @@ ProcessTouchEvent(InternalEvent *ev, Dev
+ CheckMotion(&ev->device_event, dev);
+
+ /* Make sure we have a valid window trace for event delivery; must be
+- * called after event type mutation. */
++ * called after event type mutation. Touch end events are always processed
++ * in order to end touch records. */
+ /* FIXME: check this */
+- if (!TouchEnsureSprite(dev, ti, ev))
++ if ((type == ET_TouchBegin && !TouchBuildSprite(dev, ti, ev)) ||
++ (type != ET_TouchEnd && ti->sprite.spriteTraceGood == 0))
+ return;
+
+ /* TouchOwnership events are handled separately from the rest, as they
+@@ -1813,6 +1930,14 @@ DeliverTouchEndEvent(DeviceIntPtr dev, T
+ {
+ 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;
++ if (!(ev->device_event.flags & TOUCH_CLIENT_ID))
++ ti->pending_finish = TRUE;
++ }
++
+ goto out;
+ }
+
+@@ -1923,9 +2048,6 @@ DeliverTouchEvents(DeviceIntPtr dev, Tou
+
+ DeliverTouchEvent(dev, ti, ev, listener, client, win, grab, mask);
+ }
+-
+- if (ti->emulate_pointer)
+- UpdateDeviceState(dev, &ev->device_event);
+ }
+
+ int
+--- a/dix/dispatch.c
++++ b/dix/dispatch.c
+@@ -215,7 +215,7 @@ UpdateCurrentTimeIf(void)
+ systime.milliseconds = GetTimeInMillis();
+ if (systime.milliseconds < currentTime.milliseconds)
+ systime.months++;
+- if (*checkForInput[0] == *checkForInput[1])
++ if (CompareTimeStamps(systime, currentTime) == LATER)
+ currentTime = systime;
+ }
+
+@@ -408,6 +408,9 @@ Dispatch(void)
+ }
+ /* now, finally, deal with client requests */
+
++ /* Update currentTime so request time checks, such as for input
++ * device grabs, are calculated correctly */
++ UpdateCurrentTimeIf();
+ result = ReadRequestFromClient(client);
+ if (result <= 0)
+ {
+--- a/dix/events.c
++++ b/dix/events.c
+@@ -1312,14 +1312,10 @@ ComputeFreezes(void)
+ {
+ if (IsTouchEvent((InternalEvent*)event))
+ {
+- InternalEvent *events = InitEventList(GetMaximumEventsNum());
+- int i, nev;
+ TouchPointInfoPtr ti = TouchFindByClientID(replayDev, event->touchid);
+ BUG_WARN(!ti);
+- nev = GetTouchOwnershipEvents(events, replayDev, ti, XIRejectTouch, ti->listeners[0].listener, 0);
+- for (i = 0; i < nev; i++)
+- mieqProcessDeviceEvent(replayDev, events + i, NULL);
+- ProcessInputEvents();
++
++ TouchListenerAcceptReject(replayDev, ti, 0, XIRejectTouch);
+ } else if (replayDev->focus && !IsPointerEvent((InternalEvent*)event))
+ DeliverFocusedEvent(replayDev, (InternalEvent*)event, w);
+ else
+@@ -1459,6 +1455,38 @@ ReattachToOldMaster(DeviceIntPtr dev)
+ }
+
+ /**
++ * Update touch records when an explicit grab is activated. Any touches owned by
++ * the grabbing client are updated so the listener state reflects the new grab.
++ */
++static void
++UpdateTouchesForGrab(DeviceIntPtr mouse)
++{
++ int i;
++
++ if (!mouse->touch || mouse->deviceGrab.fromPassiveGrab)
++ return;
++
++ for (i = 0; i < mouse->touch->num_touches; i++) {
++ TouchPointInfoPtr ti = mouse->touch->touches + i;
++ GrabPtr grab = mouse->deviceGrab.grab;
++
++ if (ti->active &&
++ CLIENT_BITS(ti->listeners[0].listener) == grab->resource) {
++ ti->listeners[0].listener = grab->resource;
++ ti->listeners[0].level = grab->grabtype;
++ ti->listeners[0].state = LISTENER_IS_OWNER;
++ ti->listeners[0].window = grab->window;
++
++ if (grab->grabtype == CORE || grab->grabtype == XI ||
++ !xi2mask_isset(grab->xi2mask, mouse, XI_TouchBegin))
++ ti->listeners[0].type = LISTENER_POINTER_GRAB;
++ else
++ ti->listeners[0].type = LISTENER_GRAB;
++ }
++ }
++}
++
++/**
+ * Activate a pointer grab on the given device. A pointer grab will cause all
+ * core pointer events of this device to be delivered to the grabbing client only.
+ * No other device will send core events to the grab client while the grab is
+@@ -1509,6 +1537,7 @@ ActivatePointerGrab(DeviceIntPtr mouse,
+ grabinfo->fromPassiveGrab = isPassive;
+ grabinfo->implicitGrab = autoGrab & ImplicitGrabMask;
+ PostNewCursor(mouse);
++ UpdateTouchesForGrab(mouse);
+ CheckGrabForSyncs(mouse,(Bool)grab->pointerMode, (Bool)grab->keyboardMode);
+ }
+
+@@ -1524,6 +1553,8 @@ DeactivatePointerGrab(DeviceIntPtr mouse
+ DeviceIntPtr dev;
+ Bool wasImplicit = (mouse->deviceGrab.fromPassiveGrab &&
+ mouse->deviceGrab.implicitGrab);
++ XID grab_resource = grab->resource;
++ int i;
+
+ TouchRemovePointerGrab(mouse);
+
+@@ -1549,6 +1580,15 @@ 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);
++ }
+ }
+
+ /**
+--- a/dix/touch.c
++++ b/dix/touch.c
+@@ -375,13 +375,6 @@ TouchEndTouch(DeviceIntPtr dev, TouchPoi
+ if (ti->emulate_pointer)
+ {
+ GrabPtr grab;
+- DeviceEvent ev;
+- memset(&ev, 0, sizeof(ev));
+- ev.type = ET_TouchEnd;
+- ev.detail.button = 1;
+- ev.touchid = ti->client_id;
+- ev.flags = TOUCH_POINTER_EMULATED|TOUCH_END;
+- UpdateDeviceState(dev, &ev);
+
+ if ((grab = dev->deviceGrab.grab))
+ {
+@@ -496,10 +489,22 @@ TouchEventHistoryReplay(TouchPointInfoPt
+ flags = TOUCH_CLIENT_ID|TOUCH_REPLAYING;
+ if (ti->emulate_pointer)
+ flags |= TOUCH_POINTER_EMULATED;
+- /* send fake begin event to next owner */
++ /* Generate events based on a fake touch begin event to get DCCE events if
++ * needed */
++ /* FIXME: This needs to be cleaned up */
+ nev = GetTouchEvents(tel, dev, ti->client_id, XI_TouchBegin, flags, mask);
+- for (i = 0; i < nev; i++)
+- DeliverTouchEvents(dev, ti, tel + i, resource);
++ for (i = 0; i < nev; i++) {
++ /* Send saved touch begin event */
++ if (tel[i].any.type == ET_TouchBegin) {
++ DeviceEvent *ev = &ti->history[0];
++ ev->flags |= TOUCH_REPLAYING;
++ DeliverTouchEvents(dev, ti, (InternalEvent*)ev, resource);
++ }
++ else {/* Send DCCE event */
++ tel[i].any.time = ti->history[0].time;
++ DeliverTouchEvents(dev, ti, tel + i, resource);
++ }
++ }
+
+ valuator_mask_free(&mask);
+ FreeEventList(tel, GetMaximumEventsNum());
+@@ -558,22 +563,12 @@ TouchBuildDependentSpriteTrace(DeviceInt
+ * TouchBegin events.
+ */
+ Bool
+-TouchEnsureSprite(DeviceIntPtr sourcedev, TouchPointInfoPtr ti,
+- InternalEvent *ev)
++TouchBuildSprite(DeviceIntPtr sourcedev, TouchPointInfoPtr ti,
++ InternalEvent *ev)
+ {
+ TouchClassPtr t = sourcedev->touch;
+ SpritePtr sprite = &ti->sprite;
+
+- /* We may not have a sprite if there are no applicable grabs or
+- * event selections, or if they've disappeared, or if all the grab
+- * owners have rejected the touch. Don't bother delivering motion
+- * events if not, but TouchEnd events still need to be processed so
+- * we can call FinishTouchPoint and release it for later use. */
+- if (ev->any.type == ET_TouchEnd)
+- return TRUE;
+- else if (ev->any.type != ET_TouchBegin)
+- return (sprite->spriteTraceGood > 0);
+-
+ if (t->mode == XIDirectTouch)
+ {
+ /* Focus immediately under the touchpoint in direct touch mode.
+@@ -897,6 +892,11 @@ TouchSetupListeners(DeviceIntPtr dev, To
+ if (dev->deviceGrab.grab)
+ TouchAddActiveGrabListener(dev, ti, ev, dev->deviceGrab.grab);
+
++ /* We set up an active touch listener for existing touches, but not any
++ * passive grab or regular listeners. */
++ if (ev->any.type != ET_TouchBegin)
++ return;
++
+ /* First, find all grabbing clients from the root window down
+ * to the deepest child window. */
+ for (i = 0; i < sprite->spriteTraceGood; i++)
+@@ -988,15 +988,48 @@ TouchListenerGone(XID resource)
+ }
+
+ int
++TouchListenerAcceptReject(DeviceIntPtr dev, TouchPointInfoPtr ti, int listener,
++ int mode)
++{
++ InternalEvent *events;
++ int nev;
++ int i;
++
++ if (listener > 0) {
++ if (mode == XIRejectTouch)
++ TouchRejected(dev, ti, ti->listeners[listener].listener, NULL);
++ else
++ ti->listeners[listener].state = LISTENER_EARLY_ACCEPT;
++
++ return Success;
++ }
++
++ events = InitEventList(GetMaximumEventsNum());
++ if (!events) {
++ BUG_WARN_MSG(TRUE, "Failed to allocate touch ownership events\n");
++ return BadAlloc;
++ }
++
++ nev = GetTouchOwnershipEvents(events, dev, ti, mode,
++ ti->listeners[0].listener, 0);
++ BUG_WARN_MSG(nev == 0, "Failed to get touch ownership events\n");
++
++ for (i = 0; i < nev; i++)
++ mieqProcessDeviceEvent(dev, events + i, NULL);
++
++ ProcessInputEvents();
++
++ FreeEventList(events, GetMaximumEventsNum());
++
++ return nev ? Success : BadMatch;
++}
++
++int
+ TouchAcceptReject(ClientPtr client, DeviceIntPtr dev, int mode,
+ uint32_t touchid, Window grab_window, XID *error)
+ {
+ TouchPointInfoPtr ti;
+- int nev, i;
+- InternalEvent *events = InitEventList(GetMaximumEventsNum());
+-
+- if (!events)
+- return BadAlloc;
++ int i;
+
+ if (!dev->touch)
+ {
+@@ -1020,25 +1053,5 @@ TouchAcceptReject(ClientPtr client, Devi
+ if (i == ti->num_listeners)
+ return BadAccess;
+
+- if (i > 0)
+- {
+- if (mode == XIRejectTouch)
+- TouchRejected(dev, ti, ti->listeners[i].listener, NULL);
+- else
+- ti->listeners[i].state = LISTENER_EARLY_ACCEPT;
+-
+- return Success;
+- }
+-
+- nev = GetTouchOwnershipEvents(events, dev, ti, mode,
+- ti->listeners[0].listener, 0);
+- if (nev == 0)
+- return BadAlloc;
+- for (i = 0; i < nev; i++)
+- mieqProcessDeviceEvent(dev, events + i, NULL);
+-
+- ProcessInputEvents();
+-
+- FreeEventList(events, GetMaximumEventsNum());
+- return Success;
++ return TouchListenerAcceptReject(dev, ti, i, mode);
+ }
+--- a/include/input.h
++++ b/include/input.h
+@@ -624,14 +624,16 @@ extern void TouchAddListener(TouchPointI
+ WindowPtr window);
+ extern Bool TouchRemoveListener(TouchPointInfoPtr ti, XID resource);
+ extern void TouchSetupListeners(DeviceIntPtr dev, TouchPointInfoPtr ti, InternalEvent *ev);
+-extern Bool TouchEnsureSprite(DeviceIntPtr sourcedev, TouchPointInfoPtr ti,
+- InternalEvent *ev);
++extern Bool TouchBuildSprite(DeviceIntPtr sourcedev, TouchPointInfoPtr ti,
++ InternalEvent *ev);
+ extern Bool TouchBuildDependentSpriteTrace(DeviceIntPtr dev, SpritePtr sprite);
+ extern int TouchConvertToPointerEvent(const InternalEvent *ev,
+ InternalEvent *motion, InternalEvent *button);
+ extern int TouchGetPointerEventType(const InternalEvent *ev);
+ extern void TouchRemovePointerGrab(DeviceIntPtr dev);
+ extern void TouchListenerGone(XID resource);
++extern int TouchListenerAcceptReject(DeviceIntPtr dev, TouchPointInfoPtr ti,
++ int listener, int mode);
+ extern int TouchAcceptReject(ClientPtr client, DeviceIntPtr dev, int mode,
+ uint32_t touchid, Window grab_window, XID *error);
+
diff --git a/debian/patches/series b/debian/patches/series
index e07cbea54145882a2fbbb40612a405e2de2a7cd8..f17f72626e52b41cfb7442fbbffb99ad8ac07f6f 100644 (file)
--- a/debian/patches/series
+++ b/debian/patches/series
224_return_BadWindow_not_BadMatch.diff
225_non-root_config_paths.patch
226_fall_back_to_autoconfiguration.patch
+227_null_ptr_midispcur.patch
# Temporary, until it's reviewed & accepted upstream
500_pointer_barrier_thresholds.diff
-501_touch_accept_end.patch
-502_indirect_touch_window_set.patch
-503_fix_mouse_warp.patch
-504_implement_passive_touch_ungrab.patch
505_query_pointer_touchscreen.patch
506_touchscreen_pointer_emulation_checks.patch
+507_touchscreen_fixes.patch
diff --git a/dix/getevents.c b/dix/getevents.c
index 306d0ff09af75dcdece51a875b0d1a17adfe07ec..fd5998d7e6475de46072f84346bd56f91c76e55b 100644 (file)
--- a/dix/getevents.c
+++ b/dix/getevents.c
static void
updateSlaveDeviceCoords(DeviceIntPtr master, DeviceIntPtr pDev)
{
- ScreenPtr scr = miPointerGetScreen(pDev);
int i;
DeviceIntPtr lastSlave;
pDev->last.valuators[0] = rescaleValuatorAxis(pDev->last.valuators[0],
NULL,
pDev->valuator->axes + 0,
- 0, scr->width);
+ screenInfo.x,
+ screenInfo.width);
}
if(pDev->valuator->numAxes > 1)
{
pDev->last.valuators[1] = rescaleValuatorAxis(pDev->last.valuators[1],
NULL,
pDev->valuator->axes + 1,
- 0, scr->height);
+ screenInfo.y,
+ screenInfo.height);
}
/* calculate the other axis as well based on info from the old
transformAbsolute(pDev, &mask);
clipAbsolute(pDev, &mask);
+ if ((flags & POINTER_NORAW) == 0)
+ set_raw_valuators(raw, &mask, raw->valuators.data);
} else {
if (flags & POINTER_ACCELERATE)
accelPointer(pDev, &mask, ms);
+ if ((flags & POINTER_NORAW) == 0)
+ set_raw_valuators(raw, &mask, raw->valuators.data);
+
moveRelative(pDev, &mask);
}
/* valuators are in device coordinate system in absolute coordinates */
-
- if ((flags & POINTER_NORAW) == 0)
- set_raw_valuators(raw, &mask, raw->valuators.data);
-
scale_to_desktop(pDev, &mask, &devx, &devy, &screenx, &screeny);
scr = positionSprite(pDev, (flags & POINTER_ABSOLUTE) ? Absolute : Relative,
&mask, &devx, &devy, &screenx, &screeny);
diff --git a/dix/touch.c b/dix/touch.c
index d04801c86ad327c70449aaeec747dada90b9acf2..0aa24f293d6c9ea630dbcd1f61daceaaacf15fa2 100644 (file)
--- a/dix/touch.c
+++ b/dix/touch.c
/* All touches should have the same sprite trace, so find and reuse an
* existing touch's sprite if possible, else use the device's sprite. */
for (i = 0; i < t->num_touches; i++)
- if (t->touches[i].sprite.spriteTraceGood > 0)
+ if (!t->touches[i].pending_finish &&
+ t->touches[i].sprite.spriteTraceGood > 0)
break;
if (i < t->num_touches)
srcsprite = &t->touches[i].sprite;
diff --git a/include/input.h b/include/input.h
index 1015a747dea59ef76075507236d0057526a70c9d..8dec9fcbed290771f1dd9c69552572001b3bcf51 100644 (file)
--- a/include/input.h
+++ b/include/input.h
LISTENER_AWAITING_OWNER, /**< Waiting for a TouchOwnership event */
LISTENER_EARLY_ACCEPT, /**< Waiting for ownership, has already
accepted */
- LISTENER_IS_OWNER, /**< Is the current owner */
+ LISTENER_IS_OWNER, /**< Is the current owner, hasn't accepted */
+ LISTENER_HAS_ACCEPTED, /**< Is the current owner, has accepted */
LISTENER_HAS_END, /**< Has already received the end event */
};