[prev in list] [next in list] [prev in thread] [next in thread] 

List:       freedesktop-xorg
Subject:    Re: [compiz] status of input redirection
From:       David Reveman <davidr () novell ! com>
Date:       2007-05-31 18:30:19
Message-ID: 1180636219.11472.29.camel () ion ! ximian
[Download RAW message or body]

On Tue, 2007-05-29 at 08:53 +0200, dragoran wrote:
> There where some patches to implement input redirection in xorg a while 
> ago...
> what happend to them? are they still beeing worked on?

The attached patches work well. The server patch needs some more work if
we want to allow different pickers and I haven't had time to do that
yet.

-David

["compositeproto-input-transform-1.patch" (compositeproto-input-transform-1.patch)]

--- a/composite.h
+++ b/composite.h
@@ -63,8 +63,9 @@
 #define X_CompositeNameWindowPixmap		6
 #define X_CompositeGetOverlayWindow             7
 #define X_CompositeReleaseOverlayWindow         8
-#define X_CompositeRedirectCoordinate		9
-#define X_CompositeTransformCoordinate		10
+#define X_CompositeSetTriangularCoordinateMesh	9
+#define X_CompositeRedirectCoordinate		10
+#define X_CompositeTransformCoordinate		11
 
 #define CompositeNumberRequests	    (X_CompositeTransformCoordinate + 1)
 
--- a/compositeproto.h
+++ b/compositeproto.h
@@ -192,6 +192,15 @@ typedef struct {
     CARD8   compositeReqType;
     CARD16  length;
     Window  window B32;
+} xCompositeSetTriangularCoordinateMeshReq;
+
+#define sz_xCompositeSetTriangularCoordinateMeshReq	8
+
+typedef struct {
+    CARD8   reqType;
+    CARD8   compositeReqType;
+    CARD16  length;
+    Window  window B32;
     BOOL    redirect;
     BYTE    unused1;
     CARD16  unused2 B16;
--- a/configure.ac
+++ b/configure.ac
@@ -24,7 +24,7 @@ dnl
 dnl Process this file with autoconf to create configure.
 
 AC_PREREQ([2.57])
-AC_INIT([CompositeProto], [0.3], [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg])
+AC_INIT([CompositeProto], [0.4], [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg])
 AM_INIT_AUTOMAKE([foreign dist-bzip2])
 AM_MAINTAINER_MODE
 

["libXcomposite-input-transform-1.patch" (libXcomposite-input-transform-1.patch)]

--- a/configure.ac
+++ b/configure.ac
@@ -34,7 +34,7 @@ dnl protocol, so Xcomposite version l.n.m corresponds to protocol \
version l.n  dnl that 'revision' number appears in Xcomposite.h and has to be \
manually  dnl synchronized.
 dnl
-AC_INIT(libXcomposite, 0.3.1, \
[https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], libXcomposite) \
+AC_INIT(libXcomposite, 0.4.0, \
[https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], libXcomposite)  \
AM_INIT_AUTOMAKE([dist-bzip2])  AM_MAINTAINER_MODE
 
@@ -52,7 +52,7 @@ if test "$VERSION" = "" ; then
 fi
 COMPOSITEEXT_VERSION=[`echo $VERSION | sed \
's/^\([0-9][0-9]*\.[0-9][0-9]*\).*$/\1/'`]  AC_SUBST(COMPOSITEEXT_VERSION)
-PKG_CHECK_MODULES(XCOMPOSITE, [compositeproto >= $COMPOSITEEXT_VERSION] x11 xfixes \
xext fixesproto) +PKG_CHECK_MODULES(XCOMPOSITE, [compositeproto >= \
$COMPOSITEEXT_VERSION] x11 xfixes xext fixesproto xrender renderproto)  \
AC_SUBST(XCOMPOSITE_CFLAGS)  AC_SUBST(XCOMPOSITE_LIBS)
 
--- a/include/X11/extensions/Xcomposite.h
+++ b/include/X11/extensions/Xcomposite.h
@@ -47,6 +47,7 @@
 
 #include <X11/extensions/composite.h>
 #include <X11/extensions/Xfixes.h>
+#include <X11/extensions/Xrender.h>
 #include <X11/Xfuncproto.h>
 
 /*
@@ -92,6 +93,12 @@ XCompositeGetOverlayWindow (Display *dpy, Window window);
 void
 XCompositeReleaseOverlayWindow (Display *dpy, Window window);
 
+void
+XCompositeSetTriangularCoordinateMesh (Display		  *dpy,
+				       Window		  window,
+				       _Xconst XTriangle *triangle,
+				       int		  nTriangle);
+
 _XFUNCPROTOEND
 
 #endif /* _XCOMPOSITE_H_ */
--- a/src/Xcomposite.c
+++ b/src/Xcomposite.c
@@ -391,3 +391,40 @@ XCompositeReleaseOverlayWindow (Display *dpy, Window window)
     UnlockDisplay (dpy);
     SyncHandle ();
 }
