270 lines
9.3 KiB
C
270 lines
9.3 KiB
C
/*
|
|
* Copyright © 1998 Keith Packard
|
|
*
|
|
* Permission to use, copy, modify, distribute, and sell this software and its
|
|
* documentation for any purpose is hereby granted without fee, provided that
|
|
* the above copyright notice appear in all copies and that both that
|
|
* copyright notice and this permission notice appear in supporting
|
|
* documentation, and that the name of Keith Packard not be used in
|
|
* advertising or publicity pertaining to distribution of the software without
|
|
* specific, written prior permission. Keith Packard makes no
|
|
* representations about the suitability of this software for any purpose. It
|
|
* is provided "as is" without express or implied warranty.
|
|
*
|
|
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
|
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
|
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
|
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
|
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
|
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
* PERFORMANCE OF THIS SOFTWARE.
|
|
*/
|
|
|
|
#ifdef HAVE_DIX_CONFIG_H
|
|
#include <dix-config.h>
|
|
#endif
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include "fb.h"
|
|
|
|
void
|
|
fbCopyNtoN(DrawablePtr pSrcDrawable,
|
|
DrawablePtr pDstDrawable,
|
|
GCPtr pGC,
|
|
BoxPtr pbox,
|
|
int nbox,
|
|
int dx,
|
|
int dy, Bool reverse, Bool upsidedown, Pixel bitplane, void *closure)
|
|
{
|
|
CARD8 alu = pGC ? pGC->alu : GXcopy;
|
|
FbBits pm = pGC ? fbGetGCPrivate(pGC)->pm : FB_ALLONES;
|
|
FbBits *src;
|
|
FbStride srcStride;
|
|
int srcBpp;
|
|
int srcXoff, srcYoff;
|
|
FbBits *dst;
|
|
FbStride dstStride;
|
|
int dstBpp;
|
|
int dstXoff, dstYoff;
|
|
|
|
fbGetDrawable(pSrcDrawable, src, srcStride, srcBpp, srcXoff, srcYoff);
|
|
fbGetDrawable(pDstDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
|
|
|
|
while (nbox--) {
|
|
#ifndef FB_ACCESS_WRAPPER /* pixman_blt() doesn't support accessors yet */
|
|
if (pm == FB_ALLONES && alu == GXcopy && !reverse && !upsidedown) {
|
|
if (!pixman_blt
|
|
((uint32_t *) src, (uint32_t *) dst, srcStride, dstStride,
|
|
srcBpp, dstBpp, (pbox->x1 + dx + srcXoff),
|
|
(pbox->y1 + dy + srcYoff), (pbox->x1 + dstXoff),
|
|
(pbox->y1 + dstYoff), (pbox->x2 - pbox->x1),
|
|
(pbox->y2 - pbox->y1)))
|
|
goto fallback;
|
|
else
|
|
goto next;
|
|
}
|
|
fallback:
|
|
#endif
|
|
fbBlt(src + (pbox->y1 + dy + srcYoff) * srcStride,
|
|
srcStride,
|
|
(pbox->x1 + dx + srcXoff) * srcBpp,
|
|
dst + (pbox->y1 + dstYoff) * dstStride,
|
|
dstStride,
|
|
(pbox->x1 + dstXoff) * dstBpp,
|
|
(pbox->x2 - pbox->x1) * dstBpp,
|
|
(pbox->y2 - pbox->y1), alu, pm, dstBpp, reverse, upsidedown);
|
|
#ifndef FB_ACCESS_WRAPPER
|
|
next:
|
|
#endif
|
|
pbox++;
|
|
}
|
|
fbFinishAccess(pDstDrawable);
|
|
fbFinishAccess(pSrcDrawable);
|
|
}
|
|
|
|
void
|
|
fbCopy1toN(DrawablePtr pSrcDrawable,
|
|
DrawablePtr pDstDrawable,
|
|
GCPtr pGC,
|
|
BoxPtr pbox,
|
|
int nbox,
|
|
int dx,
|
|
int dy, Bool reverse, Bool upsidedown, Pixel bitplane, void *closure)
|
|
{
|
|
FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
|
|
FbBits *src;
|
|
FbStride srcStride;
|
|
int srcBpp;
|
|
int srcXoff, srcYoff;
|
|
FbBits *dst;
|
|
FbStride dstStride;
|
|
int dstBpp;
|
|
int dstXoff, dstYoff;
|
|
|
|
fbGetDrawable(pSrcDrawable, src, srcStride, srcBpp, srcXoff, srcYoff);
|
|
fbGetDrawable(pDstDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
|
|
|
|
while (nbox--) {
|
|
if (dstBpp == 1) {
|
|
fbBlt(src + (pbox->y1 + dy + srcYoff) * srcStride,
|
|
srcStride,
|
|
(pbox->x1 + dx + srcXoff) * srcBpp,
|
|
dst + (pbox->y1 + dstYoff) * dstStride,
|
|
dstStride,
|
|
(pbox->x1 + dstXoff) * dstBpp,
|
|
(pbox->x2 - pbox->x1) * dstBpp,
|
|
(pbox->y2 - pbox->y1),
|
|
FbOpaqueStipple1Rop(pGC->alu,
|
|
pGC->fgPixel, pGC->bgPixel),
|
|
pPriv->pm, dstBpp, reverse, upsidedown);
|
|
}
|
|
else {
|
|
fbBltOne((FbStip *) (src + (pbox->y1 + dy + srcYoff) * srcStride),
|
|
srcStride * (FB_UNIT / FB_STIP_UNIT),
|
|
(pbox->x1 + dx + srcXoff),
|
|
dst + (pbox->y1 + dstYoff) * dstStride,
|
|
dstStride,
|
|
(pbox->x1 + dstXoff) * dstBpp,
|
|
dstBpp,
|
|
(pbox->x2 - pbox->x1) * dstBpp,
|
|
(pbox->y2 - pbox->y1),
|
|
pPriv->and, pPriv->xor, pPriv->bgand, pPriv->bgxor);
|
|
}
|
|
pbox++;
|
|
}
|
|
|
|
fbFinishAccess(pDstDrawable);
|
|
fbFinishAccess(pSrcDrawable);
|
|
}
|
|
|
|
void
|
|
fbCopyNto1(DrawablePtr pSrcDrawable,
|
|
DrawablePtr pDstDrawable,
|
|
GCPtr pGC,
|
|
BoxPtr pbox,
|
|
int nbox,
|
|
int dx,
|
|
int dy, Bool reverse, Bool upsidedown, Pixel bitplane, void *closure)
|
|
{
|
|
FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
|
|
|
|
while (nbox--) {
|
|
if (pDstDrawable->bitsPerPixel == 1) {
|
|
FbBits *src;
|
|
FbStride srcStride;
|
|
int srcBpp;
|
|
int srcXoff, srcYoff;
|
|
|
|
FbStip *dst;
|
|
FbStride dstStride;
|
|
int dstBpp;
|
|
int dstXoff, dstYoff;
|
|
|
|
fbGetDrawable(pSrcDrawable, src, srcStride, srcBpp, srcXoff,
|
|
srcYoff);
|
|
fbGetStipDrawable(pDstDrawable, dst, dstStride, dstBpp, dstXoff,
|
|
dstYoff);
|
|
fbBltPlane(src + (pbox->y1 + dy + srcYoff) * srcStride, srcStride,
|
|
(pbox->x1 + dx + srcXoff) * srcBpp, srcBpp,
|
|
dst + (pbox->y1 + dstYoff) * dstStride, dstStride,
|
|
(pbox->x1 + dstXoff) * dstBpp,
|
|
(pbox->x2 - pbox->x1) * srcBpp, (pbox->y2 - pbox->y1),
|
|
(FbStip) pPriv->and, (FbStip) pPriv->xor,
|
|
(FbStip) pPriv->bgand, (FbStip) pPriv->bgxor, bitplane);
|
|
fbFinishAccess(pDstDrawable);
|
|
fbFinishAccess(pSrcDrawable);
|
|
}
|
|
else {
|
|
FbBits *src;
|
|
FbStride srcStride;
|
|
int srcBpp;
|
|
int srcXoff, srcYoff;
|
|
|
|
FbBits *dst;
|
|
FbStride dstStride;
|
|
int dstBpp;
|
|
int dstXoff, dstYoff;
|
|
|
|
FbStip *tmp;
|
|
FbStride tmpStride;
|
|
int width, height;
|
|
|
|
width = pbox->x2 - pbox->x1;
|
|
height = pbox->y2 - pbox->y1;
|
|
|
|
tmpStride = ((width + FB_STIP_MASK) >> FB_STIP_SHIFT);
|
|
tmp = xallocarray(tmpStride * height, sizeof(FbStip));
|
|
if (!tmp)
|
|
return;
|
|
|
|
fbGetDrawable(pSrcDrawable, src, srcStride, srcBpp, srcXoff,
|
|
srcYoff);
|
|
fbGetDrawable(pDstDrawable, dst, dstStride, dstBpp, dstXoff,
|
|
dstYoff);
|
|
|
|
fbBltPlane(src + (pbox->y1 + dy + srcYoff) * srcStride,
|
|
srcStride,
|
|
(pbox->x1 + dx + srcXoff) * srcBpp,
|
|
srcBpp,
|
|
tmp,
|
|
tmpStride,
|
|
0,
|
|
width * srcBpp,
|
|
height,
|
|
fbAndStip(GXcopy, FB_ALLONES, FB_ALLONES),
|
|
fbXorStip(GXcopy, FB_ALLONES, FB_ALLONES),
|
|
fbAndStip(GXcopy, 0, FB_ALLONES),
|
|
fbXorStip(GXcopy, 0, FB_ALLONES), bitplane);
|
|
fbBltOne(tmp,
|
|
tmpStride,
|
|
0,
|
|
dst + (pbox->y1 + dstYoff) * dstStride,
|
|
dstStride,
|
|
(pbox->x1 + dstXoff) * dstBpp,
|
|
dstBpp,
|
|
width * dstBpp,
|
|
height,
|
|
pPriv->and, pPriv->xor, pPriv->bgand, pPriv->bgxor);
|
|
free(tmp);
|
|
|
|
fbFinishAccess(pDstDrawable);
|
|
fbFinishAccess(pSrcDrawable);
|
|
}
|
|
pbox++;
|
|
}
|
|
}
|
|
|
|
RegionPtr
|
|
fbCopyArea(DrawablePtr pSrcDrawable,
|
|
DrawablePtr pDstDrawable,
|
|
GCPtr pGC,
|
|
int xIn, int yIn, int widthSrc, int heightSrc, int xOut, int yOut)
|
|
{
|
|
return miDoCopy(pSrcDrawable, pDstDrawable, pGC, xIn, yIn,
|
|
widthSrc, heightSrc, xOut, yOut, fbCopyNtoN, 0, 0);
|
|
}
|
|
|
|
RegionPtr
|
|
fbCopyPlane(DrawablePtr pSrcDrawable,
|
|
DrawablePtr pDstDrawable,
|
|
GCPtr pGC,
|
|
int xIn,
|
|
int yIn,
|
|
int widthSrc,
|
|
int heightSrc, int xOut, int yOut, unsigned long bitplane)
|
|
{
|
|
if (pSrcDrawable->bitsPerPixel > 1)
|
|
return miDoCopy(pSrcDrawable, pDstDrawable, pGC,
|
|
xIn, yIn, widthSrc, heightSrc,
|
|
xOut, yOut, fbCopyNto1, (Pixel) bitplane, 0);
|
|
else if (bitplane & 1)
|
|
return miDoCopy(pSrcDrawable, pDstDrawable, pGC, xIn, yIn,
|
|
widthSrc, heightSrc, xOut, yOut, fbCopy1toN,
|
|
(Pixel) bitplane, 0);
|
|
else
|
|
return miHandleExposures(pSrcDrawable, pDstDrawable, pGC,
|
|
xIn, yIn,
|
|
widthSrc, heightSrc, xOut, yOut);
|
|
}
|