summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2003-07-02 17:53:46 +0000
committerKeith Packard <keithp@keithp.com>2003-07-02 17:53:46 +0000
commitb923d897a51707c25b2dc62395d9765ba1a47bfe (patch)
treee6f2fcfa9a11eb1e8f49213cabe5131e0b0c1afd
parent544ee9bb7a060d6a85b5168a2de74ff1db430c89 (diff)
Initial revision
-rw-r--r--hw/kdrive/smi/Imakefile20
-rw-r--r--hw/kdrive/smi/smi.c367
-rw-r--r--hw/kdrive/smi/smi.h196
-rw-r--r--hw/kdrive/smi/smidraw.c336
-rw-r--r--hw/kdrive/smi/smidraw.h72
-rw-r--r--hw/kdrive/smi/smistub.c58
-rw-r--r--hw/kdrive/smi/smivideo.c1013
7 files changed, 2062 insertions, 0 deletions
diff --git a/hw/kdrive/smi/Imakefile b/hw/kdrive/smi/Imakefile
new file mode 100644
index 000000000..930425447
--- /dev/null
+++ b/hw/kdrive/smi/Imakefile
@@ -0,0 +1,20 @@
+XCOMM $XFree86: xc/programs/Xserver/hw/kdrive/smi/Imakefile,v 1.2 2001/06/16 05:48:48 keithp Exp $
+KDRIVE=..
+#include "../Kdrive.tmpl"
+
+#if BuildXvExt
+XVSRCS=smivideo.c
+XVOBJS=smivideo.o
+#endif
+
+SRCS = smi.c smidraw.c smistub.c $(XVSRCS)
+
+OBJS = smi.o smidraw.o smistub.o $(XVOBJS)
+
+DEFINES = XvExtensionDefines -DVESA /* -DUSE_PCI*/
+
+INCLUDES = -I. $(KDINCS) -I$(KDRIVE)/vesa
+
+NormalLibraryObjectRule()
+NormalLibraryTarget(smi,$(OBJS))
+DependTarget()
diff --git a/hw/kdrive/smi/smi.c b/hw/kdrive/smi/smi.c
new file mode 100644
index 000000000..1445b7f59
--- /dev/null
+++ b/hw/kdrive/smi/smi.c
@@ -0,0 +1,367 @@
+/*
+ * Copyright © 2001 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: xc/programs/Xserver/hw/kdrive/smi/smi.c,v 1.11 2002/10/18 06:31:17 keithp Exp $ */
+
+#include "smi.h"
+#include <sys/io.h>
+
+#define DEBUG
+#ifdef DEBUG
+#define DBGOUT(fmt,a...) fprintf (stderr, fmt, ##a)
+#else
+#define DBGOUT(fmt,a...)
+#endif
+
+#define ENTER() DBGOUT("Enter %s\n", __FUNCTION__)
+#define LEAVE() DBGOUT("Leave %s\n", __FUNCTION__)
+
+
+
+Bool
+smiCardInit (KdCardInfo *card)
+{
+ SmiCardInfo *smic;
+
+ ENTER ();
+ smic = (SmiCardInfo *) xalloc (sizeof (SmiCardInfo));
+ if (!smic)
+ return FALSE;
+
+ (void) smiMapReg (card, smic);
+
+ if (!vesaInitialize (card, &smic->vesa))
+ {
+ xfree (smic);
+ return FALSE;
+ }
+
+ card->driver = smic;
+ LEAVE();
+ return TRUE;
+}
+
+Bool
+smiScreenInit (KdScreenInfo *screen)
+{
+ SmiCardInfo *smic = screen->card->driver;
+ SmiScreenInfo *smis;
+ int screen_size, memory;
+
+ ENTER();
+ smis = (SmiScreenInfo *) xalloc (sizeof (SmiScreenInfo));
+ if (!smis)
+ return FALSE;
+ memset (smis, '\0', sizeof (SmiScreenInfo));
+ if (!vesaScreenInitialize (screen, &smis->vesa))
+ {
+ xfree (smis);
+ return FALSE;
+ }
+ if (!smic->reg_base)
+ screen->dumb = TRUE;
+ if (smis->vesa.mapping != VESA_LINEAR)
+ screen->dumb = TRUE;
+ smis->screen = smis->vesa.fb;
+ memory = smis->vesa.fb_size;
+ screen_size = screen->fb[0].byteStride * screen->height;
+ screen->softCursor = TRUE;
+ memory -= screen_size;
+ if (memory > screen->fb[0].byteStride)
+ {
+ smis->off_screen = smis->screen + screen_size;
+ smis->off_screen_size = memory;
+ }
+ else
+ {
+ smis->off_screen = 0;
+ smis->off_screen_size = 0;
+ }
+ screen->driver = smis;
+ LEAVE();
+ return TRUE;
+}
+
+Bool
+smiInitScreen (ScreenPtr pScreen)
+{
+ Bool ret;
+ ENTER ();
+#if 0
+#ifdef XV
+ KdScreenPriv(pScreen);
+ SmiCardInfo *smic = pScreenPriv->screen->card->driver;
+ if (smic->media_reg && smic->reg)
+ smiInitVideo(pScreen);
+#endif
+#endif
+ ret = vesaInitScreen (pScreen);
+ LEAVE();
+}
+
+#ifdef RANDR
+smiRandRSetConfig (ScreenPtr pScreen,
+ Rotation randr,
+ int rate,
+ RRScreenSizePtr pSize)
+{
+ Bool ret;
+ KdScreenPriv(pScreen);
+
+ ENTER ();
+ KdCheckSync (pScreen);
+
+ ret = vesaRandRSetConfig (pScreen, randr, rate, pSize);
+ LEAVE();
+ return ret;
+}
+
+Bool
+smiRandRInit (ScreenPtr pScreen)
+{
+ rrScrPriv(pScreen);
+
+ ENTER ();
+ pScrPriv->rrSetConfig = smiRandRSetConfig;
+ LEAVE ();
+ return TRUE;
+}
+#endif
+
+Bool
+smiFinishInitScreen (ScreenPtr pScreen)
+{
+ ENTER ();
+ if (!vesaFinishInitScreen (pScreen))
+ return FALSE;
+#ifdef RANDR
+ if (!smiRandRInit (pScreen))
+ return FALSE;
+#endif
+ LEAVE ();
+ return TRUE;
+}
+
+void
+smiPreserve (KdCardInfo *card)
+{
+ SmiCardInfo *smic = card->driver;
+
+ ENTER ();
+ vesaPreserve(card);
+ LEAVE();
+}
+
+Bool
+smiMapReg (KdCardInfo *card, SmiCardInfo *smic)
+{
+ ENTER ();
+ smic->io_base = 0; /* only handles one SMI card at standard VGA address */
+ smic->reg_base = (CARD8 *) KdMapDevice (SMI_REG_BASE(card),
+ SMI_REG_SIZE(card));
+
+ if (!smic->reg_base)
+ {
+ smic->dpr = 0;
+ return FALSE;
+ }
+
+ KdSetMappedMode (SMI_REG_BASE(card),
+ SMI_REG_SIZE(card),
+ KD_MAPPED_MODE_REGISTERS);
+ smic->dpr = (DPR *) (smic->reg_base + SMI_DPR_OFF(card));
+ LEAVE ();
+ return TRUE;
+}
+
+void
+smiUnmapReg (KdCardInfo *card, SmiCardInfo *smic)
+{
+ ENTER ();
+ if (smic->reg_base)
+ {
+ KdResetMappedMode (SMI_REG_BASE(card),
+ SMI_REG_SIZE(card),
+ KD_MAPPED_MODE_REGISTERS);
+ KdUnmapDevice ((void *) smic->reg_base, SMI_REG_SIZE(card));
+ smic->reg_base = 0;
+ smic->dpr = 0;
+ }
+ LEAVE ();
+}
+
+void
+smiOutb (CARD16 port, CARD8 val)
+{
+ asm volatile ("outb %b0,%w1" : : "a" (val), "d" (port));
+}
+
+CARD8
+smiInb (CARD16 port)
+{
+ CARD8 v;
+ asm volatile ("inb %w1,%b0" : "=a" (v) : "d" (port));
+ return v;
+}
+
+CARD8
+smiGetIndex (SmiCardInfo *smic, CARD16 addr, CARD16 data, CARD8 id)
+{
+ smiOutb (smic->io_base + addr, id);
+ return smiInb (smic->io_base + data);
+}
+
+void
+smiSetIndex (SmiCardInfo *smic, CARD16 addr, CARD16 data, CARD8 id, CARD8 val)
+{
+ smiOutb (smic->io_base + addr, id);
+ smiOutb (smic->io_base + data, val);
+}
+
+void
+smiSetMMIO (KdCardInfo *card, SmiCardInfo *smic)
+{
+ ENTER ();
+ if (!smic->reg_base)
+ smiMapReg (card, smic);
+ LEAVE();
+}
+
+void
+smiResetMMIO (KdCardInfo *card, SmiCardInfo *smic)
+{
+ smiUnmapReg (card, smic);
+}
+
+Bool
+smiEnable (ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ SmiCardInfo *smic = pScreenPriv->card->driver;
+
+ ENTER ();
+ if (!vesaEnable (pScreen))
+ return FALSE;
+
+ smiSetMMIO (pScreenPriv->card, smic);
+ smiDPMS (pScreen, KD_DPMS_NORMAL);
+#if 0
+#ifdef XV
+ KdXVEnable (pScreen);
+#endif
+#endif
+ LEAVE ();
+ return TRUE;
+}
+
+void
+smiDisable (ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ SmiCardInfo *smic = pScreenPriv->card->driver;
+
+ ENTER ();
+#ifdef XV
+ KdXVDisable (pScreen);
+#endif
+ smiResetMMIO (pScreenPriv->card, smic);
+ vesaDisable (pScreen);
+ LEAVE ();
+}
+
+Bool
+smiDPMS (ScreenPtr pScreen, int mode)
+{
+ Bool ret;
+ ENTER ();
+ ret = vesaDPMS (pScreen, mode);
+ LEAVE ();
+ return ret;
+}
+
+void
+smiRestore (KdCardInfo *card)
+{
+ SmiCardInfo *smic = card->driver;
+
+ ENTER ();
+ vesaRestore (card);
+ LEAVE();
+}
+
+void
+smiScreenFini (KdScreenInfo *screen)
+{
+ SmiScreenInfo *smis = (SmiScreenInfo *) screen->driver;
+
+ ENTER ();
+ vesaScreenFini (screen);
+ xfree (smis);
+ screen->driver = 0;
+ LEAVE ();
+}
+
+void
+smiCardFini (KdCardInfo *card)
+{
+ SmiCardInfo *smic = card->driver;
+
+ ENTER ();
+ smiUnmapReg (card, smic);
+ vesaCardFini (card);
+ LEAVE ();
+}
+
+#define smiCursorInit 0 /* initCursor */
+#define smiCursorEnable 0 /* enableCursor */
+#define smiCursorDisable 0 /* disableCursor */
+#define smiCursorFini 0 /* finiCursor */
+#define smiRecolorCursor 0 /* recolorCursor */
+
+KdCardFuncs smiFuncs = {
+ smiCardInit, /* cardinit */
+ smiScreenInit, /* scrinit */
+ smiInitScreen, /* initScreen */
+ smiPreserve, /* preserve */
+ smiEnable, /* enable */
+ smiDPMS, /* dpms */
+ smiDisable, /* disable */
+ smiRestore, /* restore */
+ smiScreenFini, /* scrfini */
+ smiCardFini, /* cardfini */
+
+ smiCursorInit, /* initCursor */
+ smiCursorEnable, /* enableCursor */
+ smiCursorDisable, /* disableCursor */
+ smiCursorFini, /* finiCursor */
+ smiRecolorCursor, /* recolorCursor */
+
+ smiDrawInit, /* initAccel */
+ smiDrawEnable, /* enableAccel */
+ smiDrawSync, /* syncAccel */
+ smiDrawDisable, /* disableAccel */
+ smiDrawFini, /* finiAccel */
+
+ vesaGetColors, /* getColors */
+ vesaPutColors, /* putColors */
+
+ smiFinishInitScreen, /* finishInitScreen */
+};
diff --git a/hw/kdrive/smi/smi.h b/hw/kdrive/smi/smi.h
new file mode 100644
index 000000000..5092988d7
--- /dev/null
+++ b/hw/kdrive/smi/smi.h
@@ -0,0 +1,196 @@
+/*
+ * Id: smi.h,v 1.2 1999/11/02 08:17:24 keithp Exp $
+ *
+ * Copyright © 2001 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: xc/programs/Xserver/hw/kdrive/smi/smi.h,v 1.6 2001/07/24 19:06:03 keithp Exp $ */
+
+#ifndef _SMI_H_
+#define _SMI_H_
+#include <vesa.h>
+#include "kxv.h"
+
+/*
+ * offset from ioport beginning
+ */
+
+#define SMI_IO_BASE(c) ((c)->attr.io)
+#define SMI_REG_BASE(c) ((c)->attr.address[0])
+#define SMI_REG_SIZE(c) (4096)
+
+#define SMI_DPR_OFF(c) (0x00000)
+
+typedef volatile CARD8 VOL8;
+typedef volatile CARD16 VOL16;
+typedef volatile CARD32 VOL32;
+
+/* DPR reg */
+typedef struct _DPR {
+ VOL32 src_xy; /* 0x00 */
+ VOL32 dst_xy; /* 0x04 */
+ VOL32 dst_wh; /* 0x08 */
+ VOL32 accel_cmd; /* 0x0c */
+ VOL32 src_stride; /* 0x10 */
+ VOL32 fg; /* 0x14 */
+ VOL32 bg; /* 0x18 */
+ VOL32 data_format; /* 0x1c */
+ VOL32 transparent; /* 0x20 */
+ VOL32 mask1; /* 0x24 ? */
+ VOL32 mask2; /* 0x28 ? */
+ VOL32 scissors_ul; /* 0x2c */
+ VOL32 scissors_lr; /* 0x30 */
+ VOL32 mask3; /* 0x34 */
+ VOL32 mask4; /* 0x38 */
+ VOL32 dst_stride; /* 0x3c */
+ VOL32 unknown_40; /* 0x40 */
+ VOL32 unknown_44; /* 0x44 */
+} DPR;
+
+#define SMI_XY(x,y) (((y) & 0x7fff) | (((x) & 0x7fff) << 16))
+
+/* 2D Engine commands */
+#define SMI_TRANSPARENT_SRC 0x00000100
+#define SMI_TRANSPARENT_DEST 0x00000300
+
+#define SMI_OPAQUE_PXL 0x00000000
+#define SMI_TRANSPARENT_PXL 0x00000400
+
+#define SMI_MONO_PACK_8 0x00001000
+#define SMI_MONO_PACK_16 0x00002000
+#define SMI_MONO_PACK_32 0x00003000
+
+#define SMI_ROP2_SRC 0x00008000
+#define SMI_ROP2_PAT 0x0000C000
+#define SMI_ROP3 0x00000000
+
+#define SMI_BITBLT 0x00000000
+#define SMI_RECT_FILL 0x00010000
+#define SMI_TRAPEZOID_FILL 0x00030000
+#define SMI_SHORT_STROKE 0x00060000
+#define SMI_BRESENHAM_LINE 0x00070000
+#define SMI_HOSTBLT_WRITE 0x00080000
+#define SMI_HOSTBLT_READ 0x00090000
+#define SMI_ROTATE_BLT 0x000B0000
+
+#define SMI_SRC_COLOR 0x00000000
+#define SMI_SRC_MONOCHROME 0x00400000
+
+#define SMI_GRAPHICS_STRETCH 0x00800000
+
+#define SMI_ROTATE_CW 0x01000000
+#define SMI_ROTATE_CCW 0x02000000
+
+#define SMI_MAJOR_X 0x00000000
+#define SMI_MAJOR_Y 0x04000000
+
+#define SMI_LEFT_TO_RIGHT 0x00000000
+#define SMI_RIGHT_TO_LEFT 0x08000000
+
+#define SMI_COLOR_PATTERN 0x40000000
+#define SMI_MONO_PATTERN 0x00000000
+
+#define SMI_QUICK_START 0x10000000
+#define SMI_START_ENGINE 0x80000000
+
+#define VGA_SEQ_INDEX 0x3C4
+#define VGA_SEQ_DATA 0x3C5
+
+typedef struct _smiCardInfo {
+ VesaCardPrivRec vesa;
+ CARD16 io_base;
+ CARD8 *reg_base;
+ DPR *dpr;
+ int avail;
+} SmiCardInfo;
+
+#define getSmiCardInfo(kd) ((SmiCardInfo *) ((kd)->card->driver))
+#define smiCardInfo(kd) SmiCardInfo *smic = getSmiCardInfo(kd)
+
+typedef struct _smiScreenInfo {
+ VesaScreenPrivRec vesa;
+ CARD8 *screen;
+ CARD8 *off_screen;
+ int off_screen_size;
+ CARD32 stride;
+ CARD32 data_format;
+ CARD8 dpr_vpr_enable;
+} SmiScreenInfo;
+
+#define getSmiScreenInfo(kd) ((SmiScreenInfo *) ((kd)->screen->driver))
+#define smiScreenInfo(kd) SmiScreenInfo *smis = getSmiScreenInfo(kd)
+
+void
+smiPreserve (KdCardInfo *card);
+
+Bool
+smiMapReg (KdCardInfo *card, SmiCardInfo *smic);
+
+void
+smiUnmapReg (KdCardInfo *card, SmiCardInfo *smic);
+
+void
+smiSetMMIO (KdCardInfo *card, SmiCardInfo *smic);
+
+void
+smiResetMMIO (KdCardInfo *card, SmiCardInfo *smic);
+
+Bool
+smiEnable (ScreenPtr pScreen);
+
+void
+smiDisable (ScreenPtr pScreen);
+
+void
+smiWaitAvail(SmiCardInfo *smic, int n);
+
+void
+smiWaitIdle (SmiCardInfo *smic);
+
+Bool
+smiDrawSetup (ScreenPtr pScreen);
+
+Bool
+smiDrawInit (ScreenPtr pScreen);
+
+void
+smiDrawReinit (ScreenPtr pScreen);
+
+void
+smiDrawEnable (ScreenPtr pScreen);
+
+void
+smiDrawSync (ScreenPtr pScreen);
+
+void
+smiDrawDisable (ScreenPtr pScreen);
+
+void
+smiDrawFini (ScreenPtr pScreen);
+
+CARD8
+smiReadIndex (SmiCardInfo *smic, CARD16 port, CARD8 index);
+
+void
+smiWriteIndex (SmiCardInfo *smic, CARD16 port, CARD8 index, CARD8 value);
+
+extern KdCardFuncs smiFuncs;
+
+#endif /* _SMI_H_ */
diff --git a/hw/kdrive/smi/smidraw.c b/hw/kdrive/smi/smidraw.c
new file mode 100644
index 000000000..445d356b5
--- /dev/null
+++ b/hw/kdrive/smi/smidraw.c
@@ -0,0 +1,336 @@
+/*
+ * Id: smidraw.c,v 1.1 1999/11/02 03:54:47 keithp Exp $
+ *
+ * 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: xc/programs/Xserver/hw/kdrive/smi/smidraw.c,v 1.7 2001/07/24 19:06:03 keithp Exp $ */
+
+#include "smi.h"
+#include "smidraw.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"
+#include "picturestr.h"
+
+CARD8 smiBltRop[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 */
+};
+
+CARD8 smiSolidRop[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 */
+};
+
+
+#define GET_STATUS(smic) smiGetIndex (smic, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x16)
+
+#define ENGINE_IDLE_EMPTY(smic) ((GET_STATUS(smic) & 0x18) == 0x10)
+#define FIFO_EMPTY(smic) ((GET_STATUS(smic) & 0x10) == 0x10)
+
+static void
+smiSleep (int ms)
+{
+ struct timespec req;
+
+ req.tv_sec = ms / 1000;
+ req.tv_nsec = (ms % 1000) * 1000000;
+ while (req.tv_sec || req.tv_nsec)
+ if (nanosleep (&req, &req) == 0)
+ break;
+}
+
+#define MAX_FIFO 16
+
+void
+smiWaitAvail(SmiCardInfo *smic, int n)
+{
+ if (smic->avail < n)
+ {
+ while (!FIFO_EMPTY (smic))
+ ;
+ smic->avail = MAX_FIFO;
+ }
+ smic->avail -= n;
+}
+
+void
+smiWaitIdle (SmiCardInfo *smic)
+{
+ while (!ENGINE_IDLE_EMPTY (smic))
+ ;
+ smic->avail = MAX_FIFO;
+}
+
+static SmiCardInfo *smic;
+static SmiScreenInfo *smis;
+static DPR *dpr;
+static CARD32 accel_cmd;
+
+static Bool
+smiSetup (ScreenPtr pScreen, int wait)
+{
+ KdScreenPriv(pScreen);
+
+ smis = getSmiScreenInfo (pScreenPriv);
+ smic = getSmiCardInfo(pScreenPriv);
+ dpr = smic->dpr;
+
+ if (!dpr)
+ return FALSE;
+
+ /* enable DPR/VPR registers */
+ smiSetIndex (smic, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x21,
+ smis->dpr_vpr_enable);
+
+ smiWaitAvail (smic, wait + 9);
+ dpr->src_stride = (smis->stride << 16) | smis->stride;
+ dpr->data_format = smis->data_format;
+ dpr->mask1 = 0xffffffff;
+ dpr->mask2 = 0xffffffff;
+ dpr->dst_stride = (smis->stride << 16) | smis->stride;
+ dpr->unknown_40 = 0x0;
+ dpr->unknown_44 = 0x0;
+ dpr->scissors_ul = 0x0;
+ dpr->scissors_lr = SMI_XY(4095,4095);
+
+ return TRUE;
+}
+
+Bool
+smiPrepareSolid (DrawablePtr pDrawable,
+ int alu,
+ Pixel pm,
+ Pixel fg)
+{
+ KdScreenPriv(pDrawable->pScreen);
+
+ if (~pm & FbFullMask(pDrawable->depth))
+ return FALSE;
+
+ if (!smiSetup (pDrawable->pScreen, 3))
+ return FALSE;
+
+ accel_cmd = smiSolidRop[alu] | SMI_BITBLT | SMI_START_ENGINE;
+ dpr->fg = fg;
+ dpr->mask3 = 0xffffffff;
+ dpr->mask4 = 0xffffffff;
+ return TRUE;
+}
+
+void
+smiSolid (int x1, int y1, int x2, int y2)
+{
+ smiWaitAvail(smic,3);
+ dpr->dst_xy = SMI_XY(x1,y1);
+ dpr->dst_wh = SMI_XY(x2-x1,y2-y1);
+ dpr->accel_cmd = accel_cmd;
+}
+
+void
+smiDoneSolid (void)
+{
+}
+
+static int copyDx;
+static int copyDy;
+
+Bool
+smiPrepareCopy (DrawablePtr pSrcDrawable,
+ DrawablePtr pDstDrawable,
+ int dx,
+ int dy,
+ int alu,
+ Pixel pm)
+{
+ KdScreenPriv(pSrcDrawable->pScreen);
+
+ if (~pm & FbFullMask(pSrcDrawable->depth))
+ return FALSE;
+
+ if (!smiSetup (pSrcDrawable->pScreen, 0))
+ return FALSE;
+
+ accel_cmd = smiBltRop[alu] | SMI_BITBLT | SMI_START_ENGINE;
+
+ copyDx = dx;
+ copyDy = dy;
+ if (dy < 0 || (dy == 0 && dx < 0))
+ accel_cmd |= SMI_RIGHT_TO_LEFT;
+ return TRUE;
+}
+
+void
+smiCopy (int srcX,
+ int srcY,
+ int dstX,
+ int dstY,
+ int w,
+ int h)
+{
+ if (accel_cmd & SMI_RIGHT_TO_LEFT)
+ {
+ srcX += w - 1;
+ dstX += w - 1;
+ srcY += h - 1;
+ dstY += h - 1;
+ }
+ smiWaitAvail (smic, 4);
+ dpr->src_xy = SMI_XY (srcX, srcY);
+ dpr->dst_xy = SMI_XY (dstX, dstY);
+ dpr->dst_wh = SMI_XY (w, h);
+ dpr->accel_cmd = accel_cmd;
+}
+
+void
+smiDoneCopy (void)
+{
+}
+
+KaaScreenPrivRec smiKaa = {
+ smiPrepareSolid,
+ smiSolid,
+ smiDoneSolid,
+
+ smiPrepareCopy,
+ smiCopy,
+ smiDoneCopy,
+};
+
+Bool
+smiDrawInit (ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+
+ if (pScreenPriv->screen->fb[0].depth == 4)
+ return FALSE;
+
+ if (!kaaDrawInit (pScreen, &smiKaa))
+ return FALSE;
+
+ return TRUE;
+}
+
+void
+smiDrawEnable (ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ int i;
+ static const int xyAddress[] = { 320, 400, 512, 640, 800, 1024, 1280, 1600, 2048 };
+
+ smis = getSmiScreenInfo (pScreenPriv);
+ smic = getSmiCardInfo(pScreenPriv);
+ dpr = smic->dpr;
+
+ smis->stride = pScreenPriv->screen->fb[0].byteStride;
+ smis->dpr_vpr_enable = smiGetIndex (smic, VGA_SEQ_INDEX,
+ VGA_SEQ_DATA, 0x21) & ~0x03;
+
+ switch (pScreenPriv->screen->fb[0].depth) {
+ case 8:
+ smis->data_format = 0x00000000;
+ break;
+ case 15:
+ case 16:
+ smis->data_format = 0x00100000;
+ smis->stride >>= 1;
+ break;
+ case 24:
+ smis->data_format = 0x00300000;
+ break;
+ case 32:
+ smis->data_format = 0x00200000;
+ smis->stride >>= 2;
+ break;
+ }
+ for (i = 0; i < sizeof(xyAddress) / sizeof(xyAddress[0]); i++)
+ {
+ if (xyAddress[i] == pScreenPriv->screen->fb[0].pixelStride)
+ {
+ smis->data_format |= i << 16;
+ break;
+ }
+ }
+
+ smiSetup (pScreen, 0);
+
+ KdMarkSync (pScreen);
+}
+
+void
+smiDrawDisable (ScreenPtr pScreen)
+{
+ smic = 0;
+ smis = 0;
+ dpr = 0;
+ accel_cmd = 0;
+}
+
+void
+smiDrawFini (ScreenPtr pScreen)
+{
+}
+
+void
+smiDrawSync (ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ smic = getSmiCardInfo(pScreenPriv);
+
+ smiWaitIdle (smic);
+}
diff --git a/hw/kdrive/smi/smidraw.h b/hw/kdrive/smi/smidraw.h
new file mode 100644
index 000000000..3ec0831fc
--- /dev/null
+++ b/hw/kdrive/smi/smidraw.h
@@ -0,0 +1,72 @@
+/*
+ * Id: smidraw.h,v 1.1 1999/11/02 03:54:47 keithp Exp $
+ *
+ * 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: xc/programs/Xserver/hw/kdrive/mach64/mach64draw.h,v 1.1 2001/06/03 18:48:19 keithp Exp $ */
+
+#ifndef _SMIDRAW_H_
+#define _SMIDRAW_H_
+
+#define SetupSmi(s) KdScreenPriv(s); \
+ smiCardInfo(pScreenPriv); \
+ Cop *cop = smic->cop
+
+#define SmiAlpha (COP_MULTI_ALPHA|COP_ALPHA_WRITE_ENABLE)
+
+#define _smiInit(cop,smic) { \
+ if ((cop)->status == 0xffffffff) smiSetMMIO(smic); \
+ (cop)->multi = (smic)->cop_depth; \
+ (cop)->multi = (smic)->cop_stride; \
+ (cop)->multi = SmiAlpha; \
+} \
+
+#define _smiSetSolidRect(cop,pix,alu,cmd) {\
+ cop->multi = COP_MULTI_PATTERN; \
+ cop->multi = COP_MULTI_ROP | smiRop[alu]; \
+ cop->fg = (pix); \
+ cmd = COP_OP_BLT | COP_SCL_OPAQUE | COP_OP_ROP | COP_OP_FG; \
+}
+
+#define _smiRect(cop,x1,y1,x2,y2,cmd) { \
+ (cop)->dst_start_xy = TRI_XY (x1,y1); \
+ (cop)->dst_end_xy = TRI_XY(x2,y2); \
+ _smiWaitDone(cop); \
+ (cop)->command = (cmd); \
+}
+
+#define COP_STATUS_BUSY (COP_STATUS_BE_BUSY | \
+ COP_STATUS_DPE_BUSY | \
+ COP_STATUS_MI_BUSY)
+
+#define _smiWaitDone(cop) { \
+ int __q__ = 500000; \
+ while (__q__-- && (cop)->status & COP_STATUS_BUSY) \
+ ; \
+ if (!__q__) \
+ (cop)->status = 0; \
+}
+
+#define _smiWaitIdleEmpty(cop) _smiWaitDone(cop)
+
+#define sourceInvarient(alu) (((alu) & 3) == (((alu) >> 2) & 3))
+
+#endif
diff --git a/hw/kdrive/smi/smistub.c b/hw/kdrive/smi/smistub.c
new file mode 100644
index 000000000..d43908439
--- /dev/null
+++ b/hw/kdrive/smi/smistub.c
@@ -0,0 +1,58 @@
+/*
+ * Id: smistub.c,v 1.1 1999/11/02 08:19:15 keithp Exp $
+ *
+ * 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: xc/programs/Xserver/hw/kdrive/smi/smistub.c,v 1.4 2002/10/08 21:25:35 keithp Exp $ */
+
+#include "smi.h"
+
+void
+InitCard (char *name)
+{
+ KdCardAttr attr;
+
+ if (LinuxFindPci (0x126f, 0x0720, 0, &attr))
+ KdCardInfoAdd (&smiFuncs, &attr, 0);
+}
+
+void
+InitOutput (ScreenInfo *pScreenInfo, int argc, char **argv)
+{
+ KdInitOutput (pScreenInfo, argc, argv);
+}
+
+void
+InitInput (int argc, char **argv)
+{
+ KdInitInput (&LinuxMouseFuncs, &LinuxKeyboardFuncs);
+}
+
+int
+ddxProcessArgument (int argc, char **argv, int i)
+{
+ int ret;
+
+ if (!(ret = vesaProcessArgument (argc, argv, i)))
+ ret = KdProcessArgument(argc, argv, i);
+ return ret;
+}
diff --git a/hw/kdrive/smi/smivideo.c b/hw/kdrive/smi/smivideo.c
new file mode 100644
index 000000000..8ff29e67f
--- /dev/null
+++ b/hw/kdrive/smi/smivideo.c
@@ -0,0 +1,1013 @@
+/*
+ * Copyright © 2001 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: xc/programs/Xserver/hw/kdrive/mach64/mach64video.c,v 1.10 2003/04/23 21:51:18 tsi Exp $ */
+#include "mach64.h"
+
+#include "Xv.h"
+#include "../../xfree86/common/fourcc.h"
+
+#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE)
+
+static Atom xvBrightness, xvSaturation, xvColorKey;
+
+#define IMAGE_MAX_WIDTH 720
+#define IMAGE_MAX_HEIGHT 576
+
+static void
+mach64StopVideo(KdScreenInfo *screen, pointer data, Bool exit)
+{
+ ScreenPtr pScreen = screen->pScreen;
+ KdScreenPriv(pScreen);
+ KdCardInfo *card = pScreenPriv->card;
+ Mach64ScreenInfo *mach64s = (Mach64ScreenInfo *) screen->driver;
+ Mach64CardInfo *mach64c = (Mach64CardInfo *) card->driver;
+ Mach64PortPrivPtr pPortPriv = mach64s->pAdaptor->pPortPrivates[0].ptr;
+ Reg *reg = mach64c->reg;
+ MediaReg *media = mach64c->media_reg;
+
+ REGION_EMPTY(screen->pScreen, &pPortPriv->clip);
+
+ if (!media)
+ return;
+
+ if(pPortPriv->videoOn)
+ {
+ mach64WaitIdle (reg);
+ /* wait for buffer to be displayed */
+ while (((media->TRIG_CNTL >> 5) & 1) != pPortPriv->currentBuf)
+ ;
+ /* wait for buffer to be finished */
+ while (((media->TRIG_CNTL >> 6) & 1) != 0)
+ ;
+ mach64WaitAvail (reg, 1);
+ media->OVERLAY_SCALE_CNTL = 0;
+ pPortPriv->videoOn = FALSE;
+ mach64WaitIdle (reg);
+ }
+}
+
+static int
+mach64SetPortAttribute(KdScreenInfo *screen,
+ Atom attribute,
+ int value,
+ pointer data)
+{
+ ScreenPtr pScreen = screen->pScreen;
+ KdScreenPriv(pScreen);
+ KdCardInfo *card = pScreenPriv->card;
+ Mach64ScreenInfo *mach64s = (Mach64ScreenInfo *) screen->driver;
+ Mach64CardInfo *mach64c = (Mach64CardInfo *) card->driver;
+ Mach64PortPrivPtr pPortPriv = mach64s->pAdaptor->pPortPrivates[0].ptr;
+ MediaReg *media = mach64c->media_reg;
+
+ if(attribute == xvBrightness)
+ {
+ if(value < -1000)
+ value = -1000;
+ if (value > 1000)
+ value = 1000;
+ pPortPriv->brightness = value;
+ }
+ else if(attribute == xvSaturation)
+ {
+ if (value < -1000)
+ value = -1000;
+ if (value > 1000)
+ value = 1000;
+ pPortPriv->saturation = value;
+ }
+ else if(attribute == xvColorKey)
+ {
+ if (pPortPriv->colorKey != value)
+ {
+ pPortPriv->colorKey = value;
+ REGION_EMPTY(screen->pScreen, &pPortPriv->clip);
+ }
+ }
+ else
+ return BadMatch;
+
+ return Success;
+}
+
+static int
+mach64GetPortAttribute(KdScreenInfo *screen,
+ Atom attribute,
+ int *value,
+ pointer data)
+{
+ Mach64PortPrivPtr pPortPriv = (Mach64PortPrivPtr)data;
+
+ if(attribute == xvBrightness)
+ *value = pPortPriv->brightness;
+ else if(attribute == xvSaturation)
+ *value = pPortPriv->saturation;
+ else if(attribute == xvColorKey)
+ *value = pPortPriv->colorKey;
+ else
+ return BadMatch;
+
+ return Success;
+}
+
+static void
+mach64QueryBestSize(KdScreenInfo *screen,
+ Bool motion,
+ short vid_w,
+ short vid_h,
+ short drw_w,
+ short drw_h,
+ unsigned int *p_w,
+ unsigned int *p_h,
+ pointer data)
+{
+ *p_w = drw_w;
+ *p_h = drw_h;
+}
+
+
+static void
+mach64CopyPackedData(KdScreenInfo *screen,
+ unsigned char *buf,
+ int randr,
+ int srcPitch,
+ int dstPitch,
+ int srcW,
+ int srcH,
+ int top,
+ int left,
+ int h,
+ int w)
+{
+ ScreenPtr pScreen = screen->pScreen;
+ KdScreenPriv(pScreen);
+ KdCardInfo *card = pScreenPriv->card;
+ Mach64ScreenInfo *mach64s = (Mach64ScreenInfo *) screen->driver;
+ Mach64CardInfo *mach64c = (Mach64CardInfo *) card->driver;
+ Mach64PortPrivPtr pPortPriv = mach64s->pAdaptor->pPortPrivates[0].ptr;
+ CARD8 *src, *dst;
+ int srcDown, srcRight, srcNext;
+ int p;
+
+ switch (randr & RR_Rotate_All) {
+ case RR_Rotate_0:
+ src = buf;
+ srcDown = srcPitch;
+ srcRight = 2;
+ break;
+ case RR_Rotate_90:
+ src = buf + (srcH - 1) * 2;
+ srcDown = -2;
+ srcRight = srcPitch;
+ break;
+ case RR_Rotate_180:
+ src = buf + srcPitch * (srcH - 1) + (srcW - 1) * 2;
+ srcDown = -srcPitch;
+ srcRight = -2;
+ break;
+ case RR_Rotate_270:
+ src = buf + srcPitch * (srcW - 1);
+ srcDown = 2;
+ srcRight = -srcPitch;
+ break;
+ }
+
+ src = src + top*srcDown + left*srcRight;
+
+ if (pPortPriv->currentBuf == 0)
+ dst = (CARD8 *) mach64s->vesa.fb + pPortPriv->YBuf0Offset;
+ else
+ dst = (CARD8 *) mach64s->vesa.fb + pPortPriv->YBuf1Offset;
+
+ w >>= 1;
+ srcRight >>= 1;
+ srcNext = srcRight >> 1;
+ while(h--)
+ {
+ CARD16 *s = (CARD16 *) src;
+ CARD32 *d = (CARD32 *) dst;
+ p = w;
+ while (p--)
+ {
+ *d++ = s[0] | (s[srcNext] << 16);
+ s += srcRight;
+ }
+ src += srcPitch;
+ dst += dstPitch;
+ }
+}
+
+static void
+mach64CopyPlanarData(KdScreenInfo *screen,
+ unsigned char *buf,
+ int randr,
+ int srcPitch,
+ int srcPitch2,
+ int dstPitch, /* of chroma */
+ int srcW,
+ int srcH,
+ int height,
+ int top,
+ int left,
+ int h,
+ int w,
+ int id)
+{
+ ScreenPtr pScreen = screen->pScreen;
+ KdScreenPriv(pScreen);
+ KdCardInfo *card = pScreenPriv->card;
+ Mach64ScreenInfo *mach64s = (Mach64ScreenInfo *) screen->driver;
+ Mach64CardInfo *mach64c = (Mach64CardInfo *) card->driver;
+ Mach64PortPrivPtr pPortPriv = mach64s->pAdaptor->pPortPrivates[0].ptr;
+ int i, j;
+ CARD8 *src1, *src2, *src3, *dst1;
+ int srcDown, srcDown2, srcRight, srcRight2, srcNext;
+
+ /* compute source data pointers */
+ src1 = buf;
+ src2 = src1 + height * srcPitch;
+ src3 = src2 + (height >> 1) * srcPitch2;
+ switch (randr & RR_Rotate_All) {
+ case RR_Rotate_0:
+ srcDown = srcPitch;
+ srcDown2 = srcPitch2;
+ srcRight = 2;
+ srcRight2 = 1;
+ srcNext = 1;
+ break;
+ case RR_Rotate_90:
+ src1 = src1 + srcH - 1;
+ src2 = src2 + (srcH >> 1) - 1;
+ src3 = src3 + (srcH >> 1) - 1;
+ srcDown = -1;
+ srcDown2 = -1;
+ srcRight = srcPitch * 2;
+ srcRight2 = srcPitch2;
+ srcNext = srcPitch;
+ break;
+ case RR_Rotate_180:
+ src1 = src1 + srcPitch * (srcH - 1) + (srcW - 1);
+ src2 = src2 + srcPitch2 * ((srcH >> 1) - 1) + ((srcW >> 1) - 1);
+ src3 = src3 + srcPitch2 * ((srcH >> 1) - 1) + ((srcW >> 1) - 1);
+ srcDown = -srcPitch;
+ srcDown2 = -srcPitch2;
+ srcRight = -2;
+ srcRight2 = -1;
+ srcNext = -1;
+ break;
+ case RR_Rotate_270:
+ src1 = src1 + srcPitch * (srcW - 1);
+ src2 = src2 + srcPitch2 * ((srcW >> 1) - 1);
+ src3 = src3 + srcPitch2 * ((srcW >> 1) - 1);
+ srcDown = 1;
+ srcDown2 = 1;
+ srcRight = -srcPitch * 2;
+ srcRight2 = -srcPitch2;
+ srcNext = -srcPitch;
+ break;
+ }
+
+ /* adjust for origin */
+ src1 += top * srcDown + left * srcNext;
+ src2 += (top >> 1) * srcDown2 + (left >> 1) * srcRight2;
+ src3 += (top >> 1) * srcDown2 + (left >> 1) * srcRight2;
+
+ if (id == FOURCC_I420)
+ {
+ CARD8 *srct = src2;
+ src2 = src3;
+ src3 = srct;
+ }
+
+ if (pPortPriv->currentBuf == 0)
+ dst1 = (CARD8 *) mach64s->vesa.fb + pPortPriv->YBuf0Offset;
+ else
+ dst1 = (CARD8 *) mach64s->vesa.fb + pPortPriv->YBuf1Offset;
+
+ w >>= 1;
+ for (j = 0; j < h; j++)
+ {
+ CARD32 *dst = (CARD32 *) dst1;
+ CARD8 *s1l = src1;
+ CARD8 *s1r = src1 + srcNext;
+ CARD8 *s2 = src2;
+ CARD8 *s3 = src3;
+
+ for (i = 0; i < w; i++)
+ {
+ *dst++ = *s1l | (*s1r << 16) | (*s3 << 8) | (*s2 << 24);
+ s1l += srcRight;
+ s1r += srcRight;
+ s2 += srcRight2;
+ s3 += srcRight2;
+ }
+ src1 += srcDown;
+ dst1 += dstPitch;
+ if (j & 1)
+ {
+ src2 += srcDown2;
+ src3 += srcDown2;
+ }
+ }
+}
+
+static void
+mach64PaintRegion (ScreenPtr pScreen, RegionPtr pRgn, Pixel fg)
+{
+ WindowPtr pRoot = WindowTable[pScreen->myNum];
+ GCPtr pGC;
+ CARD32 val[2];
+ xRectangle *rects, *r;
+ BoxPtr pBox = REGION_RECTS (pRgn);
+ int nBox = REGION_NUM_RECTS (pRgn);
+
+ rects = ALLOCATE_LOCAL (nBox * sizeof (xRectangle));
+ if (!rects)
+ goto bail0;
+ r = rects;
+ while (nBox--)
+ {
+ r->x = pBox->x1;
+ r->y = pBox->y1;
+ r->width = pBox->x2 - pBox->x1;
+ r->height = pBox->y2 - pBox->y1;
+ r++;
+ pBox++;
+ }
+
+ pGC = GetScratchGC (pRoot->drawable.depth, pScreen);
+ if (!pGC)
+ goto bail1;
+
+ val[0] = fg;
+ val[1] = IncludeInferiors;
+ ChangeGC (pGC, GCForeground|GCSubwindowMode, val);
+
+ ValidateGC (&pRoot->drawable, pGC);
+
+ (*pGC->ops->PolyFillRect) (&pRoot->drawable, pGC,
+ REGION_NUM_RECTS (pRgn), rects);
+
+ FreeScratchGC (pGC);
+bail1:
+ DEALLOCATE_LOCAL (rects);
+bail0:
+ ;
+}
+
+/* Mach64ClipVideo -
+
+ Takes the dst box in standard X BoxRec form (top and left
+ edges inclusive, bottom and right exclusive). The new dst
+ box is returned. The source boundaries are given (x1, y1
+ inclusive, x2, y2 exclusive) and returned are the new source
+ boundaries in 16.16 fixed point.
+*/
+
+static void
+Mach64ClipVideo(BoxPtr dst,
+ INT32 *x1,
+ INT32 *x2,
+ INT32 *y1,
+ INT32 *y2,
+ BoxPtr extents, /* extents of the clip region */
+ INT32 width,
+ INT32 height)
+{
+ INT32 vscale, hscale, delta;
+ int diff;
+
+ hscale = ((*x2 - *x1) << 16) / (dst->x2 - dst->x1);
+ vscale = ((*y2 - *y1) << 16) / (dst->y2 - dst->y1);
+
+ *x1 <<= 16; *x2 <<= 16;
+ *y1 <<= 16; *y2 <<= 16;
+
+ diff = extents->x1 - dst->x1;
+ if(diff > 0) {
+ dst->x1 = extents->x1;
+ *x1 += diff * hscale;
+ }
+ diff = dst->x2 - extents->x2;
+ if(diff > 0) {
+ dst->x2 = extents->x2;
+ *x2 -= diff * hscale;
+ }
+ diff = extents->y1 - dst->y1;
+ if(diff > 0) {
+ dst->y1 = extents->y1;
+ *y1 += diff * vscale;
+ }
+ diff = dst->y2 - extents->y2;
+ if(diff > 0) {
+ dst->y2 = extents->y2;
+ *y2 -= diff * vscale;
+ }
+
+ if(*x1 < 0) {
+ diff = (- *x1 + hscale - 1)/ hscale;
+ dst->x1 += diff;
+ *x1 += diff * hscale;
+ }
+ delta = *x2 - (width << 16);
+ if(delta > 0) {
+ diff = (delta + hscale - 1)/ hscale;
+ dst->x2 -= diff;
+ *x2 -= diff * hscale;
+ }
+ if(*y1 < 0) {
+ diff = (- *y1 + vscale - 1)/ vscale;
+ dst->y1 += diff;
+ *y1 += diff * vscale;
+ }
+ delta = *y2 - (height << 16);
+ if(delta > 0) {
+ diff = (delta + vscale - 1)/ vscale;
+ dst->y2 -= diff;
+ *y2 -= diff * vscale;
+ }
+}
+
+static void
+mach64DisplayVideo(KdScreenInfo *screen,
+ int id,
+ int dstPitch, /* of chroma for 4:2:0 */
+ int x1,
+ int y1,
+ int x2,
+ int y2,
+ int dst_x1,
+ int dst_y1,
+ int dst_x2,
+ int dst_y2,
+ short src_w,
+ short src_h,
+ short drw_w,
+ short drw_h)
+{
+ ScreenPtr pScreen = screen->pScreen;
+ KdScreenPriv(pScreen);
+ KdCardInfo *card = pScreenPriv->card;
+ Mach64ScreenInfo *mach64s = (Mach64ScreenInfo *) screen->driver;
+ Mach64CardInfo *mach64c = (Mach64CardInfo *) card->driver;
+ Mach64PortPrivPtr pPortPriv = mach64s->pAdaptor->pPortPrivates[0].ptr;
+ Reg *reg = mach64c->reg;
+ MediaReg *media = mach64c->media_reg;
+ int xscaleInt, xscaleFract, yscaleInt, yscaleFract;
+ int xscaleIntUV = 0, xscaleFractUV = 0;
+ int yscaleIntUV = 0, yscaleFractUV = 0;
+ int randr = mach64s->vesa.randr;
+ int HORZ_INC, VERT_INC;
+ CARD32 SCALER_IN;
+ CARD32 OVERLAY_SCALE_CNTL;
+ int tmp;
+ int left;
+ int bright;
+ int sat;
+
+ if (id == FOURCC_UYVY)
+ SCALER_IN = SCALER_IN_YVYU422;
+ else
+ SCALER_IN = SCALER_IN_VYUY422;
+
+ mach64WaitAvail (reg, 4);
+
+ media->VIDEO_FORMAT = SCALER_IN | VIDEO_IN_VYUY422;
+
+ /* color key */
+ media->OVERLAY_GRAPHICS_KEY_MSK = (1 << screen->fb[0].depth) - 1;
+ media->OVERLAY_GRAPHICS_KEY_CLR = pPortPriv->colorKey;
+ /* set key control to obey only graphics color key */
+ media->OVERLAY_KEY_CNTL = 0x50;
+
+ mach64WaitAvail (reg, 9);
+ media->CAPTURE_DEBUG = 0;
+ /* no exclusive video region */
+ media->OVERLAY_EXCLUSIVE_HORZ = 0;
+ media->OVERLAY_EXCLUSIVE_VERT = 0;
+ /* scaling coefficients */
+ media->SCALER_H_COEFF0 = 0x00002000;
+ media->SCALER_H_COEFF1 = 0x0D06200D;
+ media->SCALER_H_COEFF2 = 0x0D0A1C0D;
+ media->SCALER_H_COEFF3 = 0x0C0E1A0C;
+ media->SCALER_H_COEFF4 = 0x0C14140C;
+ media->SCALER_TEST = 0;
+
+ mach64WaitAvail (reg, 2);
+ media->OVERLAY_SCALE_CNTL = (SCALE_PIX_EXPAND |
+ SCALE_GAMMA_BRIGHT |
+ SCALE_BANDWIDTH |
+ SCALE_OVERLAY_EN |
+ SCALE_EN);
+
+ bright = (pPortPriv->brightness * 64 / 1000);
+ if (bright < -0x40)
+ bright = -0x40;
+ if (bright > 0x3f)
+ bright = 0x3f;
+ bright = bright & 0x7f;
+ sat = ((pPortPriv->saturation * 31 + 31000) / 2000);
+ if (sat > 0x1f)
+ sat = 0x1f;
+ if (sat < 0)
+ sat = 0;
+
+ media->SCALER_COLOUR_CNTL = ((bright << 0) | /* BRIGHTNESS */
+ (sat << 8) | /* SATURATION_U */
+ (sat << 16) | /* SATURATION_V */
+ (0 << 21) | /* SCALER_VERT_ADJ_UV */
+ (0 << 28)); /* SCALER_HORZ_ADJ_UV */
+
+ VERT_INC = (src_h << 12) / drw_h;
+ HORZ_INC = (src_w << 12) / drw_w;
+
+ mach64WaitAvail (reg, 13);
+
+ /* lock registers to prevent non-atomic update */
+ media->OVERLAY_Y_X_START = 0x80000000 | MACH64_YX (dst_x1, dst_y1);
+ /* ending screen coordinate */
+ media->OVERLAY_Y_X_END = 0x80000000 | MACH64_YX (dst_x2, dst_y2);
+
+ media->OVERLAY_SCALE_INC = MACH64_YX(HORZ_INC, VERT_INC);
+
+ media->SCALER_BUF0_OFFSET = pPortPriv->YBuf0Offset;
+ media->SCALER_BUF1_OFFSET = pPortPriv->YBuf1Offset;
+
+ media->SCALER_BUF0_OFFSET_U = pPortPriv->YBuf0Offset;
+ media->SCALER_BUF1_OFFSET_U = pPortPriv->YBuf1Offset;
+
+ media->SCALER_BUF0_OFFSET_V = pPortPriv->YBuf0Offset;
+ media->SCALER_BUF1_OFFSET_V = pPortPriv->YBuf1Offset;
+
+ media->SCALER_BUF_PITCH = dstPitch >> 1;
+ media->SCALER_HEIGHT_WIDTH = MACH64_YX(src_w - (x1 >> 16), src_h - (y1 >> 16));
+
+ media->CAPTURE_CONFIG = pPortPriv->currentBuf << 28;
+
+ /* set XY location and unlock */
+ media->OVERLAY_Y_X_START = MACH64_YX (dst_x1, dst_y1);
+}
+
+static int
+mach64PutImage(KdScreenInfo *screen,
+ short src_x,
+ short src_y,
+ short drw_x,
+ short drw_y,
+ short src_w,
+ short src_h,
+ short drw_w,
+ short drw_h,
+ int id,
+ unsigned char *buf,
+ short width,
+ short height,
+ Bool sync,
+ RegionPtr clipBoxes,
+ pointer data)
+{
+ KdCardInfo *card = screen->card;
+ Mach64ScreenInfo *mach64s = (Mach64ScreenInfo *) screen->driver;
+ Mach64CardInfo *mach64c = (Mach64CardInfo *) card->driver;
+ Mach64PortPrivPtr pPortPriv = (Mach64PortPrivPtr)data;
+ Reg *reg = mach64c->reg;
+ MediaReg *media = mach64c->media_reg;
+ INT32 x1, x2, y1, y2;
+ int randr = mach64s->vesa.randr;
+ int srcPitch, srcPitch2, dstPitch;
+ int top, left, npixels, nlines, size;
+ BoxRec dstBox;
+ int dst_width = width, dst_height = height;
+ int rot_x1, rot_y1, rot_x2, rot_y2;
+ int dst_x1, dst_y1, dst_x2, dst_y2;
+ int rot_src_w, rot_src_h, rot_drw_w, rot_drw_h;
+
+ /* Clip */
+ x1 = src_x;
+ x2 = src_x + src_w;
+ y1 = src_y;
+ y2 = src_y + src_h;
+
+ dstBox.x1 = drw_x;
+ dstBox.x2 = drw_x + drw_w;
+ dstBox.y1 = drw_y;
+ dstBox.y2 = drw_y + drw_h;
+
+ Mach64ClipVideo(&dstBox, &x1, &x2, &y1, &y2,
+ REGION_EXTENTS(pScreen, clipBoxes), width, height);
+
+ if((x1 >= x2) || (y1 >= y2))
+ return Success;
+
+ if (!media)
+ return BadAlloc;
+
+ if (randr & (RR_Rotate_0|RR_Rotate_180))
+ {
+ dst_width = width;
+ dst_height = height;
+ rot_src_w = src_w;
+ rot_src_h = src_h;
+ rot_drw_w = drw_w;
+ rot_drw_h = drw_h;
+ }
+ else
+ {
+ dst_width = height;
+ dst_height = width;
+ rot_src_w = src_h;
+ rot_src_h = src_w;
+ rot_drw_w = drw_h;
+ rot_drw_h = drw_w;
+ }
+
+ switch (randr & RR_Rotate_All) {
+ case RR_Rotate_0:
+ dst_x1 = dstBox.x1;
+ dst_y1 = dstBox.y1;
+ dst_x2 = dstBox.x2;
+ dst_y2 = dstBox.y2;
+ rot_x1 = x1;
+ rot_y1 = y1;
+ rot_x2 = x2;
+ rot_y2 = y2;
+ break;
+ case RR_Rotate_90:
+ dst_x1 = dstBox.y1;
+ dst_y1 = screen->height - dstBox.x2;
+ dst_x2 = dstBox.y2;
+ dst_y2 = screen->height - dstBox.x1;
+
+ rot_x1 = y1;
+ rot_y1 = (src_w << 16) - x2;
+ rot_x2 = y2;
+ rot_y2 = (src_w << 16) - x1;
+ break;
+ case RR_Rotate_180:
+ dst_x1 = screen->width - dstBox.x2;
+ dst_y1 = screen->height - dstBox.y2;
+ dst_x2 = screen->width - dstBox.x1;
+ dst_y2 = screen->height - dstBox.y1;
+ rot_x1 = (src_w << 16) - x2;
+ rot_y1 = (src_h << 16) - y2;
+ rot_x2 = (src_w << 16) - x1;
+ rot_y2 = (src_h << 16) - y1;
+ break;
+ case RR_Rotate_270:
+ dst_x1 = screen->width - dstBox.y2;
+ dst_y1 = dstBox.x1;
+ dst_x2 = screen->width - dstBox.y1;
+ dst_y2 = dstBox.x2;
+ rot_x1 = (src_h << 16) - y2;
+ rot_y1 = x1;
+ rot_x2 = (src_h << 16) - y1;
+ rot_y2 = x2;
+ break;
+ }
+
+ switch(id) {
+ case FOURCC_YV12:
+ case FOURCC_I420:
+ dstPitch = ((dst_width << 1) + 15) & ~15;
+ srcPitch = (width + 3) & ~3;
+ srcPitch2 = ((width >> 1) + 3) & ~3;
+ size = dstPitch * (int) dst_height;
+ break;
+ case FOURCC_UYVY:
+ case FOURCC_YUY2:
+ default:
+ dstPitch = ((dst_width << 1) + 15) & ~15;
+ srcPitch = (width << 1);
+ size = dstPitch * (int) dst_height;
+ break;
+ }
+
+ pPortPriv->offset = mach64s->off_screen - (CARD8 *) mach64s->vesa.fb;
+ /* fixup pointers */
+
+ pPortPriv->YBuf0Offset = pPortPriv->offset;
+ pPortPriv->YBuf1Offset = pPortPriv->offset + size;
+
+#if 0
+ mach64WaitIdle (reg);
+
+ if (pPortPriv->videoOn)
+ {
+ /* wait for buffer to be displayed */
+ while (((media->TRIG_CNTL >> 5) & 1) != pPortPriv->currentBuf)
+ ;
+ }
+#endif
+ /*
+ * Use the other buffer
+ */
+ pPortPriv->currentBuf = 1 - pPortPriv->currentBuf;
+
+ /* copy data */
+ top = rot_y1 >> 16;
+ left = (rot_x1 >> 16) & ~1;
+ npixels = ((((rot_x2 + 0xffff) >> 16) + 1) & ~1) - left;
+
+ switch(id) {
+ case FOURCC_YV12:
+ case FOURCC_I420:
+ top &= ~1;
+ nlines = ((((rot_y2 + 0xffff) >> 16) + 1) & ~1) - top;
+ mach64CopyPlanarData(screen, buf, randr,
+ srcPitch, srcPitch2, dstPitch,
+ rot_src_w, rot_src_h, height,
+ top, left, nlines, npixels, id);
+ break;
+ case FOURCC_UYVY:
+ case FOURCC_YUY2:
+ default:
+ nlines = ((rot_y2 + 0xffff) >> 16) - top;
+ mach64CopyPackedData(screen, buf, randr,
+ srcPitch, dstPitch,
+ rot_src_w, rot_src_h,
+ top, left, nlines,
+ npixels);
+ break;
+ }
+
+ mach64DisplayVideo(screen, id, dstPitch,
+ rot_x1, rot_y1, rot_x2, rot_y2,
+ dst_x1, dst_y1,
+ dst_x2, dst_y2,
+ rot_src_w, rot_src_h, rot_drw_w, rot_drw_h);
+
+ /* update cliplist */
+ if (!REGION_EQUAL (screen->pScreen, &pPortPriv->clip, clipBoxes))
+ {
+ REGION_COPY (screen->pScreen, &pPortPriv->clip, clipBoxes);
+ mach64PaintRegion (screen->pScreen, &pPortPriv->clip, pPortPriv->colorKey);
+ }
+
+ pPortPriv->videoOn = TRUE;
+
+ return Success;
+}
+
+static int
+mach64QueryImageAttributes(KdScreenInfo *screen,
+ int id,
+ unsigned short *w,
+ unsigned short *h,
+ int *pitches,
+ int *offsets)
+{
+ int size, tmp;
+
+ if(*w > IMAGE_MAX_WIDTH)
+ *w = IMAGE_MAX_WIDTH;
+ if(*h > IMAGE_MAX_HEIGHT)
+ *h = IMAGE_MAX_HEIGHT;
+
+ *w = (*w + 1) & ~1;
+ if(offsets) offsets[0] = 0;
+
+ switch(id) {
+ case FOURCC_YV12:
+ case FOURCC_I420:
+ *h = (*h + 1) & ~1;
+ size = (*w + 3) & ~3;
+ if(pitches)
+ pitches[0] = size;
+ size *= *h;
+ if(offsets)
+ offsets[1] = size;
+ tmp = ((*w >> 1) + 3) & ~3;
+ if(pitches)
+ pitches[1] = pitches[2] = tmp;
+ tmp *= (*h >> 1);
+ size += tmp;
+ if(offsets)
+ offsets[2] = size;
+ size += tmp;
+ break;
+ case FOURCC_UYVY:
+ case FOURCC_YUY2:
+ default:
+ size = *w << 1;
+ if(pitches)
+ pitches[0] = size;
+ size *= *h;
+ break;
+ }
+
+ return size;
+}
+
+
+/* client libraries expect an encoding */
+static KdVideoEncodingRec DummyEncoding[1] =
+{
+ {
+ 0,
+ "XV_IMAGE",
+ IMAGE_MAX_WIDTH, IMAGE_MAX_HEIGHT,
+ {1, 1}
+ }
+};
+
+#define NUM_FORMATS 3
+
+static KdVideoFormatRec Formats[NUM_FORMATS] =
+{
+ {15, TrueColor}, {16, TrueColor}, {24, TrueColor}
+};
+
+#define NUM_ATTRIBUTES 3
+
+static KdAttributeRec Attributes[NUM_ATTRIBUTES] =
+{
+ {XvSettable | XvGettable, 0, ~0, "XV_COLORKEY"},
+ {XvSettable | XvGettable, -1000, 1000, "XV_BRIGHTNESS"},
+ {XvSettable | XvGettable, -1000, 1000, "XV_SATURATION"}
+};
+
+#define NUM_IMAGES 4
+
+static KdImageRec Images[NUM_IMAGES] =
+{
+ XVIMAGE_YUY2,
+ XVIMAGE_YV12,
+ XVIMAGE_I420,
+ XVIMAGE_UYVY
+};
+
+static void mach64ResetVideo(KdScreenInfo *screen)
+{
+ ScreenPtr pScreen = screen->pScreen;
+ KdScreenPriv(pScreen);
+ KdCardInfo *card = pScreenPriv->card;
+ Mach64ScreenInfo *mach64s = (Mach64ScreenInfo *) screen->driver;
+ Mach64CardInfo *mach64c = (Mach64CardInfo *) card->driver;
+ Mach64PortPrivPtr pPortPriv = mach64s->pAdaptor->pPortPrivates[0].ptr;
+ MediaReg *media = mach64c->media_reg;
+
+ /*
+ * Default to maximum image size in YV12
+ */
+
+}
+
+static int
+mach64ReputImage (KdScreenInfo *screen,
+ short drw_x,
+ short drw_y,
+ RegionPtr clipBoxes,
+ pointer data)
+{
+ ScreenPtr pScreen = screen->pScreen;
+ Mach64PortPrivPtr pPortPriv = (Mach64PortPrivPtr)data;
+ BoxPtr pOldExtents = REGION_EXTENTS (pScreen, &pPortPriv->clip);
+ BoxPtr pNewExtents = REGION_EXTENTS (pScreen, clipBoxes);
+
+ if (pOldExtents->x1 == pNewExtents->x1 &&
+ pOldExtents->x2 == pNewExtents->x2 &&
+ pOldExtents->y1 == pNewExtents->y1 &&
+ pOldExtents->y2 == pNewExtents->y2)
+ {
+ /* update cliplist */
+ if (!REGION_EQUAL (screen->pScreen, &pPortPriv->clip, clipBoxes))
+ {
+ REGION_COPY (screen->pScreen, &pPortPriv->clip, clipBoxes);
+ mach64PaintRegion (screen->pScreen, &pPortPriv->clip, pPortPriv->colorKey);
+ }
+ return Success;
+ }
+ return BadMatch;
+}
+
+static KdVideoAdaptorPtr
+mach64SetupImageVideo(ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ mach64CardInfo(pScreenPriv);
+ mach64ScreenInfo(pScreenPriv);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ KdCardInfo *card = pScreenPriv->card;
+ KdVideoAdaptorPtr adapt;
+ Mach64PortPrivPtr pPortPriv;
+
+ if(!(adapt = xcalloc(1, sizeof(KdVideoAdaptorRec) +
+ sizeof(Mach64PortPrivRec) +
+ sizeof(DevUnion))))
+ return NULL;
+
+ adapt->type = XvWindowMask | XvInputMask | XvImageMask;
+ adapt->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT;
+ adapt->name = "Mach64 Video Overlay";
+ adapt->nEncodings = 1;
+ adapt->pEncodings = DummyEncoding;
+ adapt->nFormats = NUM_FORMATS;
+ adapt->pFormats = Formats;
+ adapt->nPorts = 1;
+ adapt->pPortPrivates = (DevUnion*)(&adapt[1]);
+
+ pPortPriv = (Mach64PortPrivPtr)(&adapt->pPortPrivates[1]);
+
+ adapt->pPortPrivates[0].ptr = (pointer)(pPortPriv);
+ adapt->pAttributes = Attributes;
+ adapt->nImages = NUM_IMAGES;
+ adapt->nAttributes = NUM_ATTRIBUTES;
+ adapt->pImages = Images;
+ adapt->PutVideo = NULL;
+ adapt->PutStill = NULL;
+ adapt->GetVideo = NULL;
+ adapt->GetStill = NULL;
+ adapt->StopVideo = mach64StopVideo;
+ adapt->SetPortAttribute = mach64SetPortAttribute;
+ adapt->GetPortAttribute = mach64GetPortAttribute;
+ adapt->QueryBestSize = mach64QueryBestSize;
+ adapt->PutImage = mach64PutImage;
+ adapt->ReputImage = mach64ReputImage;
+ adapt->QueryImageAttributes = mach64QueryImageAttributes;
+
+ pPortPriv->colorKey = mach64s->colorKey;
+ pPortPriv->videoOn = FALSE;
+ pPortPriv->brightness = 0;
+ pPortPriv->saturation = 0;
+ pPortPriv->currentBuf = 0;
+
+ /* gotta uninit this someplace */
+ REGION_INIT(pScreen, &pPortPriv->clip, NullBox, 0);
+
+ mach64s->pAdaptor = adapt;
+
+ xvBrightness = MAKE_ATOM("XV_BRIGHTNESS");
+ xvSaturation = MAKE_ATOM("XV_SATURATION");
+ xvColorKey = MAKE_ATOM("XV_COLORKEY");
+
+ mach64ResetVideo(screen);
+
+ return adapt;
+}
+
+Bool mach64InitVideo(ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ KdVideoAdaptorPtr *adaptors, *newAdaptors = NULL;
+ KdVideoAdaptorPtr newAdaptor = NULL;
+ int num_adaptors;
+ KdCardInfo *card = pScreenPriv->card;
+ Mach64ScreenInfo *mach64s = (Mach64ScreenInfo *) screen->driver;
+ Mach64CardInfo *mach64c = (Mach64CardInfo *) card->driver;
+
+ if (!mach64c->media_reg)
+ return FALSE;
+
+ newAdaptor = mach64SetupImageVideo(pScreen);
+
+ num_adaptors = KdXVListGenericAdaptors(screen, &adaptors);
+
+ if(newAdaptor)
+ {
+ if(!num_adaptors)
+ {
+ num_adaptors = 1;
+ adaptors = &newAdaptor;
+ }
+ else
+ {
+ newAdaptors = xalloc((num_adaptors + 1) *
+ sizeof(KdVideoAdaptorPtr*));
+ if(newAdaptors)
+ {
+ memcpy(newAdaptors, adaptors,
+ num_adaptors * sizeof(KdVideoAdaptorPtr));
+ newAdaptors[num_adaptors] = newAdaptor;
+ adaptors = newAdaptors;
+ num_adaptors++;
+ }
+ }
+ }
+
+ if(num_adaptors)
+ KdXVScreenInit(pScreen, adaptors, num_adaptors);
+
+ if(newAdaptors)
+ xfree(newAdaptors);
+ return TRUE;
+}