diff --git a/composite/compalloc.c b/composite/compalloc.c
index 1bac9a4..c0c11b9 100644
--- a/composite/compalloc.c
+++ b/composite/compalloc.c
@@ -142,6 +142,7 @@ compRedirectWindow (ClientPtr pClient, WindowPtr pWin, int update)
 	cw->oldy = COMP_ORIGIN_INVALID;
 	cw->damageRegistered = FALSE;
 	cw->damaged = FALSE;
+	cw->pInputMesh = NULL;
 	dixSetPrivate(&pWin->devPrivates, CompWindowPrivateKey, cw);
     }
     ccw->next = cw->clients;
diff --git a/composite/compext.c b/composite/compext.c
index 4fff20e..0345878 100644
--- a/composite/compext.c
+++ b/composite/compext.c
@@ -382,6 +382,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;
+}
+
 static int (*ProcCompositeVector[CompositeNumberRequests])(ClientPtr) = {
     ProcCompositeQueryVersion,
     ProcCompositeRedirectWindow,
@@ -392,6 +431,7 @@ static int (*ProcCompositeVector[CompositeNumberRequests])(ClientPtr) = {
     ProcCompositeNameWindowPixmap,
     ProcCompositeGetOverlayWindow,
     ProcCompositeReleaseOverlayWindow,
+    ProcCompositeSetTriangularCoordinateMesh
 };
 
 static int
@@ -516,6 +556,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);
+}
+
 static int (*SProcCompositeVector[CompositeNumberRequests])(ClientPtr) = {
     SProcCompositeQueryVersion,
     SProcCompositeRedirectWindow,
@@ -526,6 +579,7 @@ static int (*SProcCompositeVector[CompositeNumberRequests])(ClientPtr) = {
     SProcCompositeNameWindowPixmap,
     SProcCompositeGetOverlayWindow,
     SProcCompositeReleaseOverlayWindow,
+    SProcCompositeSetTriangularCoordinateMesh
 };
 
 static int
diff --git a/composite/compint.h b/composite/compint.h
index 1c19ccd..6ff4c9c 100644
--- a/composite/compint.h
+++ b/composite/compint.h
@@ -84,6 +84,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 */
@@ -95,6 +110,7 @@ typedef struct _CompWindow {
     int			    oldy;
     PixmapPtr		    pOldPixmap;
     int			    borderClipX, borderClipY;
+    CompTriangularMeshPtr   pInputMesh;
 } CompWindowRec, *CompWindowPtr;
 
 #define COMP_ORIGIN_INVALID	    0x80000000
@@ -319,4 +335,39 @@ CompositeRealChildHead (WindowPtr pWin);
 int
 DeleteWindowNoInputDevices(pointer value, XID wid);
 
+Bool
+CompositeXYParentToChild (WindowPtr pChild,
+			  int	   parentX,
+			  int	   parentY,
+			  int	   *childX,
+			  int	   *childY);
+
+Bool
+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_ */
diff --git a/composite/compwindow.c b/composite/compwindow.c
index 577fa73..318a38a 100644
--- a/composite/compwindow.c
+++ b/composite/compwindow.c
@@ -821,3 +821,344 @@ 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);
+}
+
+Bool
+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);
+		/* XXX fix the problem where the mesh could only end up in
+		 * the top left corner
+		 */
+		*childX += pChild->drawable.x;
+		*childY += pChild->drawable.y;
+		/* There is a mesh and the point was redirected,
+		 * handle as normal
+		 */
+		return TRUE;
+	    }
+
+	    map++;
+	}
+    }
+    *childX = parentX;
+    *childY = parentY;
+
+    /* There is a mesh, but nothing was redirected,
+     * don't process the event on the non-redirected
+     * window
+     */
+    if (cw && cw->pInputMesh)
+	return FALSE;
+
+    /* There is no mesh, handle events like normal */
+    if (!cw || !cw->pInputMesh)
+	return TRUE;
+}
+
+Bool
+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);
+
+		/* There is a mesh and the point was redirected,
+		 * handle as normal
+		 */
+		return TRUE;
+	    }
+
+	    map++;
+	}
+    }
+
+    *parentX = childX;
+    *parentY = childY;
+
+    /* There is a mesh, but nothing was redirected,
+     * don't process the event on the non-redirected
+     * window
+     */
+    if (cw && cw->pInputMesh)
+	return FALSE;
+
+    /* There is no mesh, handle events like normal */
+    if (!cw || !cw->pInputMesh)
+	return TRUE;
+}
+
+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 BadAlloc;
+
+	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;
+	}
+    }
+
+    /* Generate motionNotify event when mesh changes */
+    /*pSpriteWin = GetSpriteWindow (inputInfo.devices);
+    while (pSpriteWin)
+    {
+	if (pSpriteWin == pWin->parent)
+	{
+	    xEvent xE;
+	    int    x, y;
+
+	    GetSpritePosition (inputInfo.devices, &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;
+}
diff --git a/dix/dispatch.c b/dix/dispatch.c
index 0ed95df..7360fa7 100644
--- a/dix/dispatch.c
+++ b/dix/dispatch.c
@@ -142,6 +142,10 @@ typedef const char *string;
 #include "Xserver-dtrace.h"
 #endif
 
+#ifdef COMPOSITE
+#include "compint.h"
+#endif
+
 #define mskcnt ((MAXCLIENTS + 31) / 32)
 #define BITMASK(i) (1U << ((i) & 31))
 #define MASKIDX(i) ((i) >> 5)
@@ -1019,16 +1023,59 @@ ProcTranslateCoords(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)
 	{
 	    BoxRec  box;
+
+	    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 +
@@ -1051,15 +1098,14 @@ ProcTranslateCoords(ClientPtr client)
 				    y - pWin->drawable.y, &box))
 		)
             {
+		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);
diff --git a/dix/events.c b/dix/events.c
index e73044e..45f6290 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -131,6 +131,7 @@ of the copyright holder.
 #include "panoramiX.h"
 #include "panoramiXsrv.h"
 #endif
+#include "compint.h"
 #include "globals.h"
 
 #include <X11/extensions/XKBproto.h>
@@ -1874,6 +1875,7 @@ TryClientEvents (ClientPtr client, DeviceIntPtr dev, xEvent *pEvents,
     }
 }
 
+
 /**
  * Deliver events to a window. At this point, we do not yet know if the event
  * actually needs to be delivered. May activate a grab if the event is a
@@ -2458,18 +2460,46 @@ PointInBorderSize(WindowPtr pWin, int x, int y)
  * @returns the window at the given coordinates.
  */
 static WindowPtr
