Blame SOURCES/0001-xinerama-Implement-graphics-exposures-for-window-pix.patch

0b0bd3
From a92dd0013ae184c921f3415e651ff53da2ca9397 Mon Sep 17 00:00:00 2001
0b0bd3
From: Adam Jackson <ajax@redhat.com>
0b0bd3
Date: Wed, 24 Sep 2014 11:31:51 -0400
0b0bd3
Subject: [PATCH] xinerama: Implement graphics exposures for window->pixmap
0b0bd3
 copies (v2)
0b0bd3
0b0bd3
This code is using GetImage to accumulate a logical view of the window
0b0bd3
image (since the windows will be clipped to their containing screen),
0b0bd3
and then PutImage to load that back into the pixmap.  What it wasn't
0b0bd3
doing was constructing a region for the obscured areas of the window and
0b0bd3
emitting graphics exposures for same.
0b0bd3
0b0bd3
This special case for window->pixmap copies (and corresponding lack of
0b0bd3
graphics exposures) appears to date back to cvs revision 3.15 of this
0b0bd3
file in xfree86, which makes it almost exactly fifteen years old.  It's
0b0bd3
possible that we could do better now, since Composite would mean that
0b0bd3
for redirected windows we would in fact have consistent window contents
0b0bd3
on every screen.  Would be slightly ugly to have Xinerama know about
0b0bd3
Composite at the dispatch level, but then this is Xinerama we're talking
0b0bd3
about, nothing's pretty here.
0b0bd3
0b0bd3
v2: Fix coordinate translation when the source is the root window
0b0bd3
0b0bd3
Signed-off-by: Adam Jackson <ajax@redhat.com>
0b0bd3
---
0b0bd3
 Xext/panoramiXprocs.c | 70 +++++++++++++++++++++++++++++++++++++++++++--------
0b0bd3
 1 file changed, 60 insertions(+), 10 deletions(-)
0b0bd3
0b0bd3
diff --git a/Xext/panoramiXprocs.c b/Xext/panoramiXprocs.c
0b0bd3
index 83a2e08..8e3120d 100644
0b0bd3
--- a/Xext/panoramiXprocs.c
0b0bd3
+++ b/Xext/panoramiXprocs.c
0b0bd3
@@ -1050,7 +1050,7 @@ PanoramiXClearToBackground(ClientPtr client)
0b0bd3
 int
0b0bd3
 PanoramiXCopyArea(ClientPtr client)
0b0bd3
 {
0b0bd3
-    int j, result, srcx, srcy, dstx, dsty;
0b0bd3
+    int j, result, srcx, srcy, dstx, dsty, width, height;
0b0bd3
     PanoramiXRes *gc, *src, *dst;
0b0bd3
     Bool srcIsRoot = FALSE;
0b0bd3
     Bool dstIsRoot = FALSE;
0b0bd3
@@ -1091,6 +1091,8 @@ PanoramiXCopyArea(ClientPtr client)
0b0bd3
     srcy = stuff->srcY;
0b0bd3
     dstx = stuff->dstX;
0b0bd3
     dsty = stuff->dstY;
0b0bd3
+    width = stuff->width;
0b0bd3
+    height = stuff->height;
0b0bd3
     if ((dst->type == XRT_PIXMAP) && (src->type == XRT_WINDOW)) {
0b0bd3
         DrawablePtr drawables[MAXSCREENS];
0b0bd3
         DrawablePtr pDst;
0b0bd3
@@ -1105,13 +1107,12 @@ PanoramiXCopyArea(ClientPtr client)
0b0bd3
                 return rc;
0b0bd3
         }
0b0bd3
 
0b0bd3
-        pitch = PixmapBytePad(stuff->width, drawables[0]->depth);
0b0bd3
-        if (!(data = calloc(1, stuff->height * pitch)))
0b0bd3
+        pitch = PixmapBytePad(width, drawables[0]->depth);
0b0bd3
+        if (!(data = calloc(1, height * pitch)))
0b0bd3
             return BadAlloc;
0b0bd3
 
0b0bd3
-        XineramaGetImageData(drawables, srcx, srcy,
0b0bd3
-                             stuff->width, stuff->height, ZPixmap, ~0, data,
0b0bd3
-                             pitch, srcIsRoot);
0b0bd3
+        XineramaGetImageData(drawables, srcx, srcy, width, height, ZPixmap, ~0,
0b0bd3
+                             data, pitch, srcIsRoot);
0b0bd3
 
0b0bd3
         FOR_NSCREENS_BACKWARD(j) {
0b0bd3
             stuff->gc = gc->info[j].id;
0b0bd3
@@ -1123,14 +1124,63 @@ PanoramiXCopyArea(ClientPtr client)
0b0bd3
             }
0b0bd3
 
0b0bd3
             (*pGC->ops->PutImage) (pDst, pGC, pDst->depth, dstx, dsty,
0b0bd3
-                                   stuff->width, stuff->height,
0b0bd3
-                                   0, ZPixmap, data);
0b0bd3
-
0b0bd3
+                                   width, height, 0, ZPixmap, data);
0b0bd3
             if (dstShared)
