From 9508a382f8a9f241dab097d921b6d290c1c3a776 Mon Sep 17 00:00:00 2001
From: Kaleb Keithley <kaleb@freedesktop.org>
Date: Fri, 14 Nov 2003 16:48:57 +0000
Subject: Initial revision

---
 hw/xfree86/xf4bpp/ppcCpArea.c | 494 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 494 insertions(+)
 create mode 100644 hw/xfree86/xf4bpp/ppcCpArea.c

(limited to 'hw/xfree86/xf4bpp/ppcCpArea.c')

diff --git a/hw/xfree86/xf4bpp/ppcCpArea.c b/hw/xfree86/xf4bpp/ppcCpArea.c
new file mode 100644
index 000000000..e5202c267
--- /dev/null
+++ b/hw/xfree86/xf4bpp/ppcCpArea.c
@@ -0,0 +1,494 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xf4bpp/ppcCpArea.c,v 1.5 2000/09/26 15:57:21 tsi Exp $ */
+/*
+ * Copyright IBM Corporation 1987,1988,1989
+ *
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted,
+ * 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 IBM not be
+ * used in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ *
+ * IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+ * IBM 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.
+ *
+*/
+
+/* $XConsortium: ppcCpArea.c /main/6 1996/02/21 17:57:24 kaleb $ */
+
+/***********************************************************
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+                        All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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.
+
+******************************************************************/
+
+#include "xf4bpp.h"
+#include "mfbmap.h"
+#define PSZ 8
+#include "cfb.h"
+#include "cfbmskbits.h"
+#include "mergerop.h"
+#include "mi.h"
+#include "pixmapstr.h"
+#include "scrnintstr.h"
+
+/*
+ * Graft in the DoBitblt from cfb. It does everything correctly.
+ */
+static void
+vga16DoBitblt
+(
+    DrawablePtr	    pSrc,
+    DrawablePtr	    pDst,
+    int		    alu,
+    RegionPtr	    prgnDst,
+    DDXPointPtr	    pptSrc,
+    unsigned long   planemask
+)
+{
+    CARD32 *psrcBase, *pdstBase;	
+				/* start of src and dst bitmaps */
+    int widthSrc, widthDst;	/* add to get to same position in next line */
+
+    BoxPtr pbox;
+    int nbox;
+
+    BoxPtr pboxTmp, pboxNext, pboxBase, pboxNew1, pboxNew2;
+				/* temporaries for shuffling rectangles */
+    DDXPointPtr pptTmp, pptNew1, pptNew2;
+				/* shuffling boxes entails shuffling the
+				   source points too */
+    int w, h;
+    int xdir;			/* 1 = left right, -1 = right left/ */
+    int ydir;			/* 1 = top down, -1 = bottom up */
+
+    MROP_DECLARE_REG()
+
+    int careful;
+
+    MROP_INITIALIZE(alu,planemask);
+
+    cfbGetLongWidthAndPointer (pSrc, widthSrc, psrcBase)
+
+    cfbGetLongWidthAndPointer (pDst, widthDst, pdstBase)
+
+    /* 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 = ((pSrc == pDst) ||
+	       ((pSrc->type == DRAWABLE_WINDOW) &&
+		(pDst->type == DRAWABLE_WINDOW)));
+
+    pbox = REGION_RECTS(prgnDst);
+    nbox = REGION_NUM_RECTS(prgnDst);
+
+    pboxNew1 = NULL;
+    pptNew1 = NULL;
+    pboxNew2 = NULL;
+    pptNew2 = NULL;
+    if (careful && (pptSrc->y < pbox->y1))
+    {
+        /* walk source botttom to top */
+	ydir = -1;
+	widthSrc = -widthSrc;
+	widthDst = -widthDst;
+
+	if (nbox > 1)
+	{
+	    /* keep ordering in each band, reverse order of bands */
+	    pboxNew1 = (BoxPtr)ALLOCATE_LOCAL(sizeof(BoxRec) * nbox);
+	    if(!pboxNew1)
+		return;
+	    pptNew1 = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec) * nbox);
+	    if(!pptNew1)
+	    {
+	        DEALLOCATE_LOCAL(pboxNew1);
+	        return;
+	    }
+	    pboxBase = pboxNext = pbox+nbox-1;
+	    while (pboxBase >= pbox)
+	    {
+	        while ((pboxNext >= pbox) &&
+		       (pboxBase->y1 == pboxNext->y1))
+		    pboxNext--;
+	        pboxTmp = pboxNext+1;
+	        pptTmp = pptSrc + (pboxTmp - pbox);
+	        while (pboxTmp <= pboxBase)
+	        {
+		    *pboxNew1++ = *pboxTmp++;
+		    *pptNew1++ = *pptTmp++;
+	        }
+	        pboxBase = pboxNext;
+	    }
+	    pboxNew1 -= nbox;
+	    pbox = pboxNew1;
+	    pptNew1 -= nbox;
+	    pptSrc = pptNew1;
+        }
+    }
+    else
+    {
+	/* walk source top to bottom */
+	ydir = 1;
+    }
+
+    if (careful && (pptSrc->x < pbox->x1))
+    {
+	/* walk source right to left */
+        xdir = -1;
+
+	if (nbox > 1)
+	{
+	    /* reverse order of rects in each band */
+	    pboxNew2 = (BoxPtr)ALLOCATE_LOCAL(sizeof(BoxRec) * nbox);
+	    pptNew2 = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec) * nbox);
+	    if(!pboxNew2 || !pptNew2)
+	    {
+		if (pptNew2) DEALLOCATE_LOCAL(pptNew2);
+		if (pboxNew2) DEALLOCATE_LOCAL(pboxNew2);
+		if (pboxNew1)
+		{
+		    DEALLOCATE_LOCAL(pptNew1);
+		    DEALLOCATE_LOCAL(pboxNew1);
+		}
+	        return;
+	    }
+	    pboxBase = pboxNext = pbox;
+	    while (pboxBase < pbox+nbox)
+	    {
+	        while ((pboxNext < pbox+nbox) &&
+		       (pboxNext->y1 == pboxBase->y1))
+		    pboxNext++;
+	        pboxTmp = pboxNext;
+	        pptTmp = pptSrc + (pboxTmp - pbox);
+	        while (pboxTmp != pboxBase)
+	        {
+		    *pboxNew2++ = *--pboxTmp;
+		    *pptNew2++ = *--pptTmp;
+	        }
+	        pboxBase = pboxNext;
+	    }
+	    pboxNew2 -= nbox;
+	    pbox = pboxNew2;
+	    pptNew2 -= nbox;
+	    pptSrc = pptNew2;
+	}
+    }
+    else
+    {
+	/* walk source left to right */
+        xdir = 1;
+    }
+
+    while(nbox--)
+    {
+	w = pbox->x2 - pbox->x1;
+	h = pbox->y2 - pbox->y1;
+	
+	if( pSrc->type == DRAWABLE_WINDOW )
+		xf4bppBitBlt( (WindowPtr)pDst, alu, planemask,
+			pptSrc->x,		/* x0 */
+			pptSrc->y,		/* y0 */
+			pbox->x1,		/* x1 */
+			pbox->y1,		/* y1 */
+			w, h );			/* w, h */
+	    else /* DRAWABLE_PIXMAP */
+		xf4bppDrawColorImage( (WindowPtr)pDst,
+			pbox->x1, pbox->y1,
+			w,
+			h,
+			((unsigned char *)((PixmapPtr)pSrc)->devPrivate.ptr
+			 + pptSrc->x + (pptSrc->y*((PixmapPtr)pSrc)->devKind)),
+			((PixmapPtr)pSrc)->devKind,
+			alu, planemask ) ;
+	pbox++;
+	pptSrc++;
+    }
+    if (pboxNew2)
+    {
+	DEALLOCATE_LOCAL(pptNew2);
+	DEALLOCATE_LOCAL(pboxNew2);
+    }
+    if (pboxNew1)
+    {
+	DEALLOCATE_LOCAL(pptNew1);
+	DEALLOCATE_LOCAL(pboxNew1);
+    }
+}
+
+
+/*
+ * Graft in the CopyArea from mfb/cfb. It does everything correctly.
+ */
+
+RegionPtr
+xf4bppCopyArea(pSrcDrawable, pDstDrawable,
+	    pGC, srcx, srcy, width, height, dstx, dsty)
+register DrawablePtr pSrcDrawable;
+register DrawablePtr pDstDrawable;
+register GC *pGC;
+int srcx, srcy;
+int width, height;
+int dstx, dsty;
+{
+    RegionPtr prgnSrcClip = NULL;   /* may be a new region, or just a copy */
+    Bool freeSrcClip = FALSE;
+
+    RegionPtr prgnExposed;
+    RegionRec rgnDst;
+    DDXPointPtr pptSrc;
+    register DDXPointPtr ppt;
+    register BoxPtr pbox;
+    int i;
+    register int dx;
+    register int dy;
+    xRectangle origSource;
+    DDXPointRec origDest;
+    int numRects;
+    BoxRec fastBox;
+    int fastClip = 0;		/* for fast clipping with pixmap source */
+    int fastExpose = 0;		/* for fast exposures with pixmap source */
+
+    if ( pDstDrawable->type != DRAWABLE_WINDOW )
+	return miCopyArea( pSrcDrawable, pDstDrawable, pGC,
+			   srcx, srcy, width, height, dstx, dsty ) ;
+
+    /* Begin code from mfb/cfbCopyArea */
+
+    origSource.x = srcx;
+    origSource.y = srcy;
+    origSource.width = width;
+    origSource.height = height;
+    origDest.x = dstx;
+    origDest.y = dsty;
+
+    if ((pSrcDrawable != pDstDrawable) &&
+	pSrcDrawable->pScreen->SourceValidate)
+    {
+	(*pSrcDrawable->pScreen->SourceValidate) (pSrcDrawable, srcx, srcy, width, height);
+    }
+
+    srcx += pSrcDrawable->x;
+    srcy += pSrcDrawable->y;
+
+    /* clip the source */
+
+    if (pSrcDrawable->type == DRAWABLE_PIXMAP)
+    {
+	if ((pSrcDrawable == pDstDrawable) &&
+	    (pGC->clientClipType == CT_NONE))
+	{
+	    prgnSrcClip = pGC->pCompositeClip;
+	}
+	else
+	{
+	    fastClip = 1;
+	}
+    }
+    else
+    {
+	if (pGC->subWindowMode == IncludeInferiors)
+	{
+	    if (!((WindowPtr) pSrcDrawable)->parent)
+	    {
+		/*
+		 * special case bitblt from root window in
+		 * IncludeInferiors mode; just like from a pixmap
+		 */
+		fastClip = 1;
+	    }
+	    else if ((pSrcDrawable == pDstDrawable) &&
+		(pGC->clientClipType == CT_NONE))
+	    {
+		prgnSrcClip = pGC->pCompositeClip;
+	    }
+	    else
+	    {
+		prgnSrcClip = NotClippedByChildren((WindowPtr)pSrcDrawable);
+		freeSrcClip = TRUE;
+	    }
+	}
+	else
+	{
+	    prgnSrcClip = &((WindowPtr)pSrcDrawable)->clipList;
+	}
+    }
+
+    fastBox.x1 = srcx;
+    fastBox.y1 = srcy;
+    fastBox.x2 = srcx + width;
+    fastBox.y2 = srcy + height;
+
+    /* Don't create a source region if we are doing a fast clip */
+    if (fastClip)
+    {
+	fastExpose = 1;
+	/*
+	 * clip the source; if regions extend beyond the source size,
+ 	 * make sure exposure events get sent
+	 */
+	if (fastBox.x1 < pSrcDrawable->x)
+	{
+	    fastBox.x1 = pSrcDrawable->x;
+	    fastExpose = 0;
+	}
+	if (fastBox.y1 < pSrcDrawable->y)
+	{
+	    fastBox.y1 = pSrcDrawable->y;
+	    fastExpose = 0;
+	}
+	if (fastBox.x2 > pSrcDrawable->x + (int) pSrcDrawable->width)
+	{
+	    fastBox.x2 = pSrcDrawable->x + (int) pSrcDrawable->width;
+	    fastExpose = 0;
+	}
+	if (fastBox.y2 > pSrcDrawable->y + (int) pSrcDrawable->height)
+	{
+	    fastBox.y2 = pSrcDrawable->y + (int) pSrcDrawable->height;
+	    fastExpose = 0;
+	}
+    }
+    else
+    {
+	REGION_INIT(pGC->pScreen, &rgnDst, &fastBox, 1);
+	REGION_INTERSECT(pGC->pScreen, &rgnDst, &rgnDst, prgnSrcClip);
+    }
+
+    dstx += pDstDrawable->x;
+    dsty += pDstDrawable->y;
+
+    if (pDstDrawable->type == DRAWABLE_WINDOW)
+    {
+	if (!((WindowPtr)pDstDrawable)->realized)
+	{
+	    if (!fastClip)
+		REGION_UNINIT(pGC->pScreen, &rgnDst);
+	    if (freeSrcClip)
+		REGION_DESTROY(pGC->pScreen, prgnSrcClip);
+	    return NULL;
+	}
+    }
+
+    dx = srcx - dstx;
+    dy = srcy - dsty;
+
+    /* Translate and clip the dst to the destination composite clip */
+    if (fastClip)
+    {
+	RegionPtr cclip;
+
+        /* Translate the region directly */
+        fastBox.x1 -= dx;
+        fastBox.x2 -= dx;
+        fastBox.y1 -= dy;
+        fastBox.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 = pGC->pCompositeClip;
+        if (REGION_NUM_RECTS(cclip) == 1)
+        {
+	    BoxPtr pBox = REGION_RECTS(cclip);
+
+	    if (fastBox.x1 < pBox->x1) fastBox.x1 = pBox->x1;
+	    if (fastBox.x2 > pBox->x2) fastBox.x2 = pBox->x2;
+	    if (fastBox.y1 < pBox->y1) fastBox.y1 = pBox->y1;
+	    if (fastBox.y2 > pBox->y2) fastBox.y2 = pBox->y2;
+
+	    /* Check to see if the region is empty */
+	    if (fastBox.x1 >= fastBox.x2 || fastBox.y1 >= fastBox.y2)
+	    {
+		REGION_INIT(pGC->pScreen, &rgnDst, NullBox, 0);
+	    }
+	    else
+	    {
+		REGION_INIT(pGC->pScreen, &rgnDst, &fastBox, 1);
+	    }
+	}
+        else
+	{
+	    /* We must turn off fastClip now, since we must create
+	       a full blown region.  It is intersected with the
+	       composite clip below. */
+	    fastClip = 0;
+	    REGION_INIT(pGC->pScreen, &rgnDst, &fastBox, 1);
+	}
+    }
+    else
+    {
+        REGION_TRANSLATE(pGC->pScreen, &rgnDst, -dx, -dy);
+    }
+
+    if (!fastClip)
+    {
+	REGION_INTERSECT(pGC->pScreen, &rgnDst, &rgnDst, pGC->pCompositeClip);
+    }
+
+    /* Do bit blitting */
+    numRects = REGION_NUM_RECTS(&rgnDst);
+    if (numRects && width && height)
+    {
+	if(!(pptSrc = (DDXPointPtr)ALLOCATE_LOCAL(numRects *
+						  sizeof(DDXPointRec))))
+	{
+	    REGION_UNINIT(pGC->pScreen, &rgnDst);
+	    if (freeSrcClip)
+		REGION_DESTROY(pGC->pScreen, prgnSrcClip);
+	    return NULL;
+	}
+	pbox = REGION_RECTS(&rgnDst);
+	ppt = pptSrc;
+	for (i = numRects; --i >= 0; pbox++, ppt++)
+	{
+	    ppt->x = pbox->x1 + dx;
+	    ppt->y = pbox->y1 + dy;
+	}
+
+	vga16DoBitblt(pSrcDrawable, pDstDrawable, pGC->alu,
+			&rgnDst, pptSrc, pGC->planemask );
+	DEALLOCATE_LOCAL(pptSrc);
+    }
+
+    prgnExposed = NULL;
+    if (pGC->fExpose) 
+    {
+        /* Pixmap sources generate a NoExposed (we return NULL to do this) */
+        if (!fastExpose)
+	    prgnExposed =
+		miHandleExposures(pSrcDrawable, pDstDrawable, pGC,
+				  origSource.x, origSource.y,
+				  (int)origSource.width,
+				  (int)origSource.height,
+				  origDest.x, origDest.y, (unsigned long)0);
+    }
+    REGION_UNINIT(pGC->pScreen, &rgnDst);
+    if (freeSrcClip)
+	REGION_DESTROY(pGC->pScreen, prgnSrcClip);
+    return prgnExposed;
+}
-- 
cgit v1.2.3