REGION_INIT(pGC->pScreen, &rgnDst, NullBox, 0);
REGION_NULL(pGC->pScreen, &rgnDst);
amigaCVCopyArea(pSrcDrawable, pDstDrawable,	   pGC, srcx, srcy, width, height, dstx, dsty)     register DrawablePtr pSrcDrawable;     register DrawablePtr pDstDrawable;     GC   *pGC;     int   srcx, srcy;     int   width, height;     int   dstx, dsty;{   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 defined(USE_IMAGE_READ) &&defined(USE_IMAGE_WRITE)   if ((pSrcDrawable->type != DRAWABLE_WINDOW && pDstDrawable->type != DRAWABLE_WINDOW)) {#elif defined(USE_IMAGE_READ)   if (pSrcDrawable->type != DRAWABLE_WINDOW) {#elif defined(USE_IMAGE_WRITE)   if (pDstDrawable->type != DRAWABLE_WINDOW) {#else   if ((pSrcDrawable->type != DRAWABLE_WINDOW || pDstDrawable->type != DRAWABLE_WINDOW)) {#endif	WaitIdle(); /* Make sure ev'rything's allright */	switch (max(pSrcDrawable->bitsPerPixel, pDstDrawable->bitsPerPixel)) { 	case 8:	    return cfbCopyArea(pSrcDrawable, pDstDrawable, pGC,			       srcx, srcy, width, height, dstx, dsty);	case 16:	    return cfb16CopyArea(pSrcDrawable, pDstDrawable, pGC,				 srcx, srcy, width, height, dstx, dsty);	case 32:	    return cfb32CopyArea(pSrcDrawable, pDstDrawable, pGC,				 srcx, srcy, width, height, dstx, dsty);	default:	    __dolog("Error in CVCopyArea: illegal depth!\n");	    return NULL;	}    }   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);	 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     */    /*     * XXX because CopyPlane uses this routine for 8-to-1 bit copies, this     * next line *must* also correctly fetch the composite clip from an mfb     * gc     */      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,4);	 PCI_HACK();	 S3_OUTW(FRGD_MIX, FSS_BITBLT | s3alu[pGC->alu]);	 S3_OUTW(BKGD_MIX, BSS_BKGDCOL | MIX_SRC);	 S3_OUTW32(WRT_MASK, pGC->planemask);	 if (direction == (INC_X | INC_Y)) {	    for (i = 0; i < numRects; i++) {	       prect = &pbox[ordering[i]];	       WaitQueue(7); PCI_HACK();	       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); PCI_HACK();	       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); PCI_HACK();	       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); PCI_HACK();	       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(3,4); WaitIdle();	 S3_OUTW(FRGD_MIX, FSS_FRGDCOL | MIX_SRC);	 S3_OUTW(BKGD_MIX, BSS_BKGDCOL | MIX_SRC);	 S3_OUTW32(WRT_MASK, ~0);	 UNBLOCK_CURSOR;	 DEALLOCATE_LOCAL(ordering);      } #ifdef USE_IMAGE_READ      else if (pSrcDrawable->type == DRAWABLE_WINDOW &&		 pDstDrawable->type != DRAWABLE_WINDOW) {       /* Window --> Pixmap */	 int   pixWidth = PixmapBytePad(pDstDrawable->width, pDstDrawable->depth);	 char *pdst = ((PixmapPtr) pDstDrawable)->devPrivate.ptr;	 for (i = numRects; --i >= 0; pbox++)	    amigaCVImageRead (pbox->x1 + dx, pbox->y1 + dy,			       pbox->x2 - pbox->x1, pbox->y2 - pbox->y1,			       pdst, pixWidth, pbox->x1, pbox->y1,			       pGC->planemask, inf);      } #endif#ifdef USE_IMAGE_WRITE      else if (pSrcDrawable->type != DRAWABLE_WINDOW &&		 pDstDrawable->type == DRAWABLE_WINDOW) {       /* Pixmap --> Window */	 int   pixWidth = PixmapBytePad(pSrcDrawable->width, pSrcDrawable->depth);	 char *psrc = ((PixmapPtr) pSrcDrawable)->devPrivate.ptr;	 for (i = numRects; --i >= 0; pbox++)	    amigaCVImageWrite (pbox->x1, pbox->y1,				pbox->x2 - pbox->x1, pbox->y2 - pbox->y1,				psrc, pixWidth, pbox->x1 + dx, pbox->y1 + dy,				s3alu[pGC->alu], pGC->planemask,inf);      }#endif      else {       /* Pixmap --> Pixmap */	 ErrorF("s3CopyArea:  Tried to do a Pixmap to Pixmap copy\n");      }    /*     * (*localDoBitBlt) (pSrcDrawable, pDstDrawable, pGC->alu, &rgnDst,     * pptSrc, pGC->planemask);     */   }   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);   return prgnExposed;}