xserver: Branch 'master'

Adam Jackson ajax at kemper.freedesktop.org
Wed Mar 15 20:18:35 UTC 2017


 Xext/panoramiXprocs.c |   70 ++++++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 60 insertions(+), 10 deletions(-)

New commits:
commit e337de2d488a124e5fee0fdcb882567b68f1767d
Author: Adam Jackson <ajax at redhat.com>
Date:   Wed Nov 2 12:49:25 2016 -0400

    xinerama: Implement graphics exposures for window->pixmap copies (v4)
    
    This code is using GetImage to accumulate a logical view of the window
    image (since the windows will be clipped to their containing screen),
    and then PutImage to load that back into the pixmap.  What it wasn't
    doing was constructing a region for the obscured areas of the window and
    emitting graphics exposures for same.
    
    v2: Fix coordinate translation when the source is the root window
    v3: Create sourceBox with the right coordinates initially instead of
    translating (Keith Packard)
    v4: Clamp the region to 15 bits to avoid overflow (Keith Packard)
    
    Signed-off-by: Adam Jackson <ajax at redhat.com>

diff --git a/Xext/panoramiXprocs.c b/Xext/panoramiXprocs.c
index 18f3ac7..f31b1e0 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;


More information about the xorg-commit mailing list