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
--- 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
--- 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_ */
--- 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))
_______________________________________________ compiz mailing list compiz@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/compiz