+
+void
+XCompositeSetTriangularCoordinateMesh (Display		  *dpy,
+				       Window		  window,
+				       _Xconst XTriangle *triangle,
+				       int		  nTriangle)
+{
+    XCompositeExtDisplayInfo *info = XCompositeFindDisplay (dpy);
+    xCompositeSetTriangularCoordinateMeshReq *req;
+    int					     n;
+    long				     len;
+
+    XCompositeSimpleCheckExtension (dpy, info);
+    LockDisplay (dpy);
+    while (nTriangle)
+    {
+	GetReq (CompositeSetTriangularCoordinateMesh, req);
+	req->reqType = info->codes->major_opcode;
+	req->compositeReqType = X_CompositeSetTriangularCoordinateMesh;
+	req->window = window;
+	n = nTriangle;
+	len = ((long) n) * (SIZEOF (xTriangle) >> 2);
+	if (!dpy->bigreq_size && len > (dpy->max_request_size - req->length))
+	{
+	    n = (dpy->max_request_size - req->length) /
+		(SIZEOF (xTriangle) >> 2);
+	    len = ((long) n) * (SIZEOF (xTriangle) >> 2);
+	}
+	SetReqLen (req, len, len);
+	len <<= 2;
+	DataInt32 (dpy, (int *) triangle, len);
+	nTriangle -= n;
+	triangle  += n;
+    }
+    UnlockDisplay (dpy);
+    SyncHandle ();
+}
--- a/src/xcompositeint.h
+++ b/src/xcompositeint.h
@@ -51,6 +51,7 @@
 #include <X11/Xlib.h>
 #include <X11/Xlibint.h>
 #include <X11/Xutil.h>
+#include <X11/extensions/renderproto.h>
 #include <X11/extensions/compositeproto.h>
 #include <X11/extensions/Xcomposite.h>
 
@@ -83,4 +84,16 @@ XCompositeFindDisplay (Display *dpy);
 #define XCompositeSimpleCheckExtension(dpy,i) \
   if (!XCompositeHasExtension(i)) { return; }
 
+/*
+ * Xlib uses long for 32-bit values.  Xcomposite uses int.  This
+ * matters on alpha.  Note that this macro assumes that int is 32 bits
+ * except on WORD64 machines where it is 64 bits.
+ */
+
+#ifdef WORD64
+#define DataInt32(dpy,d,len)	Data32(dpy,(long *) (d),len)
+#else
+#define DataInt32(dpy,d,len)	Data(dpy,(char *) (d),len)
+#endif
+
 #endif /* _XCOMPOSITEINT_H_ */


["xserver-input-transform-2.patch" (xserver-input-transform-2.patch)]

--- a/composite/compalloc.c
+++ b/composite/compalloc.c
@@ -141,6 +141,7 @@ compRedirectWindow (ClientPtr pClient, WindowPtr pWin, int update)
 	cw->oldy = COMP_ORIGIN_INVALID;
 	cw->damageRegistered = FALSE;
 	cw->damaged = FALSE;
+	cw->pInputMesh = NULL;
 	pWin->devPrivates[CompWindowPrivateIndex].ptr = cw;
     }
     ccw->next = cw->clients;