0b0bd3
                 break;
0b0bd3
         }
0b0bd3
-
0b0bd3
         free(data);
0b0bd3
+
0b0bd3
+        if (pGC->graphicsExposures) {
0b0bd3
+            RegionRec rgn;
0b0bd3
+            int dx, dy;
0b0bd3
+
0b0bd3
+            /* create region for source box */
0b0bd3
+            BoxRec sourceBox = { srcx, srcy, srcx + width, srcy + height };
0b0bd3
+            RegionInit(&rgn, &sourceBox, 1);
0b0bd3
+
0b0bd3
+            dx = drawables[0]->x;
0b0bd3
+            dy = drawables[0]->y;
0b0bd3
+            if (srcIsRoot) {
0b0bd3
+                dx += screenInfo.screens[0]->x;
0b0bd3
+                dy += screenInfo.screens[0]->y;
0b0bd3
+            }
0b0bd3
+
0b0bd3
+            /* translate from source-relative to screen */
0b0bd3
+            RegionTranslate(&rgn, dx, dy);
0b0bd3
+
0b0bd3
+            /* subtract the (screen-space) clips of the source drawables */
0b0bd3
+            FOR_NSCREENS(j) {
0b0bd3
+                ScreenPtr screen = screenInfo.screens[j];
0b0bd3
+                RegionPtr sd;
0b0bd3
+
0b0bd3
+                if (pGC->subWindowMode == IncludeInferiors)
0b0bd3
+                    sd = NotClippedByChildren((WindowPtr)drawables[j]);
0b0bd3
+                else
0b0bd3
+                    sd = &((WindowPtr)drawables[j])->clipList;
0b0bd3
+
0b0bd3
+                if (srcIsRoot)
0b0bd3
+                    RegionTranslate(&rgn, -screen->x, -screen->y);
0b0bd3
+
0b0bd3
+                RegionSubtract(&rgn, &rgn, sd);
0b0bd3
+
0b0bd3
+                if (srcIsRoot)
0b0bd3
+                    RegionTranslate(&rgn, screen->x, screen->y);
0b0bd3
+
0b0bd3
+                if (pGC->subWindowMode == IncludeInferiors)
0b0bd3
+                    RegionDestroy(sd);
0b0bd3
+            }
0b0bd3
+
0b0bd3
+            /* -dx/-dy to get back to dest-relative, plus request offsets */
0b0bd3
+            RegionTranslate(&rgn, -dx + dstx, -dy + dsty);
0b0bd3
+
0b0bd3
+            /* intersect with gc clip; just one screen is fine because pixmap */
0b0bd3
+            RegionIntersect(&rgn, &rgn, pGC->pCompositeClip);
0b0bd3
+
0b0bd3
+            /* and expose */
0b0bd3
+            pGC->pScreen->SendGraphicsExpose(client, &rgn, dst->info[0].id,
0b0bd3
+                                             X_CopyArea, 0);
0b0bd3
+            RegionUninit(&rgn);
0b0bd3
+        }
0b0bd3
     }
0b0bd3
     else {
0b0bd3
         DrawablePtr pDst = NULL, pSrc = NULL;
0b0bd3
-- 
0b0bd3
1.9.3
0b0bd3