Imported Debian patch 2:1.11.4-0ubuntu10.1
authorChase Douglas <chase.douglas@ubuntu.com>
Thu, 19 Apr 2012 19:34:54 +0000 (12:34 -0700)
committerXavier Boudet <x-boudet@ti.com>
Wed, 2 May 2012 08:53:23 +0000 (08:53 +0000)
14 files changed:
Xext/xtest.c
Xi/exevents.c
Xi/xipassivegrab.c
debian/changelog
debian/patches/501_touch_accept_end.patch [deleted file]
debian/patches/502_indirect_touch_window_set.patch [deleted file]
debian/patches/503_fix_mouse_warp.patch [deleted file]
debian/patches/504_implement_passive_touch_ungrab.patch [deleted file]
debian/patches/506_touchscreen_pointer_emulation_checks.patch
debian/patches/507_touchscreen_fixes.patch [new file with mode: 0644]
debian/patches/series
dix/getevents.c
dix/touch.c
include/input.h

index cc675c1161c7d80b553a8456a6b757710c6eea2d..9f0701666211546b7b7469458065d93519adf89e 100644 (file)
@@ -121,6 +121,10 @@ ProcXTestCompareCursor(ClientPtr client)
     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)
@@ -321,9 +325,15 @@ ProcXTestFakeInput(ClientPtr client)
                 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)
     {
index f390f67393b2965d6a5ae3da44ebefff245534dc..d71e604350beb307f6814b4f7655f319c24c1638 100644 (file)
@@ -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:
index d91170241e34cb78f65cd344c8234ff37b934d31..89a285f6196508abb6c85db7a616bc60cc3f207e 100644 (file)
@@ -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;
index 8abf057d102bb55fc78ad0dc7a4b766ba18e90e2..58183750a3a7d1cd215e81ee676629efe2d4cbc1 100644 (file)
@@ -1,3 +1,23 @@
+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
deleted file mode 100644 (file)
index 03f7524..0000000
+++ /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
deleted file mode 100644 (file)
index 5eafe81..0000000
+++ /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
deleted file mode 100644 (file)
index d0e9d66..0000000
+++ /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
deleted file mode 100644 (file)
index 48e8a0a..0000000
+++ /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
-
index 11a9ea203cf2cf339a361b83d9dafee6fa6178f1..c6fcac8db809983dade30ba5671487a64ae14cca 100644 (file)
@@ -1,46 +1,48 @@
-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
new file mode 100644 (file)
index 0000000..2209bac
--- /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);
index e07cbea54145882a2fbbb40612a405e2de2a7cd8..f17f72626e52b41cfb7442fbbffb99ad8ac07f6f 100644 (file)
 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
index 306d0ff09af75dcdece51a875b0d1a17adfe07ec..fd5998d7e6475de46072f84346bd56f91c76e55b 100644 (file)
@@ -323,7 +323,6 @@ rescaleValuatorAxis(double coord, AxisInfoPtr from, AxisInfoPtr to,
 static void
 updateSlaveDeviceCoords(DeviceIntPtr master, DeviceIntPtr pDev)
 {
-    ScreenPtr scr = miPointerGetScreen(pDev);
     int i;
     DeviceIntPtr lastSlave;
 
@@ -341,14 +340,16 @@ updateSlaveDeviceCoords(DeviceIntPtr master, DeviceIntPtr pDev)
         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
@@ -1310,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);
index d04801c86ad327c70449aaeec747dada90b9acf2..0aa24f293d6c9ea630dbcd1f61daceaaacf15fa2 100644 (file)
@@ -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;
index 1015a747dea59ef76075507236d0057526a70c9d..8dec9fcbed290771f1dd9c69552572001b3bcf51 100644 (file)
@@ -589,7 +589,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 */
 };