REGION_INIT(pGC->pScreen, &rgnDst, NullBox, 0);
REGION_NULL(pGC->pScreen, &rgnDst);
amigaCVCopyPlane(pSrcDrawable, pDstDrawable,            pGC, srcx, srcy, width, height, dstx, dsty, bitPlane)    DrawablePtr              pSrcDrawable;    DrawablePtr              pDstDrawable;    GCPtr            pGC;    int                      srcx, srcy;    int                      width, height;    int                      dstx, dsty;    unsigned long    bitPlane;{   PixmapPtr pBitmap = NULL;   RegionPtr prgnSrcClip;	/* may be a new region, or just a copy */   Bool  freeSrcClip = FALSE;   RegionPtr prgnExposed;   RegionRec rgnDst;   register BoxPtr pbox;   int   i;   register int dx;   register int dy;   xRectangle origSource;   DDXPointRec origDest;   int   numRects;   BoxRec fastBox;   int   fastClip = 0;		/* for fast clipping with pixmap source */   int   fastExpose = 0;	/* for fast exposures with pixmap source */   fbFd *inf = amigaInfo(pSrcDrawable->pScreen);   volatile caddr_t vgaBase =  (inf->regs);   /*    * If switched away, or doing pixmap->pixmap copy, just use cfb.    */   if ((pSrcDrawable->type != DRAWABLE_WINDOW || /* was && */	pDstDrawable->type != DRAWABLE_WINDOW))   {	switch (max(pSrcDrawable->bitsPerPixel, pDstDrawable->bitsPerPixel)) { 	case 8:	    return cfbCopyPlane(pSrcDrawable, pDstDrawable, pGC,			    srcx, srcy, width, height, dstx, dsty, bitPlane);	case 16:	    return cfb16CopyPlane(pSrcDrawable, pDstDrawable, pGC,			      srcx, srcy, width, height, dstx, dsty, bitPlane);	case 32:	    return cfb32CopyPlane(pSrcDrawable, pDstDrawable, pGC,			      srcx, srcy, width, height, dstx, dsty, bitPlane);	}   } #if 0   /* This can cause server lockups */   /*    * If we are using a linear mapped framebuffer, using direct memory    * access is faster than using the graphics engine to do stipple    * operations.    */   if (s3LinearAperture) {      /*        * Fall through to below for window->window moves, since the graphics       * engine is the fastest way to do this.  Otherwise, use the cfb code       * on the linear region, because that's faster than the graphics engine       * for stipple-type operations.       */      if ((pSrcDrawable->type != DRAWABLE_WINDOW) ||	  (pDstDrawable->type != DRAWABLE_WINDOW)) {         RegionPtr retVal;	 BLOCK_CURSOR;         s3EnableLinear();         retVal = cfbCopyPlane(pSrcDrawable, pDstDrawable, pGC, srcx, srcy, 			       width, height, dstx, dsty, bitPlane);         s3DisableLinear();	 UNBLOCK_CURSOR;         return retVal;      }   } else#endif   {      if ((pSrcDrawable->type != DRAWABLE_WINDOW) &&	  (pDstDrawable->type == DRAWABLE_WINDOW) &&	  (pSrcDrawable->bitsPerPixel == 8)) {	 /*	  * Shortcut - we can do Pixmap->Window when the source depth is	  * 8 by using the handy-dandy cfbCopyPlane8to1 to create a bitmap	  * for us to use.	  */	 GCPtr pGC1;	 pBitmap=(*pSrcDrawable->pScreen->CreatePixmap)(pSrcDrawable->pScreen,                                                         pSrcDrawable->width,                                                        pSrcDrawable->height, 1);	 if (!pBitmap)	    return(NULL);	 pGC1 = GetScratchGC(1, pSrcDrawable->pScreen);	 if (!pGC1) {	    (*pSrcDrawable->pScreen->DestroyPixmap)(pBitmap);	    return(NULL);	 }	 ValidateGC((DrawablePtr)pBitmap, pGC1);	 (void) cfbCopyPlaneReduce(pSrcDrawable, (DrawablePtr)pBitmap, pGC1, srcx, srcy,			  width, height, srcx, srcy, cfbCopyPlane8to1, bitPlane);         FreeScratchGC(pGC1);	 pSrcDrawable = (DrawablePtr)pBitmap;      }      else if ((pSrcDrawable->type == DRAWABLE_WINDOW) &&	       (pDstDrawable->type != DRAWABLE_WINDOW) &&	       (pSrcDrawable->bitsPerPixel == 8)) {	 /*	  * Shortcut - we can do Window->Pixmap by copying the window to	  * a pixmap, then we have a Pixmap->Pixmap operation	  */	 GCPtr pGC1;	 RegionPtr retval;	 PixmapPtr pPixmap;	 pPixmap=(*pSrcDrawable->pScreen->CreatePixmap)(pSrcDrawable->pScreen, 						        width, height, 8);	 if (!pPixmap)	    return(NULL);	 pGC1 = GetScratchGC(8, pSrcDrawable->pScreen);	 if (!pGC1) {	    (*pSrcDrawable->pScreen->DestroyPixmap)(pPixmap);	    return(NULL);	 }	 ValidateGC((DrawablePtr)pPixmap, pGC1);	 amigaCVCopyArea(pSrcDrawable, (DrawablePtr)pPixmap, pGC1, srcx, srcy,			width, height, 0, 0);	 retval = cfbCopyPlane((DrawablePtr)pPixmap, pDstDrawable, pGC,                             0, 0, width, height, dstx, dsty, bitPlane);         FreeScratchGC(pGC1);	 (*pSrcDrawable->pScreen->DestroyPixmap)(pPixmap);	 return(retval);      }      else if (((pSrcDrawable->type == DRAWABLE_WINDOW) &&                 (pDstDrawable->type != DRAWABLE_WINDOW)) ||	       ((pSrcDrawable->type != DRAWABLE_WINDOW) &&		(pDstDrawable->type == DRAWABLE_WINDOW) &&		(pSrcDrawable->bitsPerPixel != 1))) {         /*          * Cases we can't handle, and must do another way:          *	- copy Window->Pixmap	  *	- copy Pixmap->Window, depth != {1,8}          *          * Simplest thing to do is to let miCopyPlane deal with it for us.          */         return miCopyPlane(pSrcDrawable, pDstDrawable, pGC, srcx, srcy, 			    width, height, dstx, dsty, bitPlane);      }   }   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 = cfbGetCompositeClip(pGC);      } else {	 fastClip = 1;      }   } else {      if (pGC->subWindowMode == IncludeInferiors) {	 if (!((WindowPtr) pSrcDrawable)->parent) {	    /*	     * special case bitblt from root window in IncludeInferiors mode;	     * just like from a pixmap	     */	    fastClip = 1;	 } else if ((pSrcDrawable == pDstDrawable) &&		    (pGC->clientClipType == CT_NONE)) {	    prgnSrcClip = cfbGetCompositeClip(pGC);	 } 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);         if (pBitmap)            (*pSrcDrawable->pScreen->DestroyPixmap)(pBitmap);	 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 = cfbGetCompositeClip(pGC);      if (REGION_NUM_RECTS(cclip) == 1) {	 BoxPtr pBox = REGION_RECTS(cclip);	 if (fastBox.x1 < pBox->x1)	    fastBox.x1 = pBox->x1;	 if (fastBox.x2 > pBox->x2)	    fastBox.x2 = pBox->x2;	 if (fastBox.y1 < pBox->y1)	    fastBox.y1 = pBox->y1;	 if (fastBox.y2 > pBox->y2)	    fastBox.y2 = pBox->y2;       /* Check to see if the region is empty */	 if (fastBox.x1 >= fastBox.x2 || fastBox.y1 >= fastBox.y2) {	    REGION_INIT(pGC->pScreen, &rgnDst, NullBox, 0);	 } else {	    REGION_INIT(pGC->pScreen, &rgnDst, &fastBox, 1);	 }      } else {         /*          * We must turn off fastClip now, since we must create a full blown          * region.  It is intersected with the composite clip below.          */	 fastClip = 0;	 REGION_INIT(pGC->pScreen, &rgnDst, &fastBox, 1);      }   } else {      REGION_TRANSLATE(pGC->pScreen, &rgnDst, -dx, -dy);   }   if (!fastClip) {      REGION_INTERSECT(pGC->pScreen, &rgnDst, &rgnDst, cfbGetCompositeClip(pGC));   }   /* Do bit blitting */   numRects = REGION_NUM_RECTS(&rgnDst);   if (numRects && width && height) {      pbox = REGION_RECTS(&rgnDst);      if (pSrcDrawable->type == DRAWABLE_WINDOW && 	  pDstDrawable->type == DRAWABLE_WINDOW) {         /* Window --> Window */	 unsigned int *ordering;	 BoxPtr prect;	 short direction = 0;	 ordering = (unsigned int *)ALLOCATE_LOCAL(numRects * 						   sizeof(unsigned int));	 if (!ordering) {	    DEALLOCATE_LOCAL(ordering);	    return (RegionPtr) NULL;	 }	 amigaCVFindOrdering(pSrcDrawable, pDstDrawable, pGC, numRects, pbox, 			srcx, srcy, dstx, dsty, ordering);	 if (dx > 0)	    direction |= INC_X;	 if (dy > 0)	    direction |= INC_Y;	 BLOCK_CURSOR;	 WaitQueue16_32(3,5);	 S3_OUTW(FRGD_MIX, FSS_FRGDCOL | s3alu[pGC->alu]);	 S3_OUTW32(RD_MASK, bitPlane);	 S3_OUTW32(WRT_MASK, pGC->planemask);	 WaitQueue16_32(3,5);	 S3_OUTW32(FRGD_COLOR, pGC->fgPixel);	 S3_OUTW32(BKGD_COLOR, pGC->bgPixel);	 S3_OUTW(MULTIFUNC_CNTL, PIX_CNTL|MIXSEL_EXPBLT);	 if (direction == (INC_X | INC_Y)) {	    for (i = 0; i < numRects; i++) {	       prect = &pbox[ordering[i]];	       WaitQueue(7);	       S3_OUTW(CUR_X, (short)(prect->x1 + dx));	       S3_OUTW(CUR_Y, (short)(prect->y1 + dy));	       S3_OUTW(DESTX_DIASTP, (short)(prect->x1));	       S3_OUTW(DESTY_AXSTP, (short)(prect->y1));	       S3_OUTW(MAJ_AXIS_PCNT, (short)(prect->x2 - prect->x1 - 1));	       S3_OUTW(MULTIFUNC_CNTL, 		    MIN_AXIS_PCNT | (short)(prect->y2 - prect->y1 - 1));	       S3_OUTW(CMD, CMD_BITBLT | direction | DRAW | PLANAR | WRTDATA);	    }	 } else if (direction == INC_X) {	    for (i = 0; i < numRects; i++) {	       prect = &pbox[ordering[i]];	       WaitQueue(7);	       S3_OUTW(CUR_X, (short)(prect->x1 + dx));	       S3_OUTW(CUR_Y, (short)(prect->y2 + dy - 1));	       S3_OUTW(DESTX_DIASTP, (short)(prect->x1));	       S3_OUTW(DESTY_AXSTP, (short)(prect->y2 - 1));	       S3_OUTW(MAJ_AXIS_PCNT, (short)(prect->x2 - prect->x1 - 1));	       S3_OUTW(MULTIFUNC_CNTL, 		    MIN_AXIS_PCNT | (short)(prect->y2 - prect->y1 - 1));	       S3_OUTW(CMD, CMD_BITBLT | direction | DRAW | PLANAR | WRTDATA);	    }	 } else if (direction == INC_Y) {	    for (i = 0; i < numRects; i++) {	       prect = &pbox[ordering[i]];	       WaitQueue(7);	       S3_OUTW(CUR_X, (short)(prect->x2 + dx - 1));	       S3_OUTW(CUR_Y, (short)(prect->y1 + dy));	       S3_OUTW(DESTX_DIASTP, (short)(prect->x2 - 1));	       S3_OUTW(DESTY_AXSTP, (short)(prect->y1));	       S3_OUTW(MAJ_AXIS_PCNT, (short)(prect->x2 - prect->x1 - 1));	       S3_OUTW(MULTIFUNC_CNTL, 		    MIN_AXIS_PCNT | (short)(prect->y2 - prect->y1 - 1));	       S3_OUTW(CMD, CMD_BITBLT | direction | DRAW | PLANAR | WRTDATA);	    }	 } else {	    for (i = 0; i < numRects; i++) {	       prect = &pbox[ordering[i]];	       WaitQueue(7);	       S3_OUTW(CUR_X, (short)(prect->x2 + dx - 1));	       S3_OUTW(CUR_Y, (short)(prect->y2 + dy - 1));	       S3_OUTW(DESTX_DIASTP, (short)(prect->x2 - 1));	       S3_OUTW(DESTY_AXSTP, (short)(prect->y2 - 1));	       S3_OUTW(MAJ_AXIS_PCNT, (short)(prect->x2 - prect->x1 - 1));	       S3_OUTW(MULTIFUNC_CNTL, 		    MIN_AXIS_PCNT | (short)(prect->y2 - prect->y1 - 1));	       S3_OUTW(CMD, CMD_BITBLT | direction | DRAW | PLANAR | WRTDATA);	    }	 }	 WaitQueue16_32(4,6);	 WaitIdle();	 S3_OUTW(FRGD_MIX, FSS_FRGDCOL | MIX_SRC);	 S3_OUTW32(RD_MASK, ~0);	 S3_OUTW32(WRT_MASK, ~0);	 S3_OUTW(MULTIFUNC_CNTL, PIX_CNTL | MIXSEL_FRGDMIX | COLCMPOP_F);	 UNBLOCK_CURSOR;	 DEALLOCATE_LOCAL(ordering);      } else if (pSrcDrawable->type == DRAWABLE_WINDOW && 		 pDstDrawable->type != DRAWABLE_WINDOW) {         /* Window --> Pixmap */	 /* THIS IS NOT IMPLEMENTED - IT GETS PASSED TO miCopyPlane ABOVE */      } else if (pSrcDrawable->type != DRAWABLE_WINDOW && 		 pDstDrawable->type == DRAWABLE_WINDOW) {#if 0         /* Pixmap --> Window */         PixmapPtr pix = (PixmapPtr) pSrcDrawable;	 int   pixWidth;	 char *psrc;	 pixWidth = PixmapBytePad(pSrcDrawable->width, pSrcDrawable->depth);	 psrc = pix->devPrivate.ptr;	 	 for (i = numRects; --i >= 0; pbox++) {	    s3ImageOpStipple(pbox->x1, pbox->y1,			     pbox->x2 - pbox->x1, pbox->y2 - pbox->y1,			     psrc, pixWidth,			     pix->drawable.width, pix->drawable.height,			     -dx, -dy, pGC->fgPixel, pGC->bgPixel, 			     s3alu[pGC->alu], (short)pGC->planemask);	 }#endif      } else {         /* Pixmap --> Pixmap */	 ErrorF("s3CopyArea:  Tried to do a Pixmap to Pixmap copy\n");      }   }   prgnExposed = NULL;   if (pGC->fExpose) {      extern RegionPtr miHandleExposures();      /* 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, 0);   }   REGION_UNINIT(pGC->pScreen, &rgnDst);   if (freeSrcClip)      REGION_DESTROY(pGC->pScreen, prgnSrcClip);   if (pBitmap)      (*pSrcDrawable->pScreen->DestroyPixmap) (pBitmap);   return prgnExposed;}