Re: [PATCH 1/5] dix: re-implement enter/leave model.

2009-01-07 Thread Keith Packard
On Thu, 2009-01-08 at 10:13 +1000, Peter Hutterer wrote:
> The old model was implemented based on a misunderstanding of NotifyVirtual and
> NotifyNonlinearVirtual events. It became complicated and was broken in some
> places [1]. This patch wipes this model completely.

Independent of whether this has bugs remaining, this sequence looks like
the right approach to make this problem tractable. Please push this to
master and I'll work on pulling it into the 1.6 branch, reviewing it as
best I can in the process of doing that.

-- 
keith.pack...@intel.com


signature.asc
Description: This is a digitally signed message part
___
xorg mailing list
xorg@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/xorg

[PATCH 1/5] dix: re-implement enter/leave model.

2009-01-07 Thread Peter Hutterer
The old model was implemented based on a misunderstanding of NotifyVirtual and
NotifyNonlinearVirtual events. It became complicated and was broken in some
places [1]. This patch wipes this model completely.

A much simplified implementation is provided instead. Rather than a top-down
approach ("we have a tree of windows, which ones need to get which event")
this one uses a step-by-step approach. For each window W between A and B
determine the pointer window P as perceived by this window and determine the
event type based on this information. This is in-line with the model described
by Owen Taylor [2].

[1] http://lists.freedesktop.org/archives/xorg/2008-December/041559.html
[2] http://lists.freedesktop.org/archives/xorg/2008-August/037606.html
---
 dix/enterleave.c |  596 +-
 1 files changed, 317 insertions(+), 279 deletions(-)

diff --git a/dix/enterleave.c b/dix/enterleave.c
index 8176f96..df915f5 100644
--- a/dix/enterleave.c
+++ b/dix/enterleave.c
@@ -39,74 +39,21 @@
  * to a core client without confusing it, this is a rather complicated
  * approach.
  *
- * For a full description of the model from a window's perspective, see
+ * For a full description of the enter/leave model from a window's
+ * perspective, see
  * http://lists.freedesktop.org/archives/xorg/2008-August/037606.html
  *
+ * Additional notes:
+ * -) The core protocol spec says that "In a LeaveNotify event, if a child of 
the
+ * event window contains the initial position of the pointer, then the child
+ * component is set to that child. Otherwise, it is None.  For an EnterNotify
+ * event, if a child of the event window contains the final pointer position,
+ * then the child component is set to that child. Otherwise, it is None."
  *
- * EnterNotify(Virtual, B) means EnterNotify Event, detail Virtual, child = B.
- *
- * Pointer moves from A to B, nonlinear (CoreEnterLeaveNonLinear):
- * 1. a. if A has another pointer, goto 2.
- *b. otherwise, if A has a child with a pointer in it,
- *   LeaveNotify(Inferior) to A
- *   LeaveNotify(Virtual) between A and child(A)
- *
- * 2. Find common ancestor X between A and B.
- * 3. Find closest pointer window P between A and X.
- *a. if P exists
- *   LeaveNotify(Ancestor) to A
- *   LeaveNotify(Virtual) between A and P
- *b. otherwise, if P does not exist,
- *   LeaveNotify(NonLinear) to A
- *   LeaveNotify(NonLinearVirtual) between A and X.
- *
- * 4. If X does not have a pointer, EnterNotify(NonLinearVirtual, B) to X.
- * 5. Find closest pointer window P between X and B.
- *a. if P exists, EnterNotify(NonLinearVirtual) between X and P
- *b. otherwise, EnterNotify(NonLinearVirtual) between X and B
- *
- * 5. a. if B has another pointer in it, finish.
- *b. otherwise, if B has a child with a pointer in it
- *   LeaveNotify(Virtual) between child(B) and B.
- *   EnterNotify(Inferior) to B.
- *c. otherwise, EnterNotify(NonLinear) to B.
- *
- * --
- *
- * Pointer moves from A to B, A is a parent of B (CoreEnterLeaveToDescendant):
- * 1. a. If A has another pointer, goto 2.
- *b. Otherwise, LeaveNotify(Inferior) to A.
- *
- * 2. Find highest window X that has a pointer child that is not a child of B.
- *a. if X exists, EnterNotify(Virtual, B) between A and X,
- *   EnterNotify(Virtual, B) to X (if X has no pointer).
- *b. otherwise, EnterNotify(Virtual, B) between A and B.
- *
- * 3. a. if B has another pointer, finish
- *b. otherwise, if B has a child with a pointer in it,
- *   LeaveNotify(Virtual, child(B)) between child(B) and B.
- *   EnterNotify(Inferior, child(B)) to B.
- *c. otherwise, EnterNotify(Ancestor) to B.
- *
- * --
- *
- * Pointer moves from A to B, A is a child of B (CoreEnterLeaveToAncestor):
- * 1. a. If A has another pointer, goto 2.
- *b. Otherwise, if A has a child with a pointer in it.
- *   LeaveNotify(Inferior, child(A)) to A.
- *   EnterNotify(Virtual, child(A)) between A and child(A).
- *   Skip to 3.
- *
- * 2. Find closest pointer window P between A and B.
- *If P does not exist, P is B.
- *   LeaveNotify(Ancestor) to A.
- *   LeaveNotify(Virtual, A) between A and P.
- * 3. a. If B has another pointer, finish.
- *b. otherwise, EnterNotify(Inferior) to B.
+ * By inference, this means that only NotifyVirtual or NotifyNonlinearVirtual
+ * events may have a subwindow set to other than None.
  */
 
-#define WID(w) ((w) ? ((w)->drawable.id) : 0)
-
 /**
  * Return TRUE if @win has a pointer within its boundaries, excluding child
  * window.
@@ -123,109 +70,6 @@ HasPointer(WindowPtr win)
 return FALSE;
 }
 
-static BOOL
-HasOtherPointer(WindowPtr win, DeviceIntPtr dev)
-{
-int i;
-
-for (i = 0; i < sizeof(win->enterleave); i++)
-if (win->