---
 exa/exa_accel.c |    4 +-
 fb/fb.h         |   37 ------
 fb/fbcopy.c     |  331 +--------------------------------------------------
 fb/fboverlay.c  |    2 +-
 fb/fboverlay.h  |    2 +-
 fb/fbwindow.c   |    2 +-
 mi/Makefile.am  |    1 +
 mi/mi.h         |   42 +++++++
 mi/micopy.c     |  354 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 9 files changed, 406 insertions(+), 369 deletions(-)
 create mode 100644 mi/micopy.c

diff --git a/exa/exa_accel.c b/exa/exa_accel.c
index 02858f1..cc5dd18 100644
--- a/exa/exa_accel.c
+++ b/exa/exa_accel.c
@@ -524,7 +524,7 @@ exaCopyArea(DrawablePtr pSrcDrawable, DrawablePtr 
pDstDrawable, GCPtr pGC,
                                  srcx, srcy, width, height, dstx, dsty);
     }
 
-    return  fbDoCopy (pSrcDrawable, pDstDrawable, pGC,
+    return  miDoCopy (pSrcDrawable, pDstDrawable, pGC,
                       srcx, srcy, width, height,
                       dstx, dsty, exaCopyNtoN, 0, NULL);
 }
@@ -879,7 +879,7 @@ exaCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, 
RegionPtr prgnSrc)
                          -pPixmap->screen_x, -pPixmap->screen_y);
 #endif
 
-    fbCopyRegion (&pPixmap->drawable, &pPixmap->drawable,
+    miCopyRegion (&pPixmap->drawable, &pPixmap->drawable,
                  NULL,
                  &rgnDst, dx, dy, exaCopyNtoN, 0, NULL);
 
diff --git a/fb/fb.h b/fb/fb.h
index 8384315..cadb9a0 100644
--- a/fb/fb.h
+++ b/fb/fb.h
@@ -1306,18 +1306,6 @@ fbInitVisuals (VisualPtr    *visualp,
  * fbcopy.c
  */
 
-typedef void   (*fbCopyProc) (DrawablePtr  pSrcDrawable,
-                              DrawablePtr  pDstDrawable,
-                              GCPtr        pGC,
-                              BoxPtr       pDstBox,
-                              int          nbox,
-                              int          dx,
-                              int          dy,
-                              Bool         reverse,
-                              Bool         upsidedown,
-                              Pixel        bitplane,
-                              void         *closure);
-
 extern _X_EXPORT void
 fbCopyNtoN (DrawablePtr        pSrcDrawable,
            DrawablePtr pDstDrawable,
@@ -1357,31 +1345,6 @@ fbCopyNto1 (DrawablePtr  pSrcDrawable,
            Pixel       bitplane,
            void        *closure);
 
-extern _X_EXPORT void
-fbCopyRegion (DrawablePtr   pSrcDrawable,
-             DrawablePtr   pDstDrawable,
-             GCPtr         pGC,
-             RegionPtr     pDstRegion,
-             int           dx,
-             int           dy,
-             fbCopyProc    copyProc,
-             Pixel         bitPlane,
-             void          *closure);
-
-extern _X_EXPORT RegionPtr
-fbDoCopy (DrawablePtr  pSrcDrawable,
-         DrawablePtr   pDstDrawable,
-         GCPtr         pGC,
-         int           xIn, 
-         int           yIn,
-         int           widthSrc, 
-         int           heightSrc,
-         int           xOut, 
-         int           yOut,
-         fbCopyProc    copyProc,
-         Pixel         bitplane,
-         void          *closure);
-         
 extern _X_EXPORT RegionPtr
 fbCopyArea (DrawablePtr        pSrcDrawable,
            DrawablePtr pDstDrawable,
diff --git a/fb/fbcopy.c b/fb/fbcopy.c
index b8b0b6a..fed87a5 100644
--- a/fb/fbcopy.c
+++ b/fb/fbcopy.c
@@ -289,329 +289,6 @@ fbCopyNto1 (DrawablePtr   pSrcDrawable,
     }
 }
 
-void
-fbCopyRegion (DrawablePtr   pSrcDrawable,
-             DrawablePtr   pDstDrawable,
-             GCPtr         pGC,
-             RegionPtr     pDstRegion,
-             int           dx,
-             int           dy,
-             fbCopyProc    copyProc,
-             Pixel         bitPlane,
-             void          *closure)
-{
-    int                careful;
-    Bool       reverse;
-    Bool       upsidedown;
-    BoxPtr     pbox;
-    int                nbox;
-    BoxPtr     pboxNew1, pboxNew2, pboxBase, pboxNext, pboxTmp;
-    
-    pbox = REGION_RECTS(pDstRegion);
-    nbox = REGION_NUM_RECTS(pDstRegion);
-    
-    /* XXX we have to err on the side of safety when both are windows,
-     * because we don't know if IncludeInferiors is being used.
-     */
-    careful = ((pSrcDrawable == pDstDrawable) ||
-              ((pSrcDrawable->type == DRAWABLE_WINDOW) &&
-               (pDstDrawable->type == DRAWABLE_WINDOW)));
-
-    pboxNew1 = NULL;
-    pboxNew2 = NULL;
-    if (careful && dy < 0)
-    {
-       upsidedown = TRUE;
-
-       if (nbox > 1)
-       {
-           /* keep ordering in each band, reverse order of bands */
-           pboxNew1 = (BoxPtr)xalloc(sizeof(BoxRec) * nbox);
-           if(!pboxNew1)
-               return;
-           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;
-       }
-    }
-    else
-    {
-       /* walk source top to bottom */
-       upsidedown = FALSE;
-    }
-
-    if (careful && dx < 0)
-    {
-       /* walk source right to left */
-       if (dy <= 0)
-           reverse = TRUE;
-       else
-           reverse = FALSE;
-
-       if (nbox > 1)
-       {
-           /* reverse order of rects in each band */
-           pboxNew2 = (BoxPtr)xalloc(sizeof(BoxRec) * nbox);
-           if(!pboxNew2)
-           {
-               if (pboxNew1)
-                   xfree(pboxNew1);
-               return;
-           }
-           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;
-       }
-    }
-    else
-    {
-       /* walk source left to right */
-       reverse = FALSE;
-    }
-
-    (*copyProc) (pSrcDrawable,
-                pDstDrawable,
-                pGC,
-                pbox,
-                nbox,
-                dx, dy,
-                reverse, upsidedown, bitPlane, closure);
-    
-    if (pboxNew1)
-       xfree (pboxNew1);
-    if (pboxNew2)
-       xfree (pboxNew2);
-}
-
-RegionPtr
-fbDoCopy (DrawablePtr  pSrcDrawable,
-         DrawablePtr   pDstDrawable,
-         GCPtr         pGC,
-         int           xIn, 
-         int           yIn,
-         int           widthSrc, 
-         int           heightSrc,
-         int           xOut, 
-         int           yOut,
-         fbCopyProc    copyProc,
-         Pixel         bitPlane,
-         void          *closure)
-{
-    RegionPtr  prgnSrcClip = NULL; /* may be a new region, or just a copy */
-    Bool       freeSrcClip = FALSE;
-    RegionPtr  prgnExposed = NULL;
-    RegionRec  rgnDst;
-    int                dx;
-    int                dy;
-    int                numRects;
-    int         box_x1;
-    int         box_y1;
-    int         box_x2;
-    int         box_y2;
-    Bool       fastSrc = FALSE;    /* for fast clipping with pixmap source */
-    Bool       fastDst = FALSE;    /* for fast clipping with one rect dest */
-    Bool       fastExpose = FALSE; /* for fast exposures with pixmap source */
-
-    /* Short cut for unmapped windows */
-
-    if (pDstDrawable->type == DRAWABLE_WINDOW && 
-       !((WindowPtr)pDstDrawable)->realized)
-    {
-       return NULL;
-    }
-
-    if ((pSrcDrawable != pDstDrawable) &&
-       pSrcDrawable->pScreen->SourceValidate)
-    {
-       (*pSrcDrawable->pScreen->SourceValidate) (pSrcDrawable, xIn, yIn, 
widthSrc, heightSrc);
-    }
-
-    /* Compute source clip region */
-    if (pSrcDrawable->type == DRAWABLE_PIXMAP)
-    {
-       if ((pSrcDrawable == pDstDrawable) && (pGC->clientClipType == CT_NONE))
-           prgnSrcClip = fbGetCompositeClip(pGC);
-       else
-           fastSrc = TRUE;
-    }
-    else
-    {
-       if (pGC->subWindowMode == IncludeInferiors)
-       {
-           /*
-            * XFree86 DDX empties the border clip when the
-            * VT is inactive, make sure the region isn't empty
-            */
-           if (!((WindowPtr) pSrcDrawable)->parent &&
-               REGION_NOTEMPTY (pSrcDrawable->pScreen,
-                                &((WindowPtr) pSrcDrawable)->borderClip))
-           {
-               /*
-                * special case bitblt from root window in
-                * IncludeInferiors mode; just like from a pixmap
-                */
-               fastSrc = TRUE;
-           }
-           else if ((pSrcDrawable == pDstDrawable) &&
-                    (pGC->clientClipType == CT_NONE))
-           {
-               prgnSrcClip = fbGetCompositeClip(pGC);
-           }
-           else
-           {
-               prgnSrcClip = NotClippedByChildren((WindowPtr)pSrcDrawable);
-               freeSrcClip = TRUE;
-           }
-       }
-       else
-       {
-           prgnSrcClip = &((WindowPtr)pSrcDrawable)->clipList;
-       }
-    }
-
-    xIn += pSrcDrawable->x;
-    yIn += pSrcDrawable->y;
-    
-    xOut += pDstDrawable->x;
-    yOut += pDstDrawable->y;
-
-    box_x1 = xIn;
-    box_y1 = yIn;
-    box_x2 = xIn + widthSrc;
-    box_y2 = yIn + heightSrc;
-
-    dx = xIn - xOut;
-    dy = yIn - yOut;
-
-    /* Don't create a source region if we are doing a fast clip */
-    if (fastSrc)
-    {
-       RegionPtr cclip;
-    
-       fastExpose = TRUE;
-       /*
-        * clip the source; if regions extend beyond the source size,
-        * make sure exposure events get sent
-        */
-       if (box_x1 < pSrcDrawable->x)
-       {
-           box_x1 = pSrcDrawable->x;
-           fastExpose = FALSE;
-       }
-       if (box_y1 < pSrcDrawable->y)
-       {
-           box_y1 = pSrcDrawable->y;
-           fastExpose = FALSE;
-       }
-       if (box_x2 > pSrcDrawable->x + (int) pSrcDrawable->width)
-       {
-           box_x2 = pSrcDrawable->x + (int) pSrcDrawable->width;
-           fastExpose = FALSE;
-       }
-       if (box_y2 > pSrcDrawable->y + (int) pSrcDrawable->height)
-       {
-           box_y2 = pSrcDrawable->y + (int) pSrcDrawable->height;
-           fastExpose = FALSE;
-       }
-       
-       /* Translate and clip the dst to the destination composite clip */
-        box_x1 -= dx;
-        box_x2 -= dx;
-        box_y1 -= dy;
-        box_y2 -= dy;
-
-       /* If the destination composite clip is one rectangle we can
-          do the clip directly.  Otherwise we have to create a full
-          blown region and call intersect */
-
-       cclip = fbGetCompositeClip(pGC);
-        if (REGION_NUM_RECTS(cclip) == 1)
-        {
-           BoxPtr pBox = REGION_RECTS(cclip);
-
-           if (box_x1 < pBox->x1) box_x1 = pBox->x1;
-           if (box_x2 > pBox->x2) box_x2 = pBox->x2;
-           if (box_y1 < pBox->y1) box_y1 = pBox->y1;
-           if (box_y2 > pBox->y2) box_y2 = pBox->y2;
-           fastDst = TRUE;
-       }
-    }
-    
-    /* Check to see if the region is empty */
-    if (box_x1 >= box_x2 || box_y1 >= box_y2)
-    {
-       REGION_NULL(pGC->pScreen, &rgnDst);
-    }
-    else
-    {
-        BoxRec box;
-       box.x1 = box_x1;
-       box.y1 = box_y1;
-       box.x2 = box_x2;
-       box.y2 = box_y2;
-       REGION_INIT(pGC->pScreen, &rgnDst, &box, 1);
-    }
-    
-    /* Clip against complex source if needed */
-    if (!fastSrc)
-    {
-       REGION_INTERSECT(pGC->pScreen, &rgnDst, &rgnDst, prgnSrcClip);
-       REGION_TRANSLATE(pGC->pScreen, &rgnDst, -dx, -dy);
-    }
-
-    /* Clip against complex dest if needed */
-    if (!fastDst)
-    {
-       REGION_INTERSECT(pGC->pScreen, &rgnDst, &rgnDst,
-                        fbGetCompositeClip(pGC));
-    }
-
-    /* Do bit blitting */
-    numRects = REGION_NUM_RECTS(&rgnDst);
-    if (numRects && widthSrc && heightSrc)
-       fbCopyRegion (pSrcDrawable, pDstDrawable, pGC,
-                     &rgnDst, dx, dy, copyProc, bitPlane, closure);
-
-    /* Pixmap sources generate a NoExposed (we return NULL to do this) */
-    if (!fastExpose && pGC->fExpose)
-       prgnExposed = miHandleExposures(pSrcDrawable, pDstDrawable, pGC,
-                                       xIn - pSrcDrawable->x,
-                                       yIn - pSrcDrawable->y,
-                                       widthSrc, heightSrc,
-                                       xOut - pDstDrawable->x,
-                                       yOut - pDstDrawable->y,
-                                       (unsigned long) bitPlane);
-    REGION_UNINIT(pGC->pScreen, &rgnDst);
-    if (freeSrcClip)
-       REGION_DESTROY(pGC->pScreen, prgnSrcClip);
-    fbValidateDrawable (pDstDrawable);
-    return prgnExposed;
-}
-
 RegionPtr
 fbCopyArea (DrawablePtr        pSrcDrawable,
            DrawablePtr pDstDrawable,
@@ -623,7 +300,7 @@ fbCopyArea (DrawablePtr     pSrcDrawable,
            int         xOut, 
            int         yOut)
 {
-    fbCopyProc copy;
+    miCopyProc copy;
 
 #ifdef FB_24_32BIT
     if (pSrcDrawable->bitsPerPixel != pDstDrawable->bitsPerPixel)
@@ -631,7 +308,7 @@ fbCopyArea (DrawablePtr     pSrcDrawable,
     else
 #endif
        copy = fbCopyNtoN;
-    return fbDoCopy (pSrcDrawable, pDstDrawable, pGC, xIn, yIn,
+    return miDoCopy (pSrcDrawable, pDstDrawable, pGC, xIn, yIn,
                     widthSrc, heightSrc, xOut, yOut, copy, 0, 0);
 }
 
@@ -648,11 +325,11 @@ fbCopyPlane (DrawablePtr    pSrcDrawable,
             unsigned long  bitplane)
 {
     if (pSrcDrawable->bitsPerPixel > 1)
-       return fbDoCopy (pSrcDrawable, pDstDrawable, pGC,
+       return miDoCopy (pSrcDrawable, pDstDrawable, pGC,
                         xIn, yIn, widthSrc, heightSrc,
                         xOut, yOut, fbCopyNto1, (Pixel) bitplane, 0);
     else if (bitplane & 1)
-       return fbDoCopy (pSrcDrawable, pDstDrawable, pGC, xIn, yIn,
+       return miDoCopy (pSrcDrawable, pDstDrawable, pGC, xIn, yIn,
                         widthSrc, heightSrc, xOut, yOut, fbCopy1toN,
                         (Pixel) bitplane, 0);
     else
diff --git a/fb/fboverlay.c b/fb/fboverlay.c
index 1432cb6..99939e8 100644
--- a/fb/fboverlay.c
+++ b/fb/fboverlay.c
@@ -248,7 +248,7 @@ fbOverlayCopyWindow(WindowPtr       pWin,
        {
            REGION_TRANSLATE(pScreen, &layerRgn[i], -dx, -dy);
            pPixmap = pScrPriv->layer[i].u.run.pixmap;
-           fbCopyRegion (&pPixmap->drawable, &pPixmap->drawable,
+           miCopyRegion (&pPixmap->drawable, &pPixmap->drawable,
                          0,
                          &layerRgn[i], dx, dy, pScrPriv->CopyWindow, 0,
                          (void *)(long) i);
diff --git a/fb/fboverlay.h b/fb/fboverlay.h
index ed355af..b626a77 100644
--- a/fb/fboverlay.h
+++ b/fb/fboverlay.h
@@ -53,7 +53,7 @@ typedef struct _fbOverlayLayer {
 typedef struct _fbOverlayScrPriv {
     int                            nlayers;
     fbOverlayPaintKeyProc   PaintKey;
-    fbCopyProc             CopyWindow;
+    miCopyProc             CopyWindow;
     FbOverlayLayer         layer[FB_OVERLAY_MAX];
 } FbOverlayScrPrivRec, *FbOverlayScrPrivPtr;
 
diff --git a/fb/fbwindow.c b/fb/fbwindow.c
index 022a16f..46c0334 100644
--- a/fb/fbwindow.c
+++ b/fb/fbwindow.c
@@ -140,7 +140,7 @@ fbCopyWindow(WindowPtr          pWin,
                          -pPixmap->screen_x, -pPixmap->screen_y);
 #endif
 
-    fbCopyRegion (pDrawable, pDrawable,
+    miCopyRegion (pDrawable, pDrawable,
                  0,
                  &rgnDst, dx, dy, fbCopyWindowProc, 0, 0);
     
diff --git a/mi/Makefile.am b/mi/Makefile.am
index e6a4e60..979cc39 100644
--- a/mi/Makefile.am
+++ b/mi/Makefile.am
@@ -20,6 +20,7 @@ libmi_la_SOURCES =    \
        micmap.c        \
        micmap.h        \
        micoord.h       \
+       micopy.c        \
        micursor.c      \
        midash.c        \
        midispcur.c     \
diff --git a/mi/mi.h b/mi/mi.h
index 23f9abb..c44ff06 100644
--- a/mi/mi.h
+++ b/mi/mi.h
@@ -56,6 +56,7 @@ SOFTWARE.
 #include "input.h"
 #include "cursor.h"
 #include "privates.h"
+#include "colormap.h"
 
 #define MiBits CARD32
 
@@ -123,6 +124,47 @@ extern _X_EXPORT void miPutImage(
     char * /*pImage*/
 );
 
+/* micopy.c  */
+
+#define miGetCompositeClip(pGC) ((pGC)->pCompositeClip)
+
+typedef void   (*miCopyProc) (DrawablePtr  pSrcDrawable,
+                              DrawablePtr  pDstDrawable,
+                              GCPtr        pGC,
+                              BoxPtr       pDstBox,
+                              int          nbox,
+                              int          dx,
+                              int          dy,
+                              Bool         reverse,
+                              Bool         upsidedown,
+                              Pixel        bitplane,
+                              void         *closure);
+
+extern _X_EXPORT void
+miCopyRegion (DrawablePtr   pSrcDrawable,
+             DrawablePtr   pDstDrawable,
+             GCPtr         pGC,
+             RegionPtr     pDstRegion,
+             int           dx,
+             int           dy,
+             miCopyProc    copyProc,
+             Pixel         bitPlane,
+             void          *closure);
+
+extern _X_EXPORT RegionPtr
+miDoCopy (DrawablePtr  pSrcDrawable,
+         DrawablePtr   pDstDrawable,
+         GCPtr         pGC,
+         int           xIn, 
+         int           yIn,
+         int           widthSrc, 
+         int           heightSrc,
+         int           xOut, 
+         int           yOut,
+         miCopyProc    copyProc,
+         Pixel         bitplane,
+         void          *closure);
+
 /* micursor.c */
 
 extern _X_EXPORT void miRecolorCursor(
diff --git a/mi/micopy.c b/mi/micopy.c
new file mode 100644
index 0000000..3719f46
--- /dev/null
+++ b/mi/micopy.c
@@ -0,0 +1,354 @@
+/*
+ * Copyright © 1998 Keith Packard
+ *
+ * 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 Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission.  Keith Packard makes no
+ * representations about the suitability of this software for any purpose.  It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "mi.h"
+#include "scrnintstr.h"
+#include "gcstruct.h"
+#include "pixmap.h"
+#include "pixmapstr.h"
+#include "windowstr.h"
+
+void
+miCopyRegion (DrawablePtr   pSrcDrawable,
+             DrawablePtr   pDstDrawable,
+             GCPtr         pGC,
+             RegionPtr     pDstRegion,
+             int           dx,
+             int           dy,
+             miCopyProc    copyProc,
+             Pixel         bitPlane,
+             void          *closure)
+{
+    int                careful;
+    Bool       reverse;
+    Bool       upsidedown;
+    BoxPtr     pbox;
+    int                nbox;
+    BoxPtr     pboxNew1, pboxNew2, pboxBase, pboxNext, pboxTmp;
+    
+    pbox = REGION_RECTS(pDstRegion);
+    nbox = REGION_NUM_RECTS(pDstRegion);
+    
+    /* XXX we have to err on the side of safety when both are windows,
+     * because we don't know if IncludeInferiors is being used.
+     */
+    careful = ((pSrcDrawable == pDstDrawable) ||
+              ((pSrcDrawable->type == DRAWABLE_WINDOW) &&
+               (pDstDrawable->type == DRAWABLE_WINDOW)));
+
+    pboxNew1 = NULL;
+    pboxNew2 = NULL;
+    if (careful && dy < 0)
+    {
+       upsidedown = TRUE;
+
+       if (nbox > 1)
+       {
+           /* keep ordering in each band, reverse order of bands */
+           pboxNew1 = (BoxPtr)xalloc(sizeof(BoxRec) * nbox);
+           if(!pboxNew1)
+               return;
+           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;
+       }
+    }
+    else
+    {
+       /* walk source top to bottom */
+       upsidedown = FALSE;
+    }
+
+    if (careful && dx < 0)
+    {
+       /* walk source right to left */
+       if (dy <= 0)
+           reverse = TRUE;
+       else
+           reverse = FALSE;
+
+       if (nbox > 1)
+       {
+           /* reverse order of rects in each band */
+           pboxNew2 = (BoxPtr)xalloc(sizeof(BoxRec) * nbox);
+           if(!pboxNew2)
+           {
+               if (pboxNew1)
+                   xfree(pboxNew1);
+               return;
+           }
+           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;
+       }
+    }
+    else
+    {
+       /* walk source left to right */
+       reverse = FALSE;
+    }
+
+    (*copyProc) (pSrcDrawable,
+                pDstDrawable,
+                pGC,
+                pbox,
+                nbox,
+                dx, dy,
+                reverse, upsidedown, bitPlane, closure);
+    
+    if (pboxNew1)
+       xfree (pboxNew1);
+    if (pboxNew2)
+       xfree (pboxNew2);
+}
+
+RegionPtr
+miDoCopy (DrawablePtr  pSrcDrawable,
+         DrawablePtr   pDstDrawable,
+         GCPtr         pGC,
+         int           xIn, 
+         int           yIn,
+         int           widthSrc, 
+         int           heightSrc,
+         int           xOut, 
+         int           yOut,
+         miCopyProc    copyProc,
+         Pixel         bitPlane,
+         void          *closure)
+{
+    RegionPtr  prgnSrcClip = NULL; /* may be a new region, or just a copy */
+    Bool       freeSrcClip = FALSE;
+    RegionPtr  prgnExposed = NULL;
+    RegionRec  rgnDst;
+    int                dx;
+    int                dy;
+    int                numRects;
+    int         box_x1;
+    int         box_y1;
+    int         box_x2;
+    int         box_y2;
+    Bool       fastSrc = FALSE;    /* for fast clipping with pixmap source */
+    Bool       fastDst = FALSE;    /* for fast clipping with one rect dest */
+    Bool       fastExpose = FALSE; /* for fast exposures with pixmap source */
+
+    /* Short cut for unmapped windows */
+
+    if (pDstDrawable->type == DRAWABLE_WINDOW && 
+       !((WindowPtr)pDstDrawable)->realized)
+    {
+       return NULL;
+    }
+
+    if ((pSrcDrawable != pDstDrawable) &&
+       pSrcDrawable->pScreen->SourceValidate)
+    {
+       (*pSrcDrawable->pScreen->SourceValidate) (pSrcDrawable, xIn, yIn, 
widthSrc, heightSrc);
+    }
+
+    /* Compute source clip region */
+    if (pSrcDrawable->type == DRAWABLE_PIXMAP)
+    {
+       if ((pSrcDrawable == pDstDrawable) && (pGC->clientClipType == CT_NONE))
+           prgnSrcClip = miGetCompositeClip(pGC);
+       else
+           fastSrc = TRUE;
+    }
+    else
+    {
+       if (pGC->subWindowMode == IncludeInferiors)
+       {
+           /*
+            * XFree86 DDX empties the border clip when the
+            * VT is inactive, make sure the region isn't empty
+            */
+           if (!((WindowPtr) pSrcDrawable)->parent &&
+               REGION_NOTEMPTY (pSrcDrawable->pScreen,
+                                &((WindowPtr) pSrcDrawable)->borderClip))
+           {
+               /*
+                * special case bitblt from root window in
+                * IncludeInferiors mode; just like from a pixmap
+                */
+               fastSrc = TRUE;
+           }
+           else if ((pSrcDrawable == pDstDrawable) &&
+                    (pGC->clientClipType == CT_NONE))
+           {
+               prgnSrcClip = miGetCompositeClip(pGC);
+           }
+           else
+           {
+               prgnSrcClip = NotClippedByChildren((WindowPtr)pSrcDrawable);
+               freeSrcClip = TRUE;
+           }
+       }
+       else
+       {
+           prgnSrcClip = &((WindowPtr)pSrcDrawable)->clipList;
+       }
+    }
+
+    xIn += pSrcDrawable->x;
+    yIn += pSrcDrawable->y;
+    
+    xOut += pDstDrawable->x;
+    yOut += pDstDrawable->y;
+
+    box_x1 = xIn;
+    box_y1 = yIn;
+    box_x2 = xIn + widthSrc;
+    box_y2 = yIn + heightSrc;
+
+    dx = xIn - xOut;
+    dy = yIn - yOut;
+
+    /* Don't create a source region if we are doing a fast clip */
+    if (fastSrc)
+    {
+       RegionPtr cclip;
+    
+       fastExpose = TRUE;
+       /*
+        * clip the source; if regions extend beyond the source size,
+        * make sure exposure events get sent
+        */
+       if (box_x1 < pSrcDrawable->x)
+       {
+           box_x1 = pSrcDrawable->x;
+           fastExpose = FALSE;
+       }
+       if (box_y1 < pSrcDrawable->y)
+       {
+           box_y1 = pSrcDrawable->y;
+           fastExpose = FALSE;
+       }
+       if (box_x2 > pSrcDrawable->x + (int) pSrcDrawable->width)
+       {
+           box_x2 = pSrcDrawable->x + (int) pSrcDrawable->width;
+           fastExpose = FALSE;
+       }
+       if (box_y2 > pSrcDrawable->y + (int) pSrcDrawable->height)
+       {
+           box_y2 = pSrcDrawable->y + (int) pSrcDrawable->height;
+           fastExpose = FALSE;
+       }
+       
+       /* Translate and clip the dst to the destination composite clip */
+        box_x1 -= dx;
+        box_x2 -= dx;
+        box_y1 -= dy;
+        box_y2 -= dy;
+
+       /* If the destination composite clip is one rectangle we can
+          do the clip directly.  Otherwise we have to create a full
+          blown region and call intersect */
+
+       cclip = miGetCompositeClip(pGC);
+        if (REGION_NUM_RECTS(cclip) == 1)
+        {
+           BoxPtr pBox = REGION_RECTS(cclip);
+
+           if (box_x1 < pBox->x1) box_x1 = pBox->x1;
+           if (box_x2 > pBox->x2) box_x2 = pBox->x2;
+           if (box_y1 < pBox->y1) box_y1 = pBox->y1;
+           if (box_y2 > pBox->y2) box_y2 = pBox->y2;
+           fastDst = TRUE;
+       }
+    }
+    
+    /* Check to see if the region is empty */
+    if (box_x1 >= box_x2 || box_y1 >= box_y2)
+    {
+       REGION_NULL(pGC->pScreen, &rgnDst);
+    }
+    else
+    {
+        BoxRec box;
+       box.x1 = box_x1;
+       box.y1 = box_y1;
+       box.x2 = box_x2;
+       box.y2 = box_y2;
+       REGION_INIT(pGC->pScreen, &rgnDst, &box, 1);
+    }
+    
+    /* Clip against complex source if needed */
+    if (!fastSrc)
+    {
+       REGION_INTERSECT(pGC->pScreen, &rgnDst, &rgnDst, prgnSrcClip);
+       REGION_TRANSLATE(pGC->pScreen, &rgnDst, -dx, -dy);
+    }
+
+    /* Clip against complex dest if needed */
+    if (!fastDst)
+    {
+       REGION_INTERSECT(pGC->pScreen, &rgnDst, &rgnDst,
+                        miGetCompositeClip(pGC));
+    }
+
+    /* Do bit blitting */
+    numRects = REGION_NUM_RECTS(&rgnDst);
+    if (numRects && widthSrc && heightSrc)
+       miCopyRegion (pSrcDrawable, pDstDrawable, pGC,
+                     &rgnDst, dx, dy, copyProc, bitPlane, closure);
+
+    /* Pixmap sources generate a NoExposed (we return NULL to do this) */
+    if (!fastExpose && pGC->fExpose)
+       prgnExposed = miHandleExposures(pSrcDrawable, pDstDrawable, pGC,
+                                       xIn - pSrcDrawable->x,
+                                       yIn - pSrcDrawable->y,
+                                       widthSrc, heightSrc,
+                                       xOut - pDstDrawable->x,
+                                       yOut - pDstDrawable->y,
+                                       (unsigned long) bitPlane);
+    REGION_UNINIT(pGC->pScreen, &rgnDst);
+    if (freeSrcClip)
+       REGION_DESTROY(pGC->pScreen, prgnSrcClip);
+    return prgnExposed;
+}
-- 
1.6.1.1

_______________________________________________
xorg mailing list
xorg@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/xorg

Reply via email to