-XYToWindow(DeviceIntPtr pDev, int x, int y)
+XYToWindow(DeviceIntPtr pDev, int rootX, int rootY)
 {
     WindowPtr  pWin;
     BoxRec		box;
+    int			x, y;
     SpritePtr pSprite;
+    Bool      handle = TRUE;
 
     pSprite = pDev->spriteInfo->sprite;
     pSprite->spriteTraceGood = 1;	/* root window still there */
     pWin = RootWindow(pDev)->firstChild;
     while (pWin)
     {
-	if ((pWin->mapped) &&
+	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;
+	    }
+
+	    handle = CompositeXYParentToChild (pWin, x, y, &x, &y);
+
+	    if (pWin->parent)
+	    {
+		x += pWin->parent->drawable.x;
+		y += pWin->parent->drawable.y;
+	    }
+	}
+#endif
+
+
+	if ((pWin->mapped) && (handle) &&
 	    (x >= pWin->drawable.x - wBorderWidth (pWin)) &&
 	    (x < pWin->drawable.x + (int)pWin->drawable.width +
 	     wBorderWidth(pWin)) &&
@@ -2502,6 +2532,8 @@ XYToWindow(DeviceIntPtr pDev, int x, int y)
 		                    pSprite->spriteTraceSize*sizeof(WindowPtr));
 	    }
 	    pSprite->spriteTrace[pSprite->spriteTraceGood++] = pWin;
+	    rootX = x;
+	    rootY = y;
 	    pWin = pWin->firstChild;
 	}
 	else
@@ -4629,6 +4661,7 @@ ProcQueryPointer(ClientPtr client)
     DeviceIntPtr keyboard;
     SpritePtr pSprite;
     int rc;
