This was an attempt to avoid scratch gc creation and validation for paintwin because that was expensive. This is not the case in current servers, and the danger of failure to implement it correctly (as seen in all previous implementations) is high enough to justify removing it. No performance difference detected with x11perf -create -move -resize -circulate on Xvfb. Leave the screen hooks for PaintWindow* in for now to avoid ABI change.
1464 lines
33 KiB
C
1464 lines
33 KiB
C
/*
|
|
* Copyright © 2000 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_CONFIG_H
|
|
#include <kdrive-config.h>
|
|
#endif
|
|
#include "igs.h"
|
|
#include "igsdraw.h"
|
|
|
|
#include "Xmd.h"
|
|
#include "gcstruct.h"
|
|
#include "scrnintstr.h"
|
|
#include "pixmapstr.h"
|
|
#include "regionstr.h"
|
|
#include "mistruct.h"
|
|
#include "fontstruct.h"
|
|
#include "dixfontstr.h"
|
|
#include "fb.h"
|
|
#include "migc.h"
|
|
#include "miline.h"
|
|
|
|
CARD8 igsPatRop[16] = {
|
|
/* GXclear */ 0x00, /* 0 */
|
|
/* GXand */ 0xa0, /* src AND dst */
|
|
/* GXandReverse */ 0x50, /* src AND NOT dst */
|
|
/* GXcopy */ 0xf0, /* src */
|
|
/* GXandInverted*/ 0x0a, /* NOT src AND dst */
|
|
/* GXnoop */ 0xaa, /* dst */
|
|
/* GXxor */ 0x5a, /* src XOR dst */
|
|
/* GXor */ 0xfa, /* src OR dst */
|
|
/* GXnor */ 0x05, /* NOT src AND NOT dst */
|
|
/* GXequiv */ 0xa5, /* NOT src XOR dst */
|
|
/* GXinvert */ 0x55, /* NOT dst */
|
|
/* GXorReverse */ 0xf5, /* src OR NOT dst */
|
|
/* GXcopyInverted*/ 0x0f, /* NOT src */
|
|
/* GXorInverted */ 0xaf, /* NOT src OR dst */
|
|
/* GXnand */ 0x5f, /* NOT src OR NOT dst */
|
|
/* GXset */ 0xff, /* 1 */
|
|
};
|
|
|
|
/*
|
|
* Handle pixel transfers
|
|
*/
|
|
|
|
#define BURST
|
|
#ifdef BURST
|
|
#define PixTransDeclare VOL32 *pix_trans_base = igsc->copData,\
|
|
*pix_trans = pix_trans_base
|
|
#define PixTransStart(n) if (pix_trans + (n) > pix_trans_base + 16384) pix_trans = pix_trans_base
|
|
#define PixTransStore(t) *pix_trans++ = (t)
|
|
#else
|
|
#define PixTransDeclare VOL32 *pix_trans = igsc->copData
|
|
#define PixTransStart(n)
|
|
#define PixTransStore(t) *pix_trans = (t)
|
|
#endif
|
|
|
|
static IgsPattern *
|
|
igsSetPattern (ScreenPtr pScreen,
|
|
PixmapPtr pPixmap,
|
|
CARD8 fillStyle,
|
|
INT32 xrot,
|
|
INT32 yrot)
|
|
{
|
|
KdScreenPriv(pScreen);
|
|
igsCardInfo(pScreenPriv);
|
|
igsScreenInfo(pScreenPriv);
|
|
int i;
|
|
IgsPatternCache *c;
|
|
IgsPattern *p;
|
|
|
|
if (fillStyle == FillTiled)
|
|
c = &igss->tile;
|
|
else
|
|
c = &igss->stipple;
|
|
for (i = 0; i < IGS_NUM_PATTERN; i++)
|
|
{
|
|
p = &c->pattern[i];
|
|
if (p->serial_number == pPixmap->drawable.serialNumber &&
|
|
p->xrot == xrot &&
|
|
p->yrot == yrot)
|
|
{
|
|
return p;
|
|
}
|
|
}
|
|
p = &c->pattern[c->next];
|
|
if (++c->next == IGS_NUM_PATTERN)
|
|
c->next = 0;
|
|
p->serial_number = pPixmap->drawable.serialNumber;
|
|
p->xrot = xrot;
|
|
p->yrot = yrot;
|
|
|
|
if (fillStyle != FillTiled)
|
|
{
|
|
FbStip *pix;
|
|
FbStride pixStride;
|
|
int pixBpp;
|
|
int pixXoff, pixYoff;
|
|
CARD8 tmp[8];
|
|
CARD32 *pat;
|
|
int stipX, stipY;
|
|
int y;
|
|
FbStip bits;
|
|
|
|
fbGetStipDrawable (&pPixmap->drawable, pix, pixStride, pixBpp, pixXoff, pixYoff);
|
|
|
|
modulus (-yrot - pixYoff, pPixmap->drawable.height, stipY);
|
|
modulus (-xrot - pixXoff, FB_UNIT, stipX);
|
|
|
|
pat = (CARD32 *) p->base;
|
|
|
|
for (y = 0; y < 8; y++)
|
|
{
|
|
bits = pix[stipY * pixStride];
|
|
FbRotLeft (bits, stipX);
|
|
tmp[y] = (CARD8) bits;
|
|
stipY++;
|
|
if (stipY == pPixmap->drawable.height)
|
|
stipY = 0;
|
|
}
|
|
for (i = 0; i < 2; i++)
|
|
{
|
|
bits = (tmp[i*4+0] |
|
|
(tmp[i*4+1] << 8) |
|
|
(tmp[i*4+2] << 16) |
|
|
(tmp[i*4+3] << 24));
|
|
IgsAdjustBits32 (bits);
|
|
*pat++ = bits;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
FbBits *pix;
|
|
FbStride pixStride;
|
|
int pixBpp;
|
|
FbBits *pat;
|
|
FbStride patStride;
|
|
int patBpp;
|
|
int patXoff, patYoff;
|
|
|
|
fbGetDrawable (&pPixmap->drawable, pix, pixStride, pixBpp, patXoff, patYoff);
|
|
|
|
pat = (FbBits *) p->base;
|
|
patBpp = pixBpp;
|
|
patStride = (patBpp * IGS_PATTERN_WIDTH) / (8 * sizeof (FbBits));
|
|
|
|
fbTile (pat, patStride, 0,
|
|
patBpp * IGS_PATTERN_WIDTH, IGS_PATTERN_HEIGHT,
|
|
|
|
pix, pixStride,
|
|
pPixmap->drawable.width * pixBpp,
|
|
pPixmap->drawable.height,
|
|
GXcopy, FB_ALLONES, pixBpp,
|
|
(xrot - patXoff) * pixBpp, yrot - patYoff);
|
|
}
|
|
return p;
|
|
}
|
|
|
|
void
|
|
igsFillBoxSolid (DrawablePtr pDrawable, int nBox, BoxPtr pBox,
|
|
unsigned long pixel, int alu, unsigned long planemask)
|
|
{
|
|
SetupIgs(pDrawable->pScreen);
|
|
CARD32 cmd;
|
|
|
|
_igsSetSolidRect(cop,alu,planemask,pixel,cmd);
|
|
while (nBox--)
|
|
{
|
|
_igsRect(cop,pBox->x1,pBox->y1,pBox->x2-pBox->x1,pBox->y2-pBox->y1,cmd);
|
|
pBox++;
|
|
}
|
|
KdMarkSync (pDrawable->pScreen);
|
|
}
|
|
|
|
void
|
|
igsFillBoxTiled (DrawablePtr pDrawable, int nBox, BoxPtr pBox,
|
|
PixmapPtr pPixmap, int xrot, int yrot, int alu)
|
|
{
|
|
SetupIgs(pDrawable->pScreen);
|
|
CARD32 cmd;
|
|
IgsPattern *p = igsSetPattern (pDrawable->pScreen,
|
|
pPixmap,
|
|
FillTiled,
|
|
xrot, yrot);
|
|
|
|
_igsSetTiledRect(cop,alu,planemask,p->offset,cmd);
|
|
while (nBox--)
|
|
{
|
|
_igsPatRect(cop,pBox->x1,pBox->y1,pBox->x2-pBox->x1,pBox->y2-pBox->y1,cmd);
|
|
pBox++;
|
|
}
|
|
KdMarkSync (pDrawable->pScreen);
|
|
}
|
|
|
|
void
|
|
igsFillBoxStippled (DrawablePtr pDrawable, GCPtr pGC,
|
|
int nBox, BoxPtr pBox)
|
|
{
|
|
SetupIgs(pDrawable->pScreen);
|
|
CARD32 cmd;
|
|
int xrot = pGC->patOrg.x + pDrawable->x;
|
|
int yrot = pGC->patOrg.y + pDrawable->y;
|
|
IgsPattern *p = igsSetPattern (pDrawable->pScreen,
|
|
pGC->stipple,
|
|
pGC->fillStyle,
|
|
xrot, yrot);
|
|
if (pGC->fillStyle == FillStippled)
|
|
{
|
|
_igsSetStippledRect (cop,pGC->alu,planemask,pGC->fgPixel,p->offset,cmd);
|
|
}
|
|
else
|
|
{
|
|
_igsSetOpaqueStippledRect (cop,pGC->alu,planemask,
|
|
pGC->fgPixel,pGC->bgPixel,p->offset,cmd);
|
|
}
|
|
while (nBox--)
|
|
{
|
|
_igsPatRect(cop,pBox->x1,pBox->y1,pBox->x2-pBox->x1,pBox->y2-pBox->y1,cmd);
|
|
pBox++;
|
|
}
|
|
KdMarkSync (pDrawable->pScreen);
|
|
}
|
|
|
|
|
|
void
|
|
igsStipple (ScreenPtr pScreen,
|
|
CARD32 cmd,
|
|
FbStip *psrcBase,
|
|
FbStride widthSrc,
|
|
int srcx,
|
|
int srcy,
|
|
int dstx,
|
|
int dsty,
|
|
int width,
|
|
int height)
|
|
{
|
|
SetupIgs(pScreen);
|
|
FbStip *psrcLine, *psrc;
|
|
FbStride widthRest;
|
|
FbStip bits, tmp, lastTmp;
|
|
int leftShift, rightShift;
|
|
int nl, nlMiddle;
|
|
int r;
|
|
PixTransDeclare;
|
|
|
|
/* Compute blt address and parameters */
|
|
psrc = psrcBase + srcy * widthSrc + (srcx >> 5);
|
|
nlMiddle = (width + 31) >> 5;
|
|
leftShift = srcx & 0x1f;
|
|
rightShift = 32 - leftShift;
|
|
widthRest = widthSrc - nlMiddle;
|
|
|
|
_igsPlaneBlt(cop,dstx,dsty,width,height,cmd);
|
|
|
|
if (leftShift == 0)
|
|
{
|
|
while (height--)
|
|
{
|
|
nl = nlMiddle;
|
|
PixTransStart(nl);
|
|
while (nl--)
|
|
{
|
|
tmp = *psrc++;
|
|
IgsAdjustBits32 (tmp);
|
|
PixTransStore (tmp);
|
|
}
|
|
psrc += widthRest;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
widthRest--;
|
|
while (height--)
|
|
{
|
|
bits = *psrc++;
|
|
nl = nlMiddle;
|
|
PixTransStart(nl);
|
|
while (nl--)
|
|
{
|
|
tmp = FbStipLeft(bits, leftShift);
|
|
bits = *psrc++;
|
|
tmp |= FbStipRight(bits, rightShift);
|
|
IgsAdjustBits32(tmp);
|
|
PixTransStore (tmp);
|
|
}
|
|
psrc += widthRest;
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
igsCopyNtoN (DrawablePtr pSrcDrawable,
|
|
DrawablePtr pDstDrawable,
|
|
GCPtr pGC,
|
|
BoxPtr pbox,
|
|
int nbox,
|
|
int dx,
|
|
int dy,
|
|
Bool reverse,
|
|
Bool upsidedown,
|
|
Pixel bitplane,
|
|
void *closure)
|
|
{
|
|
SetupIgs(pDstDrawable->pScreen);
|
|
int srcX, srcY, dstX, dstY;
|
|
int w, h;
|
|
CARD32 flags;
|
|
CARD32 cmd;
|
|
CARD8 alu;
|
|
|
|
if (pGC)
|
|
{
|
|
alu = pGC->alu;
|
|
if (sourceInvarient (pGC->alu))
|
|
{
|
|
igsFillBoxSolid (pDstDrawable, nbox, pbox, 0, pGC->alu, pGC->planemask);
|
|
return;
|
|
}
|
|
}
|
|
else
|
|
alu = GXcopy;
|
|
|
|
_igsSetBlt(cop,alu,pGC->planemask,reverse,upsidedown,cmd);
|
|
while (nbox--)
|
|
{
|
|
w = pbox->x2 - pbox->x1;
|
|
h = pbox->y2 - pbox->y1;
|
|
if (reverse)
|
|
dstX = pbox->x2 - 1;
|
|
else
|
|
dstX = pbox->x1;
|
|
srcX = dstX + dx;
|
|
|
|
if (upsidedown)
|
|
dstY = pbox->y2 - 1;
|
|
else
|
|
dstY = pbox->y1;
|
|
|
|
srcY = dstY + dy;
|
|
|
|
_igsBlt (cop, srcX, srcY, dstX, dstY, w, h, cmd);
|
|
pbox++;
|
|
}
|
|
KdMarkSync (pDstDrawable->pScreen);
|
|
}
|
|
|
|
RegionPtr
|
|
igsCopyArea(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC,
|
|
int srcx, int srcy, int width, int height, int dstx, int dsty)
|
|
{
|
|
KdScreenPriv(pDstDrawable->pScreen);
|
|
FbBits depthMask;
|
|
|
|
depthMask = FbFullMask (pDstDrawable->depth);
|
|
if ((pGC->planemask & depthMask) == depthMask &&
|
|
pSrcDrawable->type == DRAWABLE_WINDOW &&
|
|
pDstDrawable->type == DRAWABLE_WINDOW)
|
|
{
|
|
return fbDoCopy (pSrcDrawable, pDstDrawable, pGC,
|
|
srcx, srcy, width, height,
|
|
dstx, dsty, igsCopyNtoN, 0, 0);
|
|
}
|
|
return KdCheckCopyArea (pSrcDrawable, pDstDrawable, pGC,
|
|
srcx, srcy, width, height, dstx, dsty);
|
|
}
|
|
|
|
typedef struct _igs1toNargs {
|
|
unsigned long copyPlaneFG, copyPlaneBG;
|
|
Bool opaque;
|
|
} igs1toNargs;
|
|
|
|
void
|
|
igsCopy1toN (DrawablePtr pSrcDrawable,
|
|
DrawablePtr pDstDrawable,
|
|
GCPtr pGC,
|
|
BoxPtr pbox,
|
|
int nbox,
|
|
int dx,
|
|
int dy,
|
|
Bool reverse,
|
|
Bool upsidedown,
|
|
Pixel bitplane,
|
|
void *closure)
|
|
{
|
|
SetupIgs(pDstDrawable->pScreen);
|
|
|
|
igs1toNargs *args = closure;
|
|
int dstx, dsty;
|
|
FbStip *psrcBase;
|
|
FbStride widthSrc;
|
|
int srcBpp;
|
|
int srcXoff, srcYoff;
|
|
CARD32 cmd;
|
|
|
|
if (args->opaque && sourceInvarient (pGC->alu))
|
|
{
|
|
igsFillBoxSolid (pDstDrawable, nbox, pbox,
|
|
pGC->bgPixel, pGC->alu, pGC->planemask);
|
|
return;
|
|
}
|
|
|
|
fbGetStipDrawable (pSrcDrawable, psrcBase, widthSrc, srcBpp, srcXoff, srcYoff);
|
|
|
|
if (args->opaque)
|
|
{
|
|
_igsSetOpaquePlaneBlt (cop, pGC->alu, pGC->planemask, args->copyPlaneFG,
|
|
args->copyPlaneBG, cmd);
|
|
}
|
|
else
|
|
{
|
|
_igsSetTransparentPlaneBlt (cop, pGC->alu, pGC->planemask,
|
|
args->copyPlaneFG, cmd);
|
|
}
|
|
|
|
while (nbox--)
|
|
{
|
|
dstx = pbox->x1;
|
|
dsty = pbox->y1;
|
|
|
|
igsStipple (pDstDrawable->pScreen, cmd,
|
|
psrcBase, widthSrc,
|
|
dstx + dx - srcXoff, dsty + dy - srcYoff,
|
|
dstx, dsty,
|
|
pbox->x2 - dstx, pbox->y2 - dsty);
|
|
pbox++;
|
|
}
|
|
KdMarkSync (pDstDrawable->pScreen);
|
|
}
|
|
|
|
RegionPtr
|
|
igsCopyPlane (DrawablePtr pSrcDrawable,
|
|
DrawablePtr pDstDrawable,
|
|
GCPtr pGC,
|
|
int srcx,
|
|
int srcy,
|
|
int width,
|
|
int height,
|
|
int dstx,
|
|
int dsty,
|
|
unsigned long bitPlane)
|
|
{
|
|
RegionPtr ret;
|
|
igs1toNargs args;
|
|
FbBits depthMask;
|
|
|
|
depthMask = FbFullMask (pDstDrawable->depth);
|
|
if ((pGC->planemask & depthMask) == depthMask &&
|
|
pDstDrawable->type == DRAWABLE_WINDOW &&
|
|
pSrcDrawable->depth == 1)
|
|
{
|
|
args.copyPlaneFG = pGC->fgPixel;
|
|
args.copyPlaneBG = pGC->bgPixel;
|
|
args.opaque = TRUE;
|
|
return fbDoCopy (pSrcDrawable, pDstDrawable, pGC,
|
|
srcx, srcy, width, height,
|
|
dstx, dsty, igsCopy1toN, bitPlane, &args);
|
|
}
|
|
return KdCheckCopyPlane(pSrcDrawable, pDstDrawable, pGC,
|
|
srcx, srcy, width, height,
|
|
dstx, dsty, bitPlane);
|
|
}
|
|
|
|
#if 0
|
|
/* would you believe this is slower than fb? */
|
|
void
|
|
igsPushPixels (GCPtr pGC,
|
|
PixmapPtr pBitmap,
|
|
DrawablePtr pDrawable,
|
|
int w,
|
|
int h,
|
|
int x,
|
|
int y)
|
|
{
|
|
igs1toNargs args;
|
|
FbBits depthMask;
|
|
|
|
depthMask = FbFullMask (pDstDrawable->depth);
|
|
if ((pGC->planemask & depthMask) == depthMask &&
|
|
pDrawable->type == DRAWABLE_WINDOW &&
|
|
pGC->fillStyle == FillSolid)
|
|
{
|
|
args.opaque = FALSE;
|
|
args.copyPlaneFG = pGC->fgPixel;
|
|
(void) fbDoCopy ((DrawablePtr) pBitmap, pDrawable, pGC,
|
|
0, 0, w, h, x, y, igsCopy1toN, 1, &args);
|
|
}
|
|
else
|
|
{
|
|
KdCheckPushPixels (pGC, pBitmap, pDrawable, w, h, x, y);
|
|
}
|
|
}
|
|
#else
|
|
#define igsPushPixels KdCheckPushPixels
|
|
#endif
|
|
|
|
BOOL
|
|
igsFillOk (GCPtr pGC)
|
|
{
|
|
FbBits depthMask;
|
|
|
|
depthMask = FbFullMask(pGC->depth);
|
|
if ((pGC->planemask & depthMask) != depthMask)
|
|
return FALSE;
|
|
switch (pGC->fillStyle) {
|
|
case FillSolid:
|
|
return TRUE;
|
|
case FillTiled:
|
|
return (igsPatternDimOk (pGC->tile.pixmap->drawable.width) &&
|
|
igsPatternDimOk (pGC->tile.pixmap->drawable.height));
|
|
case FillStippled:
|
|
case FillOpaqueStippled:
|
|
return (igsPatternDimOk (pGC->stipple->drawable.width) &&
|
|
igsPatternDimOk (pGC->stipple->drawable.height));
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
void
|
|
igsFillSpans (DrawablePtr pDrawable, GCPtr pGC, int n,
|
|
DDXPointPtr ppt, int *pwidth, int fSorted)
|
|
{
|
|
SetupIgs(pDrawable->pScreen);
|
|
DDXPointPtr pptFree;
|
|
FbGCPrivPtr fbPriv = fbGetGCPrivate(pGC);
|
|
int *pwidthFree;/* copies of the pointers to free */
|
|
CARD32 cmd;
|
|
int nTmp;
|
|
INT16 x, y;
|
|
int width;
|
|
IgsPattern *p;
|
|
|
|
if (!igsFillOk (pGC))
|
|
{
|
|
KdCheckFillSpans (pDrawable, pGC, n, ppt, pwidth, fSorted);
|
|
return;
|
|
}
|
|
nTmp = n * miFindMaxBand(fbGetCompositeClip(pGC));
|
|
pwidthFree = (int *)ALLOCATE_LOCAL(nTmp * sizeof(int));
|
|
pptFree = (DDXPointRec *)ALLOCATE_LOCAL(nTmp * sizeof(DDXPointRec));
|
|
if(!pptFree || !pwidthFree)
|
|
{
|
|
if (pptFree) DEALLOCATE_LOCAL(pptFree);
|
|
if (pwidthFree) DEALLOCATE_LOCAL(pwidthFree);
|
|
return;
|
|
}
|
|
n = miClipSpans(fbGetCompositeClip(pGC),
|
|
ppt, pwidth, n,
|
|
pptFree, pwidthFree, fSorted);
|
|
pwidth = pwidthFree;
|
|
ppt = pptFree;
|
|
switch (pGC->fillStyle) {
|
|
case FillSolid:
|
|
_igsSetSolidRect(cop,pGC->alu,pGC->planemask,pGC->fgPixel,cmd);
|
|
break;
|
|
case FillTiled:
|
|
p = igsSetPattern (pDrawable->pScreen,
|
|
pGC->tile.pixmap,
|
|
FillTiled,
|
|
pGC->patOrg.x + pDrawable->x,
|
|
pGC->patOrg.y + pDrawable->y);
|
|
_igsSetTiledRect (cop,pGC->alu,pGC->planemask,p->offset,cmd);
|
|
break;
|
|
default:
|
|
p = igsSetPattern (pDrawable->pScreen,
|
|
pGC->stipple,
|
|
pGC->fillStyle,
|
|
pGC->patOrg.x + pDrawable->x,
|
|
pGC->patOrg.y + pDrawable->y);
|
|
if (pGC->fillStyle == FillStippled)
|
|
{
|
|
_igsSetStippledRect (cop,pGC->alu,pGC->planemask,
|
|
pGC->fgPixel,p->offset,cmd);
|
|
}
|
|
else
|
|
{
|
|
_igsSetOpaqueStippledRect (cop,pGC->alu,pGC->planemask,
|
|
pGC->fgPixel,pGC->bgPixel,p->offset,cmd);
|
|
}
|
|
break;
|
|
}
|
|
while (n--)
|
|
{
|
|
x = ppt->x;
|
|
y = ppt->y;
|
|
ppt++;
|
|
width = *pwidth++;
|
|
if (width)
|
|
{
|
|
_igsPatRect(cop,x,y,width,1,cmd);
|
|
}
|
|
}
|
|
DEALLOCATE_LOCAL(pptFree);
|
|
DEALLOCATE_LOCAL(pwidthFree);
|
|
KdMarkSync (pDrawable->pScreen);
|
|
}
|
|
|
|
#define NUM_STACK_RECTS 1024
|
|
|
|
void
|
|
igsPolyFillRect (DrawablePtr pDrawable, GCPtr pGC,
|
|
int nrectFill, xRectangle *prectInit)
|
|
{
|
|
SetupIgs(pDrawable->pScreen);
|
|
xRectangle *prect;
|
|
RegionPtr prgnClip;
|
|
register BoxPtr pbox;
|
|
register BoxPtr pboxClipped;
|
|
BoxPtr pboxClippedBase;
|
|
BoxPtr pextent;
|
|
BoxRec stackRects[NUM_STACK_RECTS];
|
|
FbGCPrivPtr fbPriv = fbGetGCPrivate (pGC);
|
|
int numRects;
|
|
int n;
|
|
int xorg, yorg;
|
|
int x, y;
|
|
|
|
if (!igsFillOk (pGC))
|
|
{
|
|
KdCheckPolyFillRect (pDrawable, pGC, nrectFill, prectInit);
|
|
return;
|
|
}
|
|
prgnClip = fbGetCompositeClip (pGC);
|
|
xorg = pDrawable->x;
|
|
yorg = pDrawable->y;
|
|
|
|
if (xorg || yorg)
|
|
{
|
|
prect = prectInit;
|
|
n = nrectFill;
|
|
while(n--)
|
|
{
|
|
prect->x += xorg;
|
|
prect->y += yorg;
|
|
prect++;
|
|
}
|
|
}
|
|
|
|
prect = prectInit;
|
|
|
|
numRects = REGION_NUM_RECTS(prgnClip) * nrectFill;
|
|
if (numRects > NUM_STACK_RECTS)
|
|
{
|
|
pboxClippedBase = (BoxPtr)xalloc(numRects * sizeof(BoxRec));
|
|
if (!pboxClippedBase)
|
|
return;
|
|
}
|
|
else
|
|
pboxClippedBase = stackRects;
|
|
|
|
pboxClipped = pboxClippedBase;
|
|
|
|
if (REGION_NUM_RECTS(prgnClip) == 1)
|
|
{
|
|
int x1, y1, x2, y2, bx2, by2;
|
|
|
|
pextent = REGION_RECTS(prgnClip);
|
|
x1 = pextent->x1;
|
|
y1 = pextent->y1;
|
|
x2 = pextent->x2;
|
|
y2 = pextent->y2;
|
|
while (nrectFill--)
|
|
{
|
|
if ((pboxClipped->x1 = prect->x) < x1)
|
|
pboxClipped->x1 = x1;
|
|
|
|
if ((pboxClipped->y1 = prect->y) < y1)
|
|
pboxClipped->y1 = y1;
|
|
|
|
bx2 = (int) prect->x + (int) prect->width;
|
|
if (bx2 > x2)
|
|
bx2 = x2;
|
|
pboxClipped->x2 = bx2;
|
|
|
|
by2 = (int) prect->y + (int) prect->height;
|
|
if (by2 > y2)
|
|
by2 = y2;
|
|
pboxClipped->y2 = by2;
|
|
|
|
prect++;
|
|
if ((pboxClipped->x1 < pboxClipped->x2) &&
|
|
(pboxClipped->y1 < pboxClipped->y2))
|
|
{
|
|
pboxClipped++;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
int x1, y1, x2, y2, bx2, by2;
|
|
|
|
pextent = REGION_EXTENTS(pGC->pScreen, prgnClip);
|
|
x1 = pextent->x1;
|
|
y1 = pextent->y1;
|
|
x2 = pextent->x2;
|
|
y2 = pextent->y2;
|
|
while (nrectFill--)
|
|
{
|
|
BoxRec box;
|
|
|
|
if ((box.x1 = prect->x) < x1)
|
|
box.x1 = x1;
|
|
|
|
if ((box.y1 = prect->y) < y1)
|
|
box.y1 = y1;
|
|
|
|
bx2 = (int) prect->x + (int) prect->width;
|
|
if (bx2 > x2)
|
|
bx2 = x2;
|
|
box.x2 = bx2;
|
|
|
|
by2 = (int) prect->y + (int) prect->height;
|
|
if (by2 > y2)
|
|
by2 = y2;
|
|
box.y2 = by2;
|
|
|
|
prect++;
|
|
|
|
if ((box.x1 >= box.x2) || (box.y1 >= box.y2))
|
|
continue;
|
|
|
|
n = REGION_NUM_RECTS (prgnClip);
|
|
pbox = REGION_RECTS(prgnClip);
|
|
|
|
/* clip the rectangle to each box in the clip region
|
|
this is logically equivalent to calling Intersect()
|
|
*/
|
|
while(n--)
|
|
{
|
|
pboxClipped->x1 = max(box.x1, pbox->x1);
|
|
pboxClipped->y1 = max(box.y1, pbox->y1);
|
|
pboxClipped->x2 = min(box.x2, pbox->x2);
|
|
pboxClipped->y2 = min(box.y2, pbox->y2);
|
|
pbox++;
|
|
|
|
/* see if clipping left anything */
|
|
if(pboxClipped->x1 < pboxClipped->x2 &&
|
|
pboxClipped->y1 < pboxClipped->y2)
|
|
{
|
|
pboxClipped++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (pboxClipped != pboxClippedBase)
|
|
{
|
|
switch (pGC->fillStyle) {
|
|
case FillSolid:
|
|
igsFillBoxSolid(pDrawable,
|
|
pboxClipped-pboxClippedBase, pboxClippedBase,
|
|
pGC->fgPixel, pGC->alu, pGC->planemask);
|
|
break;
|
|
case FillTiled:
|
|
igsFillBoxTiled(pDrawable,
|
|
pboxClipped-pboxClippedBase, pboxClippedBase,
|
|
pGC->tile.pixmap,
|
|
pGC->patOrg.x + pDrawable->x,
|
|
pGC->patOrg.y + pDrawable->y,
|
|
pGC->alu);
|
|
break;
|
|
case FillStippled:
|
|
case FillOpaqueStippled:
|
|
igsFillBoxStippled (pDrawable, pGC,
|
|
pboxClipped-pboxClippedBase, pboxClippedBase);
|
|
break;
|
|
}
|
|
}
|
|
if (pboxClippedBase != stackRects)
|
|
xfree(pboxClippedBase);
|
|
}
|
|
|
|
int
|
|
igsTextInRegion (GCPtr pGC,
|
|
int x,
|
|
int y,
|
|
unsigned int nglyph,
|
|
CharInfoPtr *ppci)
|
|
{
|
|
int w;
|
|
FontPtr pfont = pGC->font;
|
|
BoxRec bbox;
|
|
|
|
if (FONTCONSTMETRICS(pfont))
|
|
w = FONTMAXBOUNDS(pfont,characterWidth) * nglyph;
|
|
else
|
|
{
|
|
w = 0;
|
|
while (nglyph--)
|
|
w += (*ppci++)->metrics.characterWidth;
|
|
}
|
|
if (w < 0)
|
|
{
|
|
bbox.x1 = x + w;
|
|
bbox.x2 = x;
|
|
}
|
|
else
|
|
{
|
|
bbox.x1 = x;
|
|
bbox.x2 = x + w;
|
|
}
|
|
w = FONTMINBOUNDS(pfont,leftSideBearing);
|
|
if (w < 0)
|
|
bbox.x1 += w;
|
|
w = FONTMAXBOUNDS(pfont, rightSideBearing) - FONTMINBOUNDS(pfont, characterWidth);
|
|
if (w > 0)
|
|
bbox.x2 += w;
|
|
bbox.y1 = y - FONTMAXBOUNDS(pfont,ascent);
|
|
bbox.y2 = y + FONTMAXBOUNDS(pfont,descent);
|
|
|
|
return RECT_IN_REGION(pGC->pScreen, fbGetCompositeClip(pGC), &bbox);
|
|
}
|
|
|
|
void
|
|
igsGlyphBltClipped (DrawablePtr pDrawable,
|
|
GCPtr pGC,
|
|
int x,
|
|
int y,
|
|
unsigned int nglyph,
|
|
CharInfoPtr *ppciInit,
|
|
Bool image)
|
|
{
|
|
SetupIgs(pDrawable->pScreen);
|
|
CARD32 cmd;
|
|
int h;
|
|
int w;
|
|
int xBack, yBack;
|
|
int hBack, wBack;
|
|
int lw;
|
|
FontPtr pfont = pGC->font;
|
|
CharInfoPtr pci;
|
|
unsigned long *bits;
|
|
BoxPtr extents;
|
|
BoxRec bbox;
|
|
CARD32 b;
|
|
CharInfoPtr *ppci;
|
|
FbGCPrivPtr fbPriv = fbGetGCPrivate(pGC);
|
|
RegionPtr pClip = fbGetCompositeClip(pGC);
|
|
BoxPtr pBox;
|
|
int nbox;
|
|
int x1, y1, x2, y2;
|
|
unsigned char alu;
|
|
Bool set;
|
|
PixTransDeclare;
|
|
|
|
if (image)
|
|
{
|
|
xBack = x;
|
|
yBack = y - FONTASCENT(pGC->font);
|
|
wBack = 0;
|
|
hBack = FONTASCENT(pGC->font) + FONTDESCENT(pGC->font);
|
|
if (hBack)
|
|
{
|
|
h = nglyph;
|
|
ppci = ppciInit;
|
|
while (h--)
|
|
wBack += (*ppci++)->metrics.characterWidth;
|
|
}
|
|
if (wBack < 0)
|
|
{
|
|
xBack = xBack + wBack;
|
|
wBack = -wBack;
|
|
}
|
|
if (hBack < 0)
|
|
{
|
|
yBack = yBack + hBack;
|
|
hBack = -hBack;
|
|
}
|
|
alu = GXcopy;
|
|
if (wBack)
|
|
{
|
|
_igsSetSolidRect (cop, GXcopy, pGC->planemask, pGC->bgPixel, cmd);
|
|
for (nbox = REGION_NUM_RECTS (pClip),
|
|
pBox = REGION_RECTS (pClip);
|
|
nbox--;
|
|
pBox++)
|
|
{
|
|
x1 = xBack;
|
|
x2 = xBack + wBack;
|
|
y1 = yBack;
|
|
y2 = yBack + hBack;
|
|
if (x1 < pBox->x1) x1 = pBox->x1;
|
|
if (x2 > pBox->x2) x2 = pBox->x2;
|
|
if (y1 < pBox->y1) y1 = pBox->y1;
|
|
if (y2 > pBox->y2) y2 = pBox->y2;
|
|
if (x1 < x2 && y1 < y2)
|
|
{
|
|
_igsRect (cop, x1, y1, x2 - x1, y2 - y1, cmd);
|
|
}
|
|
}
|
|
KdMarkSync (pDrawable->pScreen);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
wBack = 0;
|
|
alu = pGC->alu;
|
|
}
|
|
|
|
ppci = ppciInit;
|
|
set = FALSE;
|
|
while (nglyph--)
|
|
{
|
|
pci = *ppci++;
|
|
h = pci->metrics.ascent + pci->metrics.descent;
|
|
w = pci->metrics.rightSideBearing - pci->metrics.leftSideBearing;
|
|
x1 = x + pci->metrics.leftSideBearing;
|
|
y1 = y - pci->metrics.ascent;
|
|
bbox.x1 = x1;
|
|
bbox.y1 = y1;
|
|
bbox.x2 = x1 + w;
|
|
bbox.y2 = y1 + h;
|
|
switch (RECT_IN_REGION(pGC->pScreen, pClip, &bbox))
|
|
{
|
|
case rgnIN:
|
|
lw = h * ((w + 31) >> 5);
|
|
if (lw)
|
|
{
|
|
if (!set)
|
|
{
|
|
_igsSetTransparentPlaneBlt (cop, alu, pGC->planemask, pGC->fgPixel, cmd);
|
|
set = TRUE;
|
|
}
|
|
_igsPlaneBlt(cop,
|
|
x + pci->metrics.leftSideBearing,
|
|
y - pci->metrics.ascent,
|
|
w, h, cmd);
|
|
bits = (unsigned long *) pci->bits;
|
|
PixTransStart (lw);
|
|
while (lw--)
|
|
{
|
|
b = *bits++;
|
|
IgsAdjustBits32 (b);
|
|
PixTransStore(b);
|
|
}
|
|
KdMarkSync (pDrawable->pScreen);
|
|
}
|
|
break;
|
|
case rgnPART:
|
|
set = FALSE;
|
|
KdCheckSync (pDrawable->pScreen);
|
|
fbPutXYImage (pDrawable,
|
|
pClip,
|
|
fbPriv->fg,
|
|
fbPriv->bg,
|
|
fbPriv->pm,
|
|
alu,
|
|
FALSE,
|
|
x1, y1,
|
|
w, h,
|
|
(FbStip *) pci->bits,
|
|
(w + 31) >> 5,
|
|
0);
|
|
break;
|
|
case rgnOUT:
|
|
break;
|
|
}
|
|
x += pci->metrics.characterWidth;
|
|
}
|
|
}
|
|
|
|
void
|
|
igsGlyphBlt (DrawablePtr pDrawable,
|
|
GCPtr pGC,
|
|
int x,
|
|
int y,
|
|
unsigned int nglyph,
|
|
CharInfoPtr *ppciInit,
|
|
Bool image)
|
|
{
|
|
SetupIgs(pDrawable->pScreen);
|
|
CARD32 cmd;
|
|
int h;
|
|
int w;
|
|
int xBack, yBack;
|
|
int hBack, wBack;
|
|
int lw;
|
|
FontPtr pfont = pGC->font;
|
|
CharInfoPtr pci;
|
|
unsigned long *bits;
|
|
BoxPtr extents;
|
|
BoxRec bbox;
|
|
CARD32 b;
|
|
CharInfoPtr *ppci;
|
|
unsigned char alu;
|
|
PixTransDeclare;
|
|
|
|
/*
|
|
* Paint background for image text
|
|
*/
|
|
if (image)
|
|
{
|
|
xBack = x;
|
|
yBack = y - FONTASCENT(pGC->font);
|
|
wBack = 0;
|
|
hBack = FONTASCENT(pGC->font) + FONTDESCENT(pGC->font);
|
|
if (hBack)
|
|
{
|
|
h = nglyph;
|
|
ppci = ppciInit;
|
|
while (h--)
|
|
wBack += (*ppci++)->metrics.characterWidth;
|
|
}
|
|
if (wBack < 0)
|
|
{
|
|
xBack = xBack + wBack;
|
|
wBack = -wBack;
|
|
}
|
|
if (hBack < 0)
|
|
{
|
|
yBack = yBack + hBack;
|
|
hBack = -hBack;
|
|
}
|
|
alu = GXcopy;
|
|
if (wBack)
|
|
{
|
|
_igsSetSolidRect (cop, GXcopy, pGC->planemask, pGC->bgPixel, cmd);
|
|
_igsRect (cop, xBack, yBack, wBack, hBack, cmd);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
wBack = 0;
|
|
alu = pGC->alu;
|
|
}
|
|
|
|
_igsSetTransparentPlaneBlt (cop, alu, pGC->planemask, pGC->fgPixel, cmd);
|
|
ppci = ppciInit;
|
|
while (nglyph--)
|
|
{
|
|
pci = *ppci++;
|
|
h = pci->metrics.ascent + pci->metrics.descent;
|
|
w = pci->metrics.rightSideBearing - pci->metrics.leftSideBearing;
|
|
lw = h * ((w + 31) >> 5);
|
|
if (lw)
|
|
{
|
|
_igsPlaneBlt(cop,
|
|
x + pci->metrics.leftSideBearing,
|
|
y - pci->metrics.ascent,
|
|
w, h, cmd);
|
|
bits = (unsigned long *) pci->bits;
|
|
PixTransStart(lw);
|
|
while (lw--)
|
|
{
|
|
b = *bits++;
|
|
IgsAdjustBits32 (b);
|
|
PixTransStore(b);
|
|
}
|
|
}
|
|
x += pci->metrics.characterWidth;
|
|
}
|
|
KdMarkSync (pDrawable->pScreen);
|
|
}
|
|
|
|
void
|
|
igsTEGlyphBlt (DrawablePtr pDrawable,
|
|
GCPtr pGC,
|
|
int xInit,
|
|
int yInit,
|
|
unsigned int nglyph,
|
|
CharInfoPtr *ppci,
|
|
Bool image)
|
|
{
|
|
SetupIgs(pDrawable->pScreen);
|
|
CARD32 cmd;
|
|
int x, y;
|
|
int h, lw, lwTmp;
|
|
int w;
|
|
FontPtr pfont = pGC->font;
|
|
unsigned long *char1, *char2, *char3, *char4;
|
|
int widthGlyphs, widthGlyph;
|
|
BoxRec bbox;
|
|
CARD32 tmp;
|
|
PixTransDeclare;
|
|
|
|
widthGlyph = FONTMAXBOUNDS(pfont,characterWidth);
|
|
if (!widthGlyph)
|
|
return;
|
|
|
|
h = FONTASCENT(pfont) + FONTDESCENT(pfont);
|
|
if (!h)
|
|
return;
|
|
|
|
x = xInit + FONTMAXBOUNDS(pfont,leftSideBearing);
|
|
y = yInit - FONTASCENT(pfont);
|
|
|
|
if (image)
|
|
{
|
|
_igsSetOpaquePlaneBlt (cop, GXcopy, pGC->planemask, pGC->fgPixel, pGC->bgPixel, cmd);
|
|
}
|
|
else
|
|
{
|
|
_igsSetTransparentPlaneBlt (cop, pGC->alu, pGC->planemask, pGC->fgPixel, cmd);
|
|
}
|
|
|
|
#if BITMAP_BIT_ORDER == LSBFirst
|
|
#define SHIFT <<
|
|
#else
|
|
#define SHIFT >>
|
|
#endif
|
|
|
|
#define LoopIt(count, w, loadup, fetch) \
|
|
while (nglyph >= count) \
|
|
{ \
|
|
nglyph -= count; \
|
|
_igsPlaneBlt (cop, x, y, w, h, cmd); \
|
|
x += w; \
|
|
loadup \
|
|
lwTmp = h; \
|
|
PixTransStart(h); \
|
|
while (lwTmp--) { \
|
|
tmp = fetch; \
|
|
IgsAdjustBits32(tmp); \
|
|
PixTransStore(tmp); \
|
|
} \
|
|
}
|
|
|
|
if (widthGlyph <= 8)
|
|
{
|
|
widthGlyphs = widthGlyph << 2;
|
|
LoopIt(4, widthGlyphs,
|
|
char1 = (unsigned long *) (*ppci++)->bits;
|
|
char2 = (unsigned long *) (*ppci++)->bits;
|
|
char3 = (unsigned long *) (*ppci++)->bits;
|
|
char4 = (unsigned long *) (*ppci++)->bits;,
|
|
(*char1++ | ((*char2++ | ((*char3++ | (*char4++
|
|
SHIFT widthGlyph))
|
|
SHIFT widthGlyph))
|
|
SHIFT widthGlyph)))
|
|
}
|
|
else if (widthGlyph <= 10)
|
|
{
|
|
widthGlyphs = (widthGlyph << 1) + widthGlyph;
|
|
LoopIt(3, widthGlyphs,
|
|
char1 = (unsigned long *) (*ppci++)->bits;
|
|
char2 = (unsigned long *) (*ppci++)->bits;
|
|
char3 = (unsigned long *) (*ppci++)->bits;,
|
|
(*char1++ | ((*char2++ | (*char3++ SHIFT widthGlyph)) SHIFT widthGlyph)))
|
|
}
|
|
else if (widthGlyph <= 16)
|
|
{
|
|
widthGlyphs = widthGlyph << 1;
|
|
LoopIt(2, widthGlyphs,
|
|
char1 = (unsigned long *) (*ppci++)->bits;
|
|
char2 = (unsigned long *) (*ppci++)->bits;,
|
|
(*char1++ | (*char2++ SHIFT widthGlyph)))
|
|
}
|
|
lw = h * ((widthGlyph + 31) >> 5);
|
|
while (nglyph--)
|
|
{
|
|
_igsPlaneBlt (cop, x, y, widthGlyph, h, cmd);
|
|
x += widthGlyph;
|
|
char1 = (unsigned long *) (*ppci++)->bits;
|
|
lwTmp = lw;
|
|
PixTransStart(lw);
|
|
while (lwTmp--)
|
|
{
|
|
tmp = *char1++;
|
|
IgsAdjustBits32(tmp);
|
|
PixTransStore(tmp);
|
|
}
|
|
}
|
|
KdMarkSync (pDrawable->pScreen);
|
|
}
|
|
|
|
/*
|
|
* Blt glyphs using image transfer window
|
|
*/
|
|
|
|
void
|
|
igsPolyGlyphBlt (DrawablePtr pDrawable,
|
|
GCPtr pGC,
|
|
int x,
|
|
int y,
|
|
unsigned int nglyph,
|
|
CharInfoPtr *ppci,
|
|
pointer pglyphBase)
|
|
{
|
|
if (pGC->fillStyle != FillSolid ||
|
|
fbGetGCPrivate(pGC)->pm != FB_ALLONES)
|
|
{
|
|
KdCheckPolyGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
|
|
return;
|
|
}
|
|
x += pDrawable->x;
|
|
y += pDrawable->y;
|
|
|
|
switch (igsTextInRegion (pGC, x, y, nglyph, ppci)) {
|
|
case rgnIN:
|
|
if (TERMINALFONT(pGC->font))
|
|
igsTEGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, FALSE);
|
|
else
|
|
igsGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, FALSE);
|
|
break;
|
|
case rgnPART:
|
|
igsGlyphBltClipped (pDrawable, pGC, x, y, nglyph, ppci, FALSE);
|
|
break;
|
|
case rgnOUT:
|
|
break;
|
|
}
|
|
}
|
|
|
|
void
|
|
igsImageGlyphBlt (DrawablePtr pDrawable,
|
|
GCPtr pGC,
|
|
int x, int y,
|
|
unsigned int nglyph,
|
|
CharInfoPtr *ppci,
|
|
pointer pglyphBase)
|
|
{
|
|
if (fbGetGCPrivate(pGC)->pm != FB_ALLONES)
|
|
{
|
|
KdCheckImageGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
|
|
return;
|
|
}
|
|
x += pDrawable->x;
|
|
y += pDrawable->y;
|
|
|
|
switch (igsTextInRegion (pGC, x, y, nglyph, ppci)) {
|
|
case rgnIN:
|
|
if (TERMINALFONT(pGC->font))
|
|
igsTEGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, TRUE);
|
|
else
|
|
igsGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, TRUE);
|
|
break;
|
|
case rgnPART:
|
|
igsGlyphBltClipped (pDrawable, pGC, x, y, nglyph, ppci, TRUE);
|
|
break;
|
|
case rgnOUT:
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void
|
|
igsInvalidatePattern (IgsPatternCache *c,
|
|
PixmapPtr pPixmap)
|
|
{
|
|
int i;
|
|
|
|
if (c->base)
|
|
{
|
|
for (i = 0; i < IGS_NUM_PATTERN; i++)
|
|
{
|
|
if (c->pattern[i].serial_number == pPixmap->drawable.serialNumber)
|
|
c->pattern[i].serial_number = ~0;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void
|
|
igsInitPattern (IgsPatternCache *c, int bsize, int psize)
|
|
{
|
|
int i;
|
|
int boffset;
|
|
int poffset;
|
|
|
|
for (i = 0; i < IGS_NUM_PATTERN; i++)
|
|
{
|
|
boffset = i * bsize;
|
|
poffset = i * psize;
|
|
c->pattern[i].xrot = -1;
|
|
c->pattern[i].yrot = -1;
|
|
c->pattern[i].serial_number = ~0;
|
|
c->pattern[i].offset = c->offset + poffset;
|
|
c->pattern[i].base = c->base + boffset;
|
|
}
|
|
c->next = 0;
|
|
}
|
|
|
|
static const GCOps igsOps = {
|
|
igsFillSpans,
|
|
KdCheckSetSpans,
|
|
KdCheckPutImage,
|
|
igsCopyArea,
|
|
igsCopyPlane,
|
|
KdCheckPolyPoint,
|
|
KdCheckPolylines,
|
|
KdCheckPolySegment,
|
|
miPolyRectangle,
|
|
KdCheckPolyArc,
|
|
miFillPolygon,
|
|
igsPolyFillRect,
|
|
KdCheckPolyFillArc,
|
|
miPolyText8,
|
|
miPolyText16,
|
|
miImageText8,
|
|
miImageText16,
|
|
igsImageGlyphBlt,
|
|
igsPolyGlyphBlt,
|
|
igsPushPixels,
|
|
};
|
|
|
|
void
|
|
igsValidateGC (GCPtr pGC, Mask changes, DrawablePtr pDrawable)
|
|
{
|
|
FbGCPrivPtr fbPriv = fbGetGCPrivate(pGC);
|
|
|
|
fbValidateGC (pGC, changes, pDrawable);
|
|
|
|
if (pDrawable->type == DRAWABLE_WINDOW)
|
|
pGC->ops = (GCOps *) &igsOps;
|
|
else
|
|
pGC->ops = (GCOps *) &fbGCOps;
|
|
}
|
|
|
|
GCFuncs igsGCFuncs = {
|
|
igsValidateGC,
|
|
miChangeGC,
|
|
miCopyGC,
|
|
miDestroyGC,
|
|
miChangeClip,
|
|
miDestroyClip,
|
|
miCopyClip
|
|
};
|
|
|
|
int
|
|
igsCreateGC (GCPtr pGC)
|
|
{
|
|
if (!fbCreateGC (pGC))
|
|
return FALSE;
|
|
|
|
if (pGC->depth != 1)
|
|
pGC->funcs = &igsGCFuncs;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void
|
|
igsCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
|
|
{
|
|
ScreenPtr pScreen = pWin->drawable.pScreen;
|
|
KdScreenPriv(pScreen);
|
|
RegionRec rgnDst;
|
|
int dx, dy;
|
|
WindowPtr pwinRoot;
|
|
|
|
pwinRoot = WindowTable[pWin->drawable.pScreen->myNum];
|
|
|
|
dx = ptOldOrg.x - pWin->drawable.x;
|
|
dy = ptOldOrg.y - pWin->drawable.y;
|
|
REGION_TRANSLATE(pWin->drawable.pScreen, prgnSrc, -dx, -dy);
|
|
|
|
REGION_INIT (pWin->drawable.pScreen, &rgnDst, NullBox, 0);
|
|
|
|
REGION_INTERSECT(pWin->drawable.pScreen, &rgnDst, &pWin->borderClip, prgnSrc);
|
|
|
|
fbCopyRegion ((DrawablePtr)pwinRoot, (DrawablePtr)pwinRoot,
|
|
0,
|
|
&rgnDst, dx, dy, igsCopyNtoN, 0, 0);
|
|
|
|
REGION_UNINIT(pWin->drawable.pScreen, &rgnDst);
|
|
}
|
|
|
|
|
|
Bool
|
|
igsDrawInit (ScreenPtr pScreen)
|
|
{
|
|
KdScreenPriv(pScreen);
|
|
igsCardInfo(pScreenPriv);
|
|
igsScreenInfo(pScreenPriv);
|
|
int i;
|
|
int pattern_size;
|
|
int boffset, poffset;
|
|
|
|
KdScreenInitAsync (pScreen);
|
|
|
|
/*
|
|
* Replace various fb screen functions
|
|
*/
|
|
pScreen->CreateGC = igsCreateGC;
|
|
pScreen->CopyWindow = igsCopyWindow;
|
|
|
|
/*
|
|
* Initialize patterns
|
|
*/
|
|
if (igss->tile.base)
|
|
{
|
|
pattern_size = IgsTileSize(pScreenPriv->screen->fb[0].bitsPerPixel);
|
|
igsInitPattern (&igss->tile,
|
|
pattern_size,
|
|
pattern_size * 8 / pScreenPriv->screen->fb[0].bitsPerPixel);
|
|
pattern_size = IgsStippleSize(pScreenPriv->screen->fb[0].bitsPerPixel);
|
|
igsInitPattern (&igss->stipple,
|
|
pattern_size,
|
|
pattern_size * 8 / pScreenPriv->screen->fb[0].bitsPerPixel);
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
void
|
|
igsDrawEnable (ScreenPtr pScreen)
|
|
{
|
|
SetupIgs(pScreen);
|
|
CARD32 cmd;
|
|
CARD32 base;
|
|
CARD16 stride;
|
|
CARD32 format;
|
|
|
|
stride = pScreenPriv->screen->fb[0].pixelStride;
|
|
_igsWaitIdleEmpty(cop);
|
|
_igsReset(cop);
|
|
switch (pScreenPriv->screen->fb[0].bitsPerPixel) {
|
|
case 8:
|
|
format = IGS_FORMAT_8BPP;
|
|
break;
|
|
case 16:
|
|
format = IGS_FORMAT_16BPP;
|
|
break;
|
|
case 24:
|
|
format = IGS_FORMAT_24BPP;
|
|
break;
|
|
case 32:
|
|
format = IGS_FORMAT_32BPP;
|
|
break;
|
|
}
|
|
cop->format = format;
|
|
cop->dst_stride = stride - 1;
|
|
cop->src1_stride = stride - 1;
|
|
cop->src2_stride = stride - 1;
|
|
cop->src1_start = 0;
|
|
cop->src2_start = 0;
|
|
cop->extension |= IGS_BLOCK_COP_REG | IGS_BURST_ENABLE;
|
|
|
|
_igsSetSolidRect(cop, GXcopy, ~0, pScreen->blackPixel, cmd);
|
|
_igsRect (cop, 0, 0,
|
|
pScreenPriv->screen->width, pScreenPriv->screen->height,
|
|
cmd);
|
|
_igsWaitIdleEmpty (cop);
|
|
}
|
|
|
|
void
|
|
igsDrawDisable (ScreenPtr pScreen)
|
|
{
|
|
}
|
|
|
|
void
|
|
igsDrawFini (ScreenPtr pScreen)
|
|
{
|
|
}
|
|
|
|
void
|
|
igsDrawSync (ScreenPtr pScreen)
|
|
{
|
|
SetupIgs(pScreen);
|
|
|
|
_igsWaitIdleEmpty(cop);
|
|
}
|