summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Xext/panoramiXprocs.c70
1 files changed, 60 insertions, 10 deletions
diff --git a/Xext/panoramiXprocs.c b/Xext/panoramiXprocs.c
index 18f3ac715..f31b1e054 100644
--- a/Xext/panoramiXprocs.c
+++ b/Xext/panoramiXprocs.c
@@ -1050,7 +1050,7 @@ PanoramiXClearToBackground(ClientPtr client)
int
PanoramiXCopyArea(ClientPtr client)
{
- int j, result, srcx, srcy, dstx, dsty;
+ int j, result, srcx, srcy, dstx, dsty, width, height;
PanoramiXRes *gc, *src, *dst;
Bool srcIsRoot = FALSE;
Bool dstIsRoot = FALSE;
@@ -1091,6 +1091,8 @@ PanoramiXCopyArea(ClientPtr client)
srcy = stuff->srcY;
dstx = stuff->dstX;
dsty = stuff->dstY;
+ width = stuff->width;
+ height = stuff->height;
if ((dst->type == XRT_PIXMAP) && (src->type == XRT_WINDOW)) {
DrawablePtr drawables[MAXSCREENS];
DrawablePtr pDst;
@@ -1105,13 +1107,12 @@ PanoramiXCopyArea(ClientPtr client)
return rc;
}
- pitch = PixmapBytePad(stuff->width, drawables[0]->depth);
- if (!(data = calloc(stuff->height, pitch)))
+ pitch = PixmapBytePad(width, drawables[0]->depth);
+ if (!(data = calloc(height, pitch)))
return BadAlloc;
- XineramaGetImageData(drawables, srcx, srcy,
- stuff->width, stuff->height, ZPixmap, ~0, data,
- pitch, srcIsRoot);
+ XineramaGetImageData(drawables, srcx, srcy, width, height, ZPixmap, ~0,
+ data, pitch, srcIsRoot);
FOR_NSCREENS_BACKWARD(j) {
stuff->gc = gc->info[j].id;
@@ -1123,14 +1124,63 @@ PanoramiXCopyArea(ClientPtr client)
}
(*pGC->ops->PutImage) (pDst, pGC, pDst->depth, dstx, dsty,
- stuff->width, stuff->height,
- 0, ZPixmap, data);
-
+ width, height, 0, ZPixmap, data);
if (dstShared)
break;
}
-
free(data);
+
+ if (pGC->graphicsExposures) {
+ RegionRec rgn;
+ int dx, dy;
+ BoxRec sourceBox;
+
+ dx = drawables[0]->x;
+ dy = drawables[0]->y;
+ if (srcIsRoot) {
+ dx += screenInfo.screens[0]->x;
+ dy += screenInfo.screens[0]->y;
+ }
+
+ sourceBox.x1 = min(srcx + dx, 0);
+ sourceBox.y1 = min(srcy + dy, 0);
+ sourceBox.x2 = max(sourceBox.x1 + width, 32767);
+ sourceBox.y2 = max(sourceBox.y1 + height, 32767);
+
+ RegionInit(&rgn, &sourceBox, 1);
+
+ /* subtract the (screen-space) clips of the source drawables */
+ FOR_NSCREENS(j) {
+ ScreenPtr screen = screenInfo.screens[j];
+ RegionPtr sd;
+
+ if (pGC->subWindowMode == IncludeInferiors)
+ sd = NotClippedByChildren((WindowPtr)drawables[j]);
+ else
+ sd = &((WindowPtr)drawables[j])->clipList;
+
+ if (srcIsRoot)
+ RegionTranslate(&rgn, -screen->x, -screen->y);
+
+ RegionSubtract(&rgn, &rgn, sd);
+
+ if (srcIsRoot)
+ RegionTranslate(&rgn, screen->x, screen->y);
+
+ if (pGC->subWindowMode == IncludeInferiors)
+ RegionDestroy(sd);
+ }
+
+ /* -dx/-dy to get back to dest-relative, plus request offsets */
+ RegionTranslate(&rgn, -dx + dstx, -dy + dsty);
+
+ /* intersect with gc clip; just one screen is fine because pixmap */
+ RegionIntersect(&rgn, &rgn, pGC->pCompositeClip);
+
+ /* and expose */
+ SendGraphicsExpose(client, &rgn, dst->info[0].id, X_CopyArea, 0);
+ RegionUninit(&rgn);
+ }
}
else {
DrawablePtr pDst = NULL, pSrc = NULL;