summaryrefslogtreecommitdiff
path: root/mi/mibstore.c
diff options
context:
space:
mode:
Diffstat (limited to 'mi/mibstore.c')
-rw-r--r--mi/mibstore.c3902
1 files changed, 35 insertions, 3867 deletions
diff --git a/mi/mibstore.c b/mi/mibstore.c
index e27c681e8..294b2caee 100644
--- a/mi/mibstore.c
+++ b/mi/mibstore.c
@@ -1,3880 +1,48 @@
-/***********************************************************
-
-Copyright 1987, 1998 The Open Group
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that
-the above copyright notice appear in all copies and that both that
-copyright notice and this permission notice appear in supporting
-documentation.
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
-AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of The Open Group shall not be
-used in advertising or otherwise to promote the sale, use or other dealings
-in this Software without prior written authorization from The Open Group.
-
-
-Copyright 1987 by the Regents of the University of California
-
- All Rights Reserved
-
-Permission to use, copy, modify, and distribute this software and its
-documentation for any purpose and without fee is hereby granted, provided
-that the above copyright notice appear in all copies and that both that
-copyright notice and this permission notice appear in supporting
-documentation, and that the name The Open Group not be used in advertising or publicity
-pertaining to distribution of the software without specific, written prior
-permission.
-
-The University of California makes no representations about the suitability
-of this software for any purpose. It is provided "as is" without express or
-implied warranty.
-
-******************************************************************/
-
-
-#define NEED_EVENTS
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <X11/X.h>
-#include <X11/Xmd.h>
-#include <X11/Xproto.h>
-#include "misc.h"
-#include "regionstr.h"
-#include "scrnintstr.h"
-#include "gcstruct.h"
-#include "windowstr.h"
-#include "pixmapstr.h"
-#include <X11/fonts/fontstruct.h>
-#include "dixfontstr.h"
-#include "dixstruct.h" /* For requestingClient */
-#include "mi.h"
-#include "mibstorest.h"
-
-/*
- * When the server fails to allocate a backing store pixmap, if you want
- * it to dynamically retry to allocate backing store on every subsequent
- * graphics op, you can enable BSEAGER; otherwise, backing store will be
- * disabled on the window until it is unmapped and then remapped.
- */
-/* #define BSEAGER */
-
-/*-
- * NOTES ON USAGE:
- *
- * The functions in this file implement a machine-independent backing-store
- * scheme. To use it, the output library must do the following:
- * - Provide a SaveAreas function that takes a destination pixmap, a
- * region of the areas to save (in the pixmap's coordinate system)
- * and the screen origin of the region. It should copy the areas from
- * the screen into the pixmap.
- * - Provide a RestoreAreas function that takes a source pixmap, a region
- * of the areas to restore (in the screen's coordinate system) and the
- * origin of the pixmap on the screen. It should copy the areas from
- * the pixmap into the screen.
- * - Provide a SetClipmaskRgn function that takes a gc and a region
- * and merges the region into any CT_PIXMAP client clip that
- * is specified in the GC. This routine is only needed if
- * miValidateBackingStore will see CT_PIXMAP clip lists; not
- * true for any of the sample servers (which convert the PIXMAP
- * clip lists into CT_REGION clip lists; an expensive but simple
- * to code option).
- * - The function placed in a window's ClearToBackground vector must call
- * pScreen->ClearBackingStore with the window, followed by
- * the window-relative x and y coordinates, followed by the width and
- * height of the area to be cleared, followed by the generateExposures
- * flag. This has been taken care of in miClearToBackground.
- * - Whatever determines GraphicsExpose events for the CopyArea and
- * CopyPlane requests should call pWin->backStorage->ExposeCopy
- * with the source and destination drawables, the GC used, a source-
- * window-relative region of exposed areas, the source and destination
- * coordinates and the bitplane copied, if CopyPlane, or 0, if
- * CopyArea.
- *
- * JUSTIFICATION
- * This is a cross between saving everything and just saving the
- * obscued areas (as in Pike's layers.) This method has the advantage
- * of only doing each output operation once per pixel, visible or
- * invisible, and avoids having to do all the crufty storage
- * management of keeping several separate rectangles. Since the
- * ddx layer ouput primitives are required to draw through clipping
- * rectangles anyway, sending multiple drawing requests for each of
- * several rectangles isn't necessary. (Of course, it could be argued
- * that the ddx routines should just take one rectangle each and
- * get called multiple times, but that would make taking advantage of
- * smart hardware harder, and probably be slower as well.)
- */
-
-#define SETUP_BACKING_TERSE(pGC) \
- miBSGCPtr pGCPrivate = (miBSGCPtr)(pGC)->devPrivates[miBSGCIndex].ptr; \
- GCFuncs *oldFuncs = pGC->funcs;
-
-#define SETUP_BACKING(pDrawable,pGC) \
- miBSWindowPtr pBackingStore = \
- (miBSWindowPtr)((WindowPtr)(pDrawable))->backStorage; \
- DrawablePtr pBackingDrawable = (DrawablePtr) \
- pBackingStore->pBackingPixmap; \
- SETUP_BACKING_TERSE(pGC) \
- GCPtr pBackingGC = pGCPrivate->pBackingGC;
-
-#define PROLOGUE(pGC) { \
- pGC->ops = pGCPrivate->wrapOps;\
- pGC->funcs = pGCPrivate->wrapFuncs; \
- }
-
-#define EPILOGUE(pGC) { \
- pGCPrivate->wrapOps = (pGC)->ops; \
- (pGC)->ops = &miBSGCOps; \
- (pGC)->funcs = oldFuncs; \
- }
-
-static void miCreateBSPixmap(WindowPtr pWin, BoxPtr pExtents);
-static void miDestroyBSPixmap(WindowPtr pWin);
-static void miTileVirtualBS(WindowPtr pWin);
-static void miBSAllocate(WindowPtr pWin), miBSFree(WindowPtr pWin);
-static Bool miBSCreateGCPrivate(GCPtr pGC);
-static void miBSClearBackingRegion(WindowPtr pWin, RegionPtr pRgn);
-
-#define MoreCopy0 ;
-#define MoreCopy2 *dstCopy++ = *srcCopy++; *dstCopy++ = *srcCopy++;
-#define MoreCopy4 MoreCopy2 MoreCopy2
-
-#define copyData(src,dst,n,morecopy) \
-{ \
- short *srcCopy = (short *)(src); \
- short *dstCopy = (short *)(dst); \
- int i; \
- int bsx = pBackingStore->x; \
- int bsy = pBackingStore->y; \
- for (i = n; --i >= 0; ) \
- { \
- *dstCopy++ = *srcCopy++ - bsx; \
- *dstCopy++ = *srcCopy++ - bsy; \
- morecopy \
- } \
-}
-
-#define copyPoints(src,dst,n,mode) \
-if (mode == CoordModeOrigin) \
-{ \
- copyData(src,dst,n,MoreCopy0); \
-} \
-else \
-{ \
- memmove((char *)(dst), (char *)(src), (n) << 2); \
- *((short *)(dst)) -= pBackingStore->x; \
- *((short *)(dst) + 1) -= pBackingStore->y; \
-}
-
-/*
- * wrappers for screen funcs
- */
-
-static int miBSScreenIndex;
-static unsigned long miBSGeneration = 0;
-
-static Bool miBSCloseScreen(int i, ScreenPtr pScreen);
-static void miBSGetImage(DrawablePtr pDrawable, int sx, int sy,
- int w, int h, unsigned int format,
- unsigned long planemask, char *pdstLine);
-static void miBSGetSpans(DrawablePtr pDrawable, int wMax,
- DDXPointPtr ppt, int *pwidth, int nspans,
- char *pdstStart);
-static Bool miBSChangeWindowAttributes(WindowPtr pWin,
- unsigned long mask);
-static Bool miBSCreateGC(GCPtr pGC);
-static Bool miBSDestroyWindow(WindowPtr pWin);
-
-/*
- * backing store screen functions
- */
-
-static void miBSSaveDoomedAreas(WindowPtr pWin, RegionPtr pObscured,
- int dx, int dy);
-static RegionPtr miBSRestoreAreas(WindowPtr pWin, RegionPtr prgnExposed);
-static void miBSExposeCopy(WindowPtr pSrc, DrawablePtr pDst,
- GCPtr pGC, RegionPtr prgnExposed,
- int srcx, int srcy, int dstx, int dsty,
- unsigned long plane);
-static RegionPtr miBSTranslateBackingStore(WindowPtr pWin, int windx,
- int windy, RegionPtr oldClip,
- int oldx, int oldy);
-static RegionPtr miBSClearBackingStore(WindowPtr pWin, int x, int y,
- int w, int h, Bool generateExposures);
-static void miBSDrawGuarantee(WindowPtr pWin, GCPtr pGC,
- int guarantee);
-
-/*
- * wrapper vectors for GC funcs and ops
- */
-
-static int miBSGCIndex;
-
-static void miBSValidateGC(GCPtr pGC, unsigned long stateChanges,
- DrawablePtr pDrawable);
-static void miBSCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst);
-static void miBSDestroyGC(GCPtr pGC);
-static void miBSChangeGC(GCPtr pGC, unsigned long mask);
-static void miBSChangeClip(GCPtr pGC, int type, pointer pvalue, int nrects);
-static void miBSDestroyClip(GCPtr pGC);
-static void miBSCopyClip(GCPtr pgcDst, GCPtr pgcSrc);
-
-static GCFuncs miBSGCFuncs = {
- miBSValidateGC,
- miBSChangeGC,
- miBSCopyGC,
- miBSDestroyGC,
- miBSChangeClip,
- miBSDestroyClip,
- miBSCopyClip,
-};
-
-static void miBSFillSpans(DrawablePtr pDrawable, GCPtr pGC, int nInit,
- DDXPointPtr pptInit, int *pwidthInit,
- int fSorted);
-static void miBSSetSpans(DrawablePtr pDrawable, GCPtr pGC, char *psrc,
- DDXPointPtr ppt, int *pwidth, int nspans,
- int fSorted);
-static void miBSPutImage(DrawablePtr pDrawable, GCPtr pGC, int depth,
- int x, int y, int w, int h, int leftPad,
- int format, char *pBits);
-static RegionPtr miBSCopyArea(DrawablePtr pSrc, DrawablePtr pDst,
- GCPtr pGC, int srcx, int srcy, int w, int h,
- int dstx, int dsty);
-static RegionPtr miBSCopyPlane(DrawablePtr pSrc, DrawablePtr pDst,
- GCPtr pGC, int srcx, int srcy, int w, int h,
- int dstx, int dsty, unsigned long plane);
-static void miBSPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode,
- int npt, xPoint *pptInit);
-static void miBSPolylines(DrawablePtr pDrawable, GCPtr pGC, int mode,
- int npt, DDXPointPtr pptInit);
-static void miBSPolySegment(DrawablePtr pDrawable, GCPtr pGC, int nseg,
- xSegment *pSegs);
-static void miBSPolyRectangle(DrawablePtr pDrawable, GCPtr pGC,
- int nrects, xRectangle *pRects);
-static void miBSPolyArc(DrawablePtr pDrawable, GCPtr pGC, int narcs,
- xArc *parcs);
-static void miBSFillPolygon(DrawablePtr pDrawable, GCPtr pGC,
- int shape, int mode, int count,
- DDXPointPtr pPts);
-static void miBSPolyFillRect(DrawablePtr pDrawable, GCPtr pGC,
- int nrectFill, xRectangle *prectInit);
-static void miBSPolyFillArc(DrawablePtr pDrawable, GCPtr pGC,
- int narcs, xArc *parcs);
-static int miBSPolyText8(DrawablePtr pDrawable, GCPtr pGC,
- int x, int y, int count, char *chars);
-static int miBSPolyText16(DrawablePtr pDrawable, GCPtr pGC,
- int x, int y, int count,
- unsigned short *chars);
-static void miBSImageText8(DrawablePtr pDrawable, GCPtr pGC,
- int x, int y, int count, char *chars);
-static void miBSImageText16(DrawablePtr pDrawable, GCPtr pGC,
- int x, int y, int count,
- unsigned short *chars);
-static void miBSImageGlyphBlt(DrawablePtr pDrawable, GCPtr pGC,
- int x, int y, unsigned int nglyph,
- CharInfoPtr *ppci, pointer pglyphBase);
-static void miBSPolyGlyphBlt(DrawablePtr pDrawable, GCPtr pGC,
- int x, int y, unsigned int nglyph,
- CharInfoPtr *ppci, pointer pglyphBase);
-static void miBSPushPixels(GCPtr pGC, PixmapPtr pBitMap,
- DrawablePtr pDst, int w, int h,
- int x, int y);
-
-static GCOps miBSGCOps = {
- miBSFillSpans, miBSSetSpans, miBSPutImage,
- miBSCopyArea, miBSCopyPlane, miBSPolyPoint,
- miBSPolylines, miBSPolySegment, miBSPolyRectangle,
- miBSPolyArc, miBSFillPolygon, miBSPolyFillRect,
- miBSPolyFillArc, miBSPolyText8, miBSPolyText16,
- miBSImageText8, miBSImageText16, miBSImageGlyphBlt,
- miBSPolyGlyphBlt, miBSPushPixels
-};
-
-#define FUNC_PROLOGUE(pGC, pPriv) \
- ((pGC)->funcs = pPriv->wrapFuncs),\
- ((pGC)->ops = pPriv->wrapOps)
-
-#define FUNC_EPILOGUE(pGC, pPriv) \
- ((pGC)->funcs = &miBSGCFuncs),\
- ((pGC)->ops = &miBSGCOps)
-
-/*
- * every GC in the server is initially wrapped with these
- * "cheap" functions. This allocates no memory and is used
- * to discover GCs used with windows which have backing
- * store enabled
- */
-
-static void miBSCheapValidateGC(GCPtr pGC, unsigned long stateChanges,
- DrawablePtr pDrawable);
-static void miBSCheapCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst);
-static void miBSCheapDestroyGC(GCPtr pGC);
-static void miBSCheapChangeGC(GCPtr pGC, unsigned long mask);
-static void miBSCheapChangeClip(GCPtr pGC, int type, pointer pvalue,
- int nrects);
-static void miBSCheapDestroyClip(GCPtr pGC);
-static void miBSCheapCopyClip(GCPtr pgcDst, GCPtr pgcSrc);
-
-static GCFuncs miBSCheapGCFuncs = {
- miBSCheapValidateGC,
- miBSCheapChangeGC,
- miBSCheapCopyGC,
- miBSCheapDestroyGC,
- miBSCheapChangeClip,
- miBSCheapDestroyClip,
- miBSCheapCopyClip,
-};
-
-#define CHEAP_FUNC_PROLOGUE(pGC) \
- ((pGC)->funcs = (GCFuncs *) (pGC)->devPrivates[miBSGCIndex].ptr)
-
-#define CHEAP_FUNC_EPILOGUE(pGC) \
- ((pGC)->funcs = &miBSCheapGCFuncs)
-
-/*
- * called from device screen initialization proc. Gets a GCPrivateIndex
- * and wraps appropriate per-screen functions. pScreen->BackingStoreFuncs
- * must be previously initialized.
- */
-
-_X_EXPORT void
-miInitializeBackingStore (pScreen)
- ScreenPtr pScreen;
-{
- miBSScreenPtr pScreenPriv;
-
- if (miBSGeneration != serverGeneration)
- {
- miBSScreenIndex = AllocateScreenPrivateIndex ();
- if (miBSScreenIndex < 0)
- return;
- miBSGCIndex = AllocateGCPrivateIndex ();
- miBSGeneration = serverGeneration;
- }
- if (!AllocateGCPrivate(pScreen, miBSGCIndex, 0))
- return;
- pScreenPriv = (miBSScreenPtr) xalloc (sizeof (miBSScreenRec));
- if (!pScreenPriv)
- return;
-
- pScreenPriv->CloseScreen = pScreen->CloseScreen;
- pScreenPriv->GetImage = pScreen->GetImage;
- pScreenPriv->GetSpans = pScreen->GetSpans;
- pScreenPriv->ChangeWindowAttributes = pScreen->ChangeWindowAttributes;
- pScreenPriv->CreateGC = pScreen->CreateGC;
- pScreenPriv->DestroyWindow = pScreen->DestroyWindow;
-
- pScreen->CloseScreen = miBSCloseScreen;
- pScreen->GetImage = miBSGetImage;
- pScreen->GetSpans = miBSGetSpans;
- pScreen->ChangeWindowAttributes = miBSChangeWindowAttributes;
- pScreen->CreateGC = miBSCreateGC;
- pScreen->DestroyWindow = miBSDestroyWindow;
-
- pScreen->SaveDoomedAreas = miBSSaveDoomedAreas;
- pScreen->RestoreAreas = miBSRestoreAreas;
- pScreen->ExposeCopy = miBSExposeCopy;
- pScreen->TranslateBackingStore = miBSTranslateBackingStore;
- pScreen->ClearBackingStore = miBSClearBackingStore;
- pScreen->DrawGuarantee = miBSDrawGuarantee;
-
- pScreen->devPrivates[miBSScreenIndex].ptr = (pointer) pScreenPriv;
-}
-
-/*
- * Screen function wrappers
- */
-
-#define SCREEN_PROLOGUE(pScreen, field)\
- ((pScreen)->field = \
- ((miBSScreenPtr) \
- (pScreen)->devPrivates[miBSScreenIndex].ptr)->field)
-
-#define SCREEN_EPILOGUE(pScreen, field, wrapper)\
- ((pScreen)->field = wrapper)
-
-/*
- * CloseScreen wrapper -- unwrap everything, free the private data
- * and call the wrapped function
- */
-
-static Bool
-miBSCloseScreen (i, pScreen)
- int i;
- ScreenPtr pScreen;
-{
- miBSScreenPtr pScreenPriv;
-
- pScreenPriv = (miBSScreenPtr) pScreen->devPrivates[miBSScreenIndex].ptr;
-
- pScreen->CloseScreen = pScreenPriv->CloseScreen;
- pScreen->GetImage = pScreenPriv->GetImage;
- pScreen->GetSpans = pScreenPriv->GetSpans;
- pScreen->ChangeWindowAttributes = pScreenPriv->ChangeWindowAttributes;
- pScreen->CreateGC = pScreenPriv->CreateGC;
-
- xfree ((pointer) pScreenPriv);
-
- return (*pScreen->CloseScreen) (i, pScreen);
-}
-
-static void miBSFillVirtualBits(DrawablePtr pDrawable, GCPtr pGC,
- RegionPtr pRgn, int x, int y, int state,
- PixUnion pixunion, unsigned long planemask);
-
-static void
-miBSGetImage (pDrawable, sx, sy, w, h, format, planemask, pdstLine)
- DrawablePtr pDrawable;
- int sx, sy, w, h;
- unsigned int format;
- unsigned long planemask;
- char *pdstLine;
-{
- ScreenPtr pScreen = pDrawable->pScreen;
- BoxRec bounds;
- unsigned char depth;
-
- SCREEN_PROLOGUE (pScreen, GetImage);
-
- if (pDrawable->type != DRAWABLE_PIXMAP &&
- ((WindowPtr) pDrawable)->visibility != VisibilityUnobscured)
- {
- PixmapPtr pPixmap;
- miBSWindowPtr pWindowPriv;
- GCPtr pGC = NULL;
- WindowPtr pWin, pSrcWin;
- int xoff, yoff;
- RegionRec Remaining;
- RegionRec Border;
- RegionRec Inside;
- BoxPtr pBox;
- int n;
-
- pWin = (WindowPtr) pDrawable;
- pPixmap = 0;
- depth = pDrawable->depth;
- bounds.x1 = sx + pDrawable->x;
- bounds.y1 = sy + pDrawable->y;
- bounds.x2 = bounds.x1 + w;
- bounds.y2 = bounds.y1 + h;
- REGION_INIT(pScreen, &Remaining, &bounds, 0);
- for (;;)
- {
- bounds.x1 = sx + pDrawable->x - pWin->drawable.x;
- bounds.y1 = sy + pDrawable->y - pWin->drawable.y;
- bounds.x2 = bounds.x1 + w;
- bounds.y2 = bounds.y1 + h;
- if (pWin->viewable && pWin->backStorage &&
- pWin->drawable.depth == depth &&
- (RECT_IN_REGION(pScreen, &(pWindowPriv =
- (miBSWindowPtr) pWin->backStorage)->SavedRegion,
- &bounds) != rgnOUT ||
- RECT_IN_REGION(pScreen, &Remaining,
- REGION_EXTENTS(pScreen, &pWin->borderSize)) != rgnOUT))
- {
- if (!pPixmap)
- {
- XID subWindowMode = IncludeInferiors;
- int x, y;
-
- pPixmap = (*pScreen->CreatePixmap) (pScreen, w, h, depth);
- if (!pPixmap)
- goto punt;
- pGC = GetScratchGC (depth, pScreen);
- if (!pGC)
- {
- (*pScreen->DestroyPixmap) (pPixmap);
- goto punt;
- }
- ChangeGC (pGC, GCSubwindowMode, &subWindowMode);
- ValidateGC ((DrawablePtr)pPixmap, pGC);
- REGION_NULL(pScreen, &Border);
- REGION_NULL(pScreen, &Inside);
- pSrcWin = (WindowPtr) pDrawable;
- x = sx;
- y = sy;
- if (pSrcWin->parent)
- {
- x += pSrcWin->origin.x;
- y += pSrcWin->origin.y;
- pSrcWin = pSrcWin->parent;
- }
- (*pGC->ops->CopyArea) ((DrawablePtr)pSrcWin,
- (DrawablePtr)pPixmap, pGC,
- x, y, w, h,
- 0, 0);
- REGION_SUBTRACT(pScreen, &Remaining, &Remaining,
- &((WindowPtr) pDrawable)->borderClip);
- }
-
- REGION_INTERSECT(pScreen, &Inside, &Remaining, &pWin->winSize);
- REGION_TRANSLATE(pScreen, &Inside,
- -pWin->drawable.x,
- -pWin->drawable.y);
- REGION_INTERSECT(pScreen, &Inside, &Inside,
- &pWindowPriv->SavedRegion);
-
- /* offset of sub-window in GetImage pixmap */
- xoff = pWin->drawable.x - pDrawable->x - sx;
- yoff = pWin->drawable.y - pDrawable->y - sy;
-
- if (REGION_NUM_RECTS(&Inside) > 0)
- {
- switch (pWindowPriv->status)
- {
- case StatusContents:
- pBox = REGION_RECTS(&Inside);
- for (n = REGION_NUM_RECTS(&Inside); --n >= 0;)
- {
- (*pGC->ops->CopyArea) (
- (DrawablePtr)pWindowPriv->pBackingPixmap,
- (DrawablePtr)pPixmap, pGC,
- pBox->x1 - pWindowPriv->x,
- pBox->y1 - pWindowPriv->y,
- pBox->x2 - pBox->x1,
- pBox->y2 - pBox->y1,
- pBox->x1 + xoff,
- pBox->y1 + yoff);
- ++pBox;
- }
- break;
- case StatusVirtual:
- case StatusVDirty:
- if (pWindowPriv->backgroundState == BackgroundPixmap ||
- pWindowPriv->backgroundState == BackgroundPixel)
- miBSFillVirtualBits ((DrawablePtr) pPixmap, pGC, &Inside,
- xoff, yoff,
- (int) pWindowPriv->backgroundState,
- pWindowPriv->background, ~0L);
- break;
- }
- }
- REGION_SUBTRACT(pScreen, &Border, &pWin->borderSize,
- &pWin->winSize);
- REGION_INTERSECT(pScreen, &Border, &Border, &Remaining);
- if (REGION_NUM_RECTS(&Border) > 0)
- {
- REGION_TRANSLATE(pScreen, &Border, -pWin->drawable.x,
- -pWin->drawable.y);
- miBSFillVirtualBits ((DrawablePtr) pPixmap, pGC, &Border,
- xoff, yoff,
- pWin->borderIsPixel ? (int)BackgroundPixel : (int)BackgroundPixmap,
- pWin->border, ~0L);
- }
- }
-
- if (pWin->viewable && pWin->firstChild)
- pWin = pWin->firstChild;
- else
- {
- while (!pWin->nextSib && pWin != (WindowPtr) pDrawable)
- pWin = pWin->parent;
- if (pWin == (WindowPtr) pDrawable)
- break;
- pWin = pWin->nextSib;
- }
- }
-
- REGION_UNINIT(pScreen, &Remaining);
-
- if (pPixmap)
- {
- REGION_UNINIT(pScreen, &Border);
- REGION_UNINIT(pScreen, &Inside);
- (*pScreen->GetImage) ((DrawablePtr) pPixmap,
- 0, 0, w, h, format, planemask, pdstLine);
- (*pScreen->DestroyPixmap) (pPixmap);
- FreeScratchGC (pGC);
- }
- else
- {
- goto punt;
- }
- }
- else
- {
-punt: ;
- (*pScreen->GetImage) (pDrawable, sx, sy, w, h,
- format, planemask, pdstLine);
- }
-
- SCREEN_EPILOGUE (pScreen, GetImage, miBSGetImage);
-}
-
-static void
-miBSGetSpans (pDrawable, wMax, ppt, pwidth, nspans, pdstStart)
- DrawablePtr pDrawable;
- int wMax;
- DDXPointPtr ppt;
- int *pwidth;
- int nspans;
- char *pdstStart;
-{
- ScreenPtr pScreen = pDrawable->pScreen;
- BoxRec bounds;
- int i;
- WindowPtr pWin;
- int dx, dy;
-
- SCREEN_PROLOGUE (pScreen, GetSpans);
-
- if (pDrawable->type != DRAWABLE_PIXMAP && ((WindowPtr) pDrawable)->backStorage)
- {
- PixmapPtr pPixmap;
- miBSWindowPtr pWindowPriv;
- GCPtr pGC;
-
- pWin = (WindowPtr) pDrawable;
- pWindowPriv = (miBSWindowPtr) pWin->backStorage;
- pPixmap = pWindowPriv->pBackingPixmap;
-
- bounds.x1 = ppt->x;
- bounds.y1 = ppt->y;
- bounds.x2 = bounds.x1 + *pwidth;
- bounds.y2 = ppt->y;
- for (i = 0; i < nspans; i++)
- {
- if (ppt[i].x < bounds.x1)
- bounds.x1 = ppt[i].x;
- if (ppt[i].x + pwidth[i] > bounds.x2)
- bounds.x2 = ppt[i].x + pwidth[i];
- if (ppt[i].y < bounds.y1)
- bounds.y1 = ppt[i].y;
- else if (ppt[i].y > bounds.y2)
- bounds.y2 = ppt[i].y;
- }
-
- switch (RECT_IN_REGION(pScreen, &pWindowPriv->SavedRegion, &bounds))
- {
- case rgnPART:
- if (!pPixmap)
- {
- miCreateBSPixmap (pWin, NullBox);
- if (!(pPixmap = pWindowPriv->pBackingPixmap))
- break;
- }
- pWindowPriv->status = StatusNoPixmap;
- pGC = GetScratchGC(pPixmap->drawable.depth,
- pPixmap->drawable.pScreen);
- if (pGC)
- {
- ValidateGC ((DrawablePtr) pPixmap, pGC);
- (*pGC->ops->CopyArea)
- (pDrawable, (DrawablePtr) pPixmap, pGC,
- bounds.x1, bounds.y1,
- bounds.x2 - bounds.x1, bounds.y2 - bounds.y1,
- bounds.x1 + pPixmap->drawable.x - pWin->drawable.x -
- pWindowPriv->x,
- bounds.y1 + pPixmap->drawable.y - pWin->drawable.y -
- pWindowPriv->y);
- FreeScratchGC(pGC);
- }
- pWindowPriv->status = StatusContents;
- /* fall through */
- case rgnIN:
- if (!pPixmap)
- {
- miCreateBSPixmap (pWin, NullBox);
- if (!(pPixmap = pWindowPriv->pBackingPixmap))
- break;
- }
- dx = pPixmap->drawable.x - pWin->drawable.x - pWindowPriv->x;
- dy = pPixmap->drawable.y - pWin->drawable.y - pWindowPriv->y;
- for (i = 0; i < nspans; i++)
- {
- ppt[i].x += dx;
- ppt[i].y += dy;
- }
- (*pScreen->GetSpans) ((DrawablePtr) pPixmap, wMax, ppt, pwidth,
- nspans, pdstStart);
- break;
- case rgnOUT:
- (*pScreen->GetSpans) (pDrawable, wMax, ppt, pwidth, nspans,
- pdstStart);
- break;
- }
- }
- else
- {
- (*pScreen->GetSpans) (pDrawable, wMax, ppt, pwidth, nspans, pdstStart);
- }
-
- SCREEN_EPILOGUE (pScreen, GetSpans, miBSGetSpans);
-}
-
-static Bool
-miBSChangeWindowAttributes (pWin, mask)
- WindowPtr pWin;
- unsigned long mask;
-{
- ScreenPtr pScreen;
- Bool ret;
-
- pScreen = pWin->drawable.pScreen;
-
- SCREEN_PROLOGUE (pScreen, ChangeWindowAttributes);
-
- ret = (*pScreen->ChangeWindowAttributes) (pWin, mask);
-
- if (ret && (mask & CWBackingStore))
- {
- if (pWin->backingStore != NotUseful || pWin->DIXsaveUnder)
- miBSAllocate (pWin);
- else
- miBSFree (pWin);
- }
-
- SCREEN_EPILOGUE (pScreen, ChangeWindowAttributes, miBSChangeWindowAttributes);
-
- return ret;
-}
-
-/*
- * GC Create wrapper. Set up the cheap GC func wrappers to track
- * GC validation on BackingStore windows
- */
-
-static Bool
-miBSCreateGC (pGC)
- GCPtr pGC;
-{
- ScreenPtr pScreen = pGC->pScreen;
- Bool ret;
-
- SCREEN_PROLOGUE (pScreen, CreateGC);
-
- if ( (ret = (*pScreen->CreateGC) (pGC)) )
- {
- pGC->devPrivates[miBSGCIndex].ptr = (pointer) pGC->funcs;
- pGC->funcs = &miBSCheapGCFuncs;
- }
-
- SCREEN_EPILOGUE (pScreen, CreateGC, miBSCreateGC);
-
- return ret;
-}
-
-static Bool
-miBSDestroyWindow (pWin)
- WindowPtr pWin;
-{
- ScreenPtr pScreen = pWin->drawable.pScreen;
- Bool ret;
-
- SCREEN_PROLOGUE (pScreen, DestroyWindow);
-
- ret = (*pScreen->DestroyWindow) (pWin);
-
- miBSFree (pWin);
-
- SCREEN_EPILOGUE (pScreen, DestroyWindow, miBSDestroyWindow);
-
- return ret;
-}
-
-/*
- * cheap GC func wrappers. Simply track validation on windows
- * with backing store to enable the real func/op wrappers
- */
-
-static void
-miBSCheapValidateGC (pGC, stateChanges, pDrawable)
- GCPtr pGC;
- unsigned long stateChanges;
- DrawablePtr pDrawable;
-{
- CHEAP_FUNC_PROLOGUE (pGC);
-
- if (pDrawable->type != DRAWABLE_PIXMAP &&
- ((WindowPtr) pDrawable)->backStorage != NULL &&
- miBSCreateGCPrivate (pGC))
- {
- (*pGC->funcs->ValidateGC) (pGC, stateChanges, pDrawable);
- }
- else
- {
- (*pGC->funcs->ValidateGC) (pGC, stateChanges, pDrawable);
-
- /* rewrap funcs as Validate may have changed them */
- pGC->devPrivates[miBSGCIndex].ptr = (pointer) pGC->funcs;
-
- CHEAP_FUNC_EPILOGUE (pGC);
- }
-}
-
-static void
-miBSCheapChangeGC (pGC, mask)
- GCPtr pGC;
- unsigned long mask;
-{
- CHEAP_FUNC_PROLOGUE (pGC);
-
- (*pGC->funcs->ChangeGC) (pGC, mask);
-
- CHEAP_FUNC_EPILOGUE (pGC);
-}
-
-static void
-miBSCheapCopyGC (pGCSrc, mask, pGCDst)
- GCPtr pGCSrc, pGCDst;
- unsigned long mask;
-{
- CHEAP_FUNC_PROLOGUE (pGCDst);
-
- (*pGCDst->funcs->CopyGC) (pGCSrc, mask, pGCDst);
-
- CHEAP_FUNC_EPILOGUE (pGCDst);
-}
-
-static void
-miBSCheapDestroyGC (pGC)
- GCPtr pGC;
-{
- CHEAP_FUNC_PROLOGUE (pGC);
-
- (*pGC->funcs->DestroyGC) (pGC);
-
- /* leave it unwrapped */
-}
-
-static void
-miBSCheapChangeClip (pGC, type, pvalue, nrects)
- GCPtr pGC;
- int type;
- pointer pvalue;
- int nrects;
-{
- CHEAP_FUNC_PROLOGUE (pGC);
-
- (*pGC->funcs->ChangeClip) (pGC, type, pvalue, nrects);
-
- CHEAP_FUNC_EPILOGUE (pGC);
-}
-
-static void
-miBSCheapCopyClip(pgcDst, pgcSrc)
- GCPtr pgcDst, pgcSrc;
-{
- CHEAP_FUNC_PROLOGUE (pgcDst);
-
- (* pgcDst->funcs->CopyClip)(pgcDst, pgcSrc);
-
- CHEAP_FUNC_EPILOGUE (pgcDst);
-}
-
-static void
-miBSCheapDestroyClip(pGC)
- GCPtr pGC;
-{
- CHEAP_FUNC_PROLOGUE (pGC);
-
- (* pGC->funcs->DestroyClip)(pGC);
-
- CHEAP_FUNC_EPILOGUE (pGC);
-}
-
-/*
- * create the full func/op wrappers for a GC
- */
-
-static Bool
-miBSCreateGCPrivate (pGC)
- GCPtr pGC;
-{
- miBSGCRec *pPriv;
-
- pPriv = (miBSGCRec *) xalloc (sizeof (miBSGCRec));
- if (!pPriv)
- return FALSE;
- pPriv->pBackingGC = NULL;
- pPriv->guarantee = GuaranteeNothing;
- pPriv->serialNumber = 0;
- pPriv->stateChanges = (1 << (GCLastBit + 1)) - 1;
- pPriv->wrapOps = pGC->ops;
- pPriv->wrapFuncs = pGC->funcs;
- pGC->funcs = &miBSGCFuncs;
- pGC->ops = &miBSGCOps;
- pGC->devPrivates[miBSGCIndex].ptr = (pointer) pPriv;
- return TRUE;
-}
-
-static void
-miBSDestroyGCPrivate (GCPtr pGC)
-{
- miBSGCRec *pPriv;
-
- pPriv = (miBSGCRec *) pGC->devPrivates[miBSGCIndex].ptr;
- if (pPriv)
- {
- pGC->devPrivates[miBSGCIndex].ptr = (pointer) pPriv->wrapFuncs;
- pGC->funcs = &miBSCheapGCFuncs;
- pGC->ops = pPriv->wrapOps;
- if (pPriv->pBackingGC)
- FreeGC (pPriv->pBackingGC, (GContext) 0);
- xfree ((pointer) pPriv);
- }
-}
-
-/*
- * GC ops -- wrap each GC operation with our own function
- */
-
-/*-
- *-----------------------------------------------------------------------
- * miBSFillSpans --
- * Perform a FillSpans, routing output to backing-store as needed.
- *
- * Results:
- * None.
- *
- * Side Effects:
- *
- *-----------------------------------------------------------------------
- */
-static void
-miBSFillSpans(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
- DrawablePtr pDrawable;
- GCPtr pGC;
- int nInit; /* number of spans to fill */
- DDXPointPtr pptInit; /* pointer to list of start points */
- int *pwidthInit; /* pointer to list of n widths */
- int fSorted;
-{
- DDXPointPtr pptCopy, pptReset;
- int *pwidthCopy;
- SETUP_BACKING (pDrawable, pGC);
-
- PROLOGUE(pGC);
-
- pptCopy = (DDXPointPtr)ALLOCATE_LOCAL(nInit*sizeof(DDXPointRec));
- pwidthCopy=(int *)ALLOCATE_LOCAL(nInit*sizeof(int));
- if (pptCopy && pwidthCopy)
- {
- copyData(pptInit, pptCopy, nInit, MoreCopy0);
- memmove((char *)pwidthCopy,(char *)pwidthInit,nInit*sizeof(int));
-
- (* pGC->ops->FillSpans)(pDrawable, pGC, nInit, pptInit,
- pwidthInit, fSorted);
- if (pGC->miTranslate)
- {
- int dx, dy;
- int nReset;
-
- pptReset = pptCopy;
- dx = pDrawable->x - pBackingDrawable->x;
- dy = pDrawable->y - pBackingDrawable->y;
- nReset = nInit;
- while (nReset--)
- {
- pptReset->x -= dx;
- pptReset->y -= dy;
- ++pptReset;
- }
- }
- (* pBackingGC->ops->FillSpans)(pBackingDrawable,
- pBackingGC, nInit, pptCopy, pwidthCopy,
- fSorted);
- }
- if (pwidthCopy) DEALLOCATE_LOCAL(pwidthCopy);
- if (pptCopy) DEALLOCATE_LOCAL(pptCopy);
-
- EPILOGUE (pGC);
-}
-
-/*-
- *-----------------------------------------------------------------------
- * miBSSetSpans --
- * Perform a SetSpans, routing output to backing-store as needed.
- *
- * Results:
- * None.
- *
- * Side Effects:
- *
- *-----------------------------------------------------------------------
- */
-static void
-miBSSetSpans(pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted)
- DrawablePtr pDrawable;
- GCPtr pGC;
- char *psrc;
- DDXPointPtr ppt;
- int *pwidth;
- int nspans;
- int fSorted;
-{
- DDXPointPtr pptCopy, pptReset;
- int *pwidthCopy;
- SETUP_BACKING (pDrawable, pGC);
-
- PROLOGUE(pGC);
-
- pptCopy = (DDXPointPtr)ALLOCATE_LOCAL(nspans*sizeof(DDXPointRec));
- pwidthCopy=(int *)ALLOCATE_LOCAL(nspans*sizeof(int));
- if (pptCopy && pwidthCopy)
- {
- copyData(ppt, pptCopy, nspans, MoreCopy0);
- memmove((char *)pwidthCopy,(char *)pwidth,nspans*sizeof(int));
-
- (* pGC->ops->SetSpans)(pDrawable, pGC, psrc, ppt, pwidth,
- nspans, fSorted);
- if (pGC->miTranslate)
- {
- int dx, dy;
- int nReset;
-
- pptReset = pptCopy;
- dx = pDrawable->x - pBackingDrawable->x;
- dy = pDrawable->y - pBackingDrawable->y;
- nReset = nspans;
- while (nReset--)
- {
- pptReset->x -= dx;
- pptReset->y -= dy;
- ++pptReset;
- }
- }
- (* pBackingGC->ops->SetSpans)(pBackingDrawable, pBackingGC,
- psrc, pptCopy, pwidthCopy, nspans, fSorted);
- }
- if (pwidthCopy) DEALLOCATE_LOCAL(pwidthCopy);
- if (pptCopy) DEALLOCATE_LOCAL(pptCopy);
-
- EPILOGUE (pGC);
-}
-
-/*-
- *-----------------------------------------------------------------------
- * miBSPutImage --
- * Perform a PutImage, routing output to backing-store as needed.
- *
- * Results:
- * None.
- *
- * Side Effects:
- *
- *-----------------------------------------------------------------------
- */
-static void
-miBSPutImage(pDrawable, pGC, depth, x, y, w, h, leftPad, format, pBits)
- DrawablePtr pDrawable;
- GCPtr pGC;
- int depth;
- int x;
- int y;
- int w;
- int h;
- int leftPad;
- int format;
- char *pBits;
-{
- SETUP_BACKING (pDrawable, pGC);
-
- PROLOGUE(pGC);
-
- (*pGC->ops->PutImage)(pDrawable, pGC,
- depth, x, y, w, h, leftPad, format, pBits);
- (*pBackingGC->ops->PutImage)(pBackingDrawable, pBackingGC,
- depth, x - pBackingStore->x, y - pBackingStore->y,
- w, h, leftPad, format, pBits);
-
- EPILOGUE (pGC);
-}
-
-typedef RegionPtr (* CopyAreaProcPtr)(DrawablePtr, DrawablePtr, GCPtr,
- int, int, int, int, int, int);
-typedef RegionPtr (* CopyPlaneProcPtr)(DrawablePtr, DrawablePtr, GCPtr,
- int, int, int, int, int, int,
- unsigned long bitPlane);
-/*-
- *-----------------------------------------------------------------------
- * miBSDoCopy --
- * Perform a CopyArea or CopyPlane within a window that has backing
- * store enabled.
- *
- * Results:
- * TRUE if the copy was performed or FALSE if a regular one should
- * be done.
- *
- * Side Effects:
- * Things are copied (no s***!)
- *
- * Notes:
- * The idea here is to form two regions that cover the source box.
- * One contains the exposed rectangles while the other contains
- * the obscured ones. An array of <box, drawable> pairs is then
- * formed where the <box> indicates the area to be copied and the
- * <drawable> indicates from where it is to be copied (exposed regions
- * come from the screen while obscured ones come from the backing
- * pixmap). The array 'sequence' is then filled with the indices of
- * the pairs in the order in which they should be copied to prevent
- * things from getting screwed up. A call is also made through the
- * backingGC to take care of any copying into the backing pixmap.
- *
- *-----------------------------------------------------------------------
- */
-static Bool
-miBSDoCopy(
- WindowPtr pWin, /* Window being scrolled */
- GCPtr pGC, /* GC we're called through */
- int srcx, /* X of source rectangle */
- int srcy, /* Y of source rectangle */
- int w, /* Width of source rectangle */
- int h, /* Height of source rectangle */
- int dstx, /* X of destination rectangle */
- int dsty, /* Y of destination rectangle */
- unsigned long plane, /* Plane to copy (0 for CopyArea) */
- CopyPlaneProcPtr copyProc, /* Procedure to call to perform the copy */
- RegionPtr *ppRgn) /* resultant Graphics Expose region */
-{
- RegionPtr pRgnExp; /* Exposed region */
- RegionPtr pRgnObs; /* Obscured region */
- BoxRec box; /* Source box (screen coord) */
- struct BoxDraw {
- BoxPtr pBox; /* Source box */
- enum {
- win, pix
- } source; /* Place from which to copy */
- } *boxes; /* Array of box/drawable pairs covering
- * source box. */
- int *sequence; /* Sequence of boxes to move */
- int i, j, k, l, y;
- BoxPtr pBox;
- int dx, dy, nrects;
- Bool graphicsExposures;
- CopyPlaneProcPtr pixCopyProc;
- int numRectsExp, numRectsObs;
- BoxPtr pBoxExp, pBoxObs;
-
- SETUP_BACKING (pWin, pGC);
- (void)oldFuncs;
-
- /*
- * Create a region of exposed boxes in pRgnExp.
- */
- box.x1 = srcx + pWin->drawable.x;
- box.x2 = box.x1 + w;
- box.y1 = srcy + pWin->drawable.y;
- box.y2 = box.y1 + h;
-
- pRgnExp = REGION_CREATE(pGC->pScreen, &box, 1);
- REGION_INTERSECT(pGC->pScreen, pRgnExp, pRgnExp, &pWin->clipList);
- pRgnObs = REGION_CREATE(pGC->pScreen, NULL, 1);
- REGION_INVERSE( pGC->pScreen, pRgnObs, pRgnExp, &box);
-
- /*
- * Translate regions into window coordinates for proper calls
- * to the copyProc, then make sure none of the obscured region sticks
- * into invalid areas of the backing pixmap.
- */
- REGION_TRANSLATE(pGC->pScreen, pRgnExp,
- -pWin->drawable.x,
- -pWin->drawable.y);
- REGION_TRANSLATE(pGC->pScreen, pRgnObs,
- -pWin->drawable.x,
- -pWin->drawable.y);
- REGION_INTERSECT(pGC->pScreen, pRgnObs, pRgnObs, &pBackingStore->SavedRegion);
-
- /*
- * If the obscured region is empty, there's no point being fancy.
- */
- if (!REGION_NOTEMPTY(pGC->pScreen, pRgnObs))
- {
- REGION_DESTROY(pGC->pScreen, pRgnExp);
- REGION_DESTROY(pGC->pScreen, pRgnObs);
-
- return (FALSE);
- }
-
- numRectsExp = REGION_NUM_RECTS(pRgnExp);
- pBoxExp = REGION_RECTS(pRgnExp);
- pBoxObs = REGION_RECTS(pRgnObs);
- numRectsObs = REGION_NUM_RECTS(pRgnObs);
- nrects = numRectsExp + numRectsObs;
-
- boxes = (struct BoxDraw *)ALLOCATE_LOCAL(nrects * sizeof(struct BoxDraw));
- sequence = (int *) ALLOCATE_LOCAL(nrects * sizeof(int));
- *ppRgn = NULL;
-
- if (!boxes || !sequence)
- {
- if (sequence) DEALLOCATE_LOCAL(sequence);
- if (boxes) DEALLOCATE_LOCAL(boxes);
- REGION_DESTROY(pGC->pScreen, pRgnExp);
- REGION_DESTROY(pGC->pScreen, pRgnObs);
-
- return(TRUE);
- }
-
- /*
- * Order the boxes in the two regions so we know from which drawable
- * to copy which box, storing the result in the boxes array
- */
- for (i = 0, j = 0, k = 0;
- (i < numRectsExp) && (j < numRectsObs);
- k++)
- {
- if (pBoxExp[i].y1 < pBoxObs[j].y1)
- {
- boxes[k].pBox = &pBoxExp[i];
- boxes[k].source = win;
- i++;
- }
- else if ((pBoxObs[j].y1 < pBoxExp[i].y1) ||
- (pBoxObs[j].x1 < pBoxExp[i].x1))
- {
- boxes[k].pBox = &pBoxObs[j];
- boxes[k].source = pix;
- j++;
- }
- else
- {
- boxes[k].pBox = &pBoxExp[i];
- boxes[k].source = win;
- i++;
- }
- }
-
- /*
- * Catch any leftover boxes from either region (note that only
- * one can have leftover boxes...)
- */
- if (i != numRectsExp)
- {
- do
- {
- boxes[k].pBox = &pBoxExp[i];
- boxes[k].source = win;
- i++;
- k++;
- } while (i < numRectsExp);
-
- }
- else
- {
- do
- {
- boxes[k].pBox = &pBoxObs[j];
- boxes[k].source = pix;
- j++;
- k++;
- } while (j < numRectsObs);
- }
-
- if (dsty <= srcy)
- {
- /*
- * Scroll up or vertically stationary, so vertical order is ok.
- */
- if (dstx <= srcx)
- {
- /*
- * Scroll left or horizontally stationary, so horizontal order
- * is ok as well.
- */
- for (i = 0; i < nrects; i++)
- {
- sequence[i] = i;
- }
- }
- else
- {
- /*
- * Scroll right. Need to reverse the rectangles within each
- * band.
- */
- for (i = 0, j = 1, k = 0;
- i < nrects;
- j = i + 1, k = i)
- {
- y = boxes[i].pBox->y1;
- while ((j < nrects) && (boxes[j].pBox->y1 == y))
- {
- j++;
- }
- for (j--; j >= k; j--, i++)
- {
- sequence[i] = j;
- }
- }
- }
- }
- else
- {
- /*
- * Scroll down. Must reverse vertical banding, at least.
- */
- if (dstx < srcx)
- {
- /*
- * Scroll left. Horizontal order is ok.
- */
- for (i = nrects - 1, j = i - 1, k = i, l = 0;
- i >= 0;
- j = i - 1, k = i)
- {
- /*
- * Find extent of current horizontal band, then reverse
- * the order of the whole band.
- */
- y = boxes[i].pBox->y1;
- while ((j >= 0) && (boxes[j].pBox->y1 == y))
- {
- j--;
- }
- for (j++; j <= k; j++, i--, l++)
- {
- sequence[l] = j;
- }
- }
- }
- else
- {
- /*
- * Scroll right or horizontal stationary.
- * Reverse horizontal order as well (if stationary, horizontal
- * order can be swapped without penalty and this is faster
- * to compute).
- */
- for (i = 0, j = nrects - 1; i < nrects; i++, j--)
- {
- sequence[i] = j;
- }
- }
- }
-
- /*
- * XXX: To avoid getting multiple NoExpose events from this operation,
- * we turn OFF graphicsExposures in the gc and deal with any uncopied
- * areas later, if there's something not in backing-store.
- */
-
- graphicsExposures = pGC->graphicsExposures;
- pGC->graphicsExposures = FALSE;
-
- dx = dstx - srcx;
- dy = dsty - srcy;
-
- /*
- * Figure out which copy procedure to use from the backing GC. Note we
- * must do this because some implementations (sun's, e.g.) have
- * pBackingGC a fake GC with the real one below it, thus the devPriv for
- * pBackingGC won't be what the output library expects.
- */
- if (plane != 0)
- {
- pixCopyProc = pBackingGC->ops->CopyPlane;
- }
- else
- {
- pixCopyProc = (CopyPlaneProcPtr)pBackingGC->ops->CopyArea;
- }
-
- for (i = 0; i < nrects; i++)
- {
- pBox = boxes[sequence[i]].pBox;
-
- /*
- * If we're copying from the pixmap, we need to place its contents
- * onto the screen before scrolling the pixmap itself. If we're copying
- * from the window, we need to copy its contents into the pixmap before
- * we scroll the window itself.
- */
- if (boxes[sequence[i]].source == pix)
- {
- (void) (* copyProc) (pBackingDrawable, &(pWin->drawable), pGC,
- pBox->x1 - pBackingStore->x,
- pBox->y1 - pBackingStore->y,
- pBox->x2 - pBox->x1, pBox->y2 - pBox->y1,
- pBox->x1 + dx, pBox->y1 + dy, plane);
- (void) (* pixCopyProc) (pBackingDrawable, pBackingDrawable, pBackingGC,
- pBox->x1 - pBackingStore->x,
- pBox->y1 - pBackingStore->y,
- pBox->x2 - pBox->x1, pBox->y2 - pBox->y1,
- pBox->x1 + dx - pBackingStore->x,
- pBox->y1 + dy - pBackingStore->y, plane);
- }
- else
- {
- (void) (* pixCopyProc) (&(pWin->drawable), pBackingDrawable, pBackingGC,
- pBox->x1, pBox->y1,
- pBox->x2 - pBox->x1, pBox->y2 - pBox->y1,
- pBox->x1 + dx - pBackingStore->x,
- pBox->y1 + dy - pBackingStore->y, plane);
- (void) (* copyProc) (&(pWin->drawable), &(pWin->drawable), pGC,
- pBox->x1, pBox->y1,
- pBox->x2 - pBox->x1, pBox->y2 - pBox->y1,
- pBox->x1 + dx, pBox->y1 + dy, plane);
- }
- }
- DEALLOCATE_LOCAL(sequence);
- DEALLOCATE_LOCAL(boxes);
-
- pGC->graphicsExposures = graphicsExposures;
- /*
- * Form union of rgnExp and rgnObs and see if covers entire area
- * to be copied. Store the resultant region for miBSCopyArea
- * to return to dispatch which will send the appropriate expose
- * events.
- */
- REGION_UNION(pGC->pScreen, pRgnExp, pRgnExp, pRgnObs);
- box.x1 = srcx;
- box.x2 = srcx + w;
- box.y1 = srcy;
- box.y2 = srcy + h;
- if (RECT_IN_REGION(pGC->pScreen, pRgnExp, &box) == rgnIN)
- {
- REGION_EMPTY(pGC->pScreen, pRgnExp);
- }
- else
- {
- REGION_INVERSE( pGC->pScreen, pRgnExp, pRgnExp, &box);
- REGION_TRANSLATE( pGC->pScreen, pRgnExp,
- dx + pWin->drawable.x,
- dy + pWin->drawable.y);
- REGION_INTERSECT( pGC->pScreen, pRgnObs, pRgnExp, &pWin->clipList);
- (*pWin->drawable.pScreen->PaintWindowBackground) (pWin,
- pRgnObs, PW_BACKGROUND);
- REGION_TRANSLATE( pGC->pScreen, pRgnExp,
- -pWin->drawable.x,
- -pWin->drawable.y);
- miBSClearBackingRegion (pWin, pRgnExp);
- }
- if (graphicsExposures)
- *ppRgn = pRgnExp;
- else
- REGION_DESTROY(pGC->pScreen, pRgnExp);
- REGION_DESTROY(pGC->pScreen, pRgnObs);
-
- return (TRUE);
-}
-
-/*-
- *-----------------------------------------------------------------------
- * miBSCopyArea --
- * Perform a CopyArea from the source to the destination, extracting
- * from the source's backing-store and storing into the destination's
- * backing-store without messing anything up. If the source and
- * destination are different, there's not too much to worry about:
- * we can just issue several calls to the regular CopyArea function.
- *
- * Results:
- * None.
- *
- * Side Effects:
- *
- *-----------------------------------------------------------------------
- */
-static RegionPtr
-miBSCopyArea (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty)
- DrawablePtr pSrc;
- DrawablePtr pDst;
- GCPtr pGC;
- int srcx;
- int srcy;
- int w;
- int h;
- int dstx;
- int dsty;
-{
- BoxPtr pExtents;
- long dx, dy;
- int bsrcx, bsrcy, bw, bh, bdstx, bdsty;
- RegionPtr pixExposed = 0, winExposed = 0;
-
- SETUP_BACKING(pDst, pGC);
-
- PROLOGUE(pGC);
-
- if ((pSrc != pDst) ||
- (!miBSDoCopy((WindowPtr)pSrc, pGC, srcx, srcy, w, h, dstx, dsty,
- (unsigned long) 0, (CopyPlaneProcPtr)pGC->ops->CopyArea,
- &winExposed)))
- {
- /*
- * always copy to the backing store first, miBSDoCopy
- * returns FALSE if the *source* region is disjoint
- * from the backing store saved region. So, copying
- * *to* the backing store is always safe
- */
- if (pGC->clientClipType != CT_PIXMAP)
- {
- /*
- * adjust srcx, srcy, w, h, dstx, dsty to be clipped to
- * the backing store. An unnecessary optimisation,
- * but a useful one when GetSpans is slow.
- */
- pExtents = REGION_EXTENTS(pDst->pScreen,
- (RegionPtr)pBackingGC->clientClip);
- bsrcx = srcx;
- bsrcy = srcy;
- bw = w;
- bh = h;
- bdstx = dstx;
- bdsty = dsty;
- dx = pExtents->x1 - bdstx;
- if (dx > 0)
- {
- bsrcx += dx;
- bdstx += dx;
- bw -= dx;
- }
- dy = pExtents->y1 - bdsty;
- if (dy > 0)
- {
- bsrcy += dy;
- bdsty += dy;
- bh -= dy;
- }
- dx = (bdstx + bw) - pExtents->x2;
- if (dx > 0)
- bw -= dx;
- dy = (bdsty + bh) - pExtents->y2;
- if (dy > 0)
- bh -= dy;
- if (bw > 0 && bh > 0)
- pixExposed = (* pBackingGC->ops->CopyArea) (pSrc,
- pBackingDrawable, pBackingGC,
- bsrcx, bsrcy, bw, bh, bdstx - pBackingStore->x,
- bdsty - pBackingStore->y);
- }
- else
- pixExposed = (* pBackingGC->ops->CopyArea) (pSrc,
- pBackingDrawable, pBackingGC,
- srcx, srcy, w, h,
- dstx - pBackingStore->x, dsty - pBackingStore->y);
-
- winExposed = (* pGC->ops->CopyArea) (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty);
- }
-
- /*
- * compute the composite graphics exposure region
- */
- if (winExposed)
- {
- if (pixExposed){
- REGION_UNION(pDst->pScreen, winExposed, winExposed, pixExposed);
- REGION_DESTROY(pDst->pScreen, pixExposed);
- }
- } else
- winExposed = pixExposed;
-
- EPILOGUE (pGC);
-
- return winExposed;
-}
-
-/*-
- *-----------------------------------------------------------------------
- * miBSCopyPlane --
- *
- * Results:
- * None.
- *
- * Side Effects:
- *
- *-----------------------------------------------------------------------
- */
-static RegionPtr
-miBSCopyPlane (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty, plane)
- DrawablePtr pSrc;
- DrawablePtr pDst;
- GC *pGC;
- int srcx,
- srcy;
- int w,
- h;
- int dstx,
- dsty;
- unsigned long plane;
-{
- BoxPtr pExtents;
- long dx, dy;
- int bsrcx, bsrcy, bw, bh, bdstx, bdsty;
- RegionPtr winExposed = 0, pixExposed = 0;
- SETUP_BACKING(pDst, pGC);
-
- PROLOGUE(pGC);
-
- if ((pSrc != pDst) ||
- (!miBSDoCopy((WindowPtr)pSrc, pGC, srcx, srcy, w, h, dstx, dsty,
- plane, pGC->ops->CopyPlane, &winExposed)))
- {
- /*
- * always copy to the backing store first, miBSDoCopy
- * returns FALSE if the *source* region is disjoint
- * from the backing store saved region. So, copying
- * *to* the backing store is always safe
- */
- if (pGC->clientClipType != CT_PIXMAP)
- {
- /*
- * adjust srcx, srcy, w, h, dstx, dsty to be clipped to
- * the backing store. An unnecessary optimisation,
- * but a useful one when GetSpans is slow.
- */
- pExtents = REGION_EXTENTS(pDst->pScreen,
- (RegionPtr)pBackingGC->clientClip);
- bsrcx = srcx;
- bsrcy = srcy;
- bw = w;
- bh = h;
- bdstx = dstx;
- bdsty = dsty;
- dx = pExtents->x1 - bdstx;
- if (dx > 0)
- {
- bsrcx += dx;
- bdstx += dx;
- bw -= dx;
- }
- dy = pExtents->y1 - bdsty;
- if (dy > 0)
- {
- bsrcy += dy;
- bdsty += dy;
- bh -= dy;
- }
- dx = (bdstx + bw) - pExtents->x2;
- if (dx > 0)
- bw -= dx;
- dy = (bdsty + bh) - pExtents->y2;
- if (dy > 0)
- bh -= dy;
- if (bw > 0 && bh > 0)
- pixExposed = (* pBackingGC->ops->CopyPlane) (pSrc,
- pBackingDrawable,
- pBackingGC, bsrcx, bsrcy, bw, bh,
- bdstx - pBackingStore->x,
- bdsty - pBackingStore->y, plane);
- }
- else
- pixExposed = (* pBackingGC->ops->CopyPlane) (pSrc,
- pBackingDrawable,
- pBackingGC, srcx, srcy, w, h,
- dstx - pBackingStore->x,
- dsty - pBackingStore->y, plane);
-
- winExposed = (* pGC->ops->CopyPlane) (pSrc, pDst, pGC, srcx, srcy, w, h,
- dstx, dsty, plane);
-
- }
-
- /*
- * compute the composite graphics exposure region
- */
- if (winExposed)
- {
- if (pixExposed)
- {
- REGION_UNION(pDst->pScreen, winExposed, winExposed, pixExposed);
- REGION_DESTROY(pDst->pScreen, pixExposed);
- }
- } else
- winExposed = pixExposed;
-
- EPILOGUE (pGC);
-
- return winExposed;
-}
-
-/*-
- *-----------------------------------------------------------------------
- * miBSPolyPoint --
- * Perform a PolyPoint, routing output to backing-store as needed.
- *
- * Results:
- * None.
- *
- * Side Effects:
- *
- *-----------------------------------------------------------------------
- */
-static void
-miBSPolyPoint (pDrawable, pGC, mode, npt, pptInit)
- DrawablePtr pDrawable;
- GCPtr pGC;
- int mode; /* Origin or Previous */
- int npt;
- xPoint *pptInit;
-{
- xPoint *pptCopy;
- SETUP_BACKING (pDrawable, pGC);
-
- PROLOGUE(pGC);
-
- pptCopy = (xPoint *)ALLOCATE_LOCAL(npt*sizeof(xPoint));
- if (pptCopy)
- {
- copyPoints(pptInit, pptCopy, npt, mode);
-
- (* pGC->ops->PolyPoint) (pDrawable, pGC, mode, npt, pptInit);
-
- (* pBackingGC->ops->PolyPoint) (pBackingDrawable,
- pBackingGC, mode, npt, pptCopy);
-
- DEALLOCATE_LOCAL(pptCopy);
- }
-
- EPILOGUE (pGC);
-}
-
-/*-
- *-----------------------------------------------------------------------
- * miBSPolyLines --
- * Perform a Polylines, routing output to backing-store as needed.
- *
- * Results:
- *
- * Side Effects:
- *
- *-----------------------------------------------------------------------
- */
-static void
-miBSPolylines (pDrawable, pGC, mode, npt, pptInit)
- DrawablePtr pDrawable;
- GCPtr pGC;
- int mode;
- int npt;
- DDXPointPtr pptInit;
-{
- DDXPointPtr pptCopy;
- SETUP_BACKING (pDrawable, pGC);
-
- PROLOGUE(pGC);
-
- pptCopy = (DDXPointPtr)ALLOCATE_LOCAL(npt*sizeof(DDXPointRec));
- if (pptCopy)
- {
- copyPoints(pptInit, pptCopy, npt, mode);
-
- (* pGC->ops->Polylines)(pDrawable, pGC, mode, npt, pptInit);
- (* pBackingGC->ops->Polylines)(pBackingDrawable,
- pBackingGC, mode, npt, pptCopy);
- DEALLOCATE_LOCAL(pptCopy);
- }
-
- EPILOGUE (pGC);
-}
-
-/*-
- *-----------------------------------------------------------------------
- * miBSPolySegment --
- * Perform a PolySegment, routing output to backing-store as needed.
- *
- * Results:
- * None.
- *
- * Side Effects:
- *
- *-----------------------------------------------------------------------
- */
-static void
-miBSPolySegment(pDrawable, pGC, nseg, pSegs)
- DrawablePtr pDrawable;
- GCPtr pGC;
- int nseg;
- xSegment *pSegs;
-{
- xSegment *pSegsCopy;
-
- SETUP_BACKING (pDrawable, pGC);
-
- PROLOGUE(pGC);
-
- pSegsCopy = (xSegment *)ALLOCATE_LOCAL(nseg*sizeof(xSegment));
- if (pSegsCopy)
- {
- copyData(pSegs, pSegsCopy, nseg << 1, MoreCopy0);
-
- (* pGC->ops->PolySegment)(pDrawable, pGC, nseg, pSegs);
- (* pBackingGC->ops->PolySegment)(pBackingDrawable,
- pBackingGC, nseg, pSegsCopy);
-
- DEALLOCATE_LOCAL(pSegsCopy);
- }
-
- EPILOGUE (pGC);
-}
-
-/*-
- *-----------------------------------------------------------------------
- * miBSPolyRectangle --
- * Perform a PolyRectangle, routing output to backing-store as needed.
- *
- * Results:
- * None
- *
- * Side Effects:
- *
- *-----------------------------------------------------------------------
- */
-static void
-miBSPolyRectangle(pDrawable, pGC, nrects, pRects)
- DrawablePtr pDrawable;
- GCPtr pGC;
- int nrects;
- xRectangle *pRects;
-{
- xRectangle *pRectsCopy;
- SETUP_BACKING (pDrawable, pGC);
-
- PROLOGUE(pGC);
-
- pRectsCopy =(xRectangle *)ALLOCATE_LOCAL(nrects*sizeof(xRectangle));
- if (pRectsCopy)
- {
- copyData(pRects, pRectsCopy, nrects, MoreCopy2);
-
- (* pGC->ops->PolyRectangle)(pDrawable, pGC, nrects, pRects);
- (* pBackingGC->ops->PolyRectangle)(pBackingDrawable,
- pBackingGC, nrects, pRectsCopy);
-
- DEALLOCATE_LOCAL(pRectsCopy);
- }
-
- EPILOGUE (pGC);
-}
-
-/*-
- *-----------------------------------------------------------------------
- * miBSPolyArc --
- * Perform a PolyArc, routing output to backing-store as needed.
- *
- * Results:
- *
- * Side Effects:
- *
- *-----------------------------------------------------------------------
- */
-static void
-miBSPolyArc(pDrawable, pGC, narcs, parcs)
- DrawablePtr pDrawable;
- GCPtr pGC;
- int narcs;
- xArc *parcs;
-{
- xArc *pArcsCopy;
- SETUP_BACKING (pDrawable, pGC);
-
- PROLOGUE(pGC);
-
- pArcsCopy = (xArc *)ALLOCATE_LOCAL(narcs*sizeof(xArc));
- if (pArcsCopy)
- {
- copyData(parcs, pArcsCopy, narcs, MoreCopy4);
-
- (* pGC->ops->PolyArc)(pDrawable, pGC, narcs, parcs);
- (* pBackingGC->ops->PolyArc)(pBackingDrawable, pBackingGC,
- narcs, pArcsCopy);
-
- DEALLOCATE_LOCAL(pArcsCopy);
- }
-
- EPILOGUE (pGC);
-}
-
-/*-
- *-----------------------------------------------------------------------
- * miBSFillPolygon --
- * Perform a FillPolygon, routing output to backing-store as needed.
- *
- * Results:
- * None.
- *
- * Side Effects:
- *
- *-----------------------------------------------------------------------
- */
-static void
-miBSFillPolygon(pDrawable, pGC, shape, mode, count, pPts)
- DrawablePtr pDrawable;
- GCPtr pGC;
- int shape, mode;
- int count;
- DDXPointPtr pPts;
-{
- DDXPointPtr pPtsCopy;
- SETUP_BACKING (pDrawable, pGC);
-
- PROLOGUE(pGC);
-
- pPtsCopy = (DDXPointPtr)ALLOCATE_LOCAL(count*sizeof(DDXPointRec));
- if (pPtsCopy)
- {
- copyPoints(pPts, pPtsCopy, count, mode);
- (* pGC->ops->FillPolygon)(pDrawable, pGC, shape, mode, count, pPts);
- (* pBackingGC->ops->FillPolygon)(pBackingDrawable,
- pBackingGC, shape, mode,
- count, pPtsCopy);
-
- DEALLOCATE_LOCAL(pPtsCopy);
- }
-
- EPILOGUE (pGC);
-}
-
-/*-
- *-----------------------------------------------------------------------
- * miBSPolyFillRect --
- * Perform a PolyFillRect, routing output to backing-store as needed.
- *
- * Results:
- * None.
- *
- * Side Effects:
- *
- *-----------------------------------------------------------------------
- */
-static void
-miBSPolyFillRect(pDrawable, pGC, nrectFill, prectInit)
- DrawablePtr pDrawable;
- GCPtr pGC;
- int nrectFill; /* number of rectangles to fill */
- xRectangle *prectInit; /* Pointer to first rectangle to fill */
-{
- xRectangle *pRectCopy;
- SETUP_BACKING (pDrawable, pGC);
-
- PROLOGUE(pGC);
-
- pRectCopy =
- (xRectangle *)ALLOCATE_LOCAL(nrectFill*sizeof(xRectangle));
- if (pRectCopy)
- {
- copyData(prectInit, pRectCopy, nrectFill, MoreCopy2);
-
- (* pGC->ops->PolyFillRect)(pDrawable, pGC, nrectFill, prectInit);
- (* pBackingGC->ops->PolyFillRect)(pBackingDrawable,
- pBackingGC, nrectFill, pRectCopy);
-
- DEALLOCATE_LOCAL(pRectCopy);
- }
-
- EPILOGUE (pGC);
-}
-
-/*-
- *-----------------------------------------------------------------------
- * miBSPolyFillArc --
- * Perform a PolyFillArc, routing output to backing-store as needed.
- *
- * Results:
- * None.
- *
- * Side Effects:
- *
- *-----------------------------------------------------------------------
- */
-static void
-miBSPolyFillArc(pDrawable, pGC, narcs, parcs)
- DrawablePtr pDrawable;
- GCPtr pGC;
- int narcs;
- xArc *parcs;
-{
- xArc *pArcsCopy;
- SETUP_BACKING (pDrawable, pGC);
-
- PROLOGUE(pGC);
-
- pArcsCopy = (xArc *)ALLOCATE_LOCAL(narcs*sizeof(xArc));
- if (pArcsCopy)
- {
- copyData(parcs, pArcsCopy, narcs, MoreCopy4);
- (* pGC->ops->PolyFillArc)(pDrawable, pGC, narcs, parcs);
- (* pBackingGC->ops->PolyFillArc)(pBackingDrawable,
- pBackingGC, narcs, pArcsCopy);
- DEALLOCATE_LOCAL(pArcsCopy);
- }
-
- EPILOGUE (pGC);
-}
-
-
-/*-
- *-----------------------------------------------------------------------
- * miBSPolyText8 --
- * Perform a PolyText8, routing output to backing-store as needed.
- *
- * Results:
- *
- * Side Effects:
- *
- *-----------------------------------------------------------------------
- */
-static int
-miBSPolyText8(pDrawable, pGC, x, y, count, chars)
- DrawablePtr pDrawable;
- GCPtr pGC;
- int x, y;
- int count;
- char *chars;
-{
- int result;
- SETUP_BACKING (pDrawable, pGC);
-
- PROLOGUE(pGC);
-
- result = (* pGC->ops->PolyText8)(pDrawable, pGC, x, y, count, chars);
- (* pBackingGC->ops->PolyText8)(pBackingDrawable, pBackingGC,
- x - pBackingStore->x, y - pBackingStore->y,
- count, chars);
-
- EPILOGUE (pGC);
- return result;
-}
-
-/*-
- *-----------------------------------------------------------------------
- * miBSPolyText16 --
- * Perform a PolyText16, routing output to backing-store as needed.
- *
- * Results:
- *
- * Side Effects:
- *
- *-----------------------------------------------------------------------
- */
-static int
-miBSPolyText16(pDrawable, pGC, x, y, count, chars)
- DrawablePtr pDrawable;
- GCPtr pGC;
- int x, y;
- int count;
- unsigned short *chars;
-{
- int result;
- SETUP_BACKING (pDrawable, pGC);
-
- PROLOGUE(pGC);
-
- result = (* pGC->ops->PolyText16)(pDrawable, pGC, x, y, count, chars);
- (* pBackingGC->ops->PolyText16)(pBackingDrawable, pBackingGC,
- x - pBackingStore->x, y - pBackingStore->y,
- count, chars);
-
- EPILOGUE (pGC);
-
- return result;
-}
-
-/*-
- *-----------------------------------------------------------------------
- * miBSImageText8 --
- * Perform a ImageText8, routing output to backing-store as needed.
- *
- * Results:
- *
- * Side Effects:
- *
- *-----------------------------------------------------------------------
- */
-static void
-miBSImageText8(pDrawable, pGC, x, y, count, chars)
- DrawablePtr pDrawable;
- GCPtr pGC;
- int x, y;
- int count;
- char *chars;
-{
- SETUP_BACKING (pDrawable, pGC);
- PROLOGUE(pGC);
-
- (* pGC->ops->ImageText8)(pDrawable, pGC, x, y, count, chars);
- (* pBackingGC->ops->ImageText8)(pBackingDrawable, pBackingGC,
- x - pBackingStore->x, y - pBackingStore->y,
- count, chars);
-
- EPILOGUE (pGC);
-}
-
-/*-
- *-----------------------------------------------------------------------
- * miBSImageText16 --
- * Perform a ImageText16, routing output to backing-store as needed.
- *
- * Results:
- *
- * Side Effects:
- *
- *-----------------------------------------------------------------------
- */
-static void
-miBSImageText16(pDrawable, pGC, x, y, count, chars)
- DrawablePtr pDrawable;
- GCPtr pGC;
- int x, y;
- int count;
- unsigned short *chars;
-{
- SETUP_BACKING (pDrawable, pGC);
- PROLOGUE(pGC);
-
- (* pGC->ops->ImageText16)(pDrawable, pGC, x, y, count, chars);
- (* pBackingGC->ops->ImageText16)(pBackingDrawable, pBackingGC,
- x - pBackingStore->x, y - pBackingStore->y,
- count, chars);
-
- EPILOGUE (pGC);
-}
-
-/*-
- *-----------------------------------------------------------------------
- * miBSImageGlyphBlt --
- * Perform a ImageGlyphBlt, routing output to backing-store as needed.
- *
- * Results:
- *
- * Side Effects:
- *
- *-----------------------------------------------------------------------
- */
-static void
-miBSImageGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase)
- DrawablePtr pDrawable;
- GCPtr pGC;
- int x, y;
- unsigned int nglyph;
- CharInfoPtr *ppci; /* array of character info */
- pointer pglyphBase; /* start of array of glyphs */
-{
- SETUP_BACKING (pDrawable, pGC);
- PROLOGUE(pGC);
-
- (* pGC->ops->ImageGlyphBlt)(pDrawable, pGC, x, y, nglyph, ppci,
- pglyphBase);
- (* pBackingGC->ops->ImageGlyphBlt)(pBackingDrawable, pBackingGC,
- x - pBackingStore->x, y - pBackingStore->y,
- nglyph, ppci, pglyphBase);
-
- EPILOGUE (pGC);
-}
-
-/*-
- *-----------------------------------------------------------------------
- * miBSPolyGlyphBlt --
- * Perform a PolyGlyphBlt, routing output to backing-store as needed.
- *
- * Results:
- *
- * Side Effects:
- *
- *-----------------------------------------------------------------------
- */
-static void
-miBSPolyGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase)
- DrawablePtr pDrawable;
- GCPtr pGC;
- int x, y;
- unsigned int nglyph;
- CharInfoPtr *ppci; /* array of character info */
- pointer pglyphBase; /* start of array of glyphs */
-{
- SETUP_BACKING (pDrawable, pGC);
- PROLOGUE(pGC);
-
- (* pGC->ops->PolyGlyphBlt)(pDrawable, pGC, x, y, nglyph,
- ppci, pglyphBase);
- (* pBackingGC->ops->PolyGlyphBlt)(pBackingDrawable, pBackingGC,
- x - pBackingStore->x, y - pBackingStore->y,
- nglyph, ppci, pglyphBase);
- EPILOGUE (pGC);
-}
-
-/*-
- *-----------------------------------------------------------------------
- * miBSPushPixels --
- * Perform a PushPixels, routing output to backing-store as needed.
- *
- * Results:
- *
- * Side Effects:
- *
- *-----------------------------------------------------------------------
- */
-static void
-miBSPushPixels(pGC, pBitMap, pDst, w, h, x, y)
- GCPtr pGC;
- PixmapPtr pBitMap;
- DrawablePtr pDst;
- int w, h, x, y;
-{
- SETUP_BACKING (pDst, pGC);
- PROLOGUE(pGC);
-
- (* pGC->ops->PushPixels)(pGC, pBitMap, pDst, w, h, x, y);
- if (pGC->miTranslate) {
- x -= pDst->x;
- y -= pDst->y;
- }
- (* pBackingGC->ops->PushPixels)(pBackingGC, pBitMap,
- pBackingDrawable, w, h,
- x - pBackingStore->x, y - pBackingStore->y);
-
- EPILOGUE (pGC);
-}
-
-/*-
- *-----------------------------------------------------------------------
- * miBSClearBackingStore --
- * Clear the given area of the backing pixmap with the background of
- * the window, whatever it is. If generateExposures is TRUE, generate
- * exposure events for the area. Note that if the area has any
- * part outside the saved portions of the window, we do not allow the
- * count in the expose events to be 0, since there will be more
- * expose events to come.
- *
- * Results:
- * None.
- *
- * Side Effects:
- * Areas of pixmap are cleared and Expose events are generated.
- *
- *-----------------------------------------------------------------------
- */
-static RegionPtr
-miBSClearBackingStore(pWin, x, y, w, h, generateExposures)
- WindowPtr pWin;
- int x;
- int y;
- int w;
- int h;
- Bool generateExposures;
-{
- RegionPtr pRgn;
- int i;
- miBSWindowPtr pBackingStore;
- ScreenPtr pScreen;
- GCPtr pGC;
- int ts_x_origin,
- ts_y_origin;
- pointer gcvalues[4];
- unsigned long gcmask;
- xRectangle *rects;
- BoxPtr pBox;
- BoxRec box;
- PixUnion background;
- char backgroundState;
- int numRects;
-
- pBackingStore = (miBSWindowPtr)pWin->backStorage;
- pScreen = pWin->drawable.pScreen;
-
- if ((pBackingStore->status == StatusNoPixmap) ||
- (pBackingStore->status == StatusBadAlloc))
- return NullRegion;
-
- if (w == 0)
- w = (int) pWin->drawable.width - x;
- if (h == 0)
- h = (int) pWin->drawable.height - y;
-
- box.x1 = x;
- box.y1 = y;
- box.x2 = x + w;
- box.y2 = y + h;
- pRgn = REGION_CREATE(pWin->drawable.pScreen, &box, 1);
- if (!pRgn)
- return NullRegion;
- REGION_INTERSECT( pScreen, pRgn, pRgn, &pBackingStore->SavedRegion);
-
- if (REGION_NOTEMPTY( pScreen, pRgn))
- {
- /*
- * if clearing entire window, simply make new virtual
- * tile. For the root window, we also destroy the pixmap
- * to save a pile of memory
- */
- if (x == 0 && y == 0 &&
- w == pWin->drawable.width &&
- h == pWin->drawable.height)
- {
- if (!pWin->parent)
- miDestroyBSPixmap (pWin);
- if (pBackingStore->status != StatusContents)
- miTileVirtualBS (pWin);
- }
-
- ts_x_origin = ts_y_origin = 0;
-
- backgroundState = pWin->backgroundState;
- background = pWin->background;
- if (backgroundState == ParentRelative) {
- WindowPtr pParent;
-
- pParent = pWin;
- while (pParent->backgroundState == ParentRelative) {
- ts_x_origin -= pParent->origin.x;
- ts_y_origin -= pParent->origin.y;
- pParent = pParent->parent;
- }
- backgroundState = pParent->backgroundState;
- background = pParent->background;
- }
-
- if ((backgroundState != None) &&
- ((pBackingStore->status == StatusContents) ||
- !SameBackground (pBackingStore->backgroundState,
- pBackingStore->background,
- backgroundState,
- background)))
- {
- if (!pBackingStore->pBackingPixmap)
- miCreateBSPixmap(pWin, NullBox);
-
- pGC = GetScratchGC(pWin->drawable.depth, pScreen);
- if (pGC && pBackingStore->pBackingPixmap)
- {
- /*
- * First take care of any ParentRelative stuff by altering the
- * tile/stipple origin to match the coordinates of the upper-left
- * corner of the first ancestor without a ParentRelative background.
- * This coordinate is, of course, negative.
- */
-
- if (backgroundState == BackgroundPixel)
- {
- gcvalues[0] = (pointer) background.pixel;
- gcvalues[1] = (pointer)FillSolid;
- gcmask = GCForeground|GCFillStyle;
- }
- else
- {
- gcvalues[0] = (pointer)FillTiled;
- gcvalues[1] = (pointer) background.pixmap;
- gcmask = GCFillStyle|GCTile;
- }
- gcvalues[2] = (pointer)(long)(ts_x_origin - pBackingStore->x);
- gcvalues[3] = (pointer)(long)(ts_y_origin - pBackingStore->y);
- gcmask |= GCTileStipXOrigin|GCTileStipYOrigin;
- DoChangeGC(pGC, gcmask, (XID *)gcvalues, TRUE);
- ValidateGC((DrawablePtr)pBackingStore->pBackingPixmap, pGC);
-
- /*
- * Figure out the array of rectangles to fill and fill them with
- * PolyFillRect in the proper mode, as set in the GC above.
- */
- numRects = REGION_NUM_RECTS(pRgn);
- rects = (xRectangle *)ALLOCATE_LOCAL(numRects*sizeof(xRectangle));
-
- if (rects)
- {
- for (i = 0, pBox = REGION_RECTS(pRgn);
- i < numRects;
- i++, pBox++)
- {
- rects[i].x = pBox->x1 - pBackingStore->x;
- rects[i].y = pBox->y1 - pBackingStore->y;
- rects[i].width = pBox->x2 - pBox->x1;
- rects[i].height = pBox->y2 - pBox->y1;
- }
- (* pGC->ops->PolyFillRect) (
- (DrawablePtr)pBackingStore->pBackingPixmap,
- pGC, numRects, rects);
- DEALLOCATE_LOCAL(rects);
- }
- FreeScratchGC(pGC);
- }
- }
-
- if (!generateExposures)
- {
- REGION_DESTROY(pScreen, pRgn);
- pRgn = NULL;
- }
- else
- {
- /*
- * result must be screen relative, but is currently
- * drawable relative.
- */
- REGION_TRANSLATE(pScreen, pRgn, pWin->drawable.x,
- pWin->drawable.y);
- }
- }
- else
- {
- REGION_DESTROY( pScreen, pRgn);
- pRgn = NULL;
- }
- return pRgn;
-}
-
-static void
-miBSClearBackingRegion (pWin, pRgn)
- WindowPtr pWin;
- RegionPtr pRgn;
-{
- BoxPtr pBox;
- int i;
-
- i = REGION_NUM_RECTS(pRgn);
- pBox = REGION_RECTS(pRgn);
- while (i--)
- {
- (void) miBSClearBackingStore(pWin, pBox->x1, pBox->y1,
- pBox->x2 - pBox->x1,
- pBox->y2 - pBox->y1,
- FALSE);
- pBox++;
- }
-}
-
/*
- * fill a region of the destination with virtual bits
- *
- * pRgn is to be translated by (x,y)
- */
-
-static void
-miBSFillVirtualBits (pDrawable, pGC, pRgn, x, y, state, pixunion, planeMask)
- DrawablePtr pDrawable;
- GCPtr pGC;
- RegionPtr pRgn;
- int x, y;
- int state;
- PixUnion pixunion;
- unsigned long planeMask;
-{
- int i;
- BITS32 gcmask;
- pointer gcval[5];
- xRectangle *pRect;
- BoxPtr pBox;
- WindowPtr pWin;
- int numRects;
-
- if (state == None)
- return;
- numRects = REGION_NUM_RECTS(pRgn);
- pRect = (xRectangle *)ALLOCATE_LOCAL(numRects * sizeof(xRectangle));
- if (!pRect)
- return;
- pWin = 0;
- if (pDrawable->type != DRAWABLE_PIXMAP)
- {
- pWin = (WindowPtr) pDrawable;
- if (!pWin->backStorage)
- pWin = 0;
- }
- i = 0;
- gcmask = 0;
- gcval[i++] = (pointer)planeMask;
- gcmask |= GCPlaneMask;
- if (state == BackgroundPixel)
- {
- if (pGC->fgPixel != pixunion.pixel)
- {
- gcval[i++] = (pointer)pixunion.pixel;
- gcmask |= GCForeground;
- }
- if (pGC->fillStyle != FillSolid)
- {
- gcval[i++] = (pointer)FillSolid;
- gcmask |= GCFillStyle;
- }
- }
- else
- {
- if (pGC->fillStyle != FillTiled)
- {
- gcval[i++] = (pointer)FillTiled;
- gcmask |= GCFillStyle;
- }
- if (pGC->tileIsPixel || pGC->tile.pixmap != pixunion.pixmap)
- {
- gcval[i++] = (pointer)pixunion.pixmap;
- gcmask |= GCTile;
- }
- if (pGC->patOrg.x != x)
- {
- gcval[i++] = (pointer)(long)x;
- gcmask |= GCTileStipXOrigin;
- }
- if (pGC->patOrg.y != y)
- {
- gcval[i++] = (pointer)(long)y;
- gcmask |= GCTileStipYOrigin;
- }
- }
- if (gcmask)
- DoChangeGC (pGC, gcmask, (XID *)gcval, 1);
-
- if (pWin)
- (*pWin->drawable.pScreen->DrawGuarantee) (pWin, pGC, GuaranteeVisBack);
-
- if (pDrawable->serialNumber != pGC->serialNumber)
- ValidateGC (pDrawable, pGC);
-
- pBox = REGION_RECTS(pRgn);
- for (i = numRects; --i >= 0; pBox++, pRect++)
- {
- pRect->x = pBox->x1 + x;
- pRect->y = pBox->y1 + y;
- pRect->width = pBox->x2 - pBox->x1;
- pRect->height = pBox->y2 - pBox->y1;
- }
- pRect -= numRects;
- (*pGC->ops->PolyFillRect) (pDrawable, pGC, numRects, pRect);
- if (pWin)
- (*pWin->drawable.pScreen->DrawGuarantee) (pWin, pGC, GuaranteeNothing);
- DEALLOCATE_LOCAL (pRect);
-}
-
-/*-
- *-----------------------------------------------------------------------
- * miBSAllocate --
- * Create and install backing store info for a window
- *
- *-----------------------------------------------------------------------
- */
-
-static void
-miBSAllocate(pWin)
- WindowPtr pWin;
-{
- miBSWindowPtr pBackingStore;
- ScreenPtr pScreen;
-
- if (pWin->drawable.pScreen->backingStoreSupport == NotUseful)
- return;
- pScreen = pWin->drawable.pScreen;
- if (!(pBackingStore = (miBSWindowPtr)pWin->backStorage))
- {
-
- pBackingStore = (miBSWindowPtr)xalloc(sizeof(miBSWindowRec));
- if (!pBackingStore)
- return;
-
- pBackingStore->pBackingPixmap = NullPixmap;
- pBackingStore->x = 0;
- pBackingStore->y = 0;
- REGION_NULL( pScreen, &pBackingStore->SavedRegion);
- pBackingStore->viewable = (char)pWin->viewable;
- pBackingStore->status = StatusNoPixmap;
- pBackingStore->backgroundState = None;
- pWin->backStorage = (pointer) pBackingStore;
- }
-
- /*
- * Now want to initialize the backing pixmap and SavedRegion if
- * necessary. The initialization consists of finding all the
- * currently-obscured regions, by taking the inverse of the window's
- * clip list, storing the result in SavedRegion, and exposing those
- * areas of the window.
- */
-
- if (pBackingStore->status == StatusNoPixmap &&
- ((pWin->backingStore == WhenMapped && pWin->viewable) ||
- (pWin->backingStore == Always)))
- {
- BoxRec box;
- RegionPtr pSavedRegion;
-
- pSavedRegion = &pBackingStore->SavedRegion;
-
- box.x1 = pWin->drawable.x;
- box.x2 = box.x1 + (int) pWin->drawable.width;
- box.y1 = pWin->drawable.y;
- box.y2 = pWin->drawable.y + (int) pWin->drawable.height;
-
- REGION_INVERSE( pScreen, pSavedRegion, &pWin->clipList, &box);
- REGION_TRANSLATE( pScreen, pSavedRegion,
- -pWin->drawable.x,
- -pWin->drawable.y);
-#ifdef SHAPE
- if (wBoundingShape (pWin))
- REGION_INTERSECT(pScreen, pSavedRegion, pSavedRegion,
- wBoundingShape (pWin));
- if (wClipShape (pWin))
- REGION_INTERSECT(pScreen, pSavedRegion, pSavedRegion,
- wClipShape (pWin));
-#endif
- /* if window is already on-screen, assume it has been drawn to */
- if (pWin->viewable)
- pBackingStore->status = StatusVDirty;
- miTileVirtualBS (pWin);
-
- /*
- * deliver all the newly available regions
- * as exposure events to the window
- */
-
- miSendExposures(pWin, pSavedRegion, 0, 0);
- }
- else if (!pWin->viewable)
- {
- /*
- * Turn off backing store when we're not supposed to
- * be saving anything
- */
- if (pBackingStore->status != StatusNoPixmap)
- {
- REGION_EMPTY( pScreen, &pBackingStore->SavedRegion);
- miDestroyBSPixmap (pWin);
- }
- }
-}
-
-/*-
- *-----------------------------------------------------------------------
- * miBSFree --
- * Destroy and free all the stuff associated with the backing-store
- * for the given window.
- *
- * Results:
- * None.
- *
- * Side Effects:
- * The backing pixmap and all the regions and GC's are destroyed.
- *
- *-----------------------------------------------------------------------
- */
-static void
-miBSFree(pWin)
- WindowPtr pWin;
-{
- miBSWindowPtr pBackingStore;
- ScreenPtr pScreen;
-
- pScreen = pWin->drawable.pScreen;
-
- pBackingStore = (miBSWindowPtr)pWin->backStorage;
- if (pBackingStore)
- {
- miDestroyBSPixmap (pWin);
-
- REGION_UNINIT( pScreen, &pBackingStore->SavedRegion);
-
- xfree(pBackingStore);
- pWin->backStorage = NULL;
- }
-}
-
-/*-
- *-----------------------------------------------------------------------
- * miResizeBackingStore --
- * Alter the size of the backing pixmap as necessary when the
- * SavedRegion changes size. The contents of the old pixmap are
- * copied/shifted into the new/same pixmap.
- *
- * Results:
- * The new Pixmap is created as necessary.
- *
- * Side Effects:
- * The old pixmap is destroyed.
- *
- *-----------------------------------------------------------------------
- */
-static void
-miResizeBackingStore(
- WindowPtr pWin,
- int dx, /* bits are moving this far */
- int dy, /* bits are moving this far */
- Bool saveBits) /* bits are useful */
-{
- miBSWindowPtr pBackingStore;
- PixmapPtr pBackingPixmap;
- ScreenPtr pScreen;
- GC *pGC;
- BoxPtr extents;
- PixmapPtr pNewPixmap;
- int nx, ny;
- int nw, nh;
-
- pBackingStore = (miBSWindowPtr)(pWin->backStorage);
- pBackingPixmap = pBackingStore->pBackingPixmap;
- if (!pBackingPixmap)
- return;
- pScreen = pWin->drawable.pScreen;
- extents = REGION_EXTENTS(pScreen, &pBackingStore->SavedRegion);
- pNewPixmap = pBackingPixmap;
-
- nw = extents->x2 - extents->x1;
- nh = extents->y2 - extents->y1;
-
- /* the policy here could be more sophisticated */
- if (nw != pBackingPixmap->drawable.width ||
- nh != pBackingPixmap->drawable.height)
- {
- if (!saveBits || !nw || !nh)
- {
- pNewPixmap = NullPixmap;
- pBackingStore->status = StatusNoPixmap;
- }
- else
- {
- pNewPixmap = (PixmapPtr)(*pScreen->CreatePixmap)
- (pScreen,
- nw, nh,
- pWin->drawable.depth);
- if (!pNewPixmap)
- {
-#ifdef BSEAGER
- pBackingStore->status = StatusNoPixmap;
-#else
- pBackingStore->status = StatusBadAlloc;
-#endif
- }
- }
- }
- if (!pNewPixmap)
- {
- pBackingStore->x = 0;
- pBackingStore->y = 0;
- }
- else
- {
- nx = pBackingStore->x - extents->x1 + dx;
- ny = pBackingStore->y - extents->y1 + dy;
- pBackingStore->x = extents->x1;
- pBackingStore->y = extents->y1;
-
- if (saveBits && (pNewPixmap != pBackingPixmap || nx != 0 || ny != 0))
- {
- pGC = GetScratchGC(pNewPixmap->drawable.depth, pScreen);
- if (pGC)
- {
- ValidateGC((DrawablePtr)pNewPixmap, pGC);
- /* if we implement a policy where the pixmap can be larger than
- * the region extents, we might want to optimize this copyarea
- * by only copying the old extents, rather than the entire
- * pixmap
- */
- (*pGC->ops->CopyArea)((DrawablePtr)pBackingPixmap,
- (DrawablePtr)pNewPixmap, pGC,
- 0, 0,
- pBackingPixmap->drawable.width,
- pBackingPixmap->drawable.height,
- nx, ny);
- FreeScratchGC(pGC);
- }
- }
- }
- /* SavedRegion is used in the backingGC clip; force an update */
- pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
- if (pNewPixmap != pBackingPixmap)
- {
- (* pScreen->DestroyPixmap)(pBackingPixmap);
- pBackingStore->pBackingPixmap = pNewPixmap;
- }
-}
-
-/*-
- *-----------------------------------------------------------------------
- * miBSSaveDoomedAreas --
- * Saved the areas of the given window that are about to be
- * obscured. If the window has moved, pObscured is expected to
- * be at the new screen location and (dx,dy) is expected to be the offset
- * to the window's previous location.
- *
- * Results:
- * None.
- *
- * Side Effects:
- * The region is copied from the screen into pBackingPixmap and
- * SavedRegion is updated.
- *
- *-----------------------------------------------------------------------
- */
-static void
-miBSSaveDoomedAreas(pWin, pObscured, dx, dy)
- WindowPtr pWin;
- RegionPtr pObscured;
- int dx, dy;
-{
- miBSWindowPtr pBackingStore;
- ScreenPtr pScreen;
- int x, y;
-
- pBackingStore = (miBSWindowPtr)pWin->backStorage;
- pScreen = pWin->drawable.pScreen;
-
- /*
- * If the window isn't realized, it's being unmapped, thus we don't
- * want to save anything if backingStore isn't Always.
- */
- if (!pWin->realized)
- {
- pBackingStore->viewable = (char)pWin->viewable;
- if (pWin->backingStore != Always)
- {
- REGION_EMPTY( pScreen, &pBackingStore->SavedRegion);
- miDestroyBSPixmap (pWin);
- return;
- }
- if (pBackingStore->status == StatusBadAlloc)
- pBackingStore->status = StatusNoPixmap;
- }
-
- /* Don't even pretend to save anything for a virtual background None */
- if ((pBackingStore->status == StatusVirtual) &&
- (pBackingStore->backgroundState == None))
- return;
-
- if (REGION_NOTEMPTY(pScreen, pObscured))
- {
- BoxRec oldExtents;
- x = pWin->drawable.x;
- y = pWin->drawable.y;
- REGION_TRANSLATE(pScreen, pObscured, -x, -y);
- oldExtents = *REGION_EXTENTS(pScreen, &pBackingStore->SavedRegion);
- REGION_UNION( pScreen, &pBackingStore->SavedRegion,
- &pBackingStore->SavedRegion,
- pObscured);
- /*
- * only save the bits if we've actually
- * started using backing store
- */
- if (pBackingStore->status != StatusVirtual)
- {
- if (!pBackingStore->pBackingPixmap)
- miCreateBSPixmap (pWin, &oldExtents);
- else
- miResizeBackingStore(pWin, 0, 0, TRUE);
-
- if (pBackingStore->pBackingPixmap) {
- if (pBackingStore->x | pBackingStore->y)
- {
- REGION_TRANSLATE( pScreen, pObscured,
- -pBackingStore->x,
- -pBackingStore->y);
- x += pBackingStore->x;
- y += pBackingStore->y;
- }
- (* pScreen->BackingStoreFuncs.SaveAreas)
- (pBackingStore->pBackingPixmap, pObscured,
- x - dx, y - dy, pWin);
- }
- }
- REGION_TRANSLATE(pScreen, pObscured, x, y);
- }
- else
- {
- if (REGION_BROKEN (pScreen, pObscured))
- {
- REGION_EMPTY( pScreen, &pBackingStore->SavedRegion);
- miDestroyBSPixmap (pWin);
- return;
- }
- }
-}
-
-/*-
- *-----------------------------------------------------------------------
- * miBSRestoreAreas --
- * Restore areas from backing-store that are no longer obscured.
- * expects prgnExposed to contain a screen-relative area.
- *
- * Results:
- * The region to generate exposure events on (which may be
- * different from the region to paint).
- *
- * Side Effects:
- * Areas are copied from pBackingPixmap to the screen. prgnExposed
- * is altered to contain the region that could not be restored from
- * backing-store.
- *
- * Notes:
- * This is called before sending any exposure events to the client,
- * and so might be called if the window has grown. Changing the backing
- * pixmap doesn't require revalidating the backingGC because the
- * client's next output request will result in a call to ValidateGC,
- * since the window clip region has changed, which will in turn call
- * miValidateBackingStore.
- *-----------------------------------------------------------------------
- */
-static RegionPtr
-miBSRestoreAreas(pWin, prgnExposed)
- WindowPtr pWin;
- RegionPtr prgnExposed;
-{
- PixmapPtr pBackingPixmap;
- miBSWindowPtr pBackingStore;
- RegionPtr prgnSaved;
- RegionPtr prgnRestored;
- ScreenPtr pScreen;
- RegionPtr exposures = prgnExposed;
-
- pScreen = pWin->drawable.pScreen;
- pBackingStore = (miBSWindowPtr)pWin->backStorage;
- pBackingPixmap = pBackingStore->pBackingPixmap;
-
- prgnSaved = &pBackingStore->SavedRegion;
-
- if (pBackingStore->status == StatusContents)
- {
- REGION_TRANSLATE(pScreen, prgnSaved, pWin->drawable.x,
- pWin->drawable.y);
-
- prgnRestored = REGION_CREATE( pScreen, (BoxPtr)NULL, 1);
- REGION_INTERSECT( pScreen, prgnRestored, prgnExposed, prgnSaved);
-
- /*
- * Since prgnExposed is no longer obscured, we no longer
- * will have a valid copy of it in backing-store, but there is a valid
- * copy of it on screen, so subtract the area we just restored from
- * from the area to be exposed.
- */
-
- if (REGION_NOTEMPTY( pScreen, prgnRestored))
- {
- REGION_SUBTRACT( pScreen, prgnSaved, prgnSaved, prgnExposed);
- REGION_SUBTRACT( pScreen, prgnExposed, prgnExposed, prgnRestored);
-
- /*
- * Do the actual restoration
- */
- (* pScreen->BackingStoreFuncs.RestoreAreas) (pBackingPixmap,
- prgnRestored,
- pWin->drawable.x + pBackingStore->x,
- pWin->drawable.y + pBackingStore->y,
- pWin);
- /*
- * if the saved region is completely empty, dispose of the
- * backing pixmap, otherwise, retranslate the saved
- * region to window relative
- */
-
- if (REGION_NOTEMPTY(pScreen, prgnSaved))
- {
- REGION_TRANSLATE(pScreen, prgnSaved,
- -pWin->drawable.x,
- -pWin->drawable.y);
- miResizeBackingStore(pWin, 0, 0, TRUE);
- }
- else
- miDestroyBSPixmap (pWin);
- }
- else
- REGION_TRANSLATE(pScreen, prgnSaved,
- -pWin->drawable.x, -pWin->drawable.y);
- REGION_DESTROY( pScreen, prgnRestored);
-
- }
- else if ((pBackingStore->status == StatusVirtual) ||
- (pBackingStore->status == StatusVDirty))
- {
- REGION_TRANSLATE(pScreen, prgnSaved,
- pWin->drawable.x, pWin->drawable.y);
- exposures = REGION_CREATE( pScreen, NullBox, 1);
- if (SameBackground (pBackingStore->backgroundState,
- pBackingStore->background,
- pWin->backgroundState,
- pWin->background))
- {
- REGION_SUBTRACT( pScreen, exposures, prgnExposed, prgnSaved);
- }
- else
- {
- miTileVirtualBS(pWin);
-
- /* we need to expose all we have (virtually) retiled */
- REGION_UNION( pScreen, exposures, prgnExposed, prgnSaved);
- }
- REGION_SUBTRACT( pScreen, prgnSaved, prgnSaved, prgnExposed);
- REGION_TRANSLATE(pScreen, prgnSaved,
- -pWin->drawable.x, -pWin->drawable.y);
- }
- else if (pWin->viewable && !pBackingStore->viewable &&
- pWin->backingStore != Always)
- {
- /*
- * The window was just mapped and nothing has been saved in
- * backing-store from the last time it was mapped. We want to capture
- * any output to regions that are already obscured but there are no
- * bits to snag off the screen, so we initialize things just as we did
- * in miBSAllocate, above.
- */
- BoxRec box;
-
- prgnSaved = &pBackingStore->SavedRegion;
-
- box.x1 = pWin->drawable.x;
- box.x2 = box.x1 + (int) pWin->drawable.width;
- box.y1 = pWin->drawable.y;
- box.y2 = box.y1 + (int) pWin->drawable.height;
-
- REGION_INVERSE( pScreen, prgnSaved, &pWin->clipList, &box);
- REGION_TRANSLATE( pScreen, prgnSaved,
- -pWin->drawable.x,
- -pWin->drawable.y);
-#ifdef SHAPE
- if (wBoundingShape (pWin))
- REGION_INTERSECT(pScreen, prgnSaved, prgnSaved,
- wBoundingShape (pWin));
- if (wClipShape (pWin))
- REGION_INTERSECT(pScreen, prgnSaved, prgnSaved,
- wClipShape (pWin));
-#endif
- miTileVirtualBS(pWin);
-
- exposures = REGION_CREATE( pScreen, &box, 1);
- }
- pBackingStore->viewable = (char)pWin->viewable;
- return exposures;
-}
-
-
-/*-
- *-----------------------------------------------------------------------
- * miBSTranslateBackingStore --
- * Shift the backing-store in the given direction. Called when bit
- * gravity is shifting things around.
- *
- * Results:
- * An occluded region of the window which should be sent exposure events.
- * This region should be in absolute coordinates (i.e. include
- * new window position).
- *
- * Side Effects:
- * If the window changed size as well as position, the backing pixmap
- * is resized. The contents of the backing pixmap are shifted
- *
- * Warning:
- * Bob and I have rewritten this routine quite a few times, each
- * time it gets a few more cases correct, and introducing some
- * interesting bugs. Naturally, I think the code is correct this
- * time.
- *
- * Let me try to explain what this routine is for:
+ * Copyright 2007 Red Hat, Inc.
*
- * It's called from SlideAndSizeWindow whenever a window
- * with backing store is resized. There are two separate
- * possibilities:
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software")
+ * to deal in the software without restriction, including without limitation
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, and/or sell copies of the Software, and to permit persons to whom
+ * them Software is furnished to do so, subject to the following conditions:
*
- * a) The window has ForgetGravity
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
*
- * In this case, windx, windy will be 0 and oldClip will
- * be NULL. This indicates that all of the window contents
- * currently saved offscreen should be discarded, and the
- * entire window exposed. TranslateBackingStore, then, should
- * prepare a completely new backing store region based on the
- * new window clipList and return that region for exposure.
- *
- * b) The window has some other gravity
- *
- * In this case, windx, windy will be set to the distance
- * that the bits should move within the window. oldClip
- * will be set to the old visible portion of the window.
- * TranslateBackingStore, then, should adjust the backing
- * store to accommodate the portion of the existing backing
- * store bits which coorespond to backing store bits which
- * will still be occluded in the new configuration. oldx,oldy
- * are set to the old position of the window on the screen.
- *
- * Furthermore, in this case any contents of the screen which
- * are about to become occluded should be fetched from the screen
- * and placed in backing store. This is to avoid the eventual
- * occlusion by the win gravity shifting the child window bits around
- * on top of this window, and potentially losing information
- *
- * It's also called from SetShape, but I think (he says not
- * really knowing for sure) that this code will even work
- * in that case.
- *-----------------------------------------------------------------------
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTIBILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT, OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
-static RegionPtr
-miBSTranslateBackingStore(pWin, windx, windy, oldClip, oldx, oldy)
- WindowPtr pWin;
- int windx; /* bit translation distance in window */
- int windy;
- RegionPtr oldClip; /* Region being copied */
- int oldx; /* old window position */
- int oldy;
-{
- miBSWindowPtr pBackingStore;
- RegionPtr pSavedRegion;
- RegionPtr newSaved, doomed;
- ScreenPtr pScreen;
- BoxRec extents;
- int scrdx; /* bit translation distance on screen */
- int scrdy;
- int dx; /* distance window moved on screen */
- int dy;
-
- pScreen = pWin->drawable.pScreen;
- pBackingStore = (miBSWindowPtr)(pWin->backStorage);
- if ((pBackingStore->status == StatusNoPixmap) ||
- (pBackingStore->status == StatusBadAlloc))
- return NullRegion;
-
- /*
- * Compute the new saved region
- */
-
- newSaved = REGION_CREATE( pScreen, NullBox, 1);
- extents.x1 = pWin->drawable.x;
- extents.x2 = pWin->drawable.x + (int) pWin->drawable.width;
- extents.y1 = pWin->drawable.y;
- extents.y2 = pWin->drawable.y + (int) pWin->drawable.height;
- REGION_INVERSE( pScreen, newSaved, &pWin->clipList, &extents);
-
- REGION_TRANSLATE( pScreen, newSaved,
- -pWin->drawable.x, -pWin->drawable.y);
-#ifdef SHAPE
- if (wBoundingShape (pWin) || wClipShape (pWin)) {
- if (wBoundingShape (pWin))
- REGION_INTERSECT( pScreen, newSaved, newSaved,
- wBoundingShape (pWin));
- if (wClipShape (pWin))
- REGION_INTERSECT( pScreen, newSaved, newSaved, wClipShape (pWin));
- }
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
#endif
-
- pSavedRegion = &pBackingStore->SavedRegion;
-
- /* now find any visible areas we can save from the screen */
- /* and then translate newSaved to old local coordinates */
- if (oldClip)
- {
- /* bit gravity makes things virtually too hard, punt */
- if (((windx != 0) || (windy != 0)) &&
- (pBackingStore->status != StatusContents))
- miCreateBSPixmap(pWin, NullBox);
-
- /*
- * The window is moving this far on the screen
- */
- dx = pWin->drawable.x - oldx;
- dy = pWin->drawable.y - oldy;
- /*
- * The bits will be moving on the screen by the
- * amount the window is moving + the amount the
- * bits are moving within the window
- */
- scrdx = windx + dx;
- scrdy = windy + dy;
-
- /*
- * intersect at old bit position to discover the
- * bits on the screen which can be put into the
- * new backing store
- */
- REGION_TRANSLATE( pScreen, oldClip, windx - oldx, windy - oldy);
- doomed = REGION_CREATE( pScreen, NullBox, 1);
- REGION_INTERSECT( pScreen, doomed, oldClip, newSaved);
- REGION_TRANSLATE( pScreen, oldClip, oldx - windx, oldy - windy);
-
- /*
- * Translate the old saved region to the position in the
- * window where it will appear to be
- */
- REGION_TRANSLATE( pScreen, pSavedRegion, windx, windy);
-
- /*
- * Add the old saved region to the new saved region, so
- * that calls to RestoreAreas will be able to fetch those
- * bits back
- */
- REGION_UNION( pScreen, newSaved, newSaved, pSavedRegion);
-
- /*
- * Swap the new saved region into the window
- */
- {
- RegionRec tmp;
-
- tmp = *pSavedRegion;
- *pSavedRegion = *newSaved;
- *newSaved = tmp;
- }
- miResizeBackingStore (pWin, windx, windy, TRUE);
-
- /*
- * Compute the newly enabled region
- * of backing store. This region will be
- * set to background in the backing pixmap and
- * sent as exposure events to the client.
- */
- REGION_SUBTRACT( pScreen, newSaved, pSavedRegion, newSaved);
-
- /*
- * Fetch bits which will be obscured from
- * the screen
- */
- if (REGION_NOTEMPTY( pScreen, doomed))
- {
- /*
- * Don't clear regions which have bits on the
- * screen
- */
- REGION_SUBTRACT( pScreen, newSaved, newSaved, doomed);
-
- /*
- * Make the region to SaveDoomedAreas absolute, instead
- * of window relative.
- */
- REGION_TRANSLATE( pScreen, doomed,
- pWin->drawable.x, pWin->drawable.y);
- (* pScreen->SaveDoomedAreas) (pWin, doomed, scrdx, scrdy);
- }
-
- REGION_DESTROY(pScreen, doomed);
-
- /*
- * and clear whatever there is that's new
- */
- if (REGION_NOTEMPTY( pScreen, newSaved))
- {
- miBSClearBackingRegion (pWin, newSaved);
- /*
- * Make the exposed region absolute
- */
- REGION_TRANSLATE(pScreen, newSaved,
- pWin->drawable.x,
- pWin->drawable.y);
- }
- else
- {
- REGION_DESTROY(pScreen, newSaved);
- newSaved = NullRegion;
- }
- }
- else
- {
- /*
- * ForgetGravity: just reset backing store and
- * expose the whole mess
- */
- REGION_COPY( pScreen, pSavedRegion, newSaved);
- REGION_TRANSLATE( pScreen, newSaved,
- pWin->drawable.x, pWin->drawable.y);
-
- miResizeBackingStore (pWin, 0, 0, FALSE);
- (void) miBSClearBackingStore (pWin, 0, 0, 0, 0, FALSE);
- }
-
- return newSaved;
-}
+#include "scrnintstr.h"
+#include "mibstore.h"
/*
- * Inform the backing store layer that you are about to validate
- * a gc with a window, and that subsequent output to the window
- * is (or is not) guaranteed to be already clipped to the visible
- * regions of the window.
- */
-
-static void
-miBSDrawGuarantee (pWin, pGC, guarantee)
- WindowPtr pWin;
- GCPtr pGC;
- int guarantee;
-{
- miBSGCPtr pPriv;
-
- if (pWin->backStorage)
- {
- pPriv = (miBSGCPtr)pGC->devPrivates[miBSGCIndex].ptr;
- if (!pPriv)
- (void) miBSCreateGCPrivate (pGC);
- pPriv = (miBSGCPtr)pGC->devPrivates[miBSGCIndex].ptr;
- if (pPriv)
- {
- /*
- * XXX KLUDGE ALERT
- *
- * when the GC is Cheap pPriv will point
- * at some device's gc func structure. guarantee
- * will point at the ChangeGC entry of that struct
- * and will never match a valid guarantee value.
- */
- switch (pPriv->guarantee)
- {
- case GuaranteeNothing:
- case GuaranteeVisBack:
- pPriv->guarantee = guarantee;
- break;
- }
- }
- }
-}
-
-#define noBackingCopy (GCGraphicsExposures|GCClipXOrigin|GCClipYOrigin| \
- GCClipMask|GCSubwindowMode| \
- GCTileStipXOrigin|GCTileStipYOrigin)
-
-/*-
- *-----------------------------------------------------------------------
- * miBSValidateGC --
- * Wrapper around output-library's ValidateGC routine
+ * There is no longer an mi implementation of backing store. This function
+ * is only for source compatibility with old drivers.
*
- * Results:
- * None.
- *
- * Side Effects:
- *
- * Notes:
- * The idea here is to perform several functions:
- * - All the output calls must be intercepted and routed to
- * backing-store as necessary.
- * - pGC in the window's devBackingStore must be set up with the
- * clip list appropriate for writing to pBackingPixmap (i.e.
- * the inverse of the window's clipList intersected with the
- * clientClip of the GC). Since the destination for this GC is
- * a pixmap, it is sufficient to set the clip list as its
- * clientClip.
- *-----------------------------------------------------------------------
+ * Note though that you do get backing store for free if your server has
+ * Composite enabled, since the automatic redirection mechanism provides
+ * essentially the same functionality. See compChangeWindowAttributes()
+ * for the implementation.
*/
-static void
-miBSValidateGC (pGC, stateChanges, pDrawable)
- GCPtr pGC;
- unsigned long stateChanges;
- DrawablePtr pDrawable;
-{
- GCPtr pBackingGC;
- miBSWindowPtr pWindowPriv = NULL;
- miBSGCPtr pPriv;
- WindowPtr pWin;
- int lift_functions;
- RegionPtr backingCompositeClip = NULL;
-
- if (pDrawable->type != DRAWABLE_PIXMAP)
- {
- pWin = (WindowPtr) pDrawable;
- pWindowPriv = (miBSWindowPtr) pWin->backStorage;
- lift_functions = (pWindowPriv == (miBSWindowPtr) NULL);
- }
- else
- {
- pWin = (WindowPtr) NULL;
- lift_functions = TRUE;
- }
-
- pPriv = (miBSGCPtr)pGC->devPrivates[miBSGCIndex].ptr;
-
- FUNC_PROLOGUE (pGC, pPriv);
-
- (*pGC->funcs->ValidateGC) (pGC, stateChanges, pDrawable);
-
- /*
- * rewrap funcs and ops as Validate may have changed them
- */
-
- pPriv->wrapFuncs = pGC->funcs;
- pPriv->wrapOps = pGC->ops;
-
- if (!lift_functions && ((pPriv->guarantee == GuaranteeVisBack) ||
- (pWindowPriv->status == StatusNoPixmap) ||
- (pWindowPriv->status == StatusBadAlloc)))
- lift_functions = TRUE;
-
- /*
- * check to see if a new backingCompositeClip region must
- * be generated
- */
-
- if (!lift_functions &&
- ((pDrawable->serialNumber != pPriv->serialNumber) ||
- (stateChanges&(GCClipXOrigin|GCClipYOrigin|GCClipMask|GCSubwindowMode))))
- {
- if (REGION_NOTEMPTY(pGC->pScreen, &pWindowPriv->SavedRegion))
- {
- backingCompositeClip = REGION_CREATE(pGC->pScreen, NULL, 1);
- if ((pGC->clientClipType == CT_NONE) ||
- (pGC->clientClipType == CT_PIXMAP))
- {
- REGION_COPY(pGC->pScreen, backingCompositeClip,
- &pWindowPriv->SavedRegion);
- }
- else
- {
- /*
- * Make a new copy of the client clip, translated to
- * its proper origin.
- */
-
- REGION_COPY(pGC->pScreen, backingCompositeClip,
- pGC->clientClip);
- REGION_TRANSLATE(pGC->pScreen, backingCompositeClip,
- pGC->clipOrg.x,
- pGC->clipOrg.y);
- REGION_INTERSECT(pGC->pScreen, backingCompositeClip,
- backingCompositeClip,
- &pWindowPriv->SavedRegion);
- }
- if (pGC->subWindowMode == IncludeInferiors)
- {
- RegionPtr translatedClip;
-
- /* XXX
- * any output in IncludeInferiors mode will not
- * be redirected to Inferiors backing store. This
- * can be fixed only at great cost to the shadow routines.
- */
- translatedClip = NotClippedByChildren (pWin);
- REGION_TRANSLATE(pGC->pScreen, translatedClip,
- -pDrawable->x,
- -pDrawable->y);
- REGION_SUBTRACT(pGC->pScreen, backingCompositeClip,
- backingCompositeClip, translatedClip);
- REGION_DESTROY(pGC->pScreen, translatedClip);
- }
- if (!REGION_NOTEMPTY(pGC->pScreen, backingCompositeClip))
- lift_functions = TRUE;
- }
- else
- {
- lift_functions = TRUE;
- }
-
- /* Reset the status when drawing to an unoccluded window so that
- * future SaveAreas will actually copy bits from the screen. Note that
- * output to root window in IncludeInferiors mode will not cause this
- * to change. This causes all transient graphics by the window
- * manager to the root window to not enable backing store.
- */
- if (lift_functions && (pWindowPriv->status == StatusVirtual) &&
- (pWin->parent || pGC->subWindowMode != IncludeInferiors))
- pWindowPriv->status = StatusVDirty;
- }
-
- /*
- * if no backing store has been allocated, and it's needed,
- * create it now.
- */
-
- if (!lift_functions && !pWindowPriv->pBackingPixmap)
- {
- miCreateBSPixmap (pWin, NullBox);
- if (!pWindowPriv->pBackingPixmap)
- lift_functions = TRUE;
- }
-
- /*
- * create the backing GC if needed, lift functions
- * if the creation fails
- */
-
- if (!lift_functions && !pPriv->pBackingGC)
- {
- int status;
- XID noexpose = xFalse;
-
- /* We never want ops with the backingGC to generate GraphicsExpose */
- pBackingGC = CreateGC ((DrawablePtr)pWindowPriv->pBackingPixmap,
- GCGraphicsExposures, &noexpose, &status,
- (XID)0, serverClient);
- if (status != Success)
- lift_functions = TRUE;
- else
- pPriv->pBackingGC = pBackingGC;
- }
-
- pBackingGC = pPriv->pBackingGC;
-
- pPriv->stateChanges |= stateChanges;
-
- if (lift_functions)
- {
- if (backingCompositeClip)
- REGION_DESTROY( pGC->pScreen, backingCompositeClip);
-
- /* unwrap the GC again */
- miBSDestroyGCPrivate (pGC);
-
- return;
- }
-
- /*
- * the rest of this function gets the pBackingGC
- * into shape for possible draws
- */
-
- pPriv->stateChanges &= ~noBackingCopy;
- if (pPriv->stateChanges)
- CopyGC(pGC, pBackingGC, pPriv->stateChanges);
- if ((pGC->patOrg.x - pWindowPriv->x) != pBackingGC->patOrg.x ||
- (pGC->patOrg.y - pWindowPriv->y) != pBackingGC->patOrg.y)
- {
- XID vals[2];
- vals[0] = pGC->patOrg.x - pWindowPriv->x;
- vals[1] = pGC->patOrg.y - pWindowPriv->y;
- DoChangeGC(pBackingGC, GCTileStipXOrigin|GCTileStipYOrigin, vals, 0);
- }
- pPriv->stateChanges = 0;
-
- if (backingCompositeClip)
- {
- XID vals[2];
-
- if (pGC->clientClipType == CT_PIXMAP)
- {
- (*pBackingGC->funcs->CopyClip)(pBackingGC, pGC);
- REGION_TRANSLATE(pGC->pScreen, backingCompositeClip,
- -pGC->clipOrg.x, -pGC->clipOrg.y);
- vals[0] = pGC->clipOrg.x - pWindowPriv->x;
- vals[1] = pGC->clipOrg.y - pWindowPriv->y;
- DoChangeGC(pBackingGC, GCClipXOrigin|GCClipYOrigin, vals, 0);
- (* pGC->pScreen->BackingStoreFuncs.SetClipmaskRgn)
- (pBackingGC, backingCompositeClip);
- REGION_DESTROY( pGC->pScreen, backingCompositeClip);
- }
- else
- {
- vals[0] = -pWindowPriv->x;
- vals[1] = -pWindowPriv->y;
- DoChangeGC(pBackingGC, GCClipXOrigin|GCClipYOrigin, vals, 0);
- (*pBackingGC->funcs->ChangeClip) (pBackingGC, CT_REGION, backingCompositeClip, 0);
- }
- pPriv->serialNumber = pDrawable->serialNumber;
- }
-
- if (pWindowPriv->pBackingPixmap->drawable.serialNumber
- != pBackingGC->serialNumber)
- {
- ValidateGC((DrawablePtr)pWindowPriv->pBackingPixmap, pBackingGC);
- }
-
- if (pBackingGC->clientClip == 0)
- ErrorF ("backing store clip list nil");
-
- FUNC_EPILOGUE (pGC, pPriv);
-}
-
-static void
-miBSChangeGC (pGC, mask)
- GCPtr pGC;
- unsigned long mask;
-{
- miBSGCPtr pPriv = (miBSGCPtr) (pGC)->devPrivates[miBSGCIndex].ptr;
-
- FUNC_PROLOGUE (pGC, pPriv);
-
- (*pGC->funcs->ChangeGC) (pGC, mask);
-
- FUNC_EPILOGUE (pGC, pPriv);
-}
-
-static void
-miBSCopyGC (pGCSrc, mask, pGCDst)
- GCPtr pGCSrc, pGCDst;
- unsigned long mask;
-{
- miBSGCPtr pPriv = (miBSGCPtr) (pGCDst)->devPrivates[miBSGCIndex].ptr;
-
- FUNC_PROLOGUE (pGCDst, pPriv);
-
- (*pGCDst->funcs->CopyGC) (pGCSrc, mask, pGCDst);
-
- FUNC_EPILOGUE (pGCDst, pPriv);
-}
-
-static void
-miBSDestroyGC (pGC)
- GCPtr pGC;
-{
- miBSGCPtr pPriv = (miBSGCPtr) (pGC)->devPrivates[miBSGCIndex].ptr;
-
- FUNC_PROLOGUE (pGC, pPriv);
-
- if (pPriv->pBackingGC)
- FreeGC(pPriv->pBackingGC, (GContext)0);
-
- (*pGC->funcs->DestroyGC) (pGC);
-
- FUNC_EPILOGUE (pGC, pPriv);
-
- xfree(pPriv);
-}
-
-static void
-miBSChangeClip(pGC, type, pvalue, nrects)
- GCPtr pGC;
- int type;
- pointer pvalue;
- int nrects;
-{
- miBSGCPtr pPriv = (miBSGCPtr) (pGC)->devPrivates[miBSGCIndex].ptr;
-
- FUNC_PROLOGUE (pGC, pPriv);
-
- (* pGC->funcs->ChangeClip)(pGC, type, pvalue, nrects);
-
- FUNC_EPILOGUE (pGC, pPriv);
-}
-
-static void
-miBSCopyClip(pgcDst, pgcSrc)
- GCPtr pgcDst, pgcSrc;
-{
- miBSGCPtr pPriv = (miBSGCPtr) (pgcDst)->devPrivates[miBSGCIndex].ptr;
-
- FUNC_PROLOGUE (pgcDst, pPriv);
-
- (* pgcDst->funcs->CopyClip)(pgcDst, pgcSrc);
-
- FUNC_EPILOGUE (pgcDst, pPriv);
-}
-
-static void
-miBSDestroyClip(pGC)
- GCPtr pGC;
-{
- miBSGCPtr pPriv = (miBSGCPtr) (pGC)->devPrivates[miBSGCIndex].ptr;
-
- FUNC_PROLOGUE (pGC, pPriv);
-
- (* pGC->funcs->DestroyClip)(pGC);
-
- FUNC_EPILOGUE (pGC, pPriv);
-}
-
-static void
-miDestroyBSPixmap (pWin)
- WindowPtr pWin;
-{
- miBSWindowPtr pBackingStore;
- ScreenPtr pScreen;
-
- pScreen = pWin->drawable.pScreen;
- pBackingStore = (miBSWindowPtr) pWin->backStorage;
- if (pBackingStore->pBackingPixmap)
- (* pScreen->DestroyPixmap)(pBackingStore->pBackingPixmap);
- pBackingStore->pBackingPixmap = NullPixmap;
- pBackingStore->x = 0;
- pBackingStore->y = 0;
- if (pBackingStore->backgroundState == BackgroundPixmap)
- (* pScreen->DestroyPixmap)(pBackingStore->background.pixmap);
- pBackingStore->backgroundState = None;
- pBackingStore->status = StatusNoPixmap;
- pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
-}
-
-static void
-miTileVirtualBS (pWin)
- WindowPtr pWin;
-{
- miBSWindowPtr pBackingStore;
-
- pBackingStore = (miBSWindowPtr) pWin->backStorage;
- if (pBackingStore->backgroundState == BackgroundPixmap)
- (* pWin->drawable.pScreen->DestroyPixmap)
- (pBackingStore->background.pixmap);
- pBackingStore->backgroundState = pWin->backgroundState;
- pBackingStore->background = pWin->background;
- if (pBackingStore->backgroundState == BackgroundPixmap)
- pBackingStore->background.pixmap->refcnt++;
-
- if (pBackingStore->status != StatusVDirty)
- pBackingStore->status = StatusVirtual;
-
- /*
- * punt parent relative tiles and do it now
- */
- if (pBackingStore->backgroundState == ParentRelative)
- miCreateBSPixmap (pWin, NullBox);
-}
-
-#ifdef DEBUG
-static int BSAllocationsFailed = 0;
-#define FAILEDSIZE 32
-static struct { int w, h; } failedRecord[FAILEDSIZE];
-static int failedIndex;
-#endif
-
-static void
-miCreateBSPixmap (pWin, pExtents)
- WindowPtr pWin;
- BoxPtr pExtents;
-{
- miBSWindowPtr pBackingStore;
- ScreenPtr pScreen;
- PixUnion background;
- char backgroundState = 0;
- BoxPtr extents;
- Bool backSet;
-
- pScreen = pWin->drawable.pScreen;
- pBackingStore = (miBSWindowPtr) pWin->backStorage;
- if (pBackingStore->status == StatusBadAlloc)
- return;
- backSet = ((pBackingStore->status == StatusVirtual) ||
- (pBackingStore->status == StatusVDirty));
-
- extents = REGION_EXTENTS( pScreen, &pBackingStore->SavedRegion);
-
- if (!pBackingStore->pBackingPixmap &&
- extents->x2 != extents->x1 &&
- extents->y2 != extents->y1)
- {
- /* the policy here could be more sophisticated */
- pBackingStore->x = extents->x1;
- pBackingStore->y = extents->y1;
- pBackingStore->pBackingPixmap =
- (PixmapPtr)(* pScreen->CreatePixmap)
- (pScreen,
- extents->x2 - extents->x1,
- extents->y2 - extents->y1,
- pWin->drawable.depth);
- }
- if (!pBackingStore->pBackingPixmap)
- {
-#ifdef DEBUG
- BSAllocationsFailed++;
- /*
- * record failed allocations
- */
- failedRecord[failedIndex].w = pWin->drawable.width;
- failedRecord[failedIndex].h = pWin->drawable.height;
- failedIndex++;
- if (failedIndex == FAILEDSIZE)
- failedIndex = 0;
-#endif
-#ifdef BSEAGER
- pBackingStore->status = StatusNoPixmap;
-#else
- pBackingStore->status = StatusBadAlloc;
-#endif
- return;
- }
-
- pBackingStore->status = StatusContents;
-
- if (backSet)
- {
- backgroundState = pWin->backgroundState;
- background = pWin->background;
-
- pWin->backgroundState = pBackingStore->backgroundState;
- pWin->background = pBackingStore->background;
- if (pWin->backgroundState == BackgroundPixmap)
- pWin->background.pixmap->refcnt++;
- }
-
- if (!pExtents)
- pExtents = extents;
-
- if (pExtents->y1 != pExtents->y2)
- {
- RegionPtr exposed;
-
- exposed = miBSClearBackingStore(pWin,
- pExtents->x1, pExtents->y1,
- pExtents->x2 - pExtents->x1,
- pExtents->y2 - pExtents->y1,
- !backSet);
- if (exposed)
- {
- miSendExposures(pWin, exposed, pWin->drawable.x, pWin->drawable.y);
- REGION_DESTROY( pScreen, exposed);
- }
- }
-
- if (backSet)
- {
- if (pWin->backgroundState == BackgroundPixmap)
- (* pScreen->DestroyPixmap) (pWin->background.pixmap);
- pWin->backgroundState = backgroundState;
- pWin->background = background;
- if (pBackingStore->backgroundState == BackgroundPixmap)
- (* pScreen->DestroyPixmap) (pBackingStore->background.pixmap);
- pBackingStore->backgroundState = None;
- }
-}
-
-/*-
- *-----------------------------------------------------------------------
- * miBSExposeCopy --
- * Handle the restoration of areas exposed by graphics operations.
- *
- * Results:
- * None.
- *
- * Side Effects:
- * prgnExposed has the areas exposed from backing-store removed
- * from it.
- *
- *-----------------------------------------------------------------------
- */
-static void
-miBSExposeCopy (pSrc, pDst, pGC, prgnExposed, srcx, srcy, dstx, dsty, plane)
- WindowPtr pSrc;
- DrawablePtr pDst;
- GCPtr pGC;
- RegionPtr prgnExposed;
- int srcx, srcy;
- int dstx, dsty;
- unsigned long plane;
-{
- RegionRec tempRgn;
- miBSWindowPtr pBackingStore;
- CopyPlaneProcPtr copyProc;
- GCPtr pScratchGC;
- BoxPtr pBox;
- int i;
- int dx, dy;
- BITS32 gcMask;
-
- if (!REGION_NOTEMPTY(pGC->pScreen, prgnExposed))
- return;
- pBackingStore = (miBSWindowPtr)pSrc->backStorage;
-
- if ((pBackingStore->status == StatusNoPixmap) ||
- (pBackingStore->status == StatusBadAlloc))
- return;
-
- REGION_NULL( pGC->pScreen, &tempRgn);
- REGION_INTERSECT( pGC->pScreen, &tempRgn, prgnExposed,
- &pBackingStore->SavedRegion);
- REGION_SUBTRACT( pGC->pScreen, prgnExposed, prgnExposed, &tempRgn);
-
- if (plane != 0) {
- copyProc = pGC->ops->CopyPlane;
- } else {
- copyProc = (CopyPlaneProcPtr)pGC->ops->CopyArea;
- }
-
- dx = dstx - srcx;
- dy = dsty - srcy;
-
- switch (pBackingStore->status) {
- case StatusVirtual:
- case StatusVDirty:
- pScratchGC = GetScratchGC (pDst->depth, pDst->pScreen);
- if (pScratchGC)
- {
- gcMask = 0;
- if (pGC->alu != pScratchGC->alu)
- gcMask = GCFunction;
- if (pGC->planemask != pScratchGC->planemask)
- gcMask |= GCPlaneMask;
- if (gcMask)
- CopyGC (pGC, pScratchGC, gcMask);
- miBSFillVirtualBits (pDst, pScratchGC, &tempRgn, dx, dy,
- (int) pBackingStore->backgroundState,
- pBackingStore->background,
- ~0L);
- FreeScratchGC (pScratchGC);
- }
- break;
- case StatusContents:
- for (i = REGION_NUM_RECTS(&tempRgn), pBox = REGION_RECTS(&tempRgn);
- --i >= 0;
- pBox++)
- {
- (* copyProc) (&(pBackingStore->pBackingPixmap->drawable), pDst, pGC,
- pBox->x1 - pBackingStore->x,
- pBox->y1 - pBackingStore->y,
- pBox->x2 - pBox->x1, pBox->y2 - pBox->y1,
- pBox->x1 + dx, pBox->y1 + dy, plane);
- }
- break;
- }
- REGION_UNINIT( pGC->pScreen, &tempRgn);
+_X_EXPORT void
+miInitializeBackingStore (ScreenPtr pScreen)
+{
+ pScreen->SaveDoomedAreas = NULL;
+ pScreen->RestoreAreas = NULL;
+ pScreen->ExposeCopy = NULL;
+ pScreen->TranslateBackingStore = NULL;
+ pScreen->ClearBackingStore = NULL;
+ pScreen->DrawGuarantee = NULL;
}