[PATCH 8/9] fb: split off a few functions into a seperate file and enhance them slightly.

Maarten Maathuis madman2003 at gmail.com
Tue Feb 3 11:06:30 PST 2009


- 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




More information about the xorg mailing list