[PATCH 8/9] fb: move some code to mi

Maarten Maathuis madman2003 at gmail.com
Thu Feb 5 08:15:09 PST 2009


---
 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




More information about the xorg mailing list