xserver/hw/kdrive/igs/igsdraw.c

1115 lines
25 KiB
C
Raw Normal View History

/*
* $XFree86$
*
* Copyright <EFBFBD> 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.
*/
#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
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
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);
}
BOOL
igsFillOk (GCPtr pGC)
{
FbBits depthMask;
depthMask = FbFullMask(pGC->depth);
if ((pGC->planemask & depthMask) != depthMask)
return FALSE;
switch (pGC->fillStyle) {
case FillSolid:
return TRUE;
#if 0
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));
#endif
}
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;
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;
#if 0
case FillTiled:
cmd = igsTilePrepare (pGC->tile.pixmap,
pGC->patOrg.x + pDrawable->x,
pGC->patOrg.y + pDrawable->y,
pGC->alu);
break;
default:
cmd = igsStipplePrepare (pDrawable, pGC);
break;
#endif
}
while (n--)
{
x = ppt->x;
y = ppt->y;
ppt++;
width = *pwidth++;
if (width)
{
_igsRect(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;
#if 0
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:
igsFillBoxStipple (pDrawable, pGC,
pboxClipped-pboxClippedBase, pboxClippedBase);
break;
#endif
}
}
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)
{
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)
{
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 const GCOps igsOps = {
igsFillSpans,
KdCheckSetSpans,
KdCheckPutImage,
igsCopyArea,
KdCheckCopyPlane,
KdCheckPolyPoint,
KdCheckPolylines,
KdCheckPolySegment,
miPolyRectangle,
KdCheckPolyArc,
miFillPolygon,
igsPolyFillRect,
KdCheckPolyFillArc,
miPolyText8,
miPolyText16,
miImageText8,
miImageText16,
igsImageGlyphBlt,
igsPolyGlyphBlt,
KdCheckPushPixels,
#ifdef NEED_LINEHELPER
,NULL
#endif
};
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);
}
void
igsPaintWindow(WindowPtr pWin, RegionPtr pRegion, int what)
{
KdScreenPriv(pWin->drawable.pScreen);
PixmapPtr pTile;
if (!REGION_NUM_RECTS(pRegion))
return;
switch (what) {
case PW_BACKGROUND:
switch (pWin->backgroundState) {
case None:
return;
case ParentRelative:
do {
pWin = pWin->parent;
} while (pWin->backgroundState == ParentRelative);
(*pWin->drawable.pScreen->PaintWindowBackground)(pWin, pRegion,
what);
return;
#if 0
case BackgroundPixmap:
pTile = pWin->background.pixmap;
if (igsPatternDimOk (pTile->drawable.width) &&
igsPatternDimOk (pTile->drawable.height))
{
igsFillBoxTiled ((DrawablePtr)pWin,
(int)REGION_NUM_RECTS(pRegion),
REGION_RECTS(pRegion),
pTile,
pWin->drawable.x, pWin->drawable.y, GXcopy);
return;
}
break;
#endif
case BackgroundPixel:
igsFillBoxSolid((DrawablePtr)pWin,
(int)REGION_NUM_RECTS(pRegion),
REGION_RECTS(pRegion),
pWin->background.pixel, GXcopy, ~0);
return;
}
break;
case PW_BORDER:
if (pWin->borderIsPixel)
{
igsFillBoxSolid((DrawablePtr)pWin,
(int)REGION_NUM_RECTS(pRegion),
REGION_RECTS(pRegion),
pWin->border.pixel, GXcopy, ~0);
return;
}
#if 0
else
{
pTile = pWin->border.pixmap;
if (igsPatternDimOk (pTile->drawable.width) &&
igsPatternDimOk (pTile->drawable.height))
{
igsFillBoxTiled ((DrawablePtr)pWin,
(int)REGION_NUM_RECTS(pRegion),
REGION_RECTS(pRegion),
pTile,
pWin->drawable.x, pWin->drawable.y, GXcopy);
return;
}
}
#endif
break;
}
KdCheckPaintWindow (pWin, pRegion, what);
}
Bool
igsDrawInit (ScreenPtr pScreen)
{
/*
* Replace various fb screen functions
*/
pScreen->CreateGC = igsCreateGC;
pScreen->CopyWindow = igsCopyWindow;
pScreen->PaintWindowBackground = igsPaintWindow;
pScreen->PaintWindowBorder = igsPaintWindow;
KdScreenInitAsync (pScreen);
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);
}