static void trim_region (RegionPtr pRegion, DrawablePtr pDrawable, int subWindowMode) { RegionRec pixClip; int draw_x = 0; int draw_y = 0; #ifdef COMPOSITE int screen_x = 0, screen_y = 0; #endif /* short circuit for empty regions */ if (!REGION_NOTEMPTY(pScreen, pRegion)) return; #ifdef COMPOSITE /* * When drawing to a pixmap which is storing window contents, * the region presented is in pixmap relative coordinates which * need to be converted to screen relative coordinates */ if (pDrawable->type != DRAWABLE_WINDOW) { screen_x = ((PixmapPtr) pDrawable)->screen_x - pDrawable->x; screen_y = ((PixmapPtr) pDrawable)->screen_y - pDrawable->y; } if (screen_x || screen_y) REGION_TRANSLATE (pScreen, pRegion, screen_x, screen_y); #endif /* Clip against any children */ if (pDrawable->type == DRAWABLE_WINDOW && ((WindowPtr)(pDrawable))->backingStore == NotUseful) { if (subWindowMode == ClipByChildren) { REGION_INTERSECT(pScreen, pRegion, pRegion, &((WindowPtr)(pDrawable))->clipList); } else if (subWindowMode == IncludeInferiors) { RegionPtr pTempRegion = NotClippedByChildren((WindowPtr)(pDrawable)); REGION_INTERSECT(pScreen, pRegion, pRegion, pTempRegion); REGION_DESTROY(pScreen, pTempRegion); } /* If subWindowMode is set to an invalid value, don't perform * any drawable-based clipping. */ } /* Clip against border or pixmap bounds */ if (pDrawable->type == DRAWABLE_WINDOW) { REGION_INTERSECT (pScreen, pRegion, pRegion, &((WindowPtr)(pDrawable))->borderClip); } else { BoxRec box; draw_x = pDrawable->x; draw_y = pDrawable->y; #ifdef COMPOSITE /* * Need to move everyone to screen coordinates * XXX what about off-screen pixmaps with non-zero x/y? */ if (!WindowDrawable(pDrawable->type)) { draw_x += ((PixmapPtr) pDrawable)->screen_x; draw_y += ((PixmapPtr) pDrawable)->screen_y; } #endif box.x1 = draw_x; box.y1 = draw_y; box.x2 = draw_x + pDrawable->width; box.y2 = draw_y + pDrawable->height; REGION_INIT(pScreen, &pixClip, &box, 1); REGION_INTERSECT (pScreen, pRegion, pRegion, &pixClip); REGION_UNINIT(pScreen, &pixClip); } /* * Move region to target coordinate space */ if (draw_x || draw_y) REGION_TRANSLATE (pScreen, pRegion, -draw_x, -draw_y); /* Now do something with the damage */ }
void miValidatePicture (PicturePtr pPicture, Mask mask) { DrawablePtr pDrawable = pPicture->pDrawable; if ((mask & (CPClipXOrigin|CPClipYOrigin|CPClipMask|CPSubwindowMode)) || (pDrawable->serialNumber != (pPicture->serialNumber & DRAWABLE_SERIAL_BITS))) { if (pDrawable->type == DRAWABLE_WINDOW) { WindowPtr pWin = (WindowPtr) pDrawable; RegionPtr pregWin; Bool freeTmpClip, freeCompClip; if (pPicture->subWindowMode == IncludeInferiors) { pregWin = NotClippedByChildren(pWin); freeTmpClip = TRUE; } else { pregWin = &pWin->clipList; freeTmpClip = FALSE; } freeCompClip = pPicture->freeCompClip; /* * if there is no client clip, we can get by with just keeping the * pointer we got, and remembering whether or not should destroy * (or maybe re-use) it later. this way, we avoid unnecessary * copying of regions. (this wins especially if many clients clip * by children and have no client clip.) */ if (pPicture->clientClipType == CT_NONE) { if (freeCompClip) RegionDestroy(pPicture->pCompositeClip); pPicture->pCompositeClip = pregWin; pPicture->freeCompClip = freeTmpClip; } else { /* * we need one 'real' region to put into the composite clip. if * pregWin the current composite clip are real, we can get rid of * one. if pregWin is real and the current composite clip isn't, * use pregWin for the composite clip. if the current composite * clip is real and pregWin isn't, use the current composite * clip. if neither is real, create a new region. */ RegionTranslate(pPicture->clientClip, pDrawable->x + pPicture->clipOrigin.x, pDrawable->y + pPicture->clipOrigin.y); if (freeCompClip) { RegionIntersect(pPicture->pCompositeClip, pregWin, pPicture->clientClip); if (freeTmpClip) RegionDestroy(pregWin); } else if (freeTmpClip) { RegionIntersect(pregWin, pregWin, pPicture->clientClip); pPicture->pCompositeClip = pregWin; } else { pPicture->pCompositeClip = RegionCreate(NullBox, 0); RegionIntersect(pPicture->pCompositeClip, pregWin, pPicture->clientClip); } pPicture->freeCompClip = TRUE; RegionTranslate(pPicture->clientClip, -(pDrawable->x + pPicture->clipOrigin.x), -(pDrawable->y + pPicture->clipOrigin.y)); } } /* end of composite clip for a window */ else { BoxRec pixbounds; /* XXX should we translate by drawable.x/y here ? */ /* If you want pixmaps in offscreen memory, yes */ pixbounds.x1 = pDrawable->x; pixbounds.y1 = pDrawable->y; pixbounds.x2 = pDrawable->x + pDrawable->width; pixbounds.y2 = pDrawable->y + pDrawable->height; if (pPicture->freeCompClip) { RegionReset(pPicture->pCompositeClip, &pixbounds); } else { pPicture->freeCompClip = TRUE; pPicture->pCompositeClip = RegionCreate(&pixbounds, 1); } if (pPicture->clientClipType == CT_REGION) { if(pDrawable->x || pDrawable->y) { RegionTranslate(pPicture->clientClip, pDrawable->x + pPicture->clipOrigin.x, pDrawable->y + pPicture->clipOrigin.y); RegionIntersect(pPicture->pCompositeClip, pPicture->pCompositeClip, pPicture->clientClip); RegionTranslate(pPicture->clientClip, -(pDrawable->x + pPicture->clipOrigin.x), -(pDrawable->y + pPicture->clipOrigin.y)); } else { RegionTranslate(pPicture->pCompositeClip, -pPicture->clipOrigin.x, -pPicture->clipOrigin.y); RegionIntersect(pPicture->pCompositeClip, pPicture->pCompositeClip, pPicture->clientClip); RegionTranslate(pPicture->pCompositeClip, pPicture->clipOrigin.x, pPicture->clipOrigin.y); } } } /* end of composite clip for pixmap */ } }
void miComputeCompositeClip(GCPtr pGC, DrawablePtr pDrawable) { if (pDrawable->type == DRAWABLE_WINDOW) { WindowPtr pWin = (WindowPtr) pDrawable; RegionPtr pregWin; Bool freeTmpClip, freeCompClip; if (pGC->subWindowMode == IncludeInferiors) { pregWin = NotClippedByChildren(pWin); freeTmpClip = TRUE; } else { pregWin = &pWin->clipList; freeTmpClip = FALSE; } freeCompClip = pGC->freeCompClip; /* * if there is no client clip, we can get by with just keeping the * pointer we got, and remembering whether or not should destroy (or * maybe re-use) it later. this way, we avoid unnecessary copying of * regions. (this wins especially if many clients clip by children * and have no client clip.) */ if (!pGC->clientClip) { if (freeCompClip) RegionDestroy(pGC->pCompositeClip); pGC->pCompositeClip = pregWin; pGC->freeCompClip = freeTmpClip; } else { /* * we need one 'real' region to put into the composite clip. if * pregWin the current composite clip are real, we can get rid of * one. if pregWin is real and the current composite clip isn't, * use pregWin for the composite clip. if the current composite * clip is real and pregWin isn't, use the current composite * clip. if neither is real, create a new region. */ RegionTranslate(pGC->clientClip, pDrawable->x + pGC->clipOrg.x, pDrawable->y + pGC->clipOrg.y); if (freeCompClip) { RegionIntersect(pGC->pCompositeClip, pregWin, pGC->clientClip); if (freeTmpClip) RegionDestroy(pregWin); } else if (freeTmpClip) { RegionIntersect(pregWin, pregWin, pGC->clientClip); pGC->pCompositeClip = pregWin; } else { pGC->pCompositeClip = RegionCreate(NullBox, 0); RegionIntersect(pGC->pCompositeClip, pregWin, pGC->clientClip); } pGC->freeCompClip = TRUE; RegionTranslate(pGC->clientClip, -(pDrawable->x + pGC->clipOrg.x), -(pDrawable->y + pGC->clipOrg.y)); } } /* end of composite clip for a window */ else { BoxRec pixbounds; /* XXX should we translate by drawable.x/y here ? */ /* If you want pixmaps in offscreen memory, yes */ pixbounds.x1 = pDrawable->x; pixbounds.y1 = pDrawable->y; pixbounds.x2 = pDrawable->x + pDrawable->width; pixbounds.y2 = pDrawable->y + pDrawable->height; if (pGC->freeCompClip) { RegionReset(pGC->pCompositeClip, &pixbounds); } else { pGC->freeCompClip = TRUE; pGC->pCompositeClip = RegionCreate(&pixbounds, 1); } if (pGC->clientClip) { if (pDrawable->x || pDrawable->y) { RegionTranslate(pGC->clientClip, pDrawable->x + pGC->clipOrg.x, pDrawable->y + pGC->clipOrg.y); RegionIntersect(pGC->pCompositeClip, pGC->pCompositeClip, pGC->clientClip); RegionTranslate(pGC->clientClip, -(pDrawable->x + pGC->clipOrg.x), -(pDrawable->y + pGC->clipOrg.y)); } else { RegionTranslate(pGC->pCompositeClip, -pGC->clipOrg.x, -pGC->clipOrg.y); RegionIntersect(pGC->pCompositeClip, pGC->pCompositeClip, pGC->clientClip); RegionTranslate(pGC->pCompositeClip, pGC->clipOrg.x, pGC->clipOrg.y); } } } /* end of composite clip for pixmap */ } /* end miComputeCompositeClip */
RegionPtr XAABitBlt( DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GC *pGC, int srcx, int srcy, int width, int height, int dstx, int dsty, void (*doBitBlt)(DrawablePtr, DrawablePtr, GCPtr, RegionPtr, DDXPointPtr), unsigned long bitPlane ) { RegionPtr prgnSrcClip = NULL; /* may be a new region, or just a copy */ RegionPtr prgnExposed; Bool freeSrcClip = FALSE; RegionRec rgnDst; DDXPointPtr pptSrc, ppt; DDXPointRec origDest; BoxPtr pbox; BoxRec fastBox; int i, dx, dy, numRects; xRectangle origSource; int fastClip = 0; /* for fast clipping with pixmap source */ int fastExpose = 0; /* for fast exposures with pixmap source */ origSource.x = srcx; origSource.y = srcy; origSource.width = width; origSource.height = height; origDest.x = dstx; origDest.y = dsty; if((pSrcDrawable != pDstDrawable) && pSrcDrawable->pScreen->SourceValidate) { (*pSrcDrawable->pScreen->SourceValidate) ( pSrcDrawable, srcx, srcy, width, height); } srcx += pSrcDrawable->x; srcy += pSrcDrawable->y; /* clip the source */ if (pSrcDrawable->type == DRAWABLE_PIXMAP) { if ((pSrcDrawable == pDstDrawable) && (pGC->clientClipType == CT_NONE)) prgnSrcClip = pGC->pCompositeClip; else fastClip = 1; } else { /* Window */ if (pGC->subWindowMode == IncludeInferiors) { if (!((WindowPtr) pSrcDrawable)->parent) { /* * special case bitblt from root window in * IncludeInferiors mode; just like from a pixmap */ fastClip = 1; } else if ((pSrcDrawable == pDstDrawable) && (pGC->clientClipType == CT_NONE)) { prgnSrcClip = pGC->pCompositeClip; } else { prgnSrcClip = NotClippedByChildren((WindowPtr)pSrcDrawable); freeSrcClip = TRUE; } } else { prgnSrcClip = &((WindowPtr)pSrcDrawable)->clipList; } } fastBox.x1 = srcx; fastBox.y1 = srcy; fastBox.x2 = srcx + width; fastBox.y2 = srcy + height; /* Don't create a source region if we are doing a fast clip */ if (fastClip) { fastExpose = 1; /* * clip the source; if regions extend beyond the source size, * make sure exposure events get sent */ if (fastBox.x1 < pSrcDrawable->x) { fastBox.x1 = pSrcDrawable->x; fastExpose = 0; } if (fastBox.y1 < pSrcDrawable->y) { fastBox.y1 = pSrcDrawable->y; fastExpose = 0; } if (fastBox.x2 > pSrcDrawable->x + (int) pSrcDrawable->width) { fastBox.x2 = pSrcDrawable->x + (int) pSrcDrawable->width; fastExpose = 0; } if (fastBox.y2 > pSrcDrawable->y + (int) pSrcDrawable->height) { fastBox.y2 = pSrcDrawable->y + (int) pSrcDrawable->height; fastExpose = 0; } } else { REGION_INIT(pGC->pScreen, &rgnDst, &fastBox, 1); REGION_INTERSECT(pGC->pScreen, &rgnDst, &rgnDst, prgnSrcClip); } dstx += pDstDrawable->x; dsty += pDstDrawable->y; if (pDstDrawable->type == DRAWABLE_WINDOW) { if (!((WindowPtr)pDstDrawable)->realized) { if (!fastClip) REGION_UNINIT(pGC->pScreen, &rgnDst); if (freeSrcClip) REGION_DESTROY(pGC->pScreen, prgnSrcClip); return NULL; } } dx = srcx - dstx; dy = srcy - dsty; /* Translate and clip the dst to the destination composite clip */ if (fastClip) { RegionPtr cclip; /* Translate the region directly */ fastBox.x1 -= dx; fastBox.x2 -= dx; fastBox.y1 -= dy; fastBox.y2 -= dy; /* If the destination composite clip is one rectangle we can do the clip directly. Otherwise we have to create a full blown region and call intersect */ cclip = pGC->pCompositeClip; if (REGION_NUM_RECTS(cclip) == 1) { BoxPtr pBox = REGION_RECTS(cclip); if (fastBox.x1 < pBox->x1) fastBox.x1 = pBox->x1; if (fastBox.x2 > pBox->x2) fastBox.x2 = pBox->x2; if (fastBox.y1 < pBox->y1) fastBox.y1 = pBox->y1; if (fastBox.y2 > pBox->y2) fastBox.y2 = pBox->y2; /* Check to see if the region is empty */ if (fastBox.x1 >= fastBox.x2 || fastBox.y1 >= fastBox.y2) { REGION_NULL(pGC->pScreen, &rgnDst); } else { REGION_INIT(pGC->pScreen, &rgnDst, &fastBox, 1); } } else { /* We must turn off fastClip now, since we must create a full blown region. It is intersected with the composite clip below. */ fastClip = 0; REGION_INIT(pGC->pScreen, &rgnDst, &fastBox,1); } } else { REGION_TRANSLATE(pGC->pScreen, &rgnDst, -dx, -dy); } if (!fastClip) { REGION_INTERSECT(pGC->pScreen, &rgnDst, &rgnDst, pGC->pCompositeClip); } /* Do bit blitting */ numRects = REGION_NUM_RECTS(&rgnDst); if (numRects && width && height) { if(!(pptSrc = (DDXPointPtr)ALLOCATE_LOCAL(numRects * sizeof(DDXPointRec)))) { REGION_UNINIT(pGC->pScreen, &rgnDst); if (freeSrcClip) REGION_DESTROY(pGC->pScreen, prgnSrcClip); return NULL; } pbox = REGION_RECTS(&rgnDst); ppt = pptSrc; for (i = numRects; --i >= 0; pbox++, ppt++) { ppt->x = pbox->x1 + dx; ppt->y = pbox->y1 + dy; } (*doBitBlt) (pSrcDrawable, pDstDrawable, pGC, &rgnDst, pptSrc); DEALLOCATE_LOCAL(pptSrc); } prgnExposed = NULL; if (pGC->fExpose) { /* Pixmap sources generate a NoExposed (we return NULL to do this) */ if (!fastExpose) prgnExposed = miHandleExposures(pSrcDrawable, pDstDrawable, pGC, origSource.x, origSource.y, (int)origSource.width, (int)origSource.height, origDest.x, origDest.y, bitPlane); } REGION_UNINIT(pGC->pScreen, &rgnDst); if (freeSrcClip) REGION_DESTROY(pGC->pScreen, prgnSrcClip); return prgnExposed; }
RegionPtr miDoCopy(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC, int xIn, int yIn, int widthSrc, int heightSrc, int xOut, int yOut, miCopyProc copyProc, Pixel bitPlane, void *closure) { RegionPtr prgnSrcClip = NULL; /* may be a new region, or just a copy */ Bool freeSrcClip = FALSE; RegionPtr prgnExposed = NULL; RegionRec rgnDst; int dx; int dy; int numRects; int box_x1; int box_y1; int box_x2; int box_y2; Bool fastSrc = FALSE; /* for fast clipping with pixmap source */ Bool fastDst = FALSE; /* for fast clipping with one rect dest */ Bool fastExpose = FALSE; /* for fast exposures with pixmap source */ /* Short cut for unmapped or fully clipped windows */ if (pDstDrawable->type == DRAWABLE_WINDOW && RegionNil(&((WindowPtr)pDstDrawable)->clipList)) { return NULL; } if (pSrcDrawable->pScreen->SourceValidate) { (*pSrcDrawable->pScreen->SourceValidate) (pSrcDrawable, xIn, yIn, widthSrc, heightSrc, pGC->subWindowMode); } /* Compute source clip region */ if (pSrcDrawable->type == DRAWABLE_PIXMAP) { if ((pSrcDrawable == pDstDrawable) && (!pGC->clientClip)) prgnSrcClip = miGetCompositeClip(pGC); else fastSrc = TRUE; } else { if (pGC->subWindowMode == IncludeInferiors) { /* * XFree86 DDX empties the border clip when the * VT is inactive, make sure the region isn't empty */ if (!((WindowPtr) pSrcDrawable)->parent && RegionNotEmpty(&((WindowPtr) pSrcDrawable)->borderClip)) { /* * special case bitblt from root window in * IncludeInferiors mode; just like from a pixmap */ fastSrc = TRUE; } else if ((pSrcDrawable == pDstDrawable) && (!pGC->clientClip)) { prgnSrcClip = miGetCompositeClip(pGC); } else { prgnSrcClip = NotClippedByChildren((WindowPtr) pSrcDrawable); freeSrcClip = TRUE; } } else { prgnSrcClip = &((WindowPtr) pSrcDrawable)->clipList; } } xIn += pSrcDrawable->x; yIn += pSrcDrawable->y; xOut += pDstDrawable->x; yOut += pDstDrawable->y; box_x1 = xIn; box_y1 = yIn; box_x2 = xIn + widthSrc; box_y2 = yIn + heightSrc; dx = xIn - xOut; dy = yIn - yOut; /* Don't create a source region if we are doing a fast clip */ if (fastSrc) { RegionPtr cclip; fastExpose = TRUE; /* * clip the source; if regions extend beyond the source size, * make sure exposure events get sent */ if (box_x1 < pSrcDrawable->x) { box_x1 = pSrcDrawable->x; fastExpose = FALSE; } if (box_y1 < pSrcDrawable->y) { box_y1 = pSrcDrawable->y; fastExpose = FALSE; } if (box_x2 > pSrcDrawable->x + (int) pSrcDrawable->width) { box_x2 = pSrcDrawable->x + (int) pSrcDrawable->width; fastExpose = FALSE; } if (box_y2 > pSrcDrawable->y + (int) pSrcDrawable->height) { box_y2 = pSrcDrawable->y + (int) pSrcDrawable->height; fastExpose = FALSE; } /* Translate and clip the dst to the destination composite clip */ box_x1 -= dx; box_x2 -= dx; box_y1 -= dy; box_y2 -= dy; /* If the destination composite clip is one rectangle we can do the clip directly. Otherwise we have to create a full blown region and call intersect */ cclip = miGetCompositeClip(pGC); if (RegionNumRects(cclip) == 1) { BoxPtr pBox = RegionRects(cclip); if (box_x1 < pBox->x1) box_x1 = pBox->x1; if (box_x2 > pBox->x2) box_x2 = pBox->x2; if (box_y1 < pBox->y1) box_y1 = pBox->y1; if (box_y2 > pBox->y2) box_y2 = pBox->y2; fastDst = TRUE; } } /* Check to see if the region is empty */ if (box_x1 >= box_x2 || box_y1 >= box_y2) { RegionNull(&rgnDst); } else { BoxRec box; box.x1 = box_x1; box.y1 = box_y1; box.x2 = box_x2; box.y2 = box_y2; RegionInit(&rgnDst, &box, 1); } /* Clip against complex source if needed */ if (!fastSrc) { RegionIntersect(&rgnDst, &rgnDst, prgnSrcClip); RegionTranslate(&rgnDst, -dx, -dy); } /* Clip against complex dest if needed */ if (!fastDst) { RegionIntersect(&rgnDst, &rgnDst, miGetCompositeClip(pGC)); } /* Do bit blitting */ numRects = RegionNumRects(&rgnDst); if (numRects && widthSrc && heightSrc) miCopyRegion(pSrcDrawable, pDstDrawable, pGC, &rgnDst, dx, dy, copyProc, bitPlane, closure); /* Pixmap sources generate a NoExposed (we return NULL to do this) */ if (!fastExpose && pGC->fExpose) prgnExposed = miHandleExposures(pSrcDrawable, pDstDrawable, pGC, xIn - pSrcDrawable->x, yIn - pSrcDrawable->y, widthSrc, heightSrc, xOut - pDstDrawable->x, yOut - pDstDrawable->y); RegionUninit(&rgnDst); if (freeSrcClip) RegionDestroy(prgnSrcClip); return prgnExposed; }
RegionPtr miHandleExposures(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC, int srcx, int srcy, int width, int height, int dstx, int dsty) { RegionPtr prgnSrcClip; /* drawable-relative source clip */ RegionRec rgnSrcRec; RegionPtr prgnDstClip; /* drawable-relative dest clip */ RegionRec rgnDstRec; BoxRec srcBox; /* unclipped source */ RegionRec rgnExposed; /* exposed region, calculated source- relative, made dst relative to intersect with visible parts of dest and send events to client, and then screen relative to paint the window background */ WindowPtr pSrcWin; BoxRec expBox = { 0, }; Bool extents; /* avoid work if we can */ if (!pGC->graphicsExposures && pDstDrawable->type == DRAWABLE_PIXMAP) return NULL; srcBox.x1 = srcx; srcBox.y1 = srcy; srcBox.x2 = srcx + width; srcBox.y2 = srcy + height; if (pSrcDrawable->type != DRAWABLE_PIXMAP) { BoxRec TsrcBox; TsrcBox.x1 = srcx + pSrcDrawable->x; TsrcBox.y1 = srcy + pSrcDrawable->y; TsrcBox.x2 = TsrcBox.x1 + width; TsrcBox.y2 = TsrcBox.y1 + height; pSrcWin = (WindowPtr) pSrcDrawable; if (pGC->subWindowMode == IncludeInferiors) { prgnSrcClip = NotClippedByChildren(pSrcWin); if ((RegionContainsRect(prgnSrcClip, &TsrcBox)) == rgnIN) { RegionDestroy(prgnSrcClip); return NULL; } } else { if ((RegionContainsRect(&pSrcWin->clipList, &TsrcBox)) == rgnIN) return NULL; prgnSrcClip = &rgnSrcRec; RegionNull(prgnSrcClip); RegionCopy(prgnSrcClip, &pSrcWin->clipList); } RegionTranslate(prgnSrcClip, -pSrcDrawable->x, -pSrcDrawable->y); } else { BoxRec box; if ((srcBox.x1 >= 0) && (srcBox.y1 >= 0) && (srcBox.x2 <= pSrcDrawable->width) && (srcBox.y2 <= pSrcDrawable->height)) return NULL; box.x1 = 0; box.y1 = 0; box.x2 = pSrcDrawable->width; box.y2 = pSrcDrawable->height; prgnSrcClip = &rgnSrcRec; RegionInit(prgnSrcClip, &box, 1); pSrcWin = NULL; } if (pDstDrawable == pSrcDrawable) { prgnDstClip = prgnSrcClip; } else if (pDstDrawable->type != DRAWABLE_PIXMAP) { if (pGC->subWindowMode == IncludeInferiors) { prgnDstClip = NotClippedByChildren((WindowPtr) pDstDrawable); } else { prgnDstClip = &rgnDstRec; RegionNull(prgnDstClip); RegionCopy(prgnDstClip, &((WindowPtr) pDstDrawable)->clipList); } RegionTranslate(prgnDstClip, -pDstDrawable->x, -pDstDrawable->y); } else { BoxRec box; box.x1 = 0; box.y1 = 0; box.x2 = pDstDrawable->width; box.y2 = pDstDrawable->height; prgnDstClip = &rgnDstRec; RegionInit(prgnDstClip, &box, 1); } /* drawable-relative source region */ RegionInit(&rgnExposed, &srcBox, 1); /* now get the hidden parts of the source box */ RegionSubtract(&rgnExposed, &rgnExposed, prgnSrcClip); /* move them over the destination */ RegionTranslate(&rgnExposed, dstx - srcx, dsty - srcy); /* intersect with visible areas of dest */ RegionIntersect(&rgnExposed, &rgnExposed, prgnDstClip); /* intersect with client clip region. */ if (pGC->clientClip) RegionIntersect(&rgnExposed, &rgnExposed, pGC->clientClip); /* * If we have LOTS of rectangles, we decide to take the extents * and force an exposure on that. This should require much less * work overall, on both client and server. This is cheating, but * isn't prohibited by the protocol ("spontaneous combustion" :-) * for windows. */ extents = pGC->graphicsExposures && (RegionNumRects(&rgnExposed) > RECTLIMIT) && (pDstDrawable->type != DRAWABLE_PIXMAP); if (pSrcWin) { RegionPtr region; if (!(region = wClipShape(pSrcWin))) region = wBoundingShape(pSrcWin); /* * If you try to CopyArea the extents of a shaped window, compacting the * exposed region will undo all our work! */ if (extents && pSrcWin && region && (RegionContainsRect(region, &srcBox) != rgnIN)) extents = FALSE; } if (extents) { expBox = *RegionExtents(&rgnExposed); RegionReset(&rgnExposed, &expBox); } if ((pDstDrawable->type != DRAWABLE_PIXMAP) && (((WindowPtr) pDstDrawable)->backgroundState != None)) { WindowPtr pWin = (WindowPtr) pDstDrawable; /* make the exposed area screen-relative */ RegionTranslate(&rgnExposed, pDstDrawable->x, pDstDrawable->y); if (extents) { /* PaintWindow doesn't clip, so we have to */ RegionIntersect(&rgnExposed, &rgnExposed, &pWin->clipList); } pDstDrawable->pScreen->PaintWindow((WindowPtr) pDstDrawable, &rgnExposed, PW_BACKGROUND); if (extents) { RegionReset(&rgnExposed, &expBox); } else RegionTranslate(&rgnExposed, -pDstDrawable->x, -pDstDrawable->y); } if (prgnDstClip == &rgnDstRec) { RegionUninit(prgnDstClip); } else if (prgnDstClip != prgnSrcClip) { RegionDestroy(prgnDstClip); } if (prgnSrcClip == &rgnSrcRec) { RegionUninit(prgnSrcClip); } else { RegionDestroy(prgnSrcClip); } if (pGC->graphicsExposures) { /* don't look */ RegionPtr exposed = RegionCreate(NullBox, 0); *exposed = rgnExposed; return exposed; } else { RegionUninit(&rgnExposed); return NULL; } }