[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