[PATCH] Remove mibank wrapper

Adam Jackson ajax at redhat.com
Mon Jan 4 12:32:49 PST 2010


Banked framebuffers are so 1990.  As of 7.4 the only drivers remaining
that used this were chips, neomagic, trident, and vesa.  vesa only used
it when not using shadowfb, which is broadly undesirable anyway, and no
longer uses it at all as of 2.3.0.  neomagic never used it by default,
and support for it is gone in git master.  The other two effectively
only ever used it for ISA chips; since ISA support is now gone from
the server, they have been modified to only compile mibank support when
ISA support is available.

Signed-off-by: Adam Jackson <ajax at redhat.com>
---
 hw/xfree86/common/xf86Mode.c   |  126 +++-
 hw/xfree86/common/xf86RandR.c  |    1 -
 hw/xfree86/modes/xf86RandR12.c |    1 -
 mi/Makefile.am                 |    4 +-
 mi/mibank.c                    | 2314 ----------------------------------------
 mi/mibank.h                    |  112 --
 6 files changed, 126 insertions(+), 2432 deletions(-)
 delete mode 100644 mi/mibank.c
 delete mode 100644 mi/mibank.h

diff --git a/hw/xfree86/common/xf86Mode.c b/hw/xfree86/common/xf86Mode.c
index 4a948d7..16627b6 100644
--- a/hw/xfree86/common/xf86Mode.c
+++ b/hw/xfree86/common/xf86Mode.c
@@ -42,7 +42,6 @@
 #include "xf86Modes.h"
 #include "os.h"
 #include "servermd.h"
-#include "mibank.h"
 #include "globals.h"
 #include "xf86.h"
 #include "xf86Priv.h"
@@ -1128,6 +1127,131 @@ found:
     return 1;
 }
 
