#include "X.h"
#include "Xprotostr.h"
#include "miscstruct.h"
#include "regionstr.h"
#include "gcstruct.h"
#include "windowstr.h"
#include "pixmapstr.h"
#include "scrnintstr.h"
#include "mi.h"
#include "ilbm.h"
#include "maskbits.h"
static unsigned char ilbmRropsOS[AFB_MAX_DEPTH];
void
ilbmDoBitblt(pSrc, pDst, alu, prgnDst, pptSrc, planemask)
DrawablePtr pSrc, pDst;
int alu;
RegionPtr prgnDst;
DDXPointPtr pptSrc;
unsigned long planemask;
{
switch (alu) {
case GXcopy:
ilbmDoBitbltCopy(pSrc, pDst, alu, prgnDst, pptSrc, planemask);
break;
case GXxor:
ilbmDoBitbltXor(pSrc, pDst, alu, prgnDst, pptSrc, planemask);
break;
case GXcopyInverted:
ilbmDoBitbltCopyInverted(pSrc, pDst, alu, prgnDst, pptSrc, planemask);
break;
case GXor:
ilbmDoBitbltOr(pSrc, pDst, alu, prgnDst, pptSrc, planemask);
break;
default:
ilbmDoBitbltGeneral(pSrc, pDst, alu, prgnDst, pptSrc, planemask);
break;
}
}
RegionPtr
ilbmCopyArea(pSrcDrawable, pDstDrawable, pGC, srcx, srcy, width, height,
dstx, dsty)
DrawablePtr pSrcDrawable;
DrawablePtr pDstDrawable;
GC *pGC;
int srcx, srcy;
int width, height;
int dstx, dsty;
{
void (*doBitBlt)();
switch (pGC->alu) {
case GXcopy:
doBitBlt = ilbmDoBitbltCopy;
break;
case GXxor:
doBitBlt = ilbmDoBitbltXor;
break;
case GXcopyInverted:
doBitBlt = ilbmDoBitbltCopyInverted;
break;
case GXor:
doBitBlt = ilbmDoBitbltOr;
break;
default:
doBitBlt = ilbmDoBitbltGeneral;
break;
}
return(ilbmBitBlt(pSrcDrawable, pDstDrawable, pGC, srcx, srcy,
width, height, dstx, dsty, doBitBlt, pGC->planemask));
}
RegionPtr
ilbmBitBlt(pSrcDrawable, pDstDrawable, pGC, srcx, srcy, width, height,
dstx, dsty, doBitBlt, planemask)
register DrawablePtr pSrcDrawable;
register DrawablePtr pDstDrawable;
register GC *pGC;
int srcx, srcy;
int width, height;
int dstx, dsty;
void (*doBitBlt)();
unsigned long planemask;
{
RegionPtr prgnSrcClip;
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;
void (*localDoBitBlt)();
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
ilbmCopyPlane(pSrcDrawable, pDstDrawable, pGC, srcx, srcy, width, height,
dstx, dsty, plane)
DrawablePtr pSrcDrawable, pDstDrawable;
register GC *pGC;
int srcx, srcy;
int width, height;
int dstx, dsty;
unsigned long plane;
{
int alu;
RegionPtr prgnExposed = NULL;
unsigned long old_planemask;
PixmapPtr pPixmap = NULL;
if (pDstDrawable->depth == 1) {
old_planemask = pGC->planemask;
pGC->planemask = plane;
if ((pGC->fgPixel & 1) == 1 && (pGC->bgPixel & 1) == 0) {
prgnExposed = (*pGC->ops->CopyArea)(pSrcDrawable, pDstDrawable,
pGC, srcx, srcy, width, height, dstx, dsty);
} else if ((pGC->fgPixel & 1) == (pGC->bgPixel & 1)) {
unsigned char rop;
ilbmReduceRop(pGC->alu, pGC->fgPixel, 1, 1, &rop);
alu = pGC->alu;
pGC->alu = rop;
prgnExposed = (*pGC->ops->CopyArea)(pSrcDrawable, pDstDrawable, pGC,
srcx, srcy, width, height, dstx,
dsty);
pGC->alu = alu;
} else {
alu = pGC->alu;
pGC->alu = ilbmInverseAlu[alu];
prgnExposed = (*pGC->ops->CopyArea)(pSrcDrawable, pDstDrawable, pGC,
srcx, srcy, width, height, dstx,
dsty);
pGC->alu = alu;
}
pGC->planemask = old_planemask;
} else {
int free_pixmap = FALSE;
PixmapPtr pBitmap = (PixmapPtr)pSrcDrawable;
ScreenPtr pScreen = pSrcDrawable->pScreen;
GCPtr pGC1;
if (pSrcDrawable == pDstDrawable ||
pSrcDrawable->type == DRAWABLE_WINDOW || pSrcDrawable->depth != 1) {
pBitmap = (*pScreen->CreatePixmap)(pScreen, width, height, 1);
if (!pBitmap)
return(NULL);
pGC1 = GetScratchGC(1, pScreen);
if (!pGC1) {
(*pScreen->DestroyPixmap)(pBitmap);
return(NULL);
}
ValidateGC((DrawablePtr)pBitmap, pGC1);
(void)ilbmBitBlt(pSrcDrawable, (DrawablePtr)pBitmap, pGC1, srcx, srcy,
width, height, 0, 0, ilbmDoBitbltCopy, plane);
free_pixmap = TRUE;
}
#if 0
else {
}
#endif
ilbmReduceOpaqueStipple(pGC->fgPixel, pGC->bgPixel, pGC->planemask,
pGC->depth, ilbmRropsOS);
(void)ilbmBitBlt((DrawablePtr)pBitmap, pDstDrawable, pGC, 0, 0, width,
height, dstx, dsty, ilbmCopy1ToN, pGC->planemask);
if (free_pixmap) {
(*pScreen->DestroyPixmap)(pBitmap);
FreeScratchGC(pGC1);
}
if (pGC->fExpose)
prgnExposed = miHandleExposures(pSrcDrawable, pDstDrawable, pGC, srcx,
srcy, width, height, dstx, dsty,
plane);
}
return prgnExposed;
}
void
ilbmCopy1ToN(pSrc, pDst, alu, prgnDst, pptSrc, planemask)
DrawablePtr pSrc, pDst;
int alu;
RegionPtr prgnDst;
DDXPointPtr pptSrc;
unsigned long planemask;
{
int numRects = REGION_NUM_RECTS(prgnDst);
BoxPtr pbox = REGION_RECTS(prgnDst);
int r;
for (r = 0; r < numRects; r++, pbox++, pptSrc++) {
int dx = pptSrc->x;
int dy = pptSrc->y;
if (alu == GXcopy)
ilbmOpaqueStippleAreaCopy(pDst, 1, pbox, alu, (PixmapPtr)pSrc, dx, dy,
ilbmRropsOS, planemask);
else
ilbmOpaqueStippleAreaGeneral(pDst, 1, pbox, alu, (PixmapPtr)pSrc, dx,
dy, ilbmRropsOS, planemask);
}
}