--- a/composite/compext.c
+++ b/composite/compext.c
@@ -512,6 +512,45 @@ ProcCompositeReleaseOverlayWindow (ClientPtr client)
     return client->noClientException;
 }
 
+static int
+ProcCompositeSetTriangularCoordinateMesh (ClientPtr client)
+{
+    CompWindowPtr cw;
+    WindowPtr	  pWin;
+    int		  n, status;
+
+    REQUEST (xCompositeSetTriangularCoordinateMeshReq);
+    REQUEST_AT_LEAST_SIZE (xCompositeSetTriangularCoordinateMeshReq);
+
+    pWin = (WindowPtr) LookupIDByType (stuff->window, RT_WINDOW);
+    if (!pWin || !pWin->parent)
+    {
+	client->errorValue = stuff->window;
+	return BadWindow;
+    }
+
+    cw = GetCompWindow (pWin);
+    if (!cw)
+    {
+	client->errorValue = stuff->window;
+	return BadWindow;
+    }
+
+    n = (client->req_len << 2) -
+	sizeof (xCompositeSetTriangularCoordinateMeshReq);
+    if (n && (n % (sizeof (xTriangle) * 2)))
+	return BadLength;
+
+    n /= sizeof (xTriangle);
+
+    status = CompositeSetTriangularCoordinateMesh (client, pWin, n,
+						   (xTriangle *) &stuff[1]);
+    if (status)
+	return status;
+
+    return client->noClientException;
+}
+
 int (*ProcCompositeVector[CompositeNumberRequests])(ClientPtr) = {
     ProcCompositeQueryVersion,
     ProcCompositeRedirectWindow,
@@ -522,6 +561,7 @@ int (*ProcCompositeVector[CompositeNumberRequests])(ClientPtr) = {
     ProcCompositeNameWindowPixmap,
     ProcCompositeGetOverlayWindow,
     ProcCompositeReleaseOverlayWindow,
+    ProcCompositeSetTriangularCoordinateMesh
 };
 
 static int
@@ -646,6 +686,19 @@ SProcCompositeReleaseOverlayWindow (ClientPtr client)
     return (*ProcCompositeVector[stuff->compositeReqType]) (client);
 }
 
