#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
#include <stdlib.h>
#include <X11/X.h>
#include <X11/Xprotostr.h>
#include "regionstr.h"
#include "gcstruct.h"
#include "windowstr.h"
#include "pixmapstr.h"
#include "scrnintstr.h"
#include "mi.h"
#include "afb.h"
#include "maskbits.h"
void
afbDoBitblt(DrawablePtr pSrc, DrawablePtr pDst, int alu, RegionPtr prgnDst, DDXPointPtr pptSrc, long unsigned int planemask)
{
switch (alu) {
case GXcopy:
afbDoBitbltCopy(pSrc, pDst, alu, prgnDst, pptSrc, planemask);
break;
case GXxor:
afbDoBitbltXor(pSrc, pDst, alu, prgnDst, pptSrc, planemask);
break;
case GXcopyInverted:
afbDoBitbltCopyInverted(pSrc, pDst, alu, prgnDst, pptSrc, planemask);
break;
case GXor:
afbDoBitbltOr(pSrc, pDst, alu, prgnDst, pptSrc, planemask);
break;
default:
afbDoBitbltGeneral(pSrc, pDst, alu, prgnDst, pptSrc, planemask);
break;
}
}
typedef void (*afb_blit_func)
(DrawablePtr, DrawablePtr, int, RegionPtr, DDXPointPtr, unsigned long);
static RegionPtr
afbBitBlt(register DrawablePtr pSrcDrawable, register DrawablePtr pDstDrawable, register GC *pGC, int srcx, int srcy, int width, int height, int dstx, int dsty, afb_blit_func doBitBlt, long unsigned int planemask)
{
RegionPtr prgnSrcClip = NULL;
Bool freeSrcClip = FALSE;
RegionPtr prgnExposed;
RegionRec rgnDst;
DDXPointPtr pptSrc;
register DDXPointPtr ppt;
register BoxPtr pbox;
int i;
register int dx;
register int dy;
xRectangle origSource;
DDXPointRec origDest;
int numRects;
BoxRec fastBox;
int fastClip = 0;
int fastExpose = 0;
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;
if (pSrcDrawable->type == DRAWABLE_PIXMAP)
if ((pSrcDrawable == pDstDrawable) && (pGC->clientClipType == CT_NONE))
prgnSrcClip = pGC->pCompositeClip;
else
fastClip = 1;
else if (pGC->subWindowMode == IncludeInferiors)
if (!((WindowPtr)pSrcDrawable)->parent)
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;
if (fastClip) {
fastExpose = 1;
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;
if (fastClip) {
RegionPtr cclip;
fastBox.x1 -= dx;
fastBox.x2 -= dx;
fastBox.y1 -= dy;
fastBox.y2 -= dy;
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;
if (fastBox.x1 >= fastBox.x2 || fastBox.y1 >= fastBox.y2) {
REGION_NULL(pGC->pScreen, &rgnDst);
} else {
REGION_INIT(pGC->pScreen, &rgnDst, &fastBox, 1);
}
} else {
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);
}
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->alu, &rgnDst, pptSrc,
planemask);
DEALLOCATE_LOCAL(pptSrc);
}
prgnExposed = NULL;
if (pGC->fExpose) {
if (!fastExpose)
prgnExposed = miHandleExposures(pSrcDrawable, pDstDrawable, pGC,
origSource.x, origSource.y,
(int)origSource.width,
(int)origSource.height, origDest.x,
origDest.y, (unsigned long)0);
}
REGION_UNINIT(pGC->pScreen, &rgnDst);
if (freeSrcClip)
REGION_DESTROY(pGC->pScreen, prgnSrcClip);
return prgnExposed;
}
RegionPtr
afbCopyArea(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GC *pGC, int srcx, int srcy, int width, int height, int dstx, int dsty)
{
afb_blit_func doBitBlt;
switch (pGC->alu) {
case GXcopy:
doBitBlt = afbDoBitbltCopy;
break;
case GXxor:
doBitBlt = afbDoBitbltXor;
break;
case GXcopyInverted:
doBitBlt = afbDoBitbltCopyInverted;
break;
case GXor:
doBitBlt = afbDoBitbltOr;
break;
default:
doBitBlt = afbDoBitbltGeneral;
break;
}
return(afbBitBlt(pSrcDrawable, pDstDrawable, pGC, srcx, srcy,
width, height, dstx, dsty, doBitBlt, pGC->planemask));
}