#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
#include <X11/X.h>
#include <X11/Xprotostr.h>
#include <stdlib.h>
#include "regionstr.h"
#include "gcstruct.h"
#include "windowstr.h"
#include "pixmapstr.h"
#include "scrnintstr.h"
#include "mi.h"
#include "mfb.h"
#include "maskbits.h"
void
mfbDoBitblt (pSrc, pDst, alu, prgnDst, pptSrc)
DrawablePtr pSrc, pDst;
int alu;
RegionPtr prgnDst;
DDXPointPtr pptSrc;
{
switch (alu)
{
case GXcopy:
mfbDoBitbltCopy (pSrc, pDst, alu, prgnDst, pptSrc);
break;
case GXxor:
mfbDoBitbltXor (pSrc, pDst, alu, prgnDst, pptSrc);
break;
case GXcopyInverted:
mfbDoBitbltCopyInverted (pSrc, pDst, alu, prgnDst, pptSrc);
break;
case GXor:
mfbDoBitbltOr (pSrc, pDst, alu, prgnDst, pptSrc);
break;
default:
mfbDoBitbltGeneral (pSrc, pDst, alu, prgnDst, pptSrc);
break;
}
}
RegionPtr
mfbCopyArea(pSrcDrawable, pDstDrawable,
pGC, srcx, srcy, width, height, dstx, dsty)
register DrawablePtr pSrcDrawable;
register DrawablePtr pDstDrawable;
register GC *pGC;
int srcx, srcy;
int width, height;
int dstx, dsty;
{
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;
void (*localDoBitBlt)(
DrawablePtr ,
DrawablePtr ,
int ,
RegionPtr ,
DDXPointPtr );
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);
}
switch (pGC->alu) {
case GXcopy:
localDoBitBlt = mfbDoBitbltCopy;
break;
case GXcopyInverted:
localDoBitBlt = mfbDoBitbltCopyInverted;
break;
case GXxor:
localDoBitBlt = mfbDoBitbltXor;
break;
case GXor:
localDoBitBlt = mfbDoBitbltOr;
break;
default:
localDoBitBlt = mfbDoBitbltGeneral;
break;
}
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;
}
if (pGC->planemask & 1)
(*localDoBitBlt) (pSrcDrawable, pDstDrawable, pGC->alu, &rgnDst, pptSrc);
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;
}
static unsigned long copyPlaneGeneration;
static int copyPlaneScreenIndex = -1;
Bool
mfbRegisterCopyPlaneProc (pScreen, proc)
ScreenPtr pScreen;
RegionPtr (*proc)(
DrawablePtr ,
DrawablePtr ,
GCPtr ,
int ,
int ,
int ,
int ,
int ,
int ,
unsigned long );
{
if (copyPlaneGeneration != serverGeneration)
{
copyPlaneScreenIndex = AllocateScreenPrivateIndex();
if (copyPlaneScreenIndex < 0)
return FALSE;
copyPlaneGeneration = serverGeneration;
}
pScreen->devPrivates[copyPlaneScreenIndex].fptr = proc;
return TRUE;
}
RegionPtr
mfbCopyPlane(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;
RegionPtr (*copyPlane)(
DrawablePtr ,
DrawablePtr ,
GCPtr ,
int ,
int ,
int ,
int ,
int ,
int ,
unsigned long );
if (pSrcDrawable->depth != 1)
{
if (copyPlaneScreenIndex >= 0 &&
(copyPlane =
pSrcDrawable->pScreen->devPrivates[copyPlaneScreenIndex].fptr)
)
{
return (*copyPlane) (pSrcDrawable, pDstDrawable,
pGC, srcx, srcy, width, height, dstx, dsty, plane);
}
else
{
FatalError ("No copyPlane proc registered for depth %d\n",
pSrcDrawable->depth);
}
}
if (plane != 1)
return NULL;
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))
{
alu = pGC->alu;
pGC->alu = mfbReduceRop(pGC->alu, pGC->fgPixel);
prgnExposed = (*pGC->ops->CopyArea)(pSrcDrawable, pDstDrawable,
pGC, srcx, srcy, width, height, dstx, dsty);
pGC->alu = alu;
}
else
{
alu = pGC->alu;
pGC->alu = InverseAlu[alu];
prgnExposed = (*pGC->ops->CopyArea)(pSrcDrawable, pDstDrawable,
pGC, srcx, srcy, width, height, dstx, dsty);
pGC->alu = alu;
}
return prgnExposed;
}