+    int rootX, rootY;
     REQUEST(xResourceReq);
     REQUEST_SIZE_MATCH(xResourceReq);
 
@@ -4651,14 +4684,27 @@ ProcQueryPointer(ClientPtr client)
     rep.mask |= XkbStateFieldFromRec(&keyboard->key->xkbInfo->state);
     rep.length = 0;
     rep.root = (RootWindow(mouse))->drawable.id;
+    rep.child = None;
+
+#ifdef COMPOSITE
+    /*
+     * Return coordinates in windows root coordinate space.
+     */
+    CompositeXYScreenToWindowRootCoordinate (pWin,
+					     pSprite->hot.x, pSprite->hot.y,
+					     &rootX, &rootY);
     rep.rootX = pSprite->hot.x;
     rep.rootY = pSprite->hot.y;
-    rep.child = None;
+#else
+    rep.rootX = rootX = pSprite->hot.x;
+    rep.rootY = rootY = pSprite->hot.y;
+#endif
+
     if (pSprite->hot.pScreen == pWin->drawable.pScreen)
     {
 	rep.sameScreen = xTrue;
-	rep.winX = pSprite->hot.x - pWin->drawable.x;
-	rep.winY = pSprite->hot.y - pWin->drawable.y;
+	rep.winX = rootX - pWin->drawable.x;
+	rep.winY = rootY - pWin->drawable.y;
 	for (t = pSprite->win; t; t = t->parent)
 	    if (t->parent == pWin)
 	    {
@@ -5327,9 +5373,95 @@ WriteEventsToClient(ClientPtr pClient, int count, xEvent *events)
     int       i,
               eventlength = sizeof(xEvent);
 
+#ifdef COMPOSITE
+    xEvent    stackCopy;
+    xEvent    *compEventCopy = &stackCopy;
+#endif
+
     if (!XkbFilterEvents(pClient, count, events))
 	return;
 
+#ifdef COMPOSITE
+Bool Must_have_memory;
+    if (count > 1)
+    {
+	Must_have_memory = TRUE; /* XXX */
+	compEventCopy = xalloc (count * sizeof (xEvent));
+	Must_have_memory = FALSE; /* XXX */
+    }
+
+    memcpy (compEventCopy, events, count * sizeof (xEvent));
+    events = compEventCopy;
+
+    for (i = 0; i < count; i++)
+    {
+	deviceKeyButtonPointer *deviceEvent;
+	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;
+	default:
+	    if (events[i].u.u.type == DeviceMotionNotify  ||
+		events[i].u.u.type == DeviceButtonPress	  ||
+		events[i].u.u.type == DeviceButtonRelease ||
+		events[i].u.u.type == DeviceKeyPress	  ||
+		events[i].u.u.type == DeviceKeyRelease)
+	    {
+		deviceEvent = (deviceKeyButtonPointer *) &events[i];
+
+		pWin = LookupIDByType (deviceEvent->event, RT_WINDOW);
+		if (pWin)
+		{
+		    x = deviceEvent->root_x;
+		    y = deviceEvent->root_y;
+
+		    CompositeXYScreenToWindowRootCoordinate (pWin, x, y,
+							     &x, &y);
+
+		    dx = x - deviceEvent->root_x;
+		    dy = y - deviceEvent->root_y;
+
+		    //deviceEvent->root_x  += dx;
+		    //deviceEvent->root_y  += dy;
+		    deviceEvent->event_x += dx;
+		    deviceEvent->event_y += dy;
+		}
+	    }
+	    break;
+	}
+    }
+#endif
+
 #ifdef PANORAMIX
     if(!noPanoramiXExtension &&
        (panoramiXdataPtr[0].x || panoramiXdataPtr[0].y))
@@ -5429,6 +5561,12 @@ WriteEventsToClient(ClientPtr pClient, int count, xEvent *events)
          * matter. And we're all set. Woohoo. */
 	WriteToClient(pClient, count * eventlength, (char *) events);
     }
+
+#ifdef COMPOSITE
+    if (compEventCopy != &stackCopy)
+	xfree (compEventCopy);
+#endif
+
 }
 
 /*