+/* Least common multiple */
+static unsigned int
+miLCM(unsigned int x, unsigned int y)
+{
+    unsigned int m = x, n = y, o;
+
+    while ((o = m % n))
+    {
+        m = n;
+        n = o;
+    }
+
+    return (x / n) * y;
+}
+
+/*
+ * Given various screen attributes, determine the minimum scanline width such
+ * that each scanline is server and DDX padded and any pixels with imbedded
+ * bank boundaries are off-screen.  This function returns -1 if such a width
+ * cannot exist.
+ */
+static int
+miScanLineWidth(
+    unsigned int     xsize,         /* pixels */
+    unsigned int     ysize,         /* pixels */
+    unsigned int     width,         /* pixels */
+    unsigned long    BankSize,      /* char's */
+    PixmapFormatRec *pBankFormat,
+    unsigned int     nWidthUnit     /* bits */
+)
+{
+    unsigned long nBitsPerBank, nBitsPerScanline, nBitsPerScanlinePadUnit;
+    unsigned long minBitsPerScanline, maxBitsPerScanline;
+
+    /* Sanity checks */
+
+    if (!nWidthUnit || !pBankFormat)
+        return -1;
+
+    nBitsPerBank = BankSize * 8;
+    if (nBitsPerBank % pBankFormat->scanlinePad)
+        return -1;
+
+    if (xsize > width)
+        width = xsize;
+    nBitsPerScanlinePadUnit = miLCM(pBankFormat->scanlinePad, nWidthUnit);
+    nBitsPerScanline =
+        (((width * pBankFormat->bitsPerPixel) + nBitsPerScanlinePadUnit - 1) /
+         nBitsPerScanlinePadUnit) * nBitsPerScanlinePadUnit;
+    width = nBitsPerScanline / pBankFormat->bitsPerPixel;
+
+    if (!xsize || !(nBitsPerBank % pBankFormat->bitsPerPixel))
+        return (int)width;
+
+    /*
+     * Scanlines will be server-pad aligned at this point.  They will also be
+     * a multiple of nWidthUnit bits long.  Ensure that pixels with imbedded
+     * bank boundaries are off-screen.
+     *
+     * It seems reasonable to limit total frame buffer size to 1/16 of the
+     * theoretical maximum address space size.  On a machine with 32-bit
+     * addresses (to 8-bit quantities) this turns out to be 256MB.  Not only
+     * does this provide a simple limiting condition for the loops below, but
+     * it also prevents unsigned long wraparounds.
+     */
+    if (!ysize)
+        return -1;
+
+    minBitsPerScanline = xsize * pBankFormat->bitsPerPixel;
+    if (minBitsPerScanline > nBitsPerBank)
+        return -1;
+
+    if (ysize == 1)
+        return (int)width;
+
+    maxBitsPerScanline =
+        (((unsigned long)(-1) >> 1) - minBitsPerScanline) / (ysize - 1);
+    while (nBitsPerScanline <= maxBitsPerScanline)
+    {
+        unsigned long BankBase, BankUnit;
+
+        BankUnit = ((nBitsPerBank + nBitsPerScanline - 1) / nBitsPerBank) *
+            nBitsPerBank;
+        if (!(BankUnit % nBitsPerScanline))
+            return (int)width;
+
+        for (BankBase = BankUnit;  ;  BankBase += nBitsPerBank)
+        {
+            unsigned long x, y;
+
+            y = BankBase / nBitsPerScanline;
+            if (y >= ysize)
+                return (int)width;
+
+            x = BankBase % nBitsPerScanline;
+            if (!(x % pBankFormat->bitsPerPixel))
+                continue;
+
+            if (x < minBitsPerScanline)
+            {
+                /*
+                 * Skip ahead certain widths by dividing the excess scanline
+                 * amongst the y's.
+                 */
+                y *= nBitsPerScanlinePadUnit;
+                nBitsPerScanline +=
+                    ((x + y - 1) / y) * nBitsPerScanlinePadUnit;
+                width = nBitsPerScanline / pBankFormat->bitsPerPixel;
+                break;
+            }
+
+            if (BankBase != BankUnit)
+                continue;
+
+            if (!(nBitsPerScanline % x))
+                return (int)width;
+
+            BankBase = ((nBitsPerScanline - minBitsPerScanline) /
+                (nBitsPerScanline - x)) * BankUnit;
+        }
+    }
+
+    return -1;
+}
+
 /*
  * xf86ValidateModes
  *
diff --git a/hw/xfree86/common/xf86RandR.c b/hw/xfree86/common/xf86RandR.c
index 02dcc34..841fb1d 100644
--- a/hw/xfree86/common/xf86RandR.c
+++ b/hw/xfree86/common/xf86RandR.c
@@ -27,7 +27,6 @@
 
 #include <X11/X.h>
 #include "os.h"
-#include "mibank.h"
 #include "globals.h"
 #include "xf86.h"
 #include "xf86str.h"
diff --git a/hw/xfree86/modes/xf86RandR12.c b/hw/xfree86/modes/xf86RandR12.c
index 1fc63c4..4e312c0 100644
--- a/hw/xfree86/modes/xf86RandR12.c
+++ b/hw/xfree86/modes/xf86RandR12.c
@@ -30,7 +30,6 @@
 
 #include "xf86.h"
 #include "os.h"
-#include "mibank.h"
 #include "globals.h"
 #include "xf86.h"
 #include "xf86Priv.h"
diff --git a/mi/Makefile.am b/mi/Makefile.am
index 9714a21..f22dde9 100644
--- a/mi/Makefile.am
+++ b/mi/Makefile.am
@@ -1,7 +1,7 @@
 noinst_LTLIBRARIES = libmi.la
 
 if XORG
-sdk_HEADERS = mibank.h micmap.h miline.h mipointer.h mi.h mibstore.h \
+sdk_HEADERS = micmap.h miline.h mipointer.h mi.h mibstore.h \
               migc.h mipointrst.h mizerarc.h micoord.h mifillarc.h \
               mispans.h miwideline.h mistruct.h mifpoly.h mioverlay.h
 endif
@@ -11,8 +11,6 @@ AM_CFLAGS = $(DIX_CFLAGS)
 libmi_la_SOURCES = 	\
 	mi.h		\
 	miarc.c		\
-	mibank.c	\
-	mibank.h	\
 	mibitblt.c	\
 	mibstore.c	\
 	mibstore.h	\
diff --git a/mi/mibank.c b/mi/mibank.c
deleted file mode 100644
index 9e4d631..0000000
--- a/mi/mibank.c
+++ /dev/null
@@ -1,2314 +0,0 @@
-/*
- * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that copyright
- * notice and this permission notice appear in supporting documentation, and
- * that the name of Marc Aurele La France not be used in advertising or
- * publicity pertaining to distribution of the software without specific,
- * written prior permission.  Marc Aurele La France makes no representations
- * about the suitability of this software for any purpose.  It is provided
- * "as-is" without express or implied warranty.
- *
- * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.  IN NO
- * EVENT SHALL MARC AURELE LA FRANCE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/*
- * Copyright 1990,91,92,93 by Thomas Roell, Germany.
- * Copyright 1991,92,93    by SGCS (Snitily Graphics Consulting Services), USA.
- *
- * Permission to use, copy, modify, distribute, and sell this software
- * and its documentation for any purpose is hereby granted without fee,
- * provided that the above copyright notice appear in all copies and
- * that both that copyright notice and this  permission notice appear
- * in supporting documentation, and that the name of Thomas Roell nor
- * SGCS be used in advertising or publicity pertaining to distribution
- * of the software without specific, written prior permission.
- * Thomas Roell nor SGCS makes no representations about the suitability
- * of this software for any purpose. It is provided "as is" without
- * express or implied warranty.
- *
- * THOMAS ROELL AND SGCS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
- * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS, IN NO EVENT SHALL THOMAS ROELL OR SGCS BE LIABLE FOR ANY
- * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
- * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
- * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-
-/*
- * This thing originated from an idea of Edwin Goei and his bank switching
- * code for the DEC TX board.
- */
-
-/*
- * Heavily modified for the XFree86 Project to turn this into an mi wrapper.
- * ---  Marc Aurele La France (tsi at xfree86.org)
- */
-
-/*
- * "Heavily modified", indeed!  By the time this is finalized, there probably
- * won't be much left of Roell's code...
- *
- * Miscellaneous notes:
- * - Pixels with imbedded bank boundaries are required to be off-screen.  There
- *   >might< be a way to fool the underlying framebuffer into dealing with
- *   partial pixels.
- * - Plans to generalise this to do (hardware) colour plane switching have been
- *   dropped due to colour flashing concerns.
- *
- * TODO:
- * - Re-instate shared and double banking for framebuffers whose pixmap formats
- *   don't describe how the server "sees" the screen.
- * - Remove remaining assumptions that a pixmap's devPrivate field points
- *   directly to its pixel data.
- */
-
-/* #define NO_ALLOCA 1 */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include "servermd.h"
-#include "gcstruct.h"
-#include "pixmapstr.h"
-#include "scrnintstr.h"
-#include "windowstr.h"
-#include "mi.h"
-#include "mibank.h"
-
-#define BANK_SINGLE 0
-#define BANK_SHARED 1
-#define BANK_DOUBLE 2
-#define BANK_NOBANK 3
-
-typedef struct _miBankScreen
-{
-    miBankInfoRec BankInfo;
-    unsigned int  nBankBPP;
-    unsigned int  type;
-
-    unsigned long nBitsPerBank;
-    unsigned long nBitsPerScanline;
-    unsigned long nPixelsPerScanlinePadUnit;
-
-    PixmapPtr     pScreenPixmap;
-    PixmapPtr     pBankPixmap;
-    GCPtr         pBankGC;
-
-    int           nBanks, maxRects;
-    RegionPtr     *pBanks;
-
-    pointer       pbits;
-
-    /*
-     * Screen Wrappers
-     */
-    CreateScreenResourcesProcPtr  CreateScreenResources;
-    ModifyPixmapHeaderProcPtr     ModifyPixmapHeader;
-    CloseScreenProcPtr            CloseScreen;
-    GetImageProcPtr               GetImage;
-    GetSpansProcPtr               GetSpans;
-    CreateGCProcPtr               CreateGC;
-    CopyWindowProcPtr             CopyWindow;
-} miBankScreenRec, *miBankScreenPtr;
-
-typedef struct _miBankGC
-{
-    GCOps     *wrappedOps,   *unwrappedOps;
-    GCFuncs   *wrappedFuncs, *unwrappedFuncs;
-
-    Bool      fastCopy, fastPlane;
-
-    RegionPtr pBankedClips[1];
-} miBankGCRec, *miBankGCPtr;
-
-typedef struct _miBankQueue
-{
-    Bool           fastBlit;
-    unsigned short srcBankNo;
-    unsigned short dstBankNo;
-    short          x;
-    short          y;
-    short          w;
-    short          h;
-} miBankQueue;
-
-/*
- * CAVEAT:  This banking scheme requires that the DDX store Pixmap data in the
- *          server's address space.
- */
-
-#define ModifyPixmap(_pPix, _width, _devKind, _pbits) \
-    (*pScreen->ModifyPixmapHeader)((_pPix), \
-        (_width), -1, -1, -1, (_devKind), (_pbits))
-
-#define SET_SINGLE_BANK(_pPix, _width, _devKind, _no) \
-    ModifyPixmap(_pPix, _width, _devKind, \
-        (char *)pScreenPriv->BankInfo.pBankA + \
-        (*pScreenPriv->BankInfo.SetSourceAndDestinationBanks)(pScreen, (_no)) - \
-        (pScreenPriv->BankInfo.BankSize * (_no)))
-
-#define SET_SOURCE_BANK(_pPix, _width, _devKind, _no) \
-    ModifyPixmap(_pPix, _width, _devKind, \
-        (char *)pScreenPriv->BankInfo.pBankA + \
-        (*pScreenPriv->BankInfo.SetSourceBank)(pScreen, (_no)) - \
-        (pScreenPriv->BankInfo.BankSize * (_no)))
-
-#define SET_DESTINATION_BANK(_pPix, _width, _devKind, _no) \
-    ModifyPixmap(_pPix, _width, _devKind, \
-        (char *)pScreenPriv->BankInfo.pBankB + \
-        (*pScreenPriv->BankInfo.SetDestinationBank)(pScreen, (_no)) - \
-        (pScreenPriv->BankInfo.BankSize * (_no)))
-
-#define xalloc_ARRAY(atype, ntype) xalloc((ntype) * sizeof(atype))
-
-static int miBankScreenKeyIndex;
-static DevPrivateKey miBankScreenKey = &miBankScreenKeyIndex;
-static int miBankGCKeyIndex;
-static DevPrivateKey miBankGCKey = &miBankGCKeyIndex;
-
-static unsigned long miBankGeneration = 0;
-
-#define BANK_SCRPRIVLVAL dixLookupPrivate(&pScreen->devPrivates, miBankScreenKey)
-
-#define BANK_SCRPRIVATE ((miBankScreenPtr)(BANK_SCRPRIVLVAL))
-
-#define BANK_GCPRIVLVAL(pGC) dixLookupPrivate(&(pGC)->devPrivates, miBankGCKey)
-
-#define BANK_GCPRIVATE(pGC) ((miBankGCPtr)(BANK_GCPRIVLVAL(pGC)))
-
-#define PIXMAP_STATUS(_pPix) \
-    pointer pbits = (_pPix)->devPrivate.ptr
-
-#define PIXMAP_SAVE(_pPix) \
-    PIXMAP_STATUS(_pPix); \
-    if (pbits == (pointer)pScreenPriv) \
-        (_pPix)->devPrivate.ptr = pScreenPriv->pbits
-
-#define PIXMAP_RESTORE(_pPix) \
-    (_pPix)->devPrivate.ptr = pbits
-
-#define BANK_SAVE \
-    int width   = pScreenPriv->pBankPixmap->drawable.width; \
-    int devKind = pScreenPriv->pBankPixmap->devKind; \
-    PIXMAP_SAVE(pScreenPriv->pBankPixmap)
-
-#define BANK_RESTORE \
-    pScreenPriv->pBankPixmap->drawable.width = width; \
-    pScreenPriv->pBankPixmap->devKind = devKind; \
-    PIXMAP_RESTORE(pScreenPriv->pBankPixmap)
-
-#define SCREEN_STATUS \
-    PIXMAP_STATUS(pScreenPriv->pScreenPixmap)
-
-#define SCREEN_SAVE \
-    PIXMAP_SAVE(pScreenPriv->pScreenPixmap)
-
-#define SCREEN_RESTORE \
-    PIXMAP_RESTORE(pScreenPriv->pScreenPixmap)
-
-#define SCREEN_INIT \
-    miBankScreenPtr pScreenPriv = BANK_SCRPRIVATE
-
-#define SCREEN_UNWRAP(field) \
-    pScreen->field = pScreenPriv->field
-
-#define SCREEN_WRAP(field, wrapper) \
-    pScreenPriv->field = pScreen->field; \
-    pScreen->field     = wrapper
-
-#define GC_INIT(pGC) \
-    miBankGCPtr pGCPriv = BANK_GCPRIVATE(pGC)
-
-#define GC_UNWRAP(pGC) \
-    pGCPriv->unwrappedOps   = (pGC)->ops; \
-    pGCPriv->unwrappedFuncs = (pGC)->funcs; \
-    (pGC)->ops              = pGCPriv->wrappedOps; \
-    (pGC)->funcs            = pGCPriv->wrappedFuncs
-
-#define GC_WRAP(pGC) \
-    pGCPriv->wrappedOps   = (pGC)->ops; \
-    pGCPriv->wrappedFuncs = (pGC)->funcs; \
-    (pGC)->ops            = pGCPriv->unwrappedOps; \
-    (pGC)->funcs          = pGCPriv->unwrappedFuncs
-
-#define IS_BANKED(pDrawable) \
-    ((pbits == (pointer)pScreenPriv) && \
-     (((DrawablePtr)(pDrawable))->type == DRAWABLE_WINDOW))
-
-#define CLIP_SAVE \
-    RegionPtr pOrigCompositeClip = pGC->pCompositeClip
-
-#define CLIP_RESTORE \
-    pGC->pCompositeClip = pOrigCompositeClip
-
-#define GCOP_INIT \
-    ScreenPtr pScreen = pGC->pScreen; \
-    SCREEN_INIT; \
-    GC_INIT(pGC)
-
-#define GCOP_UNWRAP \
-    GC_UNWRAP(pGC)
-
-#define GCOP_WRAP \
-    GC_WRAP(pGC)
-
-#define GCOP_TOP_PART \
-    for (i = 0;  i < pScreenPriv->nBanks;  i++) \
-    { \
-        if (!(pGC->pCompositeClip = pGCPriv->pBankedClips[i])) \
-            continue; \
-        GCOP_UNWRAP; \
-        SET_SINGLE_BANK(pScreenPriv->pScreenPixmap, -1, -1, i)
-
-#define GCOP_BOTTOM_PART \
-        GCOP_WRAP; \
-    }
-
-#define GCOP_SIMPLE(statement) \
-    if (nArray > 0) \
-    { \
-        GCOP_INIT; \
-        SCREEN_SAVE; \
-        if (!IS_BANKED(pDrawable)) \
-        { \
-            GCOP_UNWRAP; \
-            statement; \
-            GCOP_WRAP; \
-        } \
-        else \
-        { \
-            int i; \
-            CLIP_SAVE; \
-            GCOP_TOP_PART; \
-            statement; \
-            GCOP_BOTTOM_PART; \
-            CLIP_RESTORE; \
-        } \
-        SCREEN_RESTORE; \
-    }
-
-#define GCOP_0D_ARGS mode,
-#define GCOP_1D_ARGS
-#define GCOP_2D_ARGS shape, mode,
-
-#define GCOP_COMPLEX(aop, atype) \
-    if (nArray > 0) \
-    { \
-        GCOP_INIT; \
-        SCREEN_SAVE; \
-        if (!IS_BANKED(pDrawable)) \
-        { \
-            GCOP_UNWRAP; \
-            (*pGC->ops->aop)(pDrawable, pGC, GCOP_ARGS nArray, pArray); \
-            GCOP_WRAP; \
-        } \
-        else \
-        { \
-            atype *aarg = pArray, *acopy; \
-            int   i; \
-            CLIP_SAVE; \
-            if ((acopy = xalloc_ARRAY(atype, nArray))) \
-                aarg = acopy; \
-            GCOP_TOP_PART; \
-            if (acopy) \
-                memcpy(acopy, pArray, nArray * sizeof(atype)); \
-            (*pGC->ops->aop)(pDrawable, pGC, GCOP_ARGS nArray, aarg); \
-            GCOP_BOTTOM_PART; \
-            xfree(acopy); \
-            CLIP_RESTORE; \
-        } \
-        SCREEN_RESTORE; \
-    }
-
-/*********************
- * Utility functions *
- *********************/
-
-static int
-miBankOf(
-    miBankScreenPtr pScreenPriv,
-    int             x,
-    int             y
-)
-{
-    int iBank = ((x * (int)pScreenPriv->nBankBPP) +
-                 (y * (long)pScreenPriv->nBitsPerScanline)) /
-                (long)pScreenPriv->nBitsPerBank;
-
-    if (iBank < 0)
-        iBank = 0;
-    else if (iBank >= pScreenPriv->nBanks)
-        iBank = pScreenPriv->nBanks - 1;
-
-    return iBank;
-}
-
-#define FirstBankOf(_x, _y) miBankOf(pScreenPriv, (_x), (_y))
-#define  LastBankOf(_x, _y) miBankOf(pScreenPriv, (_x) - 1, (_y))
-
-/* Determine banking type from the BankInfoRec */
-static unsigned int
-miBankDeriveType(
-    ScreenPtr     pScreen,
-    miBankInfoPtr pBankInfo
-)
-{
-    unsigned int type;
-
-    if (pBankInfo->pBankA == pBankInfo->pBankB)
-    {
-        if (pBankInfo->SetSourceBank == pBankInfo->SetDestinationBank)
-        {
-            if (pBankInfo->SetSourceAndDestinationBanks !=
-                pBankInfo->SetSourceBank)
-                return BANK_NOBANK;
-
-            type = BANK_SINGLE;
-        }
-        else
-        {
-            if (pBankInfo->SetSourceAndDestinationBanks ==
-                pBankInfo->SetDestinationBank)
-                return BANK_NOBANK;
-            if (pBankInfo->SetSourceAndDestinationBanks ==
-                pBankInfo->SetSourceBank)
-                return BANK_NOBANK;
-
-            type = BANK_SHARED;
-        }
-    }
-    else
-    {
-        if ((unsigned long)abs((char *)pBankInfo->pBankA -
-                               (char *)pBankInfo->pBankB) < pBankInfo->BankSize)
-            return BANK_NOBANK;
-
-        if (pBankInfo->SetSourceBank == pBankInfo->SetDestinationBank)
-        {
-            if (pBankInfo->SetSourceAndDestinationBanks !=
-                pBankInfo->SetSourceBank)
-                return BANK_NOBANK;
-        }
-        else
-        {
-            if (pBankInfo->SetSourceAndDestinationBanks ==
-                pBankInfo->SetDestinationBank)
-                return BANK_NOBANK;
-        }
-
-        type = BANK_DOUBLE;
-    }
-
-    /*
-     * Internal limitation:  Currently, only single banking is supported when
-     * the pixmap format and the screen's pixel format are different.  The
-     * following test is only partially successful at detecting this condition.
-     */
-    if (pBankInfo->nBankDepth != pScreen->rootDepth)
-        type = BANK_SINGLE;
-
-    return type;
-}
-
-/* Least common multiple */
-static unsigned int
-miLCM(
-    unsigned int x,
-    unsigned int y
-)
-{
-    unsigned int m = x, n = y, o;
-
-    while ((o = m % n))
-    {
-        m = n;
-        n = o;
-    }
-
-    return (x / n) * y;
-}
-
-/******************
- * GCOps wrappers *
- ******************/
-
-static void
-miBankFillSpans(
-    DrawablePtr pDrawable,
-    GCPtr       pGC,
-    int         nArray,
-    DDXPointPtr pptInit,
-    int         *pwidthInit,
-    int         fSorted
-)
-{
-    GCOP_SIMPLE((*pGC->ops->FillSpans)(pDrawable, pGC,
-        nArray, pptInit, pwidthInit, fSorted));
-}
-
-static void
-miBankSetSpans(
-    DrawablePtr pDrawable,
-    GCPtr       pGC,
-    char        *psrc,
-    DDXPointPtr ppt,
-    int         *pwidth,
-    int         nArray,
-    int         fSorted
-)
-{
-    GCOP_SIMPLE((*pGC->ops->SetSpans)(pDrawable, pGC, psrc,
-        ppt, pwidth, nArray, fSorted));
-}
-
-static void
-miBankPutImage(
-    DrawablePtr pDrawable,
-    GCPtr       pGC,
-    int         depth,
-    int         x,
-    int         y,
-    int         w,
-    int         h,
-    int         leftPad,
-    int         format,
-    char        *pImage
-)
-{
-    if ((w > 0) && (h > 0))
-    {
-        GCOP_INIT;
-        SCREEN_SAVE;
-
-        if (!IS_BANKED(pDrawable))
-        {
-            GCOP_UNWRAP;
-
-            (*pGC->ops->PutImage)(pDrawable, pGC, depth, x, y, w, h,
-                leftPad, format, pImage);
-
-            GCOP_WRAP;
-        }
-        else
-        {
-            int i, j;
-
-            CLIP_SAVE;
-
-            i = FirstBankOf(x + pDrawable->x,     y + pDrawable->y);
-            j =  LastBankOf(x + pDrawable->x + w, y + pDrawable->y + h);
-            for (;  i <= j;  i++)
-            {
-                if (!(pGC->pCompositeClip = pGCPriv->pBankedClips[i]))
-                    continue;
-
-                GCOP_UNWRAP;
-
-                SET_SINGLE_BANK(pScreenPriv->pScreenPixmap, -1, -1, i);
-
-                (*pGC->ops->PutImage)(pDrawable, pGC, depth, x, y, w, h,
-                    leftPad, format, pImage);
-
-                GCOP_WRAP;
-            }
-
-            CLIP_RESTORE;
-        }
-
-        SCREEN_RESTORE;
-    }
-}
-
-/*
- * Here the CopyArea/CopyPlane wrappers.  First off, we have to clip against
- * the source in order to make the minimal number of copies in case of slow
- * systems.  Also the exposure handling is quite tricky.  Special attention
- * is to be given to the way the copies are sequenced.  The list of boxes after
- * the source clip is used to build a workqueue, that contains the atomic
- * copies (i.e. only from one bank to one bank).  Doing so produces a minimal
- * list of things to do.
- */
-static RegionPtr
-miBankCopy(
-    DrawablePtr   pSrc,
-    DrawablePtr   pDst,
-    GCPtr         pGC,
-    int           srcx,
-    int           srcy,
-    int           w,
-    int           h,
-    int           dstx,
-    int           dsty,
-    unsigned long plane,
-    Bool          SinglePlane
-)
-{
-    int         cx1, cy1, cx2, cy2;
-    int         ns, nd, nse, nde, dx, dy, xorg = 0, yorg = 0;
-    int         maxWidth = 0, maxHeight = 0, paddedWidth = 0;
-    int         nBox, nBoxClipSrc, nBoxClipDst, nQueue;
-    BoxPtr      pBox, pBoxClipSrc, pBoxClipDst;
-    BoxRec      fastBox, ccBox;
-    RegionPtr   ret = NULL, prgnSrcClip = NULL;
-    RegionRec   rgnDst;
-    char        *pImage = NULL;
-    miBankQueue *pQueue, *pQueueNew, *Queue;
-    miBankQueue *pQueueTmp, *pQueueNext, *pQueueBase;
-    Bool        fastBlit, freeSrcClip, fastClip;
-    Bool        fExpose = FALSE, fastExpose = FALSE;
-
-    GCOP_INIT;
-    SCREEN_SAVE;
-
-    if (!IS_BANKED(pSrc) && !IS_BANKED(pDst))
-    {
-        GCOP_UNWRAP;
-
-        if (SinglePlane)
-            ret = (*pGC->ops->CopyPlane)(pSrc, pDst, pGC,
-                srcx, srcy, w, h, dstx, dsty, plane);
-        else
-            ret = (*pGC->ops->CopyArea)(pSrc, pDst, pGC,
-                srcx, srcy, w, h, dstx, dsty);
-
-        GCOP_WRAP;
-    }
-    else if (!IS_BANKED(pDst))
-    {
-        fExpose = pGC->fExpose;
-        pGC->fExpose = FALSE;
-
-        xorg = pSrc->x;
-        yorg = pSrc->y;
-        dx   = dstx - srcx;
-        dy   = dsty - srcy;
-        srcx += xorg;
-        srcy += yorg;
-
-        ns = FirstBankOf(srcx,     srcy);
-        nse = LastBankOf(srcx + w, srcy + h);
-        for (;  ns <= nse;  ns++)
-        {
-            if (!pScreenPriv->pBanks[ns])
-                continue;
-
-            nBox = REGION_NUM_RECTS(pScreenPriv->pBanks[ns]);
-            pBox = REGION_RECTS(pScreenPriv->pBanks[ns]);
-
-            for (;  nBox--;  pBox++)
-            {
-                cx1 = max(pBox->x1, srcx);
-                cy1 = max(pBox->y1, srcy);
-                cx2 = min(pBox->x2, srcx + w);
-                cy2 = min(pBox->y2, srcy + h);
-
-                if ((cx1 >= cx2) || (cy1 >= cy2))
-                    continue;
-
-                GCOP_UNWRAP;
-
-                SET_SINGLE_BANK(pScreenPriv->pScreenPixmap, -1, -1, ns);
-
-                if (SinglePlane)
-                    (*pGC->ops->CopyPlane)(pSrc, pDst, pGC,
-                        cx1 - xorg, cy1 - yorg,
-                        cx2 - cx1, cy2 - cy1,
-                        cx1 + dx - xorg, cy1 + dy - yorg, plane);
-                else
-                    (*pGC->ops->CopyArea)(pSrc, pDst, pGC,
-                        cx1 - xorg, cy1 - yorg,
-                        cx2 - cx1, cy2 - cy1,
-                        cx1 + dx - xorg, cy1 + dy - yorg);
-
-                GCOP_WRAP;
-            }
-        }
-
-        pGC->fExpose = fExpose;
-        srcx -= xorg;
-        srcy -= yorg;
-    }
-    else if (!IS_BANKED(pSrc))
-    {
-        CLIP_SAVE;
-
-        if (pGC->miTranslate)
-        {
-            xorg = pDst->x;
-            yorg = pDst->y;
-        }
-        dx = srcx - dstx;
-        dy = srcy - dsty;
-        dstx += xorg;
-        dsty += yorg;
-
-        nd = FirstBankOf(dstx,     dsty);
-        nde = LastBankOf(dstx + w, dsty + h);
-        for (;  nd <= nde;  nd++)
-        {
-            if (!(pGC->pCompositeClip = pGCPriv->pBankedClips[nd]))
-                continue;
-
-            /*
-             * It's faster to let the lower-level CopyArea do the clipping
-             * within each bank.
-             */
-            nBox = REGION_NUM_RECTS(pScreenPriv->pBanks[nd]);
-            pBox = REGION_RECTS(pScreenPriv->pBanks[nd]);
-
-            for (;  nBox--;  pBox++)
-            {
-                cx1 = max(pBox->x1, dstx);
-                cy1 = max(pBox->y1, dsty);
-                cx2 = min(pBox->x2, dstx + w);
-                cy2 = min(pBox->y2, dsty + h);
-
-                if ((cx1 >= cx2) || (cy1 >= cy2))
-                    continue;
-
-                GCOP_UNWRAP;
-
-                SET_SINGLE_BANK(pScreenPriv->pScreenPixmap, -1, -1, nd);
-
-                if (SinglePlane)
-                    (*pGC->ops->CopyPlane)(pSrc, pDst, pGC,
-                        cx1 + dx - xorg, cy1 + dy - yorg,
-                        cx2 - cx1, cy2 - cy1,
-                        cx1 - xorg, cy1 - yorg, plane);
-                else
-                    (*pGC->ops->CopyArea)(pSrc, pDst, pGC,
-                        cx1 + dx - xorg, cy1 + dy - yorg,
-                        cx2 - cx1, cy2 - cy1,
-                        cx1 - xorg, cy1 - yorg);
-
-                GCOP_WRAP;
-            }
-        }
-
-        CLIP_RESTORE;
-    }
-    else /* IS_BANKED(pSrc) && IS_BANKED(pDst) */
-    {
-        CLIP_SAVE;
-
-        fExpose = pGC->fExpose;
-
-        fastBox.x1 = srcx + pSrc->x;
-        fastBox.y1 = srcy + pSrc->y;
-        fastBox.x2 = fastBox.x1 + w;
-        fastBox.y2 = fastBox.y1 + h;
-
-        dx = dstx - fastBox.x1;
-        dy = dsty - fastBox.y1;
-        if (pGC->miTranslate)
-        {
-            xorg = pDst->x;
-            yorg = pDst->y;
-        }
-
-        /*
-         * Clip against the source.  Otherwise we will blit too much for SINGLE
-         * and SHARED banked systems.
-         */
-        freeSrcClip = FALSE;
-        fastClip    = FALSE;
-        fastExpose  = FALSE;
-
-        if (pGC->subWindowMode != IncludeInferiors)
-            prgnSrcClip = &((WindowPtr)pSrc)->clipList;
-        else if (!((WindowPtr)pSrc)->parent)
-            fastClip = TRUE;
-        else if ((pSrc == pDst) && (pGC->clientClipType == CT_NONE))
-            prgnSrcClip = pGC->pCompositeClip;
-        else
-        {
-            prgnSrcClip = NotClippedByChildren((WindowPtr)pSrc);
-            freeSrcClip = TRUE;
-        }
-
-        if (fastClip)
-        {
-            fastExpose = TRUE;
-
-            /*
-             * Clip the source.  If regions extend beyond the source size, make
-             * sure exposure events get sent.
-             */
-            if (fastBox.x1 < pSrc->x)
-            {
-                fastBox.x1 = pSrc->x;
-                fastExpose = FALSE;
-            }
-            if (fastBox.y1 < pSrc->y)
-            {
-                fastBox.y1 = pSrc->y;
-                fastExpose = FALSE;
-            }
-            if (fastBox.x2 > pSrc->x + (int) pSrc->width)
-            {
-                fastBox.x2 = pSrc->x + (int) pSrc->width;
-                fastExpose = FALSE;
-            }
-            if (fastBox.y2 > pSrc->y + (int) pSrc->height)
-            {
-                fastBox.y2 = pSrc->y + (int) pSrc->height;
-                fastExpose = FALSE;
-            }
-
-            nBox = 1;
-            pBox = &fastBox;
-        }
-        else
-        {
-            REGION_INIT(pScreen, &rgnDst, &fastBox, 1);
-            REGION_INTERSECT(pScreen, &rgnDst, &rgnDst, prgnSrcClip);
-            pBox = REGION_RECTS(&rgnDst);
-            nBox = REGION_NUM_RECTS(&rgnDst);
-        }
-
-        /*
-         * fastBlit can only be TRUE if we don't need to worry about attempts
-         * to read partial pixels through the destination bank.
-         */
-        if (SinglePlane)
-            fastBlit = pGCPriv->fastPlane;
-        else
-            fastBlit = pGCPriv->fastCopy;
-
-        nQueue = nBox * pScreenPriv->maxRects * 2;
-        pQueue = Queue = xalloc_ARRAY(miBankQueue, nQueue);
-
-        if (Queue)
-        {
-            for (;  nBox--;  pBox++)
-            {
-                ns = FirstBankOf(pBox->x1, pBox->y1);
-                nse = LastBankOf(pBox->x2, pBox->y2);
-                for (;  ns <= nse;  ns++)
-                {
-                    if (!pScreenPriv->pBanks[ns])
-                        continue;
-
-                    nBoxClipSrc = REGION_NUM_RECTS(pScreenPriv->pBanks[ns]);
-                    pBoxClipSrc = REGION_RECTS(pScreenPriv->pBanks[ns]);
-
-                    for (;  nBoxClipSrc--;  pBoxClipSrc++)
-                    {
-                        cx1 = max(pBox->x1, pBoxClipSrc->x1);
-                        cy1 = max(pBox->y1, pBoxClipSrc->y1);
-                        cx2 = min(pBox->x2, pBoxClipSrc->x2);
-                        cy2 = min(pBox->y2, pBoxClipSrc->y2);
-
-                        /* Check to see if the region is empty */
-                        if ((cx1 >= cx2) || (cy1 >= cy2))
-                            continue;
-
-                        /* Translate c[xy]* to destination coordinates */
-                        cx1 += dx + xorg;
-                        cy1 += dy + yorg;
-                        cx2 += dx + xorg;
-                        cy2 += dy + yorg;
-
-                        nd = FirstBankOf(cx1, cy1);
-                        nde = LastBankOf(cx2, cy2);
-                        for (;  nd <= nde;  nd++)
-                        {
-                            if (!pGCPriv->pBankedClips[nd])
-                                continue;
-
-                            /*
-                             * Clients can send quite large clip descriptions,
-                             * so use the bank clips here instead.
-                             */
-                            nBoxClipDst =
-                                REGION_NUM_RECTS(pScreenPriv->pBanks[nd]);
-                            pBoxClipDst =
-                                REGION_RECTS(pScreenPriv->pBanks[nd]);
-
-                            for (;  nBoxClipDst--;  pBoxClipDst++)
-                            {
-                                ccBox.x1 = max(cx1, pBoxClipDst->x1);
-                                ccBox.y1 = max(cy1, pBoxClipDst->y1);
-                                ccBox.x2 = min(cx2, pBoxClipDst->x2);
-                                ccBox.y2 = min(cy2, pBoxClipDst->y2);
-
-                                /* Check to see if the region is empty */
-                                if ((ccBox.x1 >= ccBox.x2) ||
-                                    (ccBox.y1 >= ccBox.y2))
-                                    continue;
-
-                                pQueue->srcBankNo = ns;
-                                pQueue->dstBankNo = nd;
-                                pQueue->x         = ccBox.x1 - xorg;
-                                pQueue->y         = ccBox.y1 - yorg;
-                                pQueue->w         = ccBox.x2 - ccBox.x1;
-                                pQueue->h         = ccBox.y2 - ccBox.y1;
-
-                                if (maxWidth < pQueue->w)
-                                    maxWidth = pQueue->w;
-                                if (maxHeight < pQueue->h)
-                                    maxHeight = pQueue->h;
-
-                                /*
-                                 * When shared banking is used and the source
-                                 * and destination banks differ, prevent
-                                 * attempts to fetch partial scanline pad units
-                                 * through the destination bank.
-                                 */
-                                pQueue->fastBlit = fastBlit;
-                                if (fastBlit &&
-                                    (pScreenPriv->type == BANK_SHARED) &&
-                                    (ns != nd) &&
-                                    ((ccBox.x1 %
-                                      pScreenPriv->nPixelsPerScanlinePadUnit) ||
-                                     (ccBox.x2 %
-                                      pScreenPriv->nPixelsPerScanlinePadUnit) ||
-                                     (RECT_IN_REGION(pScreen,
-                                       pGCPriv->pBankedClips[nd], &ccBox) !=
-                                      rgnIN)))
-                                    pQueue->fastBlit = FALSE;
-                                pQueue++;
-                            }
-                        }
-                    }
-                }
-            }
-        }
-
-        if (!fastClip)
-        {
-            REGION_UNINIT(pScreen, &rgnDst);
-            if (freeSrcClip)
-                REGION_DESTROY(pScreen, prgnSrcClip);
-        }
-
-        pQueueNew = pQueue;
-        nQueue = pQueue - Queue;
-
-        if (nQueue > 0)
-        {
-            BANK_SAVE;
-
-            pQueue = Queue;
-
-            if ((nQueue > 1) &&
-                ((pSrc == pDst) || (pGC->subWindowMode == IncludeInferiors)))
-            {
-                if ((srcy + pSrc->y) < (dsty + yorg))
-                {
-                    /* Sort from bottom to top */
-                    pQueueBase = pQueueNext = pQueue + nQueue - 1;
-
-                    while (pQueueBase >= pQueue)
-                    {
-                        while ((pQueueNext >= pQueue) &&
-                               (pQueueBase->y == pQueueNext->y))
-                            pQueueNext--;
-
-                        pQueueTmp = pQueueNext + 1;
-                        while (pQueueTmp <= pQueueBase)
-                            *pQueueNew++ = *pQueueTmp++;
-
-                        pQueueBase = pQueueNext;
-                    }
-
-                    pQueueNew -= nQueue;
-                    pQueue = pQueueNew;
-                    pQueueNew = Queue;
-                }
-
-                if ((srcx + pSrc->x) < (dstx + xorg))
-                {
-                    /* Sort from right to left */
-                    pQueueBase = pQueueNext = pQueue;
-
-                    while (pQueueBase < pQueue + nQueue)
-                    {
-                        while ((pQueueNext < pQueue + nQueue) &&
-                               (pQueueNext->y == pQueueBase->y))
-                            pQueueNext++;
-
-                        pQueueTmp = pQueueNext;
-                        while (pQueueTmp != pQueueBase)
-                            *pQueueNew++ = *--pQueueTmp;
-
-                        pQueueBase = pQueueNext;
-                    }
-
-                    pQueueNew -= nQueue;
-                    pQueue = pQueueNew;
-                }
-            }
-
-            paddedWidth = PixmapBytePad(maxWidth,
-                pScreenPriv->pScreenPixmap->drawable.depth);
-            pImage = xalloc(paddedWidth * maxHeight);
-
-            pGC->fExpose = FALSE;
-
-            while (nQueue--)
-            {
-                pGC->pCompositeClip = pGCPriv->pBankedClips[pQueue->dstBankNo];
-
-                GCOP_UNWRAP;
-
-                if (pQueue->srcBankNo == pQueue->dstBankNo)
-                {
-                    SET_SINGLE_BANK(pScreenPriv->pScreenPixmap,
-                        -1, -1, pQueue->srcBankNo);
-
-                    if (SinglePlane)
-                        (*pGC->ops->CopyPlane)(pSrc, pDst, pGC,
-                            pQueue->x - dx - pSrc->x, pQueue->y - dy - pSrc->y,
-                            pQueue->w, pQueue->h, pQueue->x, pQueue->y, plane);
-                    else
-                        (*pGC->ops->CopyArea)(pSrc, pDst, pGC,
-                            pQueue->x - dx - pSrc->x, pQueue->y - dy - pSrc->y,
-                            pQueue->w, pQueue->h, pQueue->x, pQueue->y);
-                }
-                else if (pQueue->fastBlit)
-                {
-                    SET_SOURCE_BANK     (pScreenPriv->pBankPixmap,
-                        pScreenPriv->pScreenPixmap->drawable.width,
-                        pScreenPriv->pScreenPixmap->devKind,
-                        pQueue->srcBankNo);
-                    SET_DESTINATION_BANK(pScreenPriv->pScreenPixmap,
-                        -1, -1, pQueue->dstBankNo);
-
-                    if (SinglePlane)
-                        (*pGC->ops->CopyPlane)(
-                            (DrawablePtr)pScreenPriv->pBankPixmap, pDst, pGC,
-                            pQueue->x - dx, pQueue->y - dy,
-                            pQueue->w, pQueue->h, pQueue->x, pQueue->y, plane);
-                    else
-                        (*pGC->ops->CopyArea)(
-                            (DrawablePtr)pScreenPriv->pBankPixmap, pDst, pGC,
-                            pQueue->x - dx, pQueue->y - dy,
-                            pQueue->w, pQueue->h, pQueue->x, pQueue->y);
-                }
-                else if (pImage)
-                {
-                    ModifyPixmap(pScreenPriv->pBankPixmap,
-                        maxWidth, paddedWidth, pImage);
-
-                    SET_SINGLE_BANK(pScreenPriv->pScreenPixmap,
-                        -1, -1, pQueue->srcBankNo);
-
-                    (*pScreenPriv->pBankGC->ops->CopyArea)(
-                        pSrc, (DrawablePtr)pScreenPriv->pBankPixmap,
-                        pScreenPriv->pBankGC,
-                        pQueue->x - dx - pSrc->x, pQueue->y - dy - pSrc->y,
-                        pQueue->w, pQueue->h, 0, 0);
-
-                    SET_SINGLE_BANK(pScreenPriv->pScreenPixmap,
-                        -1, -1, pQueue->dstBankNo);
-
-                    if (SinglePlane)
-                        (*pGC->ops->CopyPlane)(
-                            (DrawablePtr)pScreenPriv->pBankPixmap,
-                            pDst, pGC, 0, 0, pQueue->w, pQueue->h,
-                            pQueue->x, pQueue->y, plane);
-                    else
-                        (*pGC->ops->CopyArea)(
-                            (DrawablePtr)pScreenPriv->pBankPixmap,
-                            pDst, pGC, 0, 0, pQueue->w, pQueue->h,
-                            pQueue->x, pQueue->y);
-                }
-
-                GCOP_WRAP;
-
-                pQueue++;
-            }
-
-            xfree(pImage);
-
-            BANK_RESTORE;
-        }
-
-        CLIP_RESTORE;
-
-        pGC->fExpose = fExpose;
-
-        xfree(Queue);
-    }
-
-    SCREEN_RESTORE;
-
-    if (!fExpose || fastExpose)
-        return ret;
-
-    return miHandleExposures(pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty, 0);
-}
-
-static RegionPtr
-miBankCopyArea(
-    DrawablePtr pSrc,
-    DrawablePtr pDst,
-    GCPtr       pGC,
-    int         srcx,
-    int         srcy,
-    int         w,
-    int         h,
-    int         dstx,
-    int         dsty
-)
-{
-    return miBankCopy(pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty, 0, FALSE);
-}
-
-static RegionPtr
-miBankCopyPlane(
-    DrawablePtr   pSrc,
-    DrawablePtr   pDst,
-    GCPtr         pGC,
-    int           srcx,
-    int           srcy,
-    int           w,
-    int           h,
-    int           dstx,
-    int           dsty,
-    unsigned long plane
-)
-{
-    return
-        miBankCopy(pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty, plane, TRUE);
-}
-
-static void
-miBankPolyPoint(
-    DrawablePtr pDrawable,
-    GCPtr       pGC,
-    int         mode,
-    int         nArray,
-    xPoint      *pArray
-)
-{
-#   define GCOP_ARGS GCOP_0D_ARGS
-    GCOP_COMPLEX(PolyPoint, xPoint);
-#   undef GCOP_ARGS
-}
-
-static void
-miBankPolylines(
-    DrawablePtr pDrawable,
-    GCPtr       pGC,
-    int         mode,
-    int         nArray,
-    DDXPointPtr pArray
-)
-{
-#   define GCOP_ARGS GCOP_0D_ARGS
-    GCOP_COMPLEX(Polylines, DDXPointRec);
-#   undef GCOP_ARGS
-}
-
-static void
-miBankPolySegment(
-    DrawablePtr pDrawable,
-    GCPtr       pGC,
-    int         nArray,
-    xSegment    *pArray
-)
-{
-#   define GCOP_ARGS GCOP_1D_ARGS
-    GCOP_COMPLEX(PolySegment, xSegment);
-#   undef GCOP_ARGS
-}
-
-static void
-miBankPolyRectangle(
-    DrawablePtr pDrawable,
-    GCPtr       pGC,
-    int         nArray,
-    xRectangle  *pArray
-)
-{
-#   define GCOP_ARGS GCOP_1D_ARGS
-    GCOP_COMPLEX(PolyRectangle, xRectangle);
-#   undef GCOP_ARGS
-}
-
-static void
-miBankPolyArc(
-    DrawablePtr pDrawable,
-    GCPtr       pGC,
-    int         nArray,
-    xArc        *pArray
-)
-{
-#   define GCOP_ARGS GCOP_1D_ARGS
-    GCOP_COMPLEX(PolyArc, xArc);
-#   undef GCOP_ARGS
-}
-
-static void
-miBankFillPolygon(
-    DrawablePtr pDrawable,
-    GCPtr       pGC,
-    int         shape,
-    int         mode,
-    int         nArray,
-    DDXPointRec *pArray
-)
-{
-#   define GCOP_ARGS GCOP_2D_ARGS
-    GCOP_COMPLEX(FillPolygon, DDXPointRec);
-#   undef GCOP_ARGS
-}
-
-static void
-miBankPolyFillRect(
-    DrawablePtr pDrawable,
-    GCPtr       pGC,
-    int         nArray,
-    xRectangle  *pArray
-)
-{
-#   define GCOP_ARGS GCOP_1D_ARGS
-    GCOP_COMPLEX(PolyFillRect, xRectangle);
-#   undef GCOP_ARGS
-}
-
-static void
-miBankPolyFillArc(
-    DrawablePtr pDrawable,
-    GCPtr       pGC,
-    int         nArray,
-    xArc        *pArray
-)
-{
-#   define GCOP_ARGS GCOP_1D_ARGS
-    GCOP_COMPLEX(PolyFillArc, xArc);
-#   undef GCOP_ARGS
-}
-
-static int
-miBankPolyText8(
-    DrawablePtr pDrawable,
-    GCPtr       pGC,
-    int         x,
-    int         y,
-    int         nArray,
-    char        *pchar
-)
-{
-    int retval = x;
-
-    GCOP_SIMPLE(retval =
-        (*pGC->ops->PolyText8)(pDrawable, pGC, x, y, nArray, pchar));
-
-    return retval;
-}
-
-static int
-miBankPolyText16(
-    DrawablePtr    pDrawable,
-    GCPtr          pGC,
-    int            x,
-    int            y,
-    int            nArray,
-    unsigned short *pchar
-)
-{
-    int retval = x;
-
-    GCOP_SIMPLE(retval =
-        (*pGC->ops->PolyText16)(pDrawable, pGC, x, y, nArray, pchar));
-
-    return retval;
-}
-
-static void
-miBankImageText8(
-    DrawablePtr pDrawable,
-    GCPtr       pGC,
-    int         x,
-    int         y,
-    int         nArray,
-    char        *pchar
-)
-{
-    GCOP_SIMPLE((*pGC->ops->ImageText8)(pDrawable, pGC, x, y, nArray, pchar));
-}
-
-static void
-miBankImageText16(
-    DrawablePtr    pDrawable,
-    GCPtr          pGC,
-    int            x,
-    int            y,
-    int            nArray,
-    unsigned short *pchar
-)
-{
-    GCOP_SIMPLE((*pGC->ops->ImageText16)(pDrawable, pGC, x, y, nArray, pchar));
-}
-
-static void
-miBankImageGlyphBlt(
-    DrawablePtr  pDrawable,
-    GCPtr        pGC,
-    int          x,
-    int          y,
-    unsigned int nArray,
-    CharInfoPtr  *ppci,
-    pointer      pglyphBase
-)
-{
-    GCOP_SIMPLE((*pGC->ops->ImageGlyphBlt)(pDrawable, pGC,
-        x, y, nArray, ppci, pglyphBase));
-}
-
-static void
-miBankPolyGlyphBlt(
-    DrawablePtr  pDrawable,
-    GCPtr        pGC,
-    int          x,
-    int          y,
-    unsigned int nArray,
-    CharInfoPtr  *ppci,
-    pointer      pglyphBase
-)
-{
-    GCOP_SIMPLE((*pGC->ops->PolyGlyphBlt)(pDrawable, pGC,
-        x, y, nArray, ppci, pglyphBase));
-}
-
-static void
-miBankPushPixels(
-    GCPtr       pGC,
-    PixmapPtr   pBitmap,
-    DrawablePtr pDrawable,
-    int         w,
-    int         h,
-    int         x,
-    int         y
-)
-{
-    if ((w > 0) && (h > 0))
-    {
-        GCOP_INIT;
-        SCREEN_SAVE;
-
-        if (!IS_BANKED(pDrawable))
-        {
-            GCOP_UNWRAP;
-
-            (*pGC->ops->PushPixels)(pGC, pBitmap, pDrawable, w, h, x, y);
-
-            GCOP_WRAP;
-        }
-        else
-        {
-            int i, j;
-
-            CLIP_SAVE;
-
-            i = FirstBankOf(x,     y);
-            j =  LastBankOf(x + w, y + h);
-            for (;  i <= j;  i++)
-            {
-                if (!(pGC->pCompositeClip = pGCPriv->pBankedClips[i]))
-                    continue;
-
-                GCOP_UNWRAP;
-
-                SET_SINGLE_BANK(pScreenPriv->pScreenPixmap, -1, -1, i);
-
-                (*pGC->ops->PushPixels)(pGC, pBitmap, pDrawable, w, h, x, y);
-
-                GCOP_WRAP;
-            }
-
-            CLIP_RESTORE;
-        }
-
-        SCREEN_RESTORE;
-    }
-}
-
-static GCOps miBankGCOps =
-{
-    miBankFillSpans,
-    miBankSetSpans,
-    miBankPutImage,
-    miBankCopyArea,
-    miBankCopyPlane,
-    miBankPolyPoint,
-    miBankPolylines,
-    miBankPolySegment,
-    miBankPolyRectangle,
-    miBankPolyArc,
-    miBankFillPolygon,
-    miBankPolyFillRect,
-    miBankPolyFillArc,
-    miBankPolyText8,
-    miBankPolyText16,
-    miBankImageText8,
-    miBankImageText16,
-    miBankImageGlyphBlt,
-    miBankPolyGlyphBlt,
-    miBankPushPixels,
-    {NULL}              /* devPrivate */
-};
-
-/********************
- * GCFuncs wrappers *
- ********************/
-
-static void
-miBankValidateGC(
-    GCPtr         pGC,
-    unsigned long changes,
-    DrawablePtr   pDrawable
-)
-{
-    GC_INIT(pGC);
-    GC_UNWRAP(pGC);
-
-    (*pGC->funcs->ValidateGC)(pGC, changes, pDrawable);
-
-    if ((changes & (GCClipXOrigin|GCClipYOrigin|GCClipMask|GCSubwindowMode)) ||
-        (pDrawable->serialNumber != (pGC->serialNumber & DRAWABLE_SERIAL_BITS)))
-    {
-        ScreenPtr     pScreen = pGC->pScreen;
-        RegionPtr     prgnClip;
-        unsigned long planemask;
-        int           i;
-
-        SCREEN_INIT;
-        SCREEN_SAVE;
-
-        if (IS_BANKED(pDrawable))
-        {
-            for (i = 0;  i < pScreenPriv->nBanks;  i++)
-            {
-                if (!pScreenPriv->pBanks[i])
-                    continue;
-
-                if (!(prgnClip = pGCPriv->pBankedClips[i]))
-                    prgnClip = REGION_CREATE(pScreen, NULL, 1);
-
-                REGION_INTERSECT(pScreen, prgnClip,
-                    pScreenPriv->pBanks[i], pGC->pCompositeClip);
-
-                if ((REGION_NUM_RECTS(prgnClip) <= 1) &&
-                    ((prgnClip->extents.x1 == prgnClip->extents.x2) ||
-                     (prgnClip->extents.y1 == prgnClip->extents.y2)))
-                {
-                    REGION_DESTROY(pScreen, prgnClip);
-                    pGCPriv->pBankedClips[i] = NULL;
-                }
-                else
-                    pGCPriv->pBankedClips[i] = prgnClip;
-            }
-
-            /*
-             * fastCopy and fastPlane can only be TRUE if we don't need to
-             * worry about attempts to read partial pixels through the
-             * destination bank.
-             */
-            switch (pScreenPriv->type)
-            {
-                case BANK_SHARED:
-                    pGCPriv->fastCopy = pGCPriv->fastPlane = FALSE;
-
-                    if ((pGC->alu != GXclear) && (pGC->alu != GXcopy) &&
-                        (pGC->alu != GXcopyInverted) && (pGC->alu != GXset))
-                        break;
-
-                    if (pScreen->rootDepth == 1)
-                        pGCPriv->fastPlane = TRUE;
-
-                    /* This is probably paranoia */
-                    if ((pDrawable->depth != pScreen->rootDepth) ||
-                        (pDrawable->depth != pGC->depth))
-                        break;
-
-                    planemask = (1 << pGC->depth) - 1;
-                    if ((pGC->planemask & planemask) == planemask)
-                        pGCPriv->fastCopy = TRUE;
-
-                    break;
-
-                case BANK_DOUBLE:
-                    pGCPriv->fastCopy = pGCPriv->fastPlane = TRUE;
-                    break;
-
-                default:
-                    pGCPriv->fastCopy = pGCPriv->fastPlane = FALSE;
-                    break;
-            }
-        }
-        else
-        {
-            /*
-             * Here we are on a pixmap and don't need all that special clipping
-             * stuff, hence free it.
-             */
-            for (i = 0;  i < pScreenPriv->nBanks;  i++)
-            {
-                if (!pGCPriv->pBankedClips[i])
-                    continue;
-
-                REGION_DESTROY(pScreen, pGCPriv->pBankedClips[i]);
-                pGCPriv->pBankedClips[i] = NULL;
-            }
-        }
-
-        SCREEN_RESTORE;
-    }
-
-    GC_WRAP(pGC);
-}
-
-static void
-miBankChangeGC(
-    GCPtr         pGC,
-    unsigned long mask
-)
-{
-    GC_INIT(pGC);
-    GC_UNWRAP(pGC);
-
-    (*pGC->funcs->ChangeGC)(pGC, mask);
-
-    GC_WRAP(pGC);
-}
-
-static void
-miBankCopyGC(
-    GCPtr         pGCSrc,
-    unsigned long mask,
-    GCPtr         pGCDst
-)
-{
-    GC_INIT(pGCDst);
-    GC_UNWRAP(pGCDst);
-
-    (*pGCDst->funcs->CopyGC)(pGCSrc, mask, pGCDst);
-
-    GC_WRAP(pGCDst);
-}
-
-static void
-miBankDestroyGC(
-    GCPtr pGC
-)
-{
-    ScreenPtr pScreen = pGC->pScreen;
-    int       i;
-
-    SCREEN_INIT;
-    GC_INIT(pGC);
-    GC_UNWRAP(pGC);
-
-    (*pGC->funcs->DestroyGC)(pGC);
-
-    for (i = 0;  i < pScreenPriv->nBanks;  i++)
-    {
-        if (!pGCPriv->pBankedClips[i])
-            continue;
-
-        REGION_DESTROY(pScreen, pGCPriv->pBankedClips[i]);
-        pGCPriv->pBankedClips[i] = NULL;
-    }
-
-    GC_WRAP(pGC);
-}
-
-static void
-miBankChangeClip(
-    GCPtr   pGC,
-    int     type,
-    pointer pvalue,
-    int     nrects
-)
-{
-    GC_INIT(pGC);
-    GC_UNWRAP(pGC);
-
-    (*pGC->funcs->ChangeClip)(pGC, type, pvalue, nrects);
-
-    GC_WRAP(pGC);
-}
-
-static void
-miBankDestroyClip(
-    GCPtr pGC
-)
-{
-    GC_INIT(pGC);
-    GC_UNWRAP(pGC);
-
-    (*pGC->funcs->DestroyClip)(pGC);
-
-    GC_WRAP(pGC);
-}
-
-static void
-miBankCopyClip(
-    GCPtr pGCDst,
-    GCPtr pGCSrc
-)
-{
-    GC_INIT(pGCDst);
-    GC_UNWRAP(pGCDst);
-
-    (*pGCDst->funcs->CopyClip)(pGCDst, pGCSrc);
-
-    GC_WRAP(pGCDst);
-}
-
-static GCFuncs miBankGCFuncs =
-{
-    miBankValidateGC,
-    miBankChangeGC,
-    miBankCopyGC,
-    miBankDestroyGC,
-    miBankChangeClip,
-    miBankDestroyClip,
-    miBankCopyClip
-};
-
-/*******************
- * Screen Wrappers *
- *******************/
-
-static Bool
-miBankCreateScreenResources(
-    ScreenPtr pScreen
-)
-{
-    Bool retval;
-
-    SCREEN_INIT;
-    SCREEN_UNWRAP(CreateScreenResources);
-
-    if ((retval = (*pScreen->CreateScreenResources)(pScreen)))
-    {
-        /* Set screen buffer address to something recognizable */
-        pScreenPriv->pScreenPixmap = (*pScreen->GetScreenPixmap)(pScreen);
-        pScreenPriv->pbits = pScreenPriv->pScreenPixmap->devPrivate.ptr;
-        pScreenPriv->pScreenPixmap->devPrivate.ptr = (pointer)pScreenPriv;
-
-        /* Get shadow pixmap;  width & height of 0 means no pixmap data */
-        pScreenPriv->pBankPixmap = (*pScreen->CreatePixmap)(pScreen, 0, 0,
-            pScreenPriv->pScreenPixmap->drawable.depth, 0);
-        if (!pScreenPriv->pBankPixmap)
-            retval = FALSE;
-    }
-
-    /* Shadow the screen */
-    if (retval)
-        retval = (*pScreen->ModifyPixmapHeader)(pScreenPriv->pBankPixmap,
-            pScreenPriv->pScreenPixmap->drawable.width,
-            pScreenPriv->pScreenPixmap->drawable.height,
-            pScreenPriv->pScreenPixmap->drawable.depth,
-            pScreenPriv->pScreenPixmap->drawable.bitsPerPixel,
-            pScreenPriv->pScreenPixmap->devKind, NULL);
-
-    /* Create shadow GC */
-    if (retval)
-    {
-        pScreenPriv->pBankGC = CreateScratchGC(pScreen,
-            pScreenPriv->pBankPixmap->drawable.depth);
-        if (!pScreenPriv->pBankGC)
-            retval = FALSE;
-    }
-
-    /* Validate shadow GC */
-    if (retval)
-    {
-        pScreenPriv->pBankGC->graphicsExposures = FALSE;
-        pScreenPriv->pBankGC->subWindowMode = IncludeInferiors;
-        ValidateGC((DrawablePtr)pScreenPriv->pBankPixmap,
-            pScreenPriv->pBankGC);
-    }
-
-    SCREEN_WRAP(CreateScreenResources, miBankCreateScreenResources);
-
-    return retval;
-}
-
-static Bool
-miBankModifyPixmapHeader(
-    PixmapPtr pPixmap,
-    int       width,
-    int       height,
-    int       depth,
-    int       bitsPerPixel,
-    int       devKind,
-    pointer   pPixData
-)
-{
-    Bool retval = FALSE;
-
-    if (pPixmap)
-    {
-        ScreenPtr pScreen = pPixmap->drawable.pScreen;
-
-        SCREEN_INIT;
-        PIXMAP_SAVE(pPixmap);
-        SCREEN_UNWRAP(ModifyPixmapHeader);
-
-        retval = (*pScreen->ModifyPixmapHeader)(pPixmap, width, height,
-            depth, bitsPerPixel, devKind, pPixData);
-
-        SCREEN_WRAP(ModifyPixmapHeader, miBankModifyPixmapHeader);
-
-        if (pbits == (pointer)pScreenPriv)
-        {
-            pScreenPriv->pbits = pPixmap->devPrivate.ptr;
-            pPixmap->devPrivate.ptr = pbits;
-        }
-    }
-
-    return retval;
-}
-
-static Bool
-miBankCloseScreen(
-    int       nIndex,
-    ScreenPtr pScreen
-)
-{
-    int i;
-
-    SCREEN_INIT;
-
-    /* Free shadow GC */
-    FreeScratchGC(pScreenPriv->pBankGC);
-
-    /* Free shadow pixmap */
-    (*pScreen->DestroyPixmap)(pScreenPriv->pBankPixmap);
-
-    /* Restore screen pixmap devPrivate pointer */
-    pScreenPriv->pScreenPixmap->devPrivate.ptr = pScreenPriv->pbits;
-
-    /* Delete bank clips */
-    for (i = 0;  i < pScreenPriv->nBanks;  i++)
-        if (pScreenPriv->pBanks[i])
-            REGION_DESTROY(pScreen, pScreenPriv->pBanks[i]);
-
-    Xfree(pScreenPriv->pBanks);
-
-    SCREEN_UNWRAP(CreateScreenResources);
-    SCREEN_UNWRAP(ModifyPixmapHeader);
-    SCREEN_UNWRAP(CloseScreen);
-    SCREEN_UNWRAP(GetImage);
-    SCREEN_UNWRAP(GetSpans);
-    SCREEN_UNWRAP(CreateGC);
-    SCREEN_UNWRAP(CopyWindow);
-
-    Xfree(pScreenPriv);
-    return (*pScreen->CloseScreen)(nIndex, pScreen);
-}
-
-static void
-miBankGetImage(
-    DrawablePtr   pDrawable,
-    int           sx,
-    int           sy,
-    int           w,
-    int           h,
-    unsigned int  format,
-    unsigned long planemask,
-    char          *pImage
-)
-{
-    if ((w > 0) && (h > 0))
-    {
-        ScreenPtr pScreen = pDrawable->pScreen;
-
-        SCREEN_INIT;
-        SCREEN_STATUS;
-        SCREEN_UNWRAP(GetImage);
-
-        if (!IS_BANKED(pDrawable))
-        {
-            (*pScreen->GetImage)(pDrawable, sx, sy, w, h,
-                format, planemask, pImage);
-        }
-        else
-        {
-            int  paddedWidth;
-            char *pBankImage;
-
-            paddedWidth = PixmapBytePad(w,
-                pScreenPriv->pScreenPixmap->drawable.depth);
-            pBankImage = xalloc(paddedWidth * h);
-
-            if (pBankImage)
-            {
-                BANK_SAVE;
-
-                ModifyPixmap(pScreenPriv->pBankPixmap, w, paddedWidth,
-                    pBankImage);
-
-                (*pScreenPriv->pBankGC->ops->CopyArea)(
-                    (DrawablePtr)WindowTable[pScreen->myNum],
-                    (DrawablePtr)pScreenPriv->pBankPixmap,
-                    pScreenPriv->pBankGC,
-                    sx + pDrawable->x, sy + pDrawable->y, w, h, 0, 0);
-
-                (*pScreen->GetImage)((DrawablePtr)pScreenPriv->pBankPixmap,
-                    0, 0, w, h, format, planemask, pImage);
-
-                BANK_RESTORE;
-
-                xfree(pBankImage);
-            }
-        }
-
-        SCREEN_WRAP(GetImage, miBankGetImage);
-    }
-}
-
-static void
-miBankGetSpans(
-    DrawablePtr pDrawable,
-    int         wMax,
-    DDXPointPtr ppt,
-    int         *pwidth,
-    int         nspans,
-    char        *pImage
-)
-{
-    if (nspans > 0)
-    {
-        ScreenPtr pScreen = pDrawable->pScreen;
-
-        SCREEN_INIT;
-        SCREEN_STATUS;
-        SCREEN_UNWRAP(GetSpans);
-
-        if (!IS_BANKED(pDrawable))
-        {
-            (*pScreen->GetSpans)(pDrawable, wMax, ppt, pwidth, nspans, pImage);
-        }
-        else
-        {
-            char        *pBankImage;
-            int         paddedWidth;
-            DDXPointRec pt;
-
-            pt.x = pt.y = 0;
-
-            paddedWidth =
-                PixmapBytePad(pScreenPriv->pScreenPixmap->drawable.width,
-                    pScreenPriv->pScreenPixmap->drawable.depth);
-            pBankImage = xalloc(paddedWidth);
-
-            if (pBankImage)
-            {
-                BANK_SAVE;
-
-                ModifyPixmap(pScreenPriv->pBankPixmap,
-                    pScreenPriv->pScreenPixmap->drawable.width,
-                    paddedWidth, pBankImage);
-
-                for (;  nspans--;  ppt++, pwidth++)
-                {
-                    if (*pwidth <= 0)
-                        continue;
-
-                    (*pScreenPriv->pBankGC->ops->CopyArea)(
-                        (DrawablePtr)WindowTable[pScreen->myNum],
-                        (DrawablePtr)pScreenPriv->pBankPixmap,
-                        pScreenPriv->pBankGC,
-                        ppt->x, ppt->y, *pwidth, 1, 0, 0);
-
-                    (*pScreen->GetSpans)((DrawablePtr)pScreenPriv->pBankPixmap,
-                        wMax, &pt, pwidth, 1, pImage);
-
-                    pImage = pImage + PixmapBytePad(*pwidth, pDrawable->depth);
-                }
-
-                BANK_RESTORE;
-
-                xfree(pBankImage);
-            }
-        }
-
-        SCREEN_WRAP(GetSpans, miBankGetSpans);
-    }
-}
-
-static Bool
-miBankCreateGC(
-    GCPtr pGC
-)
-{
-    ScreenPtr   pScreen = pGC->pScreen;
-    miBankGCPtr pGCPriv = BANK_GCPRIVATE(pGC);
-    Bool        ret;
-
-    SCREEN_INIT;
-    SCREEN_UNWRAP(CreateGC);
-
-    if ((ret = (*pScreen->CreateGC)(pGC)))
-    {
-        pGCPriv->unwrappedOps = &miBankGCOps;
-        pGCPriv->unwrappedFuncs = &miBankGCFuncs;
-        GC_WRAP(pGC);
-
-        memset(&pGCPriv->pBankedClips, 0,
-            pScreenPriv->nBanks * sizeof(pGCPriv->pBankedClips));
-    }
-
-    SCREEN_WRAP(CreateGC, miBankCreateGC);
-
-    return ret;
-}
-
-static void
-miBankCopyWindow(
-    WindowPtr   pWindow,
-    DDXPointRec ptOldOrg,
-    RegionPtr   pRgnSrc
-)
-{
-    ScreenPtr   pScreen = pWindow->drawable.pScreen;
-    GCPtr       pGC;
-    int         dx, dy, nBox;
-    DrawablePtr pDrawable = (DrawablePtr)WindowTable[pScreen->myNum];
-    RegionPtr   pRgnDst;
-    BoxPtr      pBox, pBoxTmp, pBoxNext, pBoxBase, pBoxNew1, pBoxNew2;
-    XID         subWindowMode = IncludeInferiors;
-
-    pGC = GetScratchGC(pDrawable->depth, pScreen);
-
-    ChangeGC(pGC, GCSubwindowMode, &subWindowMode);
-    ValidateGC(pDrawable, pGC);
-
-    pRgnDst = REGION_CREATE(pScreen, NULL, 1);
-
-    dx = ptOldOrg.x - pWindow->drawable.x;
-    dy = ptOldOrg.y - pWindow->drawable.y;
-    REGION_TRANSLATE(pScreen, pRgnSrc, -dx, -dy);
-    REGION_INTERSECT(pScreen, pRgnDst, &pWindow->borderClip, pRgnSrc);
-
-    pBox = REGION_RECTS(pRgnDst);
-    nBox = REGION_NUM_RECTS(pRgnDst);
-
-    pBoxNew1 = NULL;
-    pBoxNew2 = NULL;
-
-    if (nBox > 1)
-    {
-        if (dy < 0)
-        {
-            /* Sort boxes from bottom to top */
-            pBoxNew1 = xalloc_ARRAY(BoxRec, nBox);
-
-            if (pBoxNew1)
-            {
-                pBoxBase = pBoxNext = pBox + nBox - 1;
-
-                while (pBoxBase >= pBox)
-                {
-                    while ((pBoxNext >= pBox) &&
-                           (pBoxBase->y1 == pBoxNext->y1))
-                        pBoxNext--;
-
-                    pBoxTmp = pBoxNext + 1;
-
-                    while (pBoxTmp <= pBoxBase)
-                        *pBoxNew1++ = *pBoxTmp++;
-
-                    pBoxBase = pBoxNext;
-                }
-
-                pBoxNew1 -= nBox;
-                pBox = pBoxNew1;
-            }
-        }
-
-        if (dx < 0)
-        {
-            /* Sort boxes from right to left */
-            pBoxNew2 = xalloc_ARRAY(BoxRec, nBox);
-
-            if (pBoxNew2)
-            {
-                pBoxBase = pBoxNext = pBox;
-
-                while (pBoxBase < pBox + nBox)
-                {
-                    while ((pBoxNext < pBox + nBox) &&
-                           (pBoxNext->y1 == pBoxBase->y1))
-                        pBoxNext++;
-
-                    pBoxTmp = pBoxNext;
-
-                    while (pBoxTmp != pBoxBase)
-                        *pBoxNew2++ = *--pBoxTmp;
-
-                    pBoxBase = pBoxNext;
-                }
-
-                pBoxNew2 -= nBox;
-                pBox = pBoxNew2;
-            }
-        }
-    }
-
-    while (nBox--)
-    {
-        (*pGC->ops->CopyArea)(pDrawable, pDrawable, pGC,
-            pBox->x1 + dx, pBox->y1 + dy,
-            pBox->x2 - pBox->x1, pBox->y2 - pBox->y1,
-            pBox->x1, pBox->y1);
-
-        pBox++;
-    }
-
-    FreeScratchGC(pGC);
-
-    REGION_DESTROY(pScreen, pRgnDst);
-
-    xfree(pBoxNew2);
-    xfree(pBoxNew1);
-}
-
-Bool
-miInitializeBanking(
-    ScreenPtr     pScreen,
-    unsigned int  xsize,
-    unsigned int  ysize,
-    unsigned int  width,
-    miBankInfoPtr pBankInfo
-)
-{
-    miBankScreenPtr pScreenPriv;
-    unsigned long   nBitsPerBank, nBitsPerScanline, nPixelsPerScanlinePadUnit;
-    unsigned long   BankBase, ServerPad;
-    unsigned int    type, iBank, nBanks, maxRects, we, nBankBPP;
-    int             i;
-
-    if (!pBankInfo || !pBankInfo->BankSize)
-        return TRUE;            /* No banking required */
-
-    /* Sanity checks */
-
-    if (!pScreen || !xsize || !ysize || (xsize > width) ||
-        !pBankInfo->SetSourceBank || !pBankInfo->SetDestinationBank ||
-        !pBankInfo->SetSourceAndDestinationBanks ||
-        !pBankInfo->pBankA || !pBankInfo->pBankB ||
-        !pBankInfo->nBankDepth)
-        return FALSE;
-
-    /*
-     * DDX *must* have registered a pixmap format whose depth is
-     * pBankInfo->nBankDepth.  This is not necessarily the rootDepth
-     * pixmap format.
-     */
-    i = 0;
-    while (screenInfo.formats[i].depth != pBankInfo->nBankDepth)
-        if (++i >= screenInfo.numPixmapFormats)
-            return FALSE;
-    nBankBPP = screenInfo.formats[i].bitsPerPixel;
-
-    i = 0;
-    while (screenInfo.formats[i].depth != pScreen->rootDepth)
-        if (++i >= screenInfo.numPixmapFormats)
-            return FALSE;
-
-    if (nBankBPP > screenInfo.formats[i].bitsPerPixel)
-        return FALSE;
-
-    /* Determine banking type */
-    if ((type = miBankDeriveType(pScreen, pBankInfo)) == BANK_NOBANK)
-        return FALSE;
-
-    /* Internal data */
-
-    nBitsPerBank = pBankInfo->BankSize * 8;
-    ServerPad = PixmapBytePad(1, pBankInfo->nBankDepth) * 8;
-    if (nBitsPerBank % ServerPad)
-        return FALSE;
-    nBitsPerScanline = PixmapBytePad(width, pBankInfo->nBankDepth) * 8;
-    nBanks = ((nBitsPerScanline * (ysize - 1)) +
-              (nBankBPP * xsize) + nBitsPerBank - 1) / nBitsPerBank;
-    nPixelsPerScanlinePadUnit = miLCM(ServerPad, nBankBPP) / nBankBPP;
-
-    /* Private areas */
-
-    if (miBankGeneration != serverGeneration)
-        miBankGeneration = serverGeneration;
-
-    if (!dixRequestPrivate(miBankGCKey,
-        (nBanks * sizeof(RegionPtr)) +
-            (sizeof(miBankGCRec) - sizeof(RegionPtr))))
-        return FALSE;
-
-    if (!(pScreenPriv = (miBankScreenPtr)Xcalloc(sizeof(miBankScreenRec))))
-        return FALSE;
-
-    if (!(pScreenPriv->pBanks =                 /* Allocate and clear */
-        (RegionPtr *)Xcalloc(nBanks * sizeof(RegionPtr))))
-    {
-        Xfree(pScreenPriv);
-        return FALSE;
-    }
-
-    /*
-     * Translate banks into clipping regions which are themselves clipped
-     * against the screen.  This also ensures that pixels with imbedded bank
-     * boundaries are off-screen.
-     */
-
-    BankBase = 0;
-    maxRects = 0;
-    we = 0;
-    for (iBank = 0;  iBank < nBanks;  iBank++)
-    {
-        xRectangle   pRects[3], *pRect = pRects;
-        unsigned int xb, yb, xe, ye;
-
-        xb = ((BankBase + nBankBPP - 1) % nBitsPerScanline) / nBankBPP;
-        yb =  (BankBase + nBankBPP - 1) / nBitsPerScanline;
-        if (xb >= xsize)
-        {
-            xb = we = 0;
-            yb++;
-        }
-        if (yb >= ysize)
-        {
-            we = 0;
-            break;
-        }
-
-        if (we)
-            break;
-
-        BankBase += nBitsPerBank;
-
-        we = (BankBase % nBitsPerScanline) % nBankBPP;
-        xe = (BankBase % nBitsPerScanline) / nBankBPP;
-        ye =  BankBase / nBitsPerScanline;
-        if (xe >= xsize)
-        {
-            we = xe = 0;
-            ye++;
-        }
-        if (ye >= ysize)
-        {
-            we = xe = 0;
-            ye = ysize;
-        }
-
-        if (yb == ye)
-        {
-            if (xb >= xe)
-                continue;
-
-            pRect->x      = xb;
-            pRect->y      = yb;
-            pRect->width  = xe - xb;
-            pRect->height = 1;
-            maxRects += 2;
-            pRect++;
-        }
-        else
-        {
-            if (xb)
-            {
-                pRect->x      = xb;
-                pRect->y      = yb++;
-                pRect->width  = xsize - xb;
-                pRect->height = 1;
-                maxRects += 2;
-                pRect++;
-            }
-
-            if (yb < ye)
-            {
-                pRect->x      = 0;
-                pRect->y      = yb;
-                pRect->width  = xsize;
-                pRect->height = ye - yb;
-                maxRects += min(pRect->height, 3) + 1;
-                pRect++;
-            }
-
-            if (xe)
-            {
-                pRect->x      = 0;
-                pRect->y      = ye;
-                pRect->width  = xe;
-                pRect->height = 1;
-                maxRects += 2;
-                pRect++;
-            }
-        }
-
-        pScreenPriv->pBanks[iBank] =
-            RECTS_TO_REGION(pScreen, pRect - pRects, pRects, 0);
-        if (!pScreenPriv->pBanks[iBank] ||
-            REGION_NAR(pScreenPriv->pBanks[iBank]))
-        {
-            we = 1;
-            break;
-        }
-    }
-
-    if (we && (iBank < nBanks))
-    {
-        for (i = iBank;  i >= 0;  i--)
-            if (pScreenPriv->pBanks[i])
-                REGION_DESTROY(pScreen, pScreenPriv->pBanks[i]);
-
-        Xfree(pScreenPriv->pBanks);
-        Xfree(pScreenPriv);
-
-        return FALSE;
-    }
-
-    /* Open for business */
-
-    pScreenPriv->type = type;
-    pScreenPriv->nBanks = nBanks;
-    pScreenPriv->maxRects = maxRects;
-    pScreenPriv->nBankBPP = nBankBPP;
-    pScreenPriv->BankInfo = *pBankInfo;
-    pScreenPriv->nBitsPerBank = nBitsPerBank;
-    pScreenPriv->nBitsPerScanline = nBitsPerScanline;
-    pScreenPriv->nPixelsPerScanlinePadUnit = nPixelsPerScanlinePadUnit;
-
-    SCREEN_WRAP(CreateScreenResources, miBankCreateScreenResources);
-    SCREEN_WRAP(ModifyPixmapHeader,    miBankModifyPixmapHeader);
-    SCREEN_WRAP(CloseScreen,           miBankCloseScreen);
-    SCREEN_WRAP(GetImage,              miBankGetImage);
-    SCREEN_WRAP(GetSpans,              miBankGetSpans);
-    SCREEN_WRAP(CreateGC,              miBankCreateGC);
-    SCREEN_WRAP(CopyWindow,            miBankCopyWindow);
-
-    dixSetPrivate(&pScreen->devPrivates, miBankScreenKey, pScreenPriv);
-
-    return TRUE;
-}
-
-/*
- * Given various screen attributes, determine the minimum scanline width such
- * that each scanline is server and DDX padded and any pixels with imbedded
- * bank boundaries are off-screen.  This function returns -1 if such a width
- * cannot exist.  This function exists because the DDX needs to be able to
- * determine this width before initializing a frame buffer.
- */
-int
-miScanLineWidth(
-    unsigned int     xsize,         /* pixels */
-    unsigned int     ysize,         /* pixels */
-    unsigned int     width,         /* pixels */
-    unsigned long    BankSize,      /* char's */
-    PixmapFormatRec *pBankFormat,
-    unsigned int     nWidthUnit     /* bits */
-)
-{
-    unsigned long nBitsPerBank, nBitsPerScanline, nBitsPerScanlinePadUnit;
-    unsigned long minBitsPerScanline, maxBitsPerScanline;
-
-    /* Sanity checks */
-
-    if (!nWidthUnit || !pBankFormat)
-        return -1;
-
-    nBitsPerBank = BankSize * 8;
-    if (nBitsPerBank % pBankFormat->scanlinePad)
-        return -1;
-
-    if (xsize > width)
-        width = xsize;
-    nBitsPerScanlinePadUnit = miLCM(pBankFormat->scanlinePad, nWidthUnit);
-    nBitsPerScanline =
-        (((width * pBankFormat->bitsPerPixel) + nBitsPerScanlinePadUnit - 1) /
-         nBitsPerScanlinePadUnit) * nBitsPerScanlinePadUnit;
-    width = nBitsPerScanline / pBankFormat->bitsPerPixel;
-
-    if (!xsize || !(nBitsPerBank % pBankFormat->bitsPerPixel))
-        return (int)width;
-
-    /*
-     * Scanlines will be server-pad aligned at this point.  They will also be
-     * a multiple of nWidthUnit bits long.  Ensure that pixels with imbedded
-     * bank boundaries are off-screen.
-     *
-     * It seems reasonable to limit total frame buffer size to 1/16 of the
-     * theoretical maximum address space size.  On a machine with 32-bit
-     * addresses (to 8-bit quantities) this turns out to be 256MB.  Not only
-     * does this provide a simple limiting condition for the loops below, but
-     * it also prevents unsigned long wraparounds.
-     */
-    if (!ysize)
-        return -1;
-
-    minBitsPerScanline = xsize * pBankFormat->bitsPerPixel;
-    if (minBitsPerScanline > nBitsPerBank)
-        return -1;
-
-    if (ysize == 1)
-        return (int)width;
-
-    maxBitsPerScanline =
-        (((unsigned long)(-1) >> 1) - minBitsPerScanline) / (ysize - 1);
-    while (nBitsPerScanline <= maxBitsPerScanline)
-    {
-        unsigned long BankBase, BankUnit;
-
-        BankUnit = ((nBitsPerBank + nBitsPerScanline - 1) / nBitsPerBank) *
-            nBitsPerBank;
-        if (!(BankUnit % nBitsPerScanline))
-            return (int)width;
-
-        for (BankBase = BankUnit;  ;  BankBase += nBitsPerBank)
-        {
-            unsigned long x, y;
-
-            y = BankBase / nBitsPerScanline;
-            if (y >= ysize)
-                return (int)width;
-
-            x = BankBase % nBitsPerScanline;
-            if (!(x % pBankFormat->bitsPerPixel))
-                continue;
-
-            if (x < minBitsPerScanline)
-            {
-                /*
-                 * Skip ahead certain widths by dividing the excess scanline
-                 * amongst the y's.
-                 */
-                y *= nBitsPerScanlinePadUnit;
-                nBitsPerScanline +=
-                    ((x + y - 1) / y) * nBitsPerScanlinePadUnit;
-                width = nBitsPerScanline / pBankFormat->bitsPerPixel;
-                break;
-            }
-
-            if (BankBase != BankUnit)
-                continue;
-
-            if (!(nBitsPerScanline % x))
-                return (int)width;
-
-            BankBase = ((nBitsPerScanline - minBitsPerScanline) /
-                (nBitsPerScanline - x)) * BankUnit;
-        }
-    }
-
-    return -1;
-}
diff --git a/mi/mibank.h b/mi/mibank.h
deleted file mode 100644
index 0c10540..0000000
--- a/mi/mibank.h
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi at xfree86.org
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that copyright
- * notice and this permission notice appear in supporting documentation, and
- * that the name of Marc Aurele La France not be used in advertising or
- * publicity pertaining to distribution of the software without specific,
- * written prior permission.  Marc Aurele La France makes no representations
- * about the suitability of this software for any purpose.  It is provided
- * "as-is" without express or implied warranty.
- *
- * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.  IN NO
- * EVENT SHALL MARC AURELE LA FRANCE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-
-#ifndef __MIBANK_H__
-#define __MIBANK_H__ 1
-
-#include "scrnintstr.h"
-
-/*
- * Banking external interface.
- */
-
-/*
- * This is the banking function type.  The return value is normally zero.
- * Non-zero returns can be used to implement the likes of scanline interleave,
- * etc.
- */
-typedef int miBankProc(
-    ScreenPtr /*pScreen*/,
-    unsigned int /*iBank*/
-);
-
-typedef miBankProc *miBankProcPtr;
-
-typedef struct _miBankInfo
-{
-    /*
-     * Banking refers to the use of one or more apertures (in the server's
-     * address space) to access various parts of a potentially larger hardware
-     * frame buffer.
-     *
-     * Three different banking schemes are supported:
-     *
-     * Single banking is indicated when pBankA and pBankB are equal and all
-     * three miBankProcPtr's point to the same function.  Here, both reads and
-     * writes through the aperture access the same hardware location.
-     *
-     * Shared banking is indicated when pBankA and pBankB are equal but the
-     * source and destination functions differ.  Here reads through the
-     * aperture do not necessarily access the same hardware location as writes.
-     *
-     * Double banking is indicated when pBankA and pBankB differ.  Here two
-     * independent apertures are used to provide read/write access to
-     * potentially different hardware locations.
-     *
-     * Any other combination will result in no banking.
-     */
-    miBankProcPtr SetSourceBank;                /* Set pBankA bank number */
-    miBankProcPtr SetDestinationBank;           /* Set pBankB bank number */
-    miBankProcPtr SetSourceAndDestinationBanks; /* Set both bank numbers */
-
-    pointer pBankA;     /* First aperture location */
-    pointer pBankB;     /* First or second aperture location */
-
-    /*
-     * BankSize is in units of sizeof(char) and is the size of each bank.
-     */
-    unsigned long BankSize;
-
-    /*
-     * nBankDepth is the colour depth associated with the maximum number of a
-     * pixel's bits that are simultaneously accessible through the frame buffer
-     * aperture.
-     */
-    unsigned int nBankDepth;
-} miBankInfoRec, *miBankInfoPtr;
-
-extern _X_EXPORT Bool
-miInitializeBanking(
-    ScreenPtr /*pScreen*/,
-    unsigned int /*xsize*/,
-    unsigned int /*ysize*/,
-    unsigned int /*width*/,
-    miBankInfoPtr /*pBankInfo*/
-);
-
-/*
- * This function determines the minimum screen width, given a initial estimate
- * and various screen attributes.  DDX needs to determine this width before
- * initializing the screen.
- */
-extern _X_EXPORT int
-miScanLineWidth(
-    unsigned int /*xsize*/,
-    unsigned int /*ysize*/,
-    unsigned int /*width*/,
-    unsigned long /*BankSize*/,
-    PixmapFormatRec * /*pBankFormat*/,
-    unsigned int /*nWidthUnit*/
-);
-
-#endif /* __MIBANK_H__ */
-- 
1.6.5.2



More information about the xorg-devel mailing list