+int
+SProcCompositeSetTriangularCoordinateMesh (ClientPtr client)
+{
+    int n;
+    REQUEST(xCompositeSetTriangularCoordinateMeshReq);
+
+    swaps (&stuff->length, n);
+    REQUEST_AT_LEAST_SIZE(xCompositeSetTriangularCoordinateMeshReq);
+    swapl (&stuff->window, n);
+    SwapRestL (stuff);
+    return (*ProcCompositeVector[stuff->compositeReqType]) (client);
+}
+
 int (*SProcCompositeVector[CompositeNumberRequests])(ClientPtr) = {
     SProcCompositeQueryVersion,
     SProcCompositeRedirectWindow,
@@ -656,6 +709,7 @@ int (*SProcCompositeVector[CompositeNumberRequests])(ClientPtr) = {
     SProcCompositeNameWindowPixmap,
     SProcCompositeGetOverlayWindow,
     SProcCompositeReleaseOverlayWindow,
+    SProcCompositeSetTriangularCoordinateMesh
 };
 
 static int
--- a/composite/compint.h
+++ b/composite/compint.h
@@ -85,6 +85,21 @@ typedef struct _CompClientWindow {
     int				update;
 }  CompClientWindowRec, *CompClientWindowPtr;
 
+typedef struct _CompTriangle {
+    xTriangle    tri;
+    xFixed_48_16 area;
+} CompTriangle;
+
+typedef struct _CompTriangleMap {
+    CompTriangle parent;
+    CompTriangle child;
+} CompTriangleMap;
+
+typedef struct _CompTriangularMesh {
+    CompTriangleMap *map;
+    int		    nMap;
+} CompTriangularMeshRec, *CompTriangularMeshPtr;
+
 typedef struct _CompWindow {
     RegionRec		    borderClip;
     DamagePtr		    damage;	/* for automatic update mode */
@@ -96,6 +111,7 @@ typedef struct _CompWindow {
     int			    oldy;
     PixmapPtr		    pOldPixmap;
     int			    borderClipX, borderClipY;
+    CompTriangularMeshPtr   pInputMesh;
 } CompWindowRec, *CompWindowPtr;
 
 #define COMP_ORIGIN_INVALID	    0x80000000
@@ -311,4 +327,38 @@ CompositeRealChildHead (WindowPtr pWin);
 int
 DeleteWindowNoInputDevices(pointer value, XID wid);
 
+void
+CompositeXYParentToChild (WindowPtr pChild,
+			  int	   parentX,
+			  int	   parentY,
+			  int	   *childX,
+			  int	   *childY);
+
+void
+CompositeXYChildToParent (WindowPtr pChild,
+			  int	   childX,
+			  int	   childY,
+			  int	   *parentX,
+			  int	   *parentY);
+
+void
+CompositeXYScreenToWindowRootCoordinate (WindowPtr pWin,
+					 int	   x,
+					 int	   y,
+					 int	   *rootX,
+					 int	   *rootY);
+
+void
+CompositeXYScreenFromWindowRootCoordinate (WindowPtr pWin,
+					   int	     x,
+					   int	     y,
+					   int	     *screenX,
+					   int	     *screenY);
+
+int
+CompositeSetTriangularCoordinateMesh (ClientPtr pClient,
+				      WindowPtr pWin,
+				      int	n,
+				      xTriangle *tri);
+
 #endif /* _COMPINT_H_ */
--- a/composite/compwindow.c
+++ b/composite/compwindow.c
@@ -47,6 +47,7 @@
 #endif
 
 #include "compint.h"
+#include "inputstr.h"
 
 #ifdef COMPOSITE_DEBUG
 static int
@@ -812,3 +813,316 @@ CompositeRealChildHead (WindowPtr pWin)
 	return pChildBefore;
     }
 }
