]> git.sesse.net Git - rdpsrv/blobdiff - Xserver/programs/Xserver/mi/mibstore.c
Removed Xserver/ directory, it does nothing useful ATM.
[rdpsrv] / Xserver / programs / Xserver / mi / mibstore.c
diff --git a/Xserver/programs/Xserver/mi/mibstore.c b/Xserver/programs/Xserver/mi/mibstore.c
deleted file mode 100644 (file)
index 935f758..0000000
+++ /dev/null
@@ -1,3824 +0,0 @@
-/* $XConsortium: mibstore.c,v 5.63 94/10/21 20:25:08 dpw Exp $ */
-/***********************************************************
-
-Copyright (c) 1987  X Consortium
-
-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 the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-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
-X CONSORTIUM 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 X Consortium 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 X Consortium.
-
-
-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 X Consortium 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
-#include "X.h"
-#include "Xmd.h"
-#include "Xproto.h"
-#include "misc.h"
-#include "regionstr.h"
-#include "scrnintstr.h"
-#include "gcstruct.h"
-#include "extnsionst.h"
-#include "windowstr.h"
-#include "pixmapstr.h"
-#include "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();
-static void        miDestroyBSPixmap();
-static void        miTileVirtualBS();
-static void        miBSAllocate(), miBSFree();
-static Bool        miBSCreateGCPrivate ();
-static void        miBSClearBackingRegion ();
-
-#define MoreCopy0 ;
-#define MoreCopy2 *dstCopy++ = *srcCopy++; *dstCopy++ = *srcCopy++;
-#define MoreCopy4 MoreCopy2 MoreCopy2
-
-#define copyData(src,dst,n,morecopy) \
-{ \
-    register short *srcCopy = (short *)(src); \
-    register short *dstCopy = (short *)(dst); \
-    register int i; \
-    register int bsx = pBackingStore->x; \
-    register 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();
-static void        miBSGetImage();
-static void        miBSGetSpans();
-static Bool        miBSChangeWindowAttributes();
-static Bool        miBSCreateGC();
-static Bool        miBSDestroyWindow();
-
-/*
- * backing store screen functions
- */
-
-static void        miBSSaveDoomedAreas();
-static RegionPtr    miBSRestoreAreas();
-static void        miBSExposeCopy();
-static RegionPtr    miBSTranslateBackingStore(), miBSClearBackingStore();
-static void        miBSDrawGuarantee();
-
-/*
- * wrapper vectors for GC funcs and ops
- */
-
-static int  miBSGCIndex;
-
-static void miBSValidateGC (), miBSCopyGC (),      miBSDestroyGC();
-static void miBSChangeGC();
-static void miBSChangeClip(),  miBSDestroyClip(),  miBSCopyClip();
-
-static GCFuncs miBSGCFuncs = {
-    miBSValidateGC,
-    miBSChangeGC,
-    miBSCopyGC,
-    miBSDestroyGC,
-    miBSChangeClip,
-    miBSDestroyClip,
-    miBSCopyClip,
-};
-
-static void        miBSFillSpans(),    miBSSetSpans(),     miBSPutImage();
-static RegionPtr    miBSCopyArea(),    miBSCopyPlane();
-static void        miBSPolyPoint(),    miBSPolylines(),    miBSPolySegment();
-static void        miBSPolyRectangle(),miBSPolyArc(),      miBSFillPolygon();
-static void        miBSPolyFillRect(), miBSPolyFillArc();
-static int         miBSPolyText8(),    miBSPolyText16();
-static void        miBSImageText8(),   miBSImageText16();
-static void        miBSImageGlyphBlt(),miBSPolyGlyphBlt();
-static void        miBSPushPixels();
-#ifdef NEED_LINEHELPER
-static void        miBSLineHelper();
-#endif
-
-static GCOps miBSGCOps = {
-    miBSFillSpans,     miBSSetSpans,       miBSPutImage,       
-    miBSCopyArea,      miBSCopyPlane,      miBSPolyPoint,
-    miBSPolylines,     miBSPolySegment,    miBSPolyRectangle,
-    miBSPolyArc,       miBSFillPolygon,    miBSPolyFillRect,
-    miBSPolyFillArc,   miBSPolyText8,      miBSPolyText16,
-    miBSImageText8,    miBSImageText16,    miBSImageGlyphBlt,
-    miBSPolyGlyphBlt,  miBSPushPixels
-#ifdef NEED_LINEHELPER
-    , miBSLineHelper
-#endif
-};
-
-#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(),  miBSCheapCopyGC(), miBSCheapDestroyGC();
-static void miBSCheapChangeGC ();
-static void miBSCheapChangeClip(),  miBSCheapDestroyClip();
-static void miBSCheapCopyClip();
-
-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
- */
-
-void
-miInitializeBackingStore (pScreen, funcs)
-    ScreenPtr  pScreen;
-    miBSFuncPtr        funcs;
-{
-    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;
-    pScreenPriv->funcs = funcs;
-
-    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();
-
-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;
-       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_INIT(pScreen, &Border, NullBox, 0);
-                   REGION_INIT(pScreen, &Inside, NullBox, 0);
-                   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 (pGC)
-    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;
-    register 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);
-}
-
-/*-
- *-----------------------------------------------------------------------
- * 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(pWin, pGC, srcx, srcy, w, h, dstx, dsty, plane, copyProc, ppRgn)
-    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) */
-    RegionPtr            (*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 */
-    register int       i, j, k, l, y;
-    register BoxPtr    pBox;
-    int                        dx, dy, nrects;
-    Bool               graphicsExposures;
-    RegionPtr          (*pixCopyProc)();
-    int                        numRectsExp, numRectsObs;
-    BoxPtr             pBoxExp, pBoxObs;
-
-    SETUP_BACKING (pWin, pGC);
-
-    /*
-     * 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 = 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, 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, 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, pWin, 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, 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;
-    register 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;
-    register GCPtr     pGC;
-    int                        shape, mode;
-    register 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);
-}
-
-#ifdef NEED_LINEHELPER
-/*-
- *-----------------------------------------------------------------------
- * miBSLineHelper --
- *
- * Results: should never be called
- *
- * Side Effects: server dies
- *
- *-----------------------------------------------------------------------
- */
-static void
-miBSLineHelper()
-{
-    FatalError("miBSLineHelper called\n");
-}
-#endif
-
-/*-
- *-----------------------------------------------------------------------
- * 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)(ts_x_origin - pBackingStore->x);
-               gcvalues[3] = (pointer)(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)x;
-           gcmask |= GCTileStipXOrigin;
-       }
-       if (pGC->patOrg.y != y)
-       {
-           gcval[i++] = (pointer)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;
-{
-    register miBSWindowPtr  pBackingStore;
-    register 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_INIT( pScreen, &pBackingStore->SavedRegion, NullBox, 1);
-       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;
-    register ScreenPtr 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(pWin, dx, dy, saveBits)
-    WindowPtr  pWin;
-    int                dx, 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)
-       {
-           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)
-    register 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)
-       {
-           miBSScreenPtr       pScreenPriv;
-
-           pScreenPriv = (miBSScreenPtr) pScreen->devPrivates[miBSScreenIndex].ptr;
-           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;
-               }
-               (* pScreenPriv->funcs->SaveAreas) (pBackingStore->pBackingPixmap,
-                                                  pObscured, x - dx, y - dy, pWin);
-           }
-       }
-       REGION_TRANSLATE(pScreen, pObscured, x, y);
-    }
-}
-
-/*-
- *-----------------------------------------------------------------------
- * 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)
-    register WindowPtr pWin;
-    RegionPtr prgnExposed;
-{
-    PixmapPtr pBackingPixmap;
-    miBSWindowPtr pBackingStore;
-    RegionPtr prgnSaved;
-    RegionPtr prgnRestored;
-    register 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))
-       {
-           miBSScreenPtr       pScreenPriv;
-
-           REGION_SUBTRACT( pScreen, prgnSaved, prgnSaved, prgnExposed);
-           REGION_SUBTRACT( pScreen, prgnExposed, prgnExposed, prgnRestored);
-
-           /*
-            * Do the actual restoration
-            */
-
-           pScreenPriv = (miBSScreenPtr)
-               pScreen->devPrivates[miBSScreenIndex].ptr;
-           (* pScreenPriv->funcs->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:
- *
- *     It's called from SlideAndSizeWindow whenever a window
- *     with backing store is resized.  There are two separate
- *     possibilities:
- *
- *     a)  The window has ForgetGravity
- *
- *         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.
- *-----------------------------------------------------------------------
- */
-
-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;
-{
-    register miBSWindowPtr     pBackingStore;
-    register RegionPtr                 pSavedRegion;
-    register RegionPtr                 newSaved, doomed;
-    register 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));
-    }
-#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;
-}
-
-/*
- * 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
- *
- * 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.
- *-----------------------------------------------------------------------
- */
-
-static void
-miBSValidateGC (pGC, stateChanges, pDrawable)
-    GCPtr        pGC;
-    unsigned long stateChanges;
-    DrawablePtr   pDrawable;
-{
-    GCPtr              pBackingGC;
-    miBSWindowPtr      pWindowPriv;
-    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);
-       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)
-       {
-           miBSScreenPtr   pScreenPriv;
-
-           (*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);
-           pScreenPriv = (miBSScreenPtr) 
-               pGC->pScreen->devPrivates[miBSScreenIndex].ptr;
-           (* pScreenPriv->funcs->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;
-    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)
-    {
-       /* 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;
-    RegionPtr          (*copyProc)();
-    GCPtr              pScratchGC;
-    register BoxPtr    pBox;
-    register int       i;
-    register 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_INIT( pGC->pScreen, &tempRgn, NullBox, 0);
-    REGION_INTERSECT( pGC->pScreen, &tempRgn, prgnExposed,
-                                &pBackingStore->SavedRegion);
-    REGION_SUBTRACT( pGC->pScreen, prgnExposed, prgnExposed, &tempRgn);
-
-    if (plane != 0) {
-       copyProc = pGC->ops->CopyPlane;
-    } else {
-       copyProc = 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, 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);
-}