summaryrefslogtreecommitdiff
path: root/hw/kdrive/trident
diff options
context:
space:
mode:
Diffstat (limited to 'hw/kdrive/trident')
-rw-r--r--hw/kdrive/trident/Imakefile15
-rw-r--r--hw/kdrive/trident/trident.c279
-rw-r--r--hw/kdrive/trident/trident.h205
-rw-r--r--hw/kdrive/trident/tridentcurs.c414
-rw-r--r--hw/kdrive/trident/tridentdraw.c859
-rw-r--r--hw/kdrive/trident/tridentdraw.h63
-rw-r--r--hw/kdrive/trident/tridentstub.c54
7 files changed, 1889 insertions, 0 deletions
diff --git a/hw/kdrive/trident/Imakefile b/hw/kdrive/trident/Imakefile
new file mode 100644
index 000000000..f2456a214
--- /dev/null
+++ b/hw/kdrive/trident/Imakefile
@@ -0,0 +1,15 @@
+XCOMM $XConsortium: Imakefile /main/10 1996/12/02 10:20:33 lehors $
+XCOMM $XFree86: xc/programs/Xserver/hw/nvfb/Imakefile,v 3.8 1996/12/23 06:30:19 dawes Exp $
+#include <Server.tmpl>
+
+SRCS = trident.c tridentdraw.c tridentcurs.c tridentstub.c
+
+OBJS = trident.o tridentdraw.o tridentcurs.o tridentstub.o
+
+INCLUDES = -I.. -I../fbdev -I. -I$(XBUILDINCDIR) -I$(FONTINCSRC) \
+ -I../../../fb -I../../../mi -I../../../include -I../../../os \
+ -I$(EXTINCSRC) -I$(XINCLUDESRC)
+
+NormalLibraryObjectRule()
+NormalLibraryTarget(trident,$(OBJS))
+DependTarget()
diff --git a/hw/kdrive/trident/trident.c b/hw/kdrive/trident/trident.c
new file mode 100644
index 000000000..384800f78
--- /dev/null
+++ b/hw/kdrive/trident/trident.c
@@ -0,0 +1,279 @@
+/*
+ * $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 "trident.h"
+#define extern
+#include <asm/io.h>
+#undef extern
+
+#undef TRI_DEBUG
+
+Bool
+tridentCardInit (KdCardInfo *card)
+{
+ int k;
+ char *pixels;
+ TridentCardInfo *tridentc;
+
+ tridentc = (TridentCardInfo *) xalloc (sizeof (TridentCardInfo));
+ if (!tridentc)
+ return FALSE;
+
+ if (!fbdevInitialize (card, &tridentc->fb))
+ {
+ xfree (tridentc);
+ return FALSE;
+ }
+
+ iopl (3);
+ tridentc->cop_base = (CARD8 *) KdMapDevice (TRIDENT_COP_BASE,
+ TRIDENT_COP_SIZE);
+ tridentc->cop = (Cop *) (tridentc->cop_base + TRIDENT_COP_OFF);
+ card->driver = tridentc;
+
+ return TRUE;
+}
+
+Bool
+tridentScreenInit (KdScreenInfo *screen)
+{
+ TridentCardInfo *tridentc = screen->card->driver;
+ TridentScreenInfo *tridents;
+ int screen_size, memory;
+
+ tridents = (TridentScreenInfo *) xalloc (sizeof (TridentScreenInfo));
+ if (!tridents)
+ return FALSE;
+ memset (tridents, '\0', sizeof (TridentScreenInfo));
+ if (!fbdevScreenInit (screen))
+ {
+ xfree (tridents);
+ return FALSE;
+ }
+ if (!tridentc->cop)
+ screen->dumb = TRUE;
+ screen_size = screen->byteStride * screen->height;
+ memory = (2048 + 512) * 1024;
+ if (memory >= screen_size + 2048)
+ {
+ tridents->cursor_base = tridentc->fb.fb + memory - 2048;
+ }
+ else
+ tridents->cursor_base = 0;
+ screen->driver = tridents;
+ return TRUE;
+}
+
+CARD8
+tridentReadIndex (TridentCardInfo *tridentc, CARD16 port, CARD8 index)
+{
+ CARD8 value;
+
+ outb (index, port);
+ value = inb (port+1);
+ return value;
+}
+
+void
+tridentWriteIndex (TridentCardInfo *tridentc, CARD16 port, CARD8 index, CARD8 value)
+{
+ outb (index, port);
+ outb (value, port+1);
+}
+
+void
+tridentPause ()
+{
+ struct timeval tv;
+
+ tv.tv_sec = 0;
+ tv.tv_usec = 200 * 1000;
+ select (1, 0, 0, 0, &tv);
+}
+
+void
+tridentPreserve (KdCardInfo *card)
+{
+ TridentCardInfo *tridentc = card->driver;
+
+ fbdevPreserve (card);
+ tridentc->save.reg_3c4_0e = tridentReadIndex (tridentc, 0x3c4, 0x0e);
+ tridentc->save.reg_3d4_36 = tridentReadIndex (tridentc, 0x3d4, 0x36);
+ tridentc->save.reg_3d4_39 = tridentReadIndex (tridentc, 0x3d4, 0x39);
+ tridentc->save.reg_3d4_62 = tridentReadIndex (tridentc, 0x3d4, 0x62);
+ tridentc->save.reg_3ce_21 = tridentReadIndex (tridentc, 0x3ce, 0x21);
+#ifdef TRI_DEBUG
+ fprintf (stderr, "3c4 0e: %02x\n", tridentc->save.reg_3c4_0e);
+ fprintf (stderr, "3d4 36: %02x\n", tridentc->save.reg_3d4_36);
+ fprintf (stderr, "3d4 39: %02x\n", tridentc->save.reg_3d4_39);
+ fprintf (stderr, "3d4 62: %02x\n", tridentc->save.reg_3d4_62);
+ fprintf (stderr, "3ce 21: %02x\n", tridentc->save.reg_3ce_21);
+ fflush (stderr);
+#endif
+ tridentPause ();
+}
+
+void
+tridentSetMMIO (TridentCardInfo *tridentc)
+{
+ int tries;
+ CARD8 v;
+
+#ifdef TRI_DEBUG
+ fprintf (stderr, "Set MMIO\n");
+#endif
+ /* enable config port writes */
+ for (tries = 0; tries < 3; tries++)
+ {
+ /* enable direct read when GE busy, enable PCI retries */
+ tridentWriteIndex (tridentc, 0x3d4, 0x62,
+ tridentc->save.reg_3d4_62 | 0x70);
+ /* make sure the chip is in new mode */
+ tridentReadIndex (tridentc, 0x3c4, 0xb);
+ /* enable access to upper registers */
+ tridentWriteIndex (tridentc, 0x3c4, 0xe,
+ tridentc->save.reg_3c4_0e | 0x80);
+ v = tridentReadIndex (tridentc, 0x3c4, 0xe);
+ if (!(v & 0x80))
+ {
+ fprintf (stderr, "Trident GE not enabled 0x%x\n", v);
+ continue;
+ }
+ /* enable burst r/w, disable memory mapped ports */
+ tridentWriteIndex (tridentc, 0x3d4, 0x39, 0x6);
+ /* reset GE, enable GE, set GE to 0xbff00 */
+ tridentWriteIndex (tridentc, 0x3d4, 0x36, 0x92);
+ if (tridentc->cop->status != 0xffffffff)
+ break;
+ }
+#ifdef TRI_DEBUG
+ fprintf (stderr, "COP status 0x%x\n", tridentc->cop->status);
+#endif
+ if (tridentc->cop->status == 0xffffffff)
+ FatalError ("Trident COP not visible\n");
+}
+
+void
+tridentResetMMIO (TridentCardInfo *tridentc)
+{
+#ifdef TRI_DEBUG
+ fprintf (stderr, "Reset MMIO\n");
+#endif
+ tridentWriteIndex (tridentc, 0x3ce, 0x21, tridentc->save.reg_3ce_21);
+ tridentWriteIndex (tridentc, 0x3d4, 0x62, tridentc->save.reg_3d4_62);
+ tridentWriteIndex (tridentc, 0x3d4, 0x39, tridentc->save.reg_3d4_39);
+ tridentWriteIndex (tridentc, 0x3d4, 0x36, tridentc->save.reg_3d4_36);
+ tridentWriteIndex (tridentc, 0x3c4, 0x0e, tridentc->save.reg_3c4_0e);
+ tridentPause ();
+}
+
+void
+tridentEnable (ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ TridentCardInfo *tridentc = pScreenPriv->card->driver;
+
+ fbdevEnable (pScreen);
+ tridentSetMMIO (tridentc);
+}
+
+void
+tridentDisable (ScreenPtr pScreen)
+{
+ fbdevDisable (pScreen);
+}
+
+const CARD8 tridentDPMSModes[4] = {
+ 0x80, /* KD_DPMS_NORMAL */
+ 0x8c, /* KD_DPMS_STANDBY */
+ 0x8c, /* KD_DPMS_STANDBY */
+ 0x8c, /* KD_DPMS_STANDBY */
+/* 0xb0, /* KD_DPMS_SUSPEND */
+/* 0xbc, /* KD_DPMS_POWERDOWN */
+};
+
+Bool
+tridentDPMS (ScreenPtr pScreen, int mode)
+{
+ KdScreenPriv(pScreen);
+ TridentCardInfo *tridentc = pScreenPriv->card->driver;
+
+ tridentWriteIndex (tridentc, 0x3ce, 0x21, tridentDPMSModes[mode]);
+ return TRUE;
+}
+
+void
+tridentRestore (KdCardInfo *card)
+{
+ TridentCardInfo *tridentc = card->driver;
+
+ tridentResetMMIO (tridentc);
+ fbdevRestore (card);
+}
+
+void
+tridentScreenFini (KdScreenInfo *screen)
+{
+ TridentScreenInfo *tridents = (TridentScreenInfo *) screen->driver;
+
+ xfree (tridents);
+ screen->driver = 0;
+}
+
+void
+tridentCardFini (KdCardInfo *card)
+{
+ TridentCardInfo *tridentc = card->driver;
+
+ if (tridentc->cop_base)
+ KdUnmapDevice ((void *) tridentc->cop_base, TRIDENT_COP_SIZE);
+ fbdevCardFini (card);
+}
+
+KdCardFuncs tridentFuncs = {
+ tridentCardInit, /* cardinit */
+ tridentScreenInit, /* scrinit */
+ tridentPreserve, /* preserve */
+ tridentEnable, /* enable */
+ tridentDPMS, /* dpms */
+ tridentDisable, /* disable */
+ tridentRestore, /* restore */
+ tridentScreenFini, /* scrfini */
+ tridentCardFini, /* cardfini */
+
+ tridentCursorInit, /* initCursor */
+ tridentCursorEnable, /* enableCursor */
+ tridentCursorDisable, /* disableCursor */
+ tridentCursorFini, /* finiCursor */
+ tridentRecolorCursor, /* recolorCursor */
+
+ tridentDrawInit, /* initAccel */
+ tridentDrawEnable, /* enableAccel */
+ tridentDrawDisable, /* disableAccel */
+ tridentDrawFini, /* finiAccel */
+
+ fbdevGetColors, /* getColors */
+ fbdevPutColors, /* putColors */
+};
diff --git a/hw/kdrive/trident/trident.h b/hw/kdrive/trident/trident.h
new file mode 100644
index 000000000..f726e0701
--- /dev/null
+++ b/hw/kdrive/trident/trident.h
@@ -0,0 +1,205 @@
+/*
+ * $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: $ */
+
+#ifndef _TRIDENT_H_
+#define _TRIDENT_H_
+#include <fbdev.h>
+
+/*
+ * offset from ioport beginning
+ */
+#define TRIDENT_COP_BASE 0xbf000
+#define TRIDENT_COP_OFF 0x00f00
+#define TRIDENT_COP_SIZE (0x2000)
+
+typedef volatile CARD8 VOL8;
+typedef volatile CARD16 VOL16;
+typedef volatile CARD32 VOL32;
+
+typedef struct _cop {
+ VOL32 src_start_xy; /* 0x00 */
+ VOL32 src_end_xy; /* 0x04 */
+ VOL32 dst_start_xy; /* 0x08 */
+ VOL32 dst_end_xy; /* 0x0c */
+ VOL32 alpha; /* 0x10 */
+ CARD8 pad14[0xc]; /* 0x14 */
+ VOL32 multi; /* 0x20 */
+
+#define COP_MULTI_CLIP_TOP_LEFT 0x10000000
+#define COP_MULTI_DEPTH 0x40000000
+#define COP_MULTI_COLOR_KEY 0x70000000
+#define COP_MULTI_STYLE 0x50000000
+#define COP_MULTI_PATTERN 0x80000000
+#define COP_MULTI_ROP 0x90000000
+#define COP_MULTI_STRIDE 0x60000000
+#define COP_MULTI_Z 0xa0000000
+#define COP_MULTI_ALPHA 0xb0000000
+#define COP_MULTI_TEXTURE 0xd0000000
+#define COP_MULTI_TEXTURE_BOUND 0xe0000000
+#define COP_MULTI_TEXTURE_ADVANCED 0x20000000
+#define COP_MULTI_MASK 0xf0000000
+
+
+#define COP_DEPTH_8 0x00000000
+#define COP_DEPTH_16 0x00000001
+#define COP_DEPTH_24_32 0x00000002
+#define COP_DEPTH_15 0x00000005
+#define COP_DEPTH_DITHER_DISABLE 0x00000008
+
+ VOL32 command; /* 0x24 */
+#define COP_OP_NULL 0x00000000
+#define COP_OP_LINE 0x20000000
+#define COP_OP_BLT 0x80000000
+#define COP_OP_TEXT 0x90000000
+#define COP_OP_POLY 0xb0000000
+#define COP_OP_POLY2 0xe0000000
+#define COP_SCL_EXPAND 0x00800000
+#define COP_SCL_OPAQUE 0x00400000
+#define COP_SCL_REVERSE 0x00200000
+#define COP_SCL_MONO_OFF 0x001c0000
+#define COP_LIT_TEXTURE 0x00004000
+#define COP_BILINEAR 0x00002000
+#define COP_OP_ZBUF 0x00000800
+#define COP_OP_ROP 0x00000400
+#define COP_OP_FG 0x00000200
+#define COP_OP_FB 0x00000080
+#define COP_X_REVERSE 0x00000004
+#define COP_CLIP 0x00000001
+ VOL32 texture_format; /* 0x28 */
+ CARD8 pad2c[0x4]; /* 0x2c */
+
+ VOL32 clip_bottom_right; /* 0x30 */
+ VOL32 dataIII; /* 0x34 */
+ VOL32 dataIV; /* 0x38 */
+ CARD8 pad3c[0x8]; /* 0x3c */
+
+ VOL32 fg; /* 0x44 */
+ VOL32 bg; /* 0x48 */
+ CARD8 pad4c[0x4]; /* 0x4c */
+
+ VOL32 pattern_fg; /* 0x50 */
+ VOL32 pattern_bg; /* 0x54 */
+ CARD8 pad58[0xc]; /* 0x58 */
+
+ VOL32 status; /* 0x64 */
+#define COP_STATUS_BE_BUSY 0x80000000
+#define COP_STATUS_DPE_BUSY 0x20000000
+#define COP_STATUS_MI_BUSY 0x10000000
+#define COP_STATUS_FIFO_BUSY 0x08000000
+#define COP_STATUS_WB_BUSY 0x00800000
+#define COP_STATUS_Z_FAILED 0x00400000
+#define COP_STATUS_EFFECTIVE 0x00200000
+#define COP_STATUS_LEFT_VIEW 0x00080000
+
+ CARD8 pad68[0x4]; /* 0x68 */
+
+ VOL32 src_offset; /* 0x6c */
+ VOL32 z_offset; /* 0x70 */
+ CARD8 pad74[0x4]; /* 0x74 */
+
+ VOL32 display_offset; /* 0x78 */
+ VOL32 dst_offset; /* 0x7c */
+ CARD8 pad80[0x34]; /* 0x80 */
+
+ VOL32 semaphore; /* 0xb4 */
+} Cop;
+
+#define TRI_XY(x,y) ((y) << 16 | (x))
+
+typedef struct _tridentSave {
+ CARD8 reg_3c4_0e; /* config port value */
+ CARD8 reg_3d4_36;
+ CARD8 reg_3d4_39;
+ CARD8 reg_3d4_62; /* GE setup */
+ CARD8 reg_3ce_21; /* DPMS */
+} TridentSave;
+
+typedef struct _tridentCardInfo {
+ FbdevPriv fb;
+ CARD8 *cop_base;
+ Cop *cop;
+ CARD32 cop_depth;
+ CARD32 cop_stride;
+ TridentSave save;
+} TridentCardInfo;
+
+#define getTridentCardInfo(kd) ((TridentCardInfo *) ((kd)->card->driver))
+#define tridentCardInfo(kd) TridentCardInfo *tridentc = getTridentCardInfo(kd)
+
+typedef struct _tridentCursor {
+ int width, height;
+ int xhot, yhot;
+ Bool has_cursor;
+ CursorPtr pCursor;
+ Pixel source, mask;
+} TridentCursor;
+
+#define TRIDENT_CURSOR_WIDTH 64
+#define TRIDENT_CURSOR_HEIGHT 64
+
+typedef struct _tridentScreenInfo {
+ CARD8 *cursor_base;
+ TridentCursor cursor;
+} TridentScreenInfo;
+
+#define getTridentScreenInfo(kd) ((TridentScreenInfo *) ((kd)->screen->driver))
+#define tridentScreenInfo(kd) TridentScreenInfo *tridents = getTridentScreenInfo(kd)
+
+Bool
+tridentDrawInit (ScreenPtr pScreen);
+
+void
+tridentDrawEnable (ScreenPtr pScreen);
+
+void
+tridentDrawDisable (ScreenPtr pScreen);
+
+void
+tridentDrawFini (ScreenPtr pScreen);
+
+CARD8
+tridentReadIndex (TridentCardInfo *tridentc, CARD16 port, CARD8 index);
+
+void
+tridentWriteIndex (TridentCardInfo *tridentc, CARD16 port, CARD8 index, CARD8 value);
+
+Bool
+tridentCursorInit (ScreenPtr pScreen);
+
+void
+tridentCursorEnable (ScreenPtr pScreen);
+
+void
+tridentCursorDisable (ScreenPtr pScreen);
+
+void
+tridentCursorFini (ScreenPtr pScreen);
+
+void
+tridentRecolorCursor (ScreenPtr pScreen, int ndef, xColorItem *pdef);
+
+extern KdCardFuncs tridentFuncs;
+
+#endif /* _TRIDENT_H_ */
diff --git a/hw/kdrive/trident/tridentcurs.c b/hw/kdrive/trident/tridentcurs.c
new file mode 100644
index 000000000..9c4ebb5d0
--- /dev/null
+++ b/hw/kdrive/trident/tridentcurs.c
@@ -0,0 +1,414 @@
+/*
+ * $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 "trident.h"
+#include "cursorstr.h"
+
+#define SetupCursor(s) KdScreenPriv(s); \
+ tridentCardInfo(pScreenPriv); \
+ tridentScreenInfo(pScreenPriv); \
+ TridentCursor *pCurPriv = &tridents->cursor
+
+static void
+_tridentMoveCursor (ScreenPtr pScreen, int x, int y)
+{
+ SetupCursor(pScreen);
+ CARD8 xlow, xhigh, ylow, yhigh;
+ CARD8 xoff, yoff;
+
+ x -= pCurPriv->xhot;
+ xoff = 0;
+ if (x < 0)
+ {
+ xoff = -x;
+ x = 0;
+ }
+ y -= pCurPriv->yhot;
+ yoff = 0;
+ if (y < 0)
+ {
+ yoff = -y;
+ y = 0;
+ }
+ xlow = (CARD8) x;
+ xhigh = (CARD8) (x >> 8);
+ ylow = (CARD8) y;
+ yhigh = (CARD8) (y >> 8);
+
+
+ /* This is the recommended order to move the cursor */
+
+ tridentWriteIndex (tridentc, 0x3d4, 0x41, xhigh);
+ tridentWriteIndex (tridentc, 0x3d4, 0x40, xlow);
+ tridentWriteIndex (tridentc, 0x3d4, 0x42, ylow);
+ tridentWriteIndex (tridentc, 0x3d4, 0x46, xoff);
+ tridentWriteIndex (tridentc, 0x3d4, 0x47, yoff);
+ tridentWriteIndex (tridentc, 0x3d4, 0x43, yhigh);
+}
+
+static void
+tridentMoveCursor (ScreenPtr pScreen, int x, int y)
+{
+ SetupCursor (pScreen);
+
+ if (!pCurPriv->has_cursor)
+ return;
+
+ if (!pScreenPriv->enabled)
+ return;
+
+ _tridentMoveCursor (pScreen, x, y);
+}
+
+
+static void
+tridentAllocCursorColors (ScreenPtr pScreen)
+{
+ SetupCursor (pScreen);
+ CursorPtr pCursor = pCurPriv->pCursor;
+ xColorItem sourceColor, maskColor;
+
+ /*
+ * Set these to an invalid pixel value so that
+ * when the store colors comes through, the cursor
+ * won't get recolored
+ */
+ pCurPriv->source = ~0;
+ pCurPriv->mask = ~0;
+ /*
+ * XXX S3 bug workaround; s3 chip doesn't use RGB values from
+ * the cursor color registers as documented, rather it uses
+ * them to index the DAC. This is in the errata though.
+ */
+ sourceColor.red = pCursor->foreRed;
+ sourceColor.green = pCursor->foreGreen;
+ sourceColor.blue = pCursor->foreBlue;
+ FakeAllocColor(pScreenPriv->pInstalledmap, &sourceColor);
+ maskColor.red = pCursor->backRed;
+ maskColor.green = pCursor->backGreen;
+ maskColor.blue = pCursor->backBlue;
+ FakeAllocColor(pScreenPriv->pInstalledmap, &maskColor);
+ FakeFreeColor(pScreenPriv->pInstalledmap, sourceColor.pixel);
+ FakeFreeColor(pScreenPriv->pInstalledmap, maskColor.pixel);
+
+ pCurPriv->source = sourceColor.pixel;
+ pCurPriv->mask = maskColor.pixel;
+ switch (pScreenPriv->screen->bitsPerPixel) {
+ case 4:
+ pCurPriv->source |= pCurPriv->source << 4;
+ pCurPriv->mask |= pCurPriv->mask << 4;
+ case 8:
+ pCurPriv->source |= pCurPriv->source << 8;
+ pCurPriv->mask |= pCurPriv->mask << 8;
+ case 16:
+ pCurPriv->source |= pCurPriv->source << 16;
+ pCurPriv->mask |= pCurPriv->mask << 16;
+ }
+}
+
+static void
+tridentSetCursorColors (ScreenPtr pScreen)
+{
+ SetupCursor (pScreen);
+ CursorPtr pCursor = pCurPriv->pCursor;
+ CARD32 fg, bg;
+
+ fg = pCurPriv->source;
+ bg = pCurPriv->mask;
+ tridentWriteIndex (tridentc, 0x3d4, 0x48, fg);
+ tridentWriteIndex (tridentc, 0x3d4, 0x49, fg >> 8);
+ tridentWriteIndex (tridentc, 0x3d4, 0x4a, fg >> 16);
+
+ tridentWriteIndex (tridentc, 0x3d4, 0x4c, bg);
+ tridentWriteIndex (tridentc, 0x3d4, 0x4d, bg >> 8);
+ tridentWriteIndex (tridentc, 0x3d4, 0x4e, bg >> 16);
+}
+
+void
+tridentRecolorCursor (ScreenPtr pScreen, int ndef, xColorItem *pdef)
+{
+ SetupCursor (pScreen);
+ CursorPtr pCursor = pCurPriv->pCursor;
+ xColorItem sourceColor, maskColor;
+
+ if (!pCurPriv->has_cursor || !pCursor)
+ return;
+
+ if (!pScreenPriv->enabled)
+ return;
+
+ if (pdef)
+ {
+ while (ndef)
+ {
+ if (pdef->pixel == pCurPriv->source ||
+ pdef->pixel == pCurPriv->mask)
+ break;
+ ndef--;
+ }
+ if (!ndef)
+ return;
+ }
+ tridentAllocCursorColors (pScreen);
+ tridentSetCursorColors (pScreen);
+}
+
+#define InvertBits32(v) { \
+ v = ((v & 0x55555555) << 1) | ((v >> 1) & 0x55555555); \
+ v = ((v & 0x33333333) << 2) | ((v >> 2) & 0x33333333); \
+ v = ((v & 0x0f0f0f0f) << 4) | ((v >> 4) & 0x0f0f0f0f); \
+}
+
+static void
+tridentLoadCursor (ScreenPtr pScreen, int x, int y)
+{
+ SetupCursor(pScreen);
+ CursorPtr pCursor = pCurPriv->pCursor;
+ CursorBitsPtr bits = pCursor->bits;
+ int w, h;
+ CARD32 *ram, *msk, *mskLine, *src, *srcLine;
+ int i, j;
+ int cursor_address;
+ int lwsrc;
+ unsigned char ramdac_control_;
+ CARD32 offset;
+
+ /*
+ * Allocate new colors
+ */
+ tridentAllocCursorColors (pScreen);
+
+ pCurPriv->pCursor = pCursor;
+ pCurPriv->xhot = pCursor->bits->xhot;
+ pCurPriv->yhot = pCursor->bits->yhot;
+
+ /*
+ * Stick new image into cursor memory
+ */
+ ram = (CARD32 *) tridents->cursor_base;
+ mskLine = (CARD32 *) bits->mask;
+ srcLine = (CARD32 *) bits->source;
+
+ h = bits->height;
+ if (h > TRIDENT_CURSOR_HEIGHT)
+ h = TRIDENT_CURSOR_HEIGHT;
+
+ lwsrc = BitmapBytePad(bits->width) / 4; /* words per line */
+
+ for (i = 0; i < TRIDENT_CURSOR_HEIGHT; i++) {
+ msk = mskLine;
+ src = srcLine;
+ mskLine += lwsrc;
+ srcLine += lwsrc;
+ for (j = 0; j < TRIDENT_CURSOR_WIDTH / 32; j++) {
+
+ CARD32 m, s;
+
+#if 1
+ if (i < h && j < lwsrc)
+ {
+ m = *msk++;
+ s = *src++;
+ InvertBits32(m);
+ InvertBits32(s);
+ }
+ else
+ {
+ m = 0;
+ s = 0;
+ }
+#endif
+ *ram++ = m;
+ *ram++ = s;
+ }
+ }
+
+ /* Set address for cursor bits */
+ offset = tridents->cursor_base - (CARD8 *) tridentc->fb.fb;
+ offset >>= 10;
+ tridentWriteIndex (tridentc, 0x3d4, 0x44, (CARD8) (offset & 0xff));
+ tridentWriteIndex (tridentc, 0x3d4, 0x45, (CARD8) (offset >> 8));
+
+ /* Set new color */
+ tridentSetCursorColors (pScreen);
+
+ /* Enable the cursor */
+ tridentWriteIndex (tridentc, 0x3d4, 0x50, 0xc1);
+
+ /* Move to new position */
+ tridentMoveCursor (pScreen, x, y);
+}
+
+static void
+tridentUnloadCursor (ScreenPtr pScreen)
+{
+ SetupCursor (pScreen);
+
+ /* Disable cursor */
+ tridentWriteIndex (tridentc, 0x3d4, 0x50, 0);
+}
+
+static Bool
+tridentRealizeCursor (ScreenPtr pScreen, CursorPtr pCursor)
+{
+ SetupCursor(pScreen);
+
+ if (!pScreenPriv->enabled)
+ return TRUE;
+
+ /* miRecolorCursor does this */
+ if (pCurPriv->pCursor == pCursor)
+ {
+ if (pCursor)
+ {
+ int x, y;
+
+ miPointerPosition (&x, &y);
+ tridentLoadCursor (pScreen, x, y);
+ }
+ }
+ return TRUE;
+}
+
+static Bool
+tridentUnrealizeCursor (ScreenPtr pScreen, CursorPtr pCursor)
+{
+ return TRUE;
+}
+
+static void
+tridentSetCursor (ScreenPtr pScreen, CursorPtr pCursor, int x, int y)
+{
+ SetupCursor(pScreen);
+
+ pCurPriv->pCursor = pCursor;
+
+ if (!pScreenPriv->enabled)
+ return;
+
+ if (pCursor)
+ tridentLoadCursor (pScreen, x, y);
+ else
+ tridentUnloadCursor (pScreen);
+}
+
+miPointerSpriteFuncRec tridentPointerSpriteFuncs = {
+ tridentRealizeCursor,
+ tridentUnrealizeCursor,
+ tridentSetCursor,
+ tridentMoveCursor,
+};
+
+static void
+tridentQueryBestSize (int class,
+ unsigned short *pwidth, unsigned short *pheight,
+ ScreenPtr pScreen)
+{
+ SetupCursor (pScreen);
+
+ switch (class)
+ {
+ case CursorShape:
+ if (*pwidth > pCurPriv->width)
+ *pwidth = pCurPriv->width;
+ if (*pheight > pCurPriv->height)
+ *pheight = pCurPriv->height;
+ if (*pwidth > pScreen->width)
+ *pwidth = pScreen->width;
+ if (*pheight > pScreen->height)
+ *pheight = pScreen->height;
+ break;
+ default:
+ fbQueryBestSize (class, pwidth, pheight, pScreen);
+ break;
+ }
+}
+
+Bool
+tridentCursorInit (ScreenPtr pScreen)
+{
+ SetupCursor (pScreen);
+
+ if (!tridents->cursor_base)
+ {
+ pCurPriv->has_cursor = FALSE;
+ return FALSE;
+ }
+
+ pCurPriv->width = TRIDENT_CURSOR_WIDTH;
+ pCurPriv->height= TRIDENT_CURSOR_HEIGHT;
+ pScreen->QueryBestSize = tridentQueryBestSize;
+ miPointerInitialize (pScreen,
+ &tridentPointerSpriteFuncs,
+ &kdPointerScreenFuncs,
+ FALSE);
+ pCurPriv->has_cursor = TRUE;
+ pCurPriv->pCursor = NULL;
+ return TRUE;
+}
+
+void
+tridentCursorEnable (ScreenPtr pScreen)
+{
+ SetupCursor (pScreen);
+
+ if (pCurPriv->has_cursor)
+ {
+ if (pCurPriv->pCursor)
+ {
+ int x, y;
+
+ miPointerPosition (&x, &y);
+ tridentLoadCursor (pScreen, x, y);
+ }
+ else
+ tridentUnloadCursor (pScreen);
+ }
+}
+
+void
+tridentCursorDisable (ScreenPtr pScreen)
+{
+ SetupCursor (pScreen);
+
+ if (!pScreenPriv->enabled)
+ return;
+
+ if (pCurPriv->has_cursor)
+ {
+ if (pCurPriv->pCursor)
+ {
+ tridentUnloadCursor (pScreen);
+ }
+ }
+}
+
+void
+tridentCursorFini (ScreenPtr pScreen)
+{
+ SetupCursor (pScreen);
+
+ pCurPriv->pCursor = NULL;
+}
diff --git a/hw/kdrive/trident/tridentdraw.c b/hw/kdrive/trident/tridentdraw.c
new file mode 100644
index 000000000..f64444c53
--- /dev/null
+++ b/hw/kdrive/trident/tridentdraw.c
@@ -0,0 +1,859 @@
+/*
+ * $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 "trident.h"
+#include "tridentdraw.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 tridentRop[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 */
+};
+
+#define tridentFillPix(bpp,pixel) {\
+ if (bpp == 8) \
+ { \
+ pixel = pixel & 0xff; \
+ pixel = pixel | pixel << 8; \
+ } \
+ if (bpp <= 16) \
+ { \
+ pixel = pixel & 0xffff; \
+ pixel = pixel | pixel << 16; \
+ } \
+}
+void
+tridentFillBoxSolid (DrawablePtr pDrawable, int nBox, BoxPtr pBox,
+ unsigned long pixel, int alu)
+{
+ SetupTrident(pDrawable->pScreen);
+ CARD32 cmd;
+
+ tridentFillPix(pDrawable->bitsPerPixel,pixel);
+ _tridentInit(cop,tridentc);
+ _tridentSetSolidRect(cop,pixel,alu,cmd);
+ while (nBox--)
+ {
+ _tridentRect(cop,pBox->x1,pBox->y1,pBox->x2-1,pBox->y2-1,cmd);
+ pBox++;
+ }
+ _tridentWaitIdleEmpty(cop);
+}
+
+void
+tridentCopyNtoN (DrawablePtr pSrcDrawable,
+ DrawablePtr pDstDrawable,
+ GCPtr pGC,
+ BoxPtr pbox,
+ int nbox,
+ int dx,
+ int dy,
+ Bool reverse,
+ Bool upsidedown,
+ Pixel bitplane,
+ void *closure)
+{
+ SetupTrident(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))
+ {
+ tridentFillBoxSolid (pDstDrawable, nbox, pbox, 0, pGC->alu);
+ return;
+ }
+ }
+ else
+ alu = GXcopy;
+
+ _tridentInit(cop,tridentc);
+ cop->multi = COP_MULTI_PATTERN;
+ cop->multi = COP_MULTI_ROP | tridentRop[alu];
+ if (reverse)
+ upsidedown = TRUE;
+ cmd = COP_OP_BLT | COP_SCL_OPAQUE | COP_OP_ROP | COP_OP_FB;
+ if (upsidedown)
+ cmd |= COP_X_REVERSE;
+ while (nbox--)
+ {
+ if (upsidedown)
+ {
+ cop->src_start_xy = TRI_XY (pbox->x2 + dx - 1,
+ pbox->y2 + dy - 1);
+ cop->src_end_xy = TRI_XY (pbox->x1 + dx,
+ pbox->y1 + dy);
+ cop->dst_start_xy = TRI_XY (pbox->x2 - 1,
+ pbox->y2 - 1);
+ cop->dst_end_xy = TRI_XY (pbox->x1,
+ pbox->y1);
+ }
+ else
+ {
+ cop->src_start_xy = TRI_XY (pbox->x1 + dx,
+ pbox->y1 + dy);
+ cop->src_end_xy = TRI_XY (pbox->x2 + dx - 1,
+ pbox->y2 + dy - 1);
+ cop->dst_start_xy = TRI_XY (pbox->x1,
+ pbox->y1);
+ cop->dst_end_xy = TRI_XY (pbox->x2 - 1,
+ pbox->y2 - 1);
+ }
+ cop->command = cmd;
+ pbox++;
+ }
+ _tridentWaitIdleEmpty(cop);
+}
+
+RegionPtr
+tridentCopyArea(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, tridentCopyNtoN, 0, 0);
+ }
+ return fbCopyArea (pSrcDrawable, pDstDrawable, pGC,
+ srcx, srcy, width, height, dstx, dsty);
+}
+
+BOOL
+tridentFillOk (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 (tridentPatternDimOk (pGC->tile.pixmap->drawable.width) &&
+ tridentPatternDimOk (pGC->tile.pixmap->drawable.height));
+ case FillStippled:
+ case FillOpaqueStippled:
+ return (tridentPatternDimOk (pGC->stipple->drawable.width) &&
+ tridentPatternDimOk (pGC->stipple->drawable.height));
+#endif
+ }
+ return FALSE;
+}
+
+void
+tridentFillSpans (DrawablePtr pDrawable, GCPtr pGC, int n,
+ DDXPointPtr ppt, int *pwidth, int fSorted)
+{
+ SetupTrident(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;
+ CARD32 pixel;
+
+ if (!tridentFillOk (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;
+ _tridentInit(cop,tridentc);
+ switch (pGC->fillStyle) {
+ case FillSolid:
+ pixel = pGC->fgPixel;
+ tridentFillPix (pDrawable->bitsPerPixel,pixel);
+ _tridentSetSolidRect(cop,pixel,pGC->alu,cmd);
+ break;
+#if 0
+ case FillTiled:
+ cmd = tridentTilePrepare (pGC->tile.pixmap,
+ pGC->patOrg.x + pDrawable->x,
+ pGC->patOrg.y + pDrawable->y,
+ pGC->alu);
+ break;
+ default:
+ cmd = tridentStipplePrepare (pDrawable, pGC);
+ break;
+#endif
+ }
+ while (n--)
+ {
+ x = ppt->x;
+ y = ppt->y;
+ ppt++;
+ width = *pwidth++;
+ if (width)
+ {
+ _tridentRect(cop,x,y,x + width,y,cmd);
+ }
+ }
+ _tridentWaitIdleEmpty (cop);
+ DEALLOCATE_LOCAL(pptFree);
+ DEALLOCATE_LOCAL(pwidthFree);
+}
+
+#define NUM_STACK_RECTS 1024
+
+void
+tridentPolyFillRect (DrawablePtr pDrawable, GCPtr pGC,
+ int nrectFill, xRectangle *prectInit)
+{
+ SetupTrident(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 (!tridentFillOk (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)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:
+ tridentFillBoxSolid(pDrawable,
+ pboxClipped-pboxClippedBase, pboxClippedBase,
+ pGC->fgPixel, pGC->alu);
+ break;
+#if 0
+ case FillTiled:
+ tridentFillBoxTiled(pDrawable,
+ pboxClipped-pboxClippedBase, pboxClippedBase,
+ pGC->tile.pixmap,
+ pGC->patOrg.x + pDrawable->x,
+ pGC->patOrg.y + pDrawable->y,
+ pGC->alu);
+ break;
+ case FillStippled:
+ case FillOpaqueStippled:
+ tridentFillBoxStipple (pDrawable, pGC,
+ pboxClipped-pboxClippedBase, pboxClippedBase);
+ break;
+#endif
+ }
+ }
+ if (pboxClippedBase != stackRects)
+ xfree(pboxClippedBase);
+}
+
+void
+tridentSolidBoxClipped (DrawablePtr pDrawable,
+ RegionPtr pClip,
+ int x1,
+ int y1,
+ int x2,
+ int y2,
+ FbBits fg)
+{
+ SetupTrident (pDrawable->pScreen);
+ BoxPtr pbox;
+ int nbox;
+ int partX1, partX2, partY1, partY2;
+ CARD32 cmd;
+
+ _tridentInit (cop, tridentc);
+ _tridentSetSolidRect (cop, fg, GXcopy, cmd);
+
+ for (nbox = REGION_NUM_RECTS(pClip), pbox = REGION_RECTS(pClip);
+ nbox--;
+ pbox++)
+ {
+ partX1 = pbox->x1;
+ if (partX1 < x1)
+ partX1 = x1;
+
+ partX2 = pbox->x2;
+ if (partX2 > x2)
+ partX2 = x2;
+
+ if (partX2 <= partX1)
+ continue;
+
+ partY1 = pbox->y1;
+ if (partY1 < y1)
+ partY1 = y1;
+
+ partY2 = pbox->y2;
+ if (partY2 > y2)
+ partY2 = y2;
+
+ if (partY2 <= partY1)
+ continue;
+
+ _tridentRect(cop,partX1, partY1, partX2-1, partY2-1,cmd);
+ }
+ _tridentWaitIdleEmpty(cop);
+}
+
+void
+tridentImageGlyphBlt (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ unsigned int nglyph,
+ CharInfoPtr *ppciInit,
+ pointer pglyphBase)
+{
+ FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
+ CharInfoPtr *ppci;
+ CharInfoPtr pci;
+ unsigned char *pglyph; /* pointer bits in glyph */
+ int gWidth, gHeight; /* width and height of glyph */
+ FbStride gStride; /* stride of glyph */
+ Bool opaque;
+ int n;
+ int gx, gy;
+ void (*glyph) (FbBits *,
+ FbStride,
+ int,
+ FbStip *,
+ FbBits,
+ int,
+ int);
+ FbBits *dst;
+ FbStride dstStride;
+ int dstBpp;
+ FbBits depthMask;
+
+ depthMask = FbFullMask(pDrawable->depth);
+ if ((pGC->planemask & depthMask) != depthMask)
+ {
+ fbImageGlyphBlt(pDrawable, pGC, x, y, nglyph, ppciInit, pglyphBase);
+ return;
+ }
+ glyph = 0;
+ fbGetDrawable (pDrawable, dst, dstStride, dstBpp);
+ switch (dstBpp) {
+ case 8: glyph = fbGlyph8; break;
+ case 16: glyph = fbGlyph16; break;
+ case 24: glyph = fbGlyph24; break;
+ case 32: glyph = fbGlyph32; break;
+ }
+
+ x += pDrawable->x;
+ y += pDrawable->y;
+
+ if (TERMINALFONT (pGC->font) && !glyph)
+ {
+ opaque = TRUE;
+ }
+ else
+ {
+ int xBack, widthBack;
+ int yBack, heightBack;
+
+ ppci = ppciInit;
+ n = nglyph;
+ widthBack = 0;
+ while (n--)
+ widthBack += (*ppci++)->metrics.characterWidth;
+
+ xBack = x;
+ if (widthBack < 0)
+ {
+ xBack += widthBack;
+ widthBack = -widthBack;
+ }
+ yBack = y - FONTASCENT(pGC->font);
+ heightBack = FONTASCENT(pGC->font) + FONTDESCENT(pGC->font);
+ tridentSolidBoxClipped (pDrawable,
+ fbGetCompositeClip(pGC),
+ xBack,
+ yBack,
+ xBack + widthBack,
+ yBack + heightBack,
+ pPriv->bg);
+ opaque = FALSE;
+ }
+
+ ppci = ppciInit;
+ while (nglyph--)
+ {
+ pci = *ppci++;
+ pglyph = FONTGLYPHBITS(pglyphBase, pci);
+ gWidth = GLYPHWIDTHPIXELS(pci);
+ gHeight = GLYPHHEIGHTPIXELS(pci);
+ if (gWidth && gHeight)
+ {
+ gx = x + pci->metrics.leftSideBearing;
+ gy = y - pci->metrics.ascent;
+ if (glyph && gWidth <= sizeof (FbStip) * 8 &&
+ fbGlyphIn (fbGetCompositeClip(pGC), gx, gy, gWidth, gHeight))
+ {
+ (*glyph) (dst + gy * dstStride,
+ dstStride,
+ dstBpp,
+ (FbStip *) pglyph,
+ pPriv->fg,
+ gx,
+ gHeight);
+ }
+ else
+ {
+ gStride = GLYPHWIDTHBYTESPADDED(pci) / sizeof (FbStip);
+ fbPutXYImage (pDrawable,
+ fbGetCompositeClip(pGC),
+ pPriv->fg,
+ pPriv->bg,
+ pPriv->pm,
+ GXcopy,
+ opaque,
+
+ gx,
+ gy,
+ gWidth, gHeight,
+
+ (FbStip *) pglyph,
+ gStride,
+ 0);
+ }
+ }
+ x += pci->metrics.characterWidth;
+ }
+}
+
+static const GCOps tridentOps = {
+ tridentFillSpans,
+ fbSetSpans,
+ fbPutImage,
+ tridentCopyArea,
+ fbCopyPlane,
+ fbPolyPoint,
+ fbPolyLine,
+ fbPolySegment,
+ miPolyRectangle,
+ fbPolyArc,
+ miFillPolygon,
+ tridentPolyFillRect,
+ fbPolyFillArc,
+ miPolyText8,
+ miPolyText16,
+ miImageText8,
+ miImageText16,
+ tridentImageGlyphBlt,
+ fbPolyGlyphBlt,
+ fbPushPixels,
+#ifdef NEED_LINEHELPER
+ ,NULL
+#endif
+};
+
+void
+tridentValidateGC (GCPtr pGC, Mask changes, DrawablePtr pDrawable)
+{
+ FbGCPrivPtr fbPriv = fbGetGCPrivate(pGC);
+
+ fbValidateGC (pGC, changes, pDrawable);
+
+ if (pDrawable->type == DRAWABLE_WINDOW)
+ pGC->ops = (GCOps *) &tridentOps;
+ else
+ pGC->ops = (GCOps *) &fbGCOps;
+}
+
+GCFuncs tridentGCFuncs = {
+ tridentValidateGC,
+ miChangeGC,
+ miCopyGC,
+ miDestroyGC,
+ miChangeClip,
+ miDestroyClip,
+ miCopyClip
+};
+
+int
+tridentCreateGC (GCPtr pGC)
+{
+ if (!fbCreateGC (pGC))
+ return FALSE;
+
+ if (pGC->depth != 1)
+ pGC->funcs = &tridentGCFuncs;
+
+ return TRUE;
+}
+
+void
+tridentCopyWindow(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, tridentCopyNtoN, 0, 0);
+
+ REGION_UNINIT(pWin->drawable.pScreen, &rgnDst);
+}
+
+void
+tridentPaintWindow(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 (tridentPatternDimOk (pTile->drawable.width) &&
+ tridentPatternDimOk (pTile->drawable.height))
+ {
+ tridentFillBoxTiled ((DrawablePtr)pWin,
+ (int)REGION_NUM_RECTS(pRegion),
+ REGION_RECTS(pRegion),
+ pTile,
+ pWin->drawable.x, pWin->drawable.y, GXcopy);
+ return;
+ }
+ break;
+#endif
+ case BackgroundPixel:
+ tridentFillBoxSolid((DrawablePtr)pWin,
+ (int)REGION_NUM_RECTS(pRegion),
+ REGION_RECTS(pRegion),
+ pWin->background.pixel, GXcopy);
+ return;
+ }
+ break;
+ case PW_BORDER:
+ if (pWin->borderIsPixel)
+ {
+ tridentFillBoxSolid((DrawablePtr)pWin,
+ (int)REGION_NUM_RECTS(pRegion),
+ REGION_RECTS(pRegion),
+ pWin->border.pixel, GXcopy);
+ return;
+ }
+#if 0
+ else
+ {
+ pTile = pWin->border.pixmap;
+ if (tridentPatternDimOk (pTile->drawable.width) &&
+ tridentPatternDimOk (pTile->drawable.height))
+ {
+ tridentFillBoxTiled ((DrawablePtr)pWin,
+ (int)REGION_NUM_RECTS(pRegion),
+ REGION_RECTS(pRegion),
+ pTile,
+ pWin->drawable.x, pWin->drawable.y, GXcopy);
+ return;
+ }
+ }
+#endif
+ break;
+ }
+ fbPaintWindow (pWin, pRegion, what);
+}
+
+Bool
+tridentDrawInit (ScreenPtr pScreen)
+{
+ /*
+ * Replace various fb screen functions
+ */
+ pScreen->CreateGC = tridentCreateGC;
+ pScreen->CopyWindow = tridentCopyWindow;
+ pScreen->PaintWindowBackground = tridentPaintWindow;
+ pScreen->PaintWindowBorder = tridentPaintWindow;
+
+ return TRUE;
+}
+
+void
+tridentDrawEnable (ScreenPtr pScreen)
+{
+ SetupTrident(pScreen);
+ CARD32 cmd;
+ CARD32 base;
+ CARD16 stride;
+ CARD32 format;
+ int tries;
+
+ stride = pScreenPriv->screen->pixelStride;
+ switch (pScreenPriv->screen->bitsPerPixel) {
+ case 8:
+ format = COP_DEPTH_8;
+ break;
+ case 16:
+ format = COP_DEPTH_16;
+ break;
+ case 24:
+ format = COP_DEPTH_24_32;
+ break;
+ case 32:
+ format = COP_DEPTH_24_32;
+ break;
+ }
+ /*
+ * compute a few things which will be set every time the
+ * accelerator is used; this avoids problems with APM
+ */
+ tridentc->cop_depth = COP_MULTI_DEPTH | format;
+ tridentc->cop_stride = COP_MULTI_STRIDE | (stride << 16) | (stride);
+
+#define NUM_TRIES 100000
+ for (tries = 0; tries < NUM_TRIES; tries++)
+ if (!(cop->status & COP_STATUS_BUSY))
+ break;
+ if (cop->status & COP_STATUS_BUSY)
+ FatalError ("Can't initialize graphics coprocessor");
+ cop->multi = COP_MULTI_CLIP_TOP_LEFT;
+ cop->multi = COP_MULTI_MASK | 0;
+ cop->src_offset = 0;
+ cop->dst_offset = 0;
+ cop->z_offset = 0;
+ cop->clip_bottom_right = 0x0fff0fff;
+
+ _tridentInit(cop,tridentc);
+ _tridentSetSolidRect(cop, pScreen->blackPixel, GXcopy, cmd);
+ _tridentRect (cop, 0, 0,
+ pScreenPriv->screen->width, pScreenPriv->screen->height,
+ cmd);
+ _tridentWaitIdleEmpty (cop);
+}
+
+void
+tridentDrawDisable (ScreenPtr pScreen)
+{
+}
+
+void
+tridentDrawFini (ScreenPtr pScreen)
+{
+}
diff --git a/hw/kdrive/trident/tridentdraw.h b/hw/kdrive/trident/tridentdraw.h
new file mode 100644
index 000000000..5fa64d2a7
--- /dev/null
+++ b/hw/kdrive/trident/tridentdraw.h
@@ -0,0 +1,63 @@
+/*
+ * $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: $ */
+
+#ifndef _TRIDENTDRAW_H_
+#define _TRIDENTDRAW_H_
+
+#define SetupTrident(s) KdScreenPriv(s); \
+ tridentCardInfo(pScreenPriv); \
+ Cop *cop = tridentc->cop
+
+#define _tridentInit(cop,tridentc) { \
+ if ((cop)->status == 0xffffffff) tridentSetMMIO(tridentc); \
+ (cop)->multi = (tridentc)->cop_depth; \
+ (cop)->multi = (tridentc)->cop_stride; \
+} \
+
+#define _tridentSetSolidRect(cop,pix,alu,cmd) {\
+ cop->multi = COP_MULTI_PATTERN; \
+ cop->multi = COP_MULTI_ROP | tridentRop[alu]; \
+ cop->fg = (pix); \
+ cmd = COP_OP_BLT | COP_SCL_OPAQUE | COP_OP_ROP | COP_OP_FG; \
+}
+
+#define _tridentRect(cop,x1,y1,x2,y2,cmd) { \
+ (cop)->dst_start_xy = TRI_XY (x1,y1); \
+ (cop)->dst_end_xy = TRI_XY(x2,y2); \
+ (cop)->command = (cmd); \
+}
+
+#define COP_STATUS_BUSY (COP_STATUS_BE_BUSY | \
+ COP_STATUS_DPE_BUSY | \
+ COP_STATUS_MI_BUSY | \
+ COP_STATUS_FIFO_BUSY)
+
+#define _tridentWaitDone(cop) while ((cop)->status & COP_STATUS_BUSY)
+
+#define _tridentWaitIdleEmpty(cop) _tridentWaitDone(cop);
+
+#define sourceInvarient(alu) (((alu) & 3) == (((alu) >> 2) & 3))
+
+#endif
diff --git a/hw/kdrive/trident/tridentstub.c b/hw/kdrive/trident/tridentstub.c
new file mode 100644
index 000000000..b0005e7c7
--- /dev/null
+++ b/hw/kdrive/trident/tridentstub.c
@@ -0,0 +1,54 @@
+/*
+ * $Id$
+ *
+ * Copyright 1999 SuSE, Inc.
+ *
+ * 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 SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. SuSE makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * 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.
+ *
+ * Author: Keith Packard, SuSE, Inc.
+ */
+/* $XFree86: $ */
+
+#include "trident.h"
+
+void
+InitCard (char *name)
+{
+ KdCardAttr attr;
+
+ if (LinuxFindPci (0x1023, 0x9525, 0, &attr))
+ KdCardInfoAdd (&tridentFuncs, &attr, 0);
+}
+
+void
+InitOutput (ScreenInfo *pScreenInfo, int argc, char **argv)
+{
+ KdInitOutput (pScreenInfo, argc, argv);
+}
+
+void
+InitInput (int argc, char **argv)
+{
+ KdInitInput (&Ps2MouseFuncs, &LinuxKeyboardFuncs);
+}
+
+void
+OsVendorInit (void)
+{
+ KdOsInit (&LinuxFuncs);
+}