xserver/hw/xorg/xaa Makefile.am, NONE, 1.1 xaa.h, NONE, 1.1 xaaBitBlt.c, NONE, 1.1 xaaBitOrder.c, NONE, 1.1 xaaBitmap.c, NONE, 1.1 xaaCpyArea.c, NONE, 1.1 xaaCpyPlane.c, NONE, 1.1 xaaCpyWin.c, NONE, 1.1 xaaDashLine.c, NONE, 1.1 xaaFallback.c, NONE, 1.1 xaaFillArc.c, NONE, 1.1 xaaFillPoly.c, NONE, 1.1 xaaFillRect.c, NONE, 1.1 xaaGC.c, NONE, 1.1 xaaGCmisc.c, NONE, 1.1 xaaImage.c, NONE, 1.1 xaaInit.c, NONE, 1.1 xaaInitAccel.c, NONE, 1.1 xaaLine.c, NONE, 1.1 xaaLineMisc.c, NONE, 1.1 xaaNonTEGlyph.c, NONE, 1.1 xaaNonTEText.c, NONE, 1.1 xaaOffscreen.c, NONE, 1.1 xaaOverlay.c, NONE, 1.1 xaaOverlayDF.c, NONE, 1.1 xaaPCache.c, NONE, 1.1 xaaPaintWin.c, NONE, 1.1 xaaPict.c, NONE, 1.1 xaaROP.c, NONE, 1.1 xaaRect.c, NONE, 1.1 xaaSpans.c, NONE, 1.1 xaaStateChange.c, NONE, 1.1 xaaStipple.c, NONE, 1.1 xaaTEGlyph.c, NONE, 1.1 xaaTEText.c, NONE, 1.1 xaaTables.c, NONE, 1.1 xaaWideLine.c, NONE, 1.1 xaacexp.h, NONE, 1.1 xaalocal.h, NONE, 1.1 xaarop.h, NONE, 1.1 xaawrap.h, NONE, 1.1

Daniel Stone xserver-commit at pdx.freedesktop.org
Sun Apr 25 23:52:25 EST 2004


Committed by: daniel

Update of /cvs/xserver/xserver/hw/xorg/xaa
In directory pdx:/tmp/cvs-serv17025/hw/xorg/xaa

Added Files:
	Makefile.am xaa.h xaaBitBlt.c xaaBitOrder.c xaaBitmap.c 
	xaaCpyArea.c xaaCpyPlane.c xaaCpyWin.c xaaDashLine.c 
	xaaFallback.c xaaFillArc.c xaaFillPoly.c xaaFillRect.c xaaGC.c 
	xaaGCmisc.c xaaImage.c xaaInit.c xaaInitAccel.c xaaLine.c 
	xaaLineMisc.c xaaNonTEGlyph.c xaaNonTEText.c xaaOffscreen.c 
	xaaOverlay.c xaaOverlayDF.c xaaPCache.c xaaPaintWin.c 
	xaaPict.c xaaROP.c xaaRect.c xaaSpans.c xaaStateChange.c 
	xaaStipple.c xaaTEGlyph.c xaaTEText.c xaaTables.c 
	xaaWideLine.c xaacexp.h xaalocal.h xaarop.h xaawrap.h 
Log Message:
Xizzle is dead, long live Xorg.

Re-import the DDX from X11R6.7, complete with automakey goodness, and do the
requisite configure.ac, et al, updates; also import the XKB extension from the
6.7 DIX.

Currently it'll link and then hang solid in RADEONInitAccel(), or the next
function if you enable NoAccel.


--- NEW FILE: Makefile.am ---
INCLUDES = $(XORG_INCS)
AM_CFLAGS = $(XORG_CFLAGS)

LSB_FIRST = l-xaaBitmap.c l3-xaaBitmap.c l-xaaStipple.c l3-xaaStipple.c \
            l-xaaTEGlyph.c
MSB_FIRST = m-xaaBitmap.c m3-xaaBitmap.c m-xaaStipple.c m3-xaaStipple.c \
            m-xaaTEGlyph.c
LSB_FIXED = lf-xaaBitmap.c lf3-xaaBitmap.c lf-xaaStipple.c lf3-xaaStipple.c \
            lf-xaaTEGlyph.c
MSB_FIXED = mf-xaaBitmap.c mf3-xaaBitmap.c mf-xaaStipple.c mf3-xaaStipple.c \
            mf-xaaTEGlyph.c
POLYSEG = s-xaaLine.c s-xaaDashLine.c

lib_LIBRARIES = libxorgxaa.a
libxorgxaa_a_SOURCES = xaaInit.c xaaGC.c xaaInitAccel.c xaaFallback.c \
                       xaaBitBlt.c xaaCpyArea.c xaaGCmisc.c xaaCpyWin.c \
                       xaaCpyPlane.c xaaFillRect.c xaaTEText.c xaaNonTEText.c \
                       xaaPCache.c xaaSpans.c xaaROP.c xaaImage.c \
                       xaaPaintWin.c xaaRect.c xaaLineMisc.c xaaBitOrder.c \
                       xaaFillPoly.c xaaWideLine.c xaaTables.c xaaFillArc.c \
                       xaaLine.c xaaDashLine.c xaaOverlay.c xaaOffscreen.c \
                       xaaOverlayDF.c xaaStateChange.c xaaPict.c $(POLYSEG) \
                       $(LSB_FIRST) $(MSB_FIRST) $(LSB_FIXED) $(MSB_FIXED)
s-%.c:
	echo "#define POLYSEGMENT" > $@
	echo '#include "$(srcdir)/$*.c"' >> $@
l-%.c:
	echo "#define LSBFIRST" > $@
	echo '#include "$(srcdir)/$*.c"' >> $@
l3-%.c:
	echo "#define LSBFIRST" > $@
	echo "#define TRIPLE_BITS" >> $@
	echo '#include "$(srcdir)/$*.c"' >> $@
lf-%.c:
	echo "#define LSBFIRST" > $@
	echo "#define FIXEDBASE" >> $@
	echo '#include "$(srcdir)/$*.c"' >> $@
lf3-%.c:
	echo "#define LSBFIRST" > $@
	echo "#define TRIPLE_BITS" >> $@
	echo "#define FIXEDBASE" >> $@
	echo '#include "$(srcdir)/$*.c"' >> $@
m-%.c:
	echo "#define MSBFIRST" > $@
	echo '#include "$(srcdir)/$*.c"' >> $@
m3-%.c:
	echo "#define MSBFIRST" > $@
	echo "#define TRIPLE_BITS" >> $@
	echo '#include "$(srcdir)/$*.c"' >> $@
mf-%.c:
	echo "#define MSBFIRST" > $@
	echo "#define FIXEDBASE" >> $@
	echo '#include "$(srcdir)/$*.c"' >> $@
mf3-%.c:
	echo "#define MSBFIRST" > $@
	echo "#define TRIPLE_BITS" >> $@
	echo "#define FIXEDBASE" >> $@
	echo '#include "$(srcdir)/$*.c"' >> $@

DISTCLEANFILES = $(POLYSEG) $(LSB_FIRST) $(LSB_FIXED) $(MSB_FIRST) $(MSB_FIXED)

sdk_INCLUDEDIR = $(includedir)/xorg
sdk_INCLUDES = xaa.h xaalocal.h xaadrop.h

--- NEW FILE: xaa.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaa.h,v 1.38 2002/10/21 01:54:04 mvojkovi Exp $ */

#ifndef _XAA_H
#define _XAA_H

/*

   ******** OPERATION SPECIFIC FLAGS *********

   **** solid/dashed line flags ****
 
---------               --------
23           LINE_PATTERN_LSBFIRST_MSBJUSTIFIED
22           LINE_PATTERN_LSBFIRST_LSBJUSTIFIED
21           LINE_PATTERN_MSBFIRST_MSBJUSTIFIED
20           LINE_PATTERN_MSBFIRST_LSBJUSTIFIED
19           LINE_PATTERN_POWER_OF_2_ONLY
18           LINE_LIMIT_COORDS
17                         .
[...1323 lines suppressed...]
    ScreenPtr pScreen,
    XAAInfoRecPtr infoRec
);

XAAInfoRecPtr XAACreateInfoRec(void);

void
XAADestroyInfoRec(
    XAAInfoRecPtr infoRec
);

typedef void (*DepthChangeFuncPtr) (ScrnInfoPtr pScrn, int depth);

Bool
XAAInitDualFramebufferOverlay(
   ScreenPtr pScreen, 
   DepthChangeFuncPtr callback
);

#endif /* _XAA_H */

--- NEW FILE: xaaBitBlt.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaBitBlt.c,v 1.3tsi Exp $ */

/* 
   This is a lighter version of cfbBitBlt.  We calculate the boxes
   when accelerating pixmap->screen and screen->screen copies. 
   We also pass the GC to the doBitBlt function so that it has access
   to the fg and bg so CopyPlane can use this. 
*/

#include "misc.h"
#include "xf86.h"
#include "xf86_ansic.h"
#include "xf86_OSproc.h"

#include <X11/X.h>
#include "mi.h"
#include "pixmapstr.h"
#include "gcstruct.h"
#include "windowstr.h"
#include "xaalocal.h"


RegionPtr
XAABitBlt(
    DrawablePtr pSrcDrawable,
    DrawablePtr pDstDrawable,
    GC *pGC,
    int srcx, int srcy,
    int width, int height,
    int dstx, int dsty,
    void (*doBitBlt)(DrawablePtr, DrawablePtr, GCPtr, RegionPtr, DDXPointPtr),
    unsigned long bitPlane )
{

    RegionPtr prgnSrcClip = NULL; /* may be a new region, or just a copy */
    RegionPtr prgnExposed;
    Bool freeSrcClip = FALSE;
    RegionRec rgnDst;
    DDXPointPtr pptSrc, ppt;
    DDXPointRec origDest;
    BoxPtr pbox;
    BoxRec fastBox;
    int i, dx, dy, numRects;
    xRectangle origSource;
    int fastClip = 0;		/* for fast clipping with pixmap source */
    int fastExpose = 0;		/* for fast exposures with pixmap source */

    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 {	/* Window */
	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_NULL(pGC->pScreen, &rgnDst);
	    } 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;
	}

	(*doBitBlt) (pSrcDrawable, pDstDrawable, pGC, &rgnDst, pptSrc);
	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, bitPlane);
    }
    REGION_UNINIT(pGC->pScreen, &rgnDst);
    if (freeSrcClip)
	REGION_DESTROY(pGC->pScreen, prgnSrcClip);
    return prgnExposed;
}

--- NEW FILE: xaaBitOrder.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaBitOrder.c,v 1.7 2001/05/18 20:22:31 tsi Exp $ */

#include <X11/Xmd.h>
CARD32 XAAReverseBitOrder(CARD32 v);

CARD32
XAAReverseBitOrder(CARD32 v)
{
 return (((0x01010101 & v) << 7) | ((0x02020202 & v) << 5) | 
         ((0x04040404 & v) << 3) | ((0x08080808 & v) << 1) | 
         ((0x10101010 & v) >> 1) | ((0x20202020 & v) >> 3) | 
         ((0x40404040 & v) >> 5) | ((0x80808080 & v) >> 7));
}

--- NEW FILE: xaaBitmap.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaBitmap.c,v 1.9 2000/06/29 10:55:41 alanh Exp $ */


#include "xaa.h"
#include "xaalocal.h"
#include "xaacexp.h"
#include "xf86.h"
#include "xf86_ansic.h"



/********** byte swapping ***************/


#ifdef FIXEDBASE
# define DEST(i)	*dest
# define RETURN(i)	return(dest)
#else
# define DEST(i)	dest[i]
# define RETURN(i)	return(dest + i)
#endif

#ifdef MSBFIRST
# define SOURCE(i)	SWAP_BITS_IN_BYTES(src[i])
#else
# define SOURCE(i)	src[i]
#endif


typedef CARD32 *(* BitmapScanlineProcPtr)(CARD32 *, CARD32 *, int, int);

#ifdef TRIPLE_BITS
static CARD32*
BitmapScanline(
   CARD32 *src, CARD32 *base,
   int count, int skipleft )
{
     CARD32 bits;

     while(count >= 3) {
	bits = *src;
	WRITE_BITS3(bits);
	src++;
	count -= 3;
     }
     if (count == 2) {
	bits = *src;
	WRITE_BITS2(bits);
     } else if (count == 1) {
	bits = *src;
	WRITE_BITS1(bits);
     }
     
     return base;
}

static CARD32*
BitmapScanline_Inverted(
   CARD32 *src, CARD32 *base,
   int count, int skipleft )
{
     CARD32 bits;

     while(count >= 3) {
	bits = ~(*src);
	WRITE_BITS3(bits);
	src++;
	count -= 3;
     }
     if (count == 2) {
	bits = ~(*src);
	WRITE_BITS2(bits);
     } else if (count == 1) {
	bits = ~(*src);
	WRITE_BITS1(bits);
     }
     
     return base;
}


static CARD32*
BitmapScanline_Shifted(
   CARD32 *src, CARD32 *base,
   int count, int skipleft )
{
     CARD32 bits;

     while(count >= 3) {
	bits = SHIFT_R(*src,skipleft) | SHIFT_L(*(src + 1),(32 - skipleft));
	WRITE_BITS3(bits);
	src++;
	count -= 3;
     }
     if (count == 2) {
	bits = SHIFT_R(*src,skipleft) | SHIFT_L(*(src + 1),(32 - skipleft));
	WRITE_BITS2(bits);
     } else if (count == 1) {
	bits = SHIFT_R(*src,skipleft) | SHIFT_L(*(src + 1),(32 - skipleft));
	WRITE_BITS1(bits);
     }
     
     return base;
}

static CARD32*
BitmapScanline_Shifted_Inverted(
   CARD32 *src, CARD32 *base,
   int count, int skipleft )
{
     CARD32 bits;

     while(count >= 3) {
	bits = ~(SHIFT_R(*src,skipleft) | SHIFT_L(*(src + 1),(32 - skipleft)));
	WRITE_BITS3(bits);
	src++;
	count -= 3;
     }
     if (count == 2) {
	bits = ~(SHIFT_R(*src,skipleft) | SHIFT_L(*(src + 1),(32 - skipleft)));
	WRITE_BITS2(bits);
     } else if (count == 1) {
	bits = ~(SHIFT_R(*src,skipleft) | SHIFT_L(*(src + 1),(32 - skipleft)));
	WRITE_BITS1(bits);
     }
     
     return base;
}

#define BitmapScanline_Shifted_Careful BitmapScanline_Shifted
#define BitmapScanline_Shifted_Inverted_Careful BitmapScanline_Shifted_Inverted

#else
static CARD32*
BitmapScanline(
   CARD32 *src, CARD32 *dest,
   int count, int skipleft )
{
   while(count >= 4) {
	DEST(0) = SOURCE(0);
	DEST(1) = SOURCE(1);
	DEST(2) = SOURCE(2);
	DEST(3) = SOURCE(3);
	count -= 4;
	src += 4;
#ifndef FIXEDBASE
	dest += 4;
#endif
   }
   
   if(!count) return dest;
   DEST(0) = SOURCE(0);
   if(count == 1) RETURN(1);
   DEST(1) = SOURCE(1);
   if(count == 2) RETURN(2);
   DEST(2) = SOURCE(2);
   RETURN(3);
}

static CARD32*
BitmapScanline_Inverted(
   CARD32 *src, CARD32 *dest,
   int count, int skipleft )
{
   while(count >= 4) {
	DEST(0) = ~SOURCE(0);
	DEST(1) = ~SOURCE(1);
	DEST(2) = ~SOURCE(2);
	DEST(3) = ~SOURCE(3);
	count -= 4;
	src += 4;
#ifndef FIXEDBASE
	dest += 4;
#endif
   }
   
   if(!count) return dest;
   DEST(0) = ~SOURCE(0);
   if(count == 1) RETURN(1);
   DEST(1) = ~SOURCE(1);
   if(count == 2) RETURN(2);
   DEST(2) = ~SOURCE(2);
   RETURN(3);
}


static CARD32*
BitmapScanline_Shifted(
   CARD32 *bits, CARD32 *base,
   int count, int skipleft )
{
     while(count--) {
	register CARD32 tmp = SHIFT_R(*bits,skipleft) | 
			      SHIFT_L(*(bits + 1),(32 - skipleft));
	WRITE_BITS(tmp);
	bits++;
     }
     return base;
}

static CARD32*
BitmapScanline_Shifted_Inverted(
   CARD32 *bits, CARD32 *base,
   int count, int skipleft )
{
     while(count--) {
	register CARD32 tmp = ~(SHIFT_R(*bits,skipleft) | 
				SHIFT_L(*(bits + 1),(32 - skipleft)));
	WRITE_BITS(tmp);
	bits++;
     }
     return base;
}

static CARD32*
BitmapScanline_Shifted_Careful(
   CARD32 *bits, CARD32 *base,
   int count, int skipleft )
{
     register CARD32 tmp;
     while(--count) {
 	tmp = SHIFT_R(*bits,skipleft) | SHIFT_L(*(bits + 1),(32 - skipleft));
	WRITE_BITS(tmp);
	bits++;
     }
     tmp = SHIFT_R(*bits,skipleft);
     WRITE_BITS(tmp);

     return base;
}

static CARD32*
BitmapScanline_Shifted_Inverted_Careful(
   CARD32 *bits, CARD32 *base,
   int count, int skipleft )
{
     register CARD32 tmp;
     while(--count) {
	tmp = ~(SHIFT_R(*bits,skipleft) | SHIFT_L(*(bits + 1),(32 - skipleft)));
	WRITE_BITS(tmp);
	bits++;
     }
     tmp = ~(SHIFT_R(*bits,skipleft));
     WRITE_BITS(tmp);
     return base;
}

#endif

/*  
    When the accelerator is TRANSPARENCY_ONLY, WriteBitmap can do
    the fill in two passes, inverting the source on the second pass.  
    For GXcopy we can fill the backing rectangle as a solid rect and
    avoid the invert.
*/ 

void
#ifdef TRIPLE_BITS
EXPNAME(XAAWriteBitmapColorExpand3)(
#else
EXPNAME(XAAWriteBitmapColorExpand)(
#endif
    ScrnInfoPtr pScrn,
    int x, int y, int w, int H,
    unsigned char *src,
    int srcwidth,
    int skipleft,
    int fg, int bg,
    int rop,
    unsigned int planemask 
)
{
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
    CARD32* base;
    unsigned char *srcp = src;
    int SecondPassColor = -1;
    int shift = 0, dwords;
    BitmapScanlineProcPtr firstFunc;
    BitmapScanlineProcPtr secondFunc;
    int flag;
    int h = H;

#ifdef TRIPLE_BITS
    if((bg != -1) && 
	((infoRec->CPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY) ||
	((infoRec->CPUToScreenColorExpandFillFlags & RGB_EQUAL) && 
	(!CHECK_RGB_EQUAL(bg))))) {
#else
    if((bg != -1) && 
	(infoRec->CPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY)) {
#endif
	if((rop == GXcopy) && infoRec->SetupForSolidFill) {
    	    (*infoRec->SetupForSolidFill)(pScrn, bg, rop, planemask);
            (*infoRec->SubsequentSolidFillRect)(pScrn, x, y, w, h);
	} else SecondPassColor = bg;
	bg = -1;
    }

#ifdef TRIPLE_BITS
    if(skipleft) {
#else
    if(skipleft && 
	(!(infoRec->CPUToScreenColorExpandFillFlags & LEFT_EDGE_CLIPPING) || 
	(!(infoRec->CPUToScreenColorExpandFillFlags & LEFT_EDGE_CLIPPING_NEGATIVE_X) && 
		(skipleft > x)))) {
#endif
	if((skipleft + ((w + 31) & ~31)) > ((skipleft + w + 31) & ~31)) {
	    /* don't read past the end */
	    firstFunc = BitmapScanline_Shifted_Careful;
 	    secondFunc = BitmapScanline_Shifted_Inverted_Careful;
	} else {
	    firstFunc = BitmapScanline_Shifted;
 	    secondFunc = BitmapScanline_Shifted_Inverted;
	}
	shift = skipleft;
	skipleft = 0;
    } else {
	firstFunc = BitmapScanline;
 	secondFunc = BitmapScanline_Inverted;
	w += skipleft;
	x -= skipleft;
    }

#ifdef TRIPLE_BITS
    dwords = (3 * w + 31) >> 5;
#else
    dwords = (w + 31) >> 5;
#endif

SECOND_PASS:

    flag = (infoRec->CPUToScreenColorExpandFillFlags 
	     & CPU_TRANSFER_PAD_QWORD) && ((dwords * h) & 0x01);
    (*infoRec->SetupForCPUToScreenColorExpandFill)(
					pScrn, fg, bg, rop, planemask);
    (*infoRec->SubsequentCPUToScreenColorExpandFill)(
					pScrn, x, y, w, h, skipleft);

    base = (CARD32*)infoRec->ColorExpandBase;

#ifndef FIXEDBASE
    if((dwords * h) <= infoRec->ColorExpandRange)
	while(h--) {
	    base = (*firstFunc)((CARD32*)srcp, base, dwords, shift);
	    srcp += srcwidth;
    	}
    else
#endif
	while(h--) {
	    (*firstFunc)((CARD32*)srcp, base, dwords, shift);
	    srcp += srcwidth;
	}

    if(flag){
        base = (CARD32*)infoRec->ColorExpandBase;
	base[0] = 0x00000000;
    }

    if(SecondPassColor != -1) {
	h = H; /* Reset height */
	fg = SecondPassColor;
	SecondPassColor = -1;
	firstFunc = secondFunc;
	srcp = src;
	goto SECOND_PASS;
    }

    if(infoRec->CPUToScreenColorExpandFillFlags & SYNC_AFTER_COLOR_EXPAND) 
	(*infoRec->Sync)(pScrn);
    else SET_SYNC_FLAG(infoRec);
}

#ifndef FIXEDBASE

void
#ifdef TRIPLE_BITS
EXPNAME(XAAWriteBitmapScanlineColorExpand3)(
#else
EXPNAME(XAAWriteBitmapScanlineColorExpand)(
#endif
    ScrnInfoPtr pScrn,
    int x, int y, int w, int h,
    unsigned char *src,
    int srcwidth,
    int skipleft,
    int fg, int bg,
    int rop,
    unsigned int planemask 
)
{
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
    CARD32* base;
    unsigned char *srcp = src;
    int SecondPassColor = -1;
    int shift = 0, dwords, bufferNo;
    BitmapScanlineProcPtr firstFunc;
    BitmapScanlineProcPtr secondFunc;

#ifdef TRIPLE_BITS
    if((bg != -1) &&
	((infoRec->ScanlineCPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY) 
	|| ((infoRec->ScanlineCPUToScreenColorExpandFillFlags & RGB_EQUAL) && 
	(!CHECK_RGB_EQUAL(bg))))) {
#else
    if((bg != -1) && 
	(infoRec->ScanlineCPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY)){
#endif
	if((rop == GXcopy) && infoRec->SetupForSolidFill) {
    	    (*infoRec->SetupForSolidFill)(pScrn, bg, rop, planemask);
            (*infoRec->SubsequentSolidFillRect)(pScrn, x, y, w, h);
	} else SecondPassColor = bg;
	bg = -1;
    }

#ifdef TRIPLE_BITS
    if(skipleft) {
#else
    if(skipleft && 
	(!(infoRec->ScanlineCPUToScreenColorExpandFillFlags & 
		LEFT_EDGE_CLIPPING) || 
	(!(infoRec->ScanlineCPUToScreenColorExpandFillFlags &
		 LEFT_EDGE_CLIPPING_NEGATIVE_X) && (skipleft > x)))) {
#endif
	if((skipleft + ((w + 31) & ~31)) > ((skipleft + w + 31) & ~31)) {
	    /* don't read past the end */
	    firstFunc = BitmapScanline_Shifted_Careful;
 	    secondFunc = BitmapScanline_Shifted_Inverted_Careful;
	} else {
	    firstFunc = BitmapScanline_Shifted;
 	    secondFunc = BitmapScanline_Shifted_Inverted;
	}
	shift = skipleft;
	skipleft = 0;
    } else {
	firstFunc = BitmapScanline;
 	secondFunc = BitmapScanline_Inverted;
	w += skipleft;
	x -= skipleft;
    }

#ifdef TRIPLE_BITS
    dwords = (3 * w + 31) >> 5;
#else
    dwords = (w + 31) >> 5;
#endif

SECOND_PASS:

    (*infoRec->SetupForScanlineCPUToScreenColorExpandFill)(pScrn, fg, bg, rop, planemask);
    (*infoRec->SubsequentScanlineCPUToScreenColorExpandFill)(
					pScrn, x, y, w, h, skipleft);

    bufferNo = 0;

    while(h--) {
	base = (CARD32*)infoRec->ScanlineColorExpandBuffers[bufferNo];
	(*firstFunc)((CARD32*)srcp, base, dwords, shift);
	(*infoRec->SubsequentColorExpandScanline)(pScrn, bufferNo++);
	srcp += srcwidth;
	if(bufferNo >= infoRec->NumScanlineColorExpandBuffers)
	    bufferNo = 0;
    }

    if(SecondPassColor != -1) {
	fg = SecondPassColor;
	SecondPassColor = -1;
	firstFunc = secondFunc;
	srcp = src;
	goto SECOND_PASS;
    }

    SET_SYNC_FLAG(infoRec);
}

#endif

--- NEW FILE: xaaCpyArea.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaCpyArea.c,v 1.12 2000/09/28 20:47:59 mvojkovi Exp $ */

#include "misc.h"
#include "xf86.h"
#include "xf86_ansic.h"
#include "xf86_OSproc.h"

#include <X11/X.h>
#include "scrnintstr.h"
#include "xf86str.h"
#include "xaa.h"
#include "xaalocal.h"
#include "migc.h"
#include "gcstruct.h"
#include "pixmapstr.h"

/*
  Written mostly by Harm Hanemaayer (H.Hanemaayer at inter.nl.net).
 */


RegionPtr
XAACopyArea(
    DrawablePtr pSrcDrawable,
    DrawablePtr pDstDrawable,
    GC *pGC,
    int srcx, int srcy,
    int width, int height,
    int dstx, int dsty )
{
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);

    if(pDstDrawable->type == DRAWABLE_WINDOW) {
	if((pSrcDrawable->type == DRAWABLE_WINDOW) ||
		IS_OFFSCREEN_PIXMAP(pSrcDrawable)){
	    if(infoRec->ScreenToScreenBitBlt &&
	     CHECK_ROP(pGC,infoRec->ScreenToScreenBitBltFlags) &&
	     CHECK_ROPSRC(pGC,infoRec->ScreenToScreenBitBltFlags) &&
	     CHECK_PLANEMASK(pGC,infoRec->ScreenToScreenBitBltFlags))
            return (XAABitBlt( pSrcDrawable, pDstDrawable,
		pGC, srcx, srcy, width, height, dstx, dsty,
		XAADoBitBlt, 0L));
	} else {
	    if(infoRec->WritePixmap &&
	     ((pDstDrawable->bitsPerPixel == pSrcDrawable->bitsPerPixel) ||
		((pDstDrawable->bitsPerPixel == 24) &&  
		(pSrcDrawable->bitsPerPixel == 32) &&
		(infoRec->WritePixmapFlags & CONVERT_32BPP_TO_24BPP))) &&
	     CHECK_ROP(pGC,infoRec->WritePixmapFlags) &&
	     CHECK_ROPSRC(pGC,infoRec->WritePixmapFlags) &&
	     CHECK_PLANEMASK(pGC,infoRec->WritePixmapFlags) &&
	     CHECK_NO_GXCOPY(pGC,infoRec->WritePixmapFlags)) 
            return (XAABitBlt( pSrcDrawable, pDstDrawable,
		pGC, srcx, srcy, width, height, dstx, dsty,
		XAADoImageWrite, 0L));
	}
    } else if(IS_OFFSCREEN_PIXMAP(pDstDrawable)){
	if((pSrcDrawable->type == DRAWABLE_WINDOW) ||
		IS_OFFSCREEN_PIXMAP(pSrcDrawable)){
	    if(infoRec->ScreenToScreenBitBlt &&
	     CHECK_ROP(pGC,infoRec->ScreenToScreenBitBltFlags) &&
	     CHECK_ROPSRC(pGC,infoRec->ScreenToScreenBitBltFlags) &&
	     CHECK_PLANEMASK(pGC,infoRec->ScreenToScreenBitBltFlags))
            return (XAABitBlt( pSrcDrawable, pDstDrawable,
		pGC, srcx, srcy, width, height, dstx, dsty,
		XAADoBitBlt, 0L));
	}
    }

    return (XAAFallbackOps.CopyArea(pSrcDrawable, pDstDrawable, pGC,
   	    srcx, srcy, width, height, dstx, dsty));
}


void
XAADoBitBlt(
    DrawablePtr	    pSrc, 
    DrawablePtr	    pDst,
    GC		    *pGC,
    RegionPtr	    prgnDst,
    DDXPointPtr	    pptSrc )
{
    int nbox, careful;
    BoxPtr pbox, pboxTmp, pboxNext, pboxBase, pboxNew1, pboxNew2;
    DDXPointPtr pptTmp, pptNew1, pptNew2;
    int xdir, ydir;
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);

    /* 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;

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

    (*infoRec->ScreenToScreenBitBlt)(infoRec->pScrn, nbox, pptSrc, pbox, 
	xdir, ydir, pGC->alu, pGC->planemask);
 
    if (pboxNew2) {
	DEALLOCATE_LOCAL(pptNew2);
	DEALLOCATE_LOCAL(pboxNew2);
    }
    if (pboxNew1) {
	DEALLOCATE_LOCAL(pptNew1);
	DEALLOCATE_LOCAL(pboxNew1);
    }

}

void
XAADoImageWrite(
    DrawablePtr	    pSrc, 
    DrawablePtr	    pDst,
    GC		    *pGC,
    RegionPtr	    prgnDst,
    DDXPointPtr	    pptSrc )
{
    int srcwidth;
    unsigned char* psrcBase;			/* start of image */
    unsigned char* srcPntr;			/* index into the image */
    BoxPtr pbox = REGION_RECTS(prgnDst);
    int nbox = REGION_NUM_RECTS(prgnDst);
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
    int Bpp = pSrc->bitsPerPixel >> 3; 

    psrcBase = (unsigned char *)((PixmapPtr)pSrc)->devPrivate.ptr;
    srcwidth = (int)((PixmapPtr)pSrc)->devKind;

    for(; nbox; pbox++, pptSrc++, nbox--) {
        srcPntr = psrcBase + (pptSrc->y * srcwidth) + (pptSrc->x * Bpp);

	(*infoRec->WritePixmap)(infoRec->pScrn, pbox->x1, pbox->y1, 
		pbox->x2 - pbox->x1, pbox->y2 - pbox->y1, srcPntr, srcwidth,
		pGC->alu, pGC->planemask, -1, pSrc->bitsPerPixel, pSrc->depth);
    }
}


void
XAADoImageRead(
    DrawablePtr	    pSrc, 
    DrawablePtr	    pDst,
    GC		    *pGC,
    RegionPtr	    prgnDst,
    DDXPointPtr	    pptSrc )
{
    int dstwidth;
    unsigned char* pdstBase;			/* start of image */
    unsigned char* dstPntr;			/* index into the image */
    BoxPtr pbox = REGION_RECTS(prgnDst);
    int nbox = REGION_NUM_RECTS(prgnDst);
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
    int Bpp = pSrc->bitsPerPixel >> 3;  /* wouldn't get here unless both
                                           src and dst have same bpp */

    pdstBase = (unsigned char *)((PixmapPtr)pDst)->devPrivate.ptr;
    dstwidth = (int)((PixmapPtr)pDst)->devKind;

    for(; nbox; pbox++, pptSrc++, nbox--) {
        dstPntr = pdstBase + (pbox->y1 * dstwidth) + (pbox->x1 * Bpp);

	(*infoRec->ReadPixmap)(infoRec->pScrn, pptSrc->x, pptSrc->y, 
		pbox->x2 - pbox->x1, pbox->y2 - pbox->y1, dstPntr, dstwidth,
		pSrc->bitsPerPixel, pSrc->depth);
    }
}


void 
XAAScreenToScreenBitBlt(
    ScrnInfoPtr pScrn,
    int nbox,
    DDXPointPtr pptSrc,
    BoxPtr pbox,
    int xdir, int ydir,
    int alu,
    unsigned int planemask )
{
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
    int dirsetup;

    if ((!(infoRec->CopyAreaFlags & ONLY_TWO_BITBLT_DIRECTIONS)
    || (xdir == ydir)) &&
    (!(infoRec->CopyAreaFlags & ONLY_LEFT_TO_RIGHT_BITBLT)
    || (xdir == 1))) {
        (*infoRec->SetupForScreenToScreenCopy)(pScrn,
            xdir, ydir, alu, planemask, -1);
        for (; nbox; pbox++, pptSrc++, nbox--)
            (*infoRec->SubsequentScreenToScreenCopy)(pScrn,pptSrc->x, pptSrc->y,
                pbox->x1, pbox->y1, pbox->x2 - pbox->x1, pbox->y2 - pbox->y1);
        SET_SYNC_FLAG(infoRec);
        return;
    }

   if (infoRec->CopyAreaFlags & ONLY_LEFT_TO_RIGHT_BITBLT) {
        /*
         * This is the case of a chip that only supports xdir = 1,
         * with ydir = 1 or ydir = -1, but we have xdir = -1.
         */
        (*infoRec->SetupForScreenToScreenCopy)(pScrn,
            1, ydir, alu, planemask, -1);
        for (; nbox; pbox++, pptSrc++, nbox--)
            if (pptSrc->y != pbox->y1 || pptSrc->x >= pbox->x1)
                /* No problem. Do a xdir = 1 blit instead. */
                (*infoRec->SubsequentScreenToScreenCopy)(pScrn,
                    pptSrc->x, pptSrc->y, pbox->x1, pbox->y1,
                    pbox->x2 - pbox->x1, pbox->y2 - pbox->y1);
            else 
            {
                /*
                 * This is the difficult case. Needs striping into
                 * non-overlapping horizontal chunks.
                 */
                int stripeWidth, w, fullStripes, extra, i;
                stripeWidth = 16;
                w = pbox->x2 - pbox->x1;
                if (pbox->x1 - pptSrc->x < stripeWidth)
                    stripeWidth = pbox->x1 - pptSrc->x;
                fullStripes = w / stripeWidth;
                extra = w % stripeWidth;

                /* First, take care of the little bit on the far right */
                if (extra)
                    (*infoRec->SubsequentScreenToScreenCopy)(pScrn,
                        pptSrc->x + fullStripes * stripeWidth, pptSrc->y,
                        pbox->x1 + fullStripes * stripeWidth, pbox->y1,
                        extra, pbox->y2 - pbox->y1);

                /* Now, take care of the rest of the blit */
                for (i = fullStripes - 1; i >= 0; i--)
                    (*infoRec->SubsequentScreenToScreenCopy)(pScrn,
                        pptSrc->x + i * stripeWidth, pptSrc->y,
                        pbox->x1 + i * stripeWidth, pbox->y1,
                        stripeWidth, pbox->y2 - pbox->y1);
            }
        SET_SYNC_FLAG(infoRec);
        return;
    }

    /*
     * Now the case of a chip that only supports xdir = ydir = 1 or
     * xdir = ydir = -1, but we have xdir != ydir.
     */
    dirsetup = 0;	/* No direction set up yet. */
    for (; nbox; pbox++, pptSrc++, nbox--) {
        if (xdir == 1 && pptSrc->y != pbox->y1) {
            /* Do a xdir = ydir = -1 blit instead. */
            if (dirsetup != -1) {
                (*infoRec->SetupForScreenToScreenCopy)(pScrn,
                    -1, -1, alu, planemask, -1);
                dirsetup = -1;
            }
            (*infoRec->SubsequentScreenToScreenCopy)(pScrn,pptSrc->x, pptSrc->y,
                pbox->x1, pbox->y1, pbox->x2 - pbox->x1, pbox->y2 - pbox->y1);
        }
        else if (xdir == -1 && pptSrc->y != pbox->y1) {
            /* Do a xdir = ydir = 1 blit instead. */
            if (dirsetup != 1) {
                (*infoRec->SetupForScreenToScreenCopy)(pScrn,
                    1, 1, alu, planemask, -1);
                dirsetup = 1;
            }
            (*infoRec->SubsequentScreenToScreenCopy)(pScrn,pptSrc->x, pptSrc->y,
                pbox->x1, pbox->y1, pbox->x2 - pbox->x1, pbox->y2 - pbox->y1);
        }
        else
            if (xdir == 1) {
                /*
                 * xdir = 1, ydir = -1.
                 * Perform line-by-line xdir = ydir = 1 blits, going up.
                 */
                int i;
                if (dirsetup != 1) {
                    (*infoRec->SetupForScreenToScreenCopy)(pScrn,
                        1, 1, alu, planemask, -1);
                    dirsetup = 1;
                }
                for (i = pbox->y2 - pbox->y1 - 1; i >= 0; i--)
                    (*infoRec->SubsequentScreenToScreenCopy)(pScrn,
                        pptSrc->x, pptSrc->y + i, pbox->x1, pbox->y1 + i,
                        pbox->x2 - pbox->x1, 1);
            }
            else {
                /*
                 * xdir = -1, ydir = 1.
                 * Perform line-by-line xdir = ydir = -1 blits, going down.
                 */
                int i;
                if (dirsetup != -1) {
                    (*infoRec->SetupForScreenToScreenCopy)(pScrn,
                        -1, -1, alu, planemask, -1);
                    dirsetup = -1;
                }
                for (i = 0; i < pbox->y2 - pbox->y1; i++)
                    (*infoRec->SubsequentScreenToScreenCopy)(pScrn,
                        pptSrc->x, pptSrc->y + i, pbox->x1, pbox->y1 + i,
                        pbox->x2 - pbox->x1, 1);
            }
    } /* next box */
    SET_SYNC_FLAG(infoRec);
}

--- NEW FILE: xaaCpyPlane.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaCpyPlane.c,v 1.13tsi Exp $ */

/*
   A CopyPlane function that handles bitmap->screen copies and
   sends anything else to the Fallback.

   Also, a PushPixels for solid fill styles.

   Written by Mark Vojkovich (markv at valinux.com)

*/

#include "misc.h"
#include "xf86.h"
#include "xf86_ansic.h"
#include "xf86_OSproc.h"
#include "servermd.h"

#include <X11/X.h>
#include "scrnintstr.h"
#include "mi.h"
#include "pixmapstr.h"
#include "xf86str.h"
#include "xaa.h"
#include "xaalocal.h"
#include "xaawrap.h"

static void XAACopyPlane1toNColorExpand(DrawablePtr pSrc, DrawablePtr pDst,
					GCPtr pGC, RegionPtr rgnDst,
					DDXPointPtr pptSrc);
static void XAACopyPlaneNtoNColorExpand(DrawablePtr pSrc, DrawablePtr pDst,
					GCPtr pGC, RegionPtr rgnDst,
					DDXPointPtr pptSrc);


static unsigned long TmpBitPlane; 

RegionPtr
XAACopyPlaneColorExpansion(
    DrawablePtr	pSrc,
    DrawablePtr	pDst,
    GCPtr pGC,
    int	srcx, int srcy,
    int	width, int height,
    int	dstx, int dsty,
    unsigned long bitPlane 
){
    if((pSrc->type == DRAWABLE_PIXMAP) && !XAA_DEPTH_BUG(pGC)) {
	if(pSrc->bitsPerPixel == 1) {
	   return(XAABitBlt(pSrc, pDst, pGC, srcx, srcy,
			width, height, dstx, dsty, 
			XAACopyPlane1toNColorExpand, bitPlane));
	} else if(bitPlane < (1 << pDst->depth)){
	   TmpBitPlane = bitPlane;
	   return(XAABitBlt(pSrc, pDst, pGC, srcx, srcy,
			width, height, dstx, dsty, 
			XAACopyPlaneNtoNColorExpand, bitPlane));
	}
    }

    return (XAAFallbackOps.CopyPlane(pSrc, pDst, pGC, srcx, srcy, 
			width, height, dstx, dsty, bitPlane));
}


static void 
XAACopyPlane1toNColorExpand(
    DrawablePtr   pSrc, 
    DrawablePtr	  pDst,
    GCPtr	  pGC,
    RegionPtr     rgnDst,
    DDXPointPtr   pptSrc )
{
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
    BoxPtr pbox = REGION_RECTS(rgnDst);
    int numrects = REGION_NUM_RECTS(rgnDst);
    unsigned char *src = ((PixmapPtr)pSrc)->devPrivate.ptr;
    int srcwidth = ((PixmapPtr)pSrc)->devKind; 
    
    while(numrects--) {	
	(*infoRec->WriteBitmap)(infoRec->pScrn, pbox->x1, pbox->y1, 
		pbox->x2 - pbox->x1, pbox->y2 - pbox->y1, 
		src + (srcwidth * pptSrc->y) + ((pptSrc->x >> 5) << 2), 
		srcwidth, pptSrc->x & 31, 
		pGC->fgPixel, pGC->bgPixel, pGC->alu, pGC->planemask);
	pbox++; pptSrc++;
    }
}


static void 
XAACopyPlaneNtoNColorExpand(
    DrawablePtr   pSrc, 
    DrawablePtr	  pDst,
    GCPtr	  pGC,
    RegionPtr     rgnDst,
    DDXPointPtr   pptSrc 
){
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
    BoxPtr pbox = REGION_RECTS(rgnDst);
    int numrects = REGION_NUM_RECTS(rgnDst);
    unsigned char *src = ((PixmapPtr)pSrc)->devPrivate.ptr;
    unsigned char *data, *srcPtr, *dataPtr;
    int srcwidth = ((PixmapPtr)pSrc)->devKind; 
    int pitch, width, height, h, i, index, offset;
    int Bpp = pSrc->bitsPerPixel >> 3;
    unsigned long mask = TmpBitPlane;

    if(TmpBitPlane < 8) {
	offset = 0;
    } else if(TmpBitPlane < 16) {
	offset = 1;
	mask >>= 8;
    } else if(TmpBitPlane < 24) {
	offset = 2;
	mask >>= 16;
    } else {
	offset = 3;
	mask >>= 24;
    }

    if(IS_OFFSCREEN_PIXMAP(pSrc))
	SYNC_CHECK(pSrc);
    
    while(numrects--) {	
	width = pbox->x2 - pbox->x1;
	h = height = pbox->y2 - pbox->y1;
	pitch = BitmapBytePad(width);

	if(!(data = xalloc(height * pitch)))
	   goto ALLOC_FAILED;

        bzero(data, height * pitch);

	dataPtr = data;
        srcPtr = ((pptSrc->y) * srcwidth) + src + 
                        ((pptSrc->x) * Bpp) + offset;

	while(h--) {
	    for(i = index = 0; i < width; i++, index += Bpp) {
	       if(mask & srcPtr[index])
		  dataPtr[i >> 3] |= (1 << (i & 7));
	    }
	    dataPtr += pitch;
	    srcPtr += srcwidth;
	}

	(*infoRec->WriteBitmap)(infoRec->pScrn, 
		pbox->x1, pbox->y1, width, height, data, pitch, 0, 
		pGC->fgPixel, pGC->bgPixel, pGC->alu, pGC->planemask);
	
	xfree(data);

ALLOC_FAILED:

	pbox++; pptSrc++;
    }
}

void
XAAPushPixelsSolidColorExpansion(
    GCPtr	pGC,
    PixmapPtr	pBitMap,
    DrawablePtr pDraw,
    int	dx, int dy, 
    int xOrg, int yOrg )
{
   XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
   int MaxBoxes = REGION_NUM_RECTS(pGC->pCompositeClip);
   BoxPtr	pbox, pClipBoxes;
   int		nboxes, srcx, srcy;
   xRectangle TheRect;
   unsigned char *src = pBitMap->devPrivate.ptr;
   int srcwidth = pBitMap->devKind;

   if(!REGION_NUM_RECTS(pGC->pCompositeClip))
	return;

   TheRect.x = xOrg;
   TheRect.y = yOrg;
   TheRect.width = dx;
   TheRect.height = dy; 

   if(MaxBoxes > (infoRec->PreAllocSize/sizeof(BoxRec))) {
	pClipBoxes = xalloc(MaxBoxes * sizeof(BoxRec));
	if(!pClipBoxes) return;	
   } else pClipBoxes = (BoxPtr)infoRec->PreAllocMem;

   nboxes = XAAGetRectClipBoxes(pGC, pClipBoxes, 1, &TheRect);
   pbox = pClipBoxes;

   while(nboxes--) {
	srcx = pbox->x1 - xOrg;
	srcy = pbox->y1 - yOrg;
 	(*infoRec->WriteBitmap)(infoRec->pScrn, pbox->x1, pbox->y1, 
		pbox->x2 - pbox->x1, pbox->y2 - pbox->y1, 
		src + (srcwidth * srcy) + ((srcx >> 5) << 2), 
		srcwidth, srcx & 31, 
		pGC->fgPixel, -1, pGC->alu, pGC->planemask);
	pbox++;
   }

    if(pClipBoxes != (BoxPtr)infoRec->PreAllocMem)
	xfree(pClipBoxes);
}


--- NEW FILE: xaaCpyWin.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaCpyWin.c,v 1.3tsi Exp $ */

#include "misc.h"
#include "xf86.h"
#include "xf86_ansic.h"
#include "xf86_OSproc.h"

#include <X11/X.h>
#include "scrnintstr.h"
#include "windowstr.h"
#include "xf86str.h"
#include "xaa.h"
#include "xaalocal.h"
#include "gcstruct.h"
#include "pixmapstr.h"
#include "xaawrap.h"

/*
    Written by Harm Hanemaayer (H.Hanemaayer at inter.nl.net).
*/

void 
XAACopyWindow(
    WindowPtr pWin,
    DDXPointRec ptOldOrg,
    RegionPtr prgnSrc )
{
    DDXPointPtr pptSrc, ppt;
    RegionRec rgnDst;
    BoxPtr pbox;
    int dx, dy, nbox;
    WindowPtr pwinRoot;
    ScreenPtr pScreen = pWin->drawable.pScreen;
    XAAInfoRecPtr infoRec = 
	GET_XAAINFORECPTR_FROM_DRAWABLE((&pWin->drawable));

    if (!infoRec->pScrn->vtSema || !infoRec->ScreenToScreenBitBlt) { 
	XAA_SCREEN_PROLOGUE (pScreen, CopyWindow);
	if(infoRec->pScrn->vtSema && infoRec->NeedToSync) {
	    (*infoRec->Sync)(infoRec->pScrn);
	    infoRec->NeedToSync = FALSE;
	}
        (*pScreen->CopyWindow) (pWin, ptOldOrg, prgnSrc);
	XAA_SCREEN_EPILOGUE (pScreen, CopyWindow, XAACopyWindow);
    	return;
    }

    pwinRoot = WindowTable[pScreen->myNum];

    REGION_NULL(pScreen, &rgnDst);

    dx = ptOldOrg.x - pWin->drawable.x;
    dy = ptOldOrg.y - pWin->drawable.y;
    REGION_TRANSLATE(pScreen, prgnSrc, -dx, -dy);
    REGION_INTERSECT(pScreen, &rgnDst, &pWin->borderClip, prgnSrc);

    pbox = REGION_RECTS(&rgnDst);
    nbox = REGION_NUM_RECTS(&rgnDst);
    if(!nbox || 
      !(pptSrc = (DDXPointPtr )ALLOCATE_LOCAL(nbox * sizeof(DDXPointRec)))) {
	REGION_UNINIT(pScreen, &rgnDst);
	return;
    }
    ppt = pptSrc;

    while(nbox--) {
	ppt->x = pbox->x1 + dx;
	ppt->y = pbox->y1 + dy;
	ppt++; pbox++;
    }
    
    infoRec->ScratchGC.planemask = ~0L;
    infoRec->ScratchGC.alu = GXcopy;

    XAADoBitBlt((DrawablePtr)pwinRoot, (DrawablePtr)pwinRoot,
        		&(infoRec->ScratchGC), &rgnDst, pptSrc);

    DEALLOCATE_LOCAL(pptSrc);
    REGION_UNINIT(pScreen, &rgnDst);
}

--- NEW FILE: xaaDashLine.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaDashLine.c,v 1.4 2001/10/28 03:34:04 tsi Exp $ */

#include <X11/X.h>
#include "misc.h"
#include "xf86.h"
#include "xf86_ansic.h"
#include "xf86_OSproc.h"

#include "scrnintstr.h"
#include "pixmapstr.h"
#include "miline.h"
#include "xf86str.h"
#include "xaa.h"
#include "xaalocal.h"


void
#ifdef POLYSEGMENT
XAAPolySegmentDashed(
    DrawablePtr	pDrawable,
    GCPtr	pGC,
    int		nseg,
    xSegment	*pSeg
#else
XAAPolyLinesDashed(
    DrawablePtr pDrawable,
    GCPtr	pGC,
    int		mode,		/* Origin or Previous */
    int		npt,		/* number of points */
    DDXPointPtr pptInit
#endif
){
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
    XAAGCPtr   pGCPriv = (XAAGCPtr) (pGC)->devPrivates[XAAGCIndex].ptr;
    BoxPtr pboxInit = REGION_RECTS(pGC->pCompositeClip);
    int nboxInit = REGION_NUM_RECTS(pGC->pCompositeClip);
    unsigned int bias = miGetZeroLineBias(pDrawable->pScreen);
    int xorg = pDrawable->x;
    int yorg = pDrawable->y;
    int nbox;
    BoxPtr pbox;
#ifndef POLYSEGMENT
    DDXPointPtr ppt;
#endif
    unsigned int oc1, oc2;
    int dmin, dmaj, e, octant;
    int x1, x2, y1, y2, tmp, len, offset;
    int PatternLength, PatternOffset;

    if(!nboxInit)
	return;

    if (infoRec->DashedLineFlags & LINE_LIMIT_COORDS) {
	int minValX = infoRec->DashedLineLimits.x1;
	int maxValX = infoRec->DashedLineLimits.x2;
	int minValY = infoRec->DashedLineLimits.y1;
	int maxValY = infoRec->DashedLineLimits.y2;
#ifdef POLYSEGMENT
	int n = nseg;
	xSegment *s = pSeg;

	while (n--)
#else
	int n = npt;
	int xorgtmp = xorg;
	int yorgtmp = yorg;

	ppt = pptInit;
	x2 = ppt->x + xorgtmp;
	y2 = ppt->y + yorgtmp;
	while (--n)
#endif
	{
#ifdef POLYSEGMENT
	    x1 = s->x1 + xorg;
	    y1 = s->y1 + yorg;
	    x2 = s->x2 + xorg;
	    y2 = s->y2 + yorg;
	    s++;
#else
	    x1 = x2;
	    y1 = y2;
	    ++ppt;
	    if (mode == CoordModePrevious) {
		xorgtmp = x1;
		yorgtmp = y1;
	    }
	    x2 = ppt->x + xorgtmp;
	    y2 = ppt->y + yorgtmp;
#endif
	    if (x1 > maxValX || x1 < minValX ||
		x2 > maxValX || x2 < minValX ||
		y1 > maxValY || y1 < minValY ||
		y2 > maxValY || y2 < minValY) {
#ifdef POLYSEGMENT
		XAAFallbackOps.PolySegment(pDrawable, pGC, nseg, pSeg);
#else
		XAAFallbackOps.Polylines(pDrawable, pGC, mode, npt, pptInit);
#endif
		return;
	    }
	}
    }

    PatternLength = pGCPriv->DashLength; 
    PatternOffset = pGC->dashOffset % PatternLength;

    (*infoRec->SetupForDashedLine)(infoRec->pScrn, pGC->fgPixel,
		(pGC->lineStyle == LineDoubleDash) ? pGC->bgPixel : -1,
		pGC->alu, pGC->planemask, PatternLength, pGCPriv->DashPattern);


#ifdef POLYSEGMENT
    while (nseg--)
#else
    ppt = pptInit;
    x2 = ppt->x + xorg;
    y2 = ppt->y + yorg;
    while(--npt)
#endif
    {
	nbox = nboxInit;
	pbox = pboxInit;

#ifdef POLYSEGMENT
	x1 = pSeg->x1 + xorg;	
	y1 = pSeg->y1 + yorg;
	x2 = pSeg->x2 + xorg;	
	y2 = pSeg->y2 + yorg;
	pSeg++;
#else
	x1 = x2; 
	y1 = y2;
	++ppt;
	if (mode == CoordModePrevious) {
	    xorg = x1; 
	    yorg = y1;
	}
	x2 = ppt->x + xorg; 
	y2 = ppt->y + yorg;
#endif


	if (infoRec->SubsequentDashedBresenhamLine) {
	    if((dmaj = x2 - x1) < 0) {
		dmaj = -dmaj;
		octant = XDECREASING;
	    } else octant = 0;		   

	    if((dmin = y2 - y1) < 0) {
		dmin = -dmin;
		octant |= YDECREASING;
	    }	
	
	    if(dmin >= dmaj){
		tmp = dmin; dmin = dmaj; dmaj = tmp;
		octant |= YMAJOR;
	    }

	    e = -dmaj - ((bias >> octant) & 1);
	    len = dmaj;
	    dmin <<= 1;
	    dmaj <<= 1;
	} else {	/* Muffle compiler */
	    dmin = dmaj = e = octant = len = 0;
	}

	while(nbox--) {
	    oc1 = oc2 = 0;
	    OUTCODES(oc1, x1, y1, pbox);
	    OUTCODES(oc2, x2, y2, pbox);
	    if (!(oc1 | oc2)) {   /* uncliped */
		if(infoRec->SubsequentDashedTwoPointLine) {
		   (*infoRec->SubsequentDashedTwoPointLine)(
				infoRec->pScrn, x1, y1, x2, y2, 
#ifdef POLYSEGMENT
			    	(pGC->capStyle != CapNotLast) ? 0 :
#endif
				OMIT_LAST, PatternOffset);
		} else {
		    (*infoRec->SubsequentDashedBresenhamLine)(
				infoRec->pScrn, x1, y1, dmaj, dmin, e, 
#ifdef POLYSEGMENT
			    	(pGC->capStyle != CapNotLast) ? (len+1) :
#endif
			    	len, octant, PatternOffset);
		}
		break;
	    } else if (oc1 & oc2) { /* completely clipped */
		pbox++;
	    } else if (infoRec->ClippingFlags & HARDWARE_CLIP_DASHED_LINE) {
		(*infoRec->SetClippingRectangle)(infoRec->pScrn,
			pbox->x1, pbox->y1, pbox->x2 - 1, pbox->y2 - 1);

		if(infoRec->SubsequentDashedBresenhamLine) {
		    (*infoRec->SubsequentDashedBresenhamLine)(
				infoRec->pScrn, x1, y1, dmaj, dmin, e, 
#ifdef POLYSEGMENT
			    	(pGC->capStyle != CapNotLast) ? (len+1) :
#endif
			    	len, octant, PatternOffset);
		} else {
			(*infoRec->SubsequentDashedTwoPointLine)(
				infoRec->pScrn, x1, y1, x2, y2, 
#ifdef POLYSEGMENT
			    	(pGC->capStyle != CapNotLast) ? 0 :
#endif
				OMIT_LAST, PatternOffset
			);
		}
		(*infoRec->DisableClipping)(infoRec->pScrn);
		pbox++;
	    } else {
		int new_x1 = x1, new_y1 = y1, new_x2 = x2, new_y2 = y2;
		int clip1 = 0, clip2 = 0;
		int err, adx, ady;
		    
		if(octant & YMAJOR) {
		    ady = dmaj >> 1;
		    adx = dmin >> 1;
		} else {
		    ady = dmin >> 1;
		    adx = dmaj >> 1;
		}

		if (miZeroClipLine(pbox->x1, pbox->y1, 
				       pbox->x2 - 1, pbox->y2 - 1,
				       &new_x1, &new_y1, &new_x2, &new_y2,
				       adx, ady, &clip1, &clip2,
				       octant, bias, oc1, oc2) == -1)
		{
		    pbox++;
		    continue;
		}

		if (octant & YMAJOR)
		    len = abs(new_y2 - new_y1);
		else
		    len = abs(new_x2 - new_x1);
#ifdef POLYSEGMENT
		if (clip2 != 0 || pGC->capStyle != CapNotLast)
		    len++;
#else
		len += (clip2 != 0);
#endif
		if (len) {
		    int abserr, clipdx, clipdy;
			/* unwind bresenham error term to first point */
		    if (clip1) {
			clipdx = abs(new_x1 - x1);
			clipdy = abs(new_y1 - y1);

			if (octant & YMAJOR)
			    err = e + clipdy*dmin - clipdx*dmaj;
			else
			    err = e + clipdx*dmin - clipdy*dmaj;
		    } else
			err = e;

#define range infoRec->DashedBresenhamLineErrorTermBits
		    abserr = abs(err);			    
		    while((abserr & range) || 
			  (dmaj & range) ||
			  (dmin & range)) {
			dmin >>= 1;
			dmaj >>= 1;
			abserr >>= 1;
			err /= 2;
		    }

		    if(octant & YMAJOR)
			offset = abs(new_y1 - y1);
		    else 
			offset = abs(new_x1 - x1);

		    offset += PatternOffset;
		    offset %= PatternLength;

		    (*infoRec->SubsequentDashedBresenhamLine)(
				infoRec->pScrn, new_x1, new_y1,
				dmaj, dmin, err, len, octant, offset);
		}
		pbox++;
	    }
	} /* while (nbox--) */
#ifndef POLYSEGMENT
	len = abs(y2 - y1);
	tmp = abs(x2 - x1);
	PatternOffset += (len > tmp) ? len : tmp;
	PatternOffset %= PatternLength;
#endif
    } /* while (nline--) */

#ifndef POLYSEGMENT
    /* paint the last point if the end style isn't CapNotLast.
       (Assume that a projecting, butt, or round cap that is one
        pixel wide is the same as the single pixel of the endpoint.)
    */

    if ((pGC->capStyle != CapNotLast) &&
	((ppt->x + xorg != pptInit->x + pDrawable->x) ||
	 (ppt->y + yorg != pptInit->y + pDrawable->y) ||
	 (ppt == pptInit + 1)))
    {
	nbox = nboxInit;
	pbox = pboxInit;
	while (nbox--) {
	    if ((x2 >= pbox->x1) && (y2 >= pbox->y1) &&
		(x2 <  pbox->x2) && (y2 <  pbox->y2))
	    {
		if(infoRec->SubsequentDashedTwoPointLine) {
			(*infoRec->SubsequentDashedTwoPointLine)(
				infoRec->pScrn, x2, y2, x2, y2, 0,
				PatternOffset);
		} else {
			(*infoRec->SubsequentDashedBresenhamLine)(
				infoRec->pScrn, x2, y2, 2, 0, -1, 
				1, 0, PatternOffset);
		}
		break;
	    } else
		pbox++;
	}
    }
#endif

    SET_SYNC_FLAG(infoRec);
}


--- NEW FILE: xaaFallback.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaFallback.c,v 1.4 1999/03/14 11:18:09 dawes Exp $ */

#include "misc.h"
#include "xf86.h"
#include "xf86_ansic.h"
#include "xf86_OSproc.h"

#include <X11/X.h>
#include "scrnintstr.h"
#include "xf86str.h"
#include "xaa.h"
#include "xaalocal.h"
#include "gcstruct.h"
#include "pixmapstr.h"
#include "xaawrap.h"



static void
XAAFillSpansFallback(
    DrawablePtr pDraw,
    GC		*pGC,
    int		nInit,	
    DDXPointPtr pptInit,	
    int *pwidthInit,		
    int fSorted )
{
    XAA_GC_OP_PROLOGUE_WITH_RETURN(pGC);
    SYNC_CHECK(pGC);
    (*pGC->ops->FillSpans)(pDraw, pGC, nInit, pptInit, pwidthInit, fSorted);
    XAA_GC_OP_EPILOGUE(pGC);
}

static void
XAASetSpansFallback(
    DrawablePtr		pDraw,
    GCPtr		pGC,
    char		*pcharsrc,
    register DDXPointPtr ppt,
    int			*pwidth,
    int			nspans,
    int			fSorted )
{
    XAA_GC_OP_PROLOGUE_WITH_RETURN(pGC);
    SYNC_CHECK(pGC);
    (*pGC->ops->SetSpans)(pDraw, pGC, pcharsrc, ppt, pwidth, nspans, fSorted);
    XAA_GC_OP_EPILOGUE(pGC);
}

static void
XAAPutImageFallback(
    DrawablePtr pDraw,
    GCPtr	pGC,
    int		depth, 
    int x, int y, int w, int h,
    int		leftPad,
    int		format,
    char 	*pImage )
{
    XAA_GC_OP_PROLOGUE_WITH_RETURN(pGC);
    SYNC_CHECK(pGC);
    (*pGC->ops->PutImage)(pDraw, pGC, depth, x, y, w, h, 
		leftPad, format, pImage);
    XAA_GC_OP_EPILOGUE(pGC);
}

static RegionPtr
XAACopyAreaFallback(
    DrawablePtr pSrc,
    DrawablePtr pDst,
    GC *pGC,
    int srcx, int srcy,
    int width, int height,
    int dstx, int dsty )
{
    RegionPtr ret;

    XAA_GC_OP_PROLOGUE(pGC);
    if((pSrc->type == DRAWABLE_WINDOW) || (pDst->type == DRAWABLE_WINDOW) ||
	IS_OFFSCREEN_PIXMAP(pSrc) || IS_OFFSCREEN_PIXMAP(pDst)) {
	SYNC_CHECK(pGC);
    }
    ret = (*pGC->ops->CopyArea)(pSrc, pDst,
            pGC, srcx, srcy, width, height, dstx, dsty);
    XAA_GC_OP_EPILOGUE(pGC);
    return ret;
}

static RegionPtr
XAACopyPlaneFallback(
    DrawablePtr	pSrc,
    DrawablePtr	pDst,
    GCPtr pGC,
    int	srcx, int srcy,
    int	width, int height,
    int	dstx, int dsty,
    unsigned long bitPlane )
{
    RegionPtr ret;

    XAA_GC_OP_PROLOGUE(pGC);
    if((pSrc->type == DRAWABLE_WINDOW) || (pDst->type == DRAWABLE_WINDOW) ||
	IS_OFFSCREEN_PIXMAP(pSrc) || IS_OFFSCREEN_PIXMAP(pDst)) {
	SYNC_CHECK(pGC);
    }
    ret = (*pGC->ops->CopyPlane)(pSrc, pDst,
	       pGC, srcx, srcy, width, height, dstx, dsty, bitPlane);
    XAA_GC_OP_EPILOGUE(pGC);
    return ret;
}

static void
XAAPolyPointFallback(
    DrawablePtr pDraw,
    GCPtr pGC,
    int mode,
    int npt,
    xPoint *pptInit )
{
    XAA_GC_OP_PROLOGUE_WITH_RETURN(pGC);
    SYNC_CHECK(pGC);
    (*pGC->ops->PolyPoint)(pDraw, pGC, mode, npt, pptInit);
    XAA_GC_OP_EPILOGUE(pGC);
}


static void
XAAPolylinesFallback(
    DrawablePtr pDraw,
    GCPtr	pGC,
    int		mode,		
    int		npt,		
    DDXPointPtr pptInit )
{
    XAA_GC_OP_PROLOGUE_WITH_RETURN(pGC);
    SYNC_CHECK(pGC);
    (*pGC->ops->Polylines)(pDraw, pGC, mode, npt, pptInit);
    XAA_GC_OP_EPILOGUE(pGC);
}

static void 
XAAPolySegmentFallback(
    DrawablePtr	pDraw,
    GCPtr	pGC,
    int		nseg,
    xSegment	*pSeg )
{
    XAA_GC_OP_PROLOGUE_WITH_RETURN(pGC);
    SYNC_CHECK(pGC);
    (*pGC->ops->PolySegment)(pDraw, pGC, nseg, pSeg);
    XAA_GC_OP_EPILOGUE(pGC);
}

static void
XAAPolyRectangleFallback(
    DrawablePtr  pDraw,
    GCPtr        pGC,
    int	         nRectsInit,
    xRectangle  *pRectsInit )
{
    XAA_GC_OP_PROLOGUE_WITH_RETURN(pGC);
    SYNC_CHECK(pGC);
    (*pGC->ops->PolyRectangle)(pDraw, pGC, nRectsInit, pRectsInit);
    XAA_GC_OP_EPILOGUE(pGC);
}

static void
XAAPolyArcFallback(
    DrawablePtr	pDraw,
    GCPtr	pGC,
    int		narcs,
    xArc	*parcs )
{
    XAA_GC_OP_PROLOGUE_WITH_RETURN(pGC);
    SYNC_CHECK(pGC);
    (*pGC->ops->PolyArc)(pDraw, pGC, narcs, parcs);
    XAA_GC_OP_EPILOGUE(pGC);
}

static void
XAAFillPolygonFallback(
    DrawablePtr	pDraw,
    GCPtr	pGC,
    int		shape,
    int		mode,
    int		count,
    DDXPointPtr	ptsIn )
{
    XAA_GC_OP_PROLOGUE_WITH_RETURN(pGC);
    SYNC_CHECK(pGC);
    (*pGC->ops->FillPolygon)(pDraw, pGC, shape, mode, count, ptsIn);
    XAA_GC_OP_EPILOGUE(pGC);
}


static void 
XAAPolyFillRectFallback(
    DrawablePtr	pDraw,
    GCPtr	pGC,
    int		nrectFill, 
    xRectangle	*prectInit )  
{
    XAA_GC_OP_PROLOGUE_WITH_RETURN(pGC);
    SYNC_CHECK(pGC);
    (*pGC->ops->PolyFillRect)(pDraw, pGC, nrectFill, prectInit);
    XAA_GC_OP_EPILOGUE(pGC);
}


static void
XAAPolyFillArcFallback(
    DrawablePtr	pDraw,
    GCPtr	pGC,
    int		narcs,
    xArc	*parcs )
{
    XAA_GC_OP_PROLOGUE_WITH_RETURN(pGC);
    SYNC_CHECK(pGC);
    (*pGC->ops->PolyFillArc)(pDraw, pGC, narcs, parcs);
    XAA_GC_OP_EPILOGUE(pGC);
}

static int
XAAPolyText8Fallback(
    DrawablePtr pDraw,
    GCPtr	pGC,
    int		x, 
    int 	y,
    int 	count,
    char	*chars )
{
    int ret;

    XAA_GC_OP_PROLOGUE(pGC);
    SYNC_CHECK(pGC);
    ret = (*pGC->ops->PolyText8)(pDraw, pGC, x, y, count, chars);
    XAA_GC_OP_EPILOGUE(pGC);
    return ret;
}

static int
XAAPolyText16Fallback(
    DrawablePtr pDraw,
    GCPtr	pGC,
    int		x,
    int		y,
    int 	count,
    unsigned short *chars )
{
    int ret;

    XAA_GC_OP_PROLOGUE(pGC);
    SYNC_CHECK(pGC);
    ret = (*pGC->ops->PolyText16)(pDraw, pGC, x, y, count, chars);
    XAA_GC_OP_EPILOGUE(pGC);
    return ret;
}

static void
XAAImageText8Fallback(
    DrawablePtr pDraw,
    GCPtr	pGC,
    int		x, 
    int		y,
    int 	count,
    char	*chars )
{
    XAA_GC_OP_PROLOGUE_WITH_RETURN(pGC);
    SYNC_CHECK(pGC);
    (*pGC->ops->ImageText8)(pDraw, pGC, x, y, count, chars);
    XAA_GC_OP_EPILOGUE(pGC);
}

static void
XAAImageText16Fallback(
    DrawablePtr pDraw,
    GCPtr	pGC,
    int		x,
    int		y,
    int 	count,
    unsigned short *chars )
{
    XAA_GC_OP_PROLOGUE_WITH_RETURN(pGC);
    SYNC_CHECK(pGC);
    (*pGC->ops->ImageText16)(pDraw, pGC, x, y, count, chars);
    XAA_GC_OP_EPILOGUE(pGC);
}


static void
XAAImageGlyphBltFallback(
    DrawablePtr pDraw,
    GCPtr pGC,
    int xInit, int yInit,
    unsigned int nglyph,
    CharInfoPtr *ppci,
    pointer pglyphBase )
{
    XAA_GC_OP_PROLOGUE_WITH_RETURN(pGC);
    SYNC_CHECK(pGC);
    (*pGC->ops->ImageGlyphBlt)(pDraw, pGC, xInit, yInit, nglyph, ppci, pglyphBase);
    XAA_GC_OP_EPILOGUE(pGC);
}

static void
XAAPolyGlyphBltFallback(
    DrawablePtr pDraw,
    GCPtr pGC,
    int xInit, int yInit,
    unsigned int nglyph,
    CharInfoPtr *ppci,
    pointer pglyphBase )
{
    XAA_GC_OP_PROLOGUE_WITH_RETURN(pGC);
    SYNC_CHECK(pGC);
    (*pGC->ops->PolyGlyphBlt)(pDraw, pGC, xInit, yInit, nglyph, ppci, pglyphBase);
    XAA_GC_OP_EPILOGUE(pGC);
}

static void
XAAPushPixelsFallback(
    GCPtr	pGC,
    PixmapPtr	pBitMap,
    DrawablePtr pDraw,
    int	dx, int dy, int xOrg, int yOrg )
{
    XAA_GC_OP_PROLOGUE_WITH_RETURN(pGC);
    SYNC_CHECK(pGC);
    (*pGC->ops->PushPixels)(pGC, pBitMap, pDraw, dx, dy, xOrg, yOrg);
    XAA_GC_OP_EPILOGUE(pGC);
}

GCOps XAAFallbackOps = {
    XAAFillSpansFallback, XAASetSpansFallback, 
    XAAPutImageFallback, XAACopyAreaFallback, 
    XAACopyPlaneFallback, XAAPolyPointFallback, 
    XAAPolylinesFallback, XAAPolySegmentFallback, 
    XAAPolyRectangleFallback, XAAPolyArcFallback, 
    XAAFillPolygonFallback, XAAPolyFillRectFallback, 
    XAAPolyFillArcFallback, XAAPolyText8Fallback, 
    XAAPolyText16Fallback, XAAImageText8Fallback, 
    XAAImageText16Fallback, XAAImageGlyphBltFallback, 
    XAAPolyGlyphBltFallback, XAAPushPixelsFallback,
#ifdef NEED_LINEHELPER
    NULL,
#endif
    {NULL}		/* devPrivate */
};





--- NEW FILE: xaaFillArc.c ---
/*
 * Copyright 1996  The XFree86 Project
 *
 * Permission is hereby granted, free of charge, to any person obtaining a 
 * copy of this software and associated documentation files (the "Software"), 
 * to deal in the Software without restriction, including without limitation 
 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 
 * and/or sell copies of the Software, and to permit persons to whom the 
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL 
 * HARM HANEMAAYER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF 
 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 
 * SOFTWARE.
 * 
 * Written by Harm Hanemaayer (H.Hanemaayer at inter.nl.net).
 */
/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaFillArc.c,v 1.3 1998/10/25 07:12:12 dawes Exp $ */
 
/*
 * Filled solid arcs, based on cfbfillarc.c.
 *
 * Fill arc using calls to low-level span fill. Because the math for
 * each span can be done concurrently with the drawing of the span
 * with a graphics coprocessor operation, this is faster than just
 * using miPolyFillArc, which first calculates all the spans and then
 * calls FillSpans.
 *
 * Clipped arcs are dispatched to FillSpans.
 */
#include "misc.h"
#include "xf86.h"
#include "xf86_ansic.h"
#include "xf86_OSproc.h"

#include <X11/X.h>
#include "scrnintstr.h"
#include "pixmapstr.h"
#include "xf86str.h"
#include "xaa.h"
#include "xaalocal.h"
#include "mifillarc.h"
#include "mi.h"

/*
 * This is based on the integer-math versions from mi. Perhaps on a
 * Pentium, the floating-point (double)-math version is faster.
 */

static void
XAAFillEllipseSolid(DrawablePtr pDraw, GCPtr pGC, xArc *arc)
{
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
    register int x, y, e;
    int yk, xk, ym, xm, dx, dy, xorg, yorg;
    int slw;
    miFillArcRec info;

    (*infoRec->SetupForSolidFill)(infoRec->pScrn, pGC->fgPixel, pGC->alu,
		pGC->planemask);

    miFillArcSetup(arc, &info);
    MIFILLARCSETUP();
    if (pGC->miTranslate)
    {
	xorg += pDraw->x;
	yorg += pDraw->y;
    }
    while (y > 0)
    {
	MIFILLARCSTEP(slw);
	if (slw > 0) {
	    (*infoRec->SubsequentSolidFillRect)(infoRec->pScrn, xorg - x,
		    yorg - y, slw, 1);
            if (miFillArcLower(slw))
		(*infoRec->SubsequentSolidFillRect)(infoRec->pScrn,
			xorg - x, yorg + y + dy, slw, 1);
	}
    }

    SET_SYNC_FLAG(infoRec);
}


#define ADDSPAN(l,r) \
    if (r >= l) \
	(*infoRec->SubsequentSolidFillRect)( \
	    infoRec->pScrn, l, ya, r - l + 1, 1);

#define ADDSLICESPANS(flip) \
    if (!flip) \
    { \
	ADDSPAN(xl, xr); \
    } \
    else \
    { \
	xc = xorg - x; \
	ADDSPAN(xc, xr); \
	xc += slw - 1; \
	ADDSPAN(xl, xc); \
    }

static void
XAAFillArcSliceSolid(DrawablePtr pDraw, GCPtr pGC, xArc *arc)
{ 
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
    int yk, xk, ym, xm, dx, dy, xorg, yorg, slw;
    register int x, y, e;
    miFillArcRec info;
    miArcSliceRec slice;
    int ya, xl, xr, xc;

    (*infoRec->SetupForSolidFill)(infoRec->pScrn, pGC->fgPixel, pGC->alu,
        pGC->planemask);

    miFillArcSetup(arc, &info);
    miFillArcSliceSetup(arc, &slice, pGC);
    MIFILLARCSETUP();
    slw = arc->height;
    if (slice.flip_top || slice.flip_bot)
	slw += (arc->height >> 1) + 1;
    if (pGC->miTranslate)
    {
	xorg += pDraw->x;
	yorg += pDraw->y;
	slice.edge1.x += pDraw->x;
	slice.edge2.x += pDraw->x;
    }
    while (y > 0)
    {
	MIFILLARCSTEP(slw);
	MIARCSLICESTEP(slice.edge1);
	MIARCSLICESTEP(slice.edge2);
	if (miFillSliceUpper(slice))
	{
	    ya = yorg - y;
	    MIARCSLICEUPPER(xl, xr, slice, slw);
	    
	    ADDSLICESPANS(slice.flip_top);
	}
	if (miFillSliceLower(slice))
	{
	    ya = yorg + y + dy;
	    MIARCSLICELOWER(xl, xr, slice, slw);
	    ADDSLICESPANS(slice.flip_bot);
	}
    }

    SET_SYNC_FLAG(infoRec);
}


void
XAAPolyFillArcSolid(pDraw, pGC, narcs, parcs)
    DrawablePtr	pDraw;
    GCPtr	pGC;
    int		narcs;
    xArc	*parcs;
{
    register xArc *arc;
    register int i;
    int x2, y2;
    BoxRec box;
    RegionPtr cclip;

    cclip = pGC->pCompositeClip;

    if(!REGION_NUM_RECTS(cclip))
	return;

    for (arc = parcs, i = narcs; --i >= 0; arc++)
    {
	if (miFillArcEmpty(arc))
	    continue;
	if (miCanFillArc(arc))
	{
	    box.x1 = arc->x + pDraw->x;
	    box.y1 = arc->y + pDraw->y;
 	    /*
 	     * Because box.x2 and box.y2 get truncated to 16 bits, and the
 	     * RECT_IN_REGION test treats the resulting number as a signed
 	     * integer, the RECT_IN_REGION test alone can go the wrong way.
 	     * This can result in a server crash because the rendering
 	     * routines in this file deal directly with cpu addresses
 	     * of pixels to be stored, and do not clip or otherwise check
 	     * that all such addresses are within their respective pixmaps.
 	     * So we only allow the RECT_IN_REGION test to be used for
 	     * values that can be expressed correctly in a signed short.
 	     */
 	    x2 = box.x1 + (int)arc->width + 1;
 	    box.x2 = x2;
 	    y2 = box.y1 + (int)arc->height + 1;
 	    box.y2 = y2;
 	    if ( (x2 <= MAXSHORT) && (y2 <= MAXSHORT) &&
 		    (RECT_IN_REGION(pDraw->pScreen, cclip, &box) == rgnIN) )
	    {
		if ((arc->angle2 >= FULLCIRCLE) ||
		    (arc->angle2 <= -FULLCIRCLE))
		    XAAFillEllipseSolid(pDraw, pGC, arc);
		else
		    XAAFillArcSliceSolid(pDraw, pGC, arc);
		continue;
	    }
	}
	miPolyFillArc(pDraw, pGC, 1, arc);
    }
}

--- NEW FILE: xaaFillPoly.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaFillPoly.c,v 1.15 2001/10/28 03:34:04 tsi Exp $ */

/*
 * Copyright 1996  The XFree86 Project
 *
 * Permission is hereby granted, free of charge, to any person obtaining a 
 * copy of this software and associated documentation files (the "Software"), 
 * to deal in the Software without restriction, including without limitation 
 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 
 * and/or sell copies of the Software, and to permit persons to whom the 
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL 
 * HARM HANEMAAYER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF 
 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 
 * SOFTWARE.
 * 
 */
 
/*
 * Written by Mark Vojkovich.  Loosly based on an original version
 * written by Harm Hanemaayer (H.Hanemaayer at inter.nl.net) which
 * only did solid rectangles and didn't have trapezoid support.
 *
 */


#include "misc.h"
#include "xf86.h"
#include "xf86_ansic.h"
#include "xf86_OSproc.h"

#include <X11/X.h>
#include "scrnintstr.h"
#include "pixmapstr.h"
#include "xf86str.h"
#include "mi.h"
#include "micoord.h"

#include "xaa.h"
#include "xaalocal.h"

#define POLY_USE_MI		0
#define POLY_FULLY_CLIPPED	1
#define POLY_IS_EASY		2


#define Setup(c,x,vertex,dx,dy,e,sign,step,DX) {\
    x = intToX(vertex); \
    if ((dy = intToY(c) - y)) { \
    	DX = dx = intToX(c) - x; \
	step = 0; \
    	if (dx >= 0) \
    	{ \
	    e = 0; \
	    sign = 1; \
	    if (dx >= dy) {\
	    	step = dx / dy; \
	    	dx %= dy; \
	    } \
    	} \
    	else \
    	{ \
	    e = 1 - dy; \
	    sign = -1; \
	    dx = -dx; \
	    if (dx >= dy) { \
		step = - (dx / dy); \
		dx %= dy; \
	    } \
    	} \
    } \
    x += origin; \
    vertex = c; \
}

#define Step(x,dx,dy,e,sign,step) {\
    x += step; \
    if ((e += dx) > 0) \
    { \
	x += sign; \
	e -= dy; \
    } \
}

#define FixError(x, dx, dy, e, sign, step, h)	{	\
	   e += (h) * dx;				\
	   x += (h) * step;				\
	   if(e > 0) {					\
		x += e * sign/dy;			\
		e %= dy;				\
	   	if(e) {					\
		   x += sign;				\
		   e -= dy;				\
		}					\
	   } 	 					\
}


/*
   XAAIsEasyPoly -

   Checks CoordModeOrigin one rect polygons to see if we need
   to use Mi.
   Returns: POLY_USE_MI, POLY_FULLY_CLIPPED or POLY_IS_EASY
	as well as the pointer to the "top" point and the y
	extents.
*/

int
XAAIsEasyPolygon(
   DDXPointPtr ptsIn,
   int count, 
   BoxPtr extents,
   int origin,		
   DDXPointPtr *topPoint, 	/* return */
   int *topY, int *bottomY,	/* return */
   int shape
){
    int c = 0, vertex1, vertex2;

    *topY = 32767;
    *bottomY = 0;

    origin -= (origin & 0x8000) << 1;
    vertex1 = *((int *) &extents->x1) - origin;
    vertex2 = *((int *) &extents->x2) - origin /* - 0x00010001 */;
                     /* I think this was an error in cfb ^ */

    if (shape == Convex) {
    	while (count--) {
	    c = *((int*)ptsIn);
	    if (((c - vertex1) | (vertex2 - c)) & 0x80008000)
		return POLY_USE_MI;

	    c = intToY(c);
	    if (c < *topY) {
	    	*topY = c;
	    	*topPoint = ptsIn;
	    }
	    ptsIn++;
	    if (c > *bottomY) *bottomY = c;
    	}
    } else {
	int yFlip = 0;
	int dx2, dx1, x1, x2;

	x2 = x1 = -1;
	dx2 = dx1 = 1;

    	while (count--) {
	    c = *((int*)ptsIn);
	    if (((c - vertex1) | (vertex2 - c)) & 0x80008000)
		return POLY_USE_MI;
	    c = intToY(c);
	    if (c < *topY) {
	    	*topY = c;
	    	*topPoint = ptsIn;
	    }
	    ptsIn++;
	    if (c > *bottomY) *bottomY = c;
	    if (c == x1)
		continue;
	    if (dx1 > 0) {
		if (x2 < 0) x2 = c;
		else	    dx2 = dx1 = (c - x1) >> 31;
	    } else if ((c - x1) >> 31 != dx1) {
		dx1 = ~dx1;
		yFlip++;
	    }
	    x1 = c;
       	}
	x1 = (x2 - c) >> 31;
	if (x1 != dx1) yFlip++;
	if (x1 != dx2) yFlip++;
	if (yFlip != 2) {
	   if(*topY == *bottomY)
		return POLY_FULLY_CLIPPED;
	   else
		return POLY_USE_MI;
	}
    }
    if (*topY == *bottomY)
	return POLY_FULLY_CLIPPED;

    return POLY_IS_EASY;
}

void
XAAFillPolygonSolid(
    DrawablePtr	pDraw,
    GCPtr	pGC,
    int		shape,
    int		mode,
    int		count,
    DDXPointPtr	ptsIn 
){
    XAAInfoRecPtr   infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
    int    	    origin, vertex1, vertex2;
    int		    *vertex1p, *vertex2p, *endp;
    int		    x1 = 0, x2 = 0;
    int 	    dx1 = 0, dx2 = 0, dy1 = 0, dy2 = 0;
    int		    DX1 = 0, DX2 = 0, e1 = 0, e2 = 0;
    int		    step1 = 0, step2 = 0, sign1 = 0, sign2 = 0;
    int		    c, y, maxy, h, yoffset;
    DDXPointPtr	    topPoint;

    if(!REGION_NUM_RECTS(pGC->pCompositeClip))
	return;

    if (mode == CoordModePrevious) {
	register DDXPointPtr ppt = ptsIn + 1;

	for (origin = 1; origin < count; origin++, ppt++) {
	    ppt->x += (ppt-1)->x;
	    ppt->y += (ppt-1)->y;
	}
        mode = CoordModeOrigin;
    }
    
    if (REGION_NUM_RECTS(pGC->pCompositeClip) != 1) {
	miFillPolygon (pDraw, pGC, shape, mode, count, ptsIn);
	return;
    }

    origin = coordToInt(pDraw->x, pDraw->y);

    switch( XAAIsEasyPolygon(ptsIn, count, &pGC->pCompositeClip->extents, 
		origin, &topPoint, &y, &maxy, shape) ) {
    case POLY_USE_MI: 
	miFillPolygon (pDraw, pGC, shape, mode, count, ptsIn);
    case POLY_FULLY_CLIPPED: 
	return;
    }

    endp = (int*)ptsIn + count;
    vertex2p = vertex1p = (int *)topPoint;
    origin = pDraw->x;
    yoffset = pDraw->y;
    vertex2 = vertex1 = *vertex2p++;
    if (vertex2p == endp)
	vertex2p = (int *) ptsIn;

    (*infoRec->SetupForSolidFill)(infoRec->pScrn, pGC->fgPixel, pGC->alu,
        pGC->planemask);

    while(1) {
	if (y == intToY(vertex1)) {
	    do {
	    	if (vertex1p == (int *) ptsIn)
		    vertex1p = endp;
	    	c = *--vertex1p;
	    	Setup (c,x1,vertex1,dx1,dy1,e1,sign1,step1,DX1)
	    } while (y >= intToY(vertex1));
	    h = dy1;
	} else {
	    Step(x1,dx1,dy1,e1,sign1,step1)
	    h = intToY(vertex1) - y;
	}
	if (y == intToY(vertex2)) {
	    do {
	    	c = *vertex2p++;
	    	if (vertex2p == endp)
		    vertex2p = (int *) ptsIn;
	    	Setup (c,x2,vertex2,dx2,dy2,e2,sign2,step2,DX2)
	    } while (y >= intToY(vertex2));
	    if (dy2 < h)
		h = dy2;
	} else {
	    Step(x2,dx2,dy2,e2,sign2,step2)
	    if ((c = (intToY(vertex2) - y)) < h)
		h = c;
	}

	/* fill spans for this segment */
        if(DX1 | DX2) {
      	  if(infoRec->SubsequentSolidFillTrap && (h > 6)) {
	     if(x1 == x2) {
		while(x1 == x2) {
	     	   y++;
	    	   if (!--h) break;
	    	   Step(x1,dx1,dy1,e1,sign1,step1)
	    	   Step(x2,dx2,dy2,e2,sign2,step2)
		}
		if(y == maxy) break;
    		if(!h) continue;
	     }

             if(x1 < x2)
 	     	(*infoRec->SubsequentSolidFillTrap)(infoRec->pScrn,
					y + yoffset, h,
					x1, DX1, dy1, e1, 
					x2 - 1, DX2, dy2, e2);
	     else
 	     	(*infoRec->SubsequentSolidFillTrap)(infoRec->pScrn,
					y + yoffset, h,
					x2, DX2, dy2, e2, 
					x1 - 1, DX1, dy1, e1);
	     y += h;	
             if(--h) {
	     	FixError(x1,dx1,dy1,e1,sign1,step1,h);
	     	FixError(x2,dx2,dy2,e2,sign2,step2,h);
		h = 0;
	     }  	
	  } else {
	     while(1) {
	    	if (x2 > x1)
	            (*infoRec->SubsequentSolidFillRect)(infoRec->pScrn,
	            		x1, y + yoffset, x2 - x1, 1);
	        else if (x1 > x2)
	            (*infoRec->SubsequentSolidFillRect)(infoRec->pScrn,
	                    x2, y + yoffset, x1 - x2, 1);
	     	y++;
	    	if (!--h) break;
	    	Step(x1,dx1,dy1,e1,sign1,step1)
	    	Step(x2,dx2,dy2,e2,sign2,step2)
	     }
	  }
	} else {
	    if (x2 > x1)
	        (*infoRec->SubsequentSolidFillRect)(infoRec->pScrn,
	            x1, y + yoffset, x2 - x1, h);
	    else if (x1 > x2)
	        (*infoRec->SubsequentSolidFillRect)(infoRec->pScrn,
	                x2, y + yoffset, x1 - x2, h);

	    y += h;
	    h = 0;
        } 
	if (y == maxy) break;
    }
    SET_SYNC_FLAG(infoRec);
}




void
XAAFillPolygonHelper(
    ScrnInfoPtr pScrn,
    DDXPointPtr	ptsIn,
    int 	count,
    DDXPointPtr topPoint,
    int 	y,
    int		maxy,
    int		origin,
    RectFuncPtr RectFunc,
    TrapFuncPtr TrapFunc,
    int 	xorg,
    int		yorg,
    XAACacheInfoPtr pCache
){
    int		    *vertex1p, *vertex2p, *endp;
    int		    vertex1, vertex2;
    int		    x1 = 0, x2 = 0;
    int		    dx1 = 0, dx2 = 0, dy1 = 0, dy2 = 0;
    int		    DX1 = 0, DX2 = 0, e1 = 0, e2 = 0;
    int		    step1 = 0, step2 = 0, sign1 = 0, sign2 = 0;
    int		    c, h, yoffset;


    endp = (int*)ptsIn + count;
    vertex2p = vertex1p = (int *)topPoint;
    yoffset = intToY(origin);
    origin = intToX(origin);
    vertex2 = vertex1 = *vertex2p++;
    if (vertex2p == endp)
	vertex2p = (int *)ptsIn;

    while(1) {
	if (y == intToY(vertex1)) {
	    do {
	    	if (vertex1p == (int *) ptsIn)
		    vertex1p = endp;
	    	c = *--vertex1p;
	    	Setup (c,x1,vertex1,dx1,dy1,e1,sign1,step1,DX1)
	    } while (y >= intToY(vertex1));
	    h = dy1;
	} else {
	    Step(x1,dx1,dy1,e1,sign1,step1)
	    h = intToY(vertex1) - y;
	}
	if (y == intToY(vertex2)) {
	    do {
	    	c = *vertex2p++;
	    	if (vertex2p == endp)
		    vertex2p = (int *) ptsIn;
	    	Setup (c,x2,vertex2,dx2,dy2,e2,sign2,step2,DX2)
	    } while (y >= intToY(vertex2));
	    if (dy2 < h)
		h = dy2;
	} else {
	    Step(x2,dx2,dy2,e2,sign2,step2)
	    if ((c = (intToY(vertex2) - y)) < h)
		h = c;
	}

	/* fill spans for this segment */
        if(DX1 | DX2) {
      	  if(TrapFunc && (h > 6)) {
	     if(x1 == x2) {
		while(x1 == x2) {
	     	   y++;
	    	   if (!--h) break;
	    	   Step(x1,dx1,dy1,e1,sign1,step1)
	    	   Step(x2,dx2,dy2,e2,sign2,step2)
		}
		if(y == maxy) break;
    		if(!h) continue;
	     }

             if(x1 < x2)
 	     	(*TrapFunc)(pScrn, y + yoffset, h,
				x1, DX1, dy1, e1, 
				x2 - 1, DX2, dy2, e2, xorg, yorg, pCache);
	     else
 	     	(*TrapFunc)(pScrn, y + yoffset, h,
				x2, DX2, dy2, e2, 
				x1 - 1, DX1, dy1, e1, xorg, yorg, pCache);
	     y += h;	
             if(--h) {
	     	FixError(x1,dx1,dy1,e1,sign1,step1,h);
	     	FixError(x2,dx2,dy2,e2,sign2,step2,h);
		h = 0;
	     }  	
	  } else {
	     while(1) {
	    	if (x2 > x1)
	            (*RectFunc)(pScrn,
	            	x1, y + yoffset, x2 - x1, 1, xorg, yorg, pCache);
	        else if (x1 > x2)
	            (*RectFunc)(pScrn,
	                    x2, y + yoffset, x1 - x2, 1, xorg, yorg, pCache);
	     	y++;
	    	if (!--h) break;
	    	Step(x1,dx1,dy1,e1,sign1,step1)
	    	Step(x2,dx2,dy2,e2,sign2,step2)
	     }
	  }
	} else {
	    if (x2 > x1)
	        (*RectFunc)(pScrn,
	            x1, y + yoffset, x2 - x1, h, xorg, yorg, pCache);
	    else if (x1 > x2)
	        (*RectFunc)(pScrn,
	                x2, y + yoffset, x1 - x2, h, xorg, yorg, pCache);

	    y += h;
	    h = 0;
        } 
	if (y == maxy) break;
    }
}

        /*****************\
	|  Solid Helpers  |
	\*****************/

static void
SolidTrapHelper(
   ScrnInfoPtr pScrn,
   int y, int h,
   int x1, int dx1, int dy1, int e1,
   int x2, int dx2, int dy2, int e2,
   int xorg, int yorg,
   XAACacheInfoPtr pCache
){
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);

    (*infoRec->SubsequentSolidFillTrap) (pScrn, 
		y, h, x1, dx1, dy1, e1, x2, dx2, dy2, e2);
}

static void
SolidRectHelper (
   ScrnInfoPtr pScrn,
   int x, int y, int w, int h,
   int xorg, int yorg,   
   XAACacheInfoPtr pCache
){
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);

    (*infoRec->SubsequentSolidFillRect) (pScrn, x, y, w, h);
}


	/*********************\
	|  Mono 8x8 Patterns  |
	\*********************/

static void
Mono8x8PatternTrapHelper_ScreenOrigin(
   ScrnInfoPtr pScrn,
   int y, int h,
   int x1, int dx1, int dy1, int e1,
   int x2, int dx2, int dy2, int e2,
   int xorg, int yorg,
   XAACacheInfoPtr pCache
){
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);

    (*infoRec->SubsequentMono8x8PatternFillTrap) (pScrn, xorg, yorg,
		y, h, x1, dx1, dy1, e1, x2, dx2, dy2, e2);
}

static void
Mono8x8PatternRectHelper_ScreenOrigin (
   ScrnInfoPtr pScrn,
   int x, int y, int w, int h,
   int xorg, int yorg,   
   XAACacheInfoPtr pCache
){
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);

    (*infoRec->SubsequentMono8x8PatternFillRect) (pScrn, xorg, yorg,
						x, y, w, h);
}

static void
Mono8x8PatternRectHelper (
   ScrnInfoPtr pScrn,
   int x, int y, int w, int h,
   int xorg, int yorg,   
   XAACacheInfoPtr pCache
){
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);

    xorg = (x - xorg) & 0x07;
    yorg = (y - yorg) & 0x07;

    if(!(infoRec->Mono8x8PatternFillFlags & 		
				HARDWARE_PATTERN_PROGRAMMED_ORIGIN)){
	if(infoRec->Mono8x8PatternFillFlags & 
				HARDWARE_PATTERN_PROGRAMMED_BITS) {
		int patx = pCache->pat0; 
		int paty = pCache->pat1;
		XAARotateMonoPattern(&patx, &paty, xorg, yorg,
				(infoRec->Mono8x8PatternFillFlags & 		
				BIT_ORDER_IN_BYTE_MSBFIRST));
		xorg = patx; yorg = paty;
	} else {
		int slot = (yorg << 3) + xorg;
	    	xorg = pCache->x + pCache->offsets[slot].x;
	    	yorg = pCache->y + pCache->offsets[slot].y;
	}
     }


    (*infoRec->SubsequentMono8x8PatternFillRect) (pScrn, xorg, yorg,
						x, y, w, h);
}



	/****************\
	|  Cache Expand  |
	\****************/


static void
CacheExpandRectHelper (
   ScrnInfoPtr pScrn,
   int X, int Y, int Width, int Height,
   int xorg, int yorg,   
   XAACacheInfoPtr pCache
){
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
    int x, phaseY, phaseX, skipleft, w, blit_w, blit_h;
    int cacheWidth;

    cacheWidth = (pCache->w * pScrn->bitsPerPixel) / 
	infoRec->CacheColorExpandDensity;

    phaseY = (Y - yorg) % pCache->orig_h;
    if(phaseY < 0) phaseY += pCache->orig_h;
    phaseX = (X - xorg) % pCache->orig_w;
    if(phaseX < 0) phaseX += pCache->orig_w;
	
    while(1) {
	w = Width; skipleft = phaseX; x = X;
	blit_h = pCache->h - phaseY;
	if(blit_h > Height) blit_h = Height;
	
	while(1) {
		blit_w = cacheWidth - skipleft;
		if(blit_w > w) blit_w = w;
		(*infoRec->SubsequentScreenToScreenColorExpandFill)(
			pScrn, x, Y, blit_w, blit_h,
			pCache->x, pCache->y + phaseY, skipleft);
		w -= blit_w;
		if(!w) break;
		x += blit_w;
		skipleft = (skipleft + blit_w) % pCache->orig_w;
	}
	Height -= blit_h;
	if(!Height) break;
	Y += blit_h;
	phaseY = (phaseY + blit_h) % pCache->orig_h;
    }
}



	/**************\
	|  Cache Blit  |
	\**************/


static void
CacheBltRectHelper (
   ScrnInfoPtr pScrn,
   int X, int Y, int Width, int Height,
   int xorg, int yorg,   
   XAACacheInfoPtr pCache
){
     XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
     int x, phaseY, phaseX, skipleft, w, blit_w, blit_h;

     phaseY = (Y - yorg) % pCache->orig_h;
     if(phaseY < 0) phaseY += pCache->orig_h;
     phaseX = (X - xorg) % pCache->orig_w;
     if(phaseX < 0) phaseX += pCache->orig_w;

     while(1) {
	w = Width; skipleft = phaseX; x = X;
	blit_h = pCache->h - phaseY;
	if(blit_h > Height) blit_h = Height;
	
	while(1) {
	    blit_w = pCache->w - skipleft;
	    if(blit_w > w) blit_w = w;
	    (*infoRec->SubsequentScreenToScreenCopy)(pScrn,
			pCache->x + skipleft, pCache->y + phaseY,
			x, Y, blit_w, blit_h);
	    w -= blit_w;
	    if(!w) break;
	    x += blit_w;
	    skipleft = (skipleft + blit_w) % pCache->orig_w;
	}
	Height -= blit_h;
	if(!Height) break;
	Y += blit_h;
	phaseY = (phaseY + blit_h) % pCache->orig_h;
     }	
}


	/**********************\
	|   Stippled Polygons  |
	\**********************/


void
XAAFillPolygonStippled(
    DrawablePtr	pDraw,
    GCPtr	pGC,
    int		shape,
    int		mode,
    int		count,
    DDXPointPtr	ptsIn 
){
    XAAInfoRecPtr   infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
    XAAPixmapPtr    pPriv = XAA_GET_PIXMAP_PRIVATE(pGC->stipple);
    int    	    origin, type, patx, paty, fg, bg;
    int		    y, maxy, xorg, yorg;
    DDXPointPtr	    topPoint;
    XAACacheInfoPtr pCache = NULL;
    RectFuncPtr	    RectFunc = NULL;
    TrapFuncPtr	    TrapFunc = NULL;

    if(!REGION_NUM_RECTS(pGC->pCompositeClip))
	return;

    if (mode == CoordModePrevious) {
	register DDXPointPtr ppt = ptsIn + 1;

	for (origin = 1; origin < count; origin++, ppt++) {
	    ppt->x += (ppt-1)->x;
	    ppt->y += (ppt-1)->y;
	}
        mode = CoordModeOrigin;
    }
    
    if (REGION_NUM_RECTS(pGC->pCompositeClip) != 1) {
	miFillPolygon (pDraw, pGC, shape, mode, count, ptsIn);
	return;
    }


    if(pGC->fillStyle == FillStippled) {
    	type = (*infoRec->StippledFillChooser)(pGC);
	fg = pGC->fgPixel;  bg = -1;
    } else {
    	type = (*infoRec->OpaqueStippledFillChooser)(pGC);
	fg = pGC->fgPixel;  bg = pGC->bgPixel;
    }


    if(!type) {
	(*XAAFallbackOps.FillPolygon)(pDraw, pGC, shape, mode, count, ptsIn);
	return;
    }
	
    if((type == DO_COLOR_EXPAND) || (type == DO_COLOR_8x8)) {
	miFillPolygon (pDraw, pGC, shape, mode, count, ptsIn);
	return;
    }

    origin = *((int *)&pDraw->x);

    switch( XAAIsEasyPolygon(ptsIn, count, &pGC->pCompositeClip->extents,
		 origin, &topPoint, &y, &maxy, shape) ) {
    case POLY_USE_MI: 
	miFillPolygon (pDraw, pGC, shape, mode, count, ptsIn);
    case POLY_FULLY_CLIPPED: 
	return;
    }

    xorg = (pDraw->x + pGC->patOrg.x);
    yorg = (pDraw->y + pGC->patOrg.y);


    if((fg == bg) && (bg != -1) && infoRec->SetupForSolidFill) {

	(*infoRec->SetupForSolidFill)(infoRec->pScrn, fg,
				pGC->alu, pGC->planemask);

	RectFunc = SolidRectHelper;
        TrapFunc = infoRec->SubsequentSolidFillTrap ? SolidTrapHelper : NULL;
    } else
    switch(type) {
	case DO_MONO_8x8:
	    patx = pPriv->pattern0; paty = pPriv->pattern1;
	    if(infoRec->Mono8x8PatternFillFlags & 
				HARDWARE_PATTERN_SCREEN_ORIGIN) {
		xorg = (-xorg) & 0x07; yorg = (-yorg) & 0x07;
		if(infoRec->Mono8x8PatternFillFlags & 
					HARDWARE_PATTERN_PROGRAMMED_BITS) {
		    if(!(infoRec->Mono8x8PatternFillFlags & 		
					HARDWARE_PATTERN_PROGRAMMED_ORIGIN)) {
		        XAARotateMonoPattern(&patx, &paty, xorg, yorg,
				(infoRec->Mono8x8PatternFillFlags & 		
				BIT_ORDER_IN_BYTE_MSBFIRST));
		        xorg = patx; yorg = paty;
		    }
	        } else {
		    XAACacheInfoPtr pCache = (*infoRec->CacheMono8x8Pattern)(
					infoRec->pScrn, patx, paty);
		    patx = pCache->x;  paty = pCache->y;
		    if(!(infoRec->Mono8x8PatternFillFlags & 
				HARDWARE_PATTERN_PROGRAMMED_ORIGIN)){
			int slot = (yorg << 3) + xorg;
			patx += pCache->offsets[slot].x;
			paty += pCache->offsets[slot].y;
			xorg = patx;  yorg = paty;
		    }
	        }	
		RectFunc = Mono8x8PatternRectHelper_ScreenOrigin;
		if(infoRec->SubsequentMono8x8PatternFillTrap)
		    TrapFunc = Mono8x8PatternTrapHelper_ScreenOrigin;
	    } else {  /* !HARDWARE_PATTERN_SCREEN_ORIGIN */
		if(!(infoRec->Mono8x8PatternFillFlags & 
				HARDWARE_PATTERN_PROGRAMMED_BITS)){
		    pCache = (*infoRec->CacheMono8x8Pattern)(
					infoRec->pScrn, patx, paty);
		    patx = pCache->x;  paty = pCache->y;
	    	} else {
                    pCache = &(infoRec->ScratchCacheInfoRec);
                    pCache->pat0 = patx;
                    pCache->pat1 = paty;
                }
		RectFunc = Mono8x8PatternRectHelper;
       	    }

	    (*infoRec->SetupForMono8x8PatternFill)(infoRec->pScrn, 
				patx, paty, fg, bg, pGC->alu, pGC->planemask);
	    break;
	case DO_CACHE_EXPAND:
	    pCache = (*infoRec->CacheMonoStipple)(infoRec->pScrn, pGC->stipple);

	    (*infoRec->SetupForScreenToScreenColorExpandFill)(
		infoRec->pScrn, fg, bg, pGC->alu, pGC->planemask);

	    RectFunc = CacheExpandRectHelper;
	    break;
	case DO_CACHE_BLT:
	    pCache = (*infoRec->CacheStipple)(infoRec->pScrn, pGC->stipple, 
							fg, bg);
	    (*infoRec->SetupForScreenToScreenCopy)(infoRec->pScrn, 1, 1, 
		pGC->alu, pGC->planemask, pCache->trans_color);

	    RectFunc = CacheBltRectHelper;
	    break;
	default:
	    return;
    }
        

    XAAFillPolygonHelper(infoRec->pScrn, ptsIn, count, topPoint, 
		y, maxy, origin, RectFunc, TrapFunc, xorg, yorg, pCache);

    SET_SYNC_FLAG(infoRec);	
}




	/*******************\
	|   Tiled Polygons  |
	\*******************/


void
XAAFillPolygonTiled(
    DrawablePtr	pDraw,
    GCPtr	pGC,
    int		shape,
    int		mode,
    int		count,
    DDXPointPtr	ptsIn 
){
    XAAInfoRecPtr   infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
    XAAPixmapPtr    pPriv = XAA_GET_PIXMAP_PRIVATE(pGC->tile.pixmap);
    int    	    origin, type, patx, paty;
    int		    y, maxy, xorg, yorg;
    DDXPointPtr	    topPoint;
    XAACacheInfoPtr pCache = NULL;
    RectFuncPtr	    RectFunc = NULL;
    TrapFuncPtr	    TrapFunc = NULL;

    if(!REGION_NUM_RECTS(pGC->pCompositeClip))
	return;

    if (mode == CoordModePrevious) {
	register DDXPointPtr ppt = ptsIn + 1;

	for (origin = 1; origin < count; origin++, ppt++) {
	    ppt->x += (ppt-1)->x;
	    ppt->y += (ppt-1)->y;
	}
        mode = CoordModeOrigin;
    }
    
    if (REGION_NUM_RECTS(pGC->pCompositeClip) != 1) {
	miFillPolygon (pDraw, pGC, shape, mode, count, ptsIn);
	return;
    }


    type = (*infoRec->TiledFillChooser)(pGC);

    if(!type || (type == DO_IMAGE_WRITE)) {
	(*XAAFallbackOps.FillPolygon)(pDraw, pGC, shape, mode, count, ptsIn);
	return;
    }
	
    if(type == DO_COLOR_8x8) {
	miFillPolygon (pDraw, pGC, shape, mode, count, ptsIn);
	return;
    }

    origin = *((int *)&pDraw->x);

    switch( XAAIsEasyPolygon(ptsIn, count, &pGC->pCompositeClip->extents,
		 origin, &topPoint, &y, &maxy, shape) ) {
    case POLY_USE_MI: 
	miFillPolygon (pDraw, pGC, shape, mode, count, ptsIn);
    case POLY_FULLY_CLIPPED: 
	return;
    }

    xorg = (pDraw->x + pGC->patOrg.x);
    yorg = (pDraw->y + pGC->patOrg.y);

    switch(type) {
	case DO_MONO_8x8:
	    patx = pPriv->pattern0; paty = pPriv->pattern1;
	    if(infoRec->Mono8x8PatternFillFlags & 
				HARDWARE_PATTERN_SCREEN_ORIGIN) {
		xorg = (-xorg) & 0x07; yorg = (-yorg) & 0x07;
		if(infoRec->Mono8x8PatternFillFlags & 
					HARDWARE_PATTERN_PROGRAMMED_BITS) {
		    if(!(infoRec->Mono8x8PatternFillFlags & 		
					HARDWARE_PATTERN_PROGRAMMED_ORIGIN)) {
		        XAARotateMonoPattern(&patx, &paty, xorg, yorg,
				(infoRec->Mono8x8PatternFillFlags & 		
				BIT_ORDER_IN_BYTE_MSBFIRST));
		        xorg = patx; yorg = paty;
		    }
	        } else {
		    XAACacheInfoPtr pCache = (*infoRec->CacheMono8x8Pattern)(
					infoRec->pScrn, patx, paty);
		    patx = pCache->x;  paty = pCache->y;
		    if(!(infoRec->Mono8x8PatternFillFlags & 
				HARDWARE_PATTERN_PROGRAMMED_ORIGIN)){
			int slot = (yorg << 3) + xorg;
			patx += pCache->offsets[slot].x;
			paty += pCache->offsets[slot].y;
			xorg = patx;  yorg = paty;
		    }
	        }	
		RectFunc = Mono8x8PatternRectHelper_ScreenOrigin;
		if(infoRec->SubsequentMono8x8PatternFillTrap)
		    TrapFunc = Mono8x8PatternTrapHelper_ScreenOrigin;
	    } else {  /* !HARDWARE_PATTERN_SCREEN_ORIGIN */
		if(!(infoRec->Mono8x8PatternFillFlags & 
				HARDWARE_PATTERN_PROGRAMMED_BITS)){
		    pCache = (*infoRec->CacheMono8x8Pattern)(
					infoRec->pScrn, patx, paty);
		    patx = pCache->x;  paty = pCache->y;
	    	}
		else {
		  pCache = &(infoRec->ScratchCacheInfoRec);
		  pCache->pat0 = patx;
		  pCache->pat1 = paty;
		}
		RectFunc = Mono8x8PatternRectHelper;
       	    }

	    (*infoRec->SetupForMono8x8PatternFill)(infoRec->pScrn, 
		 patx, paty, pPriv->fg, pPriv->bg, pGC->alu, pGC->planemask);
	    break;
	case DO_CACHE_BLT:
            pCache = (*infoRec->CacheTile)(infoRec->pScrn, pGC->tile.pixmap);
	    (*infoRec->SetupForScreenToScreenCopy)(infoRec->pScrn, 1, 1, 
		pGC->alu, pGC->planemask, -1);

	    RectFunc = CacheBltRectHelper;
	    break;
	case DO_PIXMAP_COPY:
	    pCache = &(infoRec->ScratchCacheInfoRec);
	    pCache->x = pPriv->offscreenArea->box.x1;
	    pCache->y = pPriv->offscreenArea->box.y1;
	    pCache->w = pCache->orig_w = 
		pPriv->offscreenArea->box.x2 - pCache->x;
	    pCache->h = pCache->orig_h = 
		pPriv->offscreenArea->box.y2 - pCache->y;

	    (*infoRec->SetupForScreenToScreenCopy)(infoRec->pScrn, 1, 1, 
		pGC->alu, pGC->planemask, -1);

	    RectFunc = CacheBltRectHelper;
	    break;
	default:
	    return;
    }

    XAAFillPolygonHelper(infoRec->pScrn, ptsIn, count, topPoint, 
		y, maxy, origin, RectFunc, TrapFunc, xorg, yorg, pCache);

    SET_SYNC_FLAG(infoRec);	
}



--- NEW FILE: xaaFillRect.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaFillRect.c,v 1.15tsi Exp $ */

#include "misc.h"
#include "xf86.h"
#include "xf86_ansic.h"
#include "xf86_OSproc.h"

#include <X11/X.h>
#include "scrnintstr.h"
#include "pixmapstr.h"
#include "xf86str.h"
#include "xaa.h"
#include "xaalocal.h"


static void XAARenderSolidRects(GCPtr, int, BoxPtr, int, int);
static void XAARenderColor8x8Rects(GCPtr, int, BoxPtr, int, int);
static void XAARenderMono8x8Rects(GCPtr, int, BoxPtr, int, int);
static void XAARenderColorExpandRects(GCPtr, int, BoxPtr, int, int);
[...1054 lines suppressed...]
	    */
	    while(n--) {
		pboxClipped->x1 = max(box.x1, pbox->x1);
		pboxClipped->y1 = max(box.y1, pbox->y1);
		pboxClipped->x2 = min(box.x2, pbox->x2);
		pboxClipped->y2 = min(box.y2, pbox->y2);
		pbox++;

		/* see if clipping left anything */
		if(pboxClipped->x1 < pboxClipped->x2 && 
		   pboxClipped->y1 < pboxClipped->y2) {
		    pboxClipped++;
		}
	    }
    	}
    }

    return(pboxClipped - pboxClippedBase);  
}


--- NEW FILE: xaaGC.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaGC.c,v 1.18 2000/09/28 20:48:00 mvojkovi Exp $ */

#include "misc.h"
#include "xf86.h"
#include "xf86_ansic.h"
#include "xf86_OSproc.h"

#include <X11/X.h>
#include "scrnintstr.h"
#include "xf86str.h"
#include "xaa.h"
#include "xaalocal.h"
#include "migc.h"
#include "gcstruct.h"
#include "pixmapstr.h"
#include "xaawrap.h"

static void XAAValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDraw);
static void XAAChangeGC(GCPtr pGC, unsigned long mask);
static void XAACopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst);
static void XAADestroyGC(GCPtr pGC);
static void XAAChangeClip(GCPtr pGC, int type, pointer pvalue, int nrects);
static void XAADestroyClip(GCPtr pGC);
static void XAACopyClip(GCPtr pgcDst, GCPtr pgcSrc);

GCFuncs XAAGCFuncs = {
    XAAValidateGC, XAAChangeGC, XAACopyGC, XAADestroyGC,
    XAAChangeClip, XAADestroyClip, XAACopyClip
};

extern GCOps XAAPixmapOps;

Bool
XAACreateGC(GCPtr pGC)
{
    ScreenPtr    pScreen = pGC->pScreen;
    XAAGCPtr     pGCPriv = (XAAGCPtr)(pGC->devPrivates[XAAGCIndex].ptr);
    Bool         ret;

    XAA_SCREEN_PROLOGUE(pScreen,CreateGC);

    if((ret = (*pScreen->CreateGC)(pGC))) {	
	pGCPriv->wrapOps = NULL;
	pGCPriv->wrapFuncs = pGC->funcs;
	pGCPriv->XAAOps = &XAAFallbackOps;
	pGCPriv->flags = 0;
	pGCPriv->DashLength = 0;
	pGCPriv->DashPattern = NULL;
	pGCPriv->changes = 0;
	/* initialize any other private fields here */
	pGC->funcs = &XAAGCFuncs;
    }
 
    XAA_SCREEN_EPILOGUE(pScreen,CreateGC,XAACreateGC);

    return ret;
}


static void
XAAValidateGC(
   GCPtr         pGC,
   unsigned long changes,
   DrawablePtr   pDraw 
){
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
    XAA_GC_FUNC_PROLOGUE(pGC);

    (*pGC->funcs->ValidateGC)(pGC, changes, pDraw);

    if((changes & GCPlaneMask) &&
       ((pGC->planemask & infoRec->FullPlanemasks[pGC->depth - 1]) == 
	 infoRec->FullPlanemasks[pGC->depth - 1]))
    {	
	pGC->planemask = ~0;
    }

    if(pGC->depth != 32) {
	if(pGC->bgPixel == -1) /* -1 is reserved for transparency */
	    pGC->bgPixel = 0x7fffffff; 
	if(pGC->fgPixel == -1) /* -1 is reserved for transparency */
	    pGC->fgPixel = 0x7fffffff; 
    }

    if((pDraw->type == DRAWABLE_PIXMAP) && !IS_OFFSCREEN_PIXMAP(pDraw)){
	pGCPriv->flags = OPS_ARE_PIXMAP;
        pGCPriv->changes |= changes;

	/* make sure we're not using videomemory pixmaps to render
	   onto system memory drawables */

	if((pGC->fillStyle == FillTiled) && 
	    IS_OFFSCREEN_PIXMAP(pGC->tile.pixmap) &&
	    !OFFSCREEN_PIXMAP_LOCKED(pGC->tile.pixmap)) {

	    XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pGC->tile.pixmap);
	    FBAreaPtr area = pPriv->offscreenArea;

	    XAARemoveAreaCallback(area); /* clobbers pPriv->offscreenArea */
	    xf86FreeOffscreenArea(area);
	}
    } 
    else if(!infoRec->pScrn->vtSema && (pDraw->type == DRAWABLE_WINDOW)) {
	pGCPriv->flags = 0;
        pGCPriv->changes |= changes;
    }
    else {
	if(!(pGCPriv->flags & OPS_ARE_ACCEL)) {	
	    changes |= pGCPriv->changes;
	    pGCPriv->changes = 0;
	}
	pGCPriv->flags = OPS_ARE_ACCEL;

#if 1
	/* Ugh.  If we can't use the blitter on offscreen pixmaps used
	   as tiles, then we need to move them out as cfb can't handle
	   tiles with non-zero origins */

	if((pGC->fillStyle == FillTiled) && 
	    IS_OFFSCREEN_PIXMAP(pGC->tile.pixmap) &&
	    (DO_PIXMAP_COPY != (*infoRec->TiledFillChooser)(pGC))) {

	    XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pGC->tile.pixmap);
	    FBAreaPtr area = pPriv->offscreenArea;

	    XAARemoveAreaCallback(area); /* clobbers pPriv->offscreenArea */
	    xf86FreeOffscreenArea(area);
	}
#endif
    }

    XAA_GC_FUNC_EPILOGUE(pGC);

    if(!(pGCPriv->flags & OPS_ARE_ACCEL)) return;

    if((changes & GCTile) && !pGC->tileIsPixel && pGC->tile.pixmap){
	XAAPixmapPtr pixPriv = XAA_GET_PIXMAP_PRIVATE(pGC->tile.pixmap);
		
	if(pixPriv->flags & DIRTY) {
	    pixPriv->flags &= ~(DIRTY | REDUCIBILITY_MASK);
	    pGC->tile.pixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
	}
    }
    if((changes & GCStipple) && pGC->stipple){
	XAAPixmapPtr pixPriv = XAA_GET_PIXMAP_PRIVATE(pGC->stipple);
		
	if(pixPriv->flags & DIRTY) {
	    pixPriv->flags &= ~(DIRTY | REDUCIBILITY_MASK);
	    pGC->stipple->drawable.serialNumber = NEXT_SERIAL_NUMBER;
	}
    }

    /* If our Ops are still the default ones we need to allocate new ones */
    if(pGC->ops == &XAAFallbackOps) {
	if(!(pGCPriv->XAAOps = xalloc(sizeof(GCOps)))) {	
	    pGCPriv->XAAOps = &XAAFallbackOps;
	    return;
	}
	/* make a modifiable copy of the default ops */
	memcpy(pGCPriv->XAAOps, &XAAFallbackOps, sizeof(GCOps));
	pGC->ops = pGCPriv->XAAOps;
	changes = ~0;
    }

    if(!changes) return;

    if((changes & GCDashList) && infoRec->ComputeDash)
	infoRec->ComputeDash(pGC);

    if(changes & infoRec->FillSpansMask)
	(*infoRec->ValidateFillSpans)(pGC, changes, pDraw); 	

    if(changes & infoRec->SetSpansMask)
	(*infoRec->ValidateSetSpans)(pGC, changes, pDraw); 	

    if(changes & infoRec->PutImageMask)
	(*infoRec->ValidatePutImage)(pGC, changes, pDraw); 	

    if(changes & infoRec->CopyAreaMask)
	(*infoRec->ValidateCopyArea)(pGC, changes, pDraw); 	

    if(changes & infoRec->CopyPlaneMask)
	(*infoRec->ValidateCopyPlane)(pGC, changes, pDraw); 	

    if(changes & infoRec->PolyPointMask)
	(*infoRec->ValidatePolyPoint)(pGC, changes, pDraw); 	

    if(changes & infoRec->PolylinesMask)
	(*infoRec->ValidatePolylines)(pGC, changes, pDraw); 	

    if(changes & infoRec->PolySegmentMask)
	(*infoRec->ValidatePolySegment)(pGC, changes, pDraw); 	

    if(changes & infoRec->PolyRectangleMask)
	(*infoRec->ValidatePolyRectangle)(pGC, changes, pDraw); 	

    if(changes & infoRec->PolyArcMask)
	(*infoRec->ValidatePolyArc)(pGC, changes, pDraw); 	

    if(changes & infoRec->FillPolygonMask)
	(*infoRec->ValidateFillPolygon)(pGC, changes, pDraw); 	

    if(changes & infoRec->PolyFillRectMask)
	(*infoRec->ValidatePolyFillRect)(pGC, changes, pDraw); 	
 
    if(changes & infoRec->PolyFillArcMask)
	(*infoRec->ValidatePolyFillArc)(pGC, changes, pDraw); 	

    if(changes & infoRec->PolyGlyphBltMask)
	(*infoRec->ValidatePolyGlyphBlt)(pGC, changes, pDraw);

    if(changes & infoRec->ImageGlyphBltMask)
	(*infoRec->ValidateImageGlyphBlt)(pGC, changes, pDraw);

    if(changes & infoRec->PolyText8Mask)
	(*infoRec->ValidatePolyText8)(pGC, changes, pDraw);
    
    if(changes & infoRec->PolyText16Mask)
	(*infoRec->ValidatePolyText16)(pGC, changes, pDraw);

    if(changes & infoRec->ImageText8Mask)
	(*infoRec->ValidateImageText8)(pGC, changes, pDraw);
    
    if(changes & infoRec->ImageText16Mask)
	(*infoRec->ValidateImageText16)(pGC, changes, pDraw);
 
    if(changes & infoRec->PushPixelsMask) 
	(*infoRec->ValidatePushPixels)(pGC, changes, pDraw); 	
}


static void
XAADestroyGC(GCPtr pGC)
{
    XAA_GC_FUNC_PROLOGUE (pGC);
     
    if(pGCPriv->XAAOps != &XAAFallbackOps)
	xfree(pGCPriv->XAAOps);

    if(pGCPriv->DashPattern)
	xfree(pGCPriv->DashPattern);    

    (*pGC->funcs->DestroyGC)(pGC);
    XAA_GC_FUNC_EPILOGUE (pGC);
}

static void
XAAChangeGC (
    GCPtr	    pGC,
    unsigned long   mask
)
{
    XAA_GC_FUNC_PROLOGUE (pGC);
    (*pGC->funcs->ChangeGC) (pGC, mask);
    XAA_GC_FUNC_EPILOGUE (pGC);

   /* we have to assume that shared memory pixmaps are dirty 
      because we can't wrap all operations on them */

    if((mask & GCTile) && !pGC->tileIsPixel &&
	PIXMAP_IS_SHARED(pGC->tile.pixmap))
    {
	XAAPixmapPtr pPixPriv = XAA_GET_PIXMAP_PRIVATE(pGC->tile.pixmap);
	pPixPriv->flags |= DIRTY;
    }

    if((mask & GCStipple) && PIXMAP_IS_SHARED(pGC->stipple)){
	XAAPixmapPtr pPixPriv = XAA_GET_PIXMAP_PRIVATE(pGC->stipple);
	pPixPriv->flags |= DIRTY;
    }
}

static void
XAACopyGC (
    GCPtr	    pGCSrc, 
    unsigned long   mask,
    GCPtr	    pGCDst)
{
    XAA_GC_FUNC_PROLOGUE (pGCDst);
    (*pGCDst->funcs->CopyGC) (pGCSrc, mask, pGCDst);
    XAA_GC_FUNC_EPILOGUE (pGCDst);
}
static void
XAAChangeClip (
    GCPtr   pGC,
    int		type,
    pointer	pvalue,
    int		nrects )
{
    XAA_GC_FUNC_PROLOGUE (pGC);
    (*pGC->funcs->ChangeClip) (pGC, type, pvalue, nrects);
    XAA_GC_FUNC_EPILOGUE (pGC);
}

static void
XAACopyClip(GCPtr pgcDst, GCPtr pgcSrc)
{
    XAA_GC_FUNC_PROLOGUE (pgcDst);
    (* pgcDst->funcs->CopyClip)(pgcDst, pgcSrc);
    XAA_GC_FUNC_EPILOGUE (pgcDst);
}

static void
XAADestroyClip(GCPtr pGC)
{
    XAA_GC_FUNC_PROLOGUE (pGC);
    (* pGC->funcs->DestroyClip)(pGC);
    XAA_GC_FUNC_EPILOGUE (pGC);
}
 
/**** Pixmap Wrappers ****/



static void
XAAFillSpansPixmap(
    DrawablePtr pDraw,
    GC		*pGC,
    int		nInit,	
    DDXPointPtr pptInit,	
    int *pwidthInit,		
    int fSorted 
){
    XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);    
    (*pGC->ops->FillSpans)(pDraw, pGC, nInit, pptInit, pwidthInit, fSorted);
    XAA_PIXMAP_OP_EPILOGUE(pGC);
}

static void
XAASetSpansPixmap(
    DrawablePtr		pDraw,
    GCPtr		pGC,
    char		*pcharsrc,
    register DDXPointPtr ppt,
    int			*pwidth,
    int			nspans,
    int			fSorted 
){
    XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);
    (*pGC->ops->SetSpans)(pDraw, pGC, pcharsrc, ppt, pwidth, nspans, fSorted);
    XAA_PIXMAP_OP_EPILOGUE(pGC);
}

static void
XAAPutImagePixmap(
    DrawablePtr pDraw,
    GCPtr	pGC,
    int		depth, 
    int x, int y, int w, int h,
    int		leftPad,
    int		format,
    char 	*pImage 
){
    XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);
    (*pGC->ops->PutImage)(pDraw, pGC, depth, x, y, w, h, 
		leftPad, format, pImage);
    XAA_PIXMAP_OP_EPILOGUE(pGC);
}

static RegionPtr
XAACopyAreaPixmap(
    DrawablePtr pSrc,
    DrawablePtr pDst,
    GC *pGC,
    int srcx, int srcy,
    int width, int height,
    int dstx, int dsty 
){
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
    RegionPtr ret;

    if(infoRec->pScrn->vtSema && 
	((pSrc->type == DRAWABLE_WINDOW) || IS_OFFSCREEN_PIXMAP(pSrc))) 
    {
	if(infoRec->ReadPixmap && (pGC->alu == GXcopy) &&
           (pSrc->bitsPerPixel == pDst->bitsPerPixel) &&
          ((pGC->planemask & infoRec->FullPlanemasks[pSrc->depth - 1])
              == infoRec->FullPlanemasks[pSrc->depth - 1]))
        {
            XAAPixmapPtr pixPriv = XAA_GET_PIXMAP_PRIVATE((PixmapPtr)(pDst));
	    pixPriv->flags |= DIRTY; 

            return (XAABitBlt( pSrc, pDst, pGC,
                srcx, srcy, width, height, dstx, dsty,
                XAADoImageRead, 0L));
        } else
	if(infoRec->NeedToSync) {
	   (*infoRec->Sync)(infoRec->pScrn);
	    infoRec->NeedToSync = FALSE;
	}
    }    

    {
	XAA_PIXMAP_OP_PROLOGUE(pGC, pDst);
	ret = (*pGC->ops->CopyArea)(pSrc, pDst,
            pGC, srcx, srcy, width, height, dstx, dsty);
	XAA_PIXMAP_OP_EPILOGUE(pGC);
    }
    return ret;
}

static RegionPtr
XAACopyPlanePixmap(
    DrawablePtr	pSrc,
    DrawablePtr	pDst,
    GCPtr pGC,
    int	srcx, int srcy,
    int	width, int height,
    int	dstx, int dsty,
    unsigned long bitPlane 
){
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
    RegionPtr ret;

    XAA_PIXMAP_OP_PROLOGUE(pGC, pDst);

    if(infoRec->pScrn->vtSema && 
	((pSrc->type == DRAWABLE_WINDOW) || IS_OFFSCREEN_PIXMAP(pSrc))){
	if(infoRec->NeedToSync) {
	   (*infoRec->Sync)(infoRec->pScrn);
	    infoRec->NeedToSync = FALSE;
	}
    }    

    ret = (*pGC->ops->CopyPlane)(pSrc, pDst,
	       pGC, srcx, srcy, width, height, dstx, dsty, bitPlane);
    XAA_PIXMAP_OP_EPILOGUE(pGC);
    return ret;
}

static void
XAAPolyPointPixmap(
    DrawablePtr pDraw,
    GCPtr pGC,
    int mode,
    int npt,
    xPoint *pptInit 
){
    XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);
    (*pGC->ops->PolyPoint)(pDraw, pGC, mode, npt, pptInit);
    XAA_PIXMAP_OP_EPILOGUE(pGC);
}


static void
XAAPolylinesPixmap(
    DrawablePtr pDraw,
    GCPtr	pGC,
    int		mode,		
    int		npt,		
    DDXPointPtr pptInit 
){
    XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);
    (*pGC->ops->Polylines)(pDraw, pGC, mode, npt, pptInit);
    XAA_PIXMAP_OP_EPILOGUE(pGC);
}

static void 
XAAPolySegmentPixmap(
    DrawablePtr	pDraw,
    GCPtr	pGC,
    int		nseg,
    xSegment	*pSeg 
){
    XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);
    (*pGC->ops->PolySegment)(pDraw, pGC, nseg, pSeg);
    XAA_PIXMAP_OP_EPILOGUE(pGC);
}

static void
XAAPolyRectanglePixmap(
    DrawablePtr  pDraw,
    GCPtr        pGC,
    int	         nRectsInit,
    xRectangle  *pRectsInit 
){
    XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);
    (*pGC->ops->PolyRectangle)(pDraw, pGC, nRectsInit, pRectsInit);
    XAA_PIXMAP_OP_EPILOGUE(pGC);
}

static void
XAAPolyArcPixmap(
    DrawablePtr	pDraw,
    GCPtr	pGC,
    int		narcs,
    xArc	*parcs 
){
    XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);
    (*pGC->ops->PolyArc)(pDraw, pGC, narcs, parcs);
    XAA_PIXMAP_OP_EPILOGUE(pGC);
}

static void
XAAFillPolygonPixmap(
    DrawablePtr	pDraw,
    GCPtr	pGC,
    int		shape,
    int		mode,
    int		count,
    DDXPointPtr	ptsIn 
){
    XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);
    (*pGC->ops->FillPolygon)(pDraw, pGC, shape, mode, count, ptsIn);
    XAA_PIXMAP_OP_EPILOGUE(pGC);
}


static void 
XAAPolyFillRectPixmap(
    DrawablePtr	pDraw,
    GCPtr	pGC,
    int		nrectFill, 
    xRectangle	*prectInit 
){
    XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);
    (*pGC->ops->PolyFillRect)(pDraw, pGC, nrectFill, prectInit);
    XAA_PIXMAP_OP_EPILOGUE(pGC);
}


static void
XAAPolyFillArcPixmap(
    DrawablePtr	pDraw,
    GCPtr	pGC,
    int		narcs,
    xArc	*parcs 
){
    XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);
    (*pGC->ops->PolyFillArc)(pDraw, pGC, narcs, parcs);
    XAA_PIXMAP_OP_EPILOGUE(pGC);
}

static int
XAAPolyText8Pixmap(
    DrawablePtr pDraw,
    GCPtr	pGC,
    int		x, 
    int 	y,
    int 	count,
    char	*chars 
){
    int ret;

    XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);
    ret = (*pGC->ops->PolyText8)(pDraw, pGC, x, y, count, chars);
    XAA_PIXMAP_OP_EPILOGUE(pGC);
    return ret;
}

static int
XAAPolyText16Pixmap(
    DrawablePtr pDraw,
    GCPtr	pGC,
    int		x,
    int		y,
    int 	count,
    unsigned short *chars 
){
    int ret;

    XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);
    ret = (*pGC->ops->PolyText16)(pDraw, pGC, x, y, count, chars);
    XAA_PIXMAP_OP_EPILOGUE(pGC);
    return ret;
}

static void
XAAImageText8Pixmap(
    DrawablePtr pDraw,
    GCPtr	pGC,
    int		x, 
    int		y,
    int 	count,
    char	*chars 
){
    XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);
    (*pGC->ops->ImageText8)(pDraw, pGC, x, y, count, chars);
    XAA_PIXMAP_OP_EPILOGUE(pGC);
}
static void
XAAImageText16Pixmap(
    DrawablePtr pDraw,
    GCPtr	pGC,
    int		x,
    int		y,
    int 	count,
    unsigned short *chars 
){
    XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);
    (*pGC->ops->ImageText16)(pDraw, pGC, x, y, count, chars);
    XAA_PIXMAP_OP_EPILOGUE(pGC);
}


static void
XAAImageGlyphBltPixmap(
    DrawablePtr pDraw,
    GCPtr pGC,
    int xInit, int yInit,
    unsigned int nglyph,
    CharInfoPtr *ppci,
    pointer pglyphBase 
){
    XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);
    (*pGC->ops->ImageGlyphBlt)(pDraw, pGC, xInit, yInit, nglyph, 
					ppci, pglyphBase);
    XAA_PIXMAP_OP_EPILOGUE(pGC);
}

static void
XAAPolyGlyphBltPixmap(
    DrawablePtr pDraw,
    GCPtr pGC,
    int xInit, int yInit,
    unsigned int nglyph,
    CharInfoPtr *ppci,
    pointer pglyphBase 
){
    XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);
    (*pGC->ops->PolyGlyphBlt)(pDraw, pGC, xInit, yInit, nglyph, 
				ppci, pglyphBase);
    XAA_PIXMAP_OP_EPILOGUE(pGC);
}

static void
XAAPushPixelsPixmap(
    GCPtr	pGC,
    PixmapPtr	pBitMap,
    DrawablePtr pDraw,
    int	dx, int dy, int xOrg, int yOrg 
){
    XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);
    (*pGC->ops->PushPixels)(pGC, pBitMap, pDraw, dx, dy, xOrg, yOrg);
    XAA_PIXMAP_OP_EPILOGUE(pGC);
}

GCOps XAAPixmapOps = {
    XAAFillSpansPixmap, XAASetSpansPixmap, 
    XAAPutImagePixmap, XAACopyAreaPixmap, 
    XAACopyPlanePixmap, XAAPolyPointPixmap, 
    XAAPolylinesPixmap, XAAPolySegmentPixmap, 
    XAAPolyRectanglePixmap, XAAPolyArcPixmap, 
    XAAFillPolygonPixmap, XAAPolyFillRectPixmap, 
    XAAPolyFillArcPixmap, XAAPolyText8Pixmap, 
    XAAPolyText16Pixmap, XAAImageText8Pixmap, 
    XAAImageText16Pixmap, XAAImageGlyphBltPixmap, 
    XAAPolyGlyphBltPixmap, XAAPushPixelsPixmap,
#ifdef NEED_LINEHELPER
    NULL,
#endif
    {NULL}		/* devPrivate */
};

--- NEW FILE: xaaGCmisc.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaGCmisc.c,v 1.14 2000/05/03 00:44:23 tsi Exp $ */

#include "misc.h"
#include "xf86.h"
#include "xf86_ansic.h"
#include "xf86_OSproc.h"

#include <X11/X.h>
#include "scrnintstr.h"
#include "fontstruct.h"
#include "dixfontstr.h"
#include "xf86str.h"
#include "xaa.h"
#include "xaalocal.h"
#include "migc.h"
#include "mi.h"
#include "gcstruct.h"
#include "pixmapstr.h"

void
XAAValidateCopyArea(
   GCPtr         pGC,
   unsigned long changes,
   DrawablePtr   pDraw )
{
   XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);

   if(infoRec->CopyArea &&
	CHECK_PLANEMASK(pGC,infoRec->CopyAreaFlags) &&
	CHECK_ROP(pGC,infoRec->CopyAreaFlags) &&
	CHECK_ROPSRC(pGC,infoRec->CopyAreaFlags)
	)
	pGC->ops->CopyArea = infoRec->CopyArea;
   else
	pGC->ops->CopyArea = XAAFallbackOps.CopyArea;
}

void
XAAValidatePutImage(
   GCPtr         pGC,
   unsigned long changes,
   DrawablePtr   pDraw )
{
   XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);

   if(infoRec->PutImage &&
	CHECK_PLANEMASK(pGC,infoRec->PutImageFlags) &&
	CHECK_ROP(pGC,infoRec->PutImageFlags) &&
	CHECK_ROPSRC(pGC,infoRec->PutImageFlags) &&
	CHECK_COLORS(pGC,infoRec->PutImageFlags)
	)
	pGC->ops->PutImage = infoRec->PutImage;
   else
	pGC->ops->PutImage = XAAFallbackOps.PutImage;
}

void
XAAValidateCopyPlane(
   GCPtr         pGC,
   unsigned long changes,
   DrawablePtr   pDraw )
{
   XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);

   if(infoRec->CopyPlane &&
	CHECK_PLANEMASK(pGC,infoRec->CopyPlaneFlags) &&
	CHECK_ROP(pGC,infoRec->CopyPlaneFlags) &&
	CHECK_ROPSRC(pGC,infoRec->CopyPlaneFlags) &&
	CHECK_COLORS(pGC,infoRec->CopyPlaneFlags)
	)
	pGC->ops->CopyPlane = infoRec->CopyPlane;
   else
	pGC->ops->CopyPlane = XAAFallbackOps.CopyPlane;
}

void
XAAValidatePushPixels(
   GCPtr         pGC,
   unsigned long changes,
   DrawablePtr   pDraw )
{
   XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);

   if(infoRec->PushPixelsSolid &&
	(pGC->fillStyle == FillSolid) &&
	CHECK_PLANEMASK(pGC,infoRec->PushPixelsFlags) &&
	CHECK_ROP(pGC,infoRec->PushPixelsFlags) &&
	CHECK_ROPSRC(pGC,infoRec->PushPixelsFlags) &&
	CHECK_FG(pGC,infoRec->PushPixelsFlags) &&
	(!(infoRec->PushPixelsFlags & TRANSPARENCY_GXCOPY_ONLY) ||
	  (pGC->alu == GXcopy))
	)
	pGC->ops->PushPixels = infoRec->PushPixelsSolid;
   else
	pGC->ops->PushPixels = XAAFallbackOps.PushPixels;

}


/* We make the assumption that the FillSpans, PolyFillRect, FillPolygon
   and PolyFillArc functions are linked in a way that they all have 
   the same rop/color/planemask restrictions. If the driver provides 
   a GC level replacement for these, it will need to supply a new 
   Validate functions if it breaks this assumption */


void
XAAValidateFillSpans(
   GCPtr         pGC,
   unsigned long changes,
   DrawablePtr   pDraw )
{
   XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);

   if(pGC->fillStyle != FillTiled) changes &= ~GCTile;
   if((pGC->fillStyle == FillTiled) || (pGC->fillStyle == FillSolid)) 
	changes &= ~GCStipple;
   if(!changes) return;
   

   pGC->ops->FillSpans = XAAFallbackOps.FillSpans;
   pGC->ops->PolyFillRect = XAAFallbackOps.PolyFillRect;
   pGC->ops->FillPolygon = XAAFallbackOps.FillPolygon;
   pGC->ops->PolyFillArc = XAAFallbackOps.PolyFillArc;

   switch(pGC->fillStyle){
   case FillSolid:
	if(infoRec->FillSpansSolid &&
		CHECK_PLANEMASK(pGC,infoRec->FillSpansSolidFlags) &&
		CHECK_ROP(pGC,infoRec->FillSpansSolidFlags) &&
		CHECK_ROPSRC(pGC,infoRec->FillSpansSolidFlags) &&
		CHECK_FG(pGC,infoRec->FillSpansSolidFlags)
		) {
	     pGC->ops->FillSpans = infoRec->FillSpansSolid;
	     pGC->ops->PolyFillRect = infoRec->PolyFillRectSolid;
	     pGC->ops->FillPolygon = infoRec->FillPolygonSolid;
	     pGC->ops->PolyFillArc = infoRec->PolyFillArcSolid;
	}
	break;
    	/* The [Stippled/OpaqueStippled/Tiled]FillChooser 
		functions do the validating */
   case FillStippled:
	if(infoRec->FillSpansStippled) {
	     pGC->ops->FillSpans = infoRec->FillSpansStippled;
	     pGC->ops->PolyFillRect = infoRec->PolyFillRectStippled;
	     if(infoRec->FillPolygonStippled)
	         pGC->ops->FillPolygon = infoRec->FillPolygonStippled;
	     else pGC->ops->FillPolygon = miFillPolygon;
	     pGC->ops->PolyFillArc = miPolyFillArc;
	}
	break;
   case FillOpaqueStippled:
	if(infoRec->FillSpansOpaqueStippled) {
	     pGC->ops->FillSpans = infoRec->FillSpansOpaqueStippled;
	     pGC->ops->PolyFillRect = infoRec->PolyFillRectOpaqueStippled;
	     if(infoRec->FillPolygonOpaqueStippled)
	         pGC->ops->FillPolygon = infoRec->FillPolygonOpaqueStippled;
	     else pGC->ops->FillPolygon = miFillPolygon;
	     pGC->ops->PolyFillArc = miPolyFillArc;
	}
	break;
   case FillTiled:
	if(infoRec->FillSpansTiled) {
	     pGC->ops->FillSpans = infoRec->FillSpansTiled;
	     pGC->ops->PolyFillRect = infoRec->PolyFillRectTiled;
	     if(infoRec->FillPolygonTiled)
	         pGC->ops->FillPolygon = infoRec->FillPolygonTiled;
	     else pGC->ops->FillPolygon = miFillPolygon;
	     pGC->ops->PolyFillArc = miPolyFillArc;
	}
	break;
   default: return;
   }
}


/* We make the assumption that these Text8/16 and GlyphBlt functions
   are linked in a way that they all have the same rop/color/planemask
   restrictions. If the driver provides a GC level replacement for
   these, it will need to supply a new Validate functions if it breaks
   this assumption */

void
XAAValidatePolyGlyphBlt(
   GCPtr         pGC,
   unsigned long changes,
   DrawablePtr   pDraw )
{
   XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
   Bool BigFont = FALSE;

   pGC->ops->PolyText8 = XAAFallbackOps.PolyText8;
   pGC->ops->PolyText16 = XAAFallbackOps.PolyText16;
   pGC->ops->PolyGlyphBlt = XAAFallbackOps.PolyGlyphBlt;

   if(!pGC->font) return;
   if(pGC->fillStyle != FillSolid) return;

   if((FONTMAXBOUNDS(pGC->font, rightSideBearing) - 
	FONTMINBOUNDS(pGC->font, leftSideBearing) > 32))
	BigFont = TRUE;

   /* no funny business */
   if((FONTMINBOUNDS(pGC->font, characterWidth) <= 0) ||
	((FONTASCENT(pGC->font) + FONTDESCENT(pGC->font)) <= 0))
	return;

   /* Check for TE Fonts */
   if(!TERMINALFONT(pGC->font) || BigFont) {
	if(infoRec->PolyGlyphBltNonTE &&
	    CHECK_PLANEMASK(pGC,infoRec->PolyGlyphBltNonTEFlags) &&
	    CHECK_ROP(pGC,infoRec->PolyGlyphBltNonTEFlags) &&
	    CHECK_ROPSRC(pGC,infoRec->PolyGlyphBltNonTEFlags) &&
	    CHECK_FG(pGC,infoRec->PolyGlyphBltNonTEFlags) &&
	    (!(infoRec->PolyGlyphBltNonTEFlags & TRANSPARENCY_GXCOPY_ONLY) ||
	  	(pGC->alu == GXcopy))
	) {
	    pGC->ops->PolyText8 = infoRec->PolyText8NonTE; 
	    pGC->ops->PolyText16 = infoRec->PolyText16NonTE;
	    pGC->ops->PolyGlyphBlt = infoRec->PolyGlyphBltNonTE;
	}
   } else {
	if(infoRec->PolyGlyphBltTE &&
	    CHECK_PLANEMASK(pGC,infoRec->PolyGlyphBltTEFlags) &&
	    CHECK_ROP(pGC,infoRec->PolyGlyphBltTEFlags) &&
	    CHECK_ROPSRC(pGC,infoRec->PolyGlyphBltNonTEFlags) &&
	    CHECK_FG(pGC,infoRec->PolyGlyphBltTEFlags) &&
	    (!(infoRec->PolyGlyphBltTEFlags & TRANSPARENCY_GXCOPY_ONLY) ||
	  	(pGC->alu == GXcopy))
	) {
	    pGC->ops->PolyText8 = infoRec->PolyText8TE;
	    pGC->ops->PolyText16 = infoRec->PolyText16TE;
	    pGC->ops->PolyGlyphBlt = infoRec->PolyGlyphBltTE;
	}
   }
}

void
XAAValidateImageGlyphBlt(
   GCPtr         pGC,
   unsigned long changes,
   DrawablePtr   pDraw )
{
   XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
   Bool BigFont = FALSE;

   pGC->ops->ImageText8 = XAAFallbackOps.ImageText8;
   pGC->ops->ImageText16 = XAAFallbackOps.ImageText16;
   pGC->ops->ImageGlyphBlt = XAAFallbackOps.ImageGlyphBlt;

   if(!pGC->font) return;

   if((FONTMAXBOUNDS(pGC->font, rightSideBearing) - 
	FONTMINBOUNDS(pGC->font, leftSideBearing) > 32))
	BigFont = TRUE;

   /* no funny business */
   if((FONTMINBOUNDS(pGC->font, characterWidth) <= 0) ||
	((FONTASCENT(pGC->font) + FONTDESCENT(pGC->font)) <= 0))
	return;


   /* Check for TE Fonts */
   if(!TERMINALFONT(pGC->font) || BigFont || (pGC->depth == 32)) {
	if(infoRec->ImageGlyphBltNonTE &&
		CHECK_PLANEMASK(pGC,infoRec->ImageGlyphBltNonTEFlags) &&
		CHECK_FG(pGC,infoRec->ImageGlyphBltNonTEFlags) &&
	   infoRec->SetupForSolidFill &&
		CHECK_PLANEMASK(pGC,infoRec->SolidFillFlags) &&
		CHECK_BG(pGC,infoRec->SolidFillFlags))
	{
		pGC->ops->ImageText8 = infoRec->ImageText8NonTE;
		pGC->ops->ImageText16 = infoRec->ImageText16NonTE;
		pGC->ops->ImageGlyphBlt = infoRec->ImageGlyphBltNonTE;
	}
   } else if(infoRec->ImageGlyphBltTE &&
	     CHECK_PLANEMASK(pGC,infoRec->ImageGlyphBltTEFlags)){
	if(!(infoRec->ImageGlyphBltTEFlags & TRANSPARENCY_ONLY) &&  
		CHECK_COLORS(pGC,infoRec->ImageGlyphBltTEFlags))
	{
		pGC->ops->ImageText8 = infoRec->ImageText8TE;
		pGC->ops->ImageText16 = infoRec->ImageText16TE;
		pGC->ops->ImageGlyphBlt = infoRec->ImageGlyphBltTE;
	} else {
	   if(CHECK_FG(pGC,infoRec->ImageGlyphBltTEFlags) &&
	      infoRec->SetupForSolidFill &&
	      CHECK_PLANEMASK(pGC,infoRec->SolidFillFlags) &&
	      CHECK_BG(pGC,infoRec->SolidFillFlags)) 
	   {
		pGC->ops->ImageText8 = infoRec->ImageText8TE;
		pGC->ops->ImageText16 = infoRec->ImageText16TE;
		pGC->ops->ImageGlyphBlt = infoRec->ImageGlyphBltTE;
	   }
	}
    }
}


void
XAAValidatePolylines(
   GCPtr         pGC,
   unsigned long changes,
   DrawablePtr   pDraw )
{
   XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
   XAAGCPtr   pGCPriv = (XAAGCPtr) (pGC)->devPrivates[XAAGCIndex].ptr;

   if(pGC->lineStyle == LineSolid) changes &= ~GCDashList;
   if(!changes) return;

   pGC->ops->PolySegment = XAAFallbackOps.PolySegment;
   pGC->ops->Polylines = XAAFallbackOps.Polylines;
   pGC->ops->PolyRectangle = XAAFallbackOps.PolyRectangle;
   pGC->ops->PolyArc = XAAFallbackOps.PolyArc;

   if((pGC->ops->FillSpans != XAAFallbackOps.FillSpans) &&
	(pGC->lineWidth > 0)){
	
	pGC->ops->PolyArc = miPolyArc;	
	pGC->ops->PolySegment = miPolySegment;	
	pGC->ops->PolyRectangle = miPolyRectangle;
	if(pGC->lineStyle == LineSolid)
	    pGC->ops->Polylines = miWideLine;
	else
	    pGC->ops->Polylines = miWideDash;
   }

   if((pGC->lineWidth == 0) && (pGC->fillStyle == FillSolid)) {

	if(pGC->lineStyle == LineSolid) {

	   if(infoRec->PolyRectangleThinSolid &&
		CHECK_PLANEMASK(pGC,infoRec->PolyRectangleThinSolidFlags) &&
		CHECK_ROP(pGC,infoRec->PolyRectangleThinSolidFlags) &&
		CHECK_ROPSRC(pGC,infoRec->PolyRectangleThinSolidFlags) &&
		CHECK_FG(pGC,infoRec->PolyRectangleThinSolidFlags)) {

		pGC->ops->PolyRectangle = infoRec->PolyRectangleThinSolid;
	   }

	   if(infoRec->PolySegmentThinSolid &&
		CHECK_PLANEMASK(pGC,infoRec->PolySegmentThinSolidFlags) &&
		CHECK_ROP(pGC,infoRec->PolySegmentThinSolidFlags) &&
		CHECK_ROPSRC(pGC,infoRec->PolySegmentThinSolidFlags) &&
		CHECK_FG(pGC,infoRec->PolySegmentThinSolidFlags)) {

		pGC->ops->PolySegment = infoRec->PolySegmentThinSolid;
	   }

	   if(infoRec->PolylinesThinSolid &&
		CHECK_PLANEMASK(pGC,infoRec->PolylinesThinSolidFlags) &&
		CHECK_ROP(pGC,infoRec->PolylinesThinSolidFlags) &&
		CHECK_ROPSRC(pGC,infoRec->PolylinesThinSolidFlags) &&
		CHECK_FG(pGC,infoRec->PolylinesThinSolidFlags)) {

		pGC->ops->Polylines = infoRec->PolylinesThinSolid;
	    }
	} else if((pGC->lineStyle == LineOnOffDash) && pGCPriv->DashPattern){

	   if(infoRec->PolySegmentThinDashed &&
		!(infoRec->PolySegmentThinDashedFlags & NO_TRANSPARENCY) &&
		((pGC->alu == GXcopy) || !(infoRec->PolySegmentThinDashedFlags &
					TRANSPARENCY_GXCOPY_ONLY)) &&
		CHECK_PLANEMASK(pGC,infoRec->PolySegmentThinDashedFlags) &&
		CHECK_ROP(pGC,infoRec->PolySegmentThinDashedFlags) &&
		CHECK_ROPSRC(pGC,infoRec->PolySegmentThinDashedFlags) &&
		CHECK_FG(pGC,infoRec->PolySegmentThinDashedFlags)) {

		pGC->ops->PolySegment = infoRec->PolySegmentThinDashed;
	   }

	   if(infoRec->PolylinesThinDashed &&
		!(infoRec->PolylinesThinDashedFlags & NO_TRANSPARENCY) &&
		((pGC->alu == GXcopy) || !(infoRec->PolylinesThinDashedFlags &
					TRANSPARENCY_GXCOPY_ONLY)) &&
		CHECK_PLANEMASK(pGC,infoRec->PolylinesThinDashedFlags) &&
		CHECK_ROP(pGC,infoRec->PolylinesThinDashedFlags) &&
		CHECK_ROPSRC(pGC,infoRec->PolylinesThinDashedFlags) &&
		CHECK_FG(pGC,infoRec->PolylinesThinDashedFlags)) {

		pGC->ops->Polylines = infoRec->PolylinesThinDashed;
	    }

	   if(pGC->ops->Polylines != XAAFallbackOps.Polylines)
		pGC->ops->PolyRectangle = miPolyRectangle;

	} else if(pGCPriv->DashPattern && (pGC->depth != 32)) { 
           /* LineDoubleDash */
	   if(infoRec->PolySegmentThinDashed &&
		!(infoRec->PolySegmentThinDashedFlags & TRANSPARENCY_ONLY) &&
		CHECK_PLANEMASK(pGC,infoRec->PolySegmentThinDashedFlags) &&
		CHECK_ROP(pGC,infoRec->PolySegmentThinDashedFlags) &&
		CHECK_ROPSRC(pGC,infoRec->PolySegmentThinDashedFlags) &&
		CHECK_COLORS(pGC,infoRec->PolySegmentThinDashedFlags)) {

		pGC->ops->PolySegment = infoRec->PolySegmentThinDashed;
	   }

	   if(infoRec->PolylinesThinDashed &&
		!(infoRec->PolylinesThinDashedFlags & TRANSPARENCY_ONLY) &&
		CHECK_PLANEMASK(pGC,infoRec->PolylinesThinDashedFlags) &&
		CHECK_ROP(pGC,infoRec->PolylinesThinDashedFlags) &&
		CHECK_ROPSRC(pGC,infoRec->PolylinesThinDashedFlags) &&
		CHECK_COLORS(pGC,infoRec->PolylinesThinDashedFlags)) {

		pGC->ops->Polylines = infoRec->PolylinesThinDashed;
	    }

	   if(pGC->ops->Polylines != XAAFallbackOps.Polylines)
		pGC->ops->PolyRectangle = miPolyRectangle;

	}
   }

   if(infoRec->PolylinesWideSolid &&
	(pGC->lineWidth > 0) &&
	(pGC->fillStyle == FillSolid) &&
	(pGC->lineStyle == LineSolid) &&
	CHECK_PLANEMASK(pGC,infoRec->PolylinesWideSolidFlags) &&
	CHECK_ROP(pGC,infoRec->PolylinesWideSolidFlags) &&
	CHECK_ROPSRC(pGC,infoRec->PolylinesWideSolidFlags) &&
	CHECK_FG(pGC,infoRec->PolylinesWideSolidFlags)) {

	pGC->ops->Polylines = infoRec->PolylinesWideSolid;
   } 
}

--- NEW FILE: xaaImage.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaImage.c,v 1.20tsi Exp $ */

#include "misc.h"
#include "xf86.h"
#include "xf86_ansic.h"
#include "xf86_OSproc.h"
#include "servermd.h"

#include <X11/X.h>
#include "scrnintstr.h"
#include "mi.h"
#include "pixmapstr.h"
#include "xf86str.h"
#include "xaa.h"
#include "xaalocal.h"

void XAAMoveDWORDS_FixedBase(
   register CARD32* dest,
   register CARD32* src,
   register int dwords )
{
     while(dwords & ~0x03) {
	 *dest = *src;
	 *dest = *(src + 1);
	 *dest = *(src + 2);
	 *dest = *(src + 3);	
	 dwords -= 4;
	 src += 4;
     }

     if(!dwords) return;
     *dest = *src;
     if(dwords == 1) return;
     *dest = *(src + 1);
     if(dwords == 2) return;
     *dest = *(src + 2);
}

void XAAMoveDWORDS(
   register CARD32* dest,
   register CARD32* src,
   register int dwords )
{
     while(dwords & ~0x03) {
	*dest = *src;
	*(dest + 1) = *(src + 1);
	*(dest + 2) = *(src + 2);
	*(dest + 3) = *(src + 3);
	src += 4;
	dest += 4;
	dwords -= 4;
     }	
     if(!dwords) return;
     *dest = *src;
     if(dwords == 1) return;
     *(dest + 1) = *(src + 1);
     if(dwords == 2) return;
     *(dest + 2) = *(src + 2);
}

void XAAMoveDWORDS_FixedSrc(
   register CARD32* dest,
   register CARD32* src,
   register int dwords )
{
     while(dwords & ~0x03) {
	*dest = *src;
	*(dest + 1) = *src;
	*(dest + 2) = *src;
	*(dest + 3) = *src;
	dest += 4;
	dwords -= 4;
     }	
     if(!dwords) return;
     *dest = *src;
     if(dwords == 1) return;
     *(dest + 1) = *src;
     if(dwords == 2) return;
     *(dest + 2) = *src;
}

static void
XAAWritePixmap32To24(
   ScrnInfoPtr pScrn,
   int x, int y, int w, int h,
   unsigned char *srcInit,	
   int srcwidth,	/* bytes */
   int rop,
   unsigned int planemask,
   int trans
){
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
    int count, dwords = ((w * 3) + 3) >> 2;
    CARD32 *src, *dst;
    Bool PlusOne = FALSE;

    if((infoRec->ImageWriteFlags & CPU_TRANSFER_PAD_QWORD) && 
					((dwords * h) & 0x01)) {
	PlusOne = TRUE;
    }

    (*infoRec->SetupForImageWrite)(pScrn, rop, planemask, trans, 24, 24);
    (*infoRec->SubsequentImageWriteRect)(pScrn, x, y, w, h, 0);
  
    if(dwords > infoRec->ImageWriteRange) {
	dst = (CARD32*)infoRec->ImageWriteBase;
	while(h--) {
	    src = (CARD32*)srcInit;
  	    count = w;

	    while(count >= 4) {
		*dst = (src[0] & 0x00ffffff) | (src[1] << 24);
		*dst = ((src[1] >> 8) & 0x0000ffff) | (src[2] << 16);
		*dst = ((src[2] >> 16) & 0x000000ff) | (src[3] << 8);
		src += 4;
		count -= 4;
	    }
	    switch(count) {
	    case 0:	break;
	    case 1:	*dst = src[0];
			break;
	    case 2:	*dst = (src[0] & 0x00ffffff) | (src[1] << 24);
			*dst = src[1] >> 8;
			break;
	    default:	*dst = (src[0] & 0x00ffffff) | (src[1] << 24);
			*dst = ((src[1] >> 8) & 0x0000ffff) | (src[2] << 16);
			*dst = src[2] >> 16;
			break;
	    }
	    srcInit += srcwidth;
	}
    } else {
	while(h--) {
	    dst = (CARD32*)infoRec->ImageWriteBase;
	    src = (CARD32*)srcInit;
  	    count = w;

	    while(count >= 4) {
		dst[0] = (src[0] & 0x00ffffff) | (src[1] << 24);
		dst[1] = ((src[1] >> 8) & 0x0000ffff) | (src[2] << 16);
		dst[2] = ((src[2] >> 16) & 0x000000ff) | (src[3] << 8);
		dst += 3;
		src += 4;
		count -= 4;
	    }
	    switch(count) {
	    case 0:	break;
	    case 1:	dst[0] = src[0];
			break;
	    case 2:	dst[0] = (src[0] & 0x00ffffff) | (src[1] << 24);
			dst[1] = src[1] >> 8;
			break;
	    default:	dst[0] = (src[0] & 0x00ffffff) | (src[1] << 24);
			dst[1] = ((src[1] >> 8) & 0x0000ffff) | (src[2] << 16);
			dst[2] = src[2] >> 16;
			break;
	    }
	    srcInit += srcwidth;
	}
    }

    if(PlusOne) {
	CARD32* base = (CARD32*)infoRec->ImageWriteBase;
	*base = 0x00000000;
    }

    if(infoRec->ImageWriteFlags & SYNC_AFTER_IMAGE_WRITE)
	(*infoRec->Sync)(pScrn);
    else SET_SYNC_FLAG(infoRec);

}

void 
XAAWritePixmap (
   ScrnInfoPtr pScrn,
   int x, int y, int w, int h,
   unsigned char *src,	
   int srcwidth,	/* bytes */
   int rop,
   unsigned int planemask,
   int trans,
   int bpp, int depth
){
    XAAInfoRecPtr infoRec;
    int dwords, skipleft, Bpp; 
    Bool beCareful, PlusOne;

    if((bpp == 32) && (pScrn->bitsPerPixel == 24)) {
	XAAWritePixmap32To24(pScrn, x, y, w, h, src, srcwidth, 
						rop, planemask, trans);	
	return;
    }

    infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
    beCareful = PlusOne = FALSE;
    Bpp = bpp >> 3;

    if((skipleft = (long)src & 0x03L)) {
	if(!(infoRec->ImageWriteFlags & LEFT_EDGE_CLIPPING)) {
	   skipleft = 0;
	   beCareful = TRUE;
	   goto BAD_ALIGNMENT;
	}

	if(Bpp == 3)
	   skipleft = 4 - skipleft;
	else
	   skipleft /= Bpp;

	if((x < skipleft) && !(infoRec->ImageWriteFlags &
				 LEFT_EDGE_CLIPPING_NEGATIVE_X)) {
	   skipleft = 0;
	   beCareful = TRUE;
	   goto BAD_ALIGNMENT;
	}

	x -= skipleft;	     
	w += skipleft;
	
	if(Bpp == 3)
	   src -= 3 * skipleft;  
	else   /* is this Alpha friendly ? */
	   src = (unsigned char*)((long)src & ~0x03L);     
    }

BAD_ALIGNMENT:

    dwords = ((w * Bpp) + 3) >> 2;

    if((infoRec->ImageWriteFlags & CPU_TRANSFER_PAD_QWORD) && 
						((dwords * h) & 0x01)) {
	PlusOne = TRUE;
    } 
		
	
    (*infoRec->SetupForImageWrite)(pScrn, rop, planemask, trans, bpp, depth);
    (*infoRec->SubsequentImageWriteRect)(pScrn, x, y, w, h, skipleft);

    if(beCareful) {
	/* in cases with bad alignment we have to be careful not
	   to read beyond the end of the source */
	if(((x * Bpp) + (dwords << 2)) > srcwidth) h--;
	else beCareful = FALSE;
    }

    if(dwords > infoRec->ImageWriteRange) {
	while(h--) {
	    XAAMoveDWORDS_FixedBase((CARD32*)infoRec->ImageWriteBase,
		(CARD32*)src, dwords);
	    src += srcwidth;
	}
	if(beCareful) {
	   int shift = ((long)src & 0x03L) << 3;
	   if(--dwords)
		XAAMoveDWORDS_FixedBase((CARD32*)infoRec->ImageWriteBase,
			(CARD32*)src, dwords);
	   src = (unsigned char*)((long)(src + (dwords << 2)) & ~0x03L);
	   *((CARD32*)infoRec->ImageWriteBase) = *((CARD32*)src) >> shift;
	}
    } else {
	if(srcwidth == (dwords << 2)) {
	   int decrement = infoRec->ImageWriteRange/dwords;

	   while(h > decrement) {
		XAAMoveDWORDS((CARD32*)infoRec->ImageWriteBase,
	 		(CARD32*)src, dwords * decrement);
		src += (srcwidth * decrement);
		h -= decrement;
	   }
	   if(h) {
		XAAMoveDWORDS((CARD32*)infoRec->ImageWriteBase,
	 		(CARD32*)src, dwords * h);
		if(beCareful) src += (srcwidth * h);
	   }
	} else {
	    while(h--) {
		XAAMoveDWORDS((CARD32*)infoRec->ImageWriteBase,
	 		(CARD32*)src, dwords);
		src += srcwidth;
	    }
	}

	if(beCareful) {
	    int shift = ((long)src & 0x03L) << 3;
	    if(--dwords)
		XAAMoveDWORDS((CARD32*)infoRec->ImageWriteBase,
					(CARD32*)src, dwords);
	    src = (unsigned char*)((long)(src + (dwords << 2)) & ~0x03L);
     
	    ((CARD32*)infoRec->ImageWriteBase)[dwords] = 
			*((CARD32*)src) >> shift;
	}
    }

    if(PlusOne) {
	CARD32* base = (CARD32*)infoRec->ImageWriteBase;
	*base = 0x00000000;
    }

    if(infoRec->ImageWriteFlags & SYNC_AFTER_IMAGE_WRITE)
	(*infoRec->Sync)(pScrn);
    else SET_SYNC_FLAG(infoRec);
}


void 
XAAWritePixmapScanline (
   ScrnInfoPtr pScrn,
   int x, int y, int w, int h,
   unsigned char *src,	
   int srcwidth,	/* bytes */
   int rop,
   unsigned int planemask,
   int trans,
   int bpp, int depth
){
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
    int dwords, skipleft, bufferNo = 0, Bpp = bpp >> 3; 
    Bool beCareful = FALSE;
    CARD32* base;

    if((skipleft = (long)src & 0x03L)) {
	if(!(infoRec->ScanlineImageWriteFlags & LEFT_EDGE_CLIPPING)) {
	   skipleft = 0;
	   beCareful = TRUE;
	   goto BAD_ALIGNMENT;
	}

	if(Bpp == 3)
	   skipleft = 4 - skipleft;
	else
	   skipleft /= Bpp;

	if((x < skipleft) && !(infoRec->ScanlineImageWriteFlags &
				 LEFT_EDGE_CLIPPING_NEGATIVE_X)) {
	   skipleft = 0;
	   beCareful = TRUE;
	   goto BAD_ALIGNMENT;
	}

	x -= skipleft;	     
	w += skipleft;
	
	if(Bpp == 3)
	   src -= 3 * skipleft;  
	else
	   src = (unsigned char*)((long)src & ~0x03L);     
    }

BAD_ALIGNMENT:

    dwords = ((w * Bpp) + 3) >> 2;

    (*infoRec->SetupForScanlineImageWrite)(
				pScrn, rop, planemask, trans, bpp, depth);
    (*infoRec->SubsequentScanlineImageWriteRect)(pScrn, x, y, w, h, skipleft);

    if(beCareful) {
	/* in cases with bad alignment we have to be careful not
	   to read beyond the end of the source */
	if(((x * Bpp) + (dwords << 2)) > srcwidth) h--;
	else beCareful = FALSE;
    }

    while(h--) {
	base = (CARD32*)infoRec->ScanlineImageWriteBuffers[bufferNo];
	XAAMoveDWORDS(base, (CARD32*)src, dwords);
	(*infoRec->SubsequentImageWriteScanline)(pScrn, bufferNo++);
	src += srcwidth;
	if(bufferNo >= infoRec->NumScanlineImageWriteBuffers)
	    bufferNo = 0;
    }

    if(beCareful) {
	int shift = ((long)src & 0x03L) << 3;
	base = (CARD32*)infoRec->ScanlineImageWriteBuffers[bufferNo];
	if(--dwords)
	    XAAMoveDWORDS(base,(CARD32*)src, dwords);
	src = (unsigned char*)((long)(src + (dwords << 2)) & ~0x03L);
     
	base[dwords] = *((CARD32*)src) >> shift;
	(*infoRec->SubsequentImageWriteScanline)(pScrn, bufferNo);
    }

    SET_SYNC_FLAG(infoRec);
}


void
XAAPutImage(
    DrawablePtr pDraw,
    GCPtr       pGC,
    int         depth, 
    int 	x, 
    int		y, 
    int		w, 
    int		h,
    int         leftPad,
    int         format,
    char        *pImage
){
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
    int bpp = BitsPerPixel(depth);
    Bool depthBug = FALSE;
    if(!w || !h) return;

    if(!REGION_NUM_RECTS(pGC->pCompositeClip))
	return;

    depthBug = XAA_DEPTH_BUG(pGC);

    if(((format == ZPixmap) && infoRec->WritePixmap &&
	     ((pDraw->bitsPerPixel == bpp) ||
		((pDraw->bitsPerPixel == 24) &&  (bpp == 32) &&
		(infoRec->WritePixmapFlags & CONVERT_32BPP_TO_24BPP))) &&
	     CHECK_ROP(pGC,infoRec->WritePixmapFlags) &&
	     CHECK_ROPSRC(pGC,infoRec->WritePixmapFlags) &&
	     CHECK_PLANEMASK(pGC,infoRec->WritePixmapFlags) &&
	     CHECK_NO_GXCOPY(pGC,infoRec->WritePixmapFlags)) ||
       ((format == XYBitmap) && !depthBug && infoRec->WriteBitmap &&
	     CHECK_ROP(pGC,infoRec->WriteBitmapFlags) &&
	     CHECK_ROPSRC(pGC,infoRec->WriteBitmapFlags) &&
	     CHECK_PLANEMASK(pGC,infoRec->WriteBitmapFlags) &&
	     CHECK_COLORS(pGC,infoRec->WriteBitmapFlags) &&
	     !(infoRec->WriteBitmapFlags & TRANSPARENCY_ONLY)) ||
       ((format == XYPixmap) && !depthBug && infoRec->WriteBitmap &&
	     CHECK_ROP(pGC,infoRec->WriteBitmapFlags) &&
	     CHECK_ROPSRC(pGC,infoRec->WriteBitmapFlags) &&
	     !(infoRec->WriteBitmapFlags & NO_PLANEMASK) &&
	     !(infoRec->WriteBitmapFlags & TRANSPARENCY_ONLY))){

	int MaxBoxes = REGION_NUM_RECTS(pGC->pCompositeClip);
	BoxPtr pbox, pClipBoxes;
	int nboxes, srcx, srcy, srcwidth;
	xRectangle TheRect;

	TheRect.x = pDraw->x + x;
	TheRect.y = pDraw->y + y;
	TheRect.width = w;
	TheRect.height = h; 

	if(MaxBoxes > (infoRec->PreAllocSize/sizeof(BoxRec))) {
	    pClipBoxes = xalloc(MaxBoxes * sizeof(BoxRec));
	    if(!pClipBoxes) return;	
	} else pClipBoxes = (BoxPtr)infoRec->PreAllocMem;

	nboxes = XAAGetRectClipBoxes(pGC, pClipBoxes, 1, &TheRect);
	pbox = pClipBoxes;

	if(format == XYBitmap) {
	    srcwidth = BitmapBytePad(leftPad + w);
	    while(nboxes--) {
		srcx = pbox->x1 - TheRect.x + leftPad;
		srcy = pbox->y1 - TheRect.y;
		(*infoRec->WriteBitmap)(infoRec->pScrn, pbox->x1, pbox->y1, 
			pbox->x2 - pbox->x1, pbox->y2 - pbox->y1, 
			(unsigned char*)pImage + 
				(srcwidth * srcy) + ((srcx >> 5) << 2), 
			srcwidth, srcx & 31, pGC->fgPixel, pGC->bgPixel,
	 		pGC->alu, pGC->planemask);
		pbox++;
	    }
        } else if(format == ZPixmap) {
	    int Bpp = bpp >> 3;
	    srcwidth = PixmapBytePad(leftPad + w, depth);
	    while(nboxes--) {
		srcx = pbox->x1 - TheRect.x + leftPad;
		srcy = pbox->y1 - TheRect.y;
		(*infoRec->WritePixmap)(infoRec->pScrn, pbox->x1, pbox->y1, 
			pbox->x2 - pbox->x1, pbox->y2 - pbox->y1, 
			(unsigned char*)pImage + 
				(srcwidth * srcy) + (srcx * Bpp), 
			srcwidth, pGC->alu, pGC->planemask, -1, 
			Bpp << 3, depth);
		pbox++;
	    }
	} else { /* XYPixmap */
	    int depth = pGC->depth;
	    int numBox, increment;
	    unsigned long i, mask;
	    BoxPtr pntBox;
	    
	    srcwidth = BitmapBytePad(w + leftPad);
	    increment = h * srcwidth;
 	    i = 1 << (depth - 1);
	    mask = ~0;

	    if((infoRec->pScrn->overlayFlags & OVERLAY_8_32_PLANAR) &&
							 (pGC->depth == 8)){
		i = 0x80000000;  mask = 0xff000000;
	    }

	    for(; i & mask; i >>= 1, pImage += increment) {
		if(i & pGC->planemask) {
		    pntBox = pbox;
		    numBox = nboxes;
		    while(numBox--) {
			srcx = pntBox->x1 - TheRect.x + leftPad;
			srcy = pntBox->y1 - TheRect.y;
			(*infoRec->WriteBitmap)(infoRec->pScrn, 
				pntBox->x1, pntBox->y1, 
				pntBox->x2 - pntBox->x1, 
				pntBox->y2 - pntBox->y1, 
				(unsigned char*)pImage + 
				(srcwidth * srcy) + ((srcx >> 5) << 2), 
				srcwidth, srcx & 31, ~0, 0, pGC->alu, i);
			pntBox++;
	    	    }
		}
	    }

	}

	if(pClipBoxes != (BoxPtr)infoRec->PreAllocMem)
	    xfree(pClipBoxes);
    } else 
	XAAFallbackOps.PutImage(pDraw, pGC, depth, x, y, w, h, leftPad, 
				format, pImage);
}

--- NEW FILE: xaaInit.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaInit.c,v 1.34 2001/07/19 14:19:42 tsi Exp $ */

#include "misc.h"
#include "xf86.h"
#include "xf86_ansic.h"
#include "xf86_OSproc.h"

#include <X11/X.h>
#include "scrnintstr.h"
#include "pixmapstr.h"
#include "windowstr.h"
#include "xf86str.h"
#include "mi.h"
#include "miline.h"
#include "xaa.h"
#include "xaalocal.h"
#include "xaawrap.h"
#include "xf86fbman.h"
#include "servermd.h"

#define MAX_PREALLOC_MEM	65536	/* MUST be >= 1024 */

#define MIN_OFFPIX_SIZE		(320*200)

static Bool XAACloseScreen(int i, ScreenPtr pScreen);
static void XAAGetImage(DrawablePtr pDrawable, int sx, int sy, int w, int h,
			unsigned int format, unsigned long planemask,
			char *pdstLine);
static void XAAGetSpans(DrawablePtr pDrawable, int wMax, DDXPointPtr ppt,
			int *pwidth, int nspans, char *pdstStart);
static PixmapPtr XAACreatePixmap(ScreenPtr pScreen, int w, int h, int depth);
static Bool XAADestroyPixmap(PixmapPtr pPixmap);
static void XAARestoreAreas (PixmapPtr pPixmap, RegionPtr prgnRestore, 
			int xorg, int yorg, WindowPtr pWin);
static void XAASaveAreas (PixmapPtr pPixmap, RegionPtr prgnSave, 
			int xorg, int yorg, WindowPtr pWin);
static Bool XAAEnterVT (int index, int flags);
static void XAALeaveVT (int index, int flags);
static int  XAASetDGAMode(int index, int num, DGADevicePtr devRet);
static void XAAEnableDisableFBAccess (int index, Bool enable);
static Bool XAAChangeWindowAttributes (WindowPtr pWin, unsigned long mask);

int XAAScreenIndex = -1;
int XAAGCIndex = -1;
int XAAPixmapIndex = -1;
static unsigned long XAAGeneration = 0;

/* temp kludge */
static Bool SwitchedOut = FALSE;

XAAInfoRecPtr
XAACreateInfoRec()
{
    XAAInfoRecPtr infoRec;

    infoRec = xcalloc(1, sizeof(XAAInfoRec));
    if(infoRec)
	infoRec->CachePixelGranularity = -1;

    return infoRec;
}

void 
XAADestroyInfoRec(XAAInfoRecPtr infoRec)
{
    if(!infoRec) return;

    if(infoRec->ClosePixmapCache)
	(*infoRec->ClosePixmapCache)(infoRec->pScrn->pScreen);
   
    if(infoRec->PreAllocMem)
	xfree(infoRec->PreAllocMem);

    if(infoRec->PixmapCachePrivate)
	xfree(infoRec->PixmapCachePrivate);

    xfree(infoRec);
}


Bool 
XAAInit(ScreenPtr pScreen, XAAInfoRecPtr infoRec)
{
    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
    XAAScreenPtr pScreenPriv;
    int i;
#ifdef RENDER
    PictureScreenPtr    ps = GetPictureScreenIfSet(pScreen);
#endif

    /* Return successfully if no acceleration wanted */
    if (!infoRec)
	return TRUE;
    
    if (XAAGeneration != serverGeneration) {
	if (	((XAAScreenIndex = AllocateScreenPrivateIndex()) < 0) ||
		((XAAGCIndex = AllocateGCPrivateIndex()) < 0) ||
		((XAAPixmapIndex = AllocatePixmapPrivateIndex()) < 0))
		return FALSE;

	XAAGeneration = serverGeneration;
    }

    if (!AllocateGCPrivate(pScreen, XAAGCIndex, sizeof(XAAGCRec)))
	return FALSE;

    if (!AllocatePixmapPrivate(pScreen, XAAPixmapIndex, sizeof(XAAPixmapRec)))
	return FALSE;

    if (!(pScreenPriv = xalloc(sizeof(XAAScreenRec))))
	return FALSE;

    pScreen->devPrivates[XAAScreenIndex].ptr = (pointer)pScreenPriv;

    if(!xf86FBManagerRunning(pScreen))
	infoRec->Flags &= ~(PIXMAP_CACHE | OFFSCREEN_PIXMAPS);
    if(!(infoRec->Flags & LINEAR_FRAMEBUFFER))
	infoRec->Flags &= ~OFFSCREEN_PIXMAPS;
   
    if(!infoRec->FullPlanemask) { /* for backwards compatibility */
	infoRec->FullPlanemask =  (1 << pScrn->depth) - 1;
	infoRec->FullPlanemasks[pScrn->depth - 1] = infoRec->FullPlanemask;
    }

    for(i = 0; i < 32; i++) {
	if(!infoRec->FullPlanemasks[i]) /* keep any set by caller */
	    infoRec->FullPlanemasks[i] = (1 << (i+1)) - 1;	
    }

    if(!XAAInitAccel(pScreen, infoRec)) return FALSE;
    pScreenPriv->AccelInfoRec = infoRec;
    infoRec->ScratchGC.pScreen = pScreen;

    
    if(!infoRec->GetImage)
	infoRec->GetImage = XAAGetImage;
    if(!infoRec->GetSpans)
	infoRec->GetSpans = XAAGetSpans;
    if(!infoRec->PaintWindowBackground)
	infoRec->PaintWindowBackground = XAAPaintWindow;
    if(!infoRec->PaintWindowBorder)
	infoRec->PaintWindowBorder = XAAPaintWindow;
    if(!infoRec->CopyWindow)
	infoRec->CopyWindow = XAACopyWindow;
    if(!infoRec->SaveAreas)
	infoRec->SaveAreas = XAASaveAreas;
    if(!infoRec->RestoreAreas)
	infoRec->RestoreAreas = XAARestoreAreas;

    pScreenPriv->CreateGC = pScreen->CreateGC;
    pScreen->CreateGC = XAACreateGC;
    pScreenPriv->CloseScreen = pScreen->CloseScreen;
    pScreen->CloseScreen = XAACloseScreen;
    pScreenPriv->GetImage = pScreen->GetImage;
    pScreen->GetImage = infoRec->GetImage;
    pScreenPriv->GetSpans = pScreen->GetSpans;
    pScreen->GetSpans = infoRec->GetSpans;
    pScreenPriv->PaintWindowBackground = pScreen->PaintWindowBackground;
    pScreen->PaintWindowBackground = infoRec->PaintWindowBackground;
    pScreenPriv->PaintWindowBorder = pScreen->PaintWindowBorder;
    pScreen->PaintWindowBorder = infoRec->PaintWindowBorder;
    pScreenPriv->CopyWindow = pScreen->CopyWindow;
    pScreen->CopyWindow = infoRec->CopyWindow;
    pScreenPriv->CreatePixmap = pScreen->CreatePixmap;
    pScreen->CreatePixmap = XAACreatePixmap;
    pScreenPriv->DestroyPixmap = pScreen->DestroyPixmap;
    pScreen->DestroyPixmap = XAADestroyPixmap;
    pScreenPriv->BackingStoreFuncs.RestoreAreas = 
			pScreen->BackingStoreFuncs.RestoreAreas;
    pScreen->BackingStoreFuncs.RestoreAreas = infoRec->RestoreAreas;
    pScreenPriv->BackingStoreFuncs.SaveAreas = 
			pScreen->BackingStoreFuncs.SaveAreas;
    pScreen->BackingStoreFuncs.SaveAreas = infoRec->SaveAreas;
    pScreenPriv->ChangeWindowAttributes = pScreen->ChangeWindowAttributes;
    pScreen->ChangeWindowAttributes = XAAChangeWindowAttributes;

    pScreenPriv->EnterVT = pScrn->EnterVT;
    pScrn->EnterVT = XAAEnterVT; 
    pScreenPriv->LeaveVT = pScrn->LeaveVT;
    pScrn->LeaveVT = XAALeaveVT;
    pScreenPriv->SetDGAMode = pScrn->SetDGAMode;
    pScrn->SetDGAMode = XAASetDGAMode;
    pScreenPriv->EnableDisableFBAccess = pScrn->EnableDisableFBAccess;
    pScrn->EnableDisableFBAccess = XAAEnableDisableFBAccess;

    pScreenPriv->WindowExposures = pScreen->WindowExposures;
#ifdef RENDER
    if (ps)
    {
	pScreenPriv->Composite = ps->Composite;
	ps->Composite = XAAComposite;
	pScreenPriv->Glyphs = ps->Glyphs;
	ps->Glyphs = XAAGlyphs;
    }
#endif    
    if(pScrn->overlayFlags & OVERLAY_8_32_PLANAR)
        XAASetupOverlay8_32Planar(pScreen);

    infoRec->PreAllocMem = xalloc(MAX_PREALLOC_MEM);
    if(infoRec->PreAllocMem)
    	infoRec->PreAllocSize = MAX_PREALLOC_MEM;

    if(infoRec->Flags & PIXMAP_CACHE) 
	xf86RegisterFreeBoxCallback(pScreen, infoRec->InitPixmapCache,
						(pointer)infoRec);

    if(infoRec->Flags & MICROSOFT_ZERO_LINE_BIAS)
	miSetZeroLineBias(pScreen, OCTANT1 | OCTANT2 | OCTANT3 | OCTANT4);

    return TRUE;
}



static Bool
XAACloseScreen (int i, ScreenPtr pScreen)
{
    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
    XAAScreenPtr pScreenPriv = 
	(XAAScreenPtr) pScreen->devPrivates[XAAScreenIndex].ptr;

    pScrn->EnterVT = pScreenPriv->EnterVT; 
    pScrn->LeaveVT = pScreenPriv->LeaveVT; 
    pScrn->EnableDisableFBAccess = pScreenPriv->EnableDisableFBAccess;
   
    pScreen->CreateGC = pScreenPriv->CreateGC;
    pScreen->CloseScreen = pScreenPriv->CloseScreen;
    pScreen->GetImage = pScreenPriv->GetImage;
    pScreen->GetSpans = pScreenPriv->GetSpans;
    pScreen->PaintWindowBackground = pScreenPriv->PaintWindowBackground;
    pScreen->PaintWindowBorder = pScreenPriv->PaintWindowBorder;
    pScreen->CopyWindow = pScreenPriv->CopyWindow;
    pScreen->WindowExposures = pScreenPriv->WindowExposures;
    pScreen->CreatePixmap = pScreenPriv->CreatePixmap;
    pScreen->DestroyPixmap = pScreenPriv->DestroyPixmap;
    pScreen->BackingStoreFuncs.RestoreAreas = 
			pScreenPriv->BackingStoreFuncs.RestoreAreas;
    pScreen->BackingStoreFuncs.SaveAreas = 
			pScreenPriv->BackingStoreFuncs.SaveAreas;
    pScreen->ChangeWindowAttributes = pScreenPriv->ChangeWindowAttributes;

    /* We leave it up to the client to free the XAAInfoRec */

    xfree ((pointer) pScreenPriv);

    return (*pScreen->CloseScreen) (i, pScreen);
}

static void
XAAGetImage (
    DrawablePtr pDraw,
    int	sx, int sy, int w, int h,
    unsigned int    format,
    unsigned long   planemask,
    char	    *pdstLine 
)
{
    ScreenPtr pScreen = pDraw->pScreen;
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
    ScrnInfoPtr pScrn = infoRec->pScrn;

    if(pScrn->vtSema && 
	((pDraw->type == DRAWABLE_WINDOW) || IS_OFFSCREEN_PIXMAP(pDraw))) 
    {
	if(infoRec->ReadPixmap && (format == ZPixmap) && 
	   ((planemask & infoRec->FullPlanemasks[pDraw->depth - 1]) == 
                           infoRec->FullPlanemasks[pDraw->depth - 1]) &&
	   (pDraw->bitsPerPixel == BitsPerPixel(pDraw->depth)))
	{
	    (*infoRec->ReadPixmap)(pScrn, 
		   sx + pDraw->x, sy + pDraw->y, w, h,
		   (unsigned char *)pdstLine,
		   PixmapBytePad(w, pDraw->depth), 
		   pDraw->bitsPerPixel, pDraw->depth);
	    return;
	}
	SYNC_CHECK(pDraw);
    }

    XAA_SCREEN_PROLOGUE (pScreen, GetImage);
    (*pScreen->GetImage) (pDraw, sx, sy, w, h, format, planemask, pdstLine);
    XAA_SCREEN_EPILOGUE (pScreen, GetImage, XAAGetImage);
}

static void
XAAGetSpans (
    DrawablePtr pDraw,
    int		wMax,
    DDXPointPtr	ppt,
    int		*pwidth,
    int		nspans,
    char	*pdstStart
)
{
    ScreenPtr pScreen = pDraw->pScreen;
    XAA_SCREEN_PROLOGUE (pScreen, GetSpans);
    if(xf86Screens[pScreen->myNum]->vtSema && 
	((pDraw->type == DRAWABLE_WINDOW) || IS_OFFSCREEN_PIXMAP(pDraw))) {
	SYNC_CHECK(pDraw);
    }
    (*pScreen->GetSpans) (pDraw, wMax, ppt, pwidth, nspans, pdstStart);
    XAA_SCREEN_EPILOGUE (pScreen, GetSpans, XAAGetSpans);
}


static void
XAASaveAreas (
    PixmapPtr pPixmap,
    RegionPtr prgnSave,
    int       xorg,
    int       yorg,
    WindowPtr pWin
){
    ScreenPtr pScreen = pPixmap->drawable.pScreen;
    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);

    if(IS_OFFSCREEN_PIXMAP(pPixmap)) {
	BoxPtr pbox = REGION_RECTS(prgnSave);
	int nboxes = REGION_NUM_RECTS(prgnSave);

	(*infoRec->SetupForScreenToScreenCopy)(pScrn, 1, 1, GXcopy, ~0, -1);
	while(nboxes--) {
	    (*infoRec->SubsequentScreenToScreenCopy)(pScrn, 
		pbox->x1 + xorg, pbox->y1 + yorg, 
		pPixmap->drawable.x + pbox->x1, 
		pPixmap->drawable.y + pbox->y1,
		pbox->x2 - pbox->x1, pbox->y2 - pbox->y1);
	    pbox++;
	}
	SET_SYNC_FLAG(infoRec);
	return;
    }

    if(xf86Screens[pScreen->myNum]->vtSema && infoRec->ReadPixmap &&
	(pWin->drawable.bitsPerPixel == pPixmap->drawable.bitsPerPixel)) {
	BoxPtr pbox = REGION_RECTS(prgnSave);
	int nboxes = REGION_NUM_RECTS(prgnSave);
	int Bpp =  pPixmap->drawable.bitsPerPixel >> 3;
	unsigned char *dstp = (unsigned char*)pPixmap->devPrivate.ptr;

	while(nboxes--) {
	    (*infoRec->ReadPixmap)(infoRec->pScrn,
		pbox->x1 + xorg, pbox->y1 + yorg, 
		pbox->x2 - pbox->x1, pbox->y2 - pbox->y1, 
		dstp + (pPixmap->devKind * pbox->y1) + (pbox->x1 * Bpp),
		pPixmap->devKind,
		pPixmap->drawable.bitsPerPixel, pPixmap->drawable.depth);
	    pbox++;
	}
	return;
    }

    XAA_SCREEN_PROLOGUE (pScreen, BackingStoreFuncs.SaveAreas);
    if(pScrn->vtSema) {
	SYNC_CHECK(&pWin->drawable);
    }
    (*pScreen->BackingStoreFuncs.SaveAreas) (
		pPixmap, prgnSave, xorg, yorg, pWin);

    XAA_SCREEN_EPILOGUE (pScreen, BackingStoreFuncs.SaveAreas,
			 XAASaveAreas);
}

static void
XAARestoreAreas (    
    PixmapPtr pPixmap,
    RegionPtr prgnRestore,
    int       xorg,
    int       yorg,
    WindowPtr pWin 
){
    ScreenPtr pScreen = pPixmap->drawable.pScreen;
    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);

    if(IS_OFFSCREEN_PIXMAP(pPixmap)) {
	BoxPtr pbox = REGION_RECTS(prgnRestore);
	int nboxes = REGION_NUM_RECTS(prgnRestore);
	int pm = ~0;

	if((pScrn->overlayFlags & OVERLAY_8_32_PLANAR) && 
					(pWin->drawable.depth == 24))
	   pm = 0x00ffffff;

	(*infoRec->SetupForScreenToScreenCopy)(pScrn, 1, 1, GXcopy, pm, -1);
	while(nboxes--) {
	    (*infoRec->SubsequentScreenToScreenCopy)(pScrn, 
		pPixmap->drawable.x + pbox->x1 - xorg, 
		pPixmap->drawable.y + pbox->y1 - yorg,
		pbox->x1, pbox->y1, pbox->x2 - pbox->x1, pbox->y2 - pbox->y1);
	    pbox++;
	}
	SET_SYNC_FLAG(infoRec);
	return;
    }

    if(pScrn->vtSema && infoRec->WritePixmap &&
	!(infoRec->WritePixmapFlags & NO_GXCOPY) &&
	((pWin->drawable.bitsPerPixel == pPixmap->drawable.bitsPerPixel) ||
		((pWin->drawable.bitsPerPixel == 24) &&  
		 (pPixmap->drawable.bitsPerPixel == 32) &&
		 (infoRec->WritePixmapFlags & CONVERT_32BPP_TO_24BPP)))) {
	BoxPtr pbox = REGION_RECTS(prgnRestore);
	int nboxes = REGION_NUM_RECTS(prgnRestore);
	int Bpp =  pPixmap->drawable.bitsPerPixel >> 3;
	unsigned char *srcp = (unsigned char*)pPixmap->devPrivate.ptr;
	int pm = ~0;

	if((pScrn->overlayFlags & OVERLAY_8_32_PLANAR) && 
					(pWin->drawable.depth == 24))
	   pm = 0x00ffffff;
 
	while(nboxes--) {
	    (*infoRec->WritePixmap)(pScrn, pbox->x1, pbox->y1, 
		pbox->x2 - pbox->x1, pbox->y2 - pbox->y1, 
		srcp + (pPixmap->devKind * (pbox->y1 - yorg)) + 
				((pbox->x1 - xorg) * Bpp), 
		pPixmap->devKind, GXcopy, pm, -1, 
		pPixmap->drawable.bitsPerPixel, pPixmap->drawable.depth);
	    pbox++;
	}
	return;
    }

    XAA_SCREEN_PROLOGUE (pScreen, BackingStoreFuncs.RestoreAreas);
    if(pScrn->vtSema) {
	SYNC_CHECK(&pWin->drawable);
    }
    (*pScreen->BackingStoreFuncs.RestoreAreas) (
		pPixmap, prgnRestore, xorg, yorg, pWin);

    XAA_SCREEN_EPILOGUE (pScreen, BackingStoreFuncs.RestoreAreas,
				 XAARestoreAreas);
}

static int
XAAPixmapBPP (ScreenPtr pScreen, int depth)
{
    PixmapPtr	pPix;
    int		bpp;
    DestroyPixmapProcPtr    destroyPixmap;
    
    XAA_SCREEN_PROLOGUE (pScreen, CreatePixmap);
    pPix = (*pScreen->CreatePixmap) (pScreen, 1, 1, depth);
    XAA_SCREEN_EPILOGUE (pScreen, CreatePixmap, XAACreatePixmap);
    if (!pPix)
	return 0;
    bpp = pPix->drawable.bitsPerPixel;
    destroyPixmap = pScreen->DestroyPixmap;
    XAA_SCREEN_PROLOGUE (pScreen, DestroyPixmap);
    (*pScreen->DestroyPixmap) (pPix);
    XAA_SCREEN_EPILOGUE (pScreen, DestroyPixmap, destroyPixmap);
    return bpp;
}

static void
XAAInitializeOffscreenDepths (ScreenPtr pScreen)
{
    XAAInfoRecPtr   infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
    ScrnInfoPtr	    pScrn = xf86Screens[pScreen->myNum];
    int		    d, dep;
    
    infoRec->offscreenDepthsInitialized = TRUE;
    infoRec->offscreenDepths = 0;
    if (infoRec->Flags & OFFSCREEN_PIXMAPS) {
	for (d = 0; d < pScreen->numDepths; d++) {
	    dep = pScreen->allowedDepths[d].depth;
	    if (XAAPixmapBPP (pScreen, dep) == pScrn->bitsPerPixel)
		infoRec->offscreenDepths |= (1 << (dep - 1));
	}
    }
}

static PixmapPtr 
XAACreatePixmap(ScreenPtr pScreen, int w, int h, int depth)
{
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
    XAAPixmapPtr pPriv;
    PixmapPtr pPix = NULL;
    int size = w * h;
    
    if (!infoRec->offscreenDepthsInitialized)
	XAAInitializeOffscreenDepths (pScreen);

    if(pScrn->vtSema && (infoRec->offscreenDepths & (1 << (depth - 1))) &&
	(size >= MIN_OFFPIX_SIZE) && !SwitchedOut &&
	(!infoRec->maxOffPixWidth || (w <= infoRec->maxOffPixWidth)) &&
	(!infoRec->maxOffPixHeight || (h <= infoRec->maxOffPixHeight)) )
    {
        PixmapLinkPtr pLink;
	PixmapPtr pScreenPix;
        FBAreaPtr area;
        int gran = 0;

	switch(pScrn->bitsPerPixel) {
        case 24: 
        case 8:  gran = 4;  break;
        case 16: gran = 2;  break;
        case 32: gran = 1;  break;
        default: break;
        }

        if(BITMAP_SCANLINE_PAD == 64)
           gran *= 2;

        if(!(area = xf86AllocateOffscreenArea(pScreen, w, h, gran, 0,
                                XAARemoveAreaCallback, NULL))) {
	    goto BAILOUT;
	}

        if(!(pLink = xalloc(sizeof(PixmapLink)))) {
            xf86FreeOffscreenArea(area);
	    goto BAILOUT;
	}

	XAA_SCREEN_PROLOGUE (pScreen, CreatePixmap);
	pPix = (*pScreen->CreatePixmap) (pScreen, 0, 0, depth);
	XAA_SCREEN_EPILOGUE (pScreen, CreatePixmap, XAACreatePixmap);

	if (!pPix) {
	    xfree (pLink);
            xf86FreeOffscreenArea(area);
	    goto BAILOUT;
	}
	
	pScreenPix = (*pScreen->GetScreenPixmap)(pScreen);

	pPriv = XAA_GET_PIXMAP_PRIVATE(pPix);
	pPix->drawable.x = area->box.x1;
	pPix->drawable.y = area->box.y1;
	pPix->drawable.width = w;
	pPix->drawable.height = h;
	pPix->drawable.bitsPerPixel = pScrn->bitsPerPixel;
	pPix->devKind = pScreenPix->devKind;
	pPix->devPrivate.ptr = pScreenPix->devPrivate.ptr;
	area->devPrivate.ptr = pPix;

	pPriv->flags = OFFSCREEN;
	pPriv->offscreenArea = area;
 	pPriv->freeData = FALSE;
	    
	pLink->next = infoRec->OffscreenPixmaps;
	pLink->pPix = pPix;
	infoRec->OffscreenPixmaps = pLink;
	return pPix;
    }
BAILOUT:
    XAA_SCREEN_PROLOGUE (pScreen, CreatePixmap);
    pPix = (*pScreen->CreatePixmap) (pScreen, w, h, depth);
    XAA_SCREEN_EPILOGUE (pScreen, CreatePixmap, XAACreatePixmap);

    if(pPix) {
       pPriv = XAA_GET_PIXMAP_PRIVATE(pPix);
       pPriv->flags = 0;
       pPriv->offscreenArea = NULL;
       pPriv->freeData = FALSE;
       if(!w || !h) /* either scratch or shared memory */
	    pPriv->flags |= SHARED_PIXMAP;
    }

    return pPix;
}

static Bool 
XAADestroyPixmap(PixmapPtr pPix)
{
    ScreenPtr pScreen = pPix->drawable.pScreen;
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
    XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pPix);
    Bool ret;

    if(pPix->refcnt == 1) {
        if(pPriv->flags & OFFSCREEN) {
	    if(pPriv->flags & DGA_PIXMAP)
	        xfree(pPriv->offscreenArea);
            else {
	        FBAreaPtr area = pPriv->offscreenArea;
		PixmapLinkPtr pLink = infoRec->OffscreenPixmaps;
	        PixmapLinkPtr prev = NULL;

		while(pLink->pPix != pPix) {
		    prev = pLink;
		    pLink = pLink->next;
		}

	        if(prev) prev->next = pLink->next;
		else infoRec->OffscreenPixmaps = pLink->next;

	        if(!area) area = pLink->area;

	        xf86FreeOffscreenArea(area);
	        pPriv->offscreenArea = NULL;
	        xfree(pLink);
	    } 
        }

        if(pPriv->freeData) { /* pixmaps that were once in video ram */
	    xfree(pPix->devPrivate.ptr);
	    pPix->devPrivate.ptr = NULL;
	}
    }
    
    XAA_SCREEN_PROLOGUE (pScreen, DestroyPixmap);
    ret = (*pScreen->DestroyPixmap) (pPix);
    XAA_SCREEN_EPILOGUE (pScreen, DestroyPixmap, XAADestroyPixmap);
 
    return ret;
}

static Bool
XAAChangeWindowAttributes (WindowPtr pWin, unsigned long mask)
{
   ScreenPtr pScreen = pWin->drawable.pScreen;
   Bool ret;

   XAA_SCREEN_PROLOGUE (pScreen, ChangeWindowAttributes);
   ret = (*pScreen->ChangeWindowAttributes) (pWin, mask);
   XAA_SCREEN_EPILOGUE (pScreen, ChangeWindowAttributes, XAAChangeWindowAttributes);

   /* we have to assume that shared memory pixmaps are dirty
      because we can't wrap operations on them */

   if((mask & CWBackPixmap) && (pWin->backgroundState == BackgroundPixmap) &&
      PIXMAP_IS_SHARED(pWin->background.pixmap))
   {
        XAAPixmapPtr pPixPriv = XAA_GET_PIXMAP_PRIVATE(pWin->background.pixmap);
	pPixPriv->flags |= DIRTY;
   }
   if((mask & CWBorderPixmap) && !(pWin->borderIsPixel) &&
      PIXMAP_IS_SHARED(pWin->border.pixmap))
   {
        XAAPixmapPtr pPixPriv = XAA_GET_PIXMAP_PRIVATE(pWin->border.pixmap);
        pPixPriv->flags |= DIRTY;
   }

   return ret;
}



/*  These two aren't really needed for anything */

static Bool 
XAAEnterVT(int index, int flags)
{
    ScreenPtr pScreen = screenInfo.screens[index];
    XAAScreenPtr pScreenPriv = 
	(XAAScreenPtr) pScreen->devPrivates[XAAScreenIndex].ptr;

    return((*pScreenPriv->EnterVT)(index, flags));
}

static void 
XAALeaveVT(int index, int flags)
{
    ScreenPtr pScreen = screenInfo.screens[index];
    XAAScreenPtr pScreenPriv = 
	(XAAScreenPtr) pScreen->devPrivates[XAAScreenIndex].ptr;
    XAAInfoRecPtr infoRec = pScreenPriv->AccelInfoRec;

    if(infoRec->NeedToSync) {
        (*infoRec->Sync)(infoRec->pScrn);
        infoRec->NeedToSync = FALSE;
    }

    (*pScreenPriv->LeaveVT)(index, flags);
}

typedef struct {
   Bool UsingPixmapCache;
   Bool CanDoColor8x8;
   Bool CanDoMono8x8;
} SavedCacheState, *SavedCacheStatePtr;

static int  
XAASetDGAMode(int index, int num, DGADevicePtr devRet)
{
    ScreenPtr pScreen = screenInfo.screens[index];
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
    XAAScreenPtr pScreenPriv = 
	(XAAScreenPtr) pScreen->devPrivates[XAAScreenIndex].ptr;
    int ret;

    if (!num && infoRec->dgaSaves) { /* restore old pixmap cache state */
	SavedCacheStatePtr state = (SavedCacheStatePtr)infoRec->dgaSaves;
	
	infoRec->UsingPixmapCache = state->UsingPixmapCache;	
	infoRec->CanDoColor8x8 = state->CanDoColor8x8;	
	infoRec->CanDoMono8x8 = state->CanDoMono8x8;
	xfree(infoRec->dgaSaves);
	infoRec->dgaSaves = NULL;
    }

    ret = (*pScreenPriv->SetDGAMode)(index, num, devRet);
    if(ret != Success) return ret;

    if(num && devRet->pPix) {  /* accelerate this pixmap */
	XAAPixmapPtr pixPriv = XAA_GET_PIXMAP_PRIVATE(devRet->pPix);
	FBAreaPtr area;

	if((area = xalloc(sizeof(FBArea)))) {
	    area->pScreen = pScreen;
	    area->box.x1 = 0;
	    area->box.x2 = 0;
	    area->box.y1 = devRet->mode->pixmapWidth;
	    area->box.y2 = devRet->mode->pixmapHeight;
	    area->granularity = 0;
	    area->MoveAreaCallback = 0;
	    area->RemoveAreaCallback = 0;
	    area->devPrivate.ptr = 0;	

	    pixPriv->flags |= OFFSCREEN | DGA_PIXMAP;
	    pixPriv->offscreenArea = area;

	    if(!infoRec->dgaSaves) { /* save pixmap cache state */
		SavedCacheStatePtr state = xalloc(sizeof(SavedCacheState));
	
		state->UsingPixmapCache = infoRec->UsingPixmapCache;	
		state->CanDoColor8x8 = infoRec->CanDoColor8x8;	
		state->CanDoMono8x8 = infoRec->CanDoMono8x8;	
		infoRec->dgaSaves = (char*)state;

		infoRec->UsingPixmapCache = FALSE;
		if(infoRec->PixmapCacheFlags & CACHE_MONO_8x8)
		    infoRec->CanDoMono8x8 = FALSE;
		if(infoRec->PixmapCacheFlags & CACHE_COLOR_8x8)
		    infoRec->CanDoColor8x8 = FALSE;
	    }
	}
    }

    return ret;
}



static void
XAAEnableDisableFBAccess (int index, Bool enable)
{
    ScreenPtr pScreen = screenInfo.screens[index];
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
    XAAScreenPtr pScreenPriv = 
	(XAAScreenPtr) pScreen->devPrivates[XAAScreenIndex].ptr;

    if(!enable) {
	if((infoRec->Flags & OFFSCREEN_PIXMAPS) && (infoRec->OffscreenPixmaps))
	    XAAMoveOutOffscreenPixmaps(pScreen);
	if(infoRec->Flags & PIXMAP_CACHE)
	    XAAInvalidatePixmapCache(pScreen);
	SwitchedOut = TRUE;
    }

    (*pScreenPriv->EnableDisableFBAccess)(index, enable);

    if(enable) {
	if((infoRec->Flags & OFFSCREEN_PIXMAPS) && (infoRec->OffscreenPixmaps))
	    XAAMoveInOffscreenPixmaps(pScreen);
	SwitchedOut = FALSE;
    }
}

--- NEW FILE: xaaInitAccel.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaInitAccel.c,v 1.35tsi Exp $ */

#include "misc.h"
#include "xf86.h"
#include "xf86_ansic.h"
#include "xf86_OSproc.h"

#include <X11/X.h>
#include "scrnintstr.h"
#include "xf86str.h"
#include "xaa.h"
#include "xaalocal.h"
#include "xf86fbman.h"
#include "servermd.h"

#ifdef XFree86LOADER
static const OptionInfoRec *XAAAvailableOptions(void *unused);
#endif

[...1474 lines suppressed...]
    xfree(options);

    if(!infoRec->CacheTile && infoRec->WritePixmapToCache)
	infoRec->CacheTile = XAACacheTile;
    if(!infoRec->CacheMonoStipple && infoRec->WritePixmapToCache)
	infoRec->CacheMonoStipple = XAACacheMonoStipple;
    if(!infoRec->CacheStipple && infoRec->WriteBitmapToCache)
	infoRec->CacheStipple = XAACacheStipple;
    if(!infoRec->CacheMono8x8Pattern && infoRec->WriteMono8x8PatternToCache)
	infoRec->CacheMono8x8Pattern = XAACacheMono8x8Pattern;
    if(!infoRec->CacheColor8x8Pattern && infoRec->WriteColor8x8PatternToCache)
	infoRec->CacheColor8x8Pattern = XAACacheColor8x8Pattern;

    if((infoRec->Flags & PIXMAP_CACHE) && !infoRec->InitPixmapCache) {
	infoRec->InitPixmapCache = XAAInitPixmapCache;
	infoRec->ClosePixmapCache = XAAClosePixmapCache;
    }
    
    return TRUE;
}

--- NEW FILE: xaaLine.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaLine.c,v 1.5 2001/10/28 03:34:04 tsi Exp $ */

#include <X11/X.h>
#include "misc.h"
#include "xf86.h"
#include "xf86_ansic.h"
#include "xf86_OSproc.h"

#include "scrnintstr.h"
#include "pixmapstr.h"
#include "miline.h"
#include "xf86str.h"
#include "xaa.h"
#include "xaalocal.h"


void
#ifdef POLYSEGMENT
XAAPolySegment(
    DrawablePtr	pDrawable,
    GCPtr	pGC,
    int		nseg,
    xSegment	*pSeg
#else
XAAPolyLines(
    DrawablePtr pDrawable,
    GCPtr	pGC,
    int		mode,		/* Origin or Previous */
    int		npt,		/* number of points */
    DDXPointPtr pptInit
#endif
){
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
    BoxPtr pboxInit = REGION_RECTS(pGC->pCompositeClip);
    int nboxInit = REGION_NUM_RECTS(pGC->pCompositeClip);
    unsigned int bias = miGetZeroLineBias(pDrawable->pScreen);
    int xorg = pDrawable->x;
    int yorg = pDrawable->y;
    int nbox;
    BoxPtr pbox;
#ifndef POLYSEGMENT
    DDXPointPtr ppt;
#endif
    int x1, x2, y1, y2, tmp, len;

    if(!nboxInit)
	return;

    if (infoRec->SolidLineFlags & LINE_LIMIT_COORDS) {
	int minValX = infoRec->SolidLineLimits.x1;
	int maxValX = infoRec->SolidLineLimits.x2;
	int minValY = infoRec->SolidLineLimits.y1;
	int maxValY = infoRec->SolidLineLimits.y2;
#ifdef POLYSEGMENT
	int n = nseg;
	xSegment *s = pSeg;

	while (n--)
#else
	int n = npt;
	int xorgtmp = xorg;
	int yorgtmp = yorg;

	ppt = pptInit;
	x2 = ppt->x + xorgtmp;
	y2 = ppt->y + yorgtmp;
	while (--n)
#endif
	{
#ifdef POLYSEGMENT
	    x1 = s->x1 + xorg;
	    y1 = s->y1 + yorg;
	    x2 = s->x2 + xorg;
	    y2 = s->y2 + yorg;
	    s++;
#else
	    x1 = x2;
	    y1 = y2;
	    ++ppt;
	    if (mode == CoordModePrevious) {
		xorgtmp = x1;
		yorgtmp = y1;
	    }
	    x2 = ppt->x + xorgtmp;
	    y2 = ppt->y + yorgtmp;
#endif
	    if (x1 > maxValX || x1 < minValX ||
		x2 > maxValX || x2 < minValX ||
		y1 > maxValY || y1 < minValY ||
		y2 > maxValY || y2 < minValY) {
#ifdef POLYSEGMENT
		XAAFallbackOps.PolySegment(pDrawable, pGC, nseg, pSeg);
#else
		XAAFallbackOps.Polylines(pDrawable, pGC, mode, npt, pptInit);
#endif
		return;
	    }
	}
    }

    (*infoRec->SetupForSolidLine)(infoRec->pScrn, pGC->fgPixel,
					pGC->alu, pGC->planemask);

#ifdef POLYSEGMENT
    while (nseg--)
#else
    ppt = pptInit;
    x2 = ppt->x + xorg;
    y2 = ppt->y + yorg;
    while(--npt)
#endif
    {
	nbox = nboxInit;
	pbox = pboxInit;

#ifdef POLYSEGMENT
	x1 = pSeg->x1 + xorg;	
	y1 = pSeg->y1 + yorg;
	x2 = pSeg->x2 + xorg;	
	y2 = pSeg->y2 + yorg;
	pSeg++;
#else
	x1 = x2; 
	y1 = y2;
	++ppt;
	if (mode == CoordModePrevious) {
	    xorg = x1; 
	    yorg = y1;
	}
	x2 = ppt->x + xorg; 
	y2 = ppt->y + yorg;
#endif

	if (x1 == x2) { /* vertical line */
	    /* make the line go top to bottom of screen, keeping
	       endpoint semantics
	    */
	    if (y1 > y2) {
		tmp = y2; 
		y2 = y1 + 1; 
		y1 = tmp + 1;
#ifdef POLYSEGMENT
		if (pGC->capStyle != CapNotLast) y1--;
#endif
	    }
#ifdef POLYSEGMENT
	    else if (pGC->capStyle != CapNotLast) y2++;
#endif
	    /* get to first band that might contain part of line */
	    while(nbox && (pbox->y2 <= y1)) {
		pbox++;
		nbox--;
	    }

	   /* stop when lower edge of box is beyond end of line */
	    while(nbox && (y2 >= pbox->y1)) {
		if ((x1 >= pbox->x1) && (x1 < pbox->x2)) {
		    tmp = max(y1, pbox->y1);
		    len = min(y2, pbox->y2) - tmp;
		    if (len) (*infoRec->SubsequentSolidHorVertLine)(
				infoRec->pScrn, x1, tmp, len, DEGREES_270);
		}
		nbox--;
		pbox++;
	    }
#ifndef POLYSEGMENT
	    y2 = ppt->y + yorg;
#endif
	} else if (y1 == y2) { /* horizontal line */
	/* force line from left to right, keeping endpoint semantics */
	    if (x1 > x2) {
		tmp = x2; 
		x2 = x1 + 1; 
		x1 = tmp + 1;
#ifdef POLYSEGMENT
		if (pGC->capStyle != CapNotLast)  x1--;
#endif
	    }
#ifdef POLYSEGMENT
	    else if (pGC->capStyle != CapNotLast) x2++;
#endif

	    /* find the correct band */
	    while(nbox && (pbox->y2 <= y1)) {
		pbox++;
		nbox--;
	    }

	    /* try to draw the line, if we haven't gone beyond it */
	    if (nbox && (pbox->y1 <= y1)) {
		int orig_y = pbox->y1;
		/* when we leave this band, we're done */
		while(nbox && (orig_y == pbox->y1)) {
		    if (pbox->x2 <= x1) {
			/* skip boxes until one might contain start point */
			nbox--;
			pbox++;
			continue;
		    }

		    /* stop if left of box is beyond right of line */
		    if (pbox->x1 >= x2) {
			nbox = 0;
			break;
		    }

		    tmp = max(x1, pbox->x1);
		    len = min(x2, pbox->x2) - tmp;
		    if (len) (*infoRec->SubsequentSolidHorVertLine)(
				infoRec->pScrn, tmp, y1, len, DEGREES_0);
		    nbox--;
		    pbox++;
		}
	    }
#ifndef POLYSEGMENT
	    x2 = ppt->x + xorg;
#endif
	} else{ /* sloped line */
	    unsigned int oc1, oc2;
	    int dmin, dmaj, e, octant;

	    if (infoRec->SubsequentSolidBresenhamLine) {
	        if((dmaj = x2 - x1) < 0) {
		   dmaj = -dmaj;
		   octant = XDECREASING;
		} else octant = 0;		   

	        if((dmin = y2 - y1) < 0) {
		   dmin = -dmin;
		   octant |= YDECREASING;
		}	
	
		if(dmin >= dmaj){
		    tmp = dmin; dmin = dmaj; dmaj = tmp;
		    octant |= YMAJOR;
		}

		e = -dmaj - ((bias >> octant) & 1);
		len = dmaj;
		dmin <<= 1;
		dmaj <<= 1;
	    } else {	/* Muffle compiler */
		dmin = dmaj = e = octant = len = 0;
	    }

	    while(nbox--) {
		oc1 = oc2 = 0;
		OUTCODES(oc1, x1, y1, pbox);
		OUTCODES(oc2, x2, y2, pbox);
		if (!(oc1 | oc2)) {   /* unclipped */
		    if(infoRec->SubsequentSolidTwoPointLine) {
			(*infoRec->SubsequentSolidTwoPointLine)(
				infoRec->pScrn, x1, y1, x2, y2, 
#ifdef POLYSEGMENT
			    	(pGC->capStyle != CapNotLast) ? 0 :
#endif
				OMIT_LAST
			);
		    } else {
			(*infoRec->SubsequentSolidBresenhamLine)(
				infoRec->pScrn, x1, y1, dmaj, dmin, e, 
#ifdef POLYSEGMENT
			    	(pGC->capStyle != CapNotLast) ? (len+1) :
#endif
			    	len, octant);
		    }
		    break;
		} else if (oc1 & oc2) { /* completely clipped */
		    pbox++;
		} else if (infoRec->ClippingFlags & HARDWARE_CLIP_SOLID_LINE) {
		    (*infoRec->SetClippingRectangle)(infoRec->pScrn,
			pbox->x1, pbox->y1, pbox->x2 - 1, pbox->y2 - 1);

		    if(infoRec->SubsequentSolidBresenhamLine) {
			(*infoRec->SubsequentSolidBresenhamLine)(
				infoRec->pScrn, x1, y1, dmaj, dmin, e, 
#ifdef POLYSEGMENT
			    	(pGC->capStyle != CapNotLast) ? (len+1) :
#endif
			    	len, octant);
		    } else {
			(*infoRec->SubsequentSolidTwoPointLine)(
				infoRec->pScrn, x1, y1, x2, y2, 
#ifdef POLYSEGMENT
			    	(pGC->capStyle != CapNotLast) ? 0 :
#endif
				OMIT_LAST
			);
		    }
		    (*infoRec->DisableClipping)(infoRec->pScrn);
		    pbox++;
		} else {
		    int new_x1 = x1, new_y1 = y1, new_x2 = x2, new_y2 = y2;
		    int clip1 = 0, clip2 = 0;
		    int err, adx, ady;
		    
		    if(octant & YMAJOR) {
			ady = dmaj >> 1;
			adx = dmin >> 1;
		    } else {
			ady = dmin >> 1;
			adx = dmaj >> 1;
		    }

		    if (miZeroClipLine(pbox->x1, pbox->y1, 
				       pbox->x2 - 1, pbox->y2 - 1,
				       &new_x1, &new_y1, &new_x2, &new_y2,
				       adx, ady, &clip1, &clip2,
				       octant, bias, oc1, oc2) == -1)
		    {
			pbox++;
			continue;
		    }

		    if (octant & YMAJOR)
			len = abs(new_y2 - new_y1);
		    else
			len = abs(new_x2 - new_x1);
#ifdef POLYSEGMENT
		    if (clip2 != 0 || pGC->capStyle != CapNotLast)
			len++;
#else
		    len += (clip2 != 0);
#endif
		    if (len) {
		    	int abserr, clipdx, clipdy;
			/* unwind bresenham error term to first point */
			if (clip1) {
			    clipdx = abs(new_x1 - x1);
			    clipdy = abs(new_y1 - y1);

			    if (octant & YMAJOR)
				err = e + clipdy*dmin - clipdx*dmaj;
			    else
				err = e + clipdx*dmin - clipdy*dmaj;
			} else
			    err = e;

#define range infoRec->SolidBresenhamLineErrorTermBits
			abserr = abs(err);			    
			while((abserr & range) || 
			      (dmaj & range) ||
			      (dmin & range)) {
				dmin >>= 1;
				dmaj >>= 1;
				abserr >>= 1;
				err /= 2;
			}

			(*infoRec->SubsequentSolidBresenhamLine)(
				infoRec->pScrn, new_x1, new_y1,
				dmaj, dmin, err, len, octant);
		    }
		    pbox++;
		}
	    } /* while (nbox--) */
	} /* sloped line */
    } /* while (nline--) */

#ifndef POLYSEGMENT
    /* paint the last point if the end style isn't CapNotLast.
       (Assume that a projecting, butt, or round cap that is one
        pixel wide is the same as the single pixel of the endpoint.)
    */

    if ((pGC->capStyle != CapNotLast) &&
	((ppt->x + xorg != pptInit->x + pDrawable->x) ||
	 (ppt->y + yorg != pptInit->y + pDrawable->y) ||
	 (ppt == pptInit + 1)))
    {
	nbox = nboxInit;
	pbox = pboxInit;
	while (nbox--)
	{
	    if ((x2 >= pbox->x1) && (y2 >= pbox->y1) &&
		(x2 <  pbox->x2) && (y2 <  pbox->y2))
	    {
		(*infoRec->SubsequentSolidHorVertLine)(
			infoRec->pScrn, x2, y2, 1, DEGREES_0);
		break;
	    }
	    else
		pbox++;
	}
    }
#endif

    SET_SYNC_FLAG(infoRec);
}


--- NEW FILE: xaaLineMisc.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaLineMisc.c,v 1.4 1998/09/27 04:43:45 dawes Exp $ */

#include "misc.h"
#include "xf86.h"
#include "xf86_ansic.h"
#include "xf86_OSproc.h"

#include <X11/X.h>
#include "scrnintstr.h"
#include "miline.h"
#include "xf86str.h"
#include "xaa.h"
#include "xaalocal.h"
   

void 
XAASolidHorVertLineAsRects(
   ScrnInfoPtr pScrn,
   int x, int y, int len, int dir
){
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);

    if(dir == DEGREES_0) 
	(*infoRec->SubsequentSolidFillRect)(pScrn, x, y, len, 1);
    else
	(*infoRec->SubsequentSolidFillRect)(pScrn, x, y, 1, len);
}
   

void 
XAASolidHorVertLineAsTwoPoint(
   ScrnInfoPtr pScrn,
   int x, int y, int len, int dir
){
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);

    len--;

    if(dir == DEGREES_0) 
	(*infoRec->SubsequentSolidTwoPointLine)(pScrn, x, y, x + len, y, 0);
    else
	(*infoRec->SubsequentSolidTwoPointLine)(pScrn, x, y, x, y + len, 0);
}
   
void 
XAASolidHorVertLineAsBresenham(
   ScrnInfoPtr pScrn,
   int x, int y, int len, int dir
){
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);

    if(dir == DEGREES_0) 
	(*infoRec->SubsequentSolidBresenhamLine)(
		pScrn, x, y, len << 1, 0, -len, len, 0);
    else
	(*infoRec->SubsequentSolidBresenhamLine)(
		pScrn, x, y, len << 1, 0, -len, len, YMAJOR);
}


void
XAAComputeDash(GCPtr pGC)
{
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
    XAAGCPtr   pGCPriv = (XAAGCPtr) (pGC)->devPrivates[XAAGCIndex].ptr;
    Bool EvenDash = (pGC->numInDashList & 0x01) ? FALSE : TRUE;
    int PatternLength = 0;
    unsigned char* DashPtr = (unsigned char*)pGC->dash;
    CARD32 *ptr;
    int count = pGC->numInDashList; 
    int shift, value, direction;
    Bool set;

    if(pGCPriv->DashPattern)
	xfree(pGCPriv->DashPattern);

    pGCPriv->DashPattern = NULL;
    pGCPriv->DashLength = 0; 
 
    while(count--) 
	PatternLength += *(DashPtr++);

    if(!EvenDash)
	PatternLength <<= 1;

    if(PatternLength > infoRec->DashPatternMaxLength) 
	return;

    if((infoRec->DashedLineFlags & LINE_PATTERN_POWER_OF_2_ONLY) && 
				(PatternLength & (PatternLength - 1)))
	return;

    pGCPriv->DashPattern = xcalloc((PatternLength + 31) >> 5, 4);
    if(!pGCPriv->DashPattern) return;
    pGCPriv->DashLength = PatternLength;

    if(infoRec->DashedLineFlags & (LINE_PATTERN_LSBFIRST_MSBJUSTIFIED |
 	 	 		   LINE_PATTERN_LSBFIRST_LSBJUSTIFIED)) {
	direction = 1;
	set = TRUE;
	DashPtr = (unsigned char*)pGC->dash;
    } else {
	direction = -1;
	set = FALSE;
	DashPtr = (unsigned char*)pGC->dash + pGC->numInDashList - 1;
    }

    if(infoRec->DashedLineFlags & (LINE_PATTERN_LSBFIRST_MSBJUSTIFIED |
 	 	 		   LINE_PATTERN_MSBFIRST_MSBJUSTIFIED))
	shift = 32 - (PatternLength & 31);
    else
	shift = 0;

    ptr = (CARD32*)(pGCPriv->DashPattern);

CONCATENATE:

    count = pGC->numInDashList;

    while(count--) {
	value = *DashPtr;
	DashPtr += direction;
	while(value) {
	    if(value < (32 - shift)) {
		if(set) *ptr |= XAAShiftMasks[value] << shift;
		shift += value;
		break;
	     } else {
		if(set) *ptr |= ~0L << shift;
		value -= (32 - shift);
		shift = 0;
		ptr++;
	     }
	}
	if(set) set = FALSE;
	else set = TRUE;
    }

    if(!EvenDash) {
	EvenDash = TRUE;
	if(infoRec->DashedLineFlags & (LINE_PATTERN_LSBFIRST_MSBJUSTIFIED |
				       LINE_PATTERN_LSBFIRST_LSBJUSTIFIED))
	   DashPtr = (unsigned char*)pGC->dash;
	else
	   DashPtr = (unsigned char*)pGC->dash + pGC->numInDashList;
	goto CONCATENATE;
    }
}

--- NEW FILE: xaaNonTEGlyph.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaNonTEGlyph.c,v 1.4 1998/09/13 05:23:55 dawes Exp $ */


#include "xaa.h"
#include "xaalocal.h"
#include "xaacexp.h"
#include "xf86.h"
#include "xf86_ansic.h"

/* Not used anymore because the algorithm isn't correct. It doesn't
   handle overlapping characters properly */

#ifdef TRIPLE_BITS
#define NonTEGlyphFunc EXPNAME(XAANonTEGlyphScanlineFunc3)
#else
#define NonTEGlyphFunc EXPNAME(XAANonTEGlyphScanlineFunc)
#endif

/********************************************************************

   Here we have NonTEGlyphRenders for a bunch of different color
   expansion types.  The driver may provide its own renderer, but
   this is the default one which renders using lower-level primitives
   exported by the chipset driver.

********************************************************************/

/* Since the dimensions of the text string and the backing rectangle
	do not always coincide, it is possible that wBack or wText
	may be 0!  The NonTEGlyphRender must always check for this. */

/* This gets built for MSBFIRST or LSBFIRST with FIXEDBASE or not,
	with TRIPLE_BITS or not. A total of 8 versions */

/* if the backing rectangle and text are of the same dimensions
	then we can draw in one pass */

void 
#ifdef TRIPLE_BITS
EXPNAME(XAANonTEGlyphRenderer3)(
#else
EXPNAME(XAANonTEGlyphRenderer)(
#endif
    ScrnInfoPtr pScrn,
    int xText, int wText, 
    int y, int h, int skipleft, int startline, 
    NonTEGlyphInfo *glyphp,
    int fg, int rop,
    unsigned int planemask )
{
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
    CARD32* base = (CARD32*)infoRec->ColorExpandBase;
#ifdef TRIPLE_BITS
    int dwords = ((3 * wText + 31) >> 5) * h;
#else
    int dwords = ((wText + 31) >> 5) * h;
#endif

    (*infoRec->SetupForCPUToScreenColorExpandFill)(
					pScrn, fg, -1, rop, planemask);
    (*infoRec->SubsequentCPUToScreenColorExpandFill)(
					pScrn, xText, y, wText, h, 0);

#ifndef FIXEDBASE
#ifdef TRIPLE_BITS
    if((((3 * wText + 31) >> 5) * h) <= infoRec->ColorExpandRange)
#else
    if((((wText + 31) >> 5) * h) <= infoRec->ColorExpandRange)
#endif
	while(h--) 
	    base = NonTEGlyphFunc(base, glyphp, startline++, wText, skipleft);
    else
#endif
	while(h--)
	    NonTEGlyphFunc(base, glyphp, startline++, wText, skipleft);

    if((infoRec->CPUToScreenColorExpandFillFlags & CPU_TRANSFER_PAD_QWORD) &&
			(dwords & 1)) {
	base = (CARD32*)infoRec->ColorExpandBase;
	base[0] = 0x00000000;
    }

    if(infoRec->CPUToScreenColorExpandFillFlags & SYNC_AFTER_COLOR_EXPAND) 
	(*infoRec->Sync)(pScrn);
    else SET_SYNC_FLAG(infoRec);
}

#ifndef FIXEDBASE
/*  Scanline version of above gets built for LSBFIRST and MSBFIRST */

void 
#ifdef TRIPLE_BITS
EXPNAME(XAANonTEGlyphRendererScanline3)(
#else
EXPNAME(XAANonTEGlyphRendererScanline)(
#endif
    ScrnInfoPtr pScrn,
    int xText, int wText, 
    int y, int h, int skipleft, int startline, 
    NonTEGlyphInfo *glyphp,
    int fg, int rop,
    unsigned int planemask )
{
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
    int bufferNo = 0;
    CARD32* base;

    (*infoRec->SetupForScanlineCPUToScreenColorExpandFill)(
				pScrn, fg, -1, rop, planemask);
    (*infoRec->SubsequentScanlineCPUToScreenColorExpandFill)(
				pScrn, xText, y, wText, h, 0);

    while(h--) {
	base = (CARD32*)infoRec->ScanlineColorExpandBuffers[bufferNo];
	NonTEGlyphFunc(base, glyphp, startline++, wText, skipleft);
	(*infoRec->SubsequentColorExpandScanline)(pScrn, bufferNo++);
	if(bufferNo >= infoRec->NumScanlineColorExpandBuffers)
	    bufferNo = 0;
    }

    SET_SYNC_FLAG(infoRec);
}

#endif

/********************************************************************

   Generic NonTE scanline rendering code.

********************************************************************/


CARD32* 
NonTEGlyphFunc(
    CARD32 *base,
    NonTEGlyphInfo *glyphp,
    int line, int TotalWidth, int skipleft )
{
    CARD32 bits = 0;
    int shift = glyphp->width; 

    if(skipleft) {
	if((line >= glyphp->firstline) && (line <= glyphp->lastline))
            bits = SHIFT_R(glyphp->bitsp[line], skipleft);
	shift -= skipleft;
    } else if((line >= glyphp->firstline) && (line <= glyphp->lastline))
            bits =  glyphp->bitsp[line];
 

    while(TotalWidth > 32) {
	while(shift < 32) {
	    glyphp++;
	    if((line >= glyphp->firstline) && (line <= glyphp->lastline)) 
		bits |= SHIFT_L(glyphp->bitsp[line],shift);
	    shift += glyphp->width;	
	}
#ifdef TRIPLE_BITS
	WRITE_BITS3(bits);
#else
	WRITE_BITS(bits);
#endif
	shift &= 31;
	if(shift && 
	 (line >= glyphp->firstline) && (line <= glyphp->lastline)) 
           bits = SHIFT_R(glyphp->bitsp[line], glyphp->width - shift);
	else bits = 0;
	TotalWidth -= 32;
    }

    if(TotalWidth) {
	TotalWidth -= shift;
	while(TotalWidth > 0) {
	     glyphp++;
	     if((line >= glyphp->firstline) && (line <= glyphp->lastline)) 
		bits |= SHIFT_L(glyphp->bitsp[line], shift);
	     shift += glyphp->width;
	     TotalWidth -= glyphp->width;
	}
#ifdef TRIPLE_BITS
	if (shift >= 22) {
	    WRITE_BITS3(bits);
	} else if (shift >= 11) {
	    WRITE_BITS2(bits);
	} else {
	    WRITE_BITS1(bits);
	}
#else
	WRITE_BITS(bits);
#endif
    }

  
    return base;
}





--- NEW FILE: xaaNonTEText.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaNonTEText.c,v 1.12 2000/04/07 19:11:10 mvojkovi Exp $ */

/********************************************************************

   In this file we have GC level replacements for PolyText8/16,
   ImageText8/16, ImageGlyphBlt and PolyGlyphBlt for NonTE (proportional) 
   fonts. The idea is that everything in this file is device independent.
   The mentioned GCOps are merely wrappers for the 
   PolyGlyphBltNonTEColorExpansion and ImageGlyphBltNonTEColorExpansion
   functions which calculate the boxes containing arbitrarily clipped 
   text and passes them to the NonTEGlyphRenderer which will usually 
   be a lower level XAA function which renders these clipped glyphs using
   the basic color expansion functions exported by the chipset driver.
   The NonTEGlyphRenderer itself may optionally be driver supplied to
   facilitate work-arounds/optimizations at a higher level than usual.

   Written by Mark Vojkovich (mvojkovi at ucsd.edu)

********************************************************************/

#include "misc.h"
#include "xf86.h"
#include "xf86_ansic.h"
#include "xf86_OSproc.h"

#include <X11/X.h>
#include "font.h"
#include "scrnintstr.h"
#include "dixfontstr.h"
#include "xf86str.h"
#include "xaa.h"
#include "xaacexp.h"
#include "xaalocal.h"
#include "gcstruct.h"
#include "pixmapstr.h"


static void ImageGlyphBltNonTEColorExpansion(ScrnInfoPtr pScrn,
				int xInit, int yInit, FontPtr font,
				int fg, int bg, unsigned planemask,
				RegionPtr cclip, int nglyph,
				unsigned char* gBase, CharInfoPtr *ppci);
static int PolyGlyphBltNonTEColorExpansion(ScrnInfoPtr pScrn,
				int xInit, int yInit, FontPtr font,
				int fg, int rop, unsigned planemask,
				RegionPtr cclip, int nglyph,
				unsigned char* gBase, CharInfoPtr *ppci);

/********************************************************************

   GC level replacements for PolyText8/16 and ImageText8/16
   for NonTE fonts when using color expansion.

********************************************************************/


int
XAAPolyText8NonTEColorExpansion(
    DrawablePtr pDraw,
    GCPtr	pGC,
    int		x, 
    int 	y,
    int 	count,
    char	*chars )
{
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
    unsigned long n;
    int width = 0;

    (*pGC->font->get_glyphs)(pGC->font, (unsigned long)count, 
		(unsigned char *)chars, Linear8Bit, &n, infoRec->CharInfo);

    if(n) {
	width = PolyGlyphBltNonTEColorExpansion( infoRec->pScrn, 
		x + pDraw->x, y + pDraw->y, pGC->font, 
		pGC->fgPixel, pGC->alu, pGC->planemask, 
		pGC->pCompositeClip, n, FONTGLYPHS(pGC->font),
 		infoRec->CharInfo);
    }

    return (x + width);
}


int
XAAPolyText16NonTEColorExpansion(
    DrawablePtr pDraw,
    GCPtr	pGC,
    int		x, 
    int		y,
    int		count,
    unsigned short *chars )
{
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
    unsigned long n;
    int width = 0;

    (*pGC->font->get_glyphs)(
		pGC->font, (unsigned long)count, (unsigned char *)chars,
		(FONTLASTROW(pGC->font) == 0) ? Linear16Bit : TwoD16Bit,
		&n, infoRec->CharInfo);

    if(n) {
	width = PolyGlyphBltNonTEColorExpansion( infoRec->pScrn, 
		x + pDraw->x, y + pDraw->y, pGC->font, 
		pGC->fgPixel, pGC->alu, pGC->planemask, 
		pGC->pCompositeClip, n, FONTGLYPHS(pGC->font),
		infoRec->CharInfo);
    }

    return (x + width);
}


void
XAAImageText8NonTEColorExpansion(
    DrawablePtr pDraw,
    GCPtr	pGC,
    int		x, 
    int		y,
    int		count,
    char	*chars 
){
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
    unsigned long n;

    if(!REGION_NUM_RECTS(pGC->pCompositeClip))
	return;

    (*pGC->font->get_glyphs)(pGC->font, (unsigned long)count, 
		(unsigned char *)chars, Linear8Bit, &n, infoRec->CharInfo);

    if(n) ImageGlyphBltNonTEColorExpansion(
	infoRec->pScrn, x + pDraw->x, y + pDraw->y,
	pGC->font, pGC->fgPixel, pGC->bgPixel, pGC->planemask, 
	pGC->pCompositeClip, n, FONTGLYPHS(pGC->font), infoRec->CharInfo);
}


void
XAAImageText16NonTEColorExpansion(
    DrawablePtr pDraw,
    GCPtr	pGC,
    int		x, 
    int		y,
    int		count,
    unsigned short *chars 
){
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
    unsigned long n;

    if(!REGION_NUM_RECTS(pGC->pCompositeClip))
	return;

    (*pGC->font->get_glyphs)(
		pGC->font, (unsigned long)count, (unsigned char *)chars,
		(FONTLASTROW(pGC->font) == 0) ? Linear16Bit : TwoD16Bit,
		&n, infoRec->CharInfo);

    if(n) ImageGlyphBltNonTEColorExpansion(
	infoRec->pScrn, x + pDraw->x, y + pDraw->y,
	pGC->font, pGC->fgPixel, pGC->bgPixel, pGC->planemask, 
	pGC->pCompositeClip, n, FONTGLYPHS(pGC->font), infoRec->CharInfo);
}



/********************************************************************

   GC level replacements for ImageGlyphBlt and PolyGlyphBlt for
   NonTE fonts when using color expansion.

********************************************************************/


void
XAAImageGlyphBltNonTEColorExpansion(
    DrawablePtr pDraw,
    GCPtr pGC,
    int xInit, int yInit,
    unsigned int nglyph,
    CharInfoPtr *ppci,      /* array of character info */
    pointer pglyphBase	       /* start of array of glyphs */
){
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);

    if(!REGION_NUM_RECTS(pGC->pCompositeClip))
	return;

    ImageGlyphBltNonTEColorExpansion(
	infoRec->pScrn, xInit + pDraw->x, yInit + pDraw->y,
	pGC->font, pGC->fgPixel, pGC->bgPixel, pGC->planemask, 
	pGC->pCompositeClip, nglyph, (unsigned char*)pglyphBase, ppci);
}

void
XAAPolyGlyphBltNonTEColorExpansion(
    DrawablePtr pDraw,
    GCPtr pGC,
    int xInit, int yInit,
    unsigned int nglyph,
    CharInfoPtr *ppci,      /* array of character info */
    pointer pglyphBase	       /* start of array of glyphs */
){
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);

    if(!REGION_NUM_RECTS(pGC->pCompositeClip))
	return;

    PolyGlyphBltNonTEColorExpansion(
	infoRec->pScrn, xInit + pDraw->x, yInit + pDraw->y,
	pGC->font, pGC->fgPixel, pGC->alu, pGC->planemask, 
	pGC->pCompositeClip, nglyph, (unsigned char*)pglyphBase, ppci);
}




/********************************************************************

   ImageGlyphBltNonTEColorExpansion -
   PolyGlyphBltNonTEColorExpansion -

   These guys compute the clipped pieces of text and send it to
   the lower-level function which will handle acceleration of 
   arbitrarily clipped text.
  
********************************************************************/



static int
CollectCharacterInfo(
    NonTEGlyphPtr glyphs,
    unsigned int nglyph,
    CharInfoPtr *ppci,
    FontPtr pfont
){
   int i, w = 0;
   
   for(i = 0; i < nglyph; i++, ppci++, glyphs++) {
	glyphs->bits = (unsigned char*)((*ppci)->bits);
	glyphs->start = w + (*ppci)->metrics.leftSideBearing;
	glyphs->end = w + (*ppci)->metrics.rightSideBearing;
	glyphs->yoff = (*ppci)->metrics.ascent;
	glyphs->height = glyphs->yoff + (*ppci)->metrics.descent;
	glyphs->srcwidth = PADGLYPHWIDTHBYTES(glyphs->end - glyphs->start);
	w += (*ppci)->metrics.characterWidth;
   }
   return w;
}


static void
PolyGlyphBltAsSingleBitmap (
   ScrnInfoPtr pScrn,
   int nglyph,
   FontPtr font,
   int xInit,
   int yInit,
   int nbox,
   BoxPtr pbox,
   int fg,
   int rop,
   unsigned planemask
){
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
    CARD32 *block, *pntr, *bits;
    int pitch, topLine, botLine, top, bot, height;
    int Left, Right, Top, Bottom;
    int LeftEdge, RightEdge;
    int bitPitch, shift, size, i, skippix;
    NonTEGlyphPtr glyphs = infoRec->GlyphInfo;
    Bool extra;
	
    Left = xInit + infoRec->GlyphInfo[0].start;
    Right = xInit + infoRec->GlyphInfo[nglyph - 1].end;
    Top = yInit - FONTMAXBOUNDS(font,ascent);
    Bottom = yInit + FONTMAXBOUNDS(font,descent);

    /* get into the first band that may contain part of our string */
    while(nbox && (Top >= pbox->y2)) {
	pbox++; nbox--;
    }

    if(!nbox) return;

    pitch = (Right - Left + 31) >> 5;
    size = (pitch << 2) * (Bottom - Top);
    block = (CARD32*)ALLOCATE_LOCAL(size);
    bzero(block, size);

    topLine = 10000; botLine = -10000;

    while(nglyph--) {
	top = -glyphs->yoff;
	bot = top + glyphs->height;
	if(top < topLine) topLine = top;
	if(bot > botLine) botLine = bot;
	skippix = glyphs->start - infoRec->GlyphInfo[0].start;
	bits = (CARD32*)glyphs->bits;
	bitPitch = glyphs->srcwidth >> 2;
	pntr = block + ((FONTMAXBOUNDS(font,ascent) + top) * pitch) +
				(skippix >> 5);
	shift = skippix & 31;
	extra = ((shift + glyphs->end - glyphs->start) > 32);

	for(i = top; i < bot; i++) {
	    *pntr |= SHIFT_L(*bits, shift);
	    if(extra)
		*(pntr + 1) |= SHIFT_R(*bits,32 - shift);
	    pntr += pitch;
	    bits += bitPitch;
	}

	glyphs++;
    }

    pntr = block + ((FONTMAXBOUNDS(font,ascent) + topLine) * pitch);

    Top = yInit + topLine;
    Bottom = yInit + botLine;

    while(nbox && (Top >= pbox->y2)) {
	pbox++; nbox--;
    }

    while(nbox && (Bottom > pbox->y1)) {
	LeftEdge = max(Left, pbox->x1);
	RightEdge = min(Right, pbox->x2);

	if(RightEdge > LeftEdge) {
	    skippix = LeftEdge - Left;
	    topLine = max(Top, pbox->y1);
	    botLine = min(Bottom, pbox->y2);	
	    height = botLine - topLine;

	    if(height > 0) 
	       (*infoRec->WriteBitmap)(pScrn, LeftEdge, topLine, 
			RightEdge - LeftEdge, height,
			(unsigned char*)(pntr + ((topLine - Top) * pitch) +
				(skippix >> 5)),
			pitch << 2, skippix & 31, fg, -1, rop, planemask);
	}

	nbox--; pbox++;
    }

    DEALLOCATE_LOCAL(block);
}

static void
ImageGlyphBltNonTEColorExpansion(
   ScrnInfoPtr pScrn,
   int xInit, int yInit,
   FontPtr font,
   int fg, int bg,
   unsigned planemask,
   RegionPtr cclip,
   int nglyph,
   unsigned char* gBase,
   CharInfoPtr *ppci 
){
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
    int skippix, skipglyph, width, n, i;
    int Left, Right, Top, Bottom;
    int LeftEdge, RightEdge, ytop, ybot;
    int nbox = REGION_NUM_RECTS(cclip);
    BoxPtr pbox = REGION_RECTS(cclip);
    Bool AlreadySetup = FALSE;

    width = CollectCharacterInfo(infoRec->GlyphInfo, nglyph, ppci, font);

    /* find our backing rectangle dimensions */
    Left = xInit;
    Right = Left + width;
    Top = yInit - FONTASCENT(font);
    Bottom = yInit + FONTDESCENT(font);

    /* get into the first band that may contain part of our box */
    while(nbox && (Top >= pbox->y2)) {
	pbox++; nbox--;
    }

    while(nbox && (Bottom >= pbox->y1)) {
	/* handle backing rect first */
	LeftEdge = max(Left, pbox->x1);
	RightEdge = min(Right, pbox->x2);
	if(RightEdge > LeftEdge) {	    
	    ytop = max(Top, pbox->y1);
	    ybot = min(Bottom, pbox->y2);

	    if(ybot > ytop) {
		if(!AlreadySetup) {
		   (*infoRec->SetupForSolidFill)(pScrn, bg, GXcopy, planemask);
		   AlreadySetup = TRUE;
		}
		(*infoRec->SubsequentSolidFillRect)(pScrn, 
			LeftEdge, ytop, RightEdge - LeftEdge, ybot - ytop);
	    }
	}
	nbox--; pbox++;
    }
 
    nbox = REGION_NUM_RECTS(cclip);
    pbox = REGION_RECTS(cclip);

    if(infoRec->WriteBitmap && (nglyph > 1) && 
			((FONTMAXBOUNDS(font, rightSideBearing) - 
          		FONTMINBOUNDS(font, leftSideBearing)) <= 32)) 
   {
	PolyGlyphBltAsSingleBitmap(pScrn, nglyph, font, 
				xInit, yInit, nbox, pbox,
				fg, GXcopy, planemask);

	return;
    }

    /* compute an approximate but covering bounding box */
    Left = xInit + infoRec->GlyphInfo[0].start;
    Right = xInit + infoRec->GlyphInfo[nglyph - 1].end;
    Top = yInit - FONTMAXBOUNDS(font,ascent);
    Bottom = yInit + FONTMAXBOUNDS(font,descent);

    /* get into the first band that may contain part of our box */
    while(nbox && (Top >= pbox->y2)) {
	pbox++; nbox--;
    }

    /* stop when the lower edge of the box is beyond our string */
    while(nbox && (Bottom >= pbox->y1)) {
	LeftEdge = max(Left, pbox->x1);
	RightEdge = min(Right, pbox->x2);

	if(RightEdge > LeftEdge) { /* we're possibly drawing something */
	    ytop = max(Top, pbox->y1);
	    ybot = min(Bottom, pbox->y2);
	    if(ybot > ytop) {
		skippix = LeftEdge - xInit;
		skipglyph = 0;
		while(skippix >= infoRec->GlyphInfo[skipglyph].end)
		   skipglyph++;

		skippix = RightEdge - xInit;
		n = 0; i = skipglyph;
		while((i < nglyph) && (skippix > infoRec->GlyphInfo[i].start)) {
		    i++; n++;
		}

		if(n) (*infoRec->NonTEGlyphRenderer)(pScrn,
			xInit, yInit, n, infoRec->GlyphInfo + skipglyph, 
			pbox, fg, GXcopy, planemask); 
	    }
	}

	nbox--; pbox++;
    }
}


static int
PolyGlyphBltNonTEColorExpansion(
   ScrnInfoPtr pScrn,
   int xInit, int yInit,
   FontPtr font,
   int fg, int rop,
   unsigned planemask,
   RegionPtr cclip,
   int nglyph,
   unsigned char* gBase,
   CharInfoPtr *ppci 
){
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
    int skippix, skipglyph, width, n, i;
    int Left, Right, Top, Bottom;
    int LeftEdge, RightEdge;
    int nbox = REGION_NUM_RECTS(cclip);
    BoxPtr pbox = REGION_RECTS(cclip);

    width = CollectCharacterInfo(infoRec->GlyphInfo, nglyph, ppci, font);

    if(!nbox)
	return width;

    if((infoRec->WriteBitmap) && (rop == GXcopy) && (nglyph > 1) &&
	((FONTMAXBOUNDS(font, rightSideBearing) - 
          FONTMINBOUNDS(font, leftSideBearing)) <= 32)) {

	 PolyGlyphBltAsSingleBitmap(pScrn, nglyph, font, 
				xInit, yInit, nbox, pbox,
				fg, rop, planemask);

	return width;
    }

    /* compute an approximate but covering bounding box */
    Left = xInit + infoRec->GlyphInfo[0].start;
    Right = xInit + infoRec->GlyphInfo[nglyph - 1].end;
    Top = yInit - FONTMAXBOUNDS(font,ascent);
    Bottom = yInit + FONTMAXBOUNDS(font,descent);

    /* get into the first band that may contain part of our string */
    while(nbox && (Top >= pbox->y2)) {
	pbox++; nbox--;
    }

    /* stop when the lower edge of the box is beyond our string */
    while(nbox && (Bottom >= pbox->y1)) {
	LeftEdge = max(Left, pbox->x1);
	RightEdge = min(Right, pbox->x2);

	if(RightEdge > LeftEdge) { /* we're possibly drawing something */

	    skippix = LeftEdge - xInit;
	    skipglyph = 0;
	    while(skippix >= infoRec->GlyphInfo[skipglyph].end)
		skipglyph++;

	    skippix = RightEdge - xInit;
	    n = 0; i = skipglyph;
	    while((i < nglyph) && (skippix > infoRec->GlyphInfo[i].start)) {
		i++; n++;
	    }

	    if(n) (*infoRec->NonTEGlyphRenderer)(pScrn,
			xInit, yInit, n, infoRec->GlyphInfo + skipglyph, 
			pbox, fg, rop, planemask); 
	}

	nbox--; pbox++;
    }
    return width;
}


/* It is possible that the none of the glyphs passed to the 
   NonTEGlyphRenderer will be drawn.  This function being called
   indicates that part of the text string's bounding box is visible
   but not necessarily that any of the characters are visible */

void XAANonTEGlyphRenderer(
   ScrnInfoPtr pScrn,
   int x, int y, int n,
   NonTEGlyphPtr glyphs,
   BoxPtr pbox,
   int fg, int rop,
   unsigned int planemask
){
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
    int x1, x2, y1, y2, i, w, h, skipleft, skiptop;
    unsigned char *src;

    for(i = 0; i < n; i++, glyphs++) {
	x1 = x + glyphs->start;
	x2 = x + glyphs->end;
	y1 = y - glyphs->yoff;
	y2 = y1 + glyphs->height;

	if(y1 < pbox->y1) {
	    skiptop = pbox->y1 - y1;
	    y1 = pbox->y1;
	} else skiptop = 0;
	if(y2 > pbox->y2) y2 = pbox->y2;
	h = y2 - y1;
	if(h <= 0) continue;

	if(x1 < pbox->x1) {
	    skipleft = pbox->x1 - x1;
	    x1 = pbox->x1;
	} else skipleft = 0;
	if(x2 > pbox->x2) x2 = pbox->x2;

	w = x2 - x1;

	if(w > 0) {
	    src = glyphs->bits + (skiptop * glyphs->srcwidth);

	    if(skipleft) {
		src += (skipleft >> 5) << 2;
		skipleft &= 31;
	    }

	    (*infoRec->WriteBitmap)(pScrn, x1, y1, w, h, src,
			glyphs->srcwidth, skipleft, fg, -1, rop, planemask);
	}
    }  

}

--- NEW FILE: xaaOffscreen.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaOffscreen.c,v 1.5 1999/07/04 06:39:17 dawes Exp $ */

/*
   Copyright (c) 1999 -  The XFree86 Project Inc.

   Written by Mark Vojkovich

*/ 

#include "misc.h"
#include "xf86.h"
#include "xf86_ansic.h"
#include "xf86_OSproc.h"

#include <X11/X.h>
#include "scrnintstr.h"
#include "pixmapstr.h"
#include "windowstr.h"
#include "xf86str.h"
#include "mi.h"
#include "miline.h"
#include "xaa.h"
#include "xaalocal.h"
#include "xaawrap.h"
#include "xf86fbman.h"
#include "servermd.h"

void
XAAMoveOutOffscreenPixmaps(ScreenPtr pScreen)
{
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
    PixmapLinkPtr pLink = infoRec->OffscreenPixmaps;
    XAAPixmapPtr pPriv;
    
    while(pLink) {
	pPriv = XAA_GET_PIXMAP_PRIVATE(pLink->pPix);
	pLink->area = pPriv->offscreenArea;
	XAAMoveOutOffscreenPixmap(pLink->pPix);	
	pLink = pLink->next;
    }    
}



void
XAAMoveInOffscreenPixmaps(ScreenPtr pScreen)
{
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
    PixmapLinkPtr pLink = infoRec->OffscreenPixmaps;
    PixmapPtr pPix, pScreenPix, tmpPix;
    pointer data;
    XAAPixmapPtr pPriv;
    GCPtr pGC;
    FBAreaPtr area;

    pScreenPix = (*pScreen->GetScreenPixmap)(pScreen);

    while(pLink) {
	pPix = pLink->pPix;
    	pPriv = XAA_GET_PIXMAP_PRIVATE(pPix);
	area = pLink->area;

	data = pPix->devPrivate.ptr;
	tmpPix = GetScratchPixmapHeader(pScreen, 
		pPix->drawable.width, pPix->drawable.height, 
		pPix->drawable.depth, pPix->drawable.bitsPerPixel, 
		pPix->devKind, data);

	pPriv->freeData = FALSE;

	pPix->drawable.x = area->box.x1;
	pPix->drawable.y = area->box.y1;
	pPix->devKind = pScreenPix->devKind;
	pPix->devPrivate.ptr = pScreenPix->devPrivate.ptr;
	pPix->drawable.bitsPerPixel = infoRec->pScrn->bitsPerPixel;
	pPix->drawable.serialNumber = NEXT_SERIAL_NUMBER;

	if(!tmpPix) {
	    pPriv->offscreenArea = area;
	    xfree(data);
	    pLink = pLink->next;
	    continue;
	}
	
	pGC = GetScratchGC(pPix->drawable.depth, pScreen);
	ValidateGC((DrawablePtr)pPix, pGC);

	(*pGC->ops->CopyArea)((DrawablePtr)tmpPix, (DrawablePtr)pPix, pGC, 
		0, 0, pPix->drawable.width, pPix->drawable.height, 0, 0);	

	xfree(data);
	tmpPix->devPrivate.ptr = NULL;

	FreeScratchGC(pGC);
	FreeScratchPixmapHeader(tmpPix);

	pPriv->offscreenArea = area;
	pLink->area = NULL;
	pLink = pLink->next;
    }    
}


void
XAARemoveAreaCallback(FBAreaPtr area)
{
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(area->pScreen);
    PixmapPtr pPix = (PixmapPtr)area->devPrivate.ptr;
    XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pPix);

    XAAMoveOutOffscreenPixmap(pPix);

    pPriv->flags &= ~OFFSCREEN;	

    DELIST_OFFSCREEN_PIXMAP(pPix);
}

void
XAAMoveOutOffscreenPixmap(PixmapPtr pPix) 
{
    ScreenPtr pScreen = pPix->drawable.pScreen;
    XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pPix);
    int width, height, devKind, bitsPerPixel;
    PixmapPtr tmpPix;
    unsigned char *data;
    GCPtr pGC;

    width = pPix->drawable.width;
    height = pPix->drawable.height;
    bitsPerPixel = pPix->drawable.bitsPerPixel;

    devKind = BitmapBytePad(width * bitsPerPixel);
    if(!(data = xalloc(devKind * height)))
	FatalError("Out of memory\n");

    tmpPix = GetScratchPixmapHeader(pScreen, width, height, 
		pPix->drawable.depth, bitsPerPixel, devKind, data);
    if(!tmpPix) {
	xfree(data);
	FatalError("Out of memory\n");
    }

    pGC = GetScratchGC(pPix->drawable.depth, pScreen);
    ValidateGC((DrawablePtr)tmpPix, pGC);

    (*pGC->ops->CopyArea)((DrawablePtr)pPix, (DrawablePtr)tmpPix,
		pGC, 0, 0, width, height, 0, 0);	

    FreeScratchGC(pGC);
    FreeScratchPixmapHeader(tmpPix);

    pPix->drawable.x = 0;
    pPix->drawable.y = 0;
    pPix->devKind = devKind;
    pPix->devPrivate.ptr = data;
    pPix->drawable.serialNumber = NEXT_SERIAL_NUMBER;

    pPriv->offscreenArea = NULL;
    pPriv->freeData = TRUE;
}

--- NEW FILE: xaaOverlay.c ---
/* $XdotOrg: xc/programs/Xserver/hw/xfree86/xaa/xaaOverlay.c,v 1.1.4.3.2.3 2004/03/04 20:16:48 kaleb Exp $ */
/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaOverlay.c,v 1.14tsi Exp $ */

#include "misc.h"
#include "xf86.h"
#include "xf86_ansic.h"
#include "xf86_OSproc.h"

#include <X11/X.h>
#include "scrnintstr.h"
#include "windowstr.h"
#include "xf86str.h"
#include "xaa.h"
#include "xaalocal.h"
#include "xaawrap.h"
#include "gcstruct.h"
#include "pixmapstr.h"
#include "mioverlay.h"

#ifdef PANORAMIX
#include "panoramiX.h"
#include "panoramiXsrv.h"
#endif

static void
XAACopyWindow8_32(
    WindowPtr pWin,
    DDXPointRec ptOldOrg,
    RegionPtr prgnSrc
){
    DDXPointPtr pptSrc, ppt;
    RegionRec rgnDst;
    BoxPtr pbox;
    int dx, dy, nbox;
    WindowPtr pwinRoot;
    ScreenPtr pScreen = pWin->drawable.pScreen;
    XAAInfoRecPtr infoRec = 
	GET_XAAINFORECPTR_FROM_DRAWABLE((&pWin->drawable));
    Bool doUnderlay = miOverlayCopyUnderlay(pScreen);
    RegionPtr borderClip = &pWin->borderClip;
    Bool freeReg = FALSE;

    if (!infoRec->pScrn->vtSema || !infoRec->ScreenToScreenBitBlt ||
	(infoRec->ScreenToScreenBitBltFlags & NO_PLANEMASK)) 
    { 
	XAA_SCREEN_PROLOGUE (pScreen, CopyWindow);
	if(infoRec->pScrn->vtSema && infoRec->NeedToSync) {
	    (*infoRec->Sync)(infoRec->pScrn);
	    infoRec->NeedToSync = FALSE;
	}
        (*pScreen->CopyWindow) (pWin, ptOldOrg, prgnSrc);
	XAA_SCREEN_EPILOGUE (pScreen, CopyWindow, XAACopyWindow8_32);
    	return;
    }

    pwinRoot = WindowTable[pScreen->myNum];

    if(doUnderlay)
	freeReg = miOverlayCollectUnderlayRegions(pWin, &borderClip);

    REGION_NULL(pScreen, &rgnDst);

    dx = ptOldOrg.x - pWin->drawable.x;
    dy = ptOldOrg.y - pWin->drawable.y;
    REGION_TRANSLATE(pScreen, prgnSrc, -dx, -dy);
    REGION_INTERSECT(pScreen, &rgnDst, borderClip, prgnSrc);

    pbox = REGION_RECTS(&rgnDst);
    nbox = REGION_NUM_RECTS(&rgnDst);
    if(!nbox || 
      !(pptSrc = (DDXPointPtr )ALLOCATE_LOCAL(nbox * sizeof(DDXPointRec)))) {
	REGION_UNINIT(pScreen, &rgnDst);
	return;
    }
    ppt = pptSrc;

    while(nbox--) {
	ppt->x = pbox->x1 + dx;
	ppt->y = pbox->y1 + dy;
	ppt++; pbox++;
    }
    
    infoRec->ScratchGC.planemask = doUnderlay ? 0x00ffffff : 0xff000000;
    infoRec->ScratchGC.alu = GXcopy;

    XAADoBitBlt((DrawablePtr)pwinRoot, (DrawablePtr)pwinRoot,
        		&(infoRec->ScratchGC), &rgnDst, pptSrc);

    DEALLOCATE_LOCAL(pptSrc);
    REGION_UNINIT(pScreen, &rgnDst);
    if(freeReg) 
	REGION_DESTROY(pScreen, borderClip);
}




static void
XAAPaintWindow8_32(
  WindowPtr pWin,
  RegionPtr prgn,
  int what 
){
    ScreenPtr  pScreen = pWin->drawable.pScreen;
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_DRAWABLE((&pWin->drawable));
    int nBox = REGION_NUM_RECTS(prgn);
    BoxPtr pBox = REGION_RECTS(prgn);
    PixmapPtr pPix = NULL;
    int depth = pWin->drawable.depth;
    int fg = 0, pm;

    if(!infoRec->pScrn->vtSema) goto BAILOUT;	

    switch (what) {
    case PW_BACKGROUND:
	switch(pWin->backgroundState) {
	case None: return;
	case ParentRelative:
	    do { pWin = pWin->parent; }
	    while(pWin->backgroundState == ParentRelative);
	    (*pWin->drawable.pScreen->PaintWindowBackground)(pWin, prgn, what);
	    return;
	case BackgroundPixel:
	    fg = pWin->background.pixel;
	    break;
	case BackgroundPixmap:
	    pPix = pWin->background.pixmap;
	    break;
	}
	break;
    case PW_BORDER:
	if (pWin->borderIsPixel) 
	    fg = pWin->border.pixel;
	else 	/* pixmap */ 
	    pPix = pWin->border.pixmap;
	break;
    default: return;
    }

    if(depth == 8) {
	pm = 0xff000000;
	fg <<= 24;
    } else
	pm = 0x00ffffff;

    if(!pPix) {	
        if(infoRec->FillSolidRects &&
           !(infoRec->FillSolidRectsFlags & NO_PLANEMASK) &&
           (!(infoRec->FillSolidRectsFlags & RGB_EQUAL) ||
			(depth == 8) || CHECK_RGB_EQUAL(fg)))  
	{
	    (*infoRec->FillSolidRects)(infoRec->pScrn, fg, GXcopy, 
						pm, nBox, pBox);
	    return;
	}
    } else {	/* pixmap */
        XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pPix);
	WindowPtr pBgWin = pWin;
	int xorg, yorg;

	if (what == PW_BORDER) {
	    for (pBgWin = pWin;
		 pBgWin->backgroundState == ParentRelative;
		 pBgWin = pBgWin->parent);
	}

        xorg = pBgWin->drawable.x;
        yorg = pBgWin->drawable.y;

#ifdef PANORAMIX
	if(!noPanoramiXExtension) {
	    int index = pScreen->myNum;
	    if(WindowTable[index] == pBgWin) {
		xorg -= panoramiXdataPtr[index].x;
		yorg -= panoramiXdataPtr[index].y;
	    }
	}
#endif

	if(IS_OFFSCREEN_PIXMAP(pPix) && infoRec->FillCacheBltRects) {
	    XAACacheInfoPtr pCache = &(infoRec->ScratchCacheInfoRec);

	    pCache->x = pPriv->offscreenArea->box.x1;
	    pCache->y = pPriv->offscreenArea->box.y1;
	    pCache->w = pCache->orig_w = 
		pPriv->offscreenArea->box.x2 - pCache->x;
	    pCache->h = pCache->orig_h = 
		pPriv->offscreenArea->box.y2 - pCache->y;
	    pCache->trans_color = -1;
	     
	    (*infoRec->FillCacheBltRects)(infoRec->pScrn, GXcopy, pm,
				nBox, pBox, xorg, yorg, pCache);

	    return;
	}

	if(pPriv->flags & DIRTY) {
	    pPriv->flags &= ~(DIRTY | REDUCIBILITY_MASK);
	    pPix->drawable.serialNumber = NEXT_SERIAL_NUMBER;
        }

    	if(!(pPriv->flags & REDUCIBILITY_CHECKED) &&
	    (infoRec->CanDoMono8x8 || infoRec->CanDoColor8x8)) {
	    XAACheckTileReducibility(pPix, infoRec->CanDoMono8x8);
	}

	if(pPriv->flags & REDUCIBLE_TO_8x8) {
	    if((pPriv->flags & REDUCIBLE_TO_2_COLOR) &&
		infoRec->CanDoMono8x8 && infoRec->FillMono8x8PatternRects &&
		!(infoRec->FillMono8x8PatternRectsFlags & NO_PLANEMASK) &&
		!(infoRec->FillMono8x8PatternRectsFlags & TRANSPARENCY_ONLY) && 
		(!(infoRec->FillMono8x8PatternRectsFlags & RGB_EQUAL) || 
		(CHECK_RGB_EQUAL(pPriv->fg) && CHECK_RGB_EQUAL(pPriv->bg)))) 
	    {
		(*infoRec->FillMono8x8PatternRects)(infoRec->pScrn,
			pPriv->fg, pPriv->bg, GXcopy, pm, nBox, pBox,
			pPriv->pattern0, pPriv->pattern1, xorg, yorg);
		return;
	    }
	    if(infoRec->CanDoColor8x8 && infoRec->FillColor8x8PatternRects &&
		!(infoRec->FillColor8x8PatternRectsFlags & NO_PLANEMASK)) 
	    {
		XAACacheInfoPtr pCache = (*infoRec->CacheColor8x8Pattern)(
					infoRec->pScrn, pPix, -1, -1);

		(*infoRec->FillColor8x8PatternRects) (infoRec->pScrn, 
			GXcopy, pm, nBox, pBox, xorg, yorg, pCache);
		return;
	    }        
	}

	if(infoRec->UsingPixmapCache && infoRec->FillCacheBltRects && 
	    !(infoRec->FillCacheBltRectsFlags & NO_PLANEMASK) && 
	    (pPix->drawable.height <= infoRec->MaxCacheableTileHeight) &&
	    (pPix->drawable.width <= infoRec->MaxCacheableTileWidth)) 
	{
	     XAACacheInfoPtr pCache = 
			(*infoRec->CacheTile)(infoRec->pScrn, pPix);
	     (*infoRec->FillCacheBltRects)(infoRec->pScrn, GXcopy, pm,
				nBox, pBox, xorg, yorg, pCache);
	     return;
	}

	if(infoRec->FillImageWriteRects && 
		!(infoRec->FillImageWriteRectsFlags & NO_PLANEMASK)) 
	{
	    (*infoRec->FillImageWriteRects) (infoRec->pScrn, GXcopy, 
			pm, nBox, pBox, xorg, yorg, pPix);
	    return;
	}
    }

    if(infoRec->NeedToSync) {
	(*infoRec->Sync)(infoRec->pScrn);
	infoRec->NeedToSync = FALSE;
    }

BAILOUT:

    if(what == PW_BACKGROUND) {
	XAA_SCREEN_PROLOGUE (pScreen, PaintWindowBackground);
	(*pScreen->PaintWindowBackground) (pWin, prgn, what);
	XAA_SCREEN_EPILOGUE(pScreen, PaintWindowBackground, XAAPaintWindow8_32);
    } else {
	XAA_SCREEN_PROLOGUE (pScreen, PaintWindowBorder);
	(*pScreen->PaintWindowBorder) (pWin, prgn, what);
	XAA_SCREEN_EPILOGUE(pScreen, PaintWindowBorder, XAAPaintWindow8_32);
    }
}


static void
XAASetColorKey8_32(
    ScreenPtr pScreen,
    int nbox,
    BoxPtr pbox
){
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
    ScrnInfoPtr pScrn = infoRec->pScrn;

    /* I'm counting on writes being clipped away while switched away.
       If this isn't going to be true then I need to be wrapping instead. */
    if(!infoRec->pScrn->vtSema) return;

    (*infoRec->FillSolidRects)(pScrn, pScrn->colorKey << 24, GXcopy, 
					0xff000000, nbox, pbox);
  
    SET_SYNC_FLAG(infoRec);
}

void 
XAASetupOverlay8_32Planar(ScreenPtr pScreen)
{
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
    int i;

    pScreen->PaintWindowBackground = XAAPaintWindow8_32;
    pScreen->PaintWindowBorder = XAAPaintWindow8_32;
    pScreen->CopyWindow = XAACopyWindow8_32;

    if(!(infoRec->FillSolidRectsFlags & NO_PLANEMASK))
	miOverlaySetTransFunction(pScreen, XAASetColorKey8_32);

    infoRec->FullPlanemask = ~0;
    for(i = 0; i < 32; i++) /* haven't thought about this much */
	infoRec->FullPlanemasks[i] = ~0;
}

--- NEW FILE: xaaOverlayDF.c ---
/*
   Copyright (c) 1999 - The XFree86 Project Inc.

   Written by Mark Vojkovich
*/
/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaOverlayDF.c,v 1.1tsi Exp $ */


#include "misc.h"
#include "xf86.h"
#include "xf86_ansic.h"
#include "xf86_OSproc.h"

#include <X11/X.h>
#include "scrnintstr.h"
#include "pixmapstr.h"
#include "windowstr.h"
#include "xf86str.h"
#include "mi.h"
[...1115 lines suppressed...]
XAAOverPutImage(
   DrawablePtr	pDraw,
   GCPtr	pGC,
   int		depth, 
   int		x, 
   int		y, 
   int		w, 
   int		h,
   int		leftPad,
   int		format,
   char		*pImage
){
    XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);

    SWITCH_DEPTH(pGC->depth);

    (*pOverPriv->PutImage)(pDraw, pGC, depth, x, y, w, h, 
				leftPad, format, pImage);
}


--- NEW FILE: xaaPCache.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaPCache.c,v 1.32tsi Exp $ */

#include "misc.h"
#include "xf86.h"
#include "xf86_ansic.h"
#include "xf86_OSproc.h"

#include <X11/X.h>
#include "scrnintstr.h"
#include "gc.h"
#include "mi.h"
#include "pixmapstr.h"
#include "windowstr.h"
#include "regionstr.h"
#include "servermd.h"
#include "xf86str.h"
#include "xaa.h"
#include "xaacexp.h"
#include "xaalocal.h"
[...2333 lines suppressed...]
   XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
   XAAPixmapCachePrivatePtr pCachePriv = 
	(XAAPixmapCachePrivatePtr)infoRec->PixmapCachePrivate;
   int i;

   if(!pCachePriv) return;

   for(i = 0; i < pCachePriv->Num512x512; i++) 
	(pCachePriv->Info512)[i].serialNumber = 0;
   for(i = 0; i < pCachePriv->Num256x256; i++) 
	(pCachePriv->Info256)[i].serialNumber = 0;
   for(i = 0; i < pCachePriv->Num128x128; i++) 
	(pCachePriv->Info128)[i].serialNumber = 0;
   for(i = 0; i < pCachePriv->NumPartial; i++) 
	(pCachePriv->InfoPartial)[i].serialNumber = 0;
   for(i = 0; i < pCachePriv->NumMono; i++) 
	(pCachePriv->InfoMono)[i].serialNumber = 0;
   for(i = 0; i < pCachePriv->NumColor; i++) 
	(pCachePriv->InfoColor)[i].serialNumber = 0;
}

--- NEW FILE: xaaPaintWin.c ---
/* $XdotOrg: xc/programs/Xserver/hw/xfree86/xaa/xaaPaintWin.c,v 1.1.4.2.2.3 2004/03/04 20:16:48 kaleb Exp $ */
/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaPaintWin.c,v 1.10 2001/10/28 03:34:04 tsi Exp $ */

#include "misc.h"
#include "xf86.h"
#include "xf86_ansic.h"
#include "xf86_OSproc.h"

#include <X11/X.h>
#include "scrnintstr.h"
#include "windowstr.h"
#include "xf86str.h"
#include "xaa.h"
#include "xaalocal.h"
#include "gcstruct.h"
#include "pixmapstr.h"
#include "xaawrap.h"

#ifdef PANORAMIX
#include "panoramiX.h"
#include "panoramiXsrv.h"
#endif

void
XAAPaintWindow(
  WindowPtr pWin,
  RegionPtr prgn,
  int what 
)
{
    ScreenPtr  pScreen = pWin->drawable.pScreen;
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_DRAWABLE((&pWin->drawable));
    int nBox = REGION_NUM_RECTS(prgn);
    BoxPtr pBox = REGION_RECTS(prgn);
    int fg = -1;
    PixmapPtr pPix = NULL;

    if(!infoRec->pScrn->vtSema) goto BAILOUT;	

    switch (what) {
    case PW_BACKGROUND:
	switch(pWin->backgroundState) {
	case None: return;
	case ParentRelative:
	    do { pWin = pWin->parent; }
	    while(pWin->backgroundState == ParentRelative);
	    (*pWin->drawable.pScreen->PaintWindowBackground)(pWin, prgn, what);
	    return;
	case BackgroundPixel:
	    fg = pWin->background.pixel;
	    break;
	case BackgroundPixmap:
	    pPix = pWin->background.pixmap;
	    break;
	}
	break;
    case PW_BORDER:
	if (pWin->borderIsPixel) 
	    fg = pWin->border.pixel;
	else 	/* pixmap */ 
	    pPix = pWin->border.pixmap;
	break;
    default: return;
    }


    if(!pPix) {
        if(infoRec->FillSolidRects &&
           (!(infoRec->FillSolidRectsFlags & RGB_EQUAL) || 
                (CHECK_RGB_EQUAL(fg))) )  {
	    (*infoRec->FillSolidRects)(infoRec->pScrn, fg, GXcopy, ~0,
					nBox, pBox);
	    return;
	}
    } else {	/* pixmap */
        XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pPix);
	WindowPtr pBgWin = pWin;
	Bool NoCache = FALSE;
	int xorg, yorg;

	/* Hack so we can use this with the dual framebuffer layers
	   which only support the pixmap cache in the primary bpp */
	if(pPix->drawable.bitsPerPixel != infoRec->pScrn->bitsPerPixel)
	    NoCache = TRUE;

	if (what == PW_BORDER) {
	    for (pBgWin = pWin;
		 pBgWin->backgroundState == ParentRelative;
		 pBgWin = pBgWin->parent);
	}

        xorg = pBgWin->drawable.x;
        yorg = pBgWin->drawable.y;

#ifdef PANORAMIX
	if(!noPanoramiXExtension) {
	    int index = pScreen->myNum;
	    if(WindowTable[index] == pBgWin) {
		xorg -= panoramiXdataPtr[index].x;
		yorg -= panoramiXdataPtr[index].y;
	    }
	}
#endif

	if(IS_OFFSCREEN_PIXMAP(pPix) && infoRec->FillCacheBltRects) {
	    XAACacheInfoPtr pCache = &(infoRec->ScratchCacheInfoRec);

	    pCache->x = pPriv->offscreenArea->box.x1;
	    pCache->y = pPriv->offscreenArea->box.y1;
	    pCache->w = pCache->orig_w = 
		pPriv->offscreenArea->box.x2 - pCache->x;
	    pCache->h = pCache->orig_h = 
		pPriv->offscreenArea->box.y2 - pCache->y;
	    pCache->trans_color = -1;
	     
	    (*infoRec->FillCacheBltRects)(infoRec->pScrn, GXcopy, ~0,
				nBox, pBox, xorg, yorg, pCache);
	    return;
	}

	if(pPriv->flags & DIRTY) {
	    pPriv->flags &= ~(DIRTY | REDUCIBILITY_MASK);
	    pPix->drawable.serialNumber = NEXT_SERIAL_NUMBER;
        }

    	if(!(pPriv->flags & REDUCIBILITY_CHECKED) &&
	    (infoRec->CanDoMono8x8 || infoRec->CanDoColor8x8)) {
	    XAACheckTileReducibility(pPix, infoRec->CanDoMono8x8);
	}

	if(pPriv->flags & REDUCIBLE_TO_8x8) {
	    if((pPriv->flags & REDUCIBLE_TO_2_COLOR) &&
		infoRec->CanDoMono8x8 && infoRec->FillMono8x8PatternRects &&
		!(infoRec->FillMono8x8PatternRectsFlags & TRANSPARENCY_ONLY) && 
		(!(infoRec->FillMono8x8PatternRectsFlags & RGB_EQUAL) || 
		(CHECK_RGB_EQUAL(pPriv->fg) && CHECK_RGB_EQUAL(pPriv->bg)))) {

	    	(*infoRec->FillMono8x8PatternRects)(infoRec->pScrn,
			pPriv->fg, pPriv->bg, GXcopy, ~0, nBox, pBox,
			pPriv->pattern0, pPriv->pattern1, xorg, yorg);
		return;
	    }
	    if(infoRec->CanDoColor8x8 && !NoCache &&
				infoRec->FillColor8x8PatternRects) {
		XAACacheInfoPtr pCache = (*infoRec->CacheColor8x8Pattern)(
					infoRec->pScrn, pPix, -1, -1);

		(*infoRec->FillColor8x8PatternRects) ( infoRec->pScrn, 
				GXcopy, ~0, nBox, pBox, xorg, yorg, pCache);
		return;
	    }        
	}

	/* The window size check is to reduce pixmap cache thrashing
	   when there are lots of little windows with pixmap backgrounds
	   like are sometimes used for buttons, etc... */

	if(infoRec->UsingPixmapCache && 
	    infoRec->FillCacheBltRects && !NoCache &&
	    ((what == PW_BORDER) ||
		(pPix->drawable.height != pWin->drawable.height) ||
		(pPix->drawable.width != pWin->drawable.width)) &&
	    (pPix->drawable.height <= infoRec->MaxCacheableTileHeight) &&
	    (pPix->drawable.width <= infoRec->MaxCacheableTileWidth)) {

	     XAACacheInfoPtr pCache = 
			(*infoRec->CacheTile)(infoRec->pScrn, pPix);
	     (*infoRec->FillCacheBltRects)(infoRec->pScrn, GXcopy, ~0,
					nBox, pBox, xorg, yorg, pCache);
	     return;
	}

	if(infoRec->FillImageWriteRects && 
		!(infoRec->FillImageWriteRectsFlags & NO_GXCOPY)) {
	    (*infoRec->FillImageWriteRects) (infoRec->pScrn, GXcopy, 
                   		~0, nBox, pBox, xorg, yorg, pPix);
	    return;
	}
    }


    if(infoRec->NeedToSync) {
	(*infoRec->Sync)(infoRec->pScrn);
	infoRec->NeedToSync = FALSE;
    }

BAILOUT:

    if(what == PW_BACKGROUND) {
	XAA_SCREEN_PROLOGUE (pScreen, PaintWindowBackground);
	(*pScreen->PaintWindowBackground) (pWin, prgn, what);
	XAA_SCREEN_EPILOGUE(pScreen, PaintWindowBackground, XAAPaintWindow);
    } else {
	XAA_SCREEN_PROLOGUE (pScreen, PaintWindowBorder);
	(*pScreen->PaintWindowBorder) (pWin, prgn, what);
	XAA_SCREEN_EPILOGUE(pScreen, PaintWindowBorder, XAAPaintWindow);
    }

}

--- NEW FILE: xaaPict.c ---
(This appears to be a binary file; contents omitted.)

--- NEW FILE: xaaROP.c ---
/* $XFree86$ */

#include <X11/X.h>
#include "misc.h"
#include "xf86.h"
#include "xf86_ansic.h"
#include "xf86_OSproc.h"

#include "scrnintstr.h"
#include "xf86str.h"
#include "xaarop.h"
#include "xaa.h"
#include "xaalocal.h"


int XAACopyROP[16] =
{
   ROP_0,               /* GXclear */
   ROP_DSa,             /* GXand */
   ROP_SDna,            /* GXandReverse */
   ROP_S,               /* GXcopy */
   ROP_DSna,            /* GXandInverted */
   ROP_D,               /* GXnoop */
   ROP_DSx,             /* GXxor */
   ROP_DSo,             /* GXor */
   ROP_DSon,            /* GXnor */
   ROP_DSxn,            /* GXequiv */
   ROP_Dn,              /* GXinvert*/
   ROP_SDno,            /* GXorReverse */
   ROP_Sn,              /* GXcopyInverted */
   ROP_DSno,            /* GXorInverted */
   ROP_DSan,            /* GXnand */
   ROP_1                /* GXset */
};

int XAACopyROP_PM[16] =
{
   ROP_0,		/* not used */
   ROP_DSPnoa,
   ROP_DPSnaon,
   ROP_DPSDxax,
   ROP_DPSana,
   ROP_D,		/* not used */
   ROP_DPSax,
   ROP_DPSao,
   ROP_DPSaon,
   ROP_DPSaxn,
   ROP_Dn,		/* not used */
   ROP_DPSanan,
   ROP_PSDPxox,		/* is that correct ? */
   ROP_DPSnao,
   ROP_DSPnoan,
   ROP_1		/* not used */
};


int XAAPatternROP[16]=
{
   ROP_0,
   ROP_DPa,
   ROP_PDna,
   ROP_P,
   ROP_DPna,
   ROP_D,
   ROP_DPx,
   ROP_DPo,
   ROP_DPon,
   ROP_PDxn,
   ROP_Dn,
   ROP_PDno,
   ROP_Pn,
   ROP_DPno,
   ROP_DPan,
   ROP_1
};

int XAAPatternROP_PM[16] =
{
   ROP_DPna,
   ROP_DPSnoa,
   ROP_DSPnaon,
   ROP_DSPDxax,
   ROP_DPSana,
   ROP_D,
   ROP_DPSax,
   ROP_DPSao,
   ROP_DPSaon,
   ROP_DPSaxn,
   ROP_DPx,
   ROP_DPSanan, 
   ROP_SPDSxox,		/* is that correct ? */
   ROP_DSPnao,
   ROP_DPSnoan,
   ROP_DPo
};


int
XAAHelpPatternROP(ScrnInfoPtr pScrn, int *fg, int *bg, int pm, int *rop)
{
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
    int ret = 0;
    
    pm &= infoRec->FullPlanemasks[pScrn->depth - 1];

    if(pm == infoRec->FullPlanemasks[pScrn->depth - 1]) {
	if(!NO_SRC_ROP(*rop)) 
	   ret |= ROP_PAT;
	*rop = XAAPatternROP[*rop];
    } else {	
	switch(*rop) {
	case GXnoop:
	    break;
	case GXset:
	case GXclear:
	case GXinvert:
	    ret |= ROP_PAT;
	    *fg = pm;
	    if(*bg != -1)
		*bg = pm;
	    break;
	default:
	    ret |= ROP_PAT | ROP_SRC;
	    break;
	}
	*rop = XAAPatternROP_PM[*rop];
    }

    return ret;
}


int
XAAHelpSolidROP(ScrnInfoPtr pScrn, int *fg, int pm, int *rop)
{
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
    int ret = 0;
    
    pm &= infoRec->FullPlanemasks[pScrn->depth - 1];

    if(pm == infoRec->FullPlanemasks[pScrn->depth - 1]) {
	if(!NO_SRC_ROP(*rop)) 
	   ret |= ROP_PAT;
	*rop = XAAPatternROP[*rop];
    } else {	
	switch(*rop) {
	case GXnoop:
	    break;
	case GXset:
	case GXclear:
	case GXinvert:
	    ret |= ROP_PAT;
	    *fg = pm;
	    break;
	default:
	    ret |= ROP_PAT | ROP_SRC;
	    break;
	}
	*rop = XAAPatternROP_PM[*rop];
    }

    return ret;
}


--- NEW FILE: xaaRect.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaRect.c,v 1.2 1998/07/25 16:58:51 dawes Exp $ */

#include "misc.h"
#include "xf86.h"
#include "xf86_ansic.h"
#include "xf86_OSproc.h"

#include <X11/X.h>
#include "scrnintstr.h"
#include "pixmapstr.h"
#include "xf86str.h"
#include "xaa.h"
#include "xaalocal.h"

/*
   Much of this file based on code by 
	Harm Hanemaayer (H.Hanemaayer at inter.nl.net).
*/


void
XAAPolyRectangleThinSolid(
    DrawablePtr  pDrawable,
    GCPtr        pGC,    
    int	         nRectsInit,
    xRectangle  *pRectsInit )
{
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
    int         nClipRects;     /* number of clip rectangles */
    BoxPtr      pClipRects;     /* points to the list of clip rects */
    int         xOrigin;        /* Drawables x origin */
    int         yOrigin;        /* Drawables x origin */
    xRectangle *pRect;          /* list of rects */
    int         nRects;         /* running count of number of rects */
    int         origX1, origY1; /* original rectangle's U/L corner */
    int         origX2, origY2; /* original rectangle's L/R corner */
    int         clippedX1;      /* clipped rectangle's left x */
    int         clippedY1;      /* clipped rectangle's top y */
    int         clippedX2;      /* clipped rectangle's right x */
    int         clippedY2;      /* clipped rectangle's bottom y */
    int         clipXMin;       /* upper left corner of clip rect */
    int         clipYMin;       /* upper left corner of clip rect */
    int         clipXMax;       /* lower right corner of clip rect */
    int         clipYMax;       /* lower right corner of clip rect */
    int         width, height;  /* width and height of rect */

    nClipRects = REGION_NUM_RECTS(pGC->pCompositeClip);
    pClipRects = REGION_RECTS(pGC->pCompositeClip);

    if(!nClipRects) return;

    xOrigin = pDrawable->x;
    yOrigin = pDrawable->y;


    (*infoRec->SetupForSolidLine)(infoRec->pScrn, 
			pGC->fgPixel, pGC->alu, pGC->planemask);


    for ( ; nClipRects > 0; 
	  nClipRects--, pClipRects++ )
    {
        clipYMin = pClipRects->y1;
        clipYMax = pClipRects->y2 - 1;
        clipXMin = pClipRects->x1;
        clipXMax = pClipRects->x2 - 1;

	for (pRect = pRectsInit, nRects = nRectsInit; 
	     nRects > 0; 
	     nRects--, pRect++ )
        {
	    /* translate rectangle data over to the drawable */
            origX1 = pRect->x + xOrigin; 
	    origY1 = pRect->y + yOrigin;
            origX2 = origX1 + pRect->width; 
	    origY2 = origY1 + pRect->height; 

	    /* reject entire rectangle if completely outside clip rect */
	    if ((origX1 > clipXMax) || (origX2 < clipXMin) ||
		(origY1 > clipYMax) || (origY2 < clipYMin))
	        continue;

	    /* clip the rectangle */
	    clippedX1 = max (origX1, clipXMin);
	    clippedX2 = min (origX2, clipXMax);
	    clippedY1 = max (origY1, clipYMin);
	    clippedY2 = min (origY2, clipYMax);

	    width = clippedX2 - clippedX1 + 1;

	    if (origY1 >= clipYMin) {
		(*infoRec->SubsequentSolidHorVertLine)(infoRec->pScrn,
			clippedX1, clippedY1, width, DEGREES_0);

		/* don't overwrite corner */
		clippedY1++;
	    }

	    if ((origY2 <= clipYMax) && (origY1 != origY2)) {
		(*infoRec->SubsequentSolidHorVertLine)(infoRec->pScrn,
			clippedX1, clippedY2, width, DEGREES_0);

		/* don't overwrite corner */
		clippedY2--; 
	    }

	    if (clippedY2 < clippedY1) continue;

	    height = clippedY2 - clippedY1 + 1;

	    /* draw vertical edges using lines if not clipped out */
            if (origX1 >= clipXMin) 
		(*infoRec->SubsequentSolidHorVertLine)(infoRec->pScrn,
			clippedX1, clippedY1, height, DEGREES_270);

            if ((origX2 <= clipXMax) && (origX2 != origX1))
		(*infoRec->SubsequentSolidHorVertLine)(infoRec->pScrn,
			clippedX2, clippedY1, height, DEGREES_270);
	}
    }

    SET_SYNC_FLAG(infoRec);
} 












--- NEW FILE: xaaSpans.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaSpans.c,v 1.14 2000/03/28 01:21:05 mvojkovi Exp $ */

#include "misc.h"
#include "xf86.h"
#include "xf86_ansic.h"
#include "xf86_OSproc.h"

#include <X11/X.h>
#include "scrnintstr.h"
#include "pixmapstr.h"
#include "xf86str.h"
#include "mi.h"
#include "mispans.h"
#include "xaa.h"
#include "xaalocal.h"


static void XAARenderSolidSpans(
	GCPtr, int, DDXPointPtr, int*, int, int, int);
static void XAARenderColor8x8Spans(
	GCPtr, int, DDXPointPtr, int*, int, int, int);
static void XAARenderMono8x8Spans(
	GCPtr, int, DDXPointPtr, int*, int, int, int);
static void XAARenderCacheBltSpans(
	GCPtr, int, DDXPointPtr, int*, int, int, int);
static void XAARenderColorExpandSpans(
	GCPtr, int, DDXPointPtr, int*, int, int, int);
static void XAARenderCacheExpandSpans(
	GCPtr, int, DDXPointPtr, int*, int, int, int);
static void XAARenderPixmapCopySpans(
	GCPtr, int, DDXPointPtr, int*, int, int, int);

void
XAAFillSpans(
    DrawablePtr pDraw,
    GC		*pGC,
    int		nInit,		/* number of spans to fill */
    DDXPointPtr pptInit,	/* pointer to list of start points */
    int *pwidthInit,		/* pointer to list of n widths */
    int fSorted 
){
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
    int type = 0;
    ClipAndRenderSpansFunc function;
    Bool fastClip = FALSE;

    if((nInit <= 0) || !pGC->planemask)
        return;

    if(!REGION_NUM_RECTS(pGC->pCompositeClip))
	return;

    switch(pGC->fillStyle) {
    case FillSolid:
	type = DO_SOLID;
	break;
    case FillStippled:
	type = (*infoRec->StippledFillChooser)(pGC);
	break;
    case FillOpaqueStippled:
	if((pGC->fgPixel == pGC->bgPixel) && infoRec->FillSpansSolid &&
                CHECK_PLANEMASK(pGC,infoRec->FillSpansSolidFlags) &&
                CHECK_ROP(pGC,infoRec->FillSpansSolidFlags) &&
                CHECK_ROPSRC(pGC,infoRec->FillSpansSolidFlags) &&
                CHECK_FG(pGC,infoRec->FillSpansSolidFlags))
	    type = DO_SOLID;
	else
	    type = (*infoRec->OpaqueStippledFillChooser)(pGC);
	break;
    case FillTiled:
	type = (*infoRec->TiledFillChooser)(pGC);
	break;
    }

    switch(type) {
    case DO_SOLID:
	function = XAARenderSolidSpans;	
	if(infoRec->ClippingFlags & HARDWARE_CLIP_SOLID_FILL) 
		fastClip = TRUE; 
	break;	
    case DO_COLOR_8x8:
	function = XAARenderColor8x8Spans;	
	if(infoRec->ClippingFlags & HARDWARE_CLIP_COLOR_8x8_FILL) 
		fastClip = TRUE; 
	break;	
    case DO_MONO_8x8:
	function = XAARenderMono8x8Spans;	
	if(infoRec->ClippingFlags & HARDWARE_CLIP_MONO_8x8_FILL) 
		fastClip = TRUE; 
	break;	
    case DO_CACHE_BLT:
	function = XAARenderCacheBltSpans;	
	if(infoRec->ClippingFlags & HARDWARE_CLIP_SCREEN_TO_SCREEN_COPY)
		fastClip = TRUE; 
	break;	
    case DO_COLOR_EXPAND:
	function = XAARenderColorExpandSpans;	
	break;	
    case DO_CACHE_EXPAND:
	function = XAARenderCacheExpandSpans;	
	if(infoRec->ClippingFlags & 
			HARDWARE_CLIP_SCREEN_TO_SCREEN_COLOR_EXPAND) 
		fastClip = TRUE; 
	break;	
    case DO_PIXMAP_COPY:
	function = XAARenderPixmapCopySpans;	
	if(infoRec->ClippingFlags & HARDWARE_CLIP_SCREEN_TO_SCREEN_COPY)
		fastClip = TRUE; 
	break;	
    case DO_IMAGE_WRITE:
    default:
	(*XAAFallbackOps.FillSpans)(pDraw, pGC, nInit, pptInit,
				pwidthInit, fSorted);
	return;
    }


    if((nInit < 10) || (REGION_NUM_RECTS(pGC->pCompositeClip) != 1))
	fastClip = FALSE;

    if(fastClip) {
	infoRec->ClipBox = &pGC->pCompositeClip->extents;
	(*function)(pGC, nInit, pptInit, pwidthInit, fSorted, 
					pDraw->x, pDraw->y);
	infoRec->ClipBox = NULL;
    } else
	XAAClipAndRenderSpans(pGC, pptInit, pwidthInit, nInit, fSorted,
					function, pDraw->x, pDraw->y);
}


	/*********************\
	|     Solid Spans     |
	\*********************/


static void
XAARenderSolidSpans(
    GCPtr pGC,
    int	n,
    DDXPointPtr ppt,
    int *pwidth,
    int fSorted,
    int xorg, int yorg 
){
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);

    (*infoRec->FillSolidSpans) (infoRec->pScrn, pGC->fgPixel, 
		pGC->alu, pGC->planemask, n, ppt, pwidth, fSorted);    
}


	/************************\
	|     Mono 8x8 Spans     |
	\************************/


static void
XAARenderMono8x8Spans(
    GCPtr pGC,
    int	n,
    DDXPointPtr ppt,
    int *pwidth,
    int fSorted,
    int xorg, int yorg 
){
   XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
   XAAPixmapPtr pPriv;
   int fg, bg;

   switch(pGC->fillStyle) {
   case FillStippled:
      pPriv = XAA_GET_PIXMAP_PRIVATE(pGC->stipple);
      fg = pGC->fgPixel;  bg = -1;
      break;
   case FillOpaqueStippled:
      pPriv = XAA_GET_PIXMAP_PRIVATE(pGC->stipple);
      fg = pGC->fgPixel;  bg = pGC->bgPixel;
      break;
   case FillTiled:
      pPriv = XAA_GET_PIXMAP_PRIVATE(pGC->tile.pixmap);
      fg = pPriv->fg;  bg = pPriv->bg;
      break;
   default:	/* Muffle compiler */
      pPriv = NULL;	/* Kaboom */
      fg = -1;  bg = -1;
      break;
   }

   (*infoRec->FillMono8x8PatternSpans) (infoRec->pScrn, 
                fg, bg, pGC->alu, pGC->planemask, 
                n, ppt, pwidth, fSorted, pPriv->pattern0, pPriv->pattern1, 
                (xorg + pGC->patOrg.x), (yorg + pGC->patOrg.y));	  
}


	/*************************\
	|     Color 8x8 Spans     |
	\*************************/


static void
XAARenderColor8x8Spans(
    GCPtr pGC,
    int	n,
    DDXPointPtr ppt,
    int *pwidth,
    int fSorted,
    int xorg, int yorg 
){
   XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
   XAACacheInfoPtr pCache;
   PixmapPtr pPix;
   int fg, bg;

   switch(pGC->fillStyle) {
   case FillStippled:
      pPix = pGC->stipple;
      fg = pGC->fgPixel;  bg = -1;
      break;
   case FillOpaqueStippled:
      pPix = pGC->stipple;
      fg = pGC->fgPixel;  bg = pGC->bgPixel;
      break;
   case FillTiled:
      pPix = pGC->tile.pixmap;
      fg = -1;  bg = -1;
      break;
   default:	/* Muffle compiler */
      pPix = NULL;
      fg = -1;  bg = -1;
      break;
   }

   pCache = (*infoRec->CacheColor8x8Pattern)(infoRec->pScrn, pPix, fg, bg);

   (*infoRec->FillColor8x8PatternSpans) (infoRec->pScrn, 
                pGC->alu, pGC->planemask, n, ppt, pwidth, fSorted, pCache,
                (yorg + pGC->patOrg.x), (xorg + pGC->patOrg.y));
}


	/****************************\
	|     Color Expand Spans     |
	\****************************/


static void
XAARenderColorExpandSpans(
    GCPtr pGC,
    int	n,
    DDXPointPtr ppt,
    int *pwidth,
    int fSorted,
    int xorg, int yorg 
){
   XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
   int fg, bg;

   switch(pGC->fillStyle) {
   case FillStippled:
      fg = pGC->fgPixel;  bg = -1;
      break;
   case FillOpaqueStippled:
      fg = pGC->fgPixel;  bg = pGC->bgPixel;
      break;
   default:	/* Muffle compiler */
      fg = -1;  bg = -1;
      break;
   }

   (*infoRec->FillColorExpandSpans) (infoRec->pScrn, fg, bg,
                pGC->alu, pGC->planemask, n, ppt, pwidth, fSorted,
                (xorg + pGC->patOrg.x), (yorg + pGC->patOrg.y),
                pGC->stipple); 

}


	/*************************\
	|     Cache Blt Spans     |
	\*************************/


static void
XAARenderCacheBltSpans(
    GCPtr pGC,
    int	n,
    DDXPointPtr ppt,
    int *pwidth,
    int fSorted,
    int xorg, int yorg 
){
   XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
   XAACacheInfoPtr pCache;

   switch(pGC->fillStyle) {
   case FillStippled:
      pCache = (*infoRec->CacheStipple)(infoRec->pScrn, pGC->stipple, 
					pGC->fgPixel, -1);
      break;
   case FillOpaqueStippled:
      pCache = (*infoRec->CacheStipple)(infoRec->pScrn, pGC->stipple, 
					pGC->fgPixel, pGC->bgPixel);
      break;
   case FillTiled:
      pCache = (*infoRec->CacheTile)(infoRec->pScrn, pGC->tile.pixmap);
      break;
   default:	/* Muffle compiler */
      pCache = NULL;
      break;
   }

   (*infoRec->FillCacheBltSpans) (infoRec->pScrn, 
                pGC->alu, pGC->planemask, n, ppt, pwidth, fSorted, pCache, 
                (xorg + pGC->patOrg.x), (yorg + pGC->patOrg.y));

}


	/****************************\
	|     Cache Expand Spans     |
	\****************************/


static void
XAARenderCacheExpandSpans(
    GCPtr pGC,
    int	n,
    DDXPointPtr ppt,
    int *pwidth,
    int fSorted,
    int xorg, int yorg 
){
   XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
   int fg, bg;

   switch(pGC->fillStyle) {
   case FillStippled:
      fg = pGC->fgPixel;  bg = -1;
      break;
   case FillOpaqueStippled:
      fg = pGC->fgPixel;  bg = pGC->bgPixel;
      break;
   default:	/* Muffle compiler */
      fg = -1;  bg = -1;
      break;
   }

   (*infoRec->FillCacheExpandSpans) (infoRec->pScrn, fg, bg,
                pGC->alu, pGC->planemask, n, ppt, pwidth, fSorted,
                (xorg + pGC->patOrg.x), (yorg + pGC->patOrg.y),
                pGC->stipple); 
}


	/***************************\
	|     Pixmap Copy Spans     |
	\***************************/


static void
XAARenderPixmapCopySpans(
    GCPtr pGC,
    int	n,
    DDXPointPtr ppt,
    int *pwidth,
    int fSorted,
    int xorg, int yorg 
){
   XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
   XAACacheInfoPtr pCache = &(infoRec->ScratchCacheInfoRec);
   XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pGC->tile.pixmap);

   pCache->x = pPriv->offscreenArea->box.x1;
   pCache->y = pPriv->offscreenArea->box.y1;
   pCache->w = pCache->orig_w = 
		pPriv->offscreenArea->box.x2 - pCache->x;
   pCache->h = pCache->orig_h = 
		pPriv->offscreenArea->box.y2 - pCache->y;
   pCache->trans_color = -1;

   (*infoRec->FillCacheBltSpans) (infoRec->pScrn, 
                pGC->alu, pGC->planemask, n, ppt, pwidth, fSorted, pCache, 
                (xorg + pGC->patOrg.x), (yorg + pGC->patOrg.y));
}





	/****************\
	|     Solid      |
	\****************/


void 
XAAFillSolidSpans(
   ScrnInfoPtr pScrn,
   int fg, int rop,
   unsigned int planemask,
   int n,
   DDXPointPtr ppt,
   int *pwidth, int fSorted 
){
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);

    (*infoRec->SetupForSolidFill)(pScrn, fg, rop, planemask);

    if(infoRec->ClipBox)
	(*infoRec->SetClippingRectangle)(infoRec->pScrn,
		infoRec->ClipBox->x1, infoRec->ClipBox->y1, 
		infoRec->ClipBox->x2 - 1, infoRec->ClipBox->y2 - 1);

    while(n--) {
	if (*pwidth > 0)
            (*infoRec->SubsequentSolidFillRect)(pScrn, ppt->x, ppt->y, 
								*pwidth, 1);
	ppt++; pwidth++;
    }

    if(infoRec->ClipBox)
	(*infoRec->DisableClipping)(infoRec->pScrn);

    SET_SYNC_FLAG(infoRec);
}

	/***************\
	|   Mono 8x8    |
	\***************/


void 
XAAFillMono8x8PatternSpansScreenOrigin(
   ScrnInfoPtr pScrn,
   int fg, int bg, int rop,
   unsigned int planemask,
   int n,
   DDXPointPtr ppt,
   int *pwidth, int fSorted,
   int pattern0, int pattern1,
   int xorigin, int yorigin 
){
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
    int patx = pattern0, paty = pattern1;
    int xorg = (-xorigin) & 0x07;
    int yorg = (-yorigin) & 0x07;


    if(infoRec->Mono8x8PatternFillFlags & HARDWARE_PATTERN_PROGRAMMED_BITS) {
   	if(!(infoRec->Mono8x8PatternFillFlags & 		
				HARDWARE_PATTERN_PROGRAMMED_ORIGIN)){
	    XAARotateMonoPattern(&patx, &paty, xorg, yorg,
				(infoRec->Mono8x8PatternFillFlags & 		
				BIT_ORDER_IN_BYTE_MSBFIRST));
	    xorg = patx; yorg = paty;
        }
    } else {
	XAACacheInfoPtr pCache =
		(*infoRec->CacheMono8x8Pattern)(pScrn, pattern0, pattern1);
	patx = pCache->x;  paty = pCache->y;
   	if(!(infoRec->Mono8x8PatternFillFlags & 
				HARDWARE_PATTERN_PROGRAMMED_ORIGIN)){
	    int slot = (yorg << 3) + xorg;
	    patx += pCache->offsets[slot].x;
	    paty += pCache->offsets[slot].y;
	    xorg = patx;  yorg = paty;
	}	
    }

    (*infoRec->SetupForMono8x8PatternFill)(pScrn, patx, paty,
	fg, bg, rop, planemask);

    if(infoRec->ClipBox)
	(*infoRec->SetClippingRectangle)(infoRec->pScrn,
		infoRec->ClipBox->x1, infoRec->ClipBox->y1, 
		infoRec->ClipBox->x2 - 1, infoRec->ClipBox->y2 - 1);

     while(n--) {
        (*infoRec->SubsequentMono8x8PatternFillRect)(pScrn, 
			xorg, yorg, ppt->x, ppt->y, *pwidth, 1);
	ppt++; pwidth++;
     }

     if(infoRec->ClipBox)
	(*infoRec->DisableClipping)(infoRec->pScrn);

     SET_SYNC_FLAG(infoRec);
}


void 
XAAFillMono8x8PatternSpans(
   ScrnInfoPtr pScrn,
   int fg, int bg, int rop,
   unsigned int planemask,
   int n,
   DDXPointPtr ppt,
   int *pwidth, int fSorted,
   int pattern0, int pattern1,
   int xorigin, int yorigin 
){
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
    int patx = pattern0, paty = pattern1;
    int xorg, yorg, slot;
    XAACacheInfoPtr pCache = NULL;


    if(!(infoRec->Mono8x8PatternFillFlags & HARDWARE_PATTERN_PROGRAMMED_BITS)){
	pCache = (*infoRec->CacheMono8x8Pattern)(pScrn, pattern0, pattern1);
	patx = pCache->x;  paty = pCache->y;
    }

    (*infoRec->SetupForMono8x8PatternFill)(pScrn, patx, paty,
					fg, bg, rop, planemask);

    if(infoRec->ClipBox)
	(*infoRec->SetClippingRectangle)(infoRec->pScrn,
		infoRec->ClipBox->x1, infoRec->ClipBox->y1, 
		infoRec->ClipBox->x2 - 1, infoRec->ClipBox->y2 - 1);

     while(n--) {
	xorg = (ppt->x - xorigin) & 0x07;
	yorg = (ppt->y - yorigin) & 0x07;

   	if(!(infoRec->Mono8x8PatternFillFlags & 		
				HARDWARE_PATTERN_PROGRAMMED_ORIGIN)){
	    if(infoRec->Mono8x8PatternFillFlags & 
				HARDWARE_PATTERN_PROGRAMMED_BITS) {
		patx = pattern0; paty = pattern1;
		XAARotateMonoPattern(&patx, &paty, xorg, yorg,
				(infoRec->Mono8x8PatternFillFlags & 		
				BIT_ORDER_IN_BYTE_MSBFIRST));
		xorg = patx; yorg = paty;
	    } else {
		slot = (yorg << 3) + xorg;
	    	xorg = patx + pCache->offsets[slot].x;
	    	yorg = paty + pCache->offsets[slot].y;
	    }
        }

        (*infoRec->SubsequentMono8x8PatternFillRect)(pScrn, 
			xorg, yorg, ppt->x, ppt->y, *pwidth, 1);
	ppt++; pwidth++;
     }

     if(infoRec->ClipBox)
	(*infoRec->DisableClipping)(infoRec->pScrn);

     SET_SYNC_FLAG(infoRec);
}



	/****************\
	|   Color 8x8    |
	\****************/


void 
XAAFillColor8x8PatternSpansScreenOrigin(
   ScrnInfoPtr pScrn,
   int rop,
   unsigned int planemask,
   int n,
   DDXPointPtr ppt,
   int *pwidth, int fSorted,
   XAACacheInfoPtr pCache,
   int xorigin, int yorigin 
){
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
    int patx = pCache->x, paty = pCache->y;
    int xorg = (-xorigin) & 0x07;
    int yorg = (-yorigin) & 0x07;


    if(!(infoRec->Color8x8PatternFillFlags & 
					HARDWARE_PATTERN_PROGRAMMED_ORIGIN)){
	int slot = (yorg << 3) + xorg;
	paty += pCache->offsets[slot].y;
	patx += pCache->offsets[slot].x;
	xorg = patx;  yorg = paty;
    }	

    (*infoRec->SetupForColor8x8PatternFill)(pScrn, patx, paty,
			 rop, planemask, pCache->trans_color);

    if(infoRec->ClipBox)
	(*infoRec->SetClippingRectangle)(infoRec->pScrn,
		infoRec->ClipBox->x1, infoRec->ClipBox->y1, 
		infoRec->ClipBox->x2 - 1, infoRec->ClipBox->y2 - 1);

     while(n--) {
        (*infoRec->SubsequentColor8x8PatternFillRect)(pScrn, 
			xorg, yorg, ppt->x, ppt->y, *pwidth, 1);
	ppt++; pwidth++;
     }
 
    if(infoRec->ClipBox)
	(*infoRec->DisableClipping)(infoRec->pScrn);

     SET_SYNC_FLAG(infoRec);
}


void 
XAAFillColor8x8PatternSpans(
   ScrnInfoPtr pScrn,
   int rop,
   unsigned int planemask,
   int n,
   DDXPointPtr ppt,
   int *pwidth, int fSorted,
   XAACacheInfoPtr pCache,
   int xorigin, int yorigin 
){
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
    int xorg, yorg, slot;

    (*infoRec->SetupForColor8x8PatternFill)(pScrn, pCache->x, pCache->y,
			 rop, planemask, pCache->trans_color);

    if(infoRec->ClipBox)
	(*infoRec->SetClippingRectangle)(infoRec->pScrn,
		infoRec->ClipBox->x1, infoRec->ClipBox->y1, 
		infoRec->ClipBox->x2 - 1, infoRec->ClipBox->y2 - 1);

     while(n--) {
	xorg = (ppt->x - xorigin) & 0x07;
	yorg = (ppt->y - yorigin) & 0x07;

   	if(!(infoRec->Color8x8PatternFillFlags & 		
				HARDWARE_PATTERN_PROGRAMMED_ORIGIN)){
	    slot = (yorg << 3) + xorg;
	    yorg = pCache->y + pCache->offsets[slot].y;
	    xorg = pCache->x + pCache->offsets[slot].x;
        }

        (*infoRec->SubsequentColor8x8PatternFillRect)(pScrn, 
			xorg, yorg, ppt->x, ppt->y, *pwidth, 1);
	ppt++; pwidth++;
     }

     if(infoRec->ClipBox)
	(*infoRec->DisableClipping)(infoRec->pScrn);

     SET_SYNC_FLAG(infoRec);
}

	/*****************\
	|   Cache Blit    |
	\*****************/


void 
XAAFillCacheBltSpans(
   ScrnInfoPtr pScrn,
   int rop,
   unsigned int planemask,
   int n,
   DDXPointPtr ppt,
   int *pwidth,
   int fSorted,
   XAACacheInfoPtr pCache,
   int xorg, int yorg
){
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
    int x, w, phaseX, phaseY, blit_w;  

    (*infoRec->SetupForScreenToScreenCopy)(pScrn, 1, 1, rop, planemask,
		pCache->trans_color);

    if(infoRec->ClipBox)
	(*infoRec->SetClippingRectangle)(infoRec->pScrn,
		infoRec->ClipBox->x1, infoRec->ClipBox->y1, 
		infoRec->ClipBox->x2 - 1, infoRec->ClipBox->y2 - 1);

     while(n--) {
	x = ppt->x;
	w = *pwidth; 
	phaseX = (x - xorg) % pCache->orig_w;
	if(phaseX < 0) phaseX += pCache->orig_w;
	phaseY = (ppt->y - yorg) % pCache->orig_h;
	if(phaseY < 0) phaseY += pCache->orig_h;

	while(1) {
	    blit_w = pCache->w - phaseX;
	    if(blit_w > w) blit_w = w;

            (*infoRec->SubsequentScreenToScreenCopy)(pScrn, 
		pCache->x + phaseX, pCache->y + phaseY,
		x, ppt->y, blit_w, 1);

	    w -= blit_w;
	    if(!w) break;
	    x += blit_w;
	    phaseX = (phaseX + blit_w) % pCache->orig_w;
	}
	ppt++; pwidth++;
     }

     if(infoRec->ClipBox)
	(*infoRec->DisableClipping)(infoRec->pScrn);

     SET_SYNC_FLAG(infoRec);
}


	/****************\
	|  Cache Expand  |
	\****************/


void 
XAAFillCacheExpandSpans(
   ScrnInfoPtr pScrn,
   int fg, int bg, int rop,
   unsigned int planemask,
   int n,
   DDXPointPtr ppt,
   int *pwidth,
   int fSorted,
   int xorg, int yorg,
   PixmapPtr pPix
){
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
    int x, w, phaseX, phaseY, blit_w, cacheWidth;  
    XAACacheInfoPtr pCache;

    pCache = (*infoRec->CacheMonoStipple)(pScrn, pPix);

    cacheWidth = (pCache->w * pScrn->bitsPerPixel) / 
	infoRec->CacheColorExpandDensity;

    (*infoRec->SetupForScreenToScreenColorExpandFill)(pScrn, fg, bg, rop, 
							planemask);

    if(infoRec->ClipBox)
	(*infoRec->SetClippingRectangle)(infoRec->pScrn,
		infoRec->ClipBox->x1, infoRec->ClipBox->y1, 
		infoRec->ClipBox->x2 - 1, infoRec->ClipBox->y2 - 1);

     while(n--) {
	x = ppt->x;
	w = *pwidth; 
	phaseX = (x - xorg) % pCache->orig_w;
	if(phaseX < 0) phaseX += pCache->orig_w;
	phaseY = (ppt->y - yorg) % pCache->orig_h;
	if(phaseY < 0) phaseY += pCache->orig_h;

	while(1) {
	    blit_w = cacheWidth - phaseX;
	    if(blit_w > w) blit_w = w;

	    (*infoRec->SubsequentScreenToScreenColorExpandFill)(
			pScrn, x, ppt->y, blit_w, 1,
			pCache->x, pCache->y + phaseY, phaseX);

	    w -= blit_w;
	    if(!w) break;
	    x += blit_w;
	    phaseX = (phaseX + blit_w) % pCache->orig_w;
	}
	ppt++; pwidth++;
     }

     if(infoRec->ClipBox)
	(*infoRec->DisableClipping)(infoRec->pScrn);

     SET_SYNC_FLAG(infoRec);
}



void
XAAClipAndRenderSpans(
    GCPtr pGC, 
    DDXPointPtr	ppt,
    int		*pwidth,
    int		nspans,
    int		fSorted,
    ClipAndRenderSpansFunc func,
    int 	xorg,
    int		yorg
){
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
    DDXPointPtr pptNew, pptBase;
    int	*pwidthBase, *pwidthNew;
    int	Right, numRects, MaxBoxes;

    MaxBoxes = infoRec->PreAllocSize/(sizeof(DDXPointRec) + sizeof(int));
    pptBase = (DDXPointRec*)infoRec->PreAllocMem;
    pwidthBase = (int*)(&pptBase[MaxBoxes]);

    pptNew = pptBase;
    pwidthNew = pwidthBase;

    numRects = REGION_NUM_RECTS(pGC->pCompositeClip);

    if(numRects == 1) {
        BoxPtr pextent = REGION_RECTS(pGC->pCompositeClip);
	    
	while(nspans--) {
	    if ((pextent->y1 <= ppt->y) && (ppt->y < pextent->y2)) {
		pptNew->x = max(pextent->x1, ppt->x);
		Right = ppt->x + *pwidth; 
		*pwidthNew = min(pextent->x2, Right) - pptNew->x;

		if (*pwidthNew > 0) {
		    pptNew->y = ppt->y;
		    pptNew++;
		    pwidthNew++;

		    if(pptNew >= (pptBase + MaxBoxes)) {
			(*func)(pGC, MaxBoxes, pptBase, pwidthBase, fSorted, 	
								xorg, yorg);
			pptNew = pptBase;
			pwidthNew = pwidthBase;
		    }
		}
	    }
	    ppt++;
	    pwidth++;
	}
    } else if (numRects) {
	BoxPtr	pbox;
	int nbox;

	while(nspans--) {
	    nbox = numRects;
	    pbox = REGION_RECTS(pGC->pCompositeClip);

	    /* find the first band */
	    while(nbox && (pbox->y2 <= ppt->y)) {
		pbox++;
		nbox--;
	    }

	    if(nbox && (pbox->y1 <= ppt->y)) {
		int orig_y = pbox->y1;
		Right = ppt->x + *pwidth;
		while(nbox && (orig_y == pbox->y1)) {
		    if(pbox->x2 <= ppt->x) {
			nbox--;
			pbox++;
			continue;
		    }

		    if(pbox->x1 >= Right) {
			nbox = 0;
			break;
		    }

		    pptNew->x = max(pbox->x1, ppt->x);
		    *pwidthNew = min(pbox->x2, Right) - pptNew->x;
		    if(*pwidthNew > 0) {
			pptNew->y = ppt->y;
			pptNew++;
			pwidthNew++;

			if(pptNew >= (pptBase + MaxBoxes)) {
			    (*func)(pGC, MaxBoxes, pptBase, pwidthBase, 
							fSorted, xorg, yorg);
			    pptNew = pptBase;
			    pwidthNew = pwidthBase;
			}
		    }
		    pbox++;
		    nbox--;
		}
	    }
	    ppt++;
	    pwidth++;
	}
    }

    if(pptNew != pptBase)
	(*func)(pGC, pptNew - pptBase, pptBase, pwidthBase, fSorted, 
						xorg, yorg);
}

--- NEW FILE: xaaStateChange.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaStateChange.c,v 3.1 2000/06/20 05:08:49 dawes Exp $ */

#include "misc.h"
#include "xf86.h"
#include "xf86_ansic.h"
#include "xf86_OSproc.h"

#include <X11/X.h>
#include "scrnintstr.h"
#include "pixmapstr.h"
#include "windowstr.h"
#include "xf86str.h"
#include "mi.h"
#include "miline.h"
#include "xaa.h"
#include "xaalocal.h"
#include "xaawrap.h"
#include "servermd.h"

[...1639 lines suppressed...]
   XAA_STATE_WRAP(CacheMonoStipple);
   XAA_STATE_WRAP(CacheMono8x8Pattern);
   XAA_STATE_WRAP(CacheColor8x8Pattern);
   XAA_STATE_WRAP(WriteBitmapToCache);
   XAA_STATE_WRAP(WritePixmapToCache);
   XAA_STATE_WRAP(WriteMono8x8PatternToCache);
   XAA_STATE_WRAP(WriteColor8x8PatternToCache);
   XAA_STATE_WRAP(GetImage);
   XAA_STATE_WRAP(GetSpans);
   XAA_STATE_WRAP(PaintWindowBackground);
   XAA_STATE_WRAP(PaintWindowBorder);
   XAA_STATE_WRAP(CopyWindow);
   XAA_STATE_WRAP(SaveAreas);
   XAA_STATE_WRAP(RestoreAreas);
#ifdef RENDER
   XAA_STATE_WRAP(SetupForCPUToScreenAlphaTexture);
   XAA_STATE_WRAP(SetupForCPUToScreenTexture);
#endif
   return TRUE;
}

--- NEW FILE: xaaStipple.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaStipple.c,v 1.11 2001/10/28 03:34:04 tsi Exp $ */

#include "xaa.h"
#include "xaalocal.h"
#include "xaacexp.h"
#include "xf86.h"
#include "xf86_ansic.h"

static CARD32* StipplePowerOfTwo(CARD32*, CARD32*, int, int, int);
static CARD32* StipplePowerOfTwo_Inverted(CARD32*, CARD32*, int, int, int);
static CARD32* StippleUpTo32(CARD32*, CARD32*, int, int, int);
static CARD32* StippleUpTo32_Inverted(CARD32*, CARD32*, int, int, int);
static CARD32* StippleOver32(CARD32*, CARD32*, int, int, int);
static CARD32* StippleOver32_Inverted(CARD32*, CARD32*, int, int, int);

#ifdef TRIPLE_BITS
#define stipple_scanline_func EXPNAME(XAAStippleScanlineFunc3)
#else
#define stipple_scanline_func EXPNAME(XAAStippleScanlineFunc)
#endif

StippleScanlineProcPtr stipple_scanline_func[6] = {
   StipplePowerOfTwo,
   StippleUpTo32,
   StippleOver32,
   StipplePowerOfTwo_Inverted,
   StippleUpTo32_Inverted,
   StippleOver32_Inverted
};


#ifdef FIXEDBASE
# define DEST(i)	*dest
# define RETURN(i)	return(dest)
#else
# define DEST(i)	dest[i]
# define RETURN(i)	return(dest + i)
#endif


/* TRIPLE_BITS pattern expansion */
#ifdef TRIPLE_BITS
#define EXPAND_PAT \
	CARD32 pat1 = byte_expand3[pat & 0xFF], \
	       pat2 = byte_expand3[(pat & 0xFF00) >> 8], \
	       pat3 = byte_expand3[(pat & 0xFF0000) >> 16], \
	       pat4 = byte_expand3[(pat & 0xFF000000) >> 24], \
	       patA = pat1 | (pat2 << 24), \
	       patB = (pat2 >> 8) | (pat3 << 16), \
	       patC = (pat3 >> 16) | (pat4 << 8)
#ifdef FIXED_BASE
#define WRITE_PAT1 { \
	*dest = patA; }
#define WRITE_PAT2 { \
	*dest = patA; \
	*dest = patB; }
#define WRITE_PAT3 { \
	*dest = patA; \
	*dest = patB; \
	*dest = patC; }
#else
#define WRITE_PAT1 { \
	*(dest++) = patA; }
#define WRITE_PAT2 { \
	*(dest) = patA; \
	*(dest + 1) = patB; \
	dest += 2; }
#define WRITE_PAT3 { \
	*(dest) = patA; \
	*(dest + 1) = patB; \
	*(dest + 2) = patC; \
	dest += 3; }
#endif
#endif


#if !defined(FIXEDBASE) && !defined(MSBFIRST) && !defined(TRIPLE_BITS)

unsigned int XAAShiftMasks[32] = {
  /* gcc is rather pedantic about SHIFT_R(0xFFFFFFFF,32) */
          0x00000000    , SHIFT_R(0xFFFFFFFF,31),
  SHIFT_R(0xFFFFFFFF,30), SHIFT_R(0xFFFFFFFF,29),
  SHIFT_R(0xFFFFFFFF,28), SHIFT_R(0xFFFFFFFF,27),
  SHIFT_R(0xFFFFFFFF,26), SHIFT_R(0xFFFFFFFF,25),
  SHIFT_R(0xFFFFFFFF,24), SHIFT_R(0xFFFFFFFF,23),
  SHIFT_R(0xFFFFFFFF,22), SHIFT_R(0xFFFFFFFF,21),
  SHIFT_R(0xFFFFFFFF,20), SHIFT_R(0xFFFFFFFF,19),
  SHIFT_R(0xFFFFFFFF,18), SHIFT_R(0xFFFFFFFF,17),
  SHIFT_R(0xFFFFFFFF,16), SHIFT_R(0xFFFFFFFF,15),
  SHIFT_R(0xFFFFFFFF,14), SHIFT_R(0xFFFFFFFF,13),
  SHIFT_R(0xFFFFFFFF,12), SHIFT_R(0xFFFFFFFF,11),
  SHIFT_R(0xFFFFFFFF,10), SHIFT_R(0xFFFFFFFF,9),
  SHIFT_R(0xFFFFFFFF,8),  SHIFT_R(0xFFFFFFFF,7),
  SHIFT_R(0xFFFFFFFF,6),  SHIFT_R(0xFFFFFFFF,5),
  SHIFT_R(0xFFFFFFFF,4),  SHIFT_R(0xFFFFFFFF,3),
  SHIFT_R(0xFFFFFFFF,2),  SHIFT_R(0xFFFFFFFF,1)
};

#endif

void 
#ifdef TRIPLE_BITS
EXPNAME(XAAFillColorExpandRects3)(
#else
EXPNAME(XAAFillColorExpandRects)(
#endif
   ScrnInfoPtr pScrn,
   int fg, int bg, int rop,
   unsigned int planemask,
   int nBox,
   BoxPtr pBox,
   int xorg, int yorg,
   PixmapPtr pPix
){
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
    CARD32 *base;
    Bool TwoPass = FALSE, FirstPass = TRUE;
    StippleScanlineProcPtr StippleFunc, FirstFunc, SecondFunc;
    int stipplewidth = pPix->drawable.width;
    int stippleheight = pPix->drawable.height;
    int srcwidth = pPix->devKind;
    int dwords, srcy, srcx, funcNo = 2, h;
    unsigned char *src = (unsigned char*)pPix->devPrivate.ptr;
    unsigned char *srcp;
    int flag;

    if(stipplewidth <= 32) {
	if(stipplewidth & (stipplewidth - 1))	
	  funcNo = 1;
	else	
	  funcNo = 0;
    } 
    StippleFunc = stipple_scanline_func[funcNo];
    SecondFunc = stipple_scanline_func[funcNo];
    FirstFunc = stipple_scanline_func[funcNo + 3];

#ifdef TRIPLE_BITS
    if((bg == -1) || 
	(!(infoRec->CPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY) &&
	(!(infoRec->CPUToScreenColorExpandFillFlags & RGB_EQUAL) ||
	(CHECK_RGB_EQUAL(bg))))) {
#else
    if((bg == -1) || 
	!(infoRec->CPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY)) {
#endif
	/* one pass */
    } else if((rop == GXcopy) && infoRec->FillSolidRects) {
	/* one pass but we fill background rects first */
	(*infoRec->FillSolidRects)(pScrn, bg, rop, planemask, nBox, pBox);
	bg = -1;
    } else {
	/* gotta do two passes */
	TwoPass = TRUE;
    }

    if(!TwoPass)
	(*infoRec->SetupForCPUToScreenColorExpandFill)(
					pScrn, fg, bg, rop, planemask);

    while(nBox--) {
#ifdef TRIPLE_BITS
	dwords = (3 * (pBox->x2 - pBox->x1) + 31) >> 5;
#else
	dwords = (pBox->x2 - pBox->x1 + 31) >> 5;
#endif

SECOND_PASS:
	if(TwoPass) {
	    (*infoRec->SetupForCPUToScreenColorExpandFill)(pScrn, 
			(FirstPass) ? bg : fg, -1, rop, planemask);
	    StippleFunc = (FirstPass) ? FirstFunc : SecondFunc;
	}

	h = pBox->y2 - pBox->y1;
	flag = (infoRec->CPUToScreenColorExpandFillFlags 
		& CPU_TRANSFER_PAD_QWORD) && ((dwords * h) & 0x01);

        (*infoRec->SubsequentCPUToScreenColorExpandFill)(
			pScrn, pBox->x1, pBox->y1,
 			pBox->x2 - pBox->x1, h, 0);

	base = (CARD32*)infoRec->ColorExpandBase;

	srcy = (pBox->y1 - yorg) % stippleheight;
	if(srcy < 0) srcy += stippleheight;
	srcx = (pBox->x1 - xorg) % stipplewidth;
	if(srcx < 0) srcx += stipplewidth;

	srcp = (srcwidth * srcy) + src;
	
#ifndef FIXEDBASE
	if((dwords * h) <= infoRec->ColorExpandRange) {
	   while(h--) {
		base = (*StippleFunc)(
			base, (CARD32*)srcp, srcx, stipplewidth, dwords);
		srcy++;
		srcp += srcwidth;
		if (srcy >= stippleheight) {
		   srcy = 0;
		   srcp = src;
		}
	   }
	} else
#endif
	   while(h--) {
		(*StippleFunc)(base, (CARD32*)srcp, srcx, stipplewidth, dwords);
		srcy++;
		srcp += srcwidth;
		if (srcy >= stippleheight) {
		   srcy = 0;
		   srcp = src;
		}
	   }
    
	  if (flag) {
	      base = (CARD32*)infoRec->ColorExpandBase;
	      base[0] = 0x00000000;
	  }

	if(TwoPass) {
	   if(FirstPass) {
		FirstPass = FALSE;
		goto SECOND_PASS;
	   } else FirstPass = TRUE;
	}

	pBox++;
     }

    if(infoRec->CPUToScreenColorExpandFillFlags & SYNC_AFTER_COLOR_EXPAND) 
	(*infoRec->Sync)(pScrn);
    else SET_SYNC_FLAG(infoRec);
}



void 
#ifdef TRIPLE_BITS
EXPNAME(XAAFillColorExpandSpans3)(
#else
EXPNAME(XAAFillColorExpandSpans)(
#endif
   ScrnInfoPtr pScrn,
   int fg, int bg, int rop,
   unsigned int planemask,
   int n,
   DDXPointPtr ppt,
   int *pwidth,
   int fSorted,
   int xorg, int yorg,
   PixmapPtr pPix
){
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
    CARD32 *base;
    Bool TwoPass = FALSE, FirstPass = TRUE;
    StippleScanlineProcPtr StippleFunc, FirstFunc, SecondFunc;
    int stipplewidth = pPix->drawable.width;
    int stippleheight = pPix->drawable.height;
    int dwords, srcy, srcx, funcNo = 2;
    unsigned char *srcp;

    if(stipplewidth <= 32) {
	if(stipplewidth & (stipplewidth - 1))	
	  funcNo = 1;
	else	
	  funcNo = 0;
    } 
    StippleFunc = stipple_scanline_func[funcNo];
    SecondFunc = stipple_scanline_func[funcNo];
    FirstFunc = stipple_scanline_func[funcNo + 3];

#ifdef TRIPLE_BITS
    if((bg == -1) || 
	(!(infoRec->CPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY) &&
	(!(infoRec->CPUToScreenColorExpandFillFlags & RGB_EQUAL) ||
	(CHECK_RGB_EQUAL(bg))))) {
#else
    if((bg == -1) || 
	!(infoRec->CPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY)) {
#endif
	/* one pass */
    } else if((rop == GXcopy) && infoRec->FillSolidSpans) {
	/* one pass but we fill background rects first */
	(*infoRec->FillSolidSpans)(
		pScrn, bg, rop, planemask, n, ppt, pwidth, fSorted);
	bg = -1;
    } else {
	/* gotta do two passes */
	TwoPass = TRUE;
    }

    if(!TwoPass)
	(*infoRec->SetupForCPUToScreenColorExpandFill)(
				pScrn, fg, bg, rop, planemask);

    while(n--) {
#ifdef TRIPLE_BITS
	dwords = (3 * *pwidth + 31) >> 5;
#else
	dwords = (*pwidth + 31) >> 5;
#endif

	srcy = (ppt->y - yorg) % stippleheight;
	if(srcy < 0) srcy += stippleheight;
	srcx = (ppt->x - xorg) % stipplewidth;
	if(srcx < 0) srcx += stipplewidth;

	srcp = (pPix->devKind * srcy) + (unsigned char*)pPix->devPrivate.ptr;

SECOND_PASS:
	if(TwoPass) {
	    (*infoRec->SetupForCPUToScreenColorExpandFill)(pScrn, 
			(FirstPass) ? bg : fg, -1, rop, planemask);
	    StippleFunc = (FirstPass) ? FirstFunc : SecondFunc;
	}

        (*infoRec->SubsequentCPUToScreenColorExpandFill)(pScrn, ppt->x, ppt->y,
 			*pwidth, 1, 0);

	base = (CARD32*)infoRec->ColorExpandBase;

	(*StippleFunc)(base, (CARD32*)srcp, srcx, stipplewidth, dwords);
    
	if((infoRec->CPUToScreenColorExpandFillFlags & CPU_TRANSFER_PAD_QWORD) 
			&& (dwords & 0x01)) {
	    base = (CARD32*)infoRec->ColorExpandBase;
	    base[0] = 0x00000000;
    	}

	if(TwoPass) {
	   if(FirstPass) {
		FirstPass = FALSE;
		goto SECOND_PASS;
	   } else FirstPass = TRUE;
	}

	ppt++; pwidth++;
     }

    if(infoRec->CPUToScreenColorExpandFillFlags & SYNC_AFTER_COLOR_EXPAND) 
	(*infoRec->Sync)(pScrn);
    else SET_SYNC_FLAG(infoRec);
}


#ifndef FIXEDBASE

void 
#ifdef TRIPLE_BITS
EXPNAME(XAAFillScanlineColorExpandRects3)(
#else
EXPNAME(XAAFillScanlineColorExpandRects)(
#endif
   ScrnInfoPtr pScrn,
   int fg, int bg, int rop,
   unsigned int planemask,
   int nBox,
   BoxPtr pBox,
   int xorg, int yorg,
   PixmapPtr pPix
){
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
    CARD32 *base;
    Bool TwoPass = FALSE, FirstPass = TRUE;
    StippleScanlineProcPtr StippleFunc, FirstFunc, SecondFunc;
    int stipplewidth = pPix->drawable.width;
    int stippleheight = pPix->drawable.height;
    int srcwidth = pPix->devKind;
    int dwords, srcy, srcx, funcNo = 2, bufferNo, h;
    unsigned char *src = pPix->devPrivate.ptr;
    unsigned char *srcp;

    if(stipplewidth <= 32) {
	if(stipplewidth & (stipplewidth - 1))	
	  funcNo = 1;
	else	
	  funcNo = 0;
    } 
    StippleFunc = stipple_scanline_func[funcNo];
    SecondFunc = stipple_scanline_func[funcNo];
    FirstFunc = stipple_scanline_func[funcNo + 3];

#ifdef TRIPLE_BITS
    if((bg == -1) || 
      (!(infoRec->ScanlineCPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY) &&
      (!(infoRec->ScanlineCPUToScreenColorExpandFillFlags & RGB_EQUAL) ||
      (CHECK_RGB_EQUAL(bg))))) {
#else
    if((bg == -1) || 
      !(infoRec->ScanlineCPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY)) {
#endif
	/* one pass */
    } else if((rop == GXcopy) && infoRec->FillSolidRects) {
	/* one pass but we fill background rects first */
	(*infoRec->FillSolidRects)(pScrn, bg, rop, planemask, nBox, pBox);
	bg = -1;
    } else {
	/* gotta do two passes */
	TwoPass = TRUE;
    }

    if(!TwoPass)
	(*infoRec->SetupForScanlineCPUToScreenColorExpandFill)(
				pScrn, fg, bg, rop, planemask);

    while(nBox--) {
#ifdef TRIPLE_BITS
	dwords = (3 * (pBox->x2 - pBox->x1) + 31) >> 5;
#else
	dwords = (pBox->x2 - pBox->x1 + 31) >> 5;
#endif

SECOND_PASS:
	if(TwoPass) {
	    (*infoRec->SetupForScanlineCPUToScreenColorExpandFill)(pScrn, 
			(FirstPass) ? bg : fg, -1, rop, planemask);
	    StippleFunc = (FirstPass) ? FirstFunc : SecondFunc;
	}

	h = pBox->y2 - pBox->y1;

        (*infoRec->SubsequentScanlineCPUToScreenColorExpandFill)(
		pScrn, pBox->x1, pBox->y1, pBox->x2 - pBox->x1, h, 0);

	bufferNo = 0;

	srcy = (pBox->y1 - yorg) % stippleheight;
	if(srcy < 0) srcy += stippleheight;
	srcx = (pBox->x1 - xorg) % stipplewidth;
	if(srcx < 0) srcx += stipplewidth;

	srcp = (srcwidth * srcy) + src;

	while(h--) {
   	    base = (CARD32*)infoRec->ScanlineColorExpandBuffers[bufferNo];
	    (*StippleFunc)(base, (CARD32*)srcp, srcx, stipplewidth, dwords);
	    (*infoRec->SubsequentColorExpandScanline)(pScrn, bufferNo++);
	    if(bufferNo >= infoRec->NumScanlineColorExpandBuffers)
		bufferNo = 0;
	    srcy++;
	    srcp += srcwidth;
	    if (srcy >= stippleheight) {
		srcy = 0;
		srcp = src;
	    }
	}
    
	if(TwoPass) {
	   if(FirstPass) {
		FirstPass = FALSE;
		goto SECOND_PASS;
	   } else FirstPass = TRUE;
	}

	pBox++;
     }

     SET_SYNC_FLAG(infoRec);
}

void 
#ifdef TRIPLE_BITS
EXPNAME(XAAFillScanlineColorExpandSpans3)(
#else
EXPNAME(XAAFillScanlineColorExpandSpans)(
#endif
   ScrnInfoPtr pScrn,
   int fg, int bg, int rop,
   unsigned int planemask,
   int n,
   DDXPointPtr ppt,
   int *pwidth,
   int fSorted,
   int xorg, int yorg,
   PixmapPtr pPix
){
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
    CARD32 *base;
    Bool TwoPass = FALSE, FirstPass = TRUE;
    StippleScanlineProcPtr StippleFunc, FirstFunc, SecondFunc;
    int stipplewidth = pPix->drawable.width;
    int stippleheight = pPix->drawable.height;
    int dwords, srcy, srcx, funcNo = 2;
    unsigned char *srcp;

    if(stipplewidth <= 32) {
	if(stipplewidth & (stipplewidth - 1))	
	  funcNo = 1;
	else	
	  funcNo = 0;
    } 
    StippleFunc = stipple_scanline_func[funcNo];
    SecondFunc = stipple_scanline_func[funcNo];
    FirstFunc = stipple_scanline_func[funcNo + 3];

#ifdef TRIPLE_BITS
    if((bg == -1) || 
      (!(infoRec->ScanlineCPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY) &&
      (!(infoRec->ScanlineCPUToScreenColorExpandFillFlags & RGB_EQUAL) ||
      (CHECK_RGB_EQUAL(bg))))) {
#else
    if((bg == -1) || 
      !(infoRec->ScanlineCPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY)) {
#endif
	/* one pass */
    } else if((rop == GXcopy) && infoRec->FillSolidSpans) {
	/* one pass but we fill background rects first */
	(*infoRec->FillSolidSpans)(
		pScrn, bg, rop, planemask, n, ppt, pwidth, fSorted);
	bg = -1;
    } else {
	/* gotta do two passes */
	TwoPass = TRUE;
    }

    if(!TwoPass)
	(*infoRec->SetupForScanlineCPUToScreenColorExpandFill)(
				pScrn, fg, bg, rop, planemask);


    while(n--) {
#ifdef TRIPLE_BITS
	dwords = (3 * *pwidth + 31) >> 5;
#else
	dwords = (*pwidth + 31) >> 5;
#endif

	srcy = (ppt->y - yorg) % stippleheight;
	if(srcy < 0) srcy += stippleheight;
	srcx = (ppt->x - xorg) % stipplewidth;
	if(srcx < 0) srcx += stipplewidth;

	srcp = (pPix->devKind * srcy) + (unsigned char*)pPix->devPrivate.ptr;

SECOND_PASS:
	if(TwoPass) {
	    (*infoRec->SetupForScanlineCPUToScreenColorExpandFill)(pScrn, 
			(FirstPass) ? bg : fg, -1, rop, planemask);
	    StippleFunc = (FirstPass) ? FirstFunc : SecondFunc;
	}

        (*infoRec->SubsequentScanlineCPUToScreenColorExpandFill)(
				pScrn, ppt->x, ppt->y, *pwidth, 1, 0);

	base = (CARD32*)infoRec->ScanlineColorExpandBuffers[0];

	(*StippleFunc)(base, (CARD32*)srcp, srcx, stipplewidth, dwords);
	(*infoRec->SubsequentColorExpandScanline)(pScrn, 0);
    
	if(TwoPass) {
	   if(FirstPass) {
		FirstPass = FALSE;
		goto SECOND_PASS;
	   } else FirstPass = TRUE;
	}

	ppt++; pwidth++;
     }

     SET_SYNC_FLAG(infoRec);
}

#endif

static CARD32 *
StipplePowerOfTwo(
   CARD32* dest, CARD32* src, 
   int shift, int width, int dwords
){
    CARD32 pat = *src;
    if(width < 32) {
	pat &= XAAShiftMasks[width];
	while(width < 32) {
	    pat |= SHIFT_L(pat,width);
	    width <<= 1;
	}
    }
   
    if(shift)
	pat = SHIFT_R(pat,shift) | SHIFT_L(pat,32 - shift);

#ifdef MSBFIRST
    pat = SWAP_BITS_IN_BYTES(pat);    
#endif

#ifdef TRIPLE_BITS
    {
	EXPAND_PAT;

	while(dwords >= 3) {
	    WRITE_PAT3;
	    dwords -= 3;
	}
	if (dwords == 2) {
	    WRITE_PAT2;
	} else if (dwords == 1) {
	    WRITE_PAT1;
	}

	return dest;
    }
#else /* TRIPLE_BITS */
   while(dwords >= 4) {
	DEST(0) = pat;
	DEST(1) = pat;
	DEST(2) = pat;
	DEST(3) = pat;
	dwords -= 4;
#ifndef FIXEDBASE
	dest += 4;
#endif
   }
   
   if(!dwords) return dest;
   DEST(0) = pat;
   if(dwords == 1) RETURN(1);
   DEST(1) = pat;
   if(dwords == 2) RETURN(2);
   DEST(2) = pat;
   RETURN(3);
#endif /* TRIPLE_BITS */
}

static CARD32 *
StipplePowerOfTwo_Inverted(
   CARD32* dest, CARD32* src, 
   int shift, int width, int dwords
){
    CARD32 pat = *src;
    if(width < 32) {
	pat &= XAAShiftMasks[width];
	while(width < 32) {
	    pat |= SHIFT_L(pat,width);
	    width <<= 1;
	}
    }
   
    if(shift)
	pat = SHIFT_R(pat,shift) | SHIFT_L(pat,32 - shift);

#ifdef MSBFIRST
    pat = SWAP_BITS_IN_BYTES(pat);    
#endif

   pat = ~pat;

#ifdef TRIPLE_BITS
    {
	EXPAND_PAT;

	while(dwords >= 3) {
	    WRITE_PAT3;
	    dwords -= 3;
	}
	if (dwords == 2) {
	    WRITE_PAT2;
	} else if (dwords == 1) {
	    WRITE_PAT1;
	}

	return dest;
    }
#else /* TRIPLE_BITS */
   while(dwords >= 4) {
	DEST(0) = pat;
	DEST(1) = pat;
	DEST(2) = pat;
	DEST(3) = pat;
	dwords -= 4;
#ifndef FIXEDBASE
	dest += 4;
#endif
   }
   
   if(!dwords) return dest;
   DEST(0) = pat;
   if(dwords == 1) RETURN(1);
   DEST(1) = pat;
   if(dwords == 2) RETURN(2);
   DEST(2) = pat;
   RETURN(3);
#endif /* TRIPLE_BITS */
}


static CARD32 *
StippleUpTo32(
   CARD32* base, CARD32* src, 
   int shift, int width, int dwords
){
    CARD32 pat = *src & XAAShiftMasks[width];

    while(width <= 15) {
	pat |= SHIFT_L(pat,width);
	width <<= 1;
    }
    pat |= SHIFT_L(pat,width);

    while(dwords--) {
	CARD32 bits = SHIFT_R(pat,shift) | SHIFT_L(pat,width-shift);
#ifdef TRIPLE_BITS
	if(dwords >= 2) {
	    WRITE_BITS3(bits);
	    dwords -= 2;
	} else if(dwords > 0) {
	    WRITE_BITS2(bits);
	    dwords--;
	} else {
	    WRITE_BITS1(bits);
	}
#else
	WRITE_BITS(bits);
#endif

	shift += 32;
	shift %= width;
    }
    return base;
}


static CARD32 *
StippleUpTo32_Inverted(
   CARD32* base, CARD32* src, 
   int shift, int width, int dwords
){
    CARD32 pat = *src & XAAShiftMasks[width];

    while(width <= 15) {
	pat |= SHIFT_L(pat,width);
	width <<= 1;
    }
    pat |= SHIFT_L(pat,width);

    while(dwords--) {
	CARD32 bits = ~(SHIFT_R(pat,shift) | SHIFT_L(pat,width-shift));
#ifdef TRIPLE_BITS
	if(dwords >= 2) {
	    WRITE_BITS3(bits);
	    dwords -= 2;
	} else if(dwords > 0) {
	    WRITE_BITS2(bits);
	    dwords--;
	} else {
	    WRITE_BITS1(bits);
	}
#else
	WRITE_BITS(bits);
#endif

	shift += 32;
	shift %= width;
    }
    return base;
}


static CARD32 *
StippleOver32(
   CARD32* base, CARD32* src, 
   int offset, int width, int dwords
){
   CARD32* srcp;
   CARD32 bits;
   int bitsleft, shift, usable;   

   while(dwords--) {
        bitsleft = width - offset;
        srcp = src + (offset >> 5);
        shift = offset & 31;
        usable = 32 - shift;

        if(bitsleft < 32) {
            if(bitsleft <= usable) {
                 bits = SHIFT_L(*src,bitsleft) | 
                       (SHIFT_R(*srcp,shift) & XAAShiftMasks[bitsleft]);
            } else {
                 bits = SHIFT_L(*src,bitsleft) |
                       (SHIFT_L(srcp[1],usable) & XAAShiftMasks[bitsleft]) |
                       (SHIFT_R(*srcp,shift) & XAAShiftMasks[usable]);
            }
        }
        else if(shift)
            bits = SHIFT_R(*srcp,shift) | SHIFT_L(srcp[1],usable);
        else
            bits = *srcp;

#ifdef TRIPLE_BITS
	if(dwords >= 2) {
	    WRITE_BITS3(bits);
	    dwords -= 2;
	} else if(dwords > 0) {
	    WRITE_BITS2(bits);
	    dwords--;
	} else {
	    WRITE_BITS1(bits);
	}
#else
	WRITE_BITS(bits);
#endif

	offset += 32;
	offset %= width;
   }
   return base;
}


static CARD32 *
StippleOver32_Inverted(
   CARD32* base, CARD32* src, 
   int offset, int width, int dwords
){
   CARD32* srcp;
   CARD32 bits;
   int bitsleft, shift, usable;

   while(dwords--) {
        bitsleft = width - offset;
        srcp = src + (offset >> 5);
        shift = offset & 31;
        usable = 32 - shift;

        if(bitsleft < 32) {
            if(bitsleft <= usable) {
                 bits = SHIFT_L(*src,bitsleft) |
                       (SHIFT_R(*srcp,shift) & XAAShiftMasks[bitsleft]);
            } else {
                 bits = SHIFT_L(*src,bitsleft) |
                       (SHIFT_L(srcp[1],usable) & XAAShiftMasks[bitsleft]) |
                       (SHIFT_R(*srcp,shift) & XAAShiftMasks[usable]);
            }
        }
        else if(shift)
            bits = SHIFT_R(*srcp,shift) | SHIFT_L(srcp[1],usable);
        else
            bits = *srcp;

	bits = ~bits;

#ifdef TRIPLE_BITS
	if(dwords >= 2) {
	    WRITE_BITS3(bits);
	    dwords -= 2;
	} else if(dwords > 0) {
	    WRITE_BITS2(bits);
	    dwords--;
	} else {
	    WRITE_BITS1(bits);
	}
#else
	WRITE_BITS(bits);
#endif

	offset += 32;
	offset %= width;
   }
   return base;
}

--- NEW FILE: xaaTEGlyph.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaTEGlyph.c,v 1.7 1999/11/06 23:14:46 mvojkovi Exp $ */


#include "xaa.h"
#include "xaalocal.h"
#include "xaacexp.h"
#include "xf86.h"
#include "xf86_ansic.h"


/* scanline function for TRIPLE_BITS_24BPP */
static CARD32 *DrawTextScanline3(CARD32 *base, CARD32 *mem, int width);

/* Loop unrolled functions for common font widths */
static CARD32 *DrawTETextScanlineGeneric(CARD32 *base, unsigned int **glyphp,
					int line, int width, int glyphwidth);
static CARD32 *DrawTETextScanlineWidth7(CARD32 *base, unsigned int **glyphp,
					int line, int width, int glyphwidth);
static CARD32 *DrawTETextScanlineWidth10(CARD32 *base, unsigned int **glyphp,
[...1033 lines suppressed...]
        WRITE_IN_BITORDER(base, 0, bits);
	CHECKRETURN(1);	
        bits = SHIFT_R(glyphp[1][line],8);
        bits |= SHIFT_L(glyphp[2][line],16);
        WRITE_IN_BITORDER(base, 1, bits);
	CHECKRETURN(2);	
        bits = SHIFT_R(glyphp[2][line],16);
        bits |= SHIFT_L(glyphp[3][line],8);
        WRITE_IN_BITORDER(base, 2, bits);
	CHECKRETURN(3);	
#ifndef FIXEDBASE
        base += 3;
#endif
        width -= 96;
        glyphp += 4;
    }
    return base;
}



--- NEW FILE: xaaTEText.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaTEText.c,v 1.6 1998/12/20 11:57:52 dawes Exp $ */

/********************************************************************

   In this file we have GC level replacements for PolyText8/16,
   ImageText8/16, ImageGlyphBlt and PolyGlyphBlt for TE (fixed) fonts.
   The idea is that everything in this file is device independent.
   The mentioned GCOps are merely wrappers for XAAGlyphBltTEColorExpansion
   which calculates the boxes containing arbitrarily clipped text
   and passes them to the TEGlyphRenderer which will usually be a lower 
   level XAA function which renders these clipped glyphs using
   the basic color expansion functions exported by the chipset driver.
   The TEGlyphRenderer itself may optionally be driver supplied to
   facilitate work-arounds/optimizations at a higher level than usual.

   v1.0 - Mark Vojkovich (mvojkovi at ucsd.edu)


********************************************************************/

#include "misc.h"
#include "xf86.h"
#include "xf86_ansic.h"
#include "xf86_OSproc.h"

#include <X11/X.h>
#include "font.h"
#include "scrnintstr.h"
#include "dixfontstr.h"
#include "xf86str.h"
#include "xaa.h"
#include "xaalocal.h"
#include "gcstruct.h"
#include "pixmapstr.h"


static void XAAGlyphBltTEColorExpansion(ScrnInfoPtr pScrn, int xInit,
			int yInit, FontPtr font, int fg, int bg, int rop,
			unsigned int planemask, RegionPtr cclip, int nglyph,
			unsigned char* gBase, CharInfoPtr *ppci);


/********************************************************************

   GC level replacements for PolyText8/16 and ImageText8/16
   for TE fonts when using color expansion.

********************************************************************/


int
XAAPolyText8TEColorExpansion(
    DrawablePtr pDraw,
    GCPtr pGC,
    int	x, int y,
    int count,
    char *chars )
{
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
    unsigned long n;

    (*pGC->font->get_glyphs)(pGC->font, (unsigned long)count, 
		(unsigned char *)chars, Linear8Bit, &n, infoRec->CharInfo);

    /* we have divorced XAAGlyphBltTEColorExpansion from the drawable */
    if(n) XAAGlyphBltTEColorExpansion(
	infoRec->pScrn, x + pDraw->x, y + pDraw->y,
	pGC->font, pGC->fgPixel, -1, pGC->alu, pGC->planemask, 
	pGC->pCompositeClip, n, FONTGLYPHS(pGC->font), infoRec->CharInfo);

    return (x + (n * FONTMAXBOUNDS(pGC->font, characterWidth)));
}


int
XAAPolyText16TEColorExpansion(
    DrawablePtr pDraw,
    GCPtr pGC,
    int	x, int y,
    int count,
    unsigned short *chars )
{
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
    unsigned long n;

    (*pGC->font->get_glyphs)(
		pGC->font, (unsigned long)count, (unsigned char *)chars,
		(FONTLASTROW(pGC->font) == 0) ? Linear16Bit : TwoD16Bit,
		&n, infoRec->CharInfo);

    if(n) XAAGlyphBltTEColorExpansion(
	infoRec->pScrn, x + pDraw->x, y + pDraw->y,
	pGC->font, pGC->fgPixel, -1, pGC->alu, pGC->planemask, 
	pGC->pCompositeClip, n, FONTGLYPHS(pGC->font), infoRec->CharInfo);

    return (x + (n * FONTMAXBOUNDS(pGC->font, characterWidth)));
}


void
XAAImageText8TEColorExpansion(
    DrawablePtr pDraw,
    GCPtr pGC,
    int	x, int y,
    int count,
    char *chars )
{
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
    unsigned long n;

    if(!REGION_NUM_RECTS(pGC->pCompositeClip))
	return;

    (*pGC->font->get_glyphs)(pGC->font, (unsigned long)count, 
		(unsigned char *)chars, Linear8Bit, &n, infoRec->CharInfo);

    if(n) XAAGlyphBltTEColorExpansion(
	infoRec->pScrn, x + pDraw->x, y + pDraw->y,
	pGC->font, pGC->fgPixel, pGC->bgPixel, GXcopy, pGC->planemask, 
	pGC->pCompositeClip, n, FONTGLYPHS(pGC->font), infoRec->CharInfo);
}


void
XAAImageText16TEColorExpansion(
    DrawablePtr pDraw,
    GCPtr pGC,
    int	x, int y,
    int count,
    unsigned short *chars )
{
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
    unsigned long n;

    if(!REGION_NUM_RECTS(pGC->pCompositeClip))
	return;

    (*pGC->font->get_glyphs)(
	      pGC->font, (unsigned long)count, (unsigned char *)chars,
	      (FONTLASTROW(pGC->font) == 0) ? Linear16Bit : TwoD16Bit,
	      &n, infoRec->CharInfo);

    if(n) XAAGlyphBltTEColorExpansion(
	infoRec->pScrn, x + pDraw->x, y + pDraw->y,
	pGC->font, pGC->fgPixel, pGC->bgPixel, GXcopy, pGC->planemask, 
	pGC->pCompositeClip, n, FONTGLYPHS(pGC->font), infoRec->CharInfo);
}



/********************************************************************

   GC level replacements for ImageGlyphBlt and PolyGlyphBlt for
   TE fonts when using color expansion.

********************************************************************/


void
XAAImageGlyphBltTEColorExpansion(
    DrawablePtr pDrawable,
    GCPtr pGC,
    int xInit, int yInit,
    unsigned int nglyph,
    CharInfoPtr *ppci,
    pointer pglyphBase )
{
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);

    if(!REGION_NUM_RECTS(pGC->pCompositeClip))
	return;

    XAAGlyphBltTEColorExpansion(
	infoRec->pScrn, xInit + pDrawable->x, yInit + pDrawable->y,
	pGC->font, pGC->fgPixel, pGC->bgPixel, GXcopy, pGC->planemask, 
	pGC->pCompositeClip, nglyph, (unsigned char*)pglyphBase, ppci);
}

void
XAAPolyGlyphBltTEColorExpansion(
    DrawablePtr pDrawable,
    GCPtr pGC,
    int xInit, int yInit,
    unsigned int nglyph,
    CharInfoPtr *ppci,
    pointer pglyphBase )
{
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);

    if(!REGION_NUM_RECTS(pGC->pCompositeClip))
	return;

    XAAGlyphBltTEColorExpansion(
	infoRec->pScrn, xInit + pDrawable->x, yInit + pDrawable->y,
	pGC->font, pGC->fgPixel, -1, pGC->alu, pGC->planemask, 
	pGC->pCompositeClip, nglyph, (unsigned char*)pglyphBase, ppci);
}




/********************************************************************

   XAAGlyphBltTEColorExpansion -

   This guy computes the clipped pieces of text and sends it to
   the lower-level function which will handle acceleration of 
   arbitrarily clipped text.
  
********************************************************************/


static void
XAAGlyphBltTEColorExpansion(
   ScrnInfoPtr pScrn,
   int xInit, int yInit,
   FontPtr font,
   int fg, int bg,
   int rop,
   unsigned int planemask,
   RegionPtr cclip,
   int nglyph,
   unsigned char* gBase,
   CharInfoPtr *ppci )
{
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
    int skippix, skipglyphs;
    int Left, Right, Top, Bottom;
    int LeftEdge, RightEdge, ytop, ybot;
    int nbox = REGION_NUM_RECTS(cclip);
    BoxPtr pbox = REGION_RECTS(cclip);
    unsigned int **glyphs = NULL; 
    int glyphWidth = FONTMAXBOUNDS(font, characterWidth);

    /* find the size of the box */
    Left = xInit;
    Right = Left + (glyphWidth * nglyph);
    Top = yInit - FONTASCENT(font);
    Bottom =  yInit + FONTDESCENT(font);

    /* get into the first band that may contain part of our string */
    while(nbox && (Top >= pbox->y2)) {
	pbox++; nbox--;
    }

    /* stop when the lower edge of the box is beyond our string */
    while(nbox && (Bottom > pbox->y1)) {
	LeftEdge = max(Left, pbox->x1);
	RightEdge = min(Right, pbox->x2);

	if(RightEdge > LeftEdge) {	/* we have something to draw */
	    ytop = max(Top, pbox->y1);
	    ybot = min(Bottom, pbox->y2);
	    
	    if((skippix = LeftEdge - Left)) {
		skipglyphs = skippix/glyphWidth;
		skippix %= glyphWidth;
	    } else skipglyphs = 0;

	    if(!glyphs) {
		int count;
		glyphs = (unsigned int**)(infoRec->PreAllocMem);

		for(count = 0; count < nglyph; count++) 
 			glyphs[count] = (unsigned int*) 
				FONTGLYPHBITS(gBase,*ppci++);

		/* our new unrolled TE code only writes DWORDS at a time 
		   so it can read up to 6 characters past the last one 
		   we're displaying */
		glyphs[count + 0] = glyphs[0];
		glyphs[count + 1] = glyphs[0];
		glyphs[count + 2] = glyphs[0];
		glyphs[count + 3] = glyphs[0];
		glyphs[count + 4] = glyphs[0];
		glyphs[count + 5] = glyphs[0];
	    }

   /* x, y, w, h, skipleft, skiptop, glyphp, glyphWidth, fg, bg, rop, pm */

	    (*infoRec->TEGlyphRenderer)( pScrn, 
		LeftEdge, ytop, RightEdge - LeftEdge, ybot - ytop, 
		skippix, ytop - Top, glyphs + skipglyphs, glyphWidth, 
		fg, bg, rop, planemask); 
	}

	nbox--; pbox++;
    }
}





--- NEW FILE: xaaTables.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaTables.c,v 1.1.2.1 1998/07/12 09:43:04 dawes Exp $ */

/*
 * This is a table of 24-bit values, indexed with an 8-bit byte value, then
 * expands each bit to three consecutive bits. This is required for color
 * expansion in 24bpp mode with the coprocessor in 8bpp mode, with LSB-first
 * bit order within a byte.
 */

unsigned int byte_expand3[256] =
{
    0x000000, 0x000007, 0x000038, 0x00003F, 0x0001C0, 0x0001C7, 0x0001F8, 0x0001FF,
    0x000E00, 0x000E07, 0x000E38, 0x000E3F, 0x000FC0, 0x000FC7, 0x000FF8, 0x000FFF,
    0x007000, 0x007007, 0x007038, 0x00703F, 0x0071C0, 0x0071C7, 0x0071F8, 0x0071FF,
    0x007E00, 0x007E07, 0x007E38, 0x007E3F, 0x007FC0, 0x007FC7, 0x007FF8, 0x007FFF,
    0x038000, 0x038007, 0x038038, 0x03803F, 0x0381C0, 0x0381C7, 0x0381F8, 0x0381FF,
    0x038E00, 0x038E07, 0x038E38, 0x038E3F, 0x038FC0, 0x038FC7, 0x038FF8, 0x038FFF,
    0x03F000, 0x03F007, 0x03F038, 0x03F03F, 0x03F1C0, 0x03F1C7, 0x03F1F8, 0x03F1FF,
    0x03FE00, 0x03FE07, 0x03FE38, 0x03FE3F, 0x03FFC0, 0x03FFC7, 0x03FFF8, 0x03FFFF,
    0x1C0000, 0x1C0007, 0x1C0038, 0x1C003F, 0x1C01C0, 0x1C01C7, 0x1C01F8, 0x1C01FF,
    0x1C0E00, 0x1C0E07, 0x1C0E38, 0x1C0E3F, 0x1C0FC0, 0x1C0FC7, 0x1C0FF8, 0x1C0FFF,
    0x1C7000, 0x1C7007, 0x1C7038, 0x1C703F, 0x1C71C0, 0x1C71C7, 0x1C71F8, 0x1C71FF,
    0x1C7E00, 0x1C7E07, 0x1C7E38, 0x1C7E3F, 0x1C7FC0, 0x1C7FC7, 0x1C7FF8, 0x1C7FFF,
    0x1F8000, 0x1F8007, 0x1F8038, 0x1F803F, 0x1F81C0, 0x1F81C7, 0x1F81F8, 0x1F81FF,
    0x1F8E00, 0x1F8E07, 0x1F8E38, 0x1F8E3F, 0x1F8FC0, 0x1F8FC7, 0x1F8FF8, 0x1F8FFF,
    0x1FF000, 0x1FF007, 0x1FF038, 0x1FF03F, 0x1FF1C0, 0x1FF1C7, 0x1FF1F8, 0x1FF1FF,
    0x1FFE00, 0x1FFE07, 0x1FFE38, 0x1FFE3F, 0x1FFFC0, 0x1FFFC7, 0x1FFFF8, 0x1FFFFF,
    0xE00000, 0xE00007, 0xE00038, 0xE0003F, 0xE001C0, 0xE001C7, 0xE001F8, 0xE001FF,
    0xE00E00, 0xE00E07, 0xE00E38, 0xE00E3F, 0xE00FC0, 0xE00FC7, 0xE00FF8, 0xE00FFF,
    0xE07000, 0xE07007, 0xE07038, 0xE0703F, 0xE071C0, 0xE071C7, 0xE071F8, 0xE071FF,
    0xE07E00, 0xE07E07, 0xE07E38, 0xE07E3F, 0xE07FC0, 0xE07FC7, 0xE07FF8, 0xE07FFF,
    0xE38000, 0xE38007, 0xE38038, 0xE3803F, 0xE381C0, 0xE381C7, 0xE381F8, 0xE381FF,
    0xE38E00, 0xE38E07, 0xE38E38, 0xE38E3F, 0xE38FC0, 0xE38FC7, 0xE38FF8, 0xE38FFF,
    0xE3F000, 0xE3F007, 0xE3F038, 0xE3F03F, 0xE3F1C0, 0xE3F1C7, 0xE3F1F8, 0xE3F1FF,
    0xE3FE00, 0xE3FE07, 0xE3FE38, 0xE3FE3F, 0xE3FFC0, 0xE3FFC7, 0xE3FFF8, 0xE3FFFF,
    0xFC0000, 0xFC0007, 0xFC0038, 0xFC003F, 0xFC01C0, 0xFC01C7, 0xFC01F8, 0xFC01FF,
    0xFC0E00, 0xFC0E07, 0xFC0E38, 0xFC0E3F, 0xFC0FC0, 0xFC0FC7, 0xFC0FF8, 0xFC0FFF,
    0xFC7000, 0xFC7007, 0xFC7038, 0xFC703F, 0xFC71C0, 0xFC71C7, 0xFC71F8, 0xFC71FF,
    0xFC7E00, 0xFC7E07, 0xFC7E38, 0xFC7E3F, 0xFC7FC0, 0xFC7FC7, 0xFC7FF8, 0xFC7FFF,
    0xFF8000, 0xFF8007, 0xFF8038, 0xFF803F, 0xFF81C0, 0xFF81C7, 0xFF81F8, 0xFF81FF,
    0xFF8E00, 0xFF8E07, 0xFF8E38, 0xFF8E3F, 0xFF8FC0, 0xFF8FC7, 0xFF8FF8, 0xFF8FFF,
    0xFFF000, 0xFFF007, 0xFFF038, 0xFFF03F, 0xFFF1C0, 0xFFF1C7, 0xFFF1F8, 0xFFF1FF,
    0xFFFE00, 0xFFFE07, 0xFFFE38, 0xFFFE3F, 0xFFFFC0, 0xFFFFC7, 0xFFFFF8, 0xFFFFFF
};

/*
 * This is a table of 24-bit values, indexed with an 8-bit byte value,
 * that reverses the bit order of a byte and then expands each bit to three
 * consecutive bits. This is required for color expansion in 24bpp mode
 * with the coprocessor in 8bpp mode, with MSB-first bit order within a
 * byte.
 */

unsigned int byte_reversed_expand3[256] =
{
    0x000000, 0x0000E0, 0x00001C, 0x0000FC, 0x008003, 0x0080E3, 0x00801F, 0x0080FF,
    0x007000, 0x0070E0, 0x00701C, 0x0070FC, 0x00F003, 0x00F0E3, 0x00F01F, 0x00F0FF,
    0x000E00, 0x000EE0, 0x000E1C, 0x000EFC, 0x008E03, 0x008EE3, 0x008E1F, 0x008EFF,
    0x007E00, 0x007EE0, 0x007E1C, 0x007EFC, 0x00FE03, 0x00FEE3, 0x00FE1F, 0x00FEFF,
    0xC00100, 0xC001E0, 0xC0011C, 0xC001FC, 0xC08103, 0xC081E3, 0xC0811F, 0xC081FF,
    0xC07100, 0xC071E0, 0xC0711C, 0xC071FC, 0xC0F103, 0xC0F1E3, 0xC0F11F, 0xC0F1FF,
    0xC00F00, 0xC00FE0, 0xC00F1C, 0xC00FFC, 0xC08F03, 0xC08FE3, 0xC08F1F, 0xC08FFF,
    0xC07F00, 0xC07FE0, 0xC07F1C, 0xC07FFC, 0xC0FF03, 0xC0FFE3, 0xC0FF1F, 0xC0FFFF,
    0x380000, 0x3800E0, 0x38001C, 0x3800FC, 0x388003, 0x3880E3, 0x38801F, 0x3880FF,
    0x387000, 0x3870E0, 0x38701C, 0x3870FC, 0x38F003, 0x38F0E3, 0x38F01F, 0x38F0FF,
    0x380E00, 0x380EE0, 0x380E1C, 0x380EFC, 0x388E03, 0x388EE3, 0x388E1F, 0x388EFF,
    0x387E00, 0x387EE0, 0x387E1C, 0x387EFC, 0x38FE03, 0x38FEE3, 0x38FE1F, 0x38FEFF,
    0xF80100, 0xF801E0, 0xF8011C, 0xF801FC, 0xF88103, 0xF881E3, 0xF8811F, 0xF881FF,
    0xF87100, 0xF871E0, 0xF8711C, 0xF871FC, 0xF8F103, 0xF8F1E3, 0xF8F11F, 0xF8F1FF,
    0xF80F00, 0xF80FE0, 0xF80F1C, 0xF80FFC, 0xF88F03, 0xF88FE3, 0xF88F1F, 0xF88FFF,
    0xF87F00, 0xF87FE0, 0xF87F1C, 0xF87FFC, 0xF8FF03, 0xF8FFE3, 0xF8FF1F, 0xF8FFFF,
    0x070000, 0x0700E0, 0x07001C, 0x0700FC, 0x078003, 0x0780E3, 0x07801F, 0x0780FF,
    0x077000, 0x0770E0, 0x07701C, 0x0770FC, 0x07F003, 0x07F0E3, 0x07F01F, 0x07F0FF,
    0x070E00, 0x070EE0, 0x070E1C, 0x070EFC, 0x078E03, 0x078EE3, 0x078E1F, 0x078EFF,
    0x077E00, 0x077EE0, 0x077E1C, 0x077EFC, 0x07FE03, 0x07FEE3, 0x07FE1F, 0x07FEFF,
    0xC70100, 0xC701E0, 0xC7011C, 0xC701FC, 0xC78103, 0xC781E3, 0xC7811F, 0xC781FF,
    0xC77100, 0xC771E0, 0xC7711C, 0xC771FC, 0xC7F103, 0xC7F1E3, 0xC7F11F, 0xC7F1FF,
    0xC70F00, 0xC70FE0, 0xC70F1C, 0xC70FFC, 0xC78F03, 0xC78FE3, 0xC78F1F, 0xC78FFF,
    0xC77F00, 0xC77FE0, 0xC77F1C, 0xC77FFC, 0xC7FF03, 0xC7FFE3, 0xC7FF1F, 0xC7FFFF,
    0x3F0000, 0x3F00E0, 0x3F001C, 0x3F00FC, 0x3F8003, 0x3F80E3, 0x3F801F, 0x3F80FF,
    0x3F7000, 0x3F70E0, 0x3F701C, 0x3F70FC, 0x3FF003, 0x3FF0E3, 0x3FF01F, 0x3FF0FF,
    0x3F0E00, 0x3F0EE0, 0x3F0E1C, 0x3F0EFC, 0x3F8E03, 0x3F8EE3, 0x3F8E1F, 0x3F8EFF,
    0x3F7E00, 0x3F7EE0, 0x3F7E1C, 0x3F7EFC, 0x3FFE03, 0x3FFEE3, 0x3FFE1F, 0x3FFEFF,
    0xFF0100, 0xFF01E0, 0xFF011C, 0xFF01FC, 0xFF8103, 0xFF81E3, 0xFF811F, 0xFF81FF,
    0xFF7100, 0xFF71E0, 0xFF711C, 0xFF71FC, 0xFFF103, 0xFFF1E3, 0xFFF11F, 0xFFF1FF,
    0xFF0F00, 0xFF0FE0, 0xFF0F1C, 0xFF0FFC, 0xFF8F03, 0xFF8FE3, 0xFF8F1F, 0xFF8FFF,
    0xFF7F00, 0xFF7FE0, 0xFF7F1C, 0xFF7FFC, 0xFFFF03, 0xFFFFE3, 0xFFFF1F, 0xFFFFFF, 
};

--- NEW FILE: xaaWideLine.c ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaWideLine.c,v 1.10 2001/11/16 16:47:56 dawes Exp $ */

/*

XAAPolylinesWideSolid does not maintain a span list and subsequently does
not follow the "touch-each-pixel-once" rules for wide lines and arcs.
This means it can only be used in the case where we have
miSpansEasyRop(pGC->alu).  Since we clip spans on the fly, we
limited usage of this function to one rect situations. This
function is used only for solid lines. 

  Adapted from miWideLine by Mark Vojkovich (mvojkovi at ucsd.edu)
Original mi code written by Keith Packard.

*/

#ifndef XFree86LOADER
#if defined(_XOPEN_SOURCE) || defined(__QNXNTO__)
#include <math.h>
#else
#define _XOPEN_SOURCE	/* to get prototype for hypot on some systems */
#include <math.h>
#undef _XOPEN_SOURCE
#endif
#endif

#include "misc.h"
#include "xf86.h"
#include "xf86_ansic.h"
#include "xf86_OSproc.h"

#include <X11/X.h>
#include "windowstr.h"
#include "gcstruct.h"
#include "regionstr.h"
#include "miwideline.h"
#include "mi.h"
#include "xf86str.h"
#include "xaa.h"
#include "xaalocal.h"

#ifdef ICEILTEMPDECL
ICEILTEMPDECL
#endif

#define DRAW_POINT(pScrn, x, y) \
  if(hardClip) (*infoRec->SubsequentSolidFillRect)(pScrn, x, y, 1, 1); \
  else XAAPointHelper(pScrn, x, y)

#define FILL_RECT(pScrn, x, y, w, h) \
  if(hardClip) (*infoRec->SubsequentSolidFillRect)(pScrn, x, y, w, h); \
  else XAAFillRectHelper(pScrn, x, y, w, h)

#define FILL_SPAN(pScrn, x, y, w) \
  if(hardClip) (*infoRec->SubsequentSolidFillRect)(pScrn, x, y, w, 1); \
  else XAASpanHelper(pScrn, x, y, w)


#define CLIPSTEPEDGE(edgey,edge,edgeleft) \
    if (ybase == edgey) { \
	if (edgeleft) { \
	    if (edge->x > xcl) \
		xcl = edge->x; \
	} else { \
	    if (edge->x < xcr) \
		xcr = edge->x; \
	} \
	edgey++; \
	edge->x += edge->stepx; \
	edge->e += edge->dx; \
	if (edge->e > 0) { \
	    edge->x += edge->signdx; \
	    edge->e -= edge->dy; \
	} \
    }

static void 
XAAPointHelper(ScrnInfoPtr pScrn, int x, int y)
{
   XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
   BoxPtr extents = infoRec->ClipBox;

   if((x >= extents->x1) && (x < extents->x2) &&
	(y >= extents->y1) && (y < extents->y2))
	(*infoRec->SubsequentSolidFillRect)(pScrn, x, y, 1, 1);
}

static void 
XAAFillRectHelper(ScrnInfoPtr pScrn, int x1, int y1, int dx, int dy)
{
   XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
   BoxPtr extents = infoRec->ClipBox;
   int x2 = x1 + dx;
   int y2 = y1 + dy;
	
   if(x1 < extents->x1) x1 = extents->x1;
   if(x2 >= extents->x2) x2 = extents->x2;
   if((dx = x2 - x1)<1) return;
   if(y1 < extents->y1) y1 = extents->y1;
   if(y2 >= extents->y2) y2 = extents->y2;
   if((dy = y2 - y1)<1) return;

   (*infoRec->SubsequentSolidFillRect)(pScrn, x1, y1, dx, dy);
}


static void 
XAASpanHelper(ScrnInfoPtr pScrn, int x1, int y, int width)
{
   XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
   BoxPtr extents = infoRec->ClipBox;
    int x2;

    if((y < extents->y1) || (y >= extents->y2)) return;

    x2 = x1 + width;
    if(x1 < extents->x1) x1 = extents->x1;
    if(x2 > extents->x2) x2 = extents->x2;
    width = x2 - x1;	

    if(width > 0)	
 	(*infoRec->SubsequentSolidFillRect)(pScrn, x1, y, width, 1);

}

#define FixError(x, dx, dy, e, sign, step, h)	{	\
	   e += (h) * dx;				\
	   x += (h) * step;				\
	   if(e > 0) {					\
		x += e * sign/dy;			\
		e %= dy;				\
	   	if(e) {					\
		   x += sign;				\
		   e -= dy;				\
		}					\
	   } 	 					\
}


static void
XAAFillPolyHelper (
    GCPtr	pGC,
    int		y,			/* start y coordinate */
    int		overall_height,		/* height of entire segment */
    PolyEdgePtr	left, PolyEdgePtr right,
    int	left_count, int right_count )
{
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
    BoxPtr extents = infoRec->ClipBox;
    int left_x, left_e, left_stepx, left_signdx, left_dy, left_dx;
    int right_x, right_e, right_stepx, right_signdx, right_dy, right_dx;
    int	height, left_height, right_height;
    int	xorg;
    Bool hardClip;

    if((y >= extents->y2) || ((y + overall_height) <= extents->y1))
	return;

    /* Muffle compiler */
    left_x = left_e = left_stepx = left_signdx = left_dy = left_dx = 0;
    right_x = right_e = right_stepx = right_signdx = right_dy = right_dx = 0;

    left_height = right_height = 0;
    xorg = 0;

    hardClip = (infoRec->ClippingFlags & HARDWARE_CLIP_SOLID_FILL);
    
    while ((left_count || left_height) && (right_count || right_height)) {
  	if (!left_height && left_count) { 
	    left_height = left->height; 
	    left_x = left->x + xorg; 
	    left_stepx = left->stepx; 
	    left_signdx = left->signdx; 
	    left_e = left->e; 
	    left_dy = left->dy; 
	    left_dx = left->dx; 
	    left_count--; 
	    left++;
	}
	if (!right_height && right_count) { 
	    right_height = right->height; 
	    right_x = right->x + xorg + 1; 
	    right_stepx = right->stepx; 
	    right_signdx = right->signdx; 
	    right_e = right->e; 
	    right_dy = right->dy; 
	    right_dx = right->dx; 
	    right_count--; 
	    right++; 
	}

	height = (left_height > right_height) ? right_height : left_height;

	left_height -= height;
	right_height -= height;

	if(hardClip && infoRec->SubsequentSolidFillTrap && (height > 6)) {
	    int right_DX, left_DX;

    	    right_DX = (right_dx * right_signdx) + (right_stepx * right_dy);
	    left_DX = (left_dx * left_signdx) + (left_stepx * left_dy);

	    (*infoRec->SubsequentSolidFillTrap)(infoRec->pScrn, y, height, 
			left_x, left_DX, left_dy, left_e, 
			right_x - 1, right_DX, right_dy, right_e);

	    FixError(left_x, left_dx, left_dy, left_e, left_signdx, 
			left_stepx, height);
	    FixError(right_x, right_dx, right_dy, right_e, right_signdx,
			right_stepx, height);
	    y += height;
	    continue;
	}

	while (height--) {
	    if(right_x > left_x) {
		FILL_SPAN(infoRec->pScrn, left_x, y, right_x - left_x);
	    }
    	    y++;
    	
 	    left_x += left_stepx; 
	    left_e += left_dx; 
	    if (left_e > 0) { 
		left_x += left_signdx; 
		left_e -= left_dy; 
	    }
	    right_x += right_stepx; 
	    right_e += right_dx; 
	    if (right_e > 0) { 
		right_x += right_signdx; 
		right_e -= right_dy; 
	    }

	}
    }
}



static void
XAAWideSegment (
    GCPtr pGC,
    int  x1, int y1, int x2, int y2,
    Bool projectLeft, Bool projectRight,
    LineFacePtr leftFace, LineFacePtr rightFace )
{
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
    double	l, L, r;
    double	xa, ya;
    double	projectXoff, projectYoff;
    double	k;
    double	maxy;
    int		x, y;
    int		dx, dy;
    int		finaly;
    PolyEdgePtr left, right;
    PolyEdgePtr	top, bottom;
    int		lefty, righty, topy, bottomy;
    int		signdx;
    PolyEdgeRec	lefts[2], rights[2];
    LineFacePtr	tface;
    int		lw = pGC->lineWidth;
    Bool	hardClip = (infoRec->ClippingFlags & HARDWARE_CLIP_SOLID_FILL);

    /* draw top-to-bottom always */
    if ((y2 < y1) || ((y2 == y1) && (x2 < x1))) {
	x = x1;
	x1 = x2;
	x2 = x;

	y = y1;
	y1 = y2;
	y2 = y;

	x = projectLeft;
	projectLeft = projectRight;
	projectRight = x;

	tface = leftFace;
	leftFace = rightFace;
	rightFace = tface;
    }

    dy = y2 - y1;
    signdx = 1;
    dx = x2 - x1;
    if (dx < 0)
	signdx = -1;

    leftFace->x = x1;
    leftFace->y = y1;
    leftFace->dx = dx;
    leftFace->dy = dy;

    rightFace->x = x2;
    rightFace->y = y2;
    rightFace->dx = -dx;
    rightFace->dy = -dy;

    if (!dy) {
	rightFace->xa = 0;
	rightFace->ya = (double) lw / 2.0;
	rightFace->k = -(double) (lw * dx) / 2.0;
	leftFace->xa = 0;
	leftFace->ya = -rightFace->ya;
	leftFace->k = rightFace->k;
	x = x1;
	if (projectLeft)
	    x -= (lw >> 1);
	y = y1 - (lw >> 1);
	dx = x2 - x;
	if (projectRight)
	    dx += ((lw + 1) >> 1);
	dy = lw;
	FILL_RECT(infoRec->pScrn, x, y, dx, dy);	
    } else if (!dx) {
	leftFace->xa =  (double) lw / 2.0;
	leftFace->ya = 0;
	leftFace->k = (double) (lw * dy) / 2.0;
	rightFace->xa = -leftFace->xa;
	rightFace->ya = 0;
	rightFace->k = leftFace->k;
	y = y1;
	if (projectLeft)
	    y -= lw >> 1;
	x = x1 - (lw >> 1);
	dy = y2 - y;
	if (projectRight)
	    dy += ((lw + 1) >> 1);
	dx = lw;
 	FILL_RECT(infoRec->pScrn, x, y, dx, dy);
    } else {
    	l = ((double) lw) / 2.0;
    	L = sqrt((double)(dx*dx + dy*dy));

	if (dx < 0) {
	    right = &rights[1];
	    left = &lefts[0];
	    top = &rights[0];
	    bottom = &lefts[1];
	} else {
	    right = &rights[0];
	    left = &lefts[1];
	    top = &lefts[0];
	    bottom = &rights[1];
	}
	r = l / L;

	/* coord of upper bound at integral y */
	ya = -r * dx;
	xa = r * dy;

	projectXoff = -ya;
	projectYoff = xa;

    	/* xa * dy - ya * dx */
	k = l * L;

	leftFace->xa = xa;
	leftFace->ya = ya;
	leftFace->k = k;
	rightFace->xa = -xa;
	rightFace->ya = -ya;
	rightFace->k = k;

	if (projectLeft)
	    righty = miPolyBuildEdge (xa - projectXoff, ya - projectYoff,
				      k, dx, dy, x1, y1, 0, right);
	else
	    righty = miPolyBuildEdge (xa, ya,
				      k, dx, dy, x1, y1, 0, right);

	/* coord of lower bound at integral y */
	ya = -ya;
	xa = -xa;

	/* xa * dy - ya * dx */
	k = - k;

	if (projectLeft)
	    lefty = miPolyBuildEdge (xa - projectXoff, ya - projectYoff,
				     k, dx, dy, x1, y1, 1, left);
	else
	    lefty = miPolyBuildEdge (xa, ya,
				     k, dx, dy, x1, y1, 1, left);

	/* coord of top face at integral y */

	if (signdx > 0) {
	    ya = -ya;
	    xa = -xa;
	}

	if (projectLeft) {
	    double xap = xa - projectXoff;
	    double yap = ya - projectYoff;
	    topy = miPolyBuildEdge (xap, yap, xap * dx + yap * dy,
				    -dy, dx, x1, y1, dx > 0, top);
	}
	else
	    topy = miPolyBuildEdge(xa, ya, 0.0, 
					-dy, dx, x1, y1, dx > 0, top);

		/* coord of bottom face at integral y */

	if (projectRight) {
	    double xap = xa + projectXoff;
	    double yap = ya + projectYoff;
	    bottomy = miPolyBuildEdge (xap, yap, xap * dx + yap * dy,
				       -dy, dx, x2, y2, dx < 0, bottom);
	    maxy = -ya + projectYoff;
	} else {
	    bottomy = miPolyBuildEdge (xa, ya, 0.0,
					-dy, dx, x2, y2, dx < 0, bottom);
	    maxy = -ya;
	}

	finaly = ICEIL (maxy) + y2;

	if (dx < 0) {
	    left->height = bottomy - lefty;
	    right->height = finaly - righty;
	    top->height = righty - topy;
	} else {
	    right->height =  bottomy - righty;
	    left->height = finaly - lefty;
	    top->height = lefty - topy;
	}
	bottom->height = finaly - bottomy;
	XAAFillPolyHelper (pGC, topy, 
		bottom->height + bottomy - topy, lefts, rights, 2, 2);
    }
}


static void
XAALineArcI (GCPtr pGC, int xorg, int yorg)
{
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
    int x, y, e, ex;
    int slw = pGC->lineWidth;
    Bool hardClip = (infoRec->ClippingFlags & HARDWARE_CLIP_SOLID_FILL);

    y = (slw >> 1) + 1;
    if (slw & 1)
	e = - ((y << 2) + 3);
    else
	e = - (y << 3);
    ex = -4;
    x = 0;
    while (y) {
	e += (y << 3) - 4;
	while (e >= 0) {
	    x++;
	    e += (ex = -((x << 3) + 4));
	}
	y--;
	slw = (x << 1) + 1;
	if ((e == ex) && (slw > 1))
	    slw--;
	    
	FILL_SPAN(infoRec->pScrn, xorg - x, yorg - y, slw);

	if ((y != 0) && ((slw > 1) || (e != ex))) {	
	    FILL_SPAN(infoRec->pScrn, xorg - x, yorg + y, slw);
	}
    }
}


static void
XAALineArcD (
    GCPtr	    pGC,
    double	    xorg,
    double	    yorg,
    PolyEdgePtr	    edge1, 
    int		    edgey1,
    Bool	    edgeleft1,
    PolyEdgePtr	    edge2,
    int		    edgey2,
    Bool	    edgeleft2 )
{
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
    double radius, x0, y0, el, er, yk, xlk, xrk, k;
    int xbase, ybase, y, boty, xl, xr, xcl, xcr;
    int ymin, ymax;
    Bool edge1IsMin, edge2IsMin;
    int ymin1, ymin2;
    Bool hardClip = (infoRec->ClippingFlags & HARDWARE_CLIP_SOLID_FILL);


    xbase = floor(xorg);
    x0 = xorg - xbase;
    ybase = ICEIL (yorg);
    y0 = yorg - ybase;

    xlk = x0 + x0 + 1.0;
    xrk = x0 + x0 - 1.0;
    yk = y0 + y0 - 1.0;
    radius = ((double)pGC->lineWidth) / 2.0;
    y = floor(radius - y0 + 1.0);
    ybase -= y;
    ymin = ybase;
    ymax = 65536;
    edge1IsMin = FALSE;
    ymin1 = edgey1;
    if (edge1->dy >= 0) {
    	if (!edge1->dy) {
	    if (edgeleft1)
	    	edge1IsMin = TRUE;
	    else
	    	ymax = edgey1;
	    edgey1 = 65536;
    	} else if ((edge1->signdx < 0) == edgeleft1)
	    	edge1IsMin = TRUE;
    }
    edge2IsMin = FALSE;
    ymin2 = edgey2;
    if (edge2->dy >= 0) {
    	if (!edge2->dy) {
	    if (edgeleft2)
	    	edge2IsMin = TRUE;
	    else
	    	ymax = edgey2;
	    edgey2 = 65536;
    	} else if ((edge2->signdx < 0) == edgeleft2)
	    	edge2IsMin = TRUE;
    }
    if (edge1IsMin) {
	ymin = ymin1;
	if (edge2IsMin && (ymin1 > ymin2))
	    ymin = ymin2;
    } else if (edge2IsMin)
	ymin = ymin2;
    el = radius * radius - ((y + y0) * (y + y0)) - (x0 * x0);
    er = el + xrk;
    xl = 1;
    xr = 0;
    if (x0 < 0.5) {
	xl = 0;
	el -= xlk;
    }
    boty = (y0 < -0.5) ? 1 : 0;
    if (ybase + y - boty > ymax)
	boty = ymax - ybase - y;
    while (y > boty) {
	k = (y << 1) + yk;
	er += k;
	while (er > 0.0) {
	    xr++;
	    er += xrk - (xr << 1);
	}
	el += k;
	while (el >= 0.0) {
	    xl--;
	    el += (xl << 1) - xlk;
	}
	y--;
	ybase++;
	if (ybase < ymin)
	    continue;
	xcl = xl + xbase;
	xcr = xr + xbase;
	CLIPSTEPEDGE(edgey1, edge1, edgeleft1);
	CLIPSTEPEDGE(edgey2, edge2, edgeleft2);
	if(xcr >= xcl) {
	    FILL_SPAN(infoRec->pScrn, xcl, ybase, xcr - xcl + 1);
	}
    }
    er = xrk - (xr << 1) - er;
    el = (xl << 1) - xlk - el;
    boty = floor(-y0 - radius + 1.0);
    if (ybase + y - boty > ymax)
	boty = ymax - ybase - y;
    while (y > boty) {
	k = (y << 1) + yk;
	er -= k;
	while ((er >= 0.0) && (xr >= 0)) {
	    xr--;
	    er += xrk - (xr << 1);
	}
	el -= k;
	while ((el > 0.0) && (xl <= 0)) {
	    xl++;
	    el += (xl << 1) - xlk;
	}
	y--;
	ybase++;
	if (ybase < ymin)
	    continue;
	xcl = xl + xbase;
	xcr = xr + xbase;
	CLIPSTEPEDGE(edgey1, edge1, edgeleft1);
	CLIPSTEPEDGE(edgey2, edge2, edgeleft2);
	if(xcr >= xcl) {
	    FILL_SPAN(infoRec->pScrn, xcl, ybase, xcr - xcl + 1);
	}
    }
}


static void
XAALineArc (
    GCPtr  pGC,
    LineFacePtr leftFace,
    LineFacePtr rightFace,
    double	xorg,
    double	yorg,
    Bool	isInt )
{
    int xorgi, yorgi;
    PolyEdgeRec	edge1, edge2;
    int		edgey1, edgey2;
    Bool	edgeleft1, edgeleft2;

    if (isInt) {
	xorgi = leftFace ? leftFace->x : rightFace->x;
	yorgi = leftFace ? leftFace->y : rightFace->y;
    } else {	/* Muffle compiler */
        xorgi = yorgi = 0;
    }
    edgey1 = 65536;
    edgey2 = 65536;
    edge1.x = 0; /* not used, keep memory checkers happy */
    edge1.dy = -1;
    edge2.x = 0; /* not used, keep memory checkers happy */
    edge2.dy = -1;
    edgeleft1 = FALSE;
    edgeleft2 = FALSE;

    if ((pGC->lineWidth > 2) &&
	((pGC->capStyle == CapRound && pGC->joinStyle != JoinRound) ||
	 (pGC->joinStyle == JoinRound && pGC->capStyle == CapButt))) {
	if (isInt) {
	    xorg = (double) xorgi;
	    yorg = (double) yorgi;
	}

	if (leftFace && rightFace) 
	    miRoundJoinClip (leftFace, rightFace, &edge1, &edge2,
			     &edgey1, &edgey2, &edgeleft1, &edgeleft2);
	else if (leftFace)
	    edgey1 = miRoundCapClip (leftFace, isInt, &edge1, &edgeleft1);
	else if (rightFace)
	    edgey2 = miRoundCapClip (rightFace, isInt, &edge2, &edgeleft2);

	isInt = FALSE;
    }

    if (isInt) {
	if(pGC->lineWidth == 1) {
	    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
	    Bool hardClip = (infoRec->ClippingFlags & HARDWARE_CLIP_SOLID_FILL);
	    DRAW_POINT(infoRec->pScrn, xorgi, yorgi);
	} else
	    XAALineArcI(pGC, xorgi, yorgi);
    } else
	XAALineArcD(pGC, xorg, yorg, &edge1, edgey1, edgeleft1,
		       &edge2, edgey2, edgeleft2);

}


static void
XAALineJoin (
    GCPtr	    pGC,
    LineFacePtr     pLeft,
    LineFacePtr     pRight )
{
    double	    mx = 0, my = 0;
    double	    denom = 0;
    PolyVertexRec   vertices[4];
    PolySlopeRec    slopes[4];
    int		    edgecount;
    PolyEdgeRec	    left[4], right[4];
    int		    nleft, nright;
    int		    y, height;
    int		    swapslopes;
    int		    joinStyle = pGC->joinStyle;
    int		    lw = pGC->lineWidth;

    if (lw == 1) {
	/* Lines going in the same direction have no join */
	if ((pLeft->dx >= 0) == (pRight->dx <= 0))
	    return;
	if (joinStyle != JoinRound) {
    	    denom = - pLeft->dx * (double)pRight->dy + pRight->dx *
 					(double)pLeft->dy;
    	    if (denom == 0.0)
	    	return;	/* no join to draw */
	}
	if (joinStyle != JoinMiter) {
	    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
	    Bool hardClip = (infoRec->ClippingFlags & HARDWARE_CLIP_SOLID_FILL);
	    DRAW_POINT(infoRec->pScrn, pLeft->x, pLeft->y);	
	    return;
	}
    } else {
    	if (joinStyle == JoinRound) {
	    XAALineArc(pGC, pLeft, pRight,(double)0.0, (double)0.0, TRUE);
	    return;
    	}
    	denom = - pLeft->dx * (double)pRight->dy + pRight->dx * 
				(double)pLeft->dy;
    	if (denom == 0.0)
	    return;	/* no join to draw */
    }

    swapslopes = 0;
    if (denom > 0) {
	pLeft->xa = -pLeft->xa;
	pLeft->ya = -pLeft->ya;
	pLeft->dx = -pLeft->dx;
	pLeft->dy = -pLeft->dy;
    } else {
	swapslopes = 1;
	pRight->xa = -pRight->xa;
	pRight->ya = -pRight->ya;
	pRight->dx = -pRight->dx;
	pRight->dy = -pRight->dy;
    }

    vertices[0].x = pRight->xa;
    vertices[0].y = pRight->ya;
    slopes[0].dx = -pRight->dy;
    slopes[0].dy =  pRight->dx;
    slopes[0].k = 0;

    vertices[1].x = 0;
    vertices[1].y = 0;
    slopes[1].dx =  pLeft->dy;
    slopes[1].dy = -pLeft->dx;
    slopes[1].k = 0;

    vertices[2].x = pLeft->xa;
    vertices[2].y = pLeft->ya;

    if (joinStyle == JoinMiter) {
    	my = (pLeft->dy  * (pRight->xa * pRight->dy - pRight->ya * pRight->dx) -
              pRight->dy * (pLeft->xa  * pLeft->dy  - pLeft->ya  * pLeft->dx ))/
	      denom;
    	if (pLeft->dy != 0) 
	    mx = pLeft->xa + (my - pLeft->ya) *
			    (double) pLeft->dx / (double) pLeft->dy;
    	else
	    mx = pRight->xa + (my - pRight->ya) *
			    (double) pRight->dx / (double) pRight->dy;
    	
	/* check miter limit */
	if ((mx * mx + my * my) * 4 > SQSECANT * lw * lw)
	    joinStyle = JoinBevel;
    }

    if (joinStyle == JoinMiter) {
	slopes[2].dx = pLeft->dx;
	slopes[2].dy = pLeft->dy;
	slopes[2].k =  pLeft->k;
	if (swapslopes) {
	    slopes[2].dx = -slopes[2].dx;
	    slopes[2].dy = -slopes[2].dy;
	    slopes[2].k  = -slopes[2].k;
	}
	vertices[3].x = mx;
	vertices[3].y = my;
	slopes[3].dx = pRight->dx;
	slopes[3].dy = pRight->dy;
	slopes[3].k  = pRight->k;
	if (swapslopes) {
	    slopes[3].dx = -slopes[3].dx;
	    slopes[3].dy = -slopes[3].dy;
	    slopes[3].k  = -slopes[3].k;
	}
	edgecount = 4;
    } else {
	double	scale, dx, dy, adx, ady;

	adx = dx = pRight->xa - pLeft->xa;
	ady = dy = pRight->ya - pLeft->ya;
	if (adx < 0)
	    adx = -adx;
	if (ady < 0)
	    ady = -ady;
	scale = ady;
	if (adx > ady)
	    scale = adx;
	slopes[2].dx = (dx * 65536) / scale;
	slopes[2].dy = (dy * 65536) / scale;
	slopes[2].k = ((pLeft->xa + pRight->xa) * slopes[2].dy -
		       (pLeft->ya + pRight->ya) * slopes[2].dx) / 2.0;
	edgecount = 3;
    }

    y = miPolyBuildPoly (vertices, slopes, edgecount, pLeft->x, pLeft->y,
		   left, right, &nleft, &nright, &height);
    XAAFillPolyHelper(pGC, y, height, left, right, nleft, nright);
}


void
XAAPolylinesWideSolid (
   DrawablePtr  pDrawable,
   GCPtr        pGC,
   int          mode,
   int          npt,
   DDXPointPtr  pPts )
{
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
    int		    x1, y1, x2, y2;
    Bool	    projectLeft, projectRight;
    LineFaceRec	    leftFace, rightFace, prevRightFace, firstFace;
    int    	    first = TRUE;
    Bool	    somethingDrawn = FALSE;
    Bool	    selfJoin = FALSE;
    int		    xorg = pDrawable->x;
    int		    yorg = pDrawable->y;
    Bool	    hardClip = FALSE;

    if(!REGION_NUM_RECTS(pGC->pCompositeClip))
	return;

    if(REGION_NUM_RECTS(pGC->pCompositeClip) != 1) {
	miWideLine(pDrawable, pGC, mode, npt, pPts);
	return;
    }

    if (mode == CoordModePrevious) {
	pPts->x += xorg;
	pPts->y += yorg;
    } else if(xorg | yorg) {
	register int n = npt;
	register DDXPointPtr pts = pPts;

	while(n--) {
	   pts->x += xorg;
	   pts->y += yorg;
	   pts++;
	}
    }

    x2 = pPts->x;
    y2 = pPts->y;
    if (npt > 1) {
    	if (mode == CoordModePrevious) {
	    int nptTmp;
	    register DDXPointPtr pPtsTmp;
    
	    x1 = x2;
	    y1 = y2;
	    nptTmp = npt;
	    pPtsTmp = pPts + 1;
	    while (--nptTmp) {
	    	x1 += pPtsTmp->x;
	    	y1 += pPtsTmp->y;
	    	++pPtsTmp;
	    }
	    if ((x2 == x1) && (y2 == y1))
	    	selfJoin = TRUE;
    	} else if ((x2 == pPts[npt-1].x) && (y2 == pPts[npt-1].y)) 
	    selfJoin = TRUE;
    }

    projectLeft = ((pGC->capStyle == CapProjecting) && !selfJoin);
    projectRight = FALSE;

    (*infoRec->SetupForSolidFill)(infoRec->pScrn, pGC->fgPixel, pGC->alu, 
						pGC->planemask);

    infoRec->ClipBox = &pGC->pCompositeClip->extents;

    if(infoRec->ClippingFlags & HARDWARE_CLIP_SOLID_FILL) {
	hardClip = TRUE;
	(*infoRec->SetClippingRectangle)(infoRec->pScrn,
              infoRec->ClipBox->x1, infoRec->ClipBox->y1, 
              infoRec->ClipBox->x2 - 1, infoRec->ClipBox->y2 - 1);		
    }

    while (--npt) {
	x1 = x2;
	y1 = y2;
	++pPts;
	x2 = pPts->x;
	y2 = pPts->y;
	if (mode == CoordModePrevious) {
	    x2 += x1;
	    y2 += y1;
	}
	if ((x1 != x2) || (y1 != y2)) {
	    somethingDrawn = TRUE;
	    if ((npt == 1) && (pGC->capStyle == CapProjecting) && !selfJoin)
	    	projectRight = TRUE;
	    XAAWideSegment(pGC, x1, y1, x2, y2,
		       	   projectLeft, projectRight, &leftFace, &rightFace);
	    if (first) {
	    	if (selfJoin)
		    firstFace = leftFace;
	    	else if (pGC->capStyle == CapRound) {
		    if (pGC->lineWidth == 1) {
			DRAW_POINT(infoRec->pScrn, x1, y1);
		    } else
		        XAALineArc(pGC,&leftFace, (LineFacePtr) NULL,
 			       	   (double)0.0, (double)0.0,TRUE);
		}
	    } else 
	    	XAALineJoin (pGC, &leftFace, &prevRightFace);

	    prevRightFace = rightFace;
	    first = FALSE;
	    projectLeft = FALSE;
	}
	if (npt == 1 && somethingDrawn) {
	    if (selfJoin)
		XAALineJoin (pGC, &firstFace, &rightFace);
	    else if (pGC->capStyle == CapRound) {
		if (pGC->lineWidth == 1) {
		    DRAW_POINT(infoRec->pScrn, x2, y2);
		} else
		    XAALineArc (pGC, (LineFacePtr) NULL, &rightFace,
			       (double)0.0, (double)0.0,TRUE);
	    }
	}
    }
    /* handle crock where all points are coincedent */
    if (!somethingDrawn) {
	projectLeft = (pGC->capStyle == CapProjecting);
	XAAWideSegment (pGC, x2, y2, x2, y2, projectLeft, projectLeft,
		       &leftFace, &rightFace);
	if (pGC->capStyle == CapRound) {
	    XAALineArc (pGC, &leftFace, (LineFacePtr) NULL,
		       (double)0.0, (double)0.0, TRUE);
	    rightFace.dx = -1;	/* sleezy hack to make it work */
	    XAALineArc (pGC, (LineFacePtr) NULL, &rightFace,
 		       (double)0.0, (double)0.0, TRUE);
	}
   }

   infoRec->ClipBox = NULL;
   if(hardClip)
	(*infoRec->DisableClipping)(infoRec->pScrn);

   SET_SYNC_FLAG(infoRec);
}

--- NEW FILE: xaacexp.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaacexp.h,v 1.3 2000/01/21 02:30:06 dawes Exp $ */


#include <X11/Xarch.h>

#ifndef FIXEDBASE
#define CHECKRETURN(b) if(width <= ((b) * 32)) return(base + (b))
#else
#define CHECKRETURN(b) if(width <= ((b) * 32)) return(base)
#endif

#if X_BYTE_ORDER == X_BIG_ENDIAN
# define SHIFT_L(value, shift) ((value) >> (shift))
# define SHIFT_R(value, shift) ((value) << (shift))
#else
# define SHIFT_L(value, shift) ((value) << (shift))
# define SHIFT_R(value, shift) ((value) >> (shift))
#endif

#ifndef MSBFIRST
# ifdef FIXEDBASE
#   define WRITE_IN_BITORDER(dest, offset, data) *(dest) = data; 
# else  
#   define WRITE_IN_BITORDER(dest, offset, data) *(dest + offset) = data;
# endif
#else	
# ifdef FIXEDBASE
#   define WRITE_IN_BITORDER(dest, offset, data) *(dest) = SWAP_BITS_IN_BYTES(data);
# else  
#   define WRITE_IN_BITORDER(dest, offset, data) *(dest + offset) = SWAP_BITS_IN_BYTES(data)
# endif
#endif

#ifdef FIXEDBASE
# ifdef MSBFIRST
#  define WRITE_BITS(b)   *base = SWAP_BITS_IN_BYTES(b)
#  define WRITE_BITS1(b) { \
	*base = byte_reversed_expand3[(b) & 0xFF] | \
		byte_reversed_expand3[((b) & 0xFF00) >> 8] << 24; }
#  define WRITE_BITS2(b) { \
	*base = byte_reversed_expand3[(b) & 0xFF] | \
		byte_reversed_expand3[((b) & 0xFF00) >> 8] << 24; \
	*base = byte_reversed_expand3[((b) & 0xFF00) >> 8] >> 8 | \
		byte_reversed_expand3[((b) & 0xFF0000) >> 16] << 16; }
#  define WRITE_BITS3(b) { \
	*base = byte_reversed_expand3[(b) & 0xFF] | \
		byte_reversed_expand3[((b) & 0xFF00) >> 8] << 24; \
	*base = byte_reversed_expand3[((b) & 0xFF00) >> 8] >> 8 | \
		byte_reversed_expand3[((b) & 0xFF0000) >> 16] << 16; \
	*base = byte_reversed_expand3[((b) & 0xFF0000) >> 16] >> 16 | \
		byte_reversed_expand3[((b) & 0xFF000000) >> 24] << 8; }
# else
#  define WRITE_BITS(b)   *base = (b)
#  define WRITE_BITS1(b) { \
	*base = byte_expand3[(b) & 0xFF] | \
		byte_expand3[((b) & 0xFF00) >> 8] << 24; }
#  define WRITE_BITS2(b) { \
	*base = byte_expand3[(b) & 0xFF] | \
		byte_expand3[((b) & 0xFF00) >> 8] << 24; \
	*base = byte_expand3[((b) & 0xFF00) >> 8] >> 8 | \
		byte_expand3[((b) & 0xFF0000) >> 16] << 16; }
#  define WRITE_BITS3(b) { \
	*base = byte_expand3[(b) & 0xFF] | \
		byte_expand3[((b) & 0xFF00) >> 8] << 24; \
	*base = byte_expand3[((b) & 0xFF00) >> 8] >> 8 | \
		byte_expand3[((b) & 0xFF0000) >> 16] << 16; \
	*base = byte_expand3[((b) & 0xFF0000) >> 16] >> 16 | \
		byte_expand3[((b) & 0xFF000000) >> 24] << 8; }
# endif
#else
# ifdef MSBFIRST
#  define WRITE_BITS(b)   *(base++) = SWAP_BITS_IN_BYTES(b)
#  define WRITE_BITS1(b) { \
	*(base++) = byte_reversed_expand3[(b) & 0xFF] | \
		byte_reversed_expand3[((b) & 0xFF00) >> 8] << 24; }
#  define WRITE_BITS2(b) { \
	*(base) = byte_reversed_expand3[(b) & 0xFF] | \
		byte_reversed_expand3[((b) & 0xFF00) >> 8] << 24; \
	*(base + 1) = byte_reversed_expand3[((b) & 0xFF00) >> 8] >> 8 | \
		byte_reversed_expand3[((b) & 0xFF0000) >> 16] << 16; \
	base += 2; }
#  define WRITE_BITS3(b) { \
	*(base) = byte_reversed_expand3[(b) & 0xFF] | \
		byte_reversed_expand3[((b) & 0xFF00) >> 8] << 24; \
	*(base + 1) = byte_reversed_expand3[((b) & 0xFF00) >> 8] >> 8 | \
		byte_reversed_expand3[((b) & 0xFF0000) >> 16] << 16; \
	*(base + 2) = byte_reversed_expand3[((b) & 0xFF0000) >> 16] >> 16 | \
		byte_reversed_expand3[((b) & 0xFF000000) >> 24] << 8; \
	base += 3; }
# else
#  define WRITE_BITS(b)   *(base++) = (b)
#  define WRITE_BITS1(b) { \
	*(base++) = byte_expand3[(b) & 0xFF] | \
		byte_expand3[((b) & 0xFF00) >> 8] << 24; }
#  define WRITE_BITS2(b) { \
	*(base) = byte_expand3[(b) & 0xFF] | \
		byte_expand3[((b) & 0xFF00) >> 8] << 24; \
	*(base + 1) = byte_expand3[((b) & 0xFF00) >> 8] >> 8 | \
		byte_expand3[((b) & 0xFF0000) >> 16] << 16; \
	base += 2; }
#  define WRITE_BITS3(b) { \
	*(base) = byte_expand3[(b) & 0xFF] | \
		byte_expand3[((b) & 0xFF00) >> 8] << 24; \
	*(base + 1) = byte_expand3[((b) & 0xFF00) >> 8] >> 8 | \
		byte_expand3[((b) & 0xFF0000) >> 16] << 16; \
	*(base + 2) = byte_expand3[((b) & 0xFF0000) >> 16] >> 16 | \
		byte_expand3[((b) & 0xFF000000) >> 24] << 8; \
	base += 3; }
# endif
#endif

#ifdef FIXEDBASE
# ifdef MSBFIRST
#  define EXPNAME(x) x##MSBFirstFixedBase
# else
#  define EXPNAME(x) x##LSBFirstFixedBase
# endif
#else
# ifdef MSBFIRST
#  define EXPNAME(x) x##MSBFirst
# else
#  define EXPNAME(x) x##LSBFirst
# endif
#endif

--- NEW FILE: xaalocal.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaalocal.h,v 1.36tsi Exp $ */

#ifndef _XAALOCAL_H
#define _XAALOCAL_H

/* This file is very unorganized ! */


#include "gcstruct.h"
#include "regionstr.h"
#include "xf86fbman.h"
#include "xaa.h"
#include "mi.h"
#ifdef RENDER
#include "picturestr.h"
#endif

#define GCWhenForced		(GCArcMode << 1)

[...1717 lines suppressed...]
   int Current256;
   XAACacheInfoPtr Info256;
   int Num128x128;
   int Current128;
   XAACacheInfoPtr Info128;
   int NumMono;
   int CurrentMono;
   XAACacheInfoPtr InfoMono;
   int NumColor;
   int CurrentColor;
   XAACacheInfoPtr InfoColor;
   int NumPartial;
   int CurrentPartial;
   XAACacheInfoPtr InfoPartial;
   DDXPointRec MonoOffsets[64];
   DDXPointRec ColorOffsets[64];
} XAAPixmapCachePrivate, *XAAPixmapCachePrivatePtr;


#endif /* _XAALOCAL_H */

--- NEW FILE: xaarop.h ---
/* $XFree86$ */

/*

   int XAAHelpSolidROP(ScrnInfoPtr pScrn, int *fg, int pm, int *rop)

	For use with solid fills emulated by solid 8x8 patterns.  You 
	give it the foreground, planemask and X rop and it will replace 
	the foreground with a new one and the rop with the appropriate 
	MS triadic raster op.  The function will return which components 
	(S-P) need to be enabled.  


   int XAAHelpPatternROP(ScrnInfoPtr pScrn, int *fg, int *bg, int pm, int *rop)

	For use with 8x8 opaque pattern fills.  You give it the foreground, 	
	and background, planemask and X rop and it will replace the 
	foreground and background with new ones and the rop with the 
	appropriate MS triadic raster op.  The function will return which 
	components (S-P) need to be enabled.  


	   ROP_PAT - Means to enable 8x8 mono patterns (all bits 
		     set for solid patterns).  Set the foreground and
		     background as returned by the function.  

	   ROP_SRC - Means a source of color == planemask should be used.


*/

#ifndef _XAAROP_H
#define _XAAROP_H

#define ROP_DST		0x00000001
#define ROP_SRC		0x00000002
#define ROP_PAT		0x00000004

#define ROP_0		0x00
#define ROP_DPSoon	0x01
#define ROP_DPSona	0x02
#define ROP_PSon	0x03
#define ROP_SDPona	0x04
#define ROP_DPon	0x05
#define ROP_PDSxnon	0x06
#define ROP_PDSaon	0x07
#define ROP_SDPnaa	0x08
#define ROP_PDSxon	0x09
#define ROP_DPna	0x0A
#define ROP_PSDnaon	0x0B
#define ROP_SPna	0x0C
#define ROP_PDSnaon	0x0D
#define ROP_PDSonon	0x0E
#define ROP_Pn		0x0F
#define ROP_PDSona	0x10
#define ROP_DSon	0x11
#define ROP_SDPxnon	0x12
#define ROP_SDPaon	0x13
#define ROP_DPSxnon	0x14
#define ROP_DPSaon	0x15
#define ROP_PSDPSanaxx	0x16
#define ROP_SSPxDSxaxn	0x17
#define ROP_SPxPDxa	0x18
#define ROP_SDPSanaxn	0x19
#define ROP_PDSPaox	0x1A
#define ROP_SDPSxaxn	0x1B
#define ROP_PSDPaox	0x1C
#define ROP_DSPDxaxn	0x1D
#define ROP_PDSox	0x1E
#define ROP_PDSoan	0x1F
#define ROP_DPSnaa	0x20
#define ROP_SDPxon	0x21
#define ROP_DSna	0x22
#define ROP_SPDnaon	0x23
#define ROP_SPxDSxa	0x24
#define ROP_PDSPanaxn	0x25
#define ROP_SDPSaox	0x26
#define ROP_SDPSxnox	0x27
#define ROP_DPSxa	0x28
#define ROP_PSDPSaoxxn	0x29
#define ROP_DPSana	0x2A
#define ROP_SSPxPDxaxn	0x2B
#define ROP_SPDSoax	0x2C
#define ROP_PSDnox	0x2D
#define ROP_PSDPxox	0x2E
#define ROP_PSDnoan	0x2F
#define ROP_PSna	0x30
#define ROP_SDPnaon	0x31
#define ROP_SDPSoox	0x32
#define ROP_Sn		0x33
#define ROP_SPDSaox	0x34
#define ROP_SPDSxnox	0x35
#define ROP_SDPox	0x36
#define ROP_SDPoan	0x37
#define ROP_PSDPoax	0x38
#define ROP_SPDnox	0x39
#define ROP_SPDSxox	0x3A
#define ROP_SPDnoan	0x3B
#define ROP_PSx		0x3C
#define ROP_SPDSonox	0x3D
#define ROP_SPDSnaox	0x3E
#define ROP_PSan	0x3F
#define ROP_PSDnaa	0x40
#define ROP_DPSxon	0x41
#define ROP_SDxPDxa	0x42
#define ROP_SPDSanaxn	0x43
#define ROP_SDna	0x44
#define ROP_DPSnaon	0x45
#define ROP_DSPDaox	0x46
#define ROP_PSDPxaxn	0x47
#define ROP_SDPxa	0x48
#define ROP_PDSPDaoxxn	0x49
#define ROP_DPSDoax	0x4A
#define ROP_PDSnox	0x4B
#define ROP_SDPana	0x4C
#define ROP_SSPxDSxoxn	0x4D
#define ROP_PDSPxox	0x4E
#define ROP_PDSnoan	0x4F
#define ROP_PDna	0x50
#define ROP_DSPnaon	0x51
#define ROP_DPSDaox	0x52
#define ROP_SPDSxaxn	0x53
#define ROP_DPSonon	0x54
#define ROP_Dn		0x55
#define ROP_DPSox	0x56
#define ROP_DPSoan	0x57
#define ROP_PDSPoax	0x58
#define ROP_DPSnox	0x59
#define ROP_DPx		0x5A
#define ROP_DPSDonox	0x5B
#define ROP_DPSDxox	0x5C
#define ROP_DPSnoan	0x5D
#define ROP_DPSDnaox	0x5E
#define ROP_DPan	0x5F
#define ROP_PDSxa	0x60
#define ROP_DSPDSaoxxn	0x61
#define ROP_DSPDoax	0x62
#define ROP_SDPnox	0x63
#define ROP_SDPSoax	0x64
#define ROP_DSPnox	0x65
#define ROP_DSx		0x66
#define ROP_SDPSonox	0x67
#define ROP_DSPDSonoxxn	0x68
#define ROP_PDSxxn	0x69
#define ROP_DPSax	0x6A
#define ROP_PSDPSoaxxn	0x6B
#define ROP_SDPax	0x6C
#define ROP_PDSPDoaxxn	0x6D
#define ROP_SDPSnoax	0x6E
#define ROP_PDSxnan	0x6F
#define ROP_PDSana	0x70
#define ROP_SSDxPDxaxn	0x71
#define ROP_SDPSxox	0x72
#define ROP_SDPnoan	0x73
#define ROP_DSPDxox	0x74
#define ROP_DSPnoan	0x75
#define ROP_SDPSnaox	0x76
#define ROP_DSan	0x77
#define ROP_PDSax	0x78
#define ROP_DSPDSoaxxn	0x79
#define ROP_DPSDnoax	0x7A
#define ROP_SDPxnan	0x7B
#define ROP_SPDSnoax	0x7C
#define ROP_DPSxnan	0x7D
#define ROP_SPxDSxo	0x7E
#define ROP_DPSaan	0x7F
#define ROP_DPSaa	0x80
#define ROP_SPxDSxon	0x81
#define ROP_DPSxna	0x82
#define ROP_SPDSnoaxn	0x83
#define ROP_SDPxna	0x84
#define ROP_PDSPnoaxn	0x85
#define ROP_DSPDSoaxx	0x86
#define ROP_PDSaxn	0x87
#define ROP_DSa		0x88
#define ROP_SDPSnaoxn	0x89
#define ROP_DSPnoa	0x8A
#define ROP_DSPDxoxn	0x8B
#define ROP_SDPnoa	0x8C
#define ROP_SDPSxoxn	0x8D
#define ROP_SSDxPDxax	0x8E
#define ROP_PDSanan	0x8F
#define ROP_PDSxna	0x90
#define ROP_SDPSnoaxn	0x91
#define ROP_DPSDPoaxx	0x92
#define ROP_SPDaxn	0x93
#define ROP_PSDPSoaxx	0x94
#define ROP_DPSaxn	0x95
#define ROP_DPSxx	0x96
#define ROP_PSDPSonoxx	0x97
#define ROP_SDPSonoxn	0x98
#define ROP_DSxn	0x99
#define ROP_DPSnax	0x9A
#define ROP_SDPSoaxn	0x9B
#define ROP_SPDnax	0x9C
#define ROP_DSPDoaxn	0x9D
#define ROP_DSPDSaoxx	0x9E
#define ROP_PDSxan	0x9F
#define ROP_DPa		0xA0
#define ROP_PDSPnaoxn	0xA1
#define ROP_DPSnoa	0xA2
#define ROP_DPSDxoxn	0xA3
#define ROP_PDSPonoxn	0xA4
#define ROP_PDxn	0xA5
#define ROP_DSPnax	0xA6
#define ROP_PDSPoaxn	0xA7
#define ROP_DPSoa	0xA8
#define ROP_DPSoxn	0xA9
#define ROP_D		0xAA
#define ROP_DPSono	0xAB
#define ROP_SPDSxax	0xAC
#define ROP_DPSDaoxn	0xAD
#define ROP_DSPnao	0xAE
#define ROP_DPno	0xAF
#define ROP_PDSnoa	0xB0
#define ROP_PDSPxoxn	0xB1
#define ROP_SSPxDSxox	0xB2
#define ROP_SDPanan	0xB3
#define ROP_PSDnax	0xB4
#define ROP_DPSDoaxn	0xB5
#define ROP_DPSDPaoxx	0xB6
#define ROP_SDPxan	0xB7
#define ROP_PSDPxax	0xB8
#define ROP_DSPDaoxn	0xB9
#define ROP_DPSnao	0xBA
#define ROP_DSno	0xBB
#define ROP_SPDSanax	0xBC
#define ROP_SDxPDxan	0xBD
#define ROP_DPSxo	0xBE
#define ROP_DPSano	0xBF
#define ROP_Psa		0xC0
#define ROP_SPDSnaoxn	0xC1
#define ROP_SPDSonoxn	0xC2
#define ROP_PSxn	0xC3
#define ROP_SPDnoa	0xC4
#define ROP_SPDSxoxn	0xC5
#define ROP_SDPnax	0xC6
#define ROP_PSDPoaxn	0xC7
#define ROP_SDPoa	0xC8
#define ROP_SPDoxn	0xC9
#define ROP_DPSDxax	0xCA
#define ROP_SPDSaoxn	0xCB
#define ROP_S		0xCC
#define ROP_SDPono	0xCD
#define ROP_SDPnao	0xCE
#define ROP_SPno	0xCF
#define ROP_PSDnoa	0xD0
#define ROP_PSDPxoxn	0xD1
#define ROP_PDSnax	0xD2
#define ROP_SPDSoaxn	0xD3
#define ROP_SSPxPDxax	0xD4
#define ROP_DPSanan	0xD5
#define ROP_PSDPSaoxx	0xD6
#define ROP_DPSxan	0xD7
#define ROP_PDSPxax	0xD8
#define ROP_SDPSaoxn	0xD9
#define ROP_DPSDanax	0xDA
#define ROP_SPxDSxan	0xDB
#define ROP_SPDnao	0xDC
#define ROP_SDno	0xDD
#define ROP_SDPxo	0xDE
#define ROP_SDPano	0xDF
#define ROP_PDSoa	0xE0
#define ROP_PDSoxn	0xE1
#define ROP_DSPDxax	0xE2
#define ROP_PSDPaoxn	0xE3
#define ROP_SDPSxax	0xE4
#define ROP_PDSPaoxn	0xE5
#define ROP_SDPSanax	0xE6
#define ROP_SPxPDxan	0xE7
#define ROP_SSPxDSxax	0xE8
#define ROP_DSPDSanaxxn	0xE9
#define ROP_DPSao	0xEA
#define ROP_DPSxno	0xEB
#define ROP_SDPao	0xEC
#define ROP_SDPxno	0xED
#define ROP_DSo		0xEE
#define ROP_SDPnoo	0xEF
#define ROP_P		0xF0
#define ROP_PDSono	0xF1
#define ROP_PDSnao	0xF2
#define ROP_PSno	0xF3
#define ROP_PSDnao	0xF4
#define ROP_PDno	0xF5
#define ROP_PDSxo	0xF6
#define ROP_PDSano	0xF7
#define ROP_PDSao	0xF8
#define ROP_PDSxno	0xF9
#define ROP_DPo		0xFA
#define ROP_DPSnoo	0xFB
#define ROP_PSo		0xFC
#define ROP_PSDnoo	0xFD
#define ROP_DPSoo	0xFE
#define ROP_1		0xFF

#define NO_SRC_ROP(rop) \
   ((rop == GXnoop) || (rop == GXset) || (rop == GXclear) || (rop == GXinvert))

int XAAHelpSolidROP(ScrnInfoPtr pScrn, int *fg, int pm, int *rop);
int XAAHelpPatternROP(ScrnInfoPtr pScrn, int *fg, int *bg, int pm, int *rop);

extern int XAACopyROP[16];
extern int XAACopyROP_PM[16];
extern int XAAPatternROP[16];
extern int XAAPatternROP_PM[16];

#endif /* _XAAROP_H */

--- NEW FILE: xaawrap.h ---
/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaawrap.h,v 1.3 1998/10/25 07:12:14 dawes Exp $ */

#define XAA_SCREEN_PROLOGUE(pScreen, field)\
  ((pScreen)->field = \
   ((XAAScreenPtr) (pScreen)->devPrivates[XAAScreenIndex].ptr)->field)

#define XAA_SCREEN_EPILOGUE(pScreen, field, wrapper)\
    ((pScreen)->field = wrapper)


#define XAA_GC_FUNC_PROLOGUE(pGC)\
    XAAGCPtr   pGCPriv = (XAAGCPtr) (pGC)->devPrivates[XAAGCIndex].ptr;\
    (pGC)->funcs = pGCPriv->wrapFuncs;\
    if(pGCPriv->flags)\
	(pGC)->ops = pGCPriv->wrapOps

#define XAA_GC_FUNC_EPILOGUE(pGC)\
    pGCPriv->wrapFuncs = (pGC)->funcs;\
    (pGC)->funcs = &XAAGCFuncs;\
    if(pGCPriv->flags) {\
	pGCPriv->wrapOps = (pGC)->ops;\
	(pGC)->ops = (pGCPriv->flags & OPS_ARE_ACCEL) ? pGCPriv->XAAOps :\
				&XAAPixmapOps;\
    }


#define XAA_GC_OP_PROLOGUE(pGC)\
    XAAGCPtr pGCPriv = (XAAGCPtr)(pGC->devPrivates[XAAGCIndex].ptr);\
    GCFuncs *oldFuncs = pGC->funcs;\
    pGC->funcs = pGCPriv->wrapFuncs;\
    pGC->ops = pGCPriv->wrapOps

#define XAA_GC_OP_PROLOGUE_WITH_RETURN(pGC)\
    XAAGCPtr pGCPriv = (XAAGCPtr)(pGC->devPrivates[XAAGCIndex].ptr);\
    GCFuncs *oldFuncs = pGC->funcs;\
    if(!REGION_NUM_RECTS(pGC->pCompositeClip)) return; \
    pGC->funcs = pGCPriv->wrapFuncs;\
    pGC->ops = pGCPriv->wrapOps

    
#define XAA_GC_OP_EPILOGUE(pGC)\
    pGCPriv->wrapOps = pGC->ops;\
    pGC->funcs = oldFuncs;\
    pGC->ops   = pGCPriv->XAAOps


#define XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw)\
    XAAGCPtr pGCPriv = (XAAGCPtr)(pGC->devPrivates[XAAGCIndex].ptr);\
    XAAPixmapPtr pixPriv = XAA_GET_PIXMAP_PRIVATE((PixmapPtr)(pDraw));\
    GCFuncs *oldFuncs = pGC->funcs;\
    pGC->funcs = pGCPriv->wrapFuncs;\
    pGC->ops = pGCPriv->wrapOps

    
#define XAA_PIXMAP_OP_EPILOGUE(pGC)\
    pGCPriv->wrapOps = pGC->ops;\
    pGC->funcs = oldFuncs;\
    pGC->ops   = &XAAPixmapOps;\
    pixPriv->flags |= DIRTY

#ifdef RENDER
#define XAA_RENDER_PROLOGUE(pScreen,field)\
    (GetPictureScreen(pScreen)->field = \
     ((XAAScreenPtr) (pScreen)->devPrivates[XAAScreenIndex].ptr)->field)

#define XAA_RENDER_EPILOGUE(pScreen, field, wrapper)\
    (GetPictureScreen(pScreen)->field = wrapper)
#endif

/* This also works fine for drawables */

#define SYNC_CHECK(pGC) {\
     XAAInfoRecPtr infoRec =\
((XAAScreenPtr)((pGC)->pScreen->devPrivates[XAAScreenIndex].ptr))->AccelInfoRec;\
    if(infoRec->NeedToSync) {\
	(*infoRec->Sync)(infoRec->pScrn);\
	infoRec->NeedToSync = FALSE;\
    }}




More information about the xserver-commit mailing list