- Compatibility wrappers, if deemed neccesary will come later.
---
 fb/Makefile.am      |    3 +-
 fb/fb.h             |   37 +-----
 fb/fb24_32.c        |    4 +-
 fb/fbcopy.c         |  342 ++---------------------------------------------
 fb/fbcopy_helpers.c |  367 +++++++++++++++++++++++++++++++++++++++++++++++++++
 fb/fbcopy_helpers.h |   52 +++++++
 fb/fboverlay.c      |    1 +
 fb/fbwindow.c       |    5 +-
 8 files changed, 448 insertions(+), 363 deletions(-)
 create mode 100644 fb/fbcopy_helpers.c
 create mode 100644 fb/fbcopy_helpers.h

diff --git a/fb/Makefile.am b/fb/Makefile.am
index 64e49f3..cfd9364 100644
--- a/fb/Makefile.am
+++ b/fb/Makefile.am
@@ -7,7 +7,7 @@ INCLUDES = \
 AM_CFLAGS = $(DIX_CFLAGS)
 
 if XORG
-sdk_HEADERS = fb.h fbrop.h fboverlay.h wfbrename.h fbpict.h
+sdk_HEADERS = fb.h fbrop.h fboverlay.h wfbrename.h fbpict.h fbcopy_helpers.h
 endif
 
 libfb_la_CFLAGS = $(AM_CFLAGS)
@@ -24,6 +24,7 @@ libfb_la_SOURCES =    \
        fbbits.h        \
        fbblt.c         \
        fbbltone.c      \
+       fbcopy_helpers.c        \
        fbcopy.c        \
        fbfill.c        \
        fbfillrect.c    \
diff --git a/fb/fb.h b/fb/fb.h
index 8384315..b0898b0 100644
--- a/fb/fb.h
+++ b/fb/fb.h
@@ -788,7 +788,7 @@ fb24_32GetImage (DrawablePtr     pDrawable,
                 unsigned long   planeMask,
                 char            *d);
 