+
+static int
+Orientation (xPointFixed *v1,
+	     xPointFixed *v2,
+	     xPointFixed *p)
+{
+    xFixed_48_16 a, b, c;
+
+    a = (xFixed_48_16) (v2->x - v1->x) * (p->y  - v1->y);
+    b = (xFixed_48_16) (p->x  - v1->x) * (v2->y - v1->y);
+
+    c = a - b;
+
+    return (c > 0) ? 1 : (c < 0) ? -1 : 0;
+}
+
+static Bool
+PointInTriangle (xTriangle   *triangle,
+		 xPointFixed *p)
+{
+    int o1, o2, o3;
+
+    o1 = Orientation (&triangle->p1, &triangle->p2, p);
+    o2 = Orientation (&triangle->p2, &triangle->p3, p);
+    o3 = Orientation (&triangle->p3, &triangle->p1, p);
+
+    /*
+     * 0 orientation means point is on the edge and we allow that as it is
+     * better that two triangles with coincident edges overlap than that
+     * there is a gap between them.
+     */
+    if (o2 == 0)
+	o2 = o3;
+    if (o1 == 0)
+	o1 = o2;
+
+    /*
+     * Point is in triangle if edge orientation relative to opposite point is
+     * the same for all edges.
+     */
+    return (o1 == o2) && (o2 == o3);
+}
+
+static Bool
+XYInTriangle (xTriangle *triangle,
+	      int	x,
+	      int	y)
+{
+    xPointFixed p;
+
+    p.x = IntToxFixed (x);
+    p.y = IntToxFixed (y);
+
+    return PointInTriangle (triangle, &p);
+}
+
+static xFixed_48_16
+TriangleArea (xPointFixed *p1,
+	      xPointFixed *p2,
+	      xPointFixed *p3)
+{
+    return (((xFixed_48_16) p3->x - p2->x) *
+	    ((xFixed_48_16) p3->y - p1->y) -
+	    ((xFixed_48_16) p3->y - p2->y) *
+	    ((xFixed_48_16) p3->x - p1->x)) >> 16;
+}
+
+/*
+ * Inverse mapping of point P located in triangle.
+ */
+static void
+MapPoint (CompTriangle *from,
+	  CompTriangle *to,
+	  xPointFixed  *p,
+	  xPointFixed  *result)
+{
+    xFixed_48_16 u, v, w;
+    xFixed_48_16 x, y;
+
+    u = (TriangleArea (&from->tri.p1, &from->tri.p2, p) << 16) / from->area;
+    v = (TriangleArea (&from->tri.p3, &from->tri.p1, p) << 16) / from->area;
+    w = (TriangleArea (&from->tri.p2, &from->tri.p3, p) << 16) / from->area;
+
+    x = to->tri.p3.x * u + to->tri.p2.x * v + to->tri.p1.x * w;
+    y = to->tri.p3.y * u + to->tri.p2.y * v + to->tri.p1.y * w;
+
+    result->x = x >> 16;
+    result->y = y >> 16;
+}
+
+static void
+XYMapPoint (CompTriangle *from,
+	    CompTriangle *to,
+	    int		 fromX,
+	    int		 fromY,
+	    int		 *toX,
+	    int		 *toY)
+{
+    xPointFixed in, out;
+
+    in.x = IntToxFixed (fromX);
+    in.y = IntToxFixed (fromY);
+
+    MapPoint (from, to, &in, &out);
+
+    *toX = xFixedToInt (out.x + xFixed1 / 2);
+    *toY = xFixedToInt (out.y + xFixed1 / 2);
+}
+
+void
+CompositeXYParentToChild (WindowPtr pChild,
+			  int	   parentX,
+			  int	   parentY,
+			  int	   *childX,
+			  int	   *childY)
+{
+    CompWindowPtr cw = GetCompWindow (pChild);
+
+    if (cw && cw->pInputMesh)
+    {
+	CompTriangleMap *map = cw->pInputMesh->map;
+	int	        nMap = cw->pInputMesh->nMap;
+
+	while (nMap--)
+	{
+	    if (!map->parent.area)
+		continue;
+
+	    if (XYInTriangle (&map->parent.tri, parentX, parentY))
+	    {
+		XYMapPoint (&map->parent, &map->child,
+			    parentX, parentY,
+			    childX, childY);
+		return;
+	    }
+
+	    map++;
+	}
+    }
+
+    *childX = parentX;
+    *childY = parentY;
+}
+
+void
+CompositeXYChildToParent (WindowPtr pChild,
+			  int	   childX,
+			  int	   childY,
+			  int	   *parentX,
+			  int	   *parentY)
+{
+    CompWindowPtr cw = GetCompWindow (pChild);
+
+    if (cw && cw->pInputMesh)
+    {
+	CompTriangleMap *map = cw->pInputMesh->map;
+	int	        nMap = cw->pInputMesh->nMap;
+
+	while (nMap--)
+	{
+	    if (!map->child.area)
+		continue;
+
+	    if (XYInTriangle (&map->child.tri, childX, childY))
+	    {
+		XYMapPoint (&map->child, &map->parent,
+			    childX, childY,
+			    parentX, parentY);
+
+		return;
+	    }
+
+	    map++;
+	}
+    }
+
+    *parentX = childX;
+    *parentY = childY;
+}
+
+void
+CompositeXYScreenToWindowRootCoordinate (WindowPtr pWin,
+					 int	   x,
+					 int	   y,
+					 int	   *rootX,
+					 int	   *rootY)
+{
+    if (!pWin->parent)
+    {
+	*rootX = x;
+	*rootY = y;
+    }
+    else
+    {
+	CompositeXYScreenToWindowRootCoordinate (pWin->parent, x, y, &x, &y);
+	CompositeXYParentToChild (pWin, x, y, rootX, rootY);
+    }
+}
+
+void
+CompositeXYScreenFromWindowRootCoordinate (WindowPtr pWin,
+					   int	     x,
+					   int	     y,
+					   int	     *screenX,
+					   int	     *screenY)
+{
+    if (!pWin->parent)
+    {
+	*screenX = x;
+	*screenY = y;
+    }
+    else
+    {
+	CompositeXYChildToParent (pWin, x, y, &x, &y);
+	CompositeXYScreenFromWindowRootCoordinate (pWin->parent,
+						   x, y, screenX, screenY);
+    }
+}
+
+int
+CompositeSetTriangularCoordinateMesh (ClientPtr pClient,
+				      WindowPtr pWin,
+				      int	n,
+				      xTriangle *tri)
+{
+    CompSubwindowsPtr   csw = GetCompSubwindows (pWin->parent);
+    CompWindowPtr	cw = GetCompWindow (pWin);
+    CompClientWindowPtr	ccw;
+    WindowPtr		pSpriteWin;
+
+    /*
+     * sub-window must be Manual update
+     */
+    if (!csw || csw->update != CompositeRedirectManual)
+	return BadAccess;
+
+    /*
+     * must be Manual update client
+     */
+    for (ccw = csw->clients; ccw; ccw = ccw->next)
+	if (ccw->update == CompositeRedirectManual &&
+	    CLIENT_ID (ccw->id) != pClient->index)
+	    return BadAccess;
+
+    if (n)
+    {
+	CompTriangularMeshPtr mesh;
+	int		      i;
+
+	mesh = xalloc (sizeof (CompTriangularMeshRec) +
+		       sizeof (CompTriangleMap) * n / 2);
+	if (!mesh)
+	    return FALSE;
+
+	mesh->map  = (CompTriangleMap *) (mesh + 1);
+	mesh->nMap = n / 2;
+
+	for (i = 0; i < n; i += 2)
+	{
+	    mesh->map[i / 2].parent.tri  = tri[i];
+	    mesh->map[i / 2].parent.area =
+		TriangleArea (&tri[i].p1, &tri[i].p2, &tri[i].p3);
+
+	    mesh->map[i / 2].child.tri  = tri[i + 1];
+	    mesh->map[i / 2].child.area =
+		TriangleArea (&tri[i + 1].p1, &tri[i + 1].p2, &tri[i + 1].p3);
+	}
+
+	if (cw->pInputMesh)
+	    xfree (cw->pInputMesh);
+
+	cw->pInputMesh = mesh;
+    }
+    else
+    {
+	if (cw->pInputMesh)
+	{
+	    xfree (cw->pInputMesh);
+	    cw->pInputMesh = NULL;
+	}
+    }
+
+    pSpriteWin = GetSpriteWindow ();
+    while (pSpriteWin)
+    {
+	/*
+	 * Generate synthetic motion event if sprite window got an
+	 * ancestor that might be affected by the coordinate mapping
+	 * used for this window.
+	 */
+	if (pSpriteWin == pWin->parent)
+	{
+	    xEvent xE;
+	    int    x, y;
+
+	    GetSpritePosition (&x, &y);
+
+	    xE.u.keyButtonPointer.rootX = x;
+	    xE.u.keyButtonPointer.rootY = y;
+	    xE.u.keyButtonPointer.time = currentTime.milliseconds;
+	    xE.u.u.type = MotionNotify;
+
+	    (*inputInfo.pointer->public.processInputProc) (&xE,
+							   inputInfo.pointer,
+							   1);
+	    break;
+	}
+
+	pSpriteWin = pSpriteWin->parent;
+    }
+
+    return 0;
+}
--- a/dix/dispatch.c
+++ b/dix/dispatch.c
@@ -122,6 +122,9 @@ int ProcInitialConnection();
 #ifdef LBX
 #include "lbxserve.h"
 #endif
