summaryrefslogtreecommitdiff
path: root/hw/kdrive/sis530/sisdraw.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/kdrive/sis530/sisdraw.c')
-rw-r--r--hw/kdrive/sis530/sisdraw.c1656
1 files changed, 1656 insertions, 0 deletions
diff --git a/hw/kdrive/sis530/sisdraw.c b/hw/kdrive/sis530/sisdraw.c
new file mode 100644
index 000000000..836f54e79
--- /dev/null
+++ b/hw/kdrive/sis530/sisdraw.c
@@ -0,0 +1,1656 @@
+/*
+ * $Id$
+ *
+ * Copyright © 1999 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.
+ */
+/* $XFree86: $ */
+
+#include "sis.h"
+#include "sisdraw.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 sisPatRop[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 */
+};
+
+CARD8 sisBltRop[16] = {
+ /* GXclear */ 0x00, /* 0 */
+ /* GXand */ 0x88, /* src AND dst */
+ /* GXandReverse */ 0x44, /* src AND NOT dst */
+ /* GXcopy */ 0xcc, /* src */
+ /* GXandInverted*/ 0x22, /* NOT src AND dst */
+ /* GXnoop */ 0xaa, /* dst */
+ /* GXxor */ 0x66, /* src XOR dst */
+ /* GXor */ 0xee, /* src OR dst */
+ /* GXnor */ 0x11, /* NOT src AND NOT dst */
+ /* GXequiv */ 0x99, /* NOT src XOR dst */
+ /* GXinvert */ 0x55, /* NOT dst */
+ /* GXorReverse */ 0xdd, /* src OR NOT dst */
+ /* GXcopyInverted*/ 0x33, /* NOT src */
+ /* GXorInverted */ 0xbb, /* NOT src OR dst */
+ /* GXnand */ 0x77, /* NOT src OR NOT dst */
+ /* GXset */ 0xff, /* 1 */
+};
+
+/* Align blts to this boundary or risk trashing an in-progress expand */
+#define SIS_MIN_PATTERN 8
+
+/* Do plane bits in this increment to balance CPU and graphics engine */
+#define SIS_PATTERN_INC 1024
+
+typedef struct _SisExpand {
+ SisCardInfo *sisc;
+ SisScreenInfo *siss;
+ CARD32 off;
+ int last;
+} SisExpand;
+
+static void
+sisExpandInit (ScreenPtr pScreen,
+ SisExpand *e)
+{
+ KdScreenPriv(pScreen);
+ sisCardInfo(pScreenPriv);
+ sisScreenInfo(pScreenPriv);
+
+ e->sisc = sisc;
+ e->siss = siss;
+ e->off = siss->expand_off;
+ e->last = 0;
+}
+
+static CARD32 *
+sisExpandAlloc (SisExpand *e,
+ int nb)
+{
+ SisCardInfo *sisc = e->sisc;
+ SisScreenInfo *siss = e->siss;
+ SisPtr sis = sisc->sis;
+ CARD32 off;
+
+ /* round up to alignment boundary */
+ nb = (nb + SIS_MIN_PATTERN-1) & ~(SIS_MIN_PATTERN-1);
+
+ off = e->off + e->last;
+ if (off + nb > siss->expand_off + siss->expand_len)
+ {
+ _sisWaitIdleEmpty (sis);
+ off = siss->expand_off;
+ }
+ e->off = off;
+ e->last = nb;
+ return (CARD32 *) (sisc->frameBuffer + off);
+}
+
+void
+sisGlyphBltClipped (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ unsigned int nglyph,
+ CharInfoPtr *ppciInit,
+ Bool imageBlt)
+{
+ SetupSis(pDrawable->pScreen);
+ FbGCPrivPtr fbPriv = fbGetGCPrivate(pGC);
+ int height;
+ int width;
+ int xBack, yBack;
+ int hBack, wBack;
+ int nb, bwidth, nl;
+ FontPtr pfont = pGC->font;
+ CharInfoPtr pci;
+ CARD8 *bits8, b;
+ CARD16 *bits16;
+ CARD32 *bits32;
+ BoxPtr extents;
+ BoxRec bbox;
+ unsigned char alu;
+ CARD32 cmd;
+ SisExpand expand;
+ CARD32 *dst, d;
+ int nbytes;
+ int shift;
+ int x1, y1, x2, y2;
+ RegionPtr pClip = fbGetCompositeClip(pGC);
+ BoxPtr pBox;
+ int nbox;
+ int rect_in;
+ int widthBlt;
+ CharInfoPtr *ppci;
+
+ x += pDrawable->x;
+ y += pDrawable->y;
+
+ if (imageBlt)
+ {
+ xBack = x;
+ yBack = y - FONTASCENT(pGC->font);
+ wBack = 0;
+ hBack = FONTASCENT(pGC->font) + FONTDESCENT(pGC->font);
+ if (hBack)
+ {
+ height = nglyph;
+ ppci = ppciInit;
+ while (height--)
+ wBack += (*ppci++)->metrics.characterWidth;
+ }
+ if (wBack < 0)
+ {
+ xBack = xBack + wBack;
+ wBack = -wBack;
+ }
+ if (hBack < 0)
+ {
+ yBack = yBack + hBack;
+ hBack = -hBack;
+ }
+ alu = GXcopy;
+ }
+ else
+ {
+ wBack = 0;
+ alu = pGC->alu;
+ }
+
+ if (wBack)
+ {
+ _sisSetSolidRect (sis, pGC->bgPixel, GXcopy, 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)
+ {
+ _sisRect (sis, x1, y1, x2 - x1, y2 - y1, cmd);
+ }
+ }
+ }
+
+ sisExpandInit (pDrawable->pScreen, &expand);
+
+ sis->u.general.src_fg = pGC->fgPixel;
+ sis->u.general.src_pitch = 0;
+ sis->u.general.src_x = 0;
+ sis->u.general.src_y = 0;
+
+ cmd = (SIS_CMD_ENH_COLOR_EXPAND |
+ SIS_CMD_SRC_SCREEN |
+ SIS_CMD_PAT_FG |
+ (sisBltRop[alu] << 8) |
+ SIS_CMD_INC_X |
+ SIS_CMD_INC_Y |
+ SIS_CMD_RECT_CLIP_ENABLE |
+ SIS_CMD_TRANSPARENT);
+
+ ppci = ppciInit;
+ while (nglyph--)
+ {
+ pci = *ppci++;
+ height = pci->metrics.ascent + pci->metrics.descent;
+ width = pci->metrics.rightSideBearing - pci->metrics.leftSideBearing;
+ widthBlt = (width + 31) & ~31;
+ nb = (widthBlt >> 3) * height;
+ if (nb)
+ {
+ x1 = x + pci->metrics.leftSideBearing;
+ y1 = y - pci->metrics.ascent;
+ bbox.x1 = x1;
+ bbox.y1 = y1;
+ bbox.x2 = x1 + width;
+ bbox.y2 = y1 + height;
+ rect_in = RECT_IN_REGION(pGC->pScreen, pClip, &bbox);
+ if (rect_in != rgnOUT)
+ {
+ dst = sisExpandAlloc (&expand, nb);
+
+ sis->u.general.src_base = expand.off;
+ sis->u.general.dst_x = x1;
+ sis->u.general.dst_y = y1;
+ sis->u.general.rect_width = widthBlt;
+ sis->u.general.rect_height = height;
+ nb >>= 2;
+ bits32 = (CARD32 *) pci->bits;
+ while (nb--)
+ {
+ d = *bits32++;
+ SisInvertBits32 (d);
+ *dst++ = d;
+ }
+ if (rect_in == rgnPART)
+ {
+ for (nbox = REGION_NUM_RECTS (pClip),
+ pBox = REGION_RECTS (pClip);
+ nbox--;
+ pBox++)
+ {
+ _sisClip (sis, pBox->x1, pBox->y1, pBox->x2, pBox->y2);
+ sis->u.general.command = cmd;
+ }
+ }
+ else
+ {
+ _sisClip (sis, 0, 0, x1+width, pScreenPriv->screen->height);
+ sis->u.general.command = cmd;
+ }
+ }
+ }
+ x += pci->metrics.characterWidth;
+ }
+ _sisClip (sis, 0, 0,
+ pScreenPriv->screen->width, pScreenPriv->screen->height);
+ _sisWaitIdleEmpty(sis);
+}
+
+Bool
+sisTEGlyphBlt (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int xInit,
+ int yInit,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ Bool imageBlt)
+{
+ SetupSis(pDrawable->pScreen);
+ int x, y;
+ int widthGlyphs, widthGlyph;
+ int widthBlt;
+ FbBits depthMask;
+ int glyphsPer;
+ FontPtr pfont = pGC->font;
+ unsigned long *char1, *char2, *char3, *char4, *char5;
+ CARD8 alu;
+ CARD32 *dst, tmp;
+ CARD8 *dst8, *bits8;
+ int nb;
+ int bwidth;
+ CARD32 cmd;
+ int h;
+ BoxRec bbox;
+ SisExpand expand;
+ int lwTmp, lw;
+ int extra, n;
+
+ widthGlyph = FONTMAXBOUNDS(pfont,characterWidth);
+ if (!widthGlyph)
+ return TRUE;
+
+ h = FONTASCENT(pfont) + FONTDESCENT(pfont);
+ if (!h)
+ return TRUE;
+
+ x = xInit + FONTMAXBOUNDS(pfont,leftSideBearing) + pDrawable->x;
+ y = yInit - FONTASCENT(pfont) + pDrawable->y;
+
+ bbox.x1 = x;
+ bbox.x2 = x + (widthGlyph * nglyph);
+ bbox.y1 = y;
+ bbox.y2 = y + h;
+
+ switch (RECT_IN_REGION(pGC->pScreen, fbGetCompositeClip(pGC), &bbox))
+ {
+ case rgnPART:
+ if (x < 0 || y < 0)
+ return FALSE;
+ sisGlyphBltClipped (pDrawable, pGC, xInit, yInit, nglyph, ppci, imageBlt);
+ case rgnOUT:
+ return TRUE;
+ }
+
+ if (widthGlyph <= 6)
+ glyphsPer = 5;
+ else if (widthGlyph <= 8)
+ glyphsPer = 4;
+ else if (widthGlyph <= 10)
+ glyphsPer = 3;
+ else if (widthGlyph <= 16)
+ glyphsPer = 2;
+ else
+ glyphsPer = 1;
+
+ widthGlyphs = widthGlyph * glyphsPer;
+ widthBlt = widthGlyphs;
+
+ /* make sure scanlines are 32-bit aligned */
+ if (widthGlyphs <= 24)
+ widthBlt = 25;
+
+ cmd = (SIS_CMD_ENH_COLOR_EXPAND |
+ SIS_CMD_SRC_SCREEN |
+ SIS_CMD_PAT_FG |
+ SIS_CMD_INC_X |
+ SIS_CMD_INC_Y);
+
+ if (imageBlt)
+ {
+ sis->u.general.clip_right = bbox.x2;
+ cmd |= ((sisBltRop[GXcopy] << 8) |
+ SIS_CMD_OPAQUE |
+ SIS_CMD_RECT_CLIP_ENABLE);
+ }
+ else
+ {
+ cmd |= ((sisBltRop[pGC->alu] << 8) |
+ SIS_CMD_TRANSPARENT |
+ SIS_CMD_RECT_CLIP_DISABLE);
+ }
+
+ sisExpandInit (pDrawable->pScreen, &expand);
+
+ sis->u.general.src_fg = pGC->fgPixel;
+ sis->u.general.src_bg = pGC->bgPixel;
+
+ bwidth = (widthBlt + 7) >> 3;
+
+ nb = bwidth * h;
+
+#define LoopIt(count, loadup, fetch) \
+ while (nglyph >= count) \
+ { \
+ nglyph -= count; \
+ dst = sisExpandAlloc (&expand, nb); \
+ sis->u.general.src_base = expand.off; \
+ sis->u.general.src_pitch = 0; \
+ sis->u.general.src_x = 0; \
+ sis->u.general.src_y = 0; \
+ sis->u.general.dst_x = x; \
+ sis->u.general.dst_y = y; \
+ sis->u.general.rect_width = widthBlt; \
+ sis->u.general.rect_height = h; \
+ x += widthGlyphs; \
+ loadup \
+ lwTmp = h; \
+ while (lwTmp--) { \
+ tmp = fetch; \
+ SisInvertBits32(tmp); \
+ *dst++ = tmp; \
+ } \
+ sis->u.general.command = cmd; \
+ }
+
+ switch (glyphsPer) {
+ case 5:
+ LoopIt(5,
+ char1 = (unsigned long *) (*ppci++)->bits;
+ char2 = (unsigned long *) (*ppci++)->bits;
+ char3 = (unsigned long *) (*ppci++)->bits;
+ char4 = (unsigned long *) (*ppci++)->bits;
+ char5 = (unsigned long *) (*ppci++)->bits;,
+ (*char1++ | ((*char2++ | ((*char3++ | ((*char4++ | (*char5++
+ << widthGlyph))
+ << widthGlyph))
+ << widthGlyph))
+ << widthGlyph)));
+ break;
+ case 4:
+ LoopIt(4,
+ char1 = (unsigned long *) (*ppci++)->bits;
+ char2 = (unsigned long *) (*ppci++)->bits;
+ char3 = (unsigned long *) (*ppci++)->bits;
+ char4 = (unsigned long *) (*ppci++)->bits;,
+ (*char1++ | ((*char2++ | ((*char3++ | (*char4++
+ << widthGlyph))
+ << widthGlyph))
+ << widthGlyph)));
+ break;
+ case 3:
+ LoopIt(3,
+ char1 = (unsigned long *) (*ppci++)->bits;
+ char2 = (unsigned long *) (*ppci++)->bits;
+ char3 = (unsigned long *) (*ppci++)->bits;,
+ (*char1++ | ((*char2++ | (*char3++ << widthGlyph)) << widthGlyph)));
+ break;
+ case 2:
+ LoopIt(2,
+ char1 = (unsigned long *) (*ppci++)->bits;
+ char2 = (unsigned long *) (*ppci++)->bits;,
+ (*char1++ | (*char2++ << widthGlyph)));
+ break;
+ }
+
+ widthBlt = (widthGlyph + 31) & ~31;
+
+ bwidth = widthBlt >> 3;
+
+ nb = bwidth * h;
+
+ lw = (widthBlt >> 5) * h;
+
+ while (nglyph--)
+ {
+ dst = (CARD32 *) sisExpandAlloc (&expand, nb);
+ char1 = (CARD32 *) (*ppci++)->bits;
+ sis->u.general.src_base = expand.off;
+ sis->u.general.src_pitch = 0;
+ sis->u.general.src_x = 0;
+ sis->u.general.src_y = 0;
+ sis->u.general.dst_x = x;
+ sis->u.general.dst_y = y;
+ sis->u.general.rect_width = widthBlt;
+ sis->u.general.rect_height = h;
+ lwTmp = lw;
+ while (lwTmp--)
+ {
+ tmp = *char1++;
+ SisInvertBits32 (tmp);
+ *dst++ = tmp;
+ }
+ sis->u.general.command = cmd;
+ x += widthGlyph;
+ }
+ if (imageBlt)
+ sis->u.general.clip_right = pScreenPriv->screen->width;
+ _sisWaitIdleEmpty(sis);
+ return TRUE;
+}
+
+Bool
+sisGlyphBlt(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ unsigned int nglyph,
+ CharInfoPtr *ppciInit,
+ Bool imageBlt)
+{
+ SetupSis(pDrawable->pScreen);
+ int height;
+ int width;
+ int xBack, yBack;
+ int hBack, wBack;
+ int nb, bwidth, nl;
+ FontPtr pfont = pGC->font;
+ CharInfoPtr pci;
+ CARD8 *bits8, b;
+ CARD16 *bits16;
+ CARD32 *bits32;
+ BoxPtr extents;
+ BoxRec bbox;
+ CharInfoPtr *ppci;
+ unsigned char alu;
+ CARD32 cmd;
+ SisExpand expand;
+ CARD32 *dst, d;
+ int nbytes;
+ int shift;
+
+ x += pDrawable->x;
+ y += pDrawable->y;
+
+ /* compute an approximate (but covering) bounding box */
+ ppci = ppciInit;
+ width = 0;
+ height = nglyph;
+ while (height--)
+ width += (*ppci++)->metrics.characterWidth;
+ if (width < 0)
+ {
+ bbox.x1 = x + width;
+ bbox.x2 = x;
+ }
+ else
+ {
+ bbox.x1 = x;
+ bbox.x2 = x + width;
+ }
+ width = FONTMINBOUNDS(pfont,leftSideBearing);
+ if (width < 0)
+ bbox.x1 += width;
+ width = FONTMAXBOUNDS(pfont, rightSideBearing) - FONTMINBOUNDS(pfont, characterWidth);
+ if (width > 0)
+ bbox.x2 += width;
+ bbox.y1 = y - FONTMAXBOUNDS(pfont,ascent);
+ bbox.y2 = y + FONTMAXBOUNDS(pfont,descent);
+
+ switch (RECT_IN_REGION(pGC->pScreen, fbGetCompositeClip(pGC), &bbox))
+ {
+ case rgnPART:
+ if (bbox.x1 < 0 || bbox.y1 < 0)
+ return FALSE;
+ sisGlyphBltClipped (pDrawable, pGC,
+ x - pDrawable->x, y - pDrawable->y,
+ nglyph, ppciInit, imageBlt);
+ case rgnOUT:
+ return TRUE;
+ }
+
+ if (imageBlt)
+ {
+ xBack = x;
+ yBack = y - FONTASCENT(pGC->font);
+ wBack = 0;
+ hBack = FONTASCENT(pGC->font) + FONTDESCENT(pGC->font);
+ if (hBack)
+ {
+ height = nglyph;
+ ppci = ppciInit;
+ while (height--)
+ wBack += (*ppci++)->metrics.characterWidth;
+ }
+ if (wBack < 0)
+ {
+ xBack = xBack + wBack;
+ wBack = -wBack;
+ }
+ if (hBack < 0)
+ {
+ yBack = yBack + hBack;
+ hBack = -hBack;
+ }
+ alu = GXcopy;
+ }
+ else
+ {
+ wBack = 0;
+ alu = pGC->alu;
+ }
+
+ if (wBack)
+ {
+ _sisSetSolidRect (sis, pGC->bgPixel, GXcopy, cmd);
+ _sisRect (sis, xBack, yBack, wBack, hBack, cmd);
+ }
+
+ sisExpandInit (pDrawable->pScreen, &expand);
+
+ sis->u.general.src_fg = pGC->fgPixel;
+
+ cmd = (SIS_CMD_ENH_COLOR_EXPAND |
+ SIS_CMD_SRC_SCREEN |
+ SIS_CMD_PAT_FG |
+ (sisBltRop[alu] << 8) |
+ SIS_CMD_INC_X |
+ SIS_CMD_INC_Y |
+ SIS_CMD_RECT_CLIP_DISABLE |
+ SIS_CMD_TRANSPARENT);
+
+ ppci = ppciInit;
+ while (nglyph--)
+ {
+ pci = *ppci++;
+ height = pci->metrics.ascent + pci->metrics.descent;
+ width = pci->metrics.rightSideBearing - pci->metrics.leftSideBearing;
+ /*
+ * For glyphs wider than 16 pixels, expand the blt to the nearest multiple
+ * of 32; this allows the scanlines to be padded to a 32-bit boundary
+ * instead of requiring byte packing
+ */
+ if (width > 16)
+ width = (width + 31) & ~31;
+ bwidth = (width + 7) >> 3;
+ nb = bwidth * height;
+ if (nb)
+ {
+ dst = sisExpandAlloc (&expand, nb);
+
+ sis->u.general.src_base = expand.off;
+ sis->u.general.src_pitch = 0;
+ sis->u.general.src_x = 0;
+ sis->u.general.src_y = 0;
+ sis->u.general.dst_x = x + pci->metrics.leftSideBearing;
+ sis->u.general.dst_y = y - pci->metrics.ascent;
+ sis->u.general.rect_width = width;
+ sis->u.general.rect_height = height;
+ switch (bwidth) {
+ case 1:
+ bits8 = (CARD8 *) pci->bits;
+ while (height >= 4)
+ {
+ d = (bits8[0] | (bits8[4] << 8) |
+ (bits8[8] << 16) | (bits8[12] << 24));
+ SisInvertBits32(d);
+ *dst++ = d;
+ bits8 += 16;
+ height -= 4;
+ }
+ if (height)
+ {
+ switch (height) {
+ case 3:
+ d = bits8[0] | (bits8[4] << 8) | (bits8[8] << 16);
+ break;
+ case 2:
+ d = bits8[0] | (bits8[4] << 8);
+ break;
+ case 1:
+ d = bits8[0];
+ break;
+ }
+ SisInvertBits32(d);
+ *dst++ = d;
+ }
+ break;
+ case 2:
+ bits16 = (CARD16 *) pci->bits;
+ while (height >= 2)
+ {
+ d = bits16[0] | (bits16[2] << 16);
+ SisInvertBits32(d);
+ *dst++ = d;
+ bits16 += 4;
+ height -= 2;
+ }
+ if (height)
+ {
+ d = bits16[0];
+ SisInvertBits32(d);
+ *dst++ = d;
+ }
+ break;
+ default:
+ nb >>= 2;
+ bits32 = (CARD32 *) pci->bits;
+ while (nb--)
+ {
+ d = *bits32++;
+ SisInvertBits32 (d);
+ *dst++ = d;
+ }
+ }
+ sis->u.general.command = cmd;
+ }
+ x += pci->metrics.characterWidth;
+ }
+ _sisWaitIdleEmpty(sis);
+ return TRUE;
+}
+/*
+ * Blt glyphs using Sis image transfer register, this does both
+ * poly glyph blt and image glyph blt (when pglyphBase == 1)
+ */
+
+void
+sisPolyGlyphBlt (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x, int y,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase)
+{
+ FbBits depthMask;
+
+ depthMask = FbFullMask (pDrawable->depth);
+ if ((pGC->planemask & depthMask) == depthMask &&
+ pGC->fillStyle == FillSolid)
+ {
+ if (TERMINALFONT(pGC->font))
+ {
+ if (sisTEGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, FALSE))
+ return;
+ }
+ else
+ {
+ if (sisGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, FALSE))
+ return;
+ }
+ }
+ fbPolyGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
+}
+
+void
+sisImageGlyphBlt (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x, int y,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase)
+{
+ FbBits depthMask;
+
+ depthMask = FbFullMask (pDrawable->depth);
+ if ((pGC->planemask & depthMask) == depthMask)
+ {
+ if (TERMINALFONT(pGC->font))
+ {
+ if (sisTEGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, TRUE))
+ return;
+ }
+ else
+ {
+ if (sisGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, TRUE))
+ return;
+ }
+ }
+ fbImageGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
+}
+
+#define sourceInvarient(alu) (((alu) & 3) == (((alu) >> 2) & 3))
+
+#define sisPatternDimOk(d) ((d) <= 8 && (((d) & ((d) - 1)) == 0))
+
+BOOL
+sisFillOk (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 (sisPatternDimOk (pGC->tile.pixmap->drawable.width) &&
+ sisPatternDimOk (pGC->tile.pixmap->drawable.height));
+ case FillStippled:
+ case FillOpaqueStippled:
+ return (sisPatternDimOk (pGC->stipple->drawable.width) &&
+ sisPatternDimOk (pGC->stipple->drawable.height));
+ }
+}
+
+CARD32
+sisStipplePrepare (DrawablePtr pDrawable, GCPtr pGC)
+{
+ SetupSis(pGC->pScreen);
+ PixmapPtr pStip = pGC->stipple;
+ int stipHeight = pStip->drawable.height;
+ int xRot, yRot;
+ int rot, stipX, stipY;
+ FbStip *stip, *stipEnd, bits;
+ FbStride stipStride;
+ int stipBpp;
+ int y;
+ CARD32 cmd;
+
+ xRot = pGC->patOrg.x + pDrawable->x;
+ yRot = pGC->patOrg.y + pDrawable->y;
+ modulus (- yRot, stipHeight, stipY);
+ modulus (- xRot, FB_UNIT, stipX);
+ rot = stipX;
+
+ fbGetStipDrawable (&pStip->drawable, stip, stipStride, stipBpp);
+ for (y = 0; y < 8; y++)
+ {
+ bits = stip[stipY<<1];
+ FbRotLeft(bits, rot);
+ SisInvertBits32(bits);
+ sis->u.general.mask[y] = (CARD8) bits;
+ stipY++;
+ if (stipY == stipHeight)
+ stipY = 0;
+ }
+ sis->u.general.pattern_fg = pGC->fgPixel;
+
+ cmd = (SIS_CMD_BITBLT |
+ SIS_CMD_SRC_SCREEN |
+ SIS_CMD_PAT_MONO |
+ (sisPatRop[pGC->alu] << 8) |
+ SIS_CMD_INC_X |
+ SIS_CMD_INC_Y |
+ SIS_CMD_RECT_CLIP_DISABLE |
+ SIS_CMD_RECT_CLIP_DONT_MERGE);
+ if (pGC->fillStyle == FillOpaqueStippled)
+ {
+ sis->u.general.pattern_bg = pGC->bgPixel;
+ cmd |= SIS_CMD_OPAQUE;
+ }
+ else
+ cmd |= SIS_CMD_TRANSPARENT;
+ return cmd;
+}
+
+CARD32
+sisTilePrepare (PixmapPtr pTile, int xRot, int yRot, CARD8 alu)
+{
+ SetupSis(pTile->drawable.pScreen);
+ int tileHeight = pTile->drawable.height;
+ int tileWidth = pTile->drawable.width;
+ FbBits *tile;
+ FbStride tileStride;
+ int tileBpp;
+
+ fbGetDrawable (&pTile->drawable, tile, tileStride, tileBpp);
+
+ /*
+ * Tile the pattern register
+ */
+ fbTile ((FbBits *) sis->u.general.pattern,
+ (8 * tileBpp) >> FB_SHIFT,
+ 0,
+
+ 8 * tileBpp, 8,
+
+ tile,
+ tileStride,
+ tileWidth * tileBpp,
+ tileHeight,
+ GXcopy, FB_ALLONES, tileBpp,
+ xRot * tileBpp,
+ yRot);
+
+ return (SIS_CMD_BITBLT |
+ SIS_CMD_SRC_SCREEN |
+ SIS_CMD_PAT_PATTERN |
+ (sisPatRop[alu] << 8) |
+ SIS_CMD_INC_X |
+ SIS_CMD_INC_Y |
+ SIS_CMD_RECT_CLIP_DISABLE |
+ SIS_CMD_RECT_CLIP_DONT_MERGE);
+}
+
+void
+sisFillBoxSolid (DrawablePtr pDrawable, int nBox, BoxPtr pBox,
+ unsigned long pixel, int alu)
+{
+ SetupSis(pDrawable->pScreen);
+ CARD32 cmd;
+
+ _sisSetSolidRect(sis,pixel,alu,cmd);
+
+ while (nBox--)
+ {
+ _sisRect(sis,pBox->x1,pBox->y1,pBox->x2-pBox->x1,pBox->y2-pBox->y1,cmd);
+ pBox++;
+ }
+ _sisWaitIdleEmpty(sis);
+}
+
+void
+sisFillBoxStipple (DrawablePtr pDrawable, GCPtr pGC,
+ int nBox, BoxPtr pBox)
+{
+ SetupSis(pDrawable->pScreen);
+ CARD32 cmd;
+
+ cmd = sisStipplePrepare (pDrawable, pGC);
+
+ while (nBox--)
+ {
+ _sisRect(sis,pBox->x1,pBox->y1,pBox->x2-pBox->x1,pBox->y2-pBox->y1,cmd);
+ pBox++;
+ }
+ _sisWaitIdleEmpty (sis);
+}
+
+void
+sisFillBoxTiled (DrawablePtr pDrawable,
+ int nBox, BoxPtr pBox,
+ PixmapPtr pTile, int xRot, int yRot, CARD8 alu)
+{
+ SetupSis (pDrawable->pScreen);
+ CARD32 cmd;
+
+ cmd = sisTilePrepare (pTile, xRot, yRot, alu);
+
+ while (nBox--)
+ {
+ _sisRect(sis,pBox->x1,pBox->y1,pBox->x2-pBox->x1,pBox->y2-pBox->y1,cmd);
+ pBox++;
+ }
+ _sisWaitIdleEmpty (sis);
+}
+
+/*
+ sisDoBitBlt
+ =============
+ Bit Blit for all window to window blits.
+*/
+
+void
+sisCopyNtoN (DrawablePtr pSrcDrawable,
+ DrawablePtr pDstDrawable,
+ GCPtr pGC,
+ BoxPtr pbox,
+ int nbox,
+ int dx,
+ int dy,
+ Bool reverse,
+ Bool upsidedown,
+ Pixel bitplane,
+ void *closure)
+{
+ SetupSis(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))
+ {
+ sisFillBoxSolid (pDstDrawable, nbox, pbox, 0, pGC->alu);
+ return;
+ }
+ }
+ else
+ alu = GXcopy;
+
+ _sisSetBlt(sis,alu,cmd);
+ while (nbox--)
+ {
+ w = pbox->x2 - pbox->x1;
+ h = pbox->y2 - pbox->y1;
+ flags = 0;
+ if (reverse)
+ {
+ dstX = pbox->x2 - 1;
+ }
+ else
+ {
+ dstX = pbox->x1;
+ flags |= SIS_CMD_INC_X;
+ }
+ srcX = dstX + dx;
+
+ if (upsidedown)
+ {
+ dstY = pbox->y2 - 1;
+ }
+ else
+ {
+ dstY = pbox->y1;
+ flags |= SIS_CMD_INC_Y;
+ }
+ srcY = dstY + dy;
+
+ _sisBlt (sis, srcX, srcY, dstX, dstY, w, h, cmd|flags);
+ pbox++;
+ }
+ _sisWaitIdleEmpty(sis);
+}
+
+RegionPtr
+sisCopyArea(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, sisCopyNtoN, 0, 0);
+ }
+ return fbCopyArea (pSrcDrawable, pDstDrawable, pGC,
+ srcx, srcy, width, height, dstx, dsty);
+}
+
+typedef struct _sis1toNargs {
+ unsigned long copyPlaneFG, copyPlaneBG;
+} sis1toNargs;
+
+void
+_sisStipple (ScreenPtr pScreen,
+ FbStip *psrcBase,
+ FbStride widthSrc,
+ CARD8 alu,
+ int srcx,
+ int srcy,
+ int dstx,
+ int dsty,
+ int width,
+ int height)
+{
+ SetupSis(pScreen);
+ FbStip *psrcLine, *psrc;
+ FbStride widthRest;
+ FbStip bits, tmp, lastTmp;
+ int leftShift, rightShift;
+ int nl, nlMiddle;
+ int r;
+ SisExpand expand;
+ CARD32 *dst;
+ int hthis;
+ int hper;
+ int bwidth;
+ CARD32 cmd;
+
+ sisExpandInit (pScreen, &expand);
+
+ /* Compute blt address and parameters */
+ psrc = psrcBase + srcy * widthSrc + (srcx >> 5);
+ nlMiddle = (width + 31) >> 5;
+ leftShift = srcx & 0x1f;
+ rightShift = 32 - leftShift;
+ widthRest = widthSrc - nlMiddle;
+
+ cmd = (SIS_CMD_ENH_COLOR_EXPAND |
+ SIS_CMD_SRC_SCREEN |
+ SIS_CMD_PAT_FG |
+ (sisBltRop[alu] << 8) |
+ SIS_CMD_INC_X |
+ SIS_CMD_INC_Y |
+ SIS_CMD_OPAQUE |
+ SIS_CMD_RECT_CLIP_ENABLE);
+
+ if (leftShift != 0)
+ widthRest--;
+
+ sis->u.general.src_x = 0;
+ sis->u.general.src_y = 0;
+ sis->u.general.dst_x = dstx;
+ sis->u.general.rect_width = (width + 31) & ~31;
+ sis->u.general.clip_right = (dstx + width);
+
+ bwidth = nlMiddle << 2;
+ hper = SIS_PATTERN_INC / bwidth;
+ if (hper == 0)
+ hper = 1;
+
+ while (height)
+ {
+ hthis = hper;
+ if (hthis > height)
+ hthis = height;
+ dst = sisExpandAlloc (&expand, bwidth * hthis);
+ sis->u.general.src_base = expand.off;
+ sis->u.general.dst_y = dsty;
+ sis->u.general.rect_height = hthis;
+
+ dsty += hthis;
+ height -= hthis;
+
+ if (leftShift == 0)
+ {
+ while (hthis--)
+ {
+ nl = nlMiddle;
+ while (nl--)
+ {
+ tmp = *psrc++;
+ SisInvertBits32(tmp);
+ *dst++ = tmp;
+ }
+ psrc += widthRest;
+ }
+ }
+ else
+ {
+ while (hthis--)
+ {
+ bits = *psrc++;
+ nl = nlMiddle;
+ while (nl--)
+ {
+ tmp = FbStipLeft(bits, leftShift);
+ bits = *psrc++;
+ tmp |= FbStipRight(bits, rightShift);
+ SisInvertBits32(tmp);
+ *dst++ = tmp;
+ }
+ psrc += widthRest;
+ }
+ }
+ sis->u.general.command = cmd;
+ }
+ sis->u.general.clip_right = pScreenPriv->screen->width;
+}
+
+void
+sisCopy1toN (DrawablePtr pSrcDrawable,
+ DrawablePtr pDstDrawable,
+ GCPtr pGC,
+ BoxPtr pbox,
+ int nbox,
+ int dx,
+ int dy,
+ Bool reverse,
+ Bool upsidedown,
+ Pixel bitplane,
+ void *closure)
+{
+ SetupSis(pDstDrawable->pScreen);
+
+ sis1toNargs *args = closure;
+ int dstx, dsty;
+ FbStip *psrcBase;
+ FbStride widthSrc;
+ int srcBpp;
+
+ if (sourceInvarient (pGC->alu))
+ {
+ sisFillBoxSolid (pDstDrawable, nbox, pbox,
+ pGC->bgPixel, pGC->alu);
+ return;
+ }
+
+ fbGetStipDrawable (pSrcDrawable, psrcBase, widthSrc, srcBpp);
+
+ sis->u.general.src_fg = args->copyPlaneFG;
+ sis->u.general.src_bg = args->copyPlaneBG;
+
+ while (nbox--)
+ {
+ dstx = pbox->x1;
+ dsty = pbox->y1;
+
+ _sisStipple (pDstDrawable->pScreen,
+ psrcBase, widthSrc,
+ pGC->alu,
+ dstx + dx, dsty + dy,
+ dstx, dsty,
+ pbox->x2 - dstx, pbox->y2 - dsty);
+ pbox++;
+ }
+ _sisWaitIdleEmpty (sis);
+}
+
+RegionPtr
+sisCopyPlane(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC,
+ int srcx, int srcy, int width, int height,
+ int dstx, int dsty, unsigned long bitPlane)
+{
+ KdScreenPriv (pDstDrawable->pScreen);
+ RegionPtr ret;
+ sis1toNargs 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;
+ return fbDoCopy (pSrcDrawable, pDstDrawable, pGC,
+ srcx, srcy, width, height,
+ dstx, dsty, sisCopy1toN, bitPlane, &args);
+ }
+ return fbCopyPlane(pSrcDrawable, pDstDrawable, pGC,
+ srcx, srcy, width, height,
+ dstx, dsty, bitPlane);
+}
+
+void
+sisFillSpans (DrawablePtr pDrawable, GCPtr pGC, int n,
+ DDXPointPtr ppt, int *pwidth, int fSorted)
+{
+ SetupSis(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 (!sisFillOk (pGC))
+ {
+ fbFillSpans (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:
+ _sisSetSolidRect(sis,pGC->fgPixel,pGC->alu,cmd);
+ break;
+ case FillTiled:
+ cmd = sisTilePrepare (pGC->tile.pixmap,
+ pGC->patOrg.x + pDrawable->x,
+ pGC->patOrg.y + pDrawable->y,
+ pGC->alu);
+ break;
+ default:
+ cmd = sisStipplePrepare (pDrawable, pGC);
+ break;
+ }
+ while (n--)
+ {
+ x = ppt->x;
+ y = ppt->y;
+ ppt++;
+ width = *pwidth++;
+ if (width)
+ {
+ _sisRect(sis,x,y,width,1,cmd);
+ }
+ }
+ _sisWaitIdleEmpty (sis);
+ DEALLOCATE_LOCAL(pptFree);
+ DEALLOCATE_LOCAL(pwidthFree);
+}
+
+#define NUM_STACK_RECTS 1024
+
+void
+sisPolyFillRect (DrawablePtr pDrawable, GCPtr pGC,
+ int nrectFill, xRectangle *prectInit)
+{
+ SetupSis(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 (!sisFillOk (pGC))
+ {
+ fbPolyFillRect (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)ALLOCATE_LOCAL(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:
+ sisFillBoxSolid(pDrawable,
+ pboxClipped-pboxClippedBase, pboxClippedBase,
+ pGC->fgPixel, pGC->alu);
+ break;
+ case FillTiled:
+ sisFillBoxTiled(pDrawable,
+ pboxClipped-pboxClippedBase, pboxClippedBase,
+ pGC->tile.pixmap,
+ pGC->patOrg.x + pDrawable->x,
+ pGC->patOrg.y + pDrawable->y,
+ pGC->alu);
+ break;
+ case FillStippled:
+ case FillOpaqueStippled:
+ sisFillBoxStipple (pDrawable, pGC,
+ pboxClipped-pboxClippedBase, pboxClippedBase);
+ break;
+ }
+ }
+ if (pboxClippedBase != stackRects)
+ DEALLOCATE_LOCAL(pboxClippedBase);
+}
+
+static const GCOps sisOps = {
+ sisFillSpans,
+ fbSetSpans,
+ fbPutImage,
+ sisCopyArea,
+ sisCopyPlane,
+ fbPolyPoint,
+ fbPolyLine,
+ fbPolySegment,
+ miPolyRectangle,
+ fbPolyArc,
+ miFillPolygon,
+ sisPolyFillRect,
+ fbPolyFillArc,
+ miPolyText8,
+ miPolyText16,
+ miImageText8,
+ miImageText16,
+ sisImageGlyphBlt,
+ sisPolyGlyphBlt,
+ fbPushPixels,
+#ifdef NEED_LINEHELPER
+ ,NULL
+#endif
+};
+
+void
+sisValidateGC (GCPtr pGC, Mask changes, DrawablePtr pDrawable)
+{
+ FbGCPrivPtr fbPriv = fbGetGCPrivate(pGC);
+
+ fbValidateGC (pGC, changes, pDrawable);
+
+ if (pDrawable->type == DRAWABLE_WINDOW)
+ pGC->ops = (GCOps *) &sisOps;
+ else
+ pGC->ops = (GCOps *) &fbGCOps;
+}
+
+GCFuncs sisGCFuncs = {
+ sisValidateGC,
+ miChangeGC,
+ miCopyGC,
+ miDestroyGC,
+ miChangeClip,
+ miDestroyClip,
+ miCopyClip
+};
+
+int
+sisCreateGC (GCPtr pGC)
+{
+ if (!fbCreateGC (pGC))
+ return FALSE;
+
+ if (pGC->depth != 1)
+ pGC->funcs = &sisGCFuncs;
+
+ return TRUE;
+}
+
+void
+sisCopyWindow(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, sisCopyNtoN, 0, 0);
+
+ REGION_UNINIT(pWin->drawable.pScreen, &rgnDst);
+}
+
+void
+sisPaintWindow(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;
+ case BackgroundPixmap:
+ pTile = pWin->background.pixmap;
+ if (sisPatternDimOk (pTile->drawable.width) &&
+ sisPatternDimOk (pTile->drawable.height))
+ {
+ sisFillBoxTiled ((DrawablePtr)pWin,
+ (int)REGION_NUM_RECTS(pRegion),
+ REGION_RECTS(pRegion),
+ pTile,
+ pWin->drawable.x, pWin->drawable.y, GXcopy);
+ return;
+ }
+ break;
+ case BackgroundPixel:
+ sisFillBoxSolid((DrawablePtr)pWin,
+ (int)REGION_NUM_RECTS(pRegion),
+ REGION_RECTS(pRegion),
+ pWin->background.pixel, GXcopy);
+ return;
+ }
+ break;
+ case PW_BORDER:
+ if (pWin->borderIsPixel)
+ {
+ sisFillBoxSolid((DrawablePtr)pWin,
+ (int)REGION_NUM_RECTS(pRegion),
+ REGION_RECTS(pRegion),
+ pWin->border.pixel, GXcopy);
+ return;
+ }
+ else
+ {
+ pTile = pWin->border.pixmap;
+ if (sisPatternDimOk (pTile->drawable.width) &&
+ sisPatternDimOk (pTile->drawable.height))
+ {
+ sisFillBoxTiled ((DrawablePtr)pWin,
+ (int)REGION_NUM_RECTS(pRegion),
+ REGION_RECTS(pRegion),
+ pTile,
+ pWin->drawable.x, pWin->drawable.y, GXcopy);
+ return;
+ }
+ }
+ break;
+ }
+ fbPaintWindow (pWin, pRegion, what);
+}
+
+Bool
+sisDrawInit (ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ sisScreenInfo(pScreenPriv);
+
+ /*
+ * Replace various fb screen functions
+ */
+ pScreen->CreateGC = sisCreateGC;
+ pScreen->CopyWindow = sisCopyWindow;
+ pScreen->PaintWindowBackground = sisPaintWindow;
+ pScreen->PaintWindowBorder = sisPaintWindow;
+
+ return TRUE;
+}
+
+void
+sisDrawEnable (ScreenPtr pScreen)
+{
+ SetupSis(pScreen);
+ sisScreenInfo(pScreenPriv);
+ CARD32 cmd;
+ CARD32 base;
+ CARD16 stride;
+
+ base = pScreenPriv->screen->frameBuffer - sisc->frameBuffer;
+ stride = pScreenPriv->screen->byteStride;
+ _sisWaitIdleEmpty(sis);
+ sis->u.general.dst_base = base;
+ sis->u.general.dst_pitch = stride;
+ sis->u.general.dst_height = pScreenPriv->screen->height;
+ _sisClip (sis, 0, 0,
+ pScreenPriv->screen->width, pScreenPriv->screen->height);
+ _sisSetSolidRect(sis, pScreen->blackPixel, GXcopy, cmd);
+ _sisRect (sis, 0, 0,
+ pScreenPriv->screen->width, pScreenPriv->screen->height,
+ cmd);
+ _sisWaitIdleEmpty (sis);
+}
+
+void
+sisDrawDisable (ScreenPtr pScreen)
+{
+}
+
+void
+sisDrawFini (ScreenPtr pScreen)
+{
+}