int draw_item_add_line_region(rdpPixmapRec *priv, RegionPtr reg, int color, int opcode, int width, xSegment *segs, int nseg, int is_segment) { struct rdp_draw_item *di; LLOGLN(10, ("draw_item_add_line_region:")); di = (struct rdp_draw_item *)g_malloc(sizeof(struct rdp_draw_item), 1); di->type = RDI_LINE; di->u.line.fg_color = color; di->u.line.opcode = opcode; di->u.line.width = width; di->u.line.segs = (xSegment *)g_malloc(sizeof(xSegment) * nseg, 1); memcpy(di->u.line.segs, segs, sizeof(xSegment) * nseg); di->u.line.nseg = nseg; if (is_segment) { di->u.line.flags = 1; } di->reg = RegionCreate(NullBox, 0); di->flags |= 1; RegionCopy(di->reg, reg); draw_item_add(priv, di); return 0; }
RegionPtr CreateClipShape(WindowPtr pWin) { BoxRec extents; extents.x1 = 0; extents.y1 = 0; extents.x2 = pWin->drawable.width; extents.y2 = pWin->drawable.height; return RegionCreate(&extents, 1); }
void miCopyClip(GCPtr pgcDst, GCPtr pgcSrc) { if (pgcSrc->clientClip) { RegionPtr prgnNew = RegionCreate(NULL, 1); RegionCopy(prgnNew, (RegionPtr) (pgcSrc->clientClip)); (*pgcDst->funcs->ChangeClip) (pgcDst, CT_REGION, prgnNew, 0); } else { (*pgcDst->funcs->ChangeClip) (pgcDst, CT_NONE, NULL, 0); } }
RegionPtr CreateBoundingShape(WindowPtr pWin) { BoxRec extents; extents.x1 = -wBorderWidth(pWin); extents.y1 = -wBorderWidth(pWin); extents.x2 = pWin->drawable.width + wBorderWidth(pWin); extents.y2 = pWin->drawable.height + wBorderWidth(pWin); return RegionCreate(&extents, 1); }
Bool xf86InitFBManagerRegion(ScreenPtr pScreen, RegionPtr FullRegion) { FBManagerPtr offman; if (RegionNil(FullRegion)) return FALSE; if (!dixRegisterPrivateKey(&xf86FBScreenKeyRec, PRIVATE_SCREEN, 0)) return FALSE; if (!xf86RegisterOffscreenManager(pScreen, &xf86FBManFuncs)) return FALSE; offman = malloc(sizeof(FBManager)); if (!offman) return FALSE; dixSetPrivate(&pScreen->devPrivates, xf86FBScreenKey, offman); offman->CloseScreen = pScreen->CloseScreen; pScreen->CloseScreen = xf86FBCloseScreen; offman->InitialBoxes = RegionCreate(NULL, 1); offman->FreeBoxes = RegionCreate(NULL, 1); RegionCopy(offman->InitialBoxes, FullRegion); RegionCopy(offman->FreeBoxes, FullRegion); offman->pScreen = pScreen; offman->UsedAreas = NULL; offman->LinearAreas = NULL; offman->NumUsedAreas = 0; offman->NumCallbacks = 0; offman->FreeBoxesUpdateCallback = NULL; offman->devPrivates = NULL; return TRUE; }
void miSetShape(WindowPtr pWin, int kind) { Bool WasViewable = (Bool) (pWin->viewable); ScreenPtr pScreen = pWin->drawable.pScreen; Bool anyMarked = FALSE; WindowPtr pLayerWin; if (kind != ShapeInput) { if (WasViewable) { anyMarked = (*pScreen->MarkOverlappedWindows) (pWin, pWin, &pLayerWin); if (pWin->valdata) { if (HasBorder(pWin)) { RegionPtr borderVisible; borderVisible = RegionCreate(NullBox, 1); RegionSubtract(borderVisible, &pWin->borderClip, &pWin->winSize); pWin->valdata->before.borderVisible = borderVisible; } pWin->valdata->before.resized = TRUE; } } SetWinSize(pWin); SetBorderSize(pWin); ResizeChildrenWinSize(pWin, 0, 0, 0, 0); if (WasViewable) { anyMarked |= (*pScreen->MarkOverlappedWindows) (pWin, pWin, NULL); if (anyMarked) (*pScreen->ValidateTree) (pLayerWin->parent, NullWindow, VTOther); } if (WasViewable) { if (anyMarked) (*pScreen->HandleExposures) (pLayerWin->parent); if (anyMarked && pScreen->PostValidateTree) (*pScreen->PostValidateTree) (pLayerWin->parent, NullWindow, VTOther); } } if (pWin->realized) WindowsRestructured(); CheckCursorConfinement(pWin); }
int draw_item_add_img_region(rdpPixmapRec *priv, RegionPtr reg, int opcode, int type) { struct rdp_draw_item *di; di = (struct rdp_draw_item *)g_malloc(sizeof(struct rdp_draw_item), 1); di->type = type; di->reg = RegionCreate(NullBox, 0); RegionCopy(di->reg, reg); di->u.img.opcode = opcode; draw_item_add(priv, di); return 0; }
RegionPtr XFixesRegionCopy(RegionPtr pRegion) { RegionPtr pNew = RegionCreate(RegionExtents(pRegion), RegionNumRects(pRegion)); if (!pNew) return 0; if (!RegionCopy(pNew, pRegion)) { RegionDestroy(pNew); return 0; } return pNew; }
void miChangeBorderWidth(WindowPtr pWin, unsigned int width) { int oldwidth; Bool anyMarked = FALSE; ScreenPtr pScreen; Bool WasViewable = (Bool) (pWin->viewable); Bool HadBorder; WindowPtr pLayerWin; oldwidth = wBorderWidth(pWin); if (oldwidth == width) return; HadBorder = HasBorder(pWin); pScreen = pWin->drawable.pScreen; if (WasViewable && width < oldwidth) anyMarked = (*pScreen->MarkOverlappedWindows) (pWin, pWin, &pLayerWin); pWin->borderWidth = width; SetBorderSize(pWin); if (WasViewable) { if (width > oldwidth) { anyMarked = (*pScreen->MarkOverlappedWindows) (pWin, pWin, &pLayerWin); /* * save the old border visible region to correctly compute * borderExposed. */ if (pWin->valdata && HadBorder) { RegionPtr borderVisible; borderVisible = RegionCreate(NULL, 1); RegionSubtract(borderVisible, &pWin->borderClip, &pWin->winSize); pWin->valdata->before.borderVisible = borderVisible; } } if (anyMarked) { (*pScreen->ValidateTree) (pLayerWin->parent, pLayerWin, VTOther); (*pScreen->HandleExposures) (pLayerWin->parent); } if (anyMarked && pScreen->PostValidateTree) (*pScreen->PostValidateTree) (pLayerWin->parent, pLayerWin, VTOther); } if (pWin->realized) WindowsRestructured(); }
int draw_item_add_fill_region(rdpPixmapRec *priv, RegionPtr reg, int color, int opcode) { struct rdp_draw_item *di; di = (struct rdp_draw_item *)g_malloc(sizeof(struct rdp_draw_item), 1); di->type = RDI_FILL; di->u.fill.fg_color = color; di->u.fill.opcode = opcode; di->reg = RegionCreate(NullBox, 0); RegionCopy(di->reg, reg); draw_item_add(priv, di); return 0; }
void sgx_exa_copy_region(DrawablePtr draw, RegionPtr reg, DrawablePtr src_draw, DrawablePtr dst_draw) { ScreenPtr screen = dst_draw->pScreen; RegionPtr copy_clip = RegionCreate(NULL, 0); GCPtr gc; gc = GetScratchGC(dst_draw->depth, screen); RegionCopy(copy_clip, reg); (*gc->funcs->ChangeClip)(gc, CT_REGION, copy_clip, 0); ValidateGC(dst_draw, gc); (*gc->ops->CopyArea)(src_draw, dst_draw, gc, 0, 0, draw->width, draw->height, 0, 0); FreeScratchGC(gc); }
void xnestCopyClip(GCPtr pGCDst, GCPtr pGCSrc) { RegionPtr pRgn; switch (pGCSrc->clientClipType) { default: case CT_NONE: xnestDestroyClip(pGCDst); break; case CT_REGION: pRgn = RegionCreate(NULL, 1); RegionCopy(pRgn, pGCSrc->clientClip); xnestChangeClip(pGCDst, CT_REGION, pRgn, 0); break; } }
int draw_item_add_srcblt_region(rdpPixmapRec *priv, RegionPtr reg, int srcx, int srcy, int dstx, int dsty, int cx, int cy) { struct rdp_draw_item *di; LLOGLN(10, ("draw_item_add_srcblt_region:")); di = (struct rdp_draw_item *)g_malloc(sizeof(struct rdp_draw_item), 1); di->type = RDI_SCRBLT; di->u.scrblt.srcx = srcx; di->u.scrblt.srcy = srcy; di->u.scrblt.dstx = dstx; di->u.scrblt.dsty = dsty; di->u.scrblt.cx = cx; di->u.scrblt.cy = cy; di->reg = RegionCreate(NullBox, 0); RegionCopy(di->reg, reg); draw_item_add(priv, di); return 0; }
Bool exaHWCopyNtoN(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC, BoxPtr pbox, int nbox, int dx, int dy, Bool reverse, Bool upsidedown) { ExaScreenPriv(pDstDrawable->pScreen); PixmapPtr pSrcPixmap, pDstPixmap; ExaPixmapPrivPtr pSrcExaPixmap, pDstExaPixmap; int src_off_x, src_off_y; int dst_off_x, dst_off_y; RegionPtr srcregion = NULL, dstregion = NULL; xRectangle *rects; Bool ret = TRUE; /* avoid doing copy operations if no boxes */ if (nbox == 0) return TRUE; pSrcPixmap = exaGetDrawablePixmap(pSrcDrawable); pDstPixmap = exaGetDrawablePixmap(pDstDrawable); exaGetDrawableDeltas(pSrcDrawable, pSrcPixmap, &src_off_x, &src_off_y); exaGetDrawableDeltas(pDstDrawable, pDstPixmap, &dst_off_x, &dst_off_y); rects = malloc(nbox * sizeof(xRectangle)); if (rects) { int i; int ordering; for (i = 0; i < nbox; i++) { rects[i].x = pbox[i].x1 + dx + src_off_x; rects[i].y = pbox[i].y1 + dy + src_off_y; rects[i].width = pbox[i].x2 - pbox[i].x1; rects[i].height = pbox[i].y2 - pbox[i].y1; } /* This must match the RegionCopy() logic for reversing rect order */ if (nbox == 1 || (dx > 0 && dy > 0) || (pDstDrawable != pSrcDrawable && (pDstDrawable->type != DRAWABLE_WINDOW || pSrcDrawable->type != DRAWABLE_WINDOW))) ordering = CT_YXBANDED; else ordering = CT_UNSORTED; srcregion = RegionFromRects(nbox, rects, ordering); free(rects); if (!pGC || !exaGCReadsDestination(pDstDrawable, pGC->planemask, pGC->fillStyle, pGC->alu, pGC->clientClip != NULL)) { dstregion = RegionCreate(NullBox, 0); RegionCopy(dstregion, srcregion); RegionTranslate(dstregion, dst_off_x - dx - src_off_x, dst_off_y - dy - src_off_y); } } pSrcExaPixmap = ExaGetPixmapPriv(pSrcPixmap); pDstExaPixmap = ExaGetPixmapPriv(pDstPixmap); /* Check whether the accelerator can use this pixmap. * If the pitch of the pixmaps is out of range, there's nothing * we can do but fall back to software rendering. */ if (pSrcExaPixmap->accel_blocked & EXA_RANGE_PITCH || pDstExaPixmap->accel_blocked & EXA_RANGE_PITCH) goto fallback; /* If the width or the height of either of the pixmaps * is out of range, check whether the boxes are actually out of the * addressable range as well. If they aren't, we can still do * the copying in hardware. */ if (pSrcExaPixmap->accel_blocked || pDstExaPixmap->accel_blocked) { int i; for (i = 0; i < nbox; i++) { /* src */ if ((pbox[i].x2 + dx + src_off_x) >= pExaScr->info->maxX || (pbox[i].y2 + dy + src_off_y) >= pExaScr->info->maxY) goto fallback; /* dst */ if ((pbox[i].x2 + dst_off_x) >= pExaScr->info->maxX || (pbox[i].y2 + dst_off_y) >= pExaScr->info->maxY) goto fallback; } } if (pExaScr->do_migration) { ExaMigrationRec pixmaps[2]; pixmaps[0].as_dst = TRUE; pixmaps[0].as_src = FALSE; pixmaps[0].pPix = pDstPixmap; pixmaps[0].pReg = dstregion; pixmaps[1].as_dst = FALSE; pixmaps[1].as_src = TRUE; pixmaps[1].pPix = pSrcPixmap; pixmaps[1].pReg = srcregion; exaDoMigration(pixmaps, 2, TRUE); } /* Mixed directions must be handled specially if the card is lame */ if ((pExaScr->info->flags & EXA_TWO_BITBLT_DIRECTIONS) && reverse != upsidedown) { if (exaCopyNtoNTwoDir(pSrcDrawable, pDstDrawable, pGC, pbox, nbox, dx, dy)) goto out; goto fallback; } if (exaPixmapHasGpuCopy(pDstPixmap)) { /* Normal blitting. */ if (exaPixmapHasGpuCopy(pSrcPixmap)) { if (!(*pExaScr->info->PrepareCopy) (pSrcPixmap, pDstPixmap, reverse ? -1 : 1, upsidedown ? -1 : 1, pGC ? pGC->alu : GXcopy, pGC ? pGC->planemask : FB_ALLONES)) { goto fallback; } while (nbox--) { (*pExaScr->info->Copy) (pDstPixmap, pbox->x1 + dx + src_off_x, pbox->y1 + dy + src_off_y, pbox->x1 + dst_off_x, pbox->y1 + dst_off_y, pbox->x2 - pbox->x1, pbox->y2 - pbox->y1); pbox++; } (*pExaScr->info->DoneCopy) (pDstPixmap); exaMarkSync(pDstDrawable->pScreen); /* UTS: mainly for SHM PutImage's secondary path. * * Only taking this path for directly accessible pixmaps. */ } else if (!pDstExaPixmap->pDamage && pSrcExaPixmap->sys_ptr) { int bpp = pSrcDrawable->bitsPerPixel; int src_stride = exaGetPixmapPitch(pSrcPixmap); CARD8 *src = NULL; if (!pExaScr->info->UploadToScreen) goto fallback; if (pSrcDrawable->bitsPerPixel != pDstDrawable->bitsPerPixel) goto fallback; if (pSrcDrawable->bitsPerPixel < 8) goto fallback; if (pGC && !(pGC->alu == GXcopy && EXA_PM_IS_SOLID(pSrcDrawable, pGC->planemask))) goto fallback; while (nbox--) { src = pSrcExaPixmap->sys_ptr + (pbox->y1 + dy + src_off_y) * src_stride + (pbox->x1 + dx + src_off_x) * (bpp / 8); if (!pExaScr->info-> UploadToScreen(pDstPixmap, pbox->x1 + dst_off_x, pbox->y1 + dst_off_y, pbox->x2 - pbox->x1, pbox->y2 - pbox->y1, (char *) src, src_stride)) goto fallback; pbox++; } } else goto fallback; } else goto fallback; goto out; fallback: ret = FALSE; out: if (dstregion) { RegionUninit(dstregion); RegionDestroy(dstregion); } if (srcregion) { RegionUninit(srcregion); RegionDestroy(srcregion); } return ret; }
/** Transfer \a pBits image to back-end server associated with \a * pDrawable's screen. If primitive subdivision optimization is * enabled, then only transfer the sections of \a pBits that are * visible (i.e., not-clipped) to the back-end server. */ void dmxPutImage(DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y, int w, int h, int leftPad, int format, char *pBits) { DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum]; dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC); XImage *img; if (DMX_GCOPS_OFFSCREEN(pDrawable)) return; img = XCreateImage(dmxScreen->beDisplay, dmxScreen->beVisuals[dmxScreen->beDefVisualIndex].visual, depth, format, leftPad, pBits, w, h, BitmapPad(dmxScreen->beDisplay), (format == ZPixmap) ? PixmapBytePad(w, depth) : BitmapBytePad(w+leftPad)); if (img) { Drawable draw; DMX_GCOPS_SET_DRAWABLE(pDrawable, draw); if (dmxSubdividePrimitives && pGC->pCompositeClip) { RegionPtr pSubImages; RegionPtr pClip; BoxRec box; BoxPtr pBox; int nBox; box.x1 = x; box.y1 = y; box.x2 = x + w; box.y2 = y + h; pSubImages = RegionCreate(&box, 1); pClip = RegionCreate(NullBox, 1); RegionCopy(pClip, pGC->pCompositeClip); RegionTranslate(pClip, -pDrawable->x, -pDrawable->y); RegionIntersect(pSubImages, pSubImages, pClip); nBox = RegionNumRects(pSubImages); pBox = RegionRects(pSubImages); while (nBox--) { XPutImage(dmxScreen->beDisplay, draw, pGCPriv->gc, img, pBox->x1 - box.x1, pBox->y1 - box.y1, pBox->x1, pBox->y1, pBox->x2 - pBox->x1, pBox->y2 - pBox->y1); pBox++; } RegionDestroy(pClip); RegionDestroy(pSubImages); } else { XPutImage(dmxScreen->beDisplay, draw, pGCPriv->gc, img, 0, 0, x, y, w, h); } XFree(img); /* Use XFree instead of XDestroyImage * because pBits is passed in from the * caller. */ dmxSync(dmxScreen, FALSE); } else { /* Error -- this should not happen! */ } }
static void cwCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc) { ScreenPtr pScreen = pWin->drawable.pScreen; SCREEN_PROLOGUE(pScreen, CopyWindow); if (!cwDrawableIsRedirWindow((DrawablePtr)pWin)) { (*pScreen->CopyWindow)(pWin, ptOldOrg, prgnSrc); } else { GCPtr pGC; BoxPtr pExtents; int x_off, y_off; int dx, dy; PixmapPtr pBackingPixmap; RegionPtr pClip; int src_x, src_y, dst_x, dst_y, w, h; dx = ptOldOrg.x - pWin->drawable.x; dy = ptOldOrg.y - pWin->drawable.y; pExtents = RegionExtents(prgnSrc); pBackingPixmap = (PixmapPtr) cwGetBackingDrawable((DrawablePtr)pWin, &x_off, &y_off); src_x = pExtents->x1 - pBackingPixmap->screen_x; src_y = pExtents->y1 - pBackingPixmap->screen_y; w = pExtents->x2 - pExtents->x1; h = pExtents->y2 - pExtents->y1; dst_x = src_x - dx; dst_y = src_y - dy; /* Translate region (as required by API) */ RegionTranslate(prgnSrc, -dx, -dy); pGC = GetScratchGC(pBackingPixmap->drawable.depth, pScreen); /* * Copy region to GC as clip, aligning as dest clip */ pClip = RegionCreate(NULL, 0); RegionIntersect(pClip, &pWin->borderClip, prgnSrc); RegionTranslate(pClip, -pBackingPixmap->screen_x, -pBackingPixmap->screen_y); (*pGC->funcs->ChangeClip) (pGC, CT_REGION, pClip, 0); ValidateGC(&pBackingPixmap->drawable, pGC); (*pGC->ops->CopyArea) (&pBackingPixmap->drawable, &pBackingPixmap->drawable, pGC, src_x, src_y, w, h, dst_x, dst_y); (*pGC->funcs->DestroyClip) (pGC); FreeScratchGC(pGC); } SCREEN_EPILOGUE(pScreen, CopyWindow, cwCopyWindow); }
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 */ } }
static Bool localQueryLargestOffscreenArea(ScreenPtr pScreen, int *width, int *height, int granularity, int preferences, int severity) { FBManagerPtr offman; RegionPtr newRegion = NULL; BoxPtr pbox; int nbox; int x, w, h, area, oldArea; *width = *height = oldArea = 0; if (granularity <= 1) granularity = 0; if ((preferences < 0) || (preferences > 3)) return FALSE; offman = (FBManagerPtr) dixLookupPrivate(&pScreen->devPrivates, xf86FBScreenKey); if (severity < 0) severity = 0; if (severity > 2) severity = 2; switch (severity) { case 2: if (offman->NumUsedAreas) { FBLinkPtr pLink; RegionRec tmpRegion; newRegion = RegionCreate(NULL, 1); RegionCopy(newRegion, offman->InitialBoxes); pLink = offman->UsedAreas; while (pLink) { if (!pLink->area.RemoveAreaCallback) { RegionInit(&tmpRegion, &(pLink->area.box), 1); RegionSubtract(newRegion, newRegion, &tmpRegion); RegionUninit(&tmpRegion); } pLink = pLink->next; } nbox = RegionNumRects(newRegion); pbox = RegionRects(newRegion); break; } case 1: if (offman->NumUsedAreas) { FBLinkPtr pLink; RegionRec tmpRegion; newRegion = RegionCreate(NULL, 1); RegionCopy(newRegion, offman->FreeBoxes); pLink = offman->UsedAreas; while (pLink) { if (pLink->area.RemoveAreaCallback) { RegionInit(&tmpRegion, &(pLink->area.box), 1); RegionAppend(newRegion, &tmpRegion); RegionUninit(&tmpRegion); } pLink = pLink->next; } nbox = RegionNumRects(newRegion); pbox = RegionRects(newRegion); break; } default: nbox = RegionNumRects(offman->FreeBoxes); pbox = RegionRects(offman->FreeBoxes); break; } while (nbox--) { x = pbox->x1; if (granularity > 1) x = ((x + granularity - 1) / granularity) * granularity; w = pbox->x2 - x; h = pbox->y2 - pbox->y1; area = w * h; if (w > 0) { Bool gotIt = FALSE; switch (preferences) { case FAVOR_AREA_THEN_WIDTH: if ((area > oldArea) || ((area == oldArea) && (w > *width))) gotIt = TRUE; break; case FAVOR_AREA_THEN_HEIGHT: if ((area > oldArea) || ((area == oldArea) && (h > *height))) gotIt = TRUE; break; case FAVOR_WIDTH_THEN_AREA: if ((w > *width) || ((w == *width) && (area > oldArea))) gotIt = TRUE; break; case FAVOR_HEIGHT_THEN_AREA: if ((h > *height) || ((h == *height) && (area > oldArea))) gotIt = TRUE; break; } if (gotIt) { *width = w; *height = h; oldArea = area; } } pbox++; } if (newRegion) RegionDestroy(newRegion); return TRUE; }
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 */
void winCopyWindowNativeGDI(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc) { DDXPointPtr pptSrc; DDXPointPtr ppt; RegionPtr prgnDst; BoxPtr pBox; int dx, dy; int i, nbox; WindowPtr pwinRoot; BoxPtr pBoxDst; ScreenPtr pScreen = pWin->drawable.pScreen; winScreenPriv(pScreen); /* Get a pointer to the root window */ pwinRoot = pWin->drawable.pScreen->root; /* Create a region for the destination */ prgnDst = RegionCreate(NULL, 1); /* Calculate the shift from the source to the destination */ dx = ptOldOrg.x - pWin->drawable.x; dy = ptOldOrg.y - pWin->drawable.y; /* Translate the region from the destination to the source? */ RegionTranslate(prgnSrc, -dx, -dy); RegionIntersect(prgnDst, &pWin->borderClip, prgnSrc); /* Get a pointer to the first box in the region to be copied */ pBox = RegionRects(prgnDst); /* Get the number of boxes in the region */ nbox = RegionNumRects(prgnDst); /* Allocate source points for each box */ if (!(pptSrc = (DDXPointPtr) malloc(nbox * sizeof(DDXPointRec)))) return; /* Set an iterator pointer */ ppt = pptSrc; /* Calculate the source point of each box? */ for (i = nbox; --i >= 0; ppt++, pBox++) { ppt->x = pBox->x1 + dx; ppt->y = pBox->y1 + dy; } /* Setup loop pointers again */ pBoxDst = RegionRects(prgnDst); ppt = pptSrc; /* BitBlt each source to the destination point */ for (i = nbox; --i >= 0; pBoxDst++, ppt++) { BitBlt(pScreenPriv->hdcScreen, pBoxDst->x1, pBoxDst->y1, pBoxDst->x2 - pBoxDst->x1, pBoxDst->y2 - pBoxDst->y1, pScreenPriv->hdcScreen, ppt->x, ppt->y, SRCCOPY); } /* Cleanup the regions, etc. */ free(pptSrc); RegionDestroy(prgnDst); }
void miMoveWindow(WindowPtr pWin, int x, int y, WindowPtr pNextSib, VTKind kind) { WindowPtr pParent; Bool WasViewable = (Bool) (pWin->viewable); short bw; RegionPtr oldRegion = NULL; DDXPointRec oldpt; Bool anyMarked = FALSE; ScreenPtr pScreen; WindowPtr windowToValidate; WindowPtr pLayerWin; /* if this is a root window, can't be moved */ if (!(pParent = pWin->parent)) return; pScreen = pWin->drawable.pScreen; bw = wBorderWidth(pWin); oldpt.x = pWin->drawable.x; oldpt.y = pWin->drawable.y; if (WasViewable) { oldRegion = RegionCreate(NullBox, 1); RegionCopy(oldRegion, &pWin->borderClip); anyMarked = (*pScreen->MarkOverlappedWindows) (pWin, pWin, &pLayerWin); } pWin->origin.x = x + (int) bw; pWin->origin.y = y + (int) bw; x = pWin->drawable.x = pParent->drawable.x + x + (int) bw; y = pWin->drawable.y = pParent->drawable.y + y + (int) bw; SetWinSize(pWin); SetBorderSize(pWin); (*pScreen->PositionWindow) (pWin, x, y); windowToValidate = MoveWindowInStack(pWin, pNextSib); ResizeChildrenWinSize(pWin, x - oldpt.x, y - oldpt.y, 0, 0); if (WasViewable) { if (pLayerWin == pWin) anyMarked |= (*pScreen->MarkOverlappedWindows) (pWin, windowToValidate, NULL); else anyMarked |= (*pScreen->MarkOverlappedWindows) (pWin, pLayerWin, NULL); if (anyMarked) { (*pScreen->ValidateTree) (pLayerWin->parent, NullWindow, kind); (*pWin->drawable.pScreen->CopyWindow) (pWin, oldpt, oldRegion); RegionDestroy(oldRegion); /* XXX need to retile border if ParentRelative origin */ (*pScreen->HandleExposures) (pLayerWin->parent); } if (anyMarked && pScreen->PostValidateTree) (*pScreen->PostValidateTree) (pLayerWin->parent, NullWindow, kind); } if (pWin->realized) WindowsRestructured(); }
static int RegionOperate(ClientPtr client, WindowPtr pWin, int kind, RegionPtr *destRgnp, RegionPtr srcRgn, int op, int xoff, int yoff, CreateDftPtr create) { if (srcRgn && (xoff || yoff)) RegionTranslate(srcRgn, xoff, yoff); if (!pWin->parent) { if (srcRgn) RegionDestroy(srcRgn); return Success; } /* May/30/2001: * The shape.PS specs say if src is None, existing shape is to be * removed (and so the op-code has no meaning in such removal); * see shape.PS, page 3, ShapeMask. */ if (srcRgn == NULL) { if (*destRgnp != NULL) { RegionDestroy(*destRgnp); *destRgnp = 0; /* go on to remove shape and generate ShapeNotify */ } else { /* May/30/2001: * The target currently has no shape in effect, so nothing to * do here. The specs say that ShapeNotify is generated whenever * the client region is "modified"; since no modification is done * here, we do not generate that event. The specs does not say * "it is an error to request removal when there is no shape in * effect", so we return good status. */ return Success; } } else switch (op) { case ShapeSet: if (*destRgnp) RegionDestroy(*destRgnp); *destRgnp = srcRgn; srcRgn = 0; break; case ShapeUnion: if (*destRgnp) RegionUnion(*destRgnp, *destRgnp, srcRgn); break; case ShapeIntersect: if (*destRgnp) RegionIntersect(*destRgnp, *destRgnp, srcRgn); else { *destRgnp = srcRgn; srcRgn = 0; } break; case ShapeSubtract: if (!*destRgnp) *destRgnp = (*create) (pWin); RegionSubtract(*destRgnp, *destRgnp, srcRgn); break; case ShapeInvert: if (!*destRgnp) *destRgnp = RegionCreate((BoxPtr) 0, 0); else RegionSubtract(*destRgnp, srcRgn, *destRgnp); break; default: client->errorValue = op; return BadValue; } if (srcRgn) RegionDestroy(srcRgn); (*pWin->drawable.pScreen->SetShape) (pWin, kind); SendShapeNotify(pWin, kind); return Success; }
static int ProcShapeCombine(ClientPtr client) { WindowPtr pSrcWin, pDestWin; REQUEST(xShapeCombineReq); RegionPtr srcRgn; RegionPtr *destRgn; CreateDftPtr createDefault; CreateDftPtr createSrc; RegionPtr tmp; int rc; REQUEST_SIZE_MATCH(xShapeCombineReq); UpdateCurrentTime(); rc = dixLookupWindow(&pDestWin, stuff->dest, client, DixSetAttrAccess); if (rc != Success) return rc; if (!pDestWin->optional) MakeWindowOptional(pDestWin); switch (stuff->destKind) { case ShapeBounding: createDefault = CreateBoundingShape; break; case ShapeClip: createDefault = CreateClipShape; break; case ShapeInput: createDefault = CreateBoundingShape; break; default: client->errorValue = stuff->destKind; return BadValue; } rc = dixLookupWindow(&pSrcWin, stuff->src, client, DixGetAttrAccess); if (rc != Success) return rc; switch (stuff->srcKind) { case ShapeBounding: srcRgn = wBoundingShape(pSrcWin); createSrc = CreateBoundingShape; break; case ShapeClip: srcRgn = wClipShape(pSrcWin); createSrc = CreateClipShape; break; case ShapeInput: srcRgn = wInputShape(pSrcWin); createSrc = CreateBoundingShape; break; default: client->errorValue = stuff->srcKind; return BadValue; } if (pSrcWin->drawable.pScreen != pDestWin->drawable.pScreen) { return BadMatch; } if (srcRgn) { tmp = RegionCreate((BoxPtr) 0, 0); RegionCopy(tmp, srcRgn); srcRgn = tmp; } else srcRgn = (*createSrc) (pSrcWin); if (!pDestWin->optional) MakeWindowOptional(pDestWin); switch (stuff->destKind) { case ShapeBounding: destRgn = &pDestWin->optional->boundingShape; break; case ShapeClip: destRgn = &pDestWin->optional->clipShape; break; case ShapeInput: destRgn = &pDestWin->optional->inputShape; break; default: return BadValue; } return RegionOperate(client, pDestWin, (int) stuff->destKind, destRgn, srcRgn, (int) stuff->op, stuff->xOff, stuff->yOff, createDefault); }
void miSlideAndSizeWindow(WindowPtr pWin, int x, int y, unsigned int w, unsigned int h, WindowPtr pSib) { WindowPtr pParent; Bool WasViewable = (Bool) (pWin->viewable); unsigned short width = pWin->drawable.width, height = pWin->drawable.height; short oldx = pWin->drawable.x, oldy = pWin->drawable.y; int bw = wBorderWidth(pWin); short dw, dh; DDXPointRec oldpt; RegionPtr oldRegion = NULL; Bool anyMarked = FALSE; ScreenPtr pScreen; WindowPtr pFirstChange; WindowPtr pChild; RegionPtr gravitate[StaticGravity + 1]; unsigned g; int nx, ny; /* destination x,y */ int newx, newy; /* new inner window position */ RegionPtr pRegion = NULL; RegionPtr destClip; /* portions of destination already written */ RegionPtr oldWinClip = NULL; /* old clip list for window */ RegionPtr borderVisible = NullRegion; /* visible area of the border */ Bool shrunk = FALSE; /* shrunk in an inner dimension */ Bool moved = FALSE; /* window position changed */ WindowPtr pLayerWin; /* if this is a root window, can't be resized */ if (!(pParent = pWin->parent)) return; pScreen = pWin->drawable.pScreen; newx = pParent->drawable.x + x + bw; newy = pParent->drawable.y + y + bw; if (WasViewable) { anyMarked = FALSE; /* * save the visible region of the window */ oldRegion = RegionCreate(NullBox, 1); RegionCopy(oldRegion, &pWin->winSize); /* * categorize child windows into regions to be moved */ for (g = 0; g <= StaticGravity; g++) gravitate[g] = (RegionPtr) NULL; for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib) { g = pChild->winGravity; if (g != UnmapGravity) { if (!gravitate[g]) gravitate[g] = RegionCreate(NullBox, 1); RegionUnion(gravitate[g], gravitate[g], &pChild->borderClip); } else { UnmapWindow(pChild, TRUE); anyMarked = TRUE; } } anyMarked |= (*pScreen->MarkOverlappedWindows) (pWin, pWin, &pLayerWin); oldWinClip = NULL; if (pWin->bitGravity != ForgetGravity) { oldWinClip = RegionCreate(NullBox, 1); RegionCopy(oldWinClip, &pWin->clipList); } /* * if the window is changing size, borderExposed * can't be computed correctly without some help. */ if (pWin->drawable.height > h || pWin->drawable.width > w) shrunk = TRUE; if (newx != oldx || newy != oldy) moved = TRUE; if ((pWin->drawable.height != h || pWin->drawable.width != w) && HasBorder(pWin)) { borderVisible = RegionCreate(NullBox, 1); /* for tiled borders, we punt and draw the whole thing */ if (pWin->borderIsPixel || !moved) { if (shrunk || moved) RegionSubtract(borderVisible, &pWin->borderClip, &pWin->winSize); else RegionCopy(borderVisible, &pWin->borderClip); } } } pWin->origin.x = x + bw; pWin->origin.y = y + bw; pWin->drawable.height = h; pWin->drawable.width = w; x = pWin->drawable.x = newx; y = pWin->drawable.y = newy; SetWinSize(pWin); SetBorderSize(pWin); dw = (int) w - (int) width; dh = (int) h - (int) height; ResizeChildrenWinSize(pWin, x - oldx, y - oldy, dw, dh); /* let the hardware adjust background and border pixmaps, if any */ (*pScreen->PositionWindow) (pWin, x, y); pFirstChange = MoveWindowInStack(pWin, pSib); if (WasViewable) { pRegion = RegionCreate(NullBox, 1); if (pLayerWin == pWin) anyMarked |= (*pScreen->MarkOverlappedWindows) (pWin, pFirstChange, NULL); else anyMarked |= (*pScreen->MarkOverlappedWindows) (pWin, pLayerWin, NULL); if (pWin->valdata) { pWin->valdata->before.resized = TRUE; pWin->valdata->before.borderVisible = borderVisible; } if (anyMarked) (*pScreen->ValidateTree) (pLayerWin->parent, pFirstChange, VTOther); /* * the entire window is trashed unless bitGravity * recovers portions of it */ RegionCopy(&pWin->valdata->after.exposed, &pWin->clipList); } GravityTranslate(x, y, oldx, oldy, dw, dh, pWin->bitGravity, &nx, &ny); if (WasViewable) { /* avoid the border */ if (HasBorder(pWin)) { int offx, offy, dx, dy; /* kruft to avoid double translates for each gravity */ offx = 0; offy = 0; for (g = 0; g <= StaticGravity; g++) { if (!gravitate[g]) continue; /* align winSize to gravitate[g]. * winSize is in new coordinates, * gravitate[g] is still in old coordinates */ GravityTranslate(x, y, oldx, oldy, dw, dh, g, &nx, &ny); dx = (oldx - nx) - offx; dy = (oldy - ny) - offy; if (dx || dy) { RegionTranslate(&pWin->winSize, dx, dy); offx += dx; offy += dy; } RegionIntersect(gravitate[g], gravitate[g], &pWin->winSize); } /* get winSize back where it belongs */ if (offx || offy) RegionTranslate(&pWin->winSize, -offx, -offy); } /* * add screen bits to the appropriate bucket */ if (oldWinClip) { /* * clip to new clipList */ RegionCopy(pRegion, oldWinClip); RegionTranslate(pRegion, nx - oldx, ny - oldy); RegionIntersect(oldWinClip, pRegion, &pWin->clipList); /* * don't step on any gravity bits which will be copied after this * region. Note -- this assumes that the regions will be copied * in gravity order. */ for (g = pWin->bitGravity + 1; g <= StaticGravity; g++) { if (gravitate[g]) RegionSubtract(oldWinClip, oldWinClip, gravitate[g]); } RegionTranslate(oldWinClip, oldx - nx, oldy - ny); g = pWin->bitGravity; if (!gravitate[g]) gravitate[g] = oldWinClip; else { RegionUnion(gravitate[g], gravitate[g], oldWinClip); RegionDestroy(oldWinClip); } } /* * move the bits on the screen */ destClip = NULL; for (g = 0; g <= StaticGravity; g++) { if (!gravitate[g]) continue; GravityTranslate(x, y, oldx, oldy, dw, dh, g, &nx, &ny); oldpt.x = oldx + (x - nx); oldpt.y = oldy + (y - ny); /* Note that gravitate[g] is *translated* by CopyWindow */ /* only copy the remaining useful bits */ RegionIntersect(gravitate[g], gravitate[g], oldRegion); /* clip to not overwrite already copied areas */ if (destClip) { RegionTranslate(destClip, oldpt.x - x, oldpt.y - y); RegionSubtract(gravitate[g], gravitate[g], destClip); RegionTranslate(destClip, x - oldpt.x, y - oldpt.y); } /* and move those bits */ if (oldpt.x != x || oldpt.y != y #ifdef COMPOSITE || pWin->redirectDraw #endif ) { (*pWin->drawable.pScreen->CopyWindow) (pWin, oldpt, gravitate[g]); } /* remove any overwritten bits from the remaining useful bits */ RegionSubtract(oldRegion, oldRegion, gravitate[g]); /* * recompute exposed regions of child windows */ for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib) { if (pChild->winGravity != g) continue; RegionIntersect(pRegion, &pChild->borderClip, gravitate[g]); TraverseTree(pChild, miRecomputeExposures, (void *) pRegion); } /* * remove the successfully copied regions of the * window from its exposed region */ if (g == pWin->bitGravity) RegionSubtract(&pWin->valdata->after.exposed, &pWin->valdata->after.exposed, gravitate[g]); if (!destClip) destClip = gravitate[g]; else { RegionUnion(destClip, destClip, gravitate[g]); RegionDestroy(gravitate[g]); } } RegionDestroy(oldRegion); RegionDestroy(pRegion); if (destClip) RegionDestroy(destClip); if (anyMarked) (*pScreen->HandleExposures) (pLayerWin->parent); if (anyMarked && pScreen->PostValidateTree) (*pScreen->PostValidateTree) (pLayerWin->parent, pFirstChange, VTOther); } if (pWin->realized) WindowsRestructured(); }
static void cwValidateGC(GCPtr pGC, unsigned long stateChanges, DrawablePtr pDrawable) { GCPtr pBackingGC; cwGCPtr pPriv; DrawablePtr pBackingDrawable; int x_off, y_off; pPriv = (cwGCPtr) getCwGC (pGC); FUNC_PROLOGUE(pGC, pPriv); /* * Must call ValidateGC to ensure pGC->pCompositeClip is valid */ (*pGC->funcs->ValidateGC)(pGC, stateChanges, pDrawable); if (!cwDrawableIsRedirWindow(pDrawable)) { cwDestroyBackingGC(pGC); FUNC_EPILOGUE(pGC, pPriv); return; } else { if (!pPriv->pBackingGC && !cwCreateBackingGC(pGC, pDrawable)) { FUNC_EPILOGUE(pGC, pPriv); return; } } pBackingGC = pPriv->pBackingGC; pBackingDrawable = cwGetBackingDrawable(pDrawable, &x_off, &y_off); pPriv->stateChanges |= stateChanges; /* * Copy the composite clip into the backing GC if either * the drawable clip list has changed or the client has changed * the client clip data */ if (pDrawable->serialNumber != pPriv->serialNumber || (pPriv->stateChanges & (GCClipXOrigin|GCClipYOrigin|GCClipMask))) { ChangeGCVal vals[2]; RegionPtr pCompositeClip; pCompositeClip = RegionCreate(NULL, 0); RegionCopy(pCompositeClip, pGC->pCompositeClip); /* Either the drawable has changed, or the clip list in the drawable has * changed. Copy the new clip list over and set the new translated * offset for it. */ (*pBackingGC->funcs->ChangeClip) (pBackingGC, CT_REGION, (pointer) pCompositeClip, 0); vals[0].val = x_off - pDrawable->x; vals[1].val = y_off - pDrawable->y; ChangeGC(NullClient, pBackingGC, (GCClipXOrigin | GCClipYOrigin), vals); pPriv->serialNumber = pDrawable->serialNumber; /* * Mask off any client clip changes to make sure * the clip list set above remains in effect */ pPriv->stateChanges &= ~(GCClipXOrigin|GCClipYOrigin|GCClipMask); } if (pPriv->stateChanges) { CopyGC(pGC, pBackingGC, pPriv->stateChanges); pPriv->stateChanges = 0; } if ((pGC->patOrg.x + x_off) != pBackingGC->patOrg.x || (pGC->patOrg.y + y_off) != pBackingGC->patOrg.y) { ChangeGCVal vals[2]; vals[0].val = pGC->patOrg.x + x_off; vals[1].val = pGC->patOrg.y + y_off; ChangeGC(NullClient, pBackingGC, (GCTileStipXOrigin | GCTileStipYOrigin), vals); } ValidateGC(pBackingDrawable, pBackingGC); FUNC_EPILOGUE(pGC, pPriv); }
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; } }