+#ifdef COMPOSITE
+#include "compint.h"
+#endif
 
 #define mskcnt ((MAXCLIENTS + 31) / 32)
 #define BITMASK(i) (1U << ((i) & 31))
@@ -1232,18 +1235,61 @@ ProcTranslateCoords(register ClientPtr client)
     }
     else
     {
-	INT16 x, y;
+	int x, y, rootX, rootY;
 	rep.sameScreen = xTrue;
 	rep.child = None;
 	/* computing absolute coordinates -- adjust to destination later */
 	x = pWin->drawable.x + stuff->srcX;
 	y = pWin->drawable.y + stuff->srcY;
+
+#ifdef COMPOSITE
+	/*
+	 * Transform from source window coordinate space to screen
+	 * and then to destination coordinate space.
+	 */
+	CompositeXYScreenFromWindowRootCoordinate (pWin, x, y, &x, &y);
+	CompositeXYScreenToWindowRootCoordinate (pDst, x, y, &x, &y);
+#endif
+
+	/* adjust to destination coordinates */
+	rep.dstX = x - pDst->drawable.x;
+	rep.dstY = y - pDst->drawable.y;
+
+	rootX = x;
+	rootY = y;
+
 	pWin = pDst->firstChild;
 	while (pWin)
 	{
 #ifdef SHAPE
 	    BoxRec  box;
 #endif
+
+	x = rootX;
+	y = rootY;
+
+#ifdef COMPOSITE
+	    /*
+	     * Transform from parent to child.
+	     */
+	    if (pWin->mapped)
+	    {
+		if (pWin->parent)
+		{
+		    x = rootX - pWin->parent->drawable.x;
+		    y = rootY - pWin->parent->drawable.y;
+		}
+
+		CompositeXYParentToChild (pWin, x, y, &x, &y);
+
+		if (pWin->parent)
+		{
+		    x += pWin->parent->drawable.x;
+		    y += pWin->parent->drawable.y;
+		}
+	    }
+#endif
+
 	    if ((pWin->mapped) &&
 		(x >= pWin->drawable.x - wBorderWidth (pWin)) &&
 		(x < pWin->drawable.x + (int)pWin->drawable.width +
@@ -1268,15 +1314,14 @@ ProcTranslateCoords(register ClientPtr client)
 #endif
 		)
             {
+		rootX = x;
+		rootY = y;
 		rep.child = pWin->drawable.id;
 		pWin = (WindowPtr) NULL;
 	    }
 	    else
 		pWin = pWin->nextSib;
 	}
-	/* adjust to destination coordinates */
-	rep.dstX = x - pDst->drawable.x;
-	rep.dstY = y - pDst->drawable.y;
     }
     WriteReplyToClient(client, sizeof(xTranslateCoordsReply), &rep);
     return(client->noClientException);
--- a/dix/events.c
+++ b/dix/events.c
@@ -131,6 +131,9 @@ of the copyright holder.
 #include "panoramiX.h"
 #include "panoramiXsrv.h"
 #endif
+#ifdef COMPOSITE
+#include "compint.h"
+#endif
 #include "globals.h"
 
 #ifdef XKB
@@ -1993,15 +2005,41 @@ PointInBorderSize(WindowPtr pWin, int x, int y)
 }
 
 static WindowPtr 
