/***** * miHandleValidateExposures(pWin) * starting at pWin, draw background in any windows that have exposure * regions, translate the regions, restore any backing store, * and then send any regions still exposed to the client *****/ void miHandleValidateExposures(WindowPtr pWin) { WindowPtr pChild; ValidatePtr val; WindowExposuresProcPtr WindowExposures; pChild = pWin; WindowExposures = pChild->drawable.pScreen->WindowExposures; while (1) { if ((val = pChild->valdata)) { if (RegionNotEmpty(&val->after.borderExposed)) miPaintWindow(pChild, &val->after.borderExposed, PW_BORDER); RegionUninit(&val->after.borderExposed); (*WindowExposures) (pChild, &val->after.exposed, NullRegion); RegionUninit(&val->after.exposed); free(val); pChild->valdata = NULL; if (pChild->firstChild) { pChild = pChild->firstChild; continue; } } while (!pChild->nextSib && (pChild != pWin)) pChild = pChild->parent; if (pChild == pWin) break; pChild = pChild->nextSib; } }
void miWindowExposures(WindowPtr pWin, RegionPtr prgn) { RegionPtr exposures = prgn; if (prgn && !RegionNil(prgn)) { RegionRec expRec; int clientInterested = (pWin->eventMask | wOtherEventMasks(pWin)) & ExposureMask; if (clientInterested && (RegionNumRects(prgn) > RECTLIMIT)) { /* * 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" :-). */ BoxRec box; box = *RegionExtents(prgn); exposures = &expRec; RegionInit(exposures, &box, 1); RegionReset(prgn, &box); /* miPaintWindow doesn't clip, so we have to */ RegionIntersect(prgn, prgn, &pWin->clipList); } miPaintWindow(pWin, prgn, PW_BACKGROUND); if (clientInterested) miSendExposures(pWin, exposures, pWin->drawable.x, pWin->drawable.y); if (exposures == &expRec) RegionUninit(exposures); RegionEmpty(prgn); } }
void miClearToBackground(WindowPtr pWin, int x, int y, int w, int h, Bool generateExposures) { BoxRec box; RegionRec reg; BoxPtr extents; int x1, y1, x2, y2; /* compute everything using ints to avoid overflow */ x1 = pWin->drawable.x + x; y1 = pWin->drawable.y + y; if (w) x2 = x1 + (int) w; else x2 = x1 + (int) pWin->drawable.width - (int) x; if (h) y2 = y1 + h; else y2 = y1 + (int) pWin->drawable.height - (int) y; extents = &pWin->clipList.extents; /* clip the resulting rectangle to the window clipList extents. This * makes sure that the result will fit in a box, given that the * screen is < 32768 on a side. */ if (x1 < extents->x1) x1 = extents->x1; if (x2 > extents->x2) x2 = extents->x2; if (y1 < extents->y1) y1 = extents->y1; if (y2 > extents->y2) y2 = extents->y2; if (x2 <= x1 || y2 <= y1) { x2 = x1 = 0; y2 = y1 = 0; } box.x1 = x1; box.x2 = x2; box.y1 = y1; box.y2 = y2; RegionInit(®, &box, 1); RegionIntersect(®, ®, &pWin->clipList); if (generateExposures) (*pWin->drawable.pScreen->WindowExposures) (pWin, ®, NULL); else if (pWin->backgroundState != None) miPaintWindow(pWin, ®, PW_BACKGROUND); RegionUninit(®); }
void winDoRandRScreenSetSize (ScreenPtr pScreen, CARD16 width, CARD16 height, CARD32 mmWidth, CARD32 mmHeight) { winScreenPriv(pScreen); winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; WindowPtr pRoot = pScreen->root; // Prevent screen updates while we change things around SetRootClip(pScreen, FALSE); /* Update the screen size as requested */ pScreenInfo->dwWidth = width; pScreenInfo->dwHeight = height; /* Reallocate the framebuffer used by the drawing engine */ (*pScreenPriv->pwinFreeFB)(pScreen); if (!(*pScreenPriv->pwinAllocateFB)(pScreen)) { ErrorF ("winDoRandRScreenSetSize - Could not reallocate framebuffer\n"); } pScreen->width = width; pScreen->height = height; pScreen->mmWidth = mmWidth; pScreen->mmHeight = mmHeight; /* Update the screen pixmap to point to the new framebuffer */ winUpdateFBPointer(pScreen, pScreenInfo->pfb); // pScreen->devPrivate == pScreen->GetScreenPixmap(screen) ? // resize the root window //pScreen->ResizeWindow(pRoot, 0, 0, width, height, NULL); // does this emit a ConfigureNotify?? // Restore the ability to update screen, now with new dimensions SetRootClip(pScreen, TRUE); // and arrange for it to be repainted miPaintWindow(pRoot, &pRoot->borderClip, PW_BACKGROUND); /* Indicate that a screen size change took place */ RRScreenSizeNotify(pScreen); }
static void expose_1 (WindowPtr pWin) { WindowPtr pChild; if (!pWin->realized) return; miPaintWindow(pWin, &pWin->borderClip, PW_BACKGROUND); /* FIXME: comments in windowstr.h indicate that borderClip doesn't include subwindow visibility. But I'm not so sure.. so we may be exposing too much.. */ miSendExposures (pWin, &pWin->borderClip, pWin->drawable.x, pWin->drawable.y); for (pChild = pWin->firstChild; pChild != NULL; pChild = pChild->nextSib) expose_1 (pChild); }
RegionPtr miHandleExposures(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC, int srcx, int srcy, int width, int height, int dstx, int dsty, unsigned long plane) { 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; Bool extents; /* avoid work if we can */ if (!pGC->graphicsExposures && (pDstDrawable->type == DRAWABLE_PIXMAP) && ((pSrcDrawable->type == DRAWABLE_PIXMAP) || (((WindowPtr) pSrcDrawable)->backStorage == NULL))) 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->clientClipType == CT_REGION) 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) { /* miPaintWindow doesn't clip, so we have to */ RegionIntersect(&rgnExposed, &rgnExposed, &pWin->clipList); } miPaintWindow((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; } }