-extern _X_EXPORT void
+extern _X_EXPORT Bool
 fb24_32CopyMtoN (DrawablePtr pSrcDrawable,
                 DrawablePtr pDstDrawable,
                 GCPtr       pGC,
@@ -1306,7 +1306,7 @@ fbInitVisuals (VisualPtr    *visualp,
  * fbcopy.c
  */
 
-typedef void   (*fbCopyProc) (DrawablePtr  pSrcDrawable,
+typedef Bool   (*fbCopyProc) (DrawablePtr  pSrcDrawable,
                               DrawablePtr  pDstDrawable,
                               GCPtr        pGC,
                               BoxPtr       pDstBox,
@@ -1318,7 +1318,7 @@ typedef void      (*fbCopyProc) (DrawablePtr  
pSrcDrawable,
                               Pixel        bitplane,
                               void         *closure);
 
-extern _X_EXPORT void
+extern _X_EXPORT Bool
 fbCopyNtoN (DrawablePtr        pSrcDrawable,
            DrawablePtr pDstDrawable,
            GCPtr       pGC,
@@ -1331,7 +1331,7 @@ fbCopyNtoN (DrawablePtr   pSrcDrawable,
            Pixel       bitplane,
            void        *closure);
 
-extern _X_EXPORT void
+extern _X_EXPORT Bool
 fbCopy1toN (DrawablePtr        pSrcDrawable,
            DrawablePtr pDstDrawable,
            GCPtr       pGC,
@@ -1344,7 +1344,7 @@ fbCopy1toN (DrawablePtr   pSrcDrawable,
            Pixel       bitplane,
            void        *closure);
 
-extern _X_EXPORT void
+extern _X_EXPORT Bool
 fbCopyNto1 (DrawablePtr        pSrcDrawable,
            DrawablePtr pDstDrawable,
            GCPtr       pGC,
@@ -1357,31 +1357,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,
@@ -2036,7 +2011,7 @@ fbPositionWindow(WindowPtr pWin, int x, int y);
 extern _X_EXPORT Bool
 fbUnmapWindow(WindowPtr pWindow);
     
-extern _X_EXPORT void
+extern _X_EXPORT Bool
 fbCopyWindowProc (DrawablePtr  pSrcDrawable,
                  DrawablePtr   pDstDrawable,
                  GCPtr         pGC,
diff --git a/fb/fb24_32.c b/fb/fb24_32.c
index 1ebd598..952b9ff 100644
--- a/fb/fb24_32.c
+++ b/fb/fb24_32.c
@@ -472,7 +472,7 @@ fb24_32GetImage (DrawablePtr     pDrawable,
     fbFinishAccess (pDrawable);
 }
 
-void
+Bool
 fb24_32CopyMtoN (DrawablePtr pSrcDrawable,
                 DrawablePtr pDstDrawable,
                 GCPtr       pGC,
@@ -529,6 +529,8 @@ fb24_32CopyMtoN (DrawablePtr pSrcDrawable,
 
     fbFinishAccess (pSrcDrawable);
     fbFinishAccess (pDstDrawable);
+
+    return TRUE;
 }
 
 PixmapPtr
diff --git a/fb/fbcopy.c b/fb/fbcopy.c
index b8b0b6a..2f430b7 100644
--- a/fb/fbcopy.c
+++ b/fb/fbcopy.c
@@ -27,8 +27,9 @@
 #include <stdlib.h>
 
 #include "fb.h"
+#include "fbcopy_helpers.h"
 
-void
+Bool
 fbCopyNtoN (DrawablePtr        pSrcDrawable,
            DrawablePtr pDstDrawable,
            GCPtr       pGC,
@@ -98,9 +99,11 @@ fbCopyNtoN (DrawablePtr      pSrcDrawable,
     }    
     fbFinishAccess (pDstDrawable);
     fbFinishAccess (pSrcDrawable);
+
+    return TRUE;
 }
 
-void
+Bool
 fbCopy1toN (DrawablePtr        pSrcDrawable,
            DrawablePtr pDstDrawable,
            GCPtr       pGC,
@@ -171,9 +174,11 @@ fbCopy1toN (DrawablePtr    pSrcDrawable,
 
     fbFinishAccess (pDstDrawable);
     fbFinishAccess (pSrcDrawable);
+
+    return TRUE;
 }
 
-void
+Bool
 fbCopyNto1 (DrawablePtr        pSrcDrawable,
            DrawablePtr pDstDrawable,
            GCPtr       pGC,
@@ -244,7 +249,7 @@ fbCopyNto1 (DrawablePtr     pSrcDrawable,
            tmpStride = ((width + FB_STIP_MASK) >> FB_STIP_SHIFT);
            tmp = xalloc (tmpStride * height * sizeof (FbStip));
            if (!tmp)
-               return;
+               return FALSE;
            
            fbGetDrawable (pSrcDrawable, src, srcStride, srcBpp, srcXoff, 
srcYoff);
            fbGetDrawable (pDstDrawable, dst, dstStride, dstBpp, dstXoff, 
dstYoff);
@@ -287,329 +292,8 @@ fbCopyNto1 (DrawablePtr   pSrcDrawable,
        }
        pbox++;
     }
-}
-
-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;
+    return TRUE;
 }
 
 RegionPtr
@@ -632,7 +316,7 @@ fbCopyArea (DrawablePtr     pSrcDrawable,
 #endif
        copy = fbCopyNtoN;
     return fbDoCopy (pSrcDrawable, pDstDrawable, pGC, xIn, yIn,
-                    widthSrc, heightSrc, xOut, yOut, copy, 0, 0);
+                    widthSrc, heightSrc, xOut, yOut, copy, 0, 0, NULL);
 }
 
 RegionPtr
@@ -650,11 +334,11 @@ fbCopyPlane (DrawablePtr    pSrcDrawable,
     if (pSrcDrawable->bitsPerPixel > 1)
        return fbDoCopy (pSrcDrawable, pDstDrawable, pGC,
                         xIn, yIn, widthSrc, heightSrc,
-                        xOut, yOut, fbCopyNto1, (Pixel) bitplane, 0);
+                        xOut, yOut, fbCopyNto1, (Pixel) bitplane, 0, NULL);
     else if (bitplane & 1)
        return fbDoCopy (pSrcDrawable, pDstDrawable, pGC, xIn, yIn,
                         widthSrc, heightSrc, xOut, yOut, fbCopy1toN,
-                        (Pixel) bitplane, 0);
+                        (Pixel) bitplane, 0, NULL);
     else
        return miHandleExposures(pSrcDrawable, pDstDrawable, pGC,
                                 xIn, yIn,
diff --git a/fb/fbcopy_helpers.c b/fb/fbcopy_helpers.c
new file mode 100644
index 0000000..b51b0ad
--- /dev/null
+++ b/fb/fbcopy_helpers.c
@@ -0,0 +1,367 @@
+/*
+ * 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 <stdlib.h>
+
+#include "fb.h"
+#include "fbcopy_helpers.h"
+
+Bool
+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;
+    Bool ret;
+
+    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 FALSE;
+           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 FALSE;
+           }
+           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;
+    }
+
+    ret = (*copyProc) (pSrcDrawable,
+                pDstDrawable,
+                pGC,
+                pbox,
+                nbox,
+                dx, dy,
+                reverse, upsidedown, bitPlane, closure);
+    
+    if (pboxNew1)
+       xfree (pboxNew1);
+    if (pboxNew2)
+       xfree (pboxNew2);
+
+    return ret;
+}
+
+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,
+         Bool          *success)
+{
+    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 */
+    Bool       ret;
+
+    /* Short cut for unmapped windows */
+
+    if (pDstDrawable->type == DRAWABLE_WINDOW && 
+       !((WindowPtr)pDstDrawable)->realized)
+    {
+       if (success)
+           *success = TRUE;
+       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)
+       ret = fbCopyRegion (pSrcDrawable, pDstDrawable, pGC,
+                     &rgnDst, dx, dy, copyProc, bitPlane, closure);
+    else
+       ret = TRUE;
+
+    /* Pixmap sources generate a NoExposed (we return NULL to do this) */
+    if (ret && !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);
+
+    /* Some users want to allow failure. */
+    if (success)
+       *success = ret;
+
+    return prgnExposed;
+}
\ No newline at end of file
diff --git a/fb/fbcopy_helpers.h b/fb/fbcopy_helpers.h
new file mode 100644
index 0000000..d523e92
--- /dev/null
+++ b/fb/fbcopy_helpers.h
@@ -0,0 +1,52 @@
+/*
+ * 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.
+ */
+
+#ifndef _FBCOPY_HELPERS_H_
+#define _FBCOPY_HELPERS_H_
+
+extern _X_EXPORT Bool
+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,
+         Bool          *success);
+
+#endif /* _FBCOPY_HELPERS_H_ */
diff --git a/fb/fboverlay.c b/fb/fboverlay.c
index 1432cb6..f90f4c5 100644
--- a/fb/fboverlay.c
+++ b/fb/fboverlay.c
@@ -30,6 +30,7 @@
 #include <stdlib.h>
 
 #include "fb.h"
+#include "fbcopy_helpers.h"
 #include "fboverlay.h"
 #include "shmint.h"
 
diff --git a/fb/fbwindow.c b/fb/fbwindow.c
index 022a16f..9730b2b 100644
--- a/fb/fbwindow.c
+++ b/fb/fbwindow.c
@@ -27,6 +27,7 @@
 #include <stdlib.h>
 
 #include "fb.h"
+#include "fbcopy_helpers.h"
 
 Bool
 fbCreateWindow(WindowPtr pWin)
@@ -64,7 +65,7 @@ fbUnmapWindow(WindowPtr pWindow)
     return TRUE;
 }
 
-void
+Bool
 fbCopyWindowProc (DrawablePtr  pSrcDrawable,
                  DrawablePtr   pDstDrawable,
                  GCPtr         pGC,
@@ -113,6 +114,8 @@ fbCopyWindowProc (DrawablePtr       pSrcDrawable,
 
     fbFinishAccess (pDstDrawable);
     fbFinishAccess (pSrcDrawable);
+
+    return TRUE;
 }
 
 void
-- 
1.6.1.1

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

Reply via email to