-XYToWindow(int x, int y)
+XYToWindow(int rootX, int rootY)
 {
     register WindowPtr  pWin;
     BoxRec		box;
+    int			x, y;
 
     spriteTraceGood = 1;	/* root window still there */
     pWin = ROOT->firstChild;
     while (pWin)
     {
+	x = rootX;
+	y = rootY;
+
+#ifdef COMPOSITE
+	/*
+	 * Transform from parent to child.
+	 */
+	if (pWin->mapped)
+	{
+	    if (pWin->parent)
+	    {
+		x = rootX - pWin->parent->drawable.x;
+		y = rootY - pWin->parent->drawable.y;
+	    }
+
+	    CompositeXYParentToChild (pWin, x, y, &x, &y);
+
+	    if (pWin->parent)
+	    {
+		x += pWin->parent->drawable.x;
+		y += pWin->parent->drawable.y;
+	    }
+	}
+#endif
+
 	if ((pWin->mapped) &&
 	    (x >= pWin->drawable.x - wBorderWidth (pWin)) &&
 	    (x < pWin->drawable.x + (int)pWin->drawable.width +
@@ -2032,6 +2070,8 @@ XYToWindow(int x, int y)
 		Must_have_memory = FALSE; /* XXX */
 	    }
 	    spriteTrace[spriteTraceGood++] = pWin;
+	    rootX = x;
+	    rootY = y;
 	    pWin = pWin->firstChild;
 	}
 	else
@@ -4028,6 +4074,7 @@ ProcQueryPointer(ClientPtr client)
     WindowPtr pWin, t;
     REQUEST(xResourceReq);
     DeviceIntPtr mouse = inputInfo.pointer;
+    int rootX, rootY;
 
     REQUEST_SIZE_MATCH(xResourceReq);
     pWin = SecurityLookupWindow(stuff->id, client, SecurityReadAccess);
@@ -4040,14 +4087,27 @@ ProcQueryPointer(ClientPtr client)
     rep.mask = mouse->button->state | inputInfo.keyboard->key->state;
     rep.length = 0;
     rep.root = (ROOT)->drawable.id;
-    rep.rootX = sprite.hot.x;
-    rep.rootY = sprite.hot.y;
     rep.child = None;
+
+#ifdef COMPOSITE
+    /*
+     * Return coordinates in windows root coordinate space.
+     */
+    CompositeXYScreenToWindowRootCoordinate (pWin,
+					     sprite.hot.x, sprite.hot.y,
+					     &rootX, &rootY);
+    rep.rootX = rootX;
+    rep.rootY = rootY;
+#else
+    rep.rootX = rootX = sprite.hot.x;
+    rep.rootY = rootY = sprite.hot.y;
+#endif
+
     if (sprite.hot.pScreen == pWin->drawable.pScreen)
     {
 	rep.sameScreen = xTrue;
-	rep.winX = sprite.hot.x - pWin->drawable.x;
-	rep.winY = sprite.hot.y - pWin->drawable.y;
+	rep.winX = rootX - pWin->drawable.x;
+	rep.winY = rootY - pWin->drawable.y;
 	for (t = sprite.win; t; t = t->parent)
 	    if (t->parent == pWin)
 	    {
@@ -4603,11 +4663,59 @@ WriteEventsToClient(ClientPtr pClient, int count, xEvent *events)
     xEvent    eventTo, *eventFrom;
     int       i;
 
+#ifdef COMPOSITE
+    xEvent copy[count];
+#endif
+
 #ifdef XKB
     if ((!noXkbExtension)&&(!XkbFilterEvents(pClient, count, events)))
 	return;
 #endif
 
+#ifdef COMPOSITE
+    memcpy (copy, events, count * sizeof (xEvent));
+    events = copy;
+
+    for (i = 0; i < count; i++)
+    {
+	WindowPtr pWin;
+	int	  x, y, dx, dy;
+
+	switch (events[i].u.u.type) {
+	case MotionNotify:
+	case ButtonPress:
+	case ButtonRelease:
+	case KeyPress:
+	case KeyRelease:
+	case EnterNotify:
+	case LeaveNotify:
+	    pWin = LookupIDByType (events[i].u.keyButtonPointer.event,
+				   RT_WINDOW);
+	    if (pWin)
+	    {
+		x = events[i].u.keyButtonPointer.rootX;
+		y = events[i].u.keyButtonPointer.rootY;
+
+		/*
+		 * rootX and rootY are in screen coordinate space.
+		 * Transform to windows root coordinate space before writing
+		 * events to client.
+		 */
+		CompositeXYScreenToWindowRootCoordinate (pWin, x, y, &x, &y);
+
+		dx = x - events[i].u.keyButtonPointer.rootX;
+		dy = y - events[i].u.keyButtonPointer.rootY;
+
+		events[i].u.keyButtonPointer.rootX  += dx;
+		events[i].u.keyButtonPointer.rootY  += dy;
+		events[i].u.keyButtonPointer.eventX += dx;
+		events[i].u.keyButtonPointer.eventY += dy;
+	    }
+	    break;
+	}
+    }
+#endif
+
 #ifdef PANORAMIX
     if(!noPanoramiXExtension && 
        (panoramiXdataPtr[0].x || panoramiXdataPtr[0].y)) 


_______________________________________________
xorg mailing list
xorg@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/xorg

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic