[comp.sources.x] REPOST: v04i089: R3 Sun Server Speedups, Part03/03

argv@island.uu.net (Dan Heller) (08/16/89)

Submitted-by: uunet!inf.rl.ac.uk!taw
Posting-number: Volume 4, Issue 89
Archive-name: ral.speedups/part03

[ No one seems to have gotten this, so I'm reposting.  --argv ]

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 2 (of 3)."
# Contents:  sunBW2.c.patch sunGC.c.patch sunbitblt.c.patch
#   sunplygblt.c.patch sunpntarea.c.patch suntegblt.c.patch
# Wrapped by taw@box on Wed Aug  2 15:45:04 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'sunBW2.c.patch' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'sunBW2.c.patch'\"
else
echo shar: Extracting \"'sunBW2.c.patch'\" \(607 characters\)
sed "s/^X//" >'sunBW2.c.patch' <<'END_OF_FILE'
X*** sunBW2.c.slow	Tue Apr 25 09:54:26 1989
X--- sunBW2.c	Tue Apr 25 09:59:55 1989
X***************
X*** 234,243 ****
X--- 234,251 ----
X  {
X      ColormapPtr pColormap;
X  
X+ #ifdef RAL
X+ /* Use RAL sunScreenInit */
X+     if (!psunScreenInit(index, pScreen,
X+ 			   sunFbs[index].fb,
X+ 			   sunFbs[index].info.fb_width,
X+ 			   sunFbs[index].info.fb_height, 90, 90))
X+ #else original
X      if (!mfbScreenInit(index, pScreen,
X  			   sunFbs[index].fb,
X  			   sunFbs[index].info.fb_width,
X  			   sunFbs[index].info.fb_height, 90, 90))
X+ #endif
X  	return (FALSE);
X  
X      pScreen->SaveScreen = sunBW2SaveScreen;
END_OF_FILE
if test 607 -ne `wc -c <'sunBW2.c.patch'`; then
    echo shar: \"'sunBW2.c.patch'\" unpacked with wrong size!
fi
# end of 'sunBW2.c.patch'
fi
if test -f 'sunGC.c.patch' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'sunGC.c.patch'\"
else
echo shar: Extracting \"'sunGC.c.patch'\" \(746 characters\)
sed "s/^X//" >'sunGC.c.patch' <<'END_OF_FILE'
X*** sunGC.c.slow	Tue Apr 25 10:00:31 1989
X--- sunGC.c	Wed Aug  2 09:10:20 1989
X***************
X*** 1531,1537 ****
X   */
X  Bool
X  sunCreateGC (pGC)
X!     GCPtr	pGC;	/* The GC to play with */
X  {
X      GCInterestPtr	pGCI;
X      register GCPtr	pShadowGC;
X--- 1531,1537 ----
X   */
X  Bool
X  sunCreateGC (pGC)
X!     register GCPtr	pGC;	/*  The GC to play with */
X  {
X      GCInterestPtr	pGCI;
X      register GCPtr	pShadowGC;
X***************
X*** 1552,1557 ****
X--- 1552,1558 ----
X  	*pShadowGC = *pGC;
X  	pGC->devPriv = (pointer)pShadowGC;
X  	bcopy (sunGCFuncs, &pGC->FillSpans, sizeof (sunGCFuncs));
X+  	((mfbPrivGCPtr)(pShadowGC->devPriv))->FillArea = sunSolidInvertArea;
X  	
X  	pGCI = (GCInterestPtr) Xalloc (sizeof (GCInterestRec));
X  	if (!pGCI) {
END_OF_FILE
if test 746 -ne `wc -c <'sunGC.c.patch'`; then
    echo shar: \"'sunGC.c.patch'\" unpacked with wrong size!
fi
# end of 'sunGC.c.patch'
fi
if test -f 'sunbitblt.c.patch' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'sunbitblt.c.patch'\"
else
echo shar: Extracting \"'sunbitblt.c.patch'\" \(19505 characters\)
sed "s/^X//" >'sunbitblt.c.patch' <<'END_OF_FILE'
X*** sunbitblt.c.slow	Tue Aug  1 09:49:21 1989
X--- sunbitblt.c	Mon May 15 09:45:28 1989
X***************
X*** 0 ****
X--- 1,654 ----
X+ /* Combined Purdue/PurduePlus patches, level 2.0, 1/17/89 */
X+ #include    "sun.h"
X+ #include "Xprotostr.h"
X+ #include "font.h"
X+ #include "fontstruct.h"
X+ 
X+ #include "maskbits.h"
X+ 
X+ char *malloc ();
X+ 
X+ /* CopyArea and CopyPlane for a monchrome sun frame buffer
X+ 
X+ 
X+     clip the source rectangle to the source's available bits.  (this
X+ avoids copying unnecessary pieces that will just get exposed anyway.)
X+ this becomes the new shape of the destination.
X+     clip the destination region to the composite clip in the
X+ GC.  this requires translating the destination region to (dstx, dsty).
X+     build a list of source points, one for each rectangle in the
X+ destination.  this is a simple translation.
X+     go do the multiple rectangle copies
X+     do graphics exposures
X+ */
X+ /*  #ifdef PURDUE!!!!
X+  ** Optimized for drawing pixmaps into windows, especially when drawing into
X+  ** unobscured windows.  Calls to the general-purpose region code were
X+  ** replaced with rectangle-to-rectangle clipping comparisions.  This is
X+  ** possible, since the pixmap is a single rectangle.  In an unobscured
X+  ** window, the destination clip is also a single rectangle, and region
X+  ** code can be avoided entirely.  This is a big savings, since the region
X+  ** code uses XAlloc() and makes many function calls.
X+  **
X+  ** In addition, if source is a pixmap, there is no need to call the
X+  ** expensive miHandleExposures() routine.  Instead, we simply return NULL.
X+  **
X+  ** Previously, drawing a pixmap into an unobscured window executed at least
X+  ** 8 XAlloc()'s, 30 function calls, and hundreds of lines of code.
X+  **
X+  ** Now, the same operation requires no XAlloc()'s, no region function calls,
X+  ** and much less overhead.  Nice for drawing lots of small pixmaps.
X+  */
X+ 
X+ static int sun_rop [] =
X+  {
X+  	PIX_SRC & PIX_NOT (PIX_SRC),
X+  	PIX_SRC & PIX_DST,
X+  	PIX_SRC & PIX_NOT (PIX_DST),
X+  	PIX_SRC,
X+  	PIX_NOT (PIX_SRC) & PIX_DST,
X+  	PIX_DST,
X+  	PIX_SRC ^ PIX_DST,
X+  	PIX_SRC | PIX_DST,
X+  	PIX_NOT (PIX_SRC | PIX_DST),
X+  	PIX_NOT (PIX_SRC ^ PIX_DST),
X+  	PIX_NOT (PIX_DST),
X+  	PIX_SRC | PIX_NOT (PIX_DST),
X+  	PIX_NOT (PIX_SRC),
X+  	PIX_NOT (PIX_SRC) | PIX_DST,
X+  	PIX_SRC | PIX_NOT (PIX_DST),
X+  	PIX_SRC | PIX_NOT (PIX_SRC),
X+  };
X+ 
X+ RegionPtr 
X+ psunCopyArea(pSrcDrawable, pDstDrawable,
X+ 	    pGC, srcx, srcy, width, height, dstx, dsty)
X+ register DrawablePtr pSrcDrawable;
X+ register DrawablePtr pDstDrawable;
X+ GC *pGC;
X+ int srcx, srcy;
X+ int width, height;
X+ int dstx, dsty;
X+ {
X+ #ifndef PURDUE
X+     BoxRec srcBox;
X+ #endif PURDUE
X+     RegionPtr prgnSrcClip;	/* may be a new region, or just a copy */
X+     int realSrcClip = 0;	/* non-0 if we've created a src clip */
X+ 
X+     RegionPtr prgnDst, prgnExposed;
X+     DDXPointPtr pptSrc;
X+     register DDXPointPtr ppt;
X+     register BoxPtr pbox;
X+     int i;
X+     register int dx;
X+     register int dy;
X+     xRectangle origSource;
X+     DDXPointRec origDest;
X+ 
X+ #ifdef PURDUE
X+     RegionRec fastRegion;	/* special region for clipping to 1 box */
X+     BoxRec fastBox;
X+     int fastClip = 0;		/* for fast clipping with pixmap source */
X+     int fastExpose = 0;		/* for fast exposures with pixmap source */
X+ #endif PURDUE
X+ 
X+     origSource.x = srcx;
X+     origSource.y = srcy;
X+     origSource.width = width;
X+     origSource.height = height;
X+     origDest.x = dstx;
X+     origDest.y = dsty;
X+ 
X+     /* clip the source */
X+ 
X+     if (pSrcDrawable->type == DRAWABLE_PIXMAP)
X+     {
X+ 	if ((pSrcDrawable == pDstDrawable) &&
X+ 	    (pGC->clientClipType == CT_NONE))
X+ 	{
X+ 	    prgnSrcClip = ((mfbPrivGC *)(pGC->devPriv))->pCompositeClip;
X+ 	}
X+ 	else
X+ #ifndef PURDUE
X+ 	{
X+ 	    BoxRec box;
X+ 
X+ 	    box.x1 = 0;
X+ 	    box.y1 = 0;
X+ 	    box.x2 = ((PixmapPtr)pSrcDrawable)->width;
X+ 	    box.y2 = ((PixmapPtr)pSrcDrawable)->height;
X+ 
X+ 	    prgnSrcClip = (*pGC->pScreen->RegionCreate)(&box, 1);
X+ 	    realSrcClip = 1;
X+ 	}
X+ #else PURDUE
X+ 	{
X+ 	    /* Pixmap sources generate simple exposure events */
X+ 	    fastExpose = 1;
X+ 
X+ 	    /* Pixmap is just one clipping rectangle so we can avoid
X+ 	       allocating a full-blown region. */
X+ 	    fastClip = 1;
X+ 
X+ 	    fastBox.x1 = srcx;
X+ 	    fastBox.y1 = srcy;
X+ 	    fastBox.x2 = srcx + width;
X+ 	    fastBox.y2 = srcy + height;
X+ 	    
X+ 	    /* Left and top are already clipped, so clip right and bottom */
X+ 	    if (fastBox.x2 > ((PixmapPtr)pSrcDrawable)->width)
X+ 	      fastBox.x2 = ((PixmapPtr)pSrcDrawable)->width;
X+ 	    if (fastBox.y2 > ((PixmapPtr)pSrcDrawable)->height)
X+ 	      fastBox.y2 = ((PixmapPtr)pSrcDrawable)->height;
X+ 
X+ 	    /* Initialize the fast region */
X+ 	    fastRegion.numRects = 1;
X+ 	    fastRegion.rects = &fastBox;
X+ 	}
X+ #endif PURDUE
X+     }
X+     else
X+     {
X+ 	srcx += ((WindowPtr)pSrcDrawable)->absCorner.x;
X+ 	srcy += ((WindowPtr)pSrcDrawable)->absCorner.y;
X+ 	if (pGC->subWindowMode == IncludeInferiors)
X+ 	{
X+ 	    if ((pSrcDrawable == pDstDrawable) &&
X+ 		(pGC->clientClipType == CT_NONE))
X+ 	    {
X+ 		prgnSrcClip = ((mfbPrivGC *)(pGC->devPriv))->pCompositeClip;
X+ 	    }
X+ 	    else
X+ 	    {
X+ 		prgnSrcClip = NotClippedByChildren((WindowPtr)pSrcDrawable);
X+ 		realSrcClip = 1;
X+ 	    }
X+ 	}
X+ 	else
X+ 	{
X+ 	    prgnSrcClip = ((WindowPtr)pSrcDrawable)->clipList;
X+ 	}
X+     }
X+ 
X+ #ifdef PURDUE
X+     /* Don't create a source region if we are doing a fast clip */
X+     if (!fastClip)
X+ #endif PURDUE
X+     {
X+       BoxRec srcBox;
X+ 
X+       srcBox.x1 = srcx;
X+       srcBox.y1 = srcy;
X+       srcBox.x2 = srcx + width;
X+       srcBox.y2 = srcy + height;
X+ 
X+       prgnDst = (*pGC->pScreen->RegionCreate)(&srcBox, 1);
X+       (*pGC->pScreen->Intersect)(prgnDst, prgnDst, prgnSrcClip);
X+      }
X+ 
X+       if (pDstDrawable->type == DRAWABLE_WINDOW)
X+     {
X+ 	if (!((WindowPtr)pDstDrawable)->realized)
X+ 	{
X+ #ifdef PURDUE
X+ 	    if (!fastClip)
X+ #endif
X+ 	    (*pGC->pScreen->RegionDestroy)(prgnDst);
X+ 	    if (realSrcClip)
X+ 		(*pGC->pScreen->RegionDestroy)(prgnSrcClip);
X+ 	    return NULL;
X+ 	}
X+ 	dstx += ((WindowPtr)pDstDrawable)->absCorner.x;
X+ 	dsty += ((WindowPtr)pDstDrawable)->absCorner.y;
X+     }
X+ 
X+     dx = srcx - dstx;
X+     dy = srcy - dsty;
X+ 
X+ #ifndef PURDUE
X+     /* clip the shape of the dst to the destination composite clip */
X+     (*pGC->pScreen->TranslateRegion)(prgnDst, -dx, -dy);
X+     (*pGC->pScreen->Intersect)(prgnDst,
X+ 		prgnDst,
X+ 		((mfbPrivGC *)(pGC->devPriv))->pCompositeClip);
X+ 
X+ #else PURDUE
X+     /* Translate and clip the dst to the destination composite clip */
X+     if (fastClip)
X+     {
X+         /* Translate the region directly */
X+         fastBox.x1 -= dx;
X+         fastBox.x2 -= dx;
X+         fastBox.y1 -= dy;
X+         fastBox.y2 -= dy;
X+ 
X+ 	/* If the destination composite clip is one rectangle we can
X+ 	   do the clip directly.  Otherwise we have to create a full
X+ 	   blown region and call intersect */
X+         if (((mfbPrivGC *)(pGC->devPriv))->pCompositeClip->numRects == 1)
X+         {
X+ 	    BoxPtr pBox = ((mfbPrivGC *)(pGC->devPriv))->pCompositeClip->rects;
X+ 	  
X+ 	    if (fastBox.x1 < pBox->x1) fastBox.x1 = pBox->x1;
X+ 	    if (fastBox.x2 > pBox->x2) fastBox.x2 = pBox->x2;
X+ 	    if (fastBox.y1 < pBox->y1) fastBox.y1 = pBox->y1;
X+ 	    if (fastBox.y2 > pBox->y2) fastBox.y2 = pBox->y2;
X+ 
X+ 	    /* Check to see if the region is empty */
X+ 	    if (fastBox.x1 >= fastBox.x2 || fastBox.y1 >= fastBox.y2)
X+ 	        fastRegion.numRects = 0;
X+ 
X+ 	    /* Use the fast region for all future computation.
X+ 	       The following code insures that RegionDestroy is not
X+ 	       called on it. */
X+ 	    prgnDst = &fastRegion;
X+ 	}
X+         else
X+ 	{
X+ 	    /* We must turn off fastClip now, since we must create
X+ 	       a full blown region.  It is intersected with the
X+ 	       composite clip below. */
X+ 	    fastClip = 0;
X+ 	    prgnDst = (*pGC->pScreen->RegionCreate)(&fastBox,1);
X+ 	}
X+     }
X+     else
X+     {
X+         (*pGC->pScreen->TranslateRegion)(prgnDst, -dx, -dy);
X+     }
X+ 
X+     if (!fastClip)
X+     {
X+ 	(*pGC->pScreen->Intersect)(prgnDst,
X+ 				   prgnDst,
X+ 				 ((mfbPrivGC *)(pGC->devPriv))->pCompositeClip);
X+     }
X+ #endif PURDUE
X+     if (!prgnDst->numRects)
X+     {
X+ 	(*pGC->pScreen->RegionDestroy)(prgnDst);
X+ 	if (realSrcClip)
X+ 	    (*pGC->pScreen->RegionDestroy)(prgnSrcClip);
X+ 	return NULL;
X+     }
X+     if(!(pptSrc = (DDXPointPtr)ALLOCATE_LOCAL( prgnDst->numRects *
X+         sizeof(DDXPointRec))))
X+     {
X+ #ifdef PURDUE
X+ 	if (!fastClip)
X+ #endif PURDUE
X+ 		(*pGC->pScreen->RegionDestroy)(prgnDst);
X+ 		if (realSrcClip)
X+ 		    (*pGC->pScreen->RegionDestroy)(prgnSrcClip);
X+ 		return NULL;
X+     }
X+     pbox = prgnDst->rects;
X+     ppt = pptSrc;
X+     for (i=0; i<prgnDst->numRects; i++, pbox++, ppt++)
X+     {
X+ 	ppt->x = pbox->x1 + dx;
X+ 	ppt->y = pbox->y1 + dy;
X+     }
X+ 
X+     if (pGC->planemask & 1)
X+ 	sunDoBitblt(pSrcDrawable, pDstDrawable, pGC->alu, prgnDst, pptSrc);
X+ 
X+     prgnExposed = NULL;
X+     if (((mfbPrivGC *)(pGC->devPriv))->fExpose) {
X+ #ifdef PURDUE
X+         /* Pixmap sources generate a NoExposed (we return NULL to do this) */
X+         if (!fastExpose)
X+ #endif PURDUE
X+         prgnExposed =
X+         miHandleExposures(pSrcDrawable, pDstDrawable, pGC,
X+ 		          origSource.x, origSource.y,
X+ 		          origSource.width, origSource.height,
X+ 		          origDest.x, origDest.y, 0);
X+ 	}
X+ 		
X+     DEALLOCATE_LOCAL(pptSrc);
X+ #ifdef PURDUE
X+     
X+     /* Destroy any created regions */
X+     if (!fastClip)
X+ #endif PURDUE
X+     (*pGC->pScreen->RegionDestroy)(prgnDst);
X+     if (realSrcClip)
X+ 	(*pGC->pScreen->RegionDestroy)(prgnSrcClip);
X+     return prgnExposed;
X+ }
X+ 
X+ 
X+ void PixrectFromPixmap (pSrcDrawable, source, srcmem)
X+ 	register DrawablePtr (pSrcDrawable);
X+ 	register struct pixrect *source;
X+ 	register struct mpr_data *srcmem;
X+  {
X+     register unsigned int *psrcBase;	/* start bitmaps */
X+     register int widthSrc;		/* add to get to same position in next line */
X+ 
X+     extern struct pixrectops mem_ops;
X+     
X+     if (pSrcDrawable->type == DRAWABLE_WINDOW)
X+     {
X+ 	psrcBase = (unsigned int *)
X+ 		(((PixmapPtr)(pSrcDrawable->pScreen->devPrivate))->devPrivate);
X+ 	widthSrc = (int)
X+ 		   ((PixmapPtr)(pSrcDrawable->pScreen->devPrivate))->devKind
X+ 		    >> 2;
X+    	source->pr_size.x = (((PixmapPtr)(pSrcDrawable->pScreen->devPrivate))->width);
X+    	source->pr_size.y = (((PixmapPtr)(pSrcDrawable->pScreen->devPrivate))->height);
X+     }
X+     else
X+     {
X+ 	psrcBase = (unsigned int *)(((PixmapPtr)pSrcDrawable)->devPrivate);
X+ 	widthSrc = (int)(((PixmapPtr)pSrcDrawable)->devKind) >> 2;
X+     	source->pr_size.x = ((PixmapPtr)pSrcDrawable)->width;
X+     	source->pr_size.y = ((PixmapPtr)pSrcDrawable)->height;
X+     }
X+ 
X+     source->pr_ops = &mem_ops;
X+     source->pr_depth = 1;
X+     source->pr_data = (char *) srcmem;
X+     
X+     srcmem->md_linebytes = widthSrc << 2;
X+     srcmem->md_image = (short *) psrcBase;
X+     srcmem->md_offset.x = srcmem->md_offset.y = 0;
X+     srcmem->md_primary = 1;
X+     srcmem->md_flags = 0;
X+  }
X+ 
X+ /* DoBitblt() does multiple rectangle moves into the rectangles
X+    if src or dst is a window, the points have already been
X+ translated.
X+ */
X+ 
X+ sunDoBitblt(pSrcDrawable, pDstDrawable, alu, prgnDst, pptSrc)
X+ DrawablePtr pSrcDrawable;
X+ DrawablePtr pDstDrawable;
X+ int alu;
X+ RegionPtr prgnDst;
X+ DDXPointPtr pptSrc;
X+ {
X+     register BoxPtr pbox;
X+     int nbox;
X+ 
X+     BoxPtr pboxTmp, pboxNext, pboxBase, pboxNew1, pboxNew2;
X+ 				/* temporaries for shuffling rectangles */
X+     DDXPointPtr pptTmp, pptNew1, pptNew2;
X+ 				/* shuffling boxes entails shuffling the
X+ 				   source points too */
X+     static struct pixrect source, destination;
X+     static struct mpr_data srcmem, dstmem;
X+     int careful;
X+     
X+     PixrectFromPixmap (pSrcDrawable, &source, &srcmem);
X+     PixrectFromPixmap (pDstDrawable, &destination, &dstmem);
X+     
X+     /* XXX we have to err on the side of safety when both are windows,
X+      * because we don't know if IncludeInferiors is being used.
X+      */
X+     careful = ((pSrcDrawable == pDstDrawable) ||
X+ 	       ((pSrcDrawable->type == DRAWABLE_WINDOW) &&
X+ 		(pDstDrawable->type == DRAWABLE_WINDOW)));
X+ 
X+     pbox = prgnDst->rects;
X+     nbox = prgnDst->numRects;
X+ 
X+     pboxNew1 = NULL;
X+     pptNew1 = NULL;
X+     pboxNew2 = NULL;
X+     pptNew2 = NULL;
X+     if (careful && (pptSrc->y < pbox->y1)) 
X+     {
X+         /* walk source bottom to top */
X+ 	if (nbox > 1)
X+ 	{
X+ 	    /* keep ordering in each band, reverse order of bands */
X+ 	    pboxNew1 = (BoxPtr)ALLOCATE_LOCAL(sizeof(BoxRec) * nbox);
X+ 	    if(!pboxNew1)
X+ 		return;
X+ 	    pptNew1 = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec) * nbox);
X+ 	    if(!pptNew1)
X+ 	    {
X+ 	        DEALLOCATE_LOCAL(pboxNew1);
X+ 	        return;
X+ 	    }
X+ 	    pboxBase = pboxNext = pbox+nbox-1;
X+ 	    while (pboxBase >= pbox)
X+ 	    {
X+ 	        while ((pboxNext >= pbox) && 
X+ 		       (pboxBase->y1 == pboxNext->y1))
X+ 		    pboxNext--;
X+ 	        pboxTmp = pboxNext+1;
X+ 	        pptTmp = pptSrc + (pboxTmp - pbox);
X+ 	        while (pboxTmp <= pboxBase)
X+ 	        {
X+ 		    *pboxNew1++ = *pboxTmp++;
X+ 		    *pptNew1++ = *pptTmp++;
X+ 	        }
X+ 	        pboxBase = pboxNext;
X+ 	    }
X+ 	    pboxNew1 -= nbox;
X+ 	    pbox = pboxNew1;
X+ 	    pptNew1 -= nbox;
X+ 	    pptSrc = pptNew1;
X+         }
X+     }
X+ 
X+     if (careful && (pptSrc->x < pbox->x1))
X+     {
X+ 	/* walk source right to left */
X+ 
X+ 	if (nbox > 1)
X+ 	{
X+ 	    /* reverse order of rects in each band */
X+ 	    pboxNew2 = (BoxPtr)ALLOCATE_LOCAL(sizeof(BoxRec) * nbox);
X+ 	    pptNew2 = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec) * nbox);
X+ 	    if(!pboxNew2 || !pptNew2)
X+ 	    {
X+ 		if (pptNew2) DEALLOCATE_LOCAL(pptNew2);
X+ 		if (pboxNew2) DEALLOCATE_LOCAL(pboxNew2);
X+ 		if (pboxNew1)
X+ 		{
X+ 		    DEALLOCATE_LOCAL(pptNew1);
X+ 		    DEALLOCATE_LOCAL(pboxNew1);
X+ 		}
X+ 	        return;
X+ 	    }
X+ 	    pboxBase = pboxNext = pbox;
X+ 	    while (pboxBase < pbox+nbox)
X+ 	    {
X+ 	        while ((pboxNext < pbox+nbox) &&
X+ 		       (pboxNext->y1 == pboxBase->y1))
X+ 		    pboxNext++;
X+ 	        pboxTmp = pboxNext;
X+ 	        pptTmp = pptSrc + (pboxTmp - pbox);
X+ 	        while (pboxTmp != pboxBase)
X+ 	        {
X+ 		    *pboxNew2++ = *--pboxTmp;
X+ 		    *pptNew2++ = *--pptTmp;
X+ 	        }
X+ 	        pboxBase = pboxNext;
X+ 	    }
X+ 	    pboxNew2 -= nbox;
X+ 	    pbox = pboxNew2;
X+ 	    pptNew2 -= nbox;
X+ 	    pptSrc = pptNew2;
X+ 	}
X+     }
X+     
X+     while (nbox--)
X+         {
X+     	    if (pr_rop (&destination, pbox->x1, pbox->y1, pbox->x2 - pbox->x1, pbox->y2 - pbox->y1, sun_rop [alu], &source, pptSrc->x, pptSrc->y) == PIX_ERR)
X+     	    	exit (3);
X+ 	    pbox++;
X+ 	    pptSrc++;
X+         }
X+ 
X+     /* free up stuff */
X+     if (pboxNew2)
X+     {
X+ 	DEALLOCATE_LOCAL(pptNew2);
X+ 	DEALLOCATE_LOCAL(pboxNew2);
X+     }
X+     if (pboxNew1)
X+     {
X+ 	DEALLOCATE_LOCAL(pptNew1);
X+ 	DEALLOCATE_LOCAL(pboxNew1);
X+     }
X+ }
X+ 
X+ int sunTileOrgX, sunTileOrgY;
X+ 
X+ void
X+ sunTileArea (pDrawable, nbox, pbox, alu, ppix)
X+     DrawablePtr pDrawable;
X+     int nbox;
X+     BoxPtr pbox;
X+     int alu;
X+     PixmapPtr ppix;
X+ {
X+     	static struct pixrect tile, destination;
X+     	static struct mpr_data tilemem, dstmem;
X+     	int rop;
X+     	
X+     	PixrectFromPixmap (pDrawable, &destination, &dstmem);
X+      	PixrectFromPixmap (ppix, &tile, &tilemem);
X+     	while (nbox--)
X+         {
X+     	    	if (pr_replrop (&destination, pbox->x1, pbox->y1, pbox->x2 - pbox->x1, pbox->y2 - pbox->y1, sun_rop [alu], &tile, pbox->x1 - sunTileOrgX, pbox->y1 - sunTileOrgY) == PIX_ERR)
X+     	    		exit (3);
X+ 	    	pbox++;
X+         }
X+ }
X+ 
X+ RegionPtr
X+ psunCopyPlane(pSrcDrawable, pDstDrawable,
X+ 	    pGC, srcx, srcy, width, height, dstx, dsty, plane)
X+ DrawablePtr pSrcDrawable, pDstDrawable;
X+ register GC *pGC;
X+ int srcx, srcy;
X+ int width, height;
X+ int dstx, dsty;
X+ unsigned int plane;
X+ {
X+     int alu;
X+     RegionPtr	prgnExposed;
X+ 
X+     /* XXX a deeper screen ought to wrap ValidateGC to get around this */
X+     if (pSrcDrawable->depth != 1)
X+ 	return miCopyPlane(pSrcDrawable, pDstDrawable,
X+ 			   pGC, srcx, srcy, width, height, dstx, dsty, plane);
X+     if (plane != 1)
X+ 	return NULL;
X+ 
X+     if ((pGC->fgPixel == 1) && (pGC->bgPixel == 0))
X+     {
X+ 	prgnExposed = (*pGC->CopyArea)(pSrcDrawable, pDstDrawable,
X+ 			 pGC, srcx, srcy, width, height, dstx, dsty);
X+     }
X+     else if (pGC->fgPixel == pGC->bgPixel)
X+     {
X+ 	alu = pGC->alu;
X+ 	pGC->alu = ReduceRop(pGC->alu, pGC->fgPixel);
X+ 	prgnExposed = (*pGC->CopyArea)(pSrcDrawable, pDstDrawable,
X+ 			 pGC, srcx, srcy, width, height, dstx, dsty);
X+ 	pGC->alu = alu;
X+     }
X+     else /* need to invert the src */
X+     {
X+ 	alu = pGC->alu;
X+ 	pGC->alu = InverseAlu[alu];
X+ 	prgnExposed = psunCopyArea (pSrcDrawable, pDstDrawable,
X+ 			 pGC, srcx, srcy, width, height, dstx, dsty);
X+ 	pGC->alu = alu;
X+     }
X+     return prgnExposed;
X+ }
X+ 
X+ extern WindowRec WindowTable[];
X+ 
X+ /* UNCLEAN!
X+    this code calls the bitblt helper code directly.
X+ 
X+    sunCopyWindow copies only the parts of the destination that are
X+ visible in the source.
X+ */
X+ 
X+ void 
X+ psunCopyWindow(pWin, ptOldOrg, prgnSrc)
X+     WindowPtr pWin;
X+     DDXPointRec ptOldOrg;
X+     RegionPtr prgnSrc;
X+ {
X+     DDXPointPtr pptSrc;
X+     register DDXPointPtr ppt;
X+     RegionPtr prgnDst;
X+     register BoxPtr pbox;
X+     register int dx, dy;
X+     register int i, nbox;
X+     WindowPtr pwinRoot;
X+ 
X+     pwinRoot = &WindowTable[pWin->drawable.pScreen->myNum];
X+ 
X+     prgnDst = (* pWin->drawable.pScreen->RegionCreate)(NULL, 
X+ 					       pWin->borderClip->numRects);
X+ 
X+     dx = ptOldOrg.x - pWin->absCorner.x;
X+     dy = ptOldOrg.y - pWin->absCorner.y;
X+     (* pWin->drawable.pScreen->TranslateRegion)(prgnSrc, -dx, -dy);
X+     (* pWin->drawable.pScreen->Intersect)(prgnDst, pWin->borderClip, prgnSrc);
X+ 
X+     pbox = prgnDst->rects;
X+     nbox = prgnDst->numRects;
X+     if(!(pptSrc = (DDXPointPtr )ALLOCATE_LOCAL( prgnDst->numRects *
X+       sizeof(DDXPointRec))))
X+ 	return;
X+     ppt = pptSrc;
X+ 
X+ #ifndef PURDUE
X+     for (i=0; i<nbox; i++, ppt++, pbox++)
X+     {
X+ 	ppt->x = pbox->x1 + dx;
X+ 	ppt->y = pbox->y1 + dy;
X+     }
X+ #else
X+     i = nbox;
X+     Duff(i, ppt->x = pbox->x1 + dx; ppt->y = pbox->y1 + dy; ppt++; pbox++);
X+ #endif  /* PURDUE */
X+ 
X+     sunDoBitblt(pwinRoot, pwinRoot, GXcopy, prgnDst, pptSrc);
X+     DEALLOCATE_LOCAL(pptSrc);
X+     (* pWin->drawable.pScreen->RegionDestroy)(prgnDst);
X+ }
X+ 
X+ void
X+ psunPushPixels (pGC, pBitMap, pDst, w, h, x, y)
X+     GCPtr	pGC;
X+     PixmapPtr	pBitMap;
X+     DrawablePtr pDst;
X+     int		w, h, x, y;
X+ {
X+     static struct pixrect source, destination;
X+     static struct mpr_data srcmem, dstmem;
X+     
X+     PixrectFromPixmap (pBitMap, &source, &srcmem);
X+     PixrectFromPixmap (pDst, &destination, &dstmem);
X+     
X+     switch (((mfbPrivGC*)(pGC->devPriv))->rop)	/* added cast - CMC */
X+      {
X+ 	      case RROP_WHITE:
X+ 	      	pr_rop (&destination, x, y, w, h, PIX_DST | PIX_SRC, &source, 0, 0);
X+ 		break;
X+ 	      case RROP_BLACK:
X+ 	      	pr_rop (&destination, x, y, w, h, PIX_DST & PIX_NOT (PIX_SRC), &source, 0, 0);
X+ 		break;
X+ 	      case RROP_INVERT:
X+ 	      	pr_rop (&destination, x, y, w, h, PIX_DST ^ PIX_SRC, &source, 0, 0);
X+ 		break;
X+ 	      case RROP_NOP:
X+ 		break;
X+      }
X+ }
END_OF_FILE
if test 19505 -ne `wc -c <'sunbitblt.c.patch'`; then
    echo shar: \"'sunbitblt.c.patch'\" unpacked with wrong size!
fi
# end of 'sunbitblt.c.patch'
fi
if test -f 'sunplygblt.c.patch' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'sunplygblt.c.patch'\"
else
echo shar: Extracting \"'sunplygblt.c.patch'\" \(6917 characters\)
sed "s/^X//" >'sunplygblt.c.patch' <<'END_OF_FILE'
X*** sunplygblt.c.slow	Tue Aug  1 09:49:21 1989
X--- sunplygblt.c	Tue Apr 25 15:00:23 1989
X***************
X*** 0 ****
X--- 1,181 ----
X+ /* $Header: sunplygblt.c,v 1.1 87/09/11 07:48:45 toddb Exp $ */
X+ /***********************************************************
X+ Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
X+ and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
X+ 
X+                         All Rights Reserved
X+ 
X+ Permission to use, copy, modify, and distribute this software and its 
X+ documentation for any purpose and without fee is hereby granted, 
X+ provided that the above copyright notice appear in all copies and that
X+ both that copyright notice and this permission notice appear in 
X+ supporting documentation, and that the names of Digital or MIT not be
X+ used in advertising or publicity pertaining to distribution of the
X+ software without specific, written prior permission.  
X+ 
X+ DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
X+ ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
X+ DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
X+ ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
X+ WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
X+ ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
X+ SOFTWARE.
X+ 
X+ ******************************************************************/
X+ #include	"X.h"
X+ #include	"Xmd.h"
X+ #include	"Xproto.h"
X+ #include	"fontstruct.h"
X+ #include	"dixfontstr.h"
X+ #include	"gcstruct.h"
X+ #include	"windowstr.h"
X+ #include	"scrnintstr.h"
X+ #include	"pixmapstr.h"
X+ #include	"regionstr.h"
X+ #include	"sun.h"
X+ #include	"maskbits.h"
X+ /*
X+     we should eventually special-case fixed-width fonts, although
X+ its more important for ImageText, which is meant for terminal
X+ emulators.
X+ 
X+     this works for fonts with glyphs <= 32 bits wide.
X+ 
X+     the clipping calculations are done for worst-case fonts.
X+ we make no assumptions about the heights, widths, or bearings
X+ of the glyphs.  if we knew that the glyphs are all the same height,
X+ we could clip the tops and bottoms per clipping box, rather
X+ than per character per clipping box.  if we knew that the glyphs'
X+ left and right bearings were well-behaved, we could clip a single
X+ character at the start, output until the last unclipped
X+ character, and then clip the last one.  this is all straightforward
X+ to determine based on max-bounds and min-bounds from the font.
X+     there is some inefficiency introduced in the per-character
X+ clipping to make what's going on clearer.
X+ 
X+     (it is possible, for example, for a font to be defined in which the
X+ next-to-last character in a font would be clipped out, but the last
X+ one wouldn't.  the code below deals with this.)
X+ 
X+     PolyText looks at the fg color and the rasterop; mfbValidateGC
X+ swaps in the right routine after looking at the reduced ratserop
X+ in the private field of the GC.  
X+ 
X+    the register allocations are provisional; in particualr startmask and
X+ endmask might not be the right things.  pglyph, xoff, pdst, and tmpSrc
X+ are fairly obvious, though.
X+ 
X+    to avoid source proliferation, this file is compiled
X+ three times:
X+ 	SUNPOLYGLYPHBLT		OP
X+ 	sunPolyGlyphBltWhite	PIX_DST|PIX_SRC
X+ 	sunPolyGlyphBltBlack	PIX_DST&PIX_NOT(PIX_SRC)
X+ 	sunPolyGlyphBltInvert	PIX_SRC^PIX_DST
X+ */
X+ 
X+ void
X+ SUNPOLYGLYPHBLT(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase)
X+     DrawablePtr pDrawable;
X+     GC 		*pGC;
X+     int 	x, y;
X+     register unsigned int nglyph;
X+     register CharInfoPtr *ppci;		/* array of character info */
X+     register unsigned char *pglyphBase;	/* start of array of glyphs */
X+ {
X+     register int i;	/* moved decl and made a register -- CMC */
X+     ExtentInfoRec info;	/* used by QueryGlyphExtents() */
X+ 
X+     register CharInfoPtr pci;	/* made a register -- CMC */
X+     FontInfoPtr pfi = pGC->font->pFI;
X+     int xorg, yorg;
X+ 
X+     int w;			/* width of glyph and char */
X+     int h;			/* height of glyph and char */
X+     register int xpos;		/* current x  */
X+     register int ypos;			/* current y */
X+ 
X+     BoxRec bbox;		/* for clipping */
X+ 
X+     static struct pr_prpos *batch = NULL;
X+     static struct pixrect *prs = NULL;
X+     static struct mpr_data *pr_datas = NULL;
X+     static int batch_length = 0;
X+  	
X+     static struct pixrect destination;
X+     static struct mpr_data data;
X+  
X+     extern struct pixrectops mem_ops;
X+     	
X+     if (pDrawable->type == DRAWABLE_WINDOW)
X+     {
X+ 	xorg = ((WindowPtr)pDrawable)->absCorner.x;
X+ 	yorg = ((WindowPtr)pDrawable)->absCorner.y;
X+     }
X+     else
X+     {
X+ 	xorg = 0;
X+ 	yorg = 0;
X+     }
X+ 
X+     xpos = x + xorg;
X+     ypos = y + yorg; 
X+ 
X+ 
X+     QueryGlyphExtents(pGC->font, ppci, nglyph, &info);
X+     bbox.x1 = xpos + info.overallLeft;
X+     bbox.x2 = xpos + info.overallRight;
X+     bbox.y1 = ypos - info.overallAscent;
X+     bbox.y2 = ypos + info.overallDescent;
X+     
X+     switch ((*pGC->pScreen->RectIn)(
X+                 ((mfbPrivGC *)(pGC->devPriv))->pCompositeClip, &bbox))
X+     {
X+       case rgnOUT:
X+ 	break;
X+       case rgnPART:
X+ 	CLIPPLTEXT(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
X+ 	break;
X+       case rgnIN:
X+  	if (nglyph == 0)
X+  		return;
X+  	PixrectFromPixmap (pDrawable, &destination, &data);
X+  	if (batch_length < nglyph)
X+  	 {
X+  		int i;
X+  		
X+  		batch_length = nglyph;
X+  		batch = (struct pr_prpos *) Xrealloc (batch, batch_length * sizeof (struct pr_prpos));
X+  		prs = (struct pixrect *) Xrealloc (prs, batch_length * sizeof (struct pixrect));
X+  		pr_datas = (struct mpr_data *) Xrealloc (pr_datas, batch_length * sizeof (struct mpr_data));
X+  		for (i = 0; i < nglyph; i++)
X+  		 {
X+  		 	pr_datas[i].md_linebytes = 4; /* bytes , ahem */
X+  		 	pr_datas[i].md_offset.x = pr_datas[i].md_offset.y = 0;
X+  		 	pr_datas[i].md_flags = 0;
X+  		 	pr_datas[i].md_primary = 1;
X+  		 	prs[i].pr_depth = 1;
X+  		 	prs[i].pr_ops = &mem_ops;
X+   	 		prs[i].pr_data = (char *) (pr_datas + i);
X+  	 		batch[i].pr = prs + i;
X+ 		 }
X+  	 }
X+  	batch[0].pos.x = batch[0].pos.y = 0;
X+  	for (i = 0; i < nglyph; i++)
X+  	 {
X+       	        pci = *ppci;
X+  	 	prs[i].pr_size.x = pci->metrics.rightSideBearing - pci->metrics.leftSideBearing;
X+  	 	prs[i].pr_size.y = pci->metrics.ascent + pci->metrics.descent;
X+  	 	batch[i].pos.x += pci->metrics.leftSideBearing;
X+  	 	batch[i].pos.y -= pci->metrics.ascent;
X+ 		if(i<(nglyph-1)) {
X+ 		                batch[i+1].pos.x = pci->metrics.characterWidth
X+ 		                                   - pci->metrics.leftSideBearing;
X+  	 	                batch[i+1].pos.y = pci->metrics.ascent;
X+  	 	                }
X+  	 	pr_datas[i].md_image = (short *) (pglyphBase + (*ppci++)->byteOffset);
X+  	 }
X+  	pr_batchrop (&destination, xpos, ypos, OP, batch, nglyph);
X+ 	break;
X+     }
X+ }
X+ 
END_OF_FILE
if test 6917 -ne `wc -c <'sunplygblt.c.patch'`; then
    echo shar: \"'sunplygblt.c.patch'\" unpacked with wrong size!
fi
# end of 'sunplygblt.c.patch'
fi
if test -f 'sunpntarea.c.patch' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'sunpntarea.c.patch'\"
else
echo shar: Extracting \"'sunpntarea.c.patch'\" \(3029 characters\)
sed "s/^X//" >'sunpntarea.c.patch' <<'END_OF_FILE'
X*** sunpntarea.c.slow	Tue Aug  1 09:49:21 1989
X--- sunpntarea.c	Tue Apr 25 10:17:49 1989
X***************
X*** 0 ****
X--- 1,104 ----
X+ #include    "sun.h"
X+ #include "Xprotostr.h"
X+ 
X+ #include "maskbits.h"
X+ 
X+ static int sun_rop [] =
X+  {
X+  	PIX_SRC & PIX_NOT (PIX_SRC),
X+  	PIX_SRC & PIX_DST,
X+  	PIX_SRC & PIX_NOT (PIX_DST),
X+  	PIX_SRC,
X+  	PIX_NOT (PIX_SRC) & PIX_DST,
X+  	PIX_DST,
X+  	PIX_SRC ^ PIX_DST,
X+  	PIX_SRC | PIX_DST,
X+  	PIX_NOT (PIX_SRC | PIX_DST),
X+  	PIX_NOT (PIX_SRC ^ PIX_DST),
X+  	PIX_NOT (PIX_DST),
X+  	PIX_SRC | PIX_NOT (PIX_DST),
X+  	PIX_NOT (PIX_SRC),
X+  	PIX_NOT (PIX_SRC) | PIX_DST,
X+  	PIX_SRC | PIX_NOT (PIX_DST),
X+  	PIX_SRC | PIX_NOT (PIX_SRC),
X+  };
X+ 
X+ 
X+ char *malloc ();
X+ /*
X+ 	SUNSOLIDFILLAREA	OPEQ	EQWHOLEWORD
X+ 	sunSolidWhiteArea	|=	= ~0
X+ 	sunSolidBlackArea	&=~	= 0
X+ 	sunSolidInvertArea	^=	^= ~0
X+ 
X+ EQWHOLEWORD is used to write whole longwords.  it could use OPEQ,
X+ but *p++ |= ~0 on at least two compilers generates much
X+ worse code than *p++ = ~0.  similarly for *p++ &= ~~0
X+ and *p++ = 0.
X+ 
X+ */
X+ 
X+ 
X+ void
X+ SUNSOLIDFILLAREA (pDrawable, nbox, pbox, alu, nop)
X+     DrawablePtr pDrawable;
X+     register int nbox;
X+     register BoxPtr pbox;
X+     int alu;
X+     PixmapPtr nop;
X+ {
X+     	static struct pixrect destination;
X+     	static struct mpr_data dstmem;
X+     	register int rop, one = 1;
X+     	
X+     	PixrectFromPixmap (pDrawable, &destination, &dstmem);
X+     	switch (one EQWHOLEWORD)
X+     	 {
X+     	 	case ~1: rop = PIX_NOT (PIX_DST); break;
X+     	 	case ~0: rop = PIX_DST | PIX_NOT (PIX_DST); break;
X+     	 	case 0: rop = PIX_DST & PIX_NOT (PIX_DST); break;
X+     	 }
X+     	while (nbox--)
X+         {
X+     	    	if (pr_rop (&destination, pbox->x1, pbox->y1, pbox->x2 - pbox->x1, pbox->y2 - pbox->y1, rop, &destination, pbox->x1, pbox->y1) == PIX_ERR)
X+     	    		exit (3);
X+ 	    	pbox++;
X+         }
X+ }
X+ 
X+ int sunTileOrgX, sunTileOrgY;
X+ /* stipple a list of boxes
X+ 
X+ you can use the reduced rasterop for stipples.  if rrop is
X+ black, AND the destination with (not stipple pattern).  if rrop is
X+ white OR the destination with the stipple pattern.  if rrop is invert,
X+ XOR the destination with the stipple pattern.
X+ 
X+ 	SUNSTIPPLEFILLAREA	OPEQ
X+ 	sunStippleWhiteArea	|=
X+ 	sunStippleBlackArea	&=~
X+ 	sunStippleInvertArea	^=
X+ */
X+ 
X+ 
X+ void
X+ SUNSTIPPLEFILLAREA (pDrawable, nbox, pbox, alu, ppix)
X+     DrawablePtr pDrawable;
X+     register int nbox;
X+     register BoxPtr pbox;
X+     register int alu;
X+     PixmapPtr ppix;
X+ {
X+     	static struct pixrect tile, destination;
X+     	static struct mpr_data tilemem, dstmem;
X+     	register int rop;
X+     	
X+     	PixrectFromPixmap (pDrawable, &destination, &dstmem);
X+      	PixrectFromPixmap (ppix, &tile, &tilemem);
X+     	while (nbox--)
X+         {
X+     	    	if (pr_replrop (&destination, pbox->x1, pbox->y1, pbox->x2 - pbox->x1, pbox->y2 - pbox->y1, sun_rop [alu], &tile, pbox->x1 - sunTileOrgX, pbox->y1 - sunTileOrgY) == PIX_ERR)
X+     	    		exit (3);
X+ 	    	pbox++;
X+         }
X+ }
END_OF_FILE
if test 3029 -ne `wc -c <'sunpntarea.c.patch'`; then
    echo shar: \"'sunpntarea.c.patch'\" unpacked with wrong size!
fi
# end of 'sunpntarea.c.patch'
fi
if test -f 'suntegblt.c.patch' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'suntegblt.c.patch'\"
else
echo shar: Extracting \"'suntegblt.c.patch'\" \(7196 characters\)
sed "s/^X//" >'suntegblt.c.patch' <<'END_OF_FILE'
X*** suntegblt.c.slow	Tue Aug  1 09:49:21 1989
X--- suntegblt.c	Mon May 15 09:59:41 1989
X***************
X*** 0 ****
X--- 1,199 ----
X+ /* $Header: suntegblt.c,v 1.1 87/09/11 07:48:45 toddb Exp $ */
X+ /***********************************************************
X+ Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
X+ and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
X+ 
X+                         All Rights Reserved
X+ 
X+ Permission to use, copy, modify, and distribute this software and its 
X+ documentation for any purpose and without fee is hereby granted, 
X+ provided that the above copyright notice appear in all copies and that
X+ both that copyright notice and this permission notice appear in 
X+ supporting documentation, and that the names of Digital or MIT not be
X+ used in advertising or publicity pertaining to distribution of the
X+ software without specific, written prior permission.  
X+ 
X+ DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
X+ ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
X+ DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
X+ ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
X+ WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
X+ ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
X+ SOFTWARE.
X+ 
X+ ******************************************************************/
X+ #include	"X.h"
X+ #include	"Xmd.h"
X+ #include	"Xproto.h"
X+ #include	"fontstruct.h"
X+ #include	"dixfontstr.h"
X+ #include	"gcstruct.h"
X+ #include	"windowstr.h"
X+ #include	"scrnintstr.h"
X+ #include	"pixmapstr.h"
X+ #include	"regionstr.h"
X+ #include	"sun.h"
X+ #include	"maskbits.h"
X+ /*
X+     this works for fonts with glyphs <= 32 bits wide.
X+ 
X+     This should be called only with a terminal-emulator font;
X+ this means that the FIXED_METRICS flag is set, and that
X+ glyphbounds == charbounds.
X+ 
X+     in theory, this goes faster; even if it doesn't, it reduces the
X+ flicker caused by writing a string over itself with image text (since
X+ the background gets repainted per character instead of per string.)
X+ this seems to be important for some converted X10 applications.
X+ 
X+     Image text looks at the bits in the glyph and the fg and bg in the
X+ GC.  it paints a rectangle, as defined in the protocol dcoument,
X+ and the paints the characters.
X+ 
X+    to avoid source proliferation, this file is compiled
X+ two times:
X+ 	SUNTEGLYPHBLT		OP
X+ 	sunTEGlyphBltWhite		(white text, black bg )
X+ 	sunTEGlyphBltBlack	~	(black text, white bg )
X+ 
X+ */
X+ 
X+ void
X+ SUNTEGLYPHBLT(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase)
X+     DrawablePtr pDrawable;
X+     GC 		*pGC;
X+     int 	x, y;
X+     register unsigned int nglyph;
X+     register CharInfoPtr *ppci;		/* array of character info */
X+     register unsigned char *pglyphBase;	/* start of array of glyphs */
X+ {
X+     register int i;
X+     CharInfoPtr pci;
X+     FontInfoPtr pfi = pGC->font->pFI;
X+     int xorg, yorg;
X+     int widthDst;
X+     unsigned int *pdstBase;	/* pointer to longword with top row 
X+ 				   of current glyph */
X+ 
X+     register int w;			/* width of glyph and char */
X+     register int h;			/* height of glyph and char */
X+     int xpos;		/* current x%32  */
X+     int ypos;			/* current y%32 */
X+     /*register unsigned char *pglyph;*/
X+     int widthGlyph;
X+ 
X+     /*register unsigned int *pdst;pointer to current longword in dst */
X+     int hTmp;			/* counter for height */
X+     /*register int startmask, endmask;*/
X+     /*int nfirst;		 used if glyphs spans a longword boundary */
X+     BoxRec bbox;		/* for clipping */
X+ 
X+     static struct pr_prpos *batch = NULL;
X+     static struct pixrect *prs = NULL;
X+     static struct mpr_data *pr_datas = NULL;
X+     static int batch_length = 0;
X+  	
X+     static struct pixrect destination;
X+     static struct mpr_data data;
X+  
X+     extern struct pixrectops mem_ops;
X+     	
X+     if (pDrawable->type == DRAWABLE_WINDOW)
X+     {
X+ 	xorg = ((WindowPtr)pDrawable)->absCorner.x;
X+ 	yorg = ((WindowPtr)pDrawable)->absCorner.y;
X+ 	pdstBase = (unsigned int *)
X+ 		(((PixmapPtr)(pDrawable->pScreen->devPrivate))->devPrivate);
X+ 	widthDst = (int)
X+ 		  (((PixmapPtr)(pDrawable->pScreen->devPrivate))->devKind) >> 2;
X+     }
X+     else
X+     {
X+ 	xorg = 0;
X+ 	yorg = 0;
X+ 	pdstBase = (unsigned int *)(((PixmapPtr)pDrawable)->devPrivate);
X+ 	widthDst = (int)(((PixmapPtr)pDrawable)->devKind) >> 2;
X+     }
X+ 
X+     xpos = x + xorg;
X+     ypos = y + yorg;
X+ 
X+     pci = &pfi->maxbounds;
X+     w = pci->metrics.characterWidth;
X+     h = pfi->fontAscent + pfi->fontDescent;
X+     widthGlyph = GLYPHWIDTHBYTESPADDED(pci);
X+ 
X+     xpos += pci->metrics.leftSideBearing;
X+     ypos -= pfi->fontAscent;
X+ 
X+     bbox.x1 = xpos;
X+     bbox.x2 = xpos + (w * nglyph);
X+     bbox.y1 = ypos;
X+     bbox.y2 = ypos + h;
X+ 
X+     switch ((*pGC->pScreen->RectIn)(
X+                 ((mfbPrivGC *)(pGC->devPriv))->pCompositeClip, &bbox))
X+     {
X+       case rgnOUT:
X+ 	break;
X+       case rgnPART:
X+ 	/* this is the WRONG thing to do, but it works.
X+ 	   calling the non-terminal text is easy, but slow, given
X+ 	   what we know about the font.
X+ 
X+ 	   the right thing to do is something like:
X+ 	    for each clip rectangle
X+ 		compute at which row the glyph starts to be in it,
X+ 		   and at which row the glyph ceases to be in it
X+ 		compute which is the first glyph inside the left
X+ 		    edge, and the last one inside the right edge
X+ 		draw a fractional first glyph, using only
X+ 		    the rows we know are in
X+ 		draw all the whole glyphs, using the appropriate rows
X+ 		draw any pieces of the last glyph, using the right rows
X+ 
X+ 	   this way, the code would take advantage of knowing that
X+ 	   all glyphs are the same height and don't overlap.
X+ 
X+ 	   one day...
X+ 	*/
X+ 	CLIPTETEXT(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
X+ 	break;
X+       case rgnIN:
X+  	if (nglyph == 0)
X+  		return;
X+  	PixrectFromPixmap (pDrawable, &destination, &data);
X+  	if (batch_length < nglyph)
X+  	 {
X+  		int i;
X+  		
X+  		batch_length = nglyph;
X+  		batch = (struct pr_prpos *) Xrealloc (batch, batch_length * sizeof (struct pr_prpos));
X+  		prs = (struct pixrect *) Xrealloc (prs, batch_length * sizeof (struct pixrect));
X+  		pr_datas = (struct mpr_data *) Xrealloc (pr_datas, batch_length * sizeof (struct mpr_data));
X+  		for (i = 0; i < nglyph; i++)
X+  		 {
X+  		 	pr_datas[i].md_linebytes = 4; /* bytes , ahem */
X+  		 	pr_datas[i].md_offset.x = pr_datas[i].md_offset.y = 0;
X+  		 	pr_datas[i].md_flags = 0;
X+  		 	pr_datas[i].md_primary = 1;
X+  		 	prs[i].pr_depth = 1;
X+  		 	prs[i].pr_ops = &mem_ops;
X+   	 		prs[i].pr_data = (char *) (pr_datas + i);
X+  	 		batch[i].pr = prs + i;
X+ 		 }
X+  	 }
X+  	for (i = 0; i < nglyph; i++)
X+  	 {
X+  	 	prs[i].pr_size.x = w;
X+  	 	prs[i].pr_size.y = h;
X+  	 	batch[i].pos.x = w;
X+  	 	batch[i].pos.y = 0;
X+  	 	pr_datas[i].md_image = (short *) (pglyphBase + (*ppci++)->byteOffset);
X+  	 }
X+  	batch[0].pos.x = batch[0].pos.y = 0; /* not the first! */
X+  	pr_batchrop (&destination, xpos, ypos, (OP(0) ? PIX_NOT (PIX_SRC) : PIX_SRC), batch, nglyph);
X+ 	break;
X+     }
X+ }
X+ 
END_OF_FILE
if test 7196 -ne `wc -c <'suntegblt.c.patch'`; then
    echo shar: \"'suntegblt.c.patch'\" unpacked with wrong size!
fi
# end of 'suntegblt.c.patch'
fi
echo shar: End of archive 2 \(of 3\).
cp /dev/null ark2isdone
MISSING=""
for I in 1 2 3 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 3 archives.
    echo "Now read README.ral"
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0