summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--xc/programs/Xserver/fb/Imakefile83
-rw-r--r--xc/programs/Xserver/fb/fb.h1280
-rw-r--r--xc/programs/Xserver/fb/fballpriv.c48
-rw-r--r--xc/programs/Xserver/fb/fbarc.c109
-rw-r--r--xc/programs/Xserver/fb/fbbits.c93
-rw-r--r--xc/programs/Xserver/fb/fbbits.h496
-rw-r--r--xc/programs/Xserver/fb/fbblt.c900
-rw-r--r--xc/programs/Xserver/fb/fbbltone.c732
-rw-r--r--xc/programs/Xserver/fb/fbbstore.c62
-rw-r--r--xc/programs/Xserver/fb/fbcmap.c593
-rw-r--r--xc/programs/Xserver/fb/fbcopy.c629
-rw-r--r--xc/programs/Xserver/fb/fbfill.c206
-rw-r--r--xc/programs/Xserver/fb/fbfillrect.c111
-rw-r--r--xc/programs/Xserver/fb/fbfillsp.c99
-rw-r--r--xc/programs/Xserver/fb/fbgc.c192
-rw-r--r--xc/programs/Xserver/fb/fbgetsp.c67
-rw-r--r--xc/programs/Xserver/fb/fbglyph.c404
-rw-r--r--xc/programs/Xserver/fb/fbimage.c328
-rw-r--r--xc/programs/Xserver/fb/fbline.c90
-rw-r--r--xc/programs/Xserver/fb/fbpixmap.c362
-rw-r--r--xc/programs/Xserver/fb/fbpoint.c155
-rw-r--r--xc/programs/Xserver/fb/fbpush.c243
-rw-r--r--xc/programs/Xserver/fb/fbrop.h116
-rw-r--r--xc/programs/Xserver/fb/fbscreen.c222
-rw-r--r--xc/programs/Xserver/fb/fbseg.c736
-rw-r--r--xc/programs/Xserver/fb/fbsetsp.c93
-rw-r--r--xc/programs/Xserver/fb/fbsolid.c210
-rw-r--r--xc/programs/Xserver/fb/fbstipple.c225
-rw-r--r--xc/programs/Xserver/fb/fbtile.c198
-rw-r--r--xc/programs/Xserver/fb/fbutil.c337
-rw-r--r--xc/programs/Xserver/fb/fbwindow.c284
-rw-r--r--xc/programs/Xserver/hw/kdrive/Imakefile20
-rw-r--r--xc/programs/Xserver/hw/kdrive/fbdev/Imakefile15
-rw-r--r--xc/programs/Xserver/hw/kdrive/fbdev/fbdev.c264
-rw-r--r--xc/programs/Xserver/hw/kdrive/fbdev/fbdev.h84
-rw-r--r--xc/programs/Xserver/hw/kdrive/fbdev/fbinit.c80
-rw-r--r--xc/programs/Xserver/hw/kdrive/itsy/Imakefile15
-rw-r--r--xc/programs/Xserver/hw/kdrive/itsy/itsy.c318
-rw-r--r--xc/programs/Xserver/hw/kdrive/itsy/itsy.h42
-rw-r--r--xc/programs/Xserver/hw/kdrive/itsy/kbd.c234
-rw-r--r--xc/programs/Xserver/hw/kdrive/itsy/ts.c209
-rw-r--r--xc/programs/Xserver/hw/kdrive/kasync.c294
-rw-r--r--xc/programs/Xserver/hw/kdrive/kcmap.c231
-rw-r--r--xc/programs/Xserver/hw/kdrive/kcolor.c881
-rw-r--r--xc/programs/Xserver/hw/kdrive/kcurscol.c92
-rw-r--r--xc/programs/Xserver/hw/kdrive/kdrive.c897
-rw-r--r--xc/programs/Xserver/hw/kdrive/kdrive.h527
-rw-r--r--xc/programs/Xserver/hw/kdrive/keyboard.c440
-rw-r--r--xc/programs/Xserver/hw/kdrive/kinfo.c110
-rw-r--r--xc/programs/Xserver/hw/kdrive/kinput.c1335
-rw-r--r--xc/programs/Xserver/hw/kdrive/kkeymap.c235
-rw-r--r--xc/programs/Xserver/hw/kdrive/kkeymap.h53
-rw-r--r--xc/programs/Xserver/hw/kdrive/kloadmap.c200
-rw-r--r--xc/programs/Xserver/hw/kdrive/kmap.c92
-rw-r--r--xc/programs/Xserver/hw/kdrive/kmode.c313
-rw-r--r--xc/programs/Xserver/hw/kdrive/knoop.c294
-rw-r--r--xc/programs/Xserver/hw/kdrive/ktest.c76
-rw-r--r--xc/programs/Xserver/hw/kdrive/linux.c322
-rw-r--r--xc/programs/Xserver/hw/kdrive/linux/Imakefile16
-rw-r--r--xc/programs/Xserver/hw/kdrive/linux/keyboard.c439
-rw-r--r--xc/programs/Xserver/hw/kdrive/linux/linux.c329
-rw-r--r--xc/programs/Xserver/hw/kdrive/linux/ps2.c131
-rw-r--r--xc/programs/Xserver/hw/kdrive/ps2.c132
-rw-r--r--xc/programs/Xserver/hw/kdrive/savage/Imakefile15
-rw-r--r--xc/programs/Xserver/hw/kdrive/savage/s3.c1462
-rw-r--r--xc/programs/Xserver/hw/kdrive/savage/s3.h559
-rw-r--r--xc/programs/Xserver/hw/kdrive/savage/s3.nick41
-rw-r--r--xc/programs/Xserver/hw/kdrive/savage/s3clock.c86
-rw-r--r--xc/programs/Xserver/hw/kdrive/savage/s3cmap.c87
-rw-r--r--xc/programs/Xserver/hw/kdrive/savage/s3curs.c405
-rw-r--r--xc/programs/Xserver/hw/kdrive/savage/s3draw.c2432
-rw-r--r--xc/programs/Xserver/hw/kdrive/savage/s3draw.h459
-rw-r--r--xc/programs/Xserver/hw/kdrive/savage/s3gc.c384
-rw-r--r--xc/programs/Xserver/hw/kdrive/savage/s3reg.c1241
-rw-r--r--xc/programs/Xserver/hw/kdrive/savage/s3reg.h218
-rw-r--r--xc/programs/Xserver/hw/kdrive/savage/s3rtst.c141
-rw-r--r--xc/programs/Xserver/hw/kdrive/savage/s3stub.c87
-rw-r--r--xc/programs/Xserver/hw/kdrive/sis530/Imakefile15
-rw-r--r--xc/programs/Xserver/hw/kdrive/sis530/sis.c955
-rw-r--r--xc/programs/Xserver/hw/kdrive/sis530/sis.h1153
-rw-r--r--xc/programs/Xserver/hw/kdrive/sis530/sisclock.c232
-rw-r--r--xc/programs/Xserver/hw/kdrive/sis530/siscmap.c64
-rw-r--r--xc/programs/Xserver/hw/kdrive/sis530/siscurs.c364
-rw-r--r--xc/programs/Xserver/hw/kdrive/sis530/sisdraw.c1669
-rw-r--r--xc/programs/Xserver/hw/kdrive/sis530/sisdraw.h183
-rw-r--r--xc/programs/Xserver/hw/kdrive/sis530/sisio.c30
-rw-r--r--xc/programs/Xserver/hw/kdrive/sis530/sisstub.c53
-rw-r--r--xc/programs/Xserver/hw/kdrive/trident/Imakefile15
-rw-r--r--xc/programs/Xserver/hw/kdrive/trident/trident.c287
-rw-r--r--xc/programs/Xserver/hw/kdrive/trident/trident.h217
-rw-r--r--xc/programs/Xserver/hw/kdrive/trident/tridentcurs.c389
-rw-r--r--xc/programs/Xserver/hw/kdrive/trident/tridentdraw.c874
-rw-r--r--xc/programs/Xserver/hw/kdrive/trident/tridentdraw.h66
-rw-r--r--xc/programs/Xserver/hw/kdrive/trident/tridentstub.c54
-rw-r--r--xc/programs/Xserver/hw/kdrive/trio/Imakefile21
-rw-r--r--xc/programs/Xserver/hw/kdrive/trio/s3.c1010
-rw-r--r--xc/programs/Xserver/hw/kdrive/trio/s3.h1196
-rw-r--r--xc/programs/Xserver/hw/kdrive/trio/s3clock.c85
-rw-r--r--xc/programs/Xserver/hw/kdrive/trio/s3cmap.c70
-rw-r--r--xc/programs/Xserver/hw/kdrive/trio/s3curs.c416
-rw-r--r--xc/programs/Xserver/hw/kdrive/trio/s3stub.c59
-rw-r--r--xc/programs/Xserver/hw/kdrive/ts300/Imakefile15
-rw-r--r--xc/programs/Xserver/hw/kdrive/ts300/ts300.c130
-rw-r--r--xc/programs/Xserver/hw/kdrive/vga.c323
-rw-r--r--xc/programs/Xserver/hw/kdrive/vga.h141
-rw-r--r--xc/programs/Xserver/hw/kdrive/vxworks/Imakefile15
-rw-r--r--xc/programs/Xserver/hw/kdrive/vxworks/vxkbd.c262
-rw-r--r--xc/programs/Xserver/hw/kdrive/vxworks/vxmouse.c121
-rw-r--r--xc/programs/Xserver/hw/kdrive/vxworks/vxworks.c65
109 files changed, 36589 insertions, 0 deletions
diff --git a/xc/programs/Xserver/fb/Imakefile b/xc/programs/Xserver/fb/Imakefile
new file mode 100644
index 000000000..eae1fc979
--- /dev/null
+++ b/xc/programs/Xserver/fb/Imakefile
@@ -0,0 +1,83 @@
+XCOMM $XFree86: xc/programs/Xserver/fb/Imakefile,v 1.1 1999/11/19 13:53:40 hohndel Exp $
+XCOMM
+XCOMM
+XCOMM $Id: Imakefile,v 1.1 2000/01/06 12:56:51 faith Exp $
+#include <Server.tmpl>
+
+#ifdef FbNoPixelAddrCode
+DEFINES=-DFBNOPIXADDR -DFBNO24BIT
+#endif
+
+SRCS = fbarc.c \
+ fballpriv.c \
+ fbbits.c \
+ fbblt.c \
+ fbbltone.c \
+ fbbstore.c \
+ fbcmap.c \
+ fbcopy.c \
+ fbfill.c \
+ fbfillrect.c \
+ fbfillsp.c \
+ fbgc.c \
+ fbgetsp.c \
+ fbglyph.c \
+ fbimage.c \
+ fbline.c \
+ fbpixmap.c \
+ fbpoint.c \
+ fbpush.c \
+ fbscreen.c \
+ fbseg.c \
+ fbsetsp.c \
+ fbsolid.c \
+ fbstipple.c \
+ fbtile.c \
+ fbutil.c \
+ fbwindow.c
+
+OBJS = fbarc.o \
+ fballpriv.o \
+ fbbits.o \
+ fbblt.o \
+ fbbltone.o \
+ fbbstore.o \
+ fbcmap.o \
+ fbcopy.o \
+ fbfill.o \
+ fbfillrect.o \
+ fbfillsp.o \
+ fbgc.o \
+ fbgetsp.o \
+ fbglyph.o \
+ fbimage.o \
+ fbline.o \
+ fbpixmap.o \
+ fbpoint.o \
+ fbpush.o \
+ fbscreen.o \
+ fbseg.o \
+ fbsetsp.o \
+ fbsolid.o \
+ fbstipple.o \
+ fbtile.o \
+ fbutil.o \
+ fbwindow.o
+
+ INCLUDES = -I. -I../mi -I../include -I$(XINCLUDESRC) \
+ -I$(FONTINCSRC) $(EXTRAINCLUDES)
+ LINTLIBS = ../dix/llib-ldix.ln ../os/llib-los.ln \
+ ../mi/llib-lmi.ln
+
+ CCOPTIONS=-ansi
+
+NormalLibraryObjectRule()
+NormalLibraryTarget(fb,$(OBJS))
+LintLibraryTarget(fb,$(SRCS))
+
+NormalLintTarget($(SRCS))
+
+#ifndef OS2Architecture
+DependTarget()
+#endif
+
diff --git a/xc/programs/Xserver/fb/fb.h b/xc/programs/Xserver/fb/fb.h
new file mode 100644
index 000000000..5c1fd311b
--- /dev/null
+++ b/xc/programs/Xserver/fb/fb.h
@@ -0,0 +1,1280 @@
+/*
+ * $Id: fb.h,v 1.1 2000/01/06 12:56:51 faith Exp $
+ *
+ * Copyright © 1998 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/fb/fb.h,v 1.3 1999/12/30 02:33:58 robin Exp $ */
+
+#ifndef _FB_H_
+#define _FB_H_
+
+#include "X.h"
+#include "scrnintstr.h"
+#include "pixmap.h"
+#include "pixmapstr.h"
+#include "region.h"
+#include "gcstruct.h"
+#include "colormap.h"
+#include "miscstruct.h"
+#include "servermd.h"
+#include "windowstr.h"
+#include "mi.h"
+#include "migc.h"
+#include "mibstore.h"
+
+/*
+ * This single define controls the basic size of data manipulated
+ * by this software; it must be log2(sizeof (FbBits) * 8)
+ */
+#ifdef VXWORKS
+#define FB_SHIFT 5
+#else
+#define FB_SHIFT 6
+#endif
+#define FB_UNIT (1 << FB_SHIFT)
+#define FB_HALFUNIT (1 << (FB_SHIFT-1))
+#define FB_MASK (FB_UNIT - 1)
+#define FB_ALLONES ((FbBits) -1)
+
+#if GLYPHPADBYTES != 4
+#error "GLYPHPADBYTES must be 4"
+#endif
+#if GETLEFTBITS_ALIGNMENT != 1
+#error "GETLEFTBITS_ALIGNMENT must be 1"
+#endif
+/* whether to bother to include 24bpp support */
+#ifndef FBNO24BIT
+#define FB_24BIT
+#endif
+
+#define FB_STIP_SHIFT LOG2_BITMAP_PAD
+#define FB_STIP_UNIT (1 << FB_STIP_SHIFT)
+#define FB_STIP_MASK (FB_STIP_UNIT - 1)
+#define FB_STIP_ALLONES ((FbStip) -1)
+
+#define FB_STIP_ODDSTRIDE(s) (((s) & (FB_MASK >> FB_STIP_SHIFT)) != 0)
+#define FB_STIP_ODDPTR(p) ((((int) (p)) & (FB_MASK >> 3)) != 0)
+
+#define FbStipStrideToBitsStride(s) (((s) >> (FB_SHIFT - FB_STIP_SHIFT)))
+#define FbBitsStrideToStipStride(s) (((s) << (FB_SHIFT - FB_STIP_SHIFT)))
+
+#define FbFullMask(n) ((n) == FB_UNIT ? FB_ALLONES : ((((FbBits) 1) << n) - 1))
+
+#if FB_SHIFT == 6
+#ifdef WIN32
+typedef unsigned __int64 FbBits;
+#else
+typedef unsigned long long FbBits;
+#endif
+#endif
+#if FB_SHIFT == 5
+typedef unsigned long FbBits;
+#endif
+typedef unsigned long FbStip;
+typedef int FbStride;
+
+
+#ifdef FB_DEBUG
+extern void fbValidateDrawable(DrawablePtr d);
+extern void fbInitializeDrawable(DrawablePtr d);
+extern void fbSetBits (FbStip *bits, int stride, FbStip data);
+#define FB_HEAD_BITS (FbStip) (0xbaadf00d)
+#define FB_TAIL_BITS (FbStip) (0xbaddf0ad)
+#else
+#define fbValidateDrawable(d)
+#define fdInitializeDrawable(d)
+#endif
+
+#include "fbrop.h"
+
+#if BITMAP_BIT_ORDER == LSBFirst
+#define FbScrLeft(x,n) ((x) >> (n))
+#define FbScrRight(x,n) ((x) << (n))
+/* #define FbLeftBits(x,n) ((x) & ((((FbBits) 1) << (n)) - 1)) */
+#define FbLeftStipBits(x,n) ((x) & ((((FbStip) 1) << (n)) - 1))
+#define FbStipMoveLsb(x,s,n) (FbStipRight (x,(s)-(n)))
+#else
+#define FbScrLeft(x,n) ((x) << (n))
+#define FbScrRight(x,n) ((x) >> (n))
+/* #define FbLeftBits(x,n) ((x) >> (FB_UNIT - (n))) */
+#define FbLeftStipBits(x,n) ((x) >> (FB_STIP_UNIT - (n)))
+#define FbStipMoveLsb(x,s,n) (x)
+#endif
+
+#define GetHighWord(x) (((int) (x)) >> 16)
+
+#if IMAGE_BYTE_ORDER == MSBFirst
+#define intToCoord(i,x,y) (((x) = GetHighWord(i)), ((y) = (int) ((short) (i))))
+#define coordToInt(x,y) (((x) << 16) | (y))
+#define intToX(i) (GetHighWord(i))
+#define intToY(i) ((int) ((short) i))
+#else
+#define intToCoord(i,x,y) (((x) = (int) ((short) (i))), ((y) = GetHighWord(i)))
+#define coordToInt(x,y) (((y) << 16) | (x))
+#define intToX(i) ((int) ((short) (i)))
+#define intToY(i) (GetHighWord(i))
+#endif
+
+#define FbStipLeft(x,n) FbScrLeft(x,n)
+#define FbStipRight(x,n) FbScrRight(x,n)
+
+#define FbRotLeft(x,n) FbScrLeft(x,n) | (n ? FbScrRight(x,FB_UNIT-n) : 0)
+#define FbRotRight(x,n) FbScrRight(x,n) | (n ? FbScrLeft(x,FB_UNIT-n) : 0)
+
+#define FbLeftMask(x) ( ((x) & FB_MASK) ? \
+ FbScrRight(FB_ALLONES,(x) & FB_MASK) : 0)
+#define FbRightMask(x) ( ((FB_UNIT - (x)) & FB_MASK) ? \
+ FbScrLeft(FB_ALLONES,(FB_UNIT - (x)) & FB_MASK) : 0)
+
+#define FbBitsMask(x,w) (FbScrRight(FB_ALLONES,(x) & FB_MASK) & \
+ FbScrLeft(FB_ALLONES,(FB_UNIT - ((x) + (w))) & FB_MASK))
+
+#define FbStipMask(x,w) (FbStipRight(FB_STIP_ALLONES,(x) & FB_STIP_MASK) & \
+ FbStipLeft(FB_STIP_ALLONES,(FB_STIP_UNIT - ((x)+(w))) & FB_STIP_MASK))
+
+
+#define FbMaskBits(x,w,l,n,r) { \
+ n = (w); \
+ r = FbRightMask((x)+n); \
+ l = FbLeftMask(x); \
+ if (l) { \
+ n -= FB_UNIT - ((x) & FB_MASK); \
+ if (n < 0) { \
+ n = 0; \
+ l &= r; \
+ r = 0; \
+ } \
+ } \
+ n >>= FB_SHIFT; \
+}
+
+/* Rotate a filled pixel value to the specified alignement */
+#define FbRot24(p,b) (FbScrRight(p,b) | FbScrLeft(p,24-(b)))
+
+/* step a filled pixel value to the next/previous FB_UNIT alignment */
+#define FbNext24Pix(p) (FbRot24(p,(24-FB_UNIT%24)))
+#define FbPrev24Pix(p) (FbRot24(p,FB_UNIT%24))
+#define FbNext24Stip(p) (FbRot24(p,(24-FB_STIP_UNIT%24)))
+#define FbPrev24Stip(p) (FbRot24(p,FB_STIP_UNIT%24))
+
+/* step a rotation value to the next/previous rotation value */
+#if FB_UNIT == 64
+#define FbNext24Rot(r) ((r) == 16 ? 0 : (r) + 8)
+#define FbPrev24Rot(r) ((r) == 0 ? 16 : (r) - 8)
+#endif
+#if FB_UNIT == 32
+#define FbNext24Rot(r) ((r) == 0 ? 16 : (r) - 8)
+#define FbPrev24Rot(r) ((r) == 16 ? 0 : (r) + 8)
+#endif
+
+#define FbNext24RotStip(r) ((r) == 0 ? 16 : (r) - 8)
+#define FbPrev24RotStip(r) ((r) == 16 ? 0 : (r) + 8)
+
+/* Whether 24-bit specific code is needed for this filled pixel value */
+#define FbCheck24Pix(p) ((p) == FbNext24Pix(p))
+
+extern int fbGCPrivateIndex;
+extern const GCOps fbGCOps;
+extern const GCFuncs fbGCFuncs;
+
+#ifdef TEKX11
+#define FB_OLD_GC
+#define FB_OLD_SCREEN
+#endif
+
+/* private field of GC */
+typedef struct {
+#ifdef FB_OLD_GC
+ unsigned char pad1;
+ unsigned char pad2;
+ unsigned char pad3;
+ unsigned fExpose:1;
+ unsigned freeCompClip:1;
+ PixmapPtr pRotatedPixmap;
+ RegionPtr pCompositeClip;
+#endif
+ FbBits and, xor; /* reduced rop values */
+ FbBits bgand, bgxor; /* for stipples */
+ FbBits fg, bg, pm; /* expanded and filled */
+ unsigned int dashLength; /* total of all dash elements */
+ Bool oneRect; /* clip list is single rectangle */
+} FbGCPrivRec, *FbGCPrivPtr;
+
+#define fbGetGCPrivate(pGC) ((FbGCPrivPtr)\
+ (pGC)->devPrivates[fbGCPrivateIndex].ptr)
+
+#ifdef FB_OLD_GC
+#define fbGetCompositeClip(pGC) (fbGetGCPrivate(pGC)->pCompositeClip)
+#define fbGetExpose(pGC) (fbGetGCPrivate(pGC)->fExpose)
+#define fbGetFreeCompClip(pGC) (fbGetGCPrivate(pGC)->freeCompClip)
+#define fbGetRotatedPixmap(pGC) (fbGetGCPrivate(pGC)->pRotatedPixmap)
+#else
+#define fbGetCompositeClip(pGC) ((pGC)->pCompositeClip)
+#define fbGetExpose(pGC) ((pGC)->fExpose)
+#define fbGetFreeCompClip(pGC) ((pGC)->freeCompClip)
+#define fbGetRotatedPixmap(pGC) ((pGC)->pRotatedPixmap)
+#endif
+
+#define fbGetScreenPixmap(s) ((PixmapPtr) (s)->devPrivate)
+#define fbGetWindowPixmap(d) fbGetScreenPixmap((d)->pScreen)
+
+#define fbGetDrawable(pDrawable, pointer, stride, bpp) { \
+ PixmapPtr _pPix; \
+ if ((pDrawable)->type != DRAWABLE_PIXMAP) \
+ _pPix = fbGetWindowPixmap(pDrawable); \
+ else \
+ _pPix = (PixmapPtr) (pDrawable); \
+ (pointer) = (FbBits *) _pPix->devPrivate.ptr; \
+ (stride) = ((int) _pPix->devKind) / sizeof (FbBits); \
+ (bpp) = _pPix->drawable.bitsPerPixel; \
+}
+
+#define fbGetStipDrawable(pDrawable, pointer, stride, bpp) { \
+ PixmapPtr _pPix; \
+ if ((pDrawable)->type != DRAWABLE_PIXMAP) \
+ _pPix = fbGetWindowPixmap(pDrawable); \
+ else \
+ _pPix = (PixmapPtr) (pDrawable); \
+ (pointer) = (FbStip *) _pPix->devPrivate.ptr; \
+ (stride) = ((int) _pPix->devKind) / sizeof (FbStip); \
+ (bpp) = _pPix->drawable.bitsPerPixel; \
+}
+
+#ifdef FB_OLD_SCREEN
+#define BitsPerPixel(d) (\
+ ((1 << PixmapWidthPaddingInfo[d].padBytesLog2) * 8 / \
+ (PixmapWidthPaddingInfo[d].padRoundUp+1)))
+#endif
+
+#define FbPowerOfTwo(w) (((w) & ((w) - 1)) == 0)
+/*
+ * Accelerated tiles are power of 2 width <= FB_UNIT
+ */
+#define FbEvenTile(w) ((w) <= FB_UNIT && FbPowerOfTwo(w))
+/*
+ * Accelerated stipples are power of 2 width and <= FB_UNIT/dstBpp
+ * with dstBpp a power of 2 as well
+ */
+#define FbEvenStip(w,bpp) ((w) * (bpp) <= FB_UNIT && FbPowerOfTwo(w) && FbPowerOfTwo(bpp))
+
+/*
+ * fballpriv.c
+ */
+Bool
+fbAllocatePrivates(ScreenPtr pScreen, int *pGCIndex);
+
+/*
+ * fbarc.c
+ */
+
+void
+fbPolyArc (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int narcs,
+ xArc *parcs);
+
+/*
+ * fbbits.c
+ */
+
+void
+fbBresSolid8(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int dashOffset,
+ int signdx,
+ int signdy,
+ int axis,
+ int x1,
+ int y1,
+ int e,
+ int e1,
+ int e3,
+ int len);
+
+void
+fbBresDash8 (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int dashOffset,
+ int signdx,
+ int signdy,
+ int axis,
+ int x1,
+ int y1,
+ int e,
+ int e1,
+ int e3,
+ int len);
+
+void
+fbDots8 (FbBits *dst,
+ FbStride dstStride,
+ int dstBpp,
+ BoxPtr pBox,
+ xPoint *pts,
+ int npt,
+ FbBits and,
+ FbBits xor);
+
+void
+fbArc8 (FbBits *dst,
+ FbStride dstStride,
+ int dstBpp,
+ xArc *arc,
+ int dx,
+ int dy,
+ FbBits and,
+ FbBits xor);
+
+void
+fbGlyph8 (FbBits *dstLine,
+ FbStride dstStride,
+ int dstBpp,
+ FbStip *stipple,
+ FbBits fg,
+ int height,
+ int shift);
+
+void
+fbBresSolid16(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int dashOffset,
+ int signdx,
+ int signdy,
+ int axis,
+ int x1,
+ int y1,
+ int e,
+ int e1,
+ int e3,
+ int len);
+
+void
+fbBresDash16(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int dashOffset,
+ int signdx,
+ int signdy,
+ int axis,
+ int x1,
+ int y1,
+ int e,
+ int e1,
+ int e3,
+ int len);
+
+void
+fbDots16(FbBits *dst,
+ FbStride dstStride,
+ int dstBpp,
+ BoxPtr pBox,
+ xPoint *pts,
+ int npt,
+ FbBits and,
+ FbBits xor);
+
+void
+fbArc16(FbBits *dst,
+ FbStride dstStride,
+ int dstBpp,
+ xArc *arc,
+ int dx,
+ int dy,
+ FbBits and,
+ FbBits xor);
+
+void
+fbGlyph16(FbBits *dstLine,
+ FbStride dstStride,
+ int dstBpp,
+ FbStip *stipple,
+ FbBits fg,
+ int height,
+ int shift);
+
+void
+fbBresSolid32(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int dashOffset,
+ int signdx,
+ int signdy,
+ int axis,
+ int x1,
+ int y1,
+ int e,
+ int e1,
+ int e3,
+ int len);
+
+void
+fbBresDash32(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int dashOffset,
+ int signdx,
+ int signdy,
+ int axis,
+ int x1,
+ int y1,
+ int e,
+ int e1,
+ int e3,
+ int len);
+
+void
+fbDots32(FbBits *dst,
+ FbStride dstStride,
+ int dstBpp,
+ BoxPtr pBox,
+ xPoint *pts,
+ int npt,
+ FbBits and,
+ FbBits xor);
+
+void
+fbArc32(FbBits *dst,
+ FbStride dstStride,
+ int dstBpp,
+ xArc *arc,
+ int dx,
+ int dy,
+ FbBits and,
+ FbBits xor);
+
+void
+fbGlyph32(FbBits *dstLine,
+ FbStride dstStride,
+ int dstBpp,
+ FbStip *stipple,
+ FbBits fg,
+ int height,
+ int shift);
+/*
+ * fbblt.c
+ */
+void
+fbBlt (FbBits *src,
+ FbStride srcStride,
+ int srcX,
+
+ FbBits *dst,
+ FbStride dstStride,
+ int dstX,
+
+ int width,
+ int height,
+
+ int alu,
+ FbBits pm,
+ int bpp,
+
+ Bool reverse,
+ Bool upsidedown);
+
+void
+fbBlt24 (FbBits *srcLine,
+ FbStride srcStride,
+ int srcX,
+
+ FbBits *dstLine,
+ FbStride dstStride,
+ int dstX,
+
+ int width,
+ int height,
+
+ int alu,
+ FbBits pm,
+
+ Bool reverse,
+ Bool upsidedown);
+
+void
+fbBltStip (FbStip *src,
+ FbStride srcStride, /* in FbStip units, not FbBits units */
+ int srcX,
+
+ FbStip *dst,
+ FbStride dstStride, /* in FbStip units, not FbBits units */
+ int dstX,
+
+ int width,
+ int height,
+
+ int alu,
+ FbBits pm,
+ int bpp);
+
+/*
+ * fbbltone.c
+ */
+void
+fbBltOne (FbStip *src,
+ FbStride srcStride,
+ int srcX,
+ FbBits *dst,
+ FbStride dstStride,
+ int dstX,
+ int dstBpp,
+
+ int width,
+ int height,
+
+ FbBits fgand,
+ FbBits fbxor,
+ FbBits bgand,
+ FbBits bgxor);
+
+#ifdef FB_24BIT
+void
+fbBltOne24 (FbStip *src,
+ FbStride srcStride, /* FbStip units per scanline */
+ int srcX, /* bit position of source */
+ FbBits *dst,
+ FbStride dstStride, /* FbBits units per scanline */
+ int dstX, /* bit position of dest */
+ int dstBpp, /* bits per destination unit */
+
+ int width, /* width in bits of destination */
+ int height, /* height in scanlines */
+
+ FbBits fgand, /* rrop values */
+ FbBits fgxor,
+ FbBits bgand,
+ FbBits bgxor);
+#endif
+
+void
+fbBltPlane (FbBits *src,
+ FbStride srcStride,
+ int srcX,
+ int srcBpp,
+
+ FbStip *dst,
+ FbStride dstStride,
+ int dstX,
+
+ int width,
+ int height,
+
+ FbStip fgand,
+ FbStip fgxor,
+ FbStip bgand,
+ FbStip bgxor,
+ Pixel planeMask);
+
+/*
+ * fbbstore.c
+ */
+void
+fbSaveAreas(PixmapPtr pPixmap,
+ RegionPtr prgnSave,
+ int xorg,
+ int yorg,
+ WindowPtr pWin);
+
+void
+fbRestoreAreas(PixmapPtr pPixmap,
+ RegionPtr prgnRestore,
+ int xorg,
+ int yorg,
+ WindowPtr pWin);
+
+/*
+ * fbcmap.c
+ */
+int
+fbListInstalledColormaps(ScreenPtr pScreen, Colormap *pmaps);
+
+void
+fbInstallColormap(ColormapPtr pmap);
+
+void
+fbUninstallColormap(ColormapPtr pmap);
+
+void
+fbResolveColor(unsigned short *pred,
+ unsigned short *pgreen,
+ unsigned short *pblue,
+ VisualPtr pVisual);
+
+Bool
+fbInitializeColormap(ColormapPtr pmap);
+
+int
+fbExpandDirectColors (ColormapPtr pmap,
+ int ndef,
+ xColorItem *indefs,
+ xColorItem *outdefs);
+
+Bool
+fbCreateDefColormap(ScreenPtr pScreen);
+
+Bool
+fbSetVisualTypes (int depth, int visuals, int bitsPerRGB);
+
+Bool
+fbInitVisuals (VisualPtr *visualp,
+ DepthPtr *depthp,
+ int *nvisualp,
+ int *ndepthp,
+ int *rootDepthp,
+ VisualID *defaultVisp,
+ unsigned long sizes,
+ int bitsPerRGB);
+
+/*
+ * fbcopy.c
+ */
+
+typedef void (*fbCopyProc) (DrawablePtr pSrcDrawable,
+ DrawablePtr pDstDrawable,
+ GCPtr pGC,
+ BoxPtr pDstBox,
+ int nbox,
+ int dx,
+ int dy,
+ Bool reverse,
+ Bool upsidedown,
+ Pixel bitplane,
+ void *closure);
+
+void
+fbCopyNtoN (DrawablePtr pSrcDrawable,
+ DrawablePtr pDstDrawable,
+ GCPtr pGC,
+ BoxPtr pbox,
+ int nbox,
+ int dx,
+ int dy,
+ Bool reverse,
+ Bool upsidedown,
+ Pixel bitplane,
+ void *closure);
+
+void
+fbCopy1toN (DrawablePtr pSrcDrawable,
+ DrawablePtr pDstDrawable,
+ GCPtr pGC,
+ BoxPtr pbox,
+ int nbox,
+ int dx,
+ int dy,
+ Bool reverse,
+ Bool upsidedown,
+ Pixel bitplane,
+ void *closure);
+
+void
+fbCopyNto1 (DrawablePtr pSrcDrawable,
+ DrawablePtr pDstDrawable,
+ GCPtr pGC,
+ BoxPtr pbox,
+ int nbox,
+ int dx,
+ int dy,
+ Bool reverse,
+ Bool upsidedown,
+ Pixel bitplane,
+ void *closure);
+
+void
+fbCopyRegion (DrawablePtr pSrcDrawable,
+ DrawablePtr pDstDrawable,
+ GCPtr pGC,
+ RegionPtr pDstRegion,
+ int dx,
+ int dy,
+ fbCopyProc copyProc,
+ Pixel bitPlane,
+ void *closure);
+
+RegionPtr
+fbDoCopy (DrawablePtr pSrcDrawable,
+ DrawablePtr pDstDrawable,
+ GCPtr pGC,
+ int xIn,
+ int yIn,
+ int widthSrc,
+ int heightSrc,
+ int xOut,
+ int yOut,
+ fbCopyProc copyProc,
+ Pixel bitplane,
+ void *closure);
+
+RegionPtr
+fbCopyArea (DrawablePtr pSrcDrawable,
+ DrawablePtr pDstDrawable,
+ GCPtr pGC,
+ int xIn,
+ int yIn,
+ int widthSrc,
+ int heightSrc,
+ int xOut,
+ int yOut);
+
+RegionPtr
+fbCopyPlane (DrawablePtr pSrcDrawable,
+ DrawablePtr pDstDrawable,
+ GCPtr pGC,
+ int xIn,
+ int yIn,
+ int widthSrc,
+ int heightSrc,
+ int xOut,
+ int yOut,
+ unsigned long bitplane);
+
+/*
+ * fbfill.c
+ */
+void
+fbFill (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ int width,
+ int height);
+
+void
+fbSolidBoxClipped (DrawablePtr pDrawable,
+ RegionPtr pClip,
+ int x1,
+ int y1,
+ int x2,
+ int y2,
+ FbBits and,
+ FbBits xor);
+
+/*
+ * fbfillrect.c
+ */
+void
+fbPolyFillRect(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nrectInit,
+ xRectangle *prectInit);
+
+#define fbPolyFillArc miPolyFillArc
+
+/*
+ * fbfillsp.c
+ */
+void
+fbFillSpans (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nInit,
+ DDXPointPtr pptInit,
+ int *pwidthInit,
+ int fSorted);
+
+
+/*
+ * fbgc.c
+ */
+
+Bool
+fbCreateGC(GCPtr pGC);
+
+void
+fbPadPixmap (PixmapPtr pPixmap);
+
+void
+fbValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable);
+
+/*
+ * fbgetsp.c
+ */
+void
+fbGetSpans(DrawablePtr pDrawable,
+ int wMax,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int nspans,
+ char *pchardstStart);
+
+/*
+ * fbglyph.c
+ */
+void
+fbPolyGlyphBlt (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase);
+
+void
+fbImageGlyphBlt (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase);
+
+void
+fbGlyph24 (FbBits *dstBits,
+ FbStride dstStride,
+ int dstBpp,
+ FbStip *stipple,
+ FbBits fg,
+ int x,
+ int height);
+
+/*
+ * fbimage.c
+ */
+
+void
+fbPutImage (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int depth,
+ int x,
+ int y,
+ int w,
+ int h,
+ int leftPad,
+ int format,
+ char *pImage);
+
+void
+fbPutZImage (DrawablePtr pDrawable,
+ RegionPtr pClip,
+ int alu,
+ FbBits pm,
+ int x,
+ int y,
+ int width,
+ int height,
+ FbStip *src,
+ FbStride srcStride);
+
+void
+fbPutXYImage (DrawablePtr pDrawable,
+ RegionPtr pClip,
+ FbBits fg,
+ FbBits bg,
+ FbBits pm,
+ int alu,
+ Bool opaque,
+
+ int x,
+ int y,
+ int width,
+ int height,
+
+ FbStip *src,
+ FbStride srcStride,
+ int srcX);
+
+void
+fbGetImage (DrawablePtr pDrawable,
+ int x,
+ int y,
+ int w,
+ int h,
+ unsigned int format,
+ unsigned long planeMask,
+ char *d);
+/*
+ * fbline.c
+ */
+
+void
+fbPolyLine (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ DDXPointPtr ppt);
+
+#define fbPolySegment miPolySegment
+
+/*
+ * fbpixmap.c
+ */
+
+PixmapPtr
+fbCreatePixmap (ScreenPtr pScreen, int width, int height, int depth);
+
+Bool
+fbDestroyPixmap (PixmapPtr pPixmap);
+
+RegionPtr
+fbPixmapToRegion(PixmapPtr pPix);
+
+/*
+ * fbpoint.c
+ */
+
+void
+fbPolyPoint (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ xPoint *pptInit);
+
+/*
+ * fbpush.c
+ */
+void
+fbPushPattern (DrawablePtr pDrawable,
+ GCPtr pGC,
+
+ FbStip *src,
+ FbStride srcStride,
+ int srcX,
+
+ int x,
+ int y,
+
+ int width,
+ int height);
+
+void
+fbPushFill (DrawablePtr pDrawable,
+ GCPtr pGC,
+
+ FbStip *src,
+ FbStride srcStride,
+ int srcX,
+
+ int x,
+ int y,
+ int width,
+ int height);
+
+void
+fbPush1toN (DrawablePtr pSrcDrawable,
+ DrawablePtr pDstDrawable,
+ GCPtr pGC,
+ BoxPtr pbox,
+ int nbox,
+ int dx,
+ int dy,
+ Bool reverse,
+ Bool upsidedown,
+ Pixel bitplane,
+ void *closure);
+
+void
+fbPushPixels (GCPtr pGC,
+ PixmapPtr pBitmap,
+ DrawablePtr pDrawable,
+ int dx,
+ int dy,
+ int xOrg,
+ int yOrg);
+
+
+/*
+ * fbscreen.c
+ */
+
+Bool
+fbCloseScreen (int index, ScreenPtr pScreen);
+
+Bool
+fbRealizeFont(ScreenPtr pScreen, FontPtr pFont);
+
+Bool
+fbUnrealizeFont(ScreenPtr pScreen, FontPtr pFont);
+
+Bool
+fbSetupScreen(ScreenPtr pScreen,
+ pointer pbits, /* pointer to screen bitmap */
+ int xsize, /* in pixels */
+ int ysize,
+ int dpix, /* dots per inch */
+ int dpiy,
+ int width, /* pixel width of frame buffer */
+ int bpp); /* bits per pixel of frame buffer */
+
+Bool
+fbFinishScreenInit(ScreenPtr pScreen,
+ pointer pbits,
+ int xsize,
+ int ysize,
+ int dpix,
+ int dpiy,
+ int width,
+ int bpp);
+
+Bool
+fbScreenInit(ScreenPtr pScreen,
+ pointer pbits,
+ int xsize,
+ int ysize,
+ int dpix,
+ int dpiy,
+ int width,
+ int bpp);
+
+void
+fbInitializeBackingStore (ScreenPtr pScreen);
+
+/*
+ * fbseg.c
+ */
+typedef void (*FbBres) (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int dashOffset,
+ int signdx,
+ int signdy,
+ int axis,
+ int x1,
+ int y1,
+ int e,
+ int e1,
+ int e3,
+ int len);
+
+/*
+ * fbsetsp.c
+ */
+
+void
+fbSetSpans (DrawablePtr pDrawable,
+ GCPtr pGC,
+ char *src,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int nspans,
+ int fSorted);
+
+/*
+ * fbsolid.c
+ */
+
+void
+fbSolid (FbBits *dst,
+ FbStride dstStride,
+ int dstX,
+ int bpp,
+
+ int width,
+ int height,
+
+ FbBits and,
+ FbBits xor);
+
+#ifdef FB_24BIT
+void
+fbSolid24 (FbBits *dst,
+ FbStride dstStride,
+ int dstX,
+
+ int width,
+ int height,
+
+ FbBits and,
+ FbBits xor);
+#endif
+
+/*
+ * fbstipple.c
+ */
+void
+fbEvenStipple (FbBits *dst,
+ FbStride dstStride,
+ int dstX,
+ int dstBpp,
+
+ int width,
+ int height,
+
+ FbStip *stip,
+ int stipHeight,
+
+ FbBits fgand,
+ FbBits fgxor,
+ FbBits bgand,
+ FbBits bgxor,
+
+ int xRot,
+ int yRot);
+
+void
+fbOddStipple (FbBits *dst,
+ FbStride dstStride,
+ int dstX,
+ int dstBpp,
+
+ int width,
+ int height,
+
+ FbStip *stip,
+ FbStride stipStride,
+ int stipWidth,
+ int stipHeight,
+
+ FbBits fgand,
+ FbBits fgxor,
+ FbBits bgand,
+ FbBits bgxor,
+
+ int xRot,
+ int yRot);
+
+void
+fbStipple (FbBits *dst,
+ FbStride dstStride,
+ int dstX,
+ int dstBpp,
+
+ int width,
+ int height,
+
+ FbStip *stip,
+ FbStride stipStride,
+ int stipWidth,
+ int stipHeight,
+
+ FbBits fgand,
+ FbBits fgxor,
+ FbBits bgand,
+ FbBits bgxor,
+
+ int xRot,
+ int yRot);
+
+/*
+ * fbtile.c
+ */
+
+void
+fbEvenTile (FbBits *dst,
+ FbStride dstStride,
+ int dstX,
+
+ int width,
+ int height,
+
+ FbBits *tile,
+ int tileHeight,
+
+ int alu,
+ FbBits pm,
+ int xRot,
+ int yRot);
+
+void
+fbOddTile (FbBits *dst,
+ FbStride dstStride,
+ int dstX,
+
+ int width,
+ int height,
+
+ FbBits *tile,
+ FbStride tileStride,
+ int tileWidth,
+ int tileHeight,
+
+ int alu,
+ FbBits pm,
+ int bpp,
+
+ int xRot,
+ int yRot);
+
+void
+fbTile (FbBits *dst,
+ FbStride dstStride,
+ int dstX,
+
+ int width,
+ int height,
+
+ FbBits *tile,
+ FbStride tileStride,
+ int tileWidth,
+ int tileHeight,
+
+ int alu,
+ FbBits pm,
+ int bpp,
+
+ int xRot,
+ int yRot);
+
+/*
+ * fbutil.c
+ */
+FbBits
+fbReplicatePixel (Pixel p, int bpp);
+
+/*
+ * fbwindow.c
+ */
+
+Bool
+fbCreateWindow(WindowPtr pWin);
+
+Bool
+fbDestroyWindow(WindowPtr pWin);
+
+Bool
+fbMapWindow(WindowPtr pWindow);
+
+Bool
+fbPositionWindow(WindowPtr pWin, int x, int y);
+
+Bool
+fbUnmapWindow(WindowPtr pWindow);
+
+void
+fbCopyWindowProc (DrawablePtr pSrcDrawable,
+ DrawablePtr pDstDrawable,
+ GCPtr pGC,
+ BoxPtr pbox,
+ int nbox,
+ int dx,
+ int dy,
+ Bool reverse,
+ Bool upsidedown,
+ Pixel bitplane,
+ void *closure);
+
+void
+fbCopyWindow(WindowPtr pWin,
+ DDXPointRec ptOldOrg,
+ RegionPtr prgnSrc);
+
+Bool
+fbChangeWindowAttributes(WindowPtr pWin, unsigned long mask);
+
+void
+fbFillRegionSolid (DrawablePtr pDrawable,
+ RegionPtr pRegion,
+ FbBits and,
+ FbBits xor);
+
+void
+fbFillRegionTiled (DrawablePtr pDrawable,
+ RegionPtr pRegion,
+ PixmapPtr pTile);
+
+void
+fbPaintWindow(WindowPtr pWin, RegionPtr pRegion, int what);
+
+
+#endif /* _FB_H_ */
diff --git a/xc/programs/Xserver/fb/fballpriv.c b/xc/programs/Xserver/fb/fballpriv.c
new file mode 100644
index 000000000..c51e153b0
--- /dev/null
+++ b/xc/programs/Xserver/fb/fballpriv.c
@@ -0,0 +1,48 @@
+/*
+ * $Id: fballpriv.c,v 1.1 2000/01/06 12:56:51 faith Exp $
+ *
+ * Copyright © 1998 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/fb/fballpriv.c,v 1.2 1999/12/30 02:33:58 robin Exp $ */
+
+#include "fb.h"
+
+int fbGCPrivateIndex;
+int fbGeneration;
+
+#ifdef FB_OLD_SCREEN
+#define miAllocateGCPrivateIndex() AllocateGCPrivateIndex()
+#endif
+
+Bool
+fbAllocatePrivates(ScreenPtr pScreen, int *pGCIndex)
+{
+ if (fbGeneration != serverGeneration)
+ {
+ fbGCPrivateIndex = miAllocateGCPrivateIndex ();
+ fbGeneration = serverGeneration;
+ }
+ if (pGCIndex)
+ *pGCIndex = fbGCPrivateIndex;
+ if (!AllocateGCPrivate(pScreen, fbGCPrivateIndex, sizeof(FbGCPrivRec)))
+ return FALSE;
+ return TRUE;
+}
diff --git a/xc/programs/Xserver/fb/fbarc.c b/xc/programs/Xserver/fb/fbarc.c
new file mode 100644
index 000000000..0b412e66f
--- /dev/null
+++ b/xc/programs/Xserver/fb/fbarc.c
@@ -0,0 +1,109 @@
+/*
+ * $Id: fbarc.c,v 1.1 2000/01/06 12:56:51 faith Exp $
+ *
+ * Copyright © 1998 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/fb/fbarc.c,v 1.1 1999/11/19 13:53:41 hohndel Exp $ */
+
+#include "fb.h"
+#include "mizerarc.h"
+
+typedef void (*FbArc) (FbBits *dst,
+ FbStride dstStride,
+ int dstBpp,
+ xArc *arc,
+ int dx,
+ int dy,
+ FbBits and,
+ FbBits xor);
+
+void
+fbPolyArc (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int narcs,
+ xArc *parcs)
+{
+ FbArc arc;
+
+ if (pGC->lineWidth == 0)
+ {
+#ifndef FBNOPIXADDR
+ arc = 0;
+ if (pGC->lineStyle == LineSolid && pGC->fillStyle == FillSolid)
+ {
+ switch (pDrawable->bitsPerPixel)
+ {
+ case 8: arc = fbArc8; break;
+ case 16: arc = fbArc16; break;
+ case 32: arc = fbArc32; break;
+ }
+ }
+ if (arc)
+ {
+ FbGCPrivPtr pPriv = fbGetGCPrivate (pGC);
+ FbBits *dst;
+ FbStride dstStride;
+ int dstBpp;
+ BoxRec box;
+ int x2, y2;
+ RegionPtr cclip;
+
+ cclip = fbGetCompositeClip (pGC);
+ fbGetDrawable (pDrawable, dst, dstStride, dstBpp);
+ while (narcs--)
+ {
+ if (miCanZeroArc (parcs))
+ {
+ box.x1 = parcs->x + pDrawable->x;
+ box.y1 = parcs->y + pDrawable->y;
+ /*
+ * Because box.x2 and box.y2 get truncated to 16 bits, and the
+ * RECT_IN_REGION test treats the resulting number as a signed
+ * integer, the RECT_IN_REGION test alone can go the wrong way.
+ * This can result in a server crash because the rendering
+ * routines in this file deal directly with cpu addresses
+ * of pixels to be stored, and do not clip or otherwise check
+ * that all such addresses are within their respective pixmaps.
+ * So we only allow the RECT_IN_REGION test to be used for
+ * values that can be expressed correctly in a signed short.
+ */
+ x2 = box.x1 + (int)parcs->width + 1;
+ box.x2 = x2;
+ y2 = box.y1 + (int)parcs->height + 1;
+ box.y2 = y2;
+ if ( (x2 <= MAXSHORT) && (y2 <= MAXSHORT) &&
+ (RECT_IN_REGION(pDrawable->pScreen, cclip, &box) == rgnIN) )
+ (*arc) (dst, dstStride, dstBpp,
+ parcs, pDrawable->x, pDrawable->y,
+ pPriv->and, pPriv->xor);
+ else
+ miZeroPolyArc(pDrawable, pGC, 1, parcs);
+ }
+ parcs++;
+ }
+ }
+ else
+#endif
+ miZeroPolyArc (pDrawable, pGC, narcs, parcs);
+ }
+ else
+ miPolyArc (pDrawable, pGC, narcs, parcs);
+}
diff --git a/xc/programs/Xserver/fb/fbbits.c b/xc/programs/Xserver/fb/fbbits.c
new file mode 100644
index 000000000..448759722
--- /dev/null
+++ b/xc/programs/Xserver/fb/fbbits.c
@@ -0,0 +1,93 @@
+/*
+ * $Id: fbbits.c,v 1.1 2000/01/06 12:56:51 faith Exp $
+ *
+ * Copyright © 1998 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/fb/fbbits.c,v 1.1 1999/11/19 13:53:41 hohndel Exp $ */
+
+#include "fb.h"
+#include "miline.h"
+#include "mizerarc.h"
+
+#define BRESSOLID fbBresSolid8
+#define BRESDASH fbBresDash8
+#define DOTS fbDots8
+#define ARC fbArc8
+#define GLYPH fbGlyph8
+#define BITS BYTE
+#define BITS2 CARD16
+#define BITS4 CARD32
+
+#include "fbbits.h"
+
+#undef BRESSOLID
+#undef BRESDASH
+#undef DOTS
+#undef ARC
+#undef GLYPH
+#undef BITS
+#undef BITS2
+#undef BITS4
+
+#define BRESSOLID fbBresSolid16
+#define BRESDASH fbBresDash16
+#define DOTS fbDots16
+#define ARC fbArc16
+#define GLYPH fbGlyph16
+#define BITS CARD16
+#define BITS2 CARD32
+#if FB_SHIFT == 6
+#define BITS4 FbBits
+#endif
+#include "fbbits.h"
+
+#undef BRESSOLID
+#undef BRESDASH
+#undef DOTS
+#undef ARC
+#undef GLYPH
+#undef BITS
+#undef BITS2
+#if FB_SHIFT == 6
+#undef BITS4
+#endif
+
+#define BRESSOLID fbBresSolid32
+#define BRESDASH fbBresDash32
+#define DOTS fbDots32
+#define ARC fbArc32
+#define GLYPH fbGlyph32
+#define BITS CARD32
+#if FB_SHIFT == 6
+#define BITS2 FbBits
+#endif
+
+#include "fbbits.h"
+
+#undef BRESSOLID
+#undef BRESDASH
+#undef DOTS
+#undef ARC
+#undef GLYPH
+#undef BITS
+#if FB_SHIFT == 6
+#undef BITS2
+#endif
diff --git a/xc/programs/Xserver/fb/fbbits.h b/xc/programs/Xserver/fb/fbbits.h
new file mode 100644
index 000000000..a334647e9
--- /dev/null
+++ b/xc/programs/Xserver/fb/fbbits.h
@@ -0,0 +1,496 @@
+/*
+ * $Id: fbbits.h,v 1.1 2000/01/06 12:56:52 faith Exp $
+ *
+ * Copyright © 1998 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/fb/fbbits.h,v 1.2 1999/12/30 02:33:58 robin Exp $ */
+
+/*
+ * This file defines functions for drawing some primitives using
+ * underlying datatypes instead of masks
+ */
+
+/*
+ * Define the following before including this file:
+ *
+ * BRESSOLID name of function for drawing a solid segment
+ * BRESDASH name of function for drawing a dashed segment
+ * DOTS name of function for drawing dots
+ * ARC name of function for drawing a solid arc
+ * BITS type of underlying unit
+ */
+
+void
+BRESSOLID (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int dashOffset,
+ int signdx,
+ int signdy,
+ int axis,
+ int x1,
+ int y1,
+ int e,
+ int e1,
+ int e3,
+ int len)
+{
+ FbBits *dst;
+ FbStride dstStride;
+ int dstBpp;
+ FbGCPrivPtr pPriv = fbGetGCPrivate (pGC);
+ BITS *bits;
+ FbStride bitsStride;
+ FbStride majorStep, minorStep;
+ BITS xor = (BITS) pPriv->xor;
+
+ fbGetDrawable (pDrawable, dst, dstStride, dstBpp);
+ bits = ((BITS *) (dst + (y1 * dstStride))) + x1;
+ bitsStride = dstStride * (sizeof (FbBits) / sizeof (BITS));
+ if (signdy < 0)
+ bitsStride = -bitsStride;
+ if (axis == X_AXIS)
+ {
+ majorStep = signdx;
+ minorStep = bitsStride;
+ }
+ else
+ {
+ majorStep = bitsStride;
+ minorStep = signdx;
+ }
+ while (len--)
+ {
+ *bits = xor;
+ bits += majorStep;
+ e += e1;
+ if (e >= 0)
+ {
+ bits += minorStep;
+ e += e3;
+ }
+ }
+}
+
+void
+BRESDASH (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int dashOffset,
+ int signdx,
+ int signdy,
+ int axis,
+ int x1,
+ int y1,
+ int e,
+ int e1,
+ int e3,
+ int len)
+{
+ FbBits *dst;
+ FbStride dstStride;
+ int dstBpp;
+ FbGCPrivPtr pPriv = fbGetGCPrivate (pGC);
+ BITS *bits;
+ FbStride bitsStride;
+ FbStride majorStep, minorStep;
+ BITS xor = (BITS) pPriv->xor;
+ BITS bgxor = (BITS) pPriv->bgxor;
+ unsigned char *dash, *lastDash;
+ int dashlen;
+ Bool even;
+ Bool doOdd;
+
+ fbGetDrawable (pDrawable, dst, dstStride, dstBpp);
+ doOdd = pGC->lineStyle == LineDoubleDash;
+ even = TRUE;
+ dash = pGC->dash;
+ lastDash = dash + pGC->numInDashList;
+ dashOffset %= pPriv->dashLength;
+ while (dashOffset >= *dash)
+ {
+ dashOffset -= *dash++;
+ if (dash == lastDash)
+ dash = pGC->dash;
+ even = !even;
+ }
+ dashlen = *dash - dashOffset;
+ bits = ((BITS *) (dst + (y1 * dstStride))) + x1;
+ bitsStride = dstStride * (sizeof (FbBits) / sizeof (BITS));
+ if (signdy < 0)
+ bitsStride = -bitsStride;
+ if (axis == X_AXIS)
+ {
+ majorStep = signdx;
+ minorStep = bitsStride;
+ }
+ else
+ {
+ majorStep = bitsStride;
+ minorStep = signdx;
+ }
+ while (len--)
+ {
+ if (even)
+ *bits = xor;
+ else if (doOdd)
+ *bits = bgxor;
+ bits += majorStep;
+ e += e1;
+ if (e >= 0)
+ {
+ bits += minorStep;
+ e += e3;
+ }
+ if (!--dashlen)
+ {
+ if (++dash == lastDash)
+ dash = pGC->dash;
+ dashlen = *dash;
+ even = !even;
+ }
+ }
+}
+
+void
+DOTS (FbBits *dst,
+ FbStride dstStride,
+ int dstBpp,
+ BoxPtr pBox,
+ xPoint *pts,
+ int npt,
+ FbBits and,
+ FbBits xor)
+{
+ BITS *bits = (BITS *) dst;
+ BITS fg = (BITS) xor;
+ FbStride bitsStride = dstStride * (sizeof (FbBits) / sizeof (BITS));
+ int x1, y1, x2, y2;
+ int x, y;
+
+ x1 = pBox->x1;
+ y1 = pBox->y1;
+ x2 = pBox->x2;
+ y2 = pBox->y2;
+ while (npt--)
+ {
+ x = pts->x;
+ y = pts->y;
+ pts++;
+ if (x1 <= x && x < x2 && y1 <= y && y < y2)
+ *(bits + y * bitsStride + x) = fg;
+ }
+}
+
+void
+ARC (FbBits *dst,
+ FbStride dstStride,
+ int dstBpp,
+ xArc *arc,
+ int drawX,
+ int drawY,
+ FbBits and,
+ FbBits xor)
+{
+ BITS *bits;
+ FbStride bitsStride;
+ miZeroArcRec info;
+ Bool do360;
+ int x;
+ BITS *addrp;
+ BITS *yorgp, *yorgop;
+ BITS andBits, xorBits;
+ int yoffset, dyoffset;
+ int y, a, b, d, mask;
+ int k1, k3, dx, dy;
+
+ bits = (BITS *) dst;
+ bitsStride = dstStride * (sizeof (FbBits) / sizeof (BITS));
+ andBits = (BITS) and;
+ xorBits = (BITS) xor;
+ do360 = miZeroArcSetup(arc, &info, TRUE);
+ yorgp = bits + ((info.yorg + drawY) * bitsStride);
+ yorgop = bits + ((info.yorgo + drawY) * bitsStride);
+ info.xorg += drawX;
+ info.xorgo += drawX;
+ MIARCSETUP();
+ yoffset = y ? bitsStride : 0;
+ dyoffset = 0;
+ mask = info.initialMask;
+
+#define COPY(d) *(d) = xorBits;
+#define RROP(d) *(d) = FbDoRRop (*(d), andBits, xorBits)
+ if (!(arc->width & 1))
+ {
+ if (mask & 2)
+ RROP(yorgp + info.xorgo);
+ if (mask & 8)
+ RROP(yorgop + info.xorgo);
+ }
+ if (!info.end.x || !info.end.y)
+ {
+ mask = info.end.mask;
+ info.end = info.altend;
+ }
+ if (do360 && (arc->width == arc->height) && !(arc->width & 1))
+ {
+ int xoffset = bitsStride;
+ BITS *yorghb = yorgp + (info.h * bitsStride) + info.xorg;
+ BITS *yorgohb = yorghb - info.h;
+
+ yorgp += info.xorg;
+ yorgop += info.xorg;
+ yorghb += info.h;
+ while (1)
+ {
+ if (andBits == 0)
+ {
+ COPY(yorgp + yoffset + x);
+ COPY(yorgp + yoffset - x);
+ COPY(yorgop - yoffset - x);
+ COPY(yorgop - yoffset + x);
+ }
+ else
+ {
+ RROP(yorgp + yoffset + x);
+ RROP(yorgp + yoffset - x);
+ RROP(yorgop - yoffset - x);
+ RROP(yorgop - yoffset + x);
+ }
+ if (a < 0)
+ break;
+ if (andBits == 0)
+ {
+ COPY(yorghb - xoffset - y);
+ COPY(yorgohb - xoffset + y);
+ COPY(yorgohb + xoffset + y);
+ COPY(yorghb + xoffset - y);
+ }
+ else
+ {
+ RROP(yorghb - xoffset - y);
+ RROP(yorgohb - xoffset + y);
+ RROP(yorgohb + xoffset + y);
+ RROP(yorghb + xoffset - y);
+ }
+ xoffset += bitsStride;
+ MIARCCIRCLESTEP(yoffset += bitsStride;);
+ }
+ yorgp -= info.xorg;
+ yorgop -= info.xorg;
+ x = info.w;
+ yoffset = info.h * bitsStride;
+ }
+ else if (do360)
+ {
+ while (y < info.h || x < info.w)
+ {
+ MIARCOCTANTSHIFT(dyoffset = bitsStride;);
+ if (andBits == 0)
+ {
+ COPY(yorgp + yoffset + info.xorg + x);
+ COPY(yorgp + yoffset + info.xorgo - x);
+ COPY(yorgop - yoffset + info.xorgo - x);
+ COPY(yorgop - yoffset + info.xorg + x);
+ }
+ else
+ {
+ RROP(yorgp + yoffset + info.xorg + x);
+ RROP(yorgp + yoffset + info.xorgo - x);
+ RROP(yorgop - yoffset + info.xorgo - x);
+ RROP(yorgop - yoffset + info.xorg + x);
+ }
+ MIARCSTEP(yoffset += dyoffset;, yoffset += bitsStride;);
+ }
+ }
+ else
+ {
+ while (y < info.h || x < info.w)
+ {
+ MIARCOCTANTSHIFT(dyoffset = bitsStride;);
+ if ((x == info.start.x) || (y == info.start.y))
+ {
+ mask = info.start.mask;
+ info.start = info.altstart;
+ }
+ if (andBits == 0)
+ {
+ if (mask & 1)
+ COPY(yorgp + yoffset + info.xorg + x);
+ if (mask & 2)
+ COPY(yorgp + yoffset + info.xorgo - x);
+ if (mask & 4)
+ COPY(yorgop - yoffset + info.xorgo - x);
+ if (mask & 8)
+ COPY(yorgop - yoffset + info.xorg + x);
+ }
+ else
+ {
+ if (mask & 1)
+ RROP(yorgp + yoffset + info.xorg + x);
+ if (mask & 2)
+ RROP(yorgp + yoffset + info.xorgo - x);
+ if (mask & 4)
+ RROP(yorgop - yoffset + info.xorgo - x);
+ if (mask & 8)
+ RROP(yorgop - yoffset + info.xorg + x);
+ }
+ if ((x == info.end.x) || (y == info.end.y))
+ {
+ mask = info.end.mask;
+ info.end = info.altend;
+ }
+ MIARCSTEP(yoffset += dyoffset;, yoffset += bitsStride;);
+ }
+ }
+ if ((x == info.start.x) || (y == info.start.y))
+ mask = info.start.mask;
+ if (mask & 1)
+ RROP(yorgp + yoffset + info.xorg + x);
+ if (mask & 4)
+ RROP(yorgop - yoffset + info.xorgo - x);
+ if (arc->height & 1)
+ {
+ if (mask & 2)
+ RROP(yorgp + yoffset + info.xorgo - x);
+ if (mask & 8)
+ RROP(yorgop - yoffset + info.xorg + x);
+ }
+}
+
+#if BITMAP_BIT_ORDER == LSBFirst
+# define WRITE_ADDR1(n) (n)
+# define WRITE_ADDR2(n) (n)
+# define WRITE_ADDR4(n) (n)
+#else
+# define WRITE_ADDR1(n) ((n) ^ 3)
+# define WRITE_ADDR2(n) ((n) ^ 2)
+# define WRITE_ADDR4(n) ((n))
+#endif
+
+#define WRITE1(d,n,fg) d[WRITE_ADDR1(n)] = (BITS) fg
+
+#ifdef BITS2
+# define WRITE2(d,n,fg) *((BITS2 *) &(d[WRITE_ADDR2(n)])) = (BITS2) fg
+#else
+# define WRITE2(d,n,fg) WRITE1(d,n+1,WRITE1(d,n,fg))
+#endif
+
+#ifdef BITS4
+# define WRITE4(d,n,fg) *((BITS4 *) &(d[WRITE_ADDR4(n)])) = (BITS4) fg
+#else
+# define WRITE4(d,n,fg) WRITE2(d,n+2,WRITE2(d,n,fg))
+#endif
+
+void
+GLYPH (FbBits *dstBits,
+ FbStride dstStride,
+ int dstBpp,
+ FbStip *stipple,
+ FbBits fg,
+ int x,
+ int height)
+{
+ int lshift;
+ FbStip bits;
+ BITS *dstLine;
+ BITS *dst;
+ int n;
+ int shift;
+
+ dstLine = (BITS *) dstBits;
+ dstLine += x & ~3;
+ dstStride *= (sizeof (FbBits) / sizeof (BITS));
+ shift = x & 3;
+ lshift = 4 - shift;
+ while (height--)
+ {
+ bits = *stipple++;
+ dst = (BITS *) dstLine;
+ n = lshift;
+ while (bits)
+ {
+ switch (FbStipMoveLsb (FbLeftStipBits (bits, n), 4, n)) {
+ case 0:
+ break;
+ case 1:
+ WRITE1(dst,0,fg);
+ break;
+ case 2:
+ WRITE1(dst,1,fg);
+ break;
+ case 3:
+ WRITE2(dst,0,fg);
+ break;
+ case 4:
+ WRITE1(dst,2,fg);
+ break;
+ case 5:
+ WRITE1(dst,0,fg);
+ WRITE1(dst,2,fg);
+ break;
+ case 6:
+ WRITE1(dst,1,fg);
+ WRITE1(dst,2,fg);
+ break;
+ case 7:
+ WRITE2(dst,0,fg);
+ WRITE1(dst,2,fg);
+ break;
+ case 8:
+ WRITE1(dst,3,fg);
+ break;
+ case 9:
+ WRITE1(dst,0,fg);
+ WRITE1(dst,3,fg);
+ break;
+ case 10:
+ WRITE1(dst,1,fg);
+ WRITE1(dst,3,fg);
+ break;
+ case 11:
+ WRITE2(dst,0,fg);
+ WRITE1(dst,3,fg);
+ break;
+ case 12:
+ WRITE2(dst,2,fg);
+ break;
+ case 13:
+ WRITE1(dst,0,fg);
+ WRITE2(dst,2,fg);
+ break;
+ case 14:
+ WRITE1(dst,1,fg);
+ WRITE2(dst,2,fg);
+ break;
+ case 15:
+ WRITE4(dst,0,fg);
+ break;
+ }
+ bits = FbStipLeft (bits, n);
+ n = 4;
+ dst += 4;
+ }
+ dstLine += dstStride;
+ }
+}
+
+#undef WRITE1
+#undef WRITE2
+#undef WRITE4
diff --git a/xc/programs/Xserver/fb/fbblt.c b/xc/programs/Xserver/fb/fbblt.c
new file mode 100644
index 000000000..79296cd19
--- /dev/null
+++ b/xc/programs/Xserver/fb/fbblt.c
@@ -0,0 +1,900 @@
+/*
+ * $Id: fbblt.c,v 1.1 2000/01/06 12:56:52 faith Exp $
+ *
+ * Copyright © 1998 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/fb/fbblt.c,v 1.1 1999/11/19 13:53:41 hohndel Exp $ */
+
+#include "fb.h"
+
+#define InitializeShifts(sx,dx,ls,rs) { \
+ if (sx != dx) { \
+ if (sx > dx) { \
+ ls = sx - dx; \
+ rs = FB_UNIT - ls; \
+ } else { \
+ rs = dx - sx; \
+ ls = FB_UNIT - rs; \
+ } \
+ } \
+}
+
+void
+fbBlt (FbBits *srcLine,
+ FbStride srcStride,
+ int srcX,
+
+ FbBits *dstLine,
+ FbStride dstStride,
+ int dstX,
+
+ int width,
+ int height,
+
+ int alu,
+ FbBits pm,
+ int bpp,
+
+ Bool reverse,
+ Bool upsidedown)
+{
+ FbBits *src, *dst;
+ int leftShift, rightShift;
+ FbBits startmask, endmask;
+ FbBits bits, bits1;
+ int n, nmiddle;
+ Bool destInvarient;
+ FbDeclareMergeRop ();
+
+#ifdef FB_24BIT
+ if (bpp == 24 && !FbCheck24Pix (pm))
+ {
+ fbBlt24 (srcLine, srcStride, srcX, dstLine, dstStride, dstX,
+ width, height, alu, pm, reverse, upsidedown);
+ return;
+ }
+#endif
+ FbInitializeMergeRop(alu, pm);
+ destInvarient = FbDestInvarientMergeRop();
+ if (upsidedown)
+ {
+ srcLine += (height - 1) * (srcStride);
+ dstLine += (height - 1) * (dstStride);
+ srcStride = -srcStride;
+ dstStride = -dstStride;
+ }
+ FbMaskBits(dstX, width, startmask, nmiddle, endmask);
+ if (reverse)
+ {
+ srcLine += ((srcX + width - 1) >> FB_SHIFT) + 1;
+ dstLine += ((dstX + width - 1) >> FB_SHIFT) + 1;
+ srcX = (srcX + width - 1) & FB_MASK;
+ dstX = (dstX + width - 1) & FB_MASK;
+ }
+ else
+ {
+ srcLine += srcX >> FB_SHIFT;
+ dstLine += dstX >> FB_SHIFT;
+ srcX &= FB_MASK;
+ dstX &= FB_MASK;
+ }
+ if (srcX == dstX)
+ {
+ while (height--)
+ {
+ src = srcLine;
+ srcLine += srcStride;
+ dst = dstLine;
+ dstLine += dstStride;
+ if (reverse)
+ {
+ if (endmask)
+ {
+ bits = *--src;
+ --dst;
+ *dst = FbDoMaskMergeRop (bits, *dst, endmask);
+ }
+ n = nmiddle;
+ if (destInvarient)
+ {
+ while (n--)
+ *--dst = FbDoDestInvarientMergeRop(*--src);
+ }
+ else
+ {
+ while (n--)
+ {
+ bits = *--src;
+ --dst;
+ *dst = FbDoMergeRop (bits, *dst);
+ }
+ }
+ if (startmask)
+ {
+ bits = *--src;
+ --dst;
+ *dst = FbDoMaskMergeRop(bits, *dst, startmask);
+ }
+ }
+ else
+ {
+ if (startmask)
+ {
+ bits = *src++;
+ *dst = FbDoMaskMergeRop (bits, *dst, startmask);
+ dst++;
+ }
+ n = nmiddle;
+ if (destInvarient)
+ {
+#if 0
+ /*
+ * This provides some speedup on screen->screen blts
+ * over the PCI bus, usually about 10%. But fb
+ * isn't usually used for this operation...
+ */
+ if (_ca2 + 1 == 0 && _cx2 == 0)
+ {
+ FbBits t1, t2, t3, t4;
+ while (n >= 4)
+ {
+ t1 = *src++;
+ t2 = *src++;
+ t3 = *src++;
+ t4 = *src++;
+ *dst++ = t1;
+ *dst++ = t2;
+ *dst++ = t3;
+ *dst++ = t4;
+ n -= 4;
+ }
+ }
+#endif
+ while (n--)
+ *dst++ = FbDoDestInvarientMergeRop(*src++);
+ }
+ else
+ {
+ while (n--)
+ {
+ bits = *src++;
+ *dst = FbDoMergeRop (bits, *dst);
+ dst++;
+ }
+ }
+ if (endmask)
+ {
+ bits = *src;
+ *dst = FbDoMaskMergeRop(bits, *dst, endmask);
+ }
+ }
+ }
+ }
+ else
+ {
+ if (srcX > dstX)
+ {
+ leftShift = srcX - dstX;
+ rightShift = FB_UNIT - leftShift;
+ }
+ else
+ {
+ rightShift = dstX - srcX;
+ leftShift = FB_UNIT - rightShift;
+ }
+ while (height--)
+ {
+ src = srcLine;
+ srcLine += srcStride;
+ dst = dstLine;
+ dstLine += dstStride;
+
+ bits1 = 0;
+ if (reverse)
+ {
+ if (srcX < dstX)
+ bits1 = *--src;
+ if (endmask)
+ {
+ bits = FbScrRight(bits1, rightShift);
+ if (FbScrRight(endmask, leftShift))
+ {
+ bits1 = *--src;
+ bits |= FbScrLeft(bits1, leftShift);
+ }
+ --dst;
+ *dst = FbDoMaskMergeRop (bits, *dst, endmask);
+ }
+ n = nmiddle;
+ if (destInvarient)
+ {
+ while (n--)
+ {
+ bits = FbScrRight(bits1, rightShift);
+ bits1 = *--src;
+ bits |= FbScrLeft(bits1, leftShift);
+ --dst;
+ *dst = FbDoDestInvarientMergeRop(bits);
+ }
+ }
+ else
+ {
+ while (n--)
+ {
+ bits = FbScrRight(bits1, rightShift);
+ bits1 = *--src;
+ bits |= FbScrLeft(bits1, leftShift);
+ --dst;
+ *dst = FbDoMergeRop(bits, *dst);
+ }
+ }
+ if (startmask)
+ {
+ bits = FbScrRight(bits1, rightShift);
+ if (FbScrRight(startmask, leftShift))
+ {
+ bits1 = *--src;
+ bits |= FbScrLeft(bits1, leftShift);
+ }
+ --dst;
+ *dst = FbDoMaskMergeRop (bits, *dst, startmask);
+ }
+ }
+ else
+ {
+ if (srcX > dstX)
+ bits1 = *src++;
+ if (startmask)
+ {
+ bits = FbScrLeft(bits1, leftShift);
+ bits1 = *src++;
+ bits |= FbScrRight(bits1, rightShift);
+ *dst = FbDoMaskMergeRop (bits, *dst, startmask);
+ dst++;
+ }
+ n = nmiddle;
+ if (destInvarient)
+ {
+ while (n--)
+ {
+ bits = FbScrLeft(bits1, leftShift);
+ bits1 = *src++;
+ bits |= FbScrRight(bits1, rightShift);
+ *dst = FbDoDestInvarientMergeRop(bits);
+ dst++;
+ }
+ }
+ else
+ {
+ while (n--)
+ {
+ bits = FbScrLeft(bits1, leftShift);
+ bits1 = *src++;
+ bits |= FbScrRight(bits1, rightShift);
+ *dst = FbDoMergeRop(bits, *dst);
+ dst++;
+ }
+ }
+ if (endmask)
+ {
+ bits = FbScrLeft(bits1, leftShift);
+ if (FbScrLeft(endmask, rightShift))
+ {
+ bits1 = *src;
+ bits |= FbScrRight(bits1, rightShift);
+ }
+ *dst = FbDoMaskMergeRop (bits, *dst, endmask);
+ }
+ }
+ }
+ }
+}
+
+#if 0
+#include <stdio.h>
+
+static unsigned long
+getPixel (char *src, int x)
+{
+ unsigned long l;
+
+ l = 0;
+ memcpy (&l, src + x * 3, 3);
+ return l;
+}
+#endif
+
+void
+fbBlt24Line (FbBits *src,
+ int srcX,
+
+ FbBits *dst,
+ int dstX,
+
+ int width,
+
+ int alu,
+ FbBits pm,
+
+ Bool reverse)
+{
+ char *origDst;
+ int origX;
+
+ int leftShift, rightShift;
+ FbBits startmask, endmask;
+ int n;
+
+ FbBits bits, bits1;
+ FbBits mask;
+
+ int rot;
+ FbDeclareMergeRop ();
+
+ origDst = (char *) dst;
+ origX = dstX / 24;
+
+ FbInitializeMergeRop (alu, FB_ALLONES);
+ FbMaskBits(dstX, width, startmask, n, endmask);
+ if (reverse)
+ {
+ src += ((srcX + width - 1) >> FB_SHIFT) + 1;
+ dst += ((dstX + width - 1) >> FB_SHIFT) + 1;
+ rot = ((dstX + width) & FB_MASK) % 24;
+ srcX = (srcX + width - 1) & FB_MASK;
+ dstX = (dstX + width - 1) & FB_MASK;
+ }
+ else
+ {
+ src += srcX >> FB_SHIFT;
+ dst += dstX >> FB_SHIFT;
+ srcX &= FB_MASK;
+ dstX &= FB_MASK;
+ rot = dstX % 24;
+ }
+ mask = FbRot24(pm,rot);
+ if (srcX == dstX)
+ {
+ if (reverse)
+ {
+ if (endmask)
+ {
+ bits = *--src;
+ --dst;
+ *dst = FbDoMaskMergeRop (bits, *dst, mask & endmask);
+ mask = FbPrev24Pix (mask);
+ }
+ while (n--)
+ {
+ bits = *--src;
+ --dst;
+ *dst = FbDoMaskMergeRop (bits, *dst, mask);
+ mask = FbPrev24Pix (mask);
+ }
+ if (startmask)
+ {
+ bits = *--src;
+ --dst;
+ *dst = FbDoMaskMergeRop(bits, *dst, mask & startmask);
+ }
+ }
+ else
+ {
+ if (startmask)
+ {
+ bits = *src++;
+ *dst = FbDoMaskMergeRop (bits, *dst, mask & startmask);
+ dst++;
+ mask = FbNext24Pix(mask);
+ }
+ while (n--)
+ {
+ bits = *src++;
+ *dst = FbDoMaskMergeRop (bits, *dst, mask);
+ dst++;
+ mask = FbNext24Pix(mask);
+ }
+ if (endmask)
+ {
+ bits = *src;
+ *dst = FbDoMaskMergeRop(bits, *dst, mask & endmask);
+ }
+ }
+ }
+ else
+ {
+ if (srcX > dstX)
+ {
+ leftShift = srcX - dstX;
+ rightShift = FB_UNIT - leftShift;
+ }
+ else
+ {
+ rightShift = dstX - srcX;
+ leftShift = FB_UNIT - rightShift;
+ }
+
+ bits1 = 0;
+ if (reverse)
+ {
+ if (srcX < dstX)
+ bits1 = *--src;
+ if (endmask)
+ {
+ bits = FbScrRight(bits1, rightShift);
+ if (FbScrRight(endmask, leftShift))
+ {
+ bits1 = *--src;
+ bits |= FbScrLeft(bits1, leftShift);
+ }
+ --dst;
+ *dst = FbDoMaskMergeRop (bits, *dst, mask & endmask);
+ mask = FbPrev24Pix(mask);
+ }
+ while (n--)
+ {
+ bits = FbScrRight(bits1, rightShift);
+ bits1 = *--src;
+ bits |= FbScrLeft(bits1, leftShift);
+ --dst;
+ *dst = FbDoMaskMergeRop(bits, *dst, mask);
+ mask = FbPrev24Pix(mask);
+ }
+ if (startmask)
+ {
+ bits = FbScrRight(bits1, rightShift);
+ if (FbScrRight(startmask, leftShift))
+ {
+ bits1 = *--src;
+ bits |= FbScrLeft(bits1, leftShift);
+ }
+ --dst;
+ *dst = FbDoMaskMergeRop (bits, *dst, mask & startmask);
+ }
+ }
+ else
+ {
+ if (srcX > dstX)
+ bits1 = *src++;
+ if (startmask)
+ {
+ bits = FbScrLeft(bits1, leftShift);
+ bits1 = *src++;
+ bits |= FbScrRight(bits1, rightShift);
+ *dst = FbDoMaskMergeRop (bits, *dst, mask & startmask);
+ dst++;
+ mask = FbNext24Pix(mask);
+ }
+ while (n--)
+ {
+ bits = FbScrLeft(bits1, leftShift);
+ bits1 = *src++;
+ bits |= FbScrRight(bits1, rightShift);
+ *dst = FbDoMaskMergeRop(bits, *dst, mask);
+ dst++;
+ mask = FbNext24Pix(mask);
+ }
+ if (endmask)
+ {
+ bits = FbScrLeft(bits1, leftShift);
+ if (FbScrLeft(endmask, rightShift))
+ {
+ bits1 = *src;
+ bits |= FbScrRight(bits1, rightShift);
+ }
+ *dst = FbDoMaskMergeRop (bits, *dst, mask & endmask);
+ }
+ }
+ }
+#if 0
+ {
+ int firstx, lastx, x;
+
+ firstx = origX;
+ if (firstx)
+ firstx--;
+ lastx = origX + width/24 + 1;
+ for (x = firstx; x <= lastx; x++)
+ fprintf (stderr, "%06x ", getPixel (origDst, x));
+ }
+ fprintf (stderr, "\n");
+#endif
+}
+
+void
+fbBlt24 (FbBits *srcLine,
+ FbStride srcStride,
+ int srcX,
+
+ FbBits *dstLine,
+ FbStride dstStride,
+ int dstX,
+
+ int width,
+ int height,
+
+ int alu,
+ FbBits pm,
+
+ Bool reverse,
+ Bool upsidedown)
+{
+ if (upsidedown)
+ {
+ srcLine += (height-1) * srcStride;
+ dstLine += (height-1) * dstStride;
+ srcStride = -srcStride;
+ dstStride = -dstStride;
+ }
+ while (height--)
+ {
+ fbBlt24Line (srcLine, srcX, dstLine, dstX, width, alu, pm, reverse);
+ srcLine += srcStride;
+ dstLine += dstStride;
+ }
+#if 0
+ fprintf (stderr, "\n");
+#endif
+}
+
+#if FB_SHIFT == FB_STIP_SHIFT + 1
+
+/*
+ * Could be generalized to FB_SHIFT > FB_STIP_SHIFT + 1 by
+ * creating an ring of values stepped through for each line
+ */
+
+void
+fbBltOdd (FbBits *srcLine,
+ FbStride srcStrideEven,
+ FbStride srcStrideOdd,
+ int srcXEven,
+ int srcXOdd,
+
+ FbBits *dstLine,
+ FbStride dstStrideEven,
+ FbStride dstStrideOdd,
+ int dstXEven,
+ int dstXOdd,
+
+ int width,
+ int height,
+
+ int alu,
+ FbBits pm,
+ int bpp)
+{
+ FbBits *src;
+ int leftShiftEven, rightShiftEven;
+ FbBits startmaskEven, endmaskEven;
+ int nmiddleEven;
+
+ FbBits *dst;
+ int leftShiftOdd, rightShiftOdd;
+ FbBits startmaskOdd, endmaskOdd;
+ int nmiddleOdd;
+
+ int leftShift, rightShift;
+ FbBits startmask, endmask;
+ int nmiddle;
+
+ int srcX, dstX;
+
+ FbBits bits, bits1;
+ int n;
+
+ Bool destInvarient;
+ Bool even;
+ FbDeclareMergeRop ();
+
+ FbInitializeMergeRop (alu, pm);
+ destInvarient = FbDestInvarientMergeRop();
+
+ srcLine += srcXEven >> FB_SHIFT;
+ dstLine += dstXEven >> FB_SHIFT;
+ srcXEven &= FB_MASK;
+ dstXEven &= FB_MASK;
+ srcXOdd &= FB_MASK;
+ dstXOdd &= FB_MASK;
+
+ FbMaskBits(dstXEven, width, startmaskEven, nmiddleEven, endmaskEven);
+ FbMaskBits(dstXOdd, width, startmaskOdd, nmiddleOdd, endmaskOdd);
+
+ even = TRUE;
+ InitializeShifts(srcXEven, dstXEven, leftShiftEven, rightShiftEven);
+ InitializeShifts(srcXOdd, dstXOdd, leftShiftOdd, rightShiftOdd);
+ while (height--)
+ {
+ src = srcLine;
+ dst = dstLine;
+ if (even)
+ {
+ srcX = srcXEven;
+ dstX = dstXEven;
+ startmask = startmaskEven;
+ endmask = endmaskEven;
+ nmiddle = nmiddleEven;
+ leftShift = leftShiftEven;
+ rightShift = rightShiftEven;
+ srcLine += srcStrideEven;
+ dstLine += dstStrideEven;
+ even = FALSE;
+ }
+ else
+ {
+ srcX = srcXOdd;
+ dstX = dstXOdd;
+ startmask = startmaskOdd;
+ endmask = endmaskOdd;
+ nmiddle = nmiddleOdd;
+ leftShift = leftShiftOdd;
+ rightShift = rightShiftOdd;
+ srcLine += srcStrideOdd;
+ dstLine += dstStrideOdd;
+ even = TRUE;
+ }
+ if (srcX == dstX)
+ {
+ if (startmask)
+ {
+ bits = *src++;
+ *dst = FbDoMaskMergeRop (bits, *dst, startmask);
+ dst++;
+ }
+ n = nmiddle;
+ if (destInvarient)
+ {
+ while (n--)
+ {
+ bits = *src++;
+ *dst = FbDoDestInvarientMergeRop(bits);
+ dst++;
+ }
+ }
+ else
+ {
+ while (n--)
+ {
+ bits = *src++;
+ *dst = FbDoMergeRop (bits, *dst);
+ dst++;
+ }
+ }
+ if (endmask)
+ {
+ bits = *src;
+ *dst = FbDoMaskMergeRop(bits, *dst, endmask);
+ }
+ }
+ else
+ {
+ bits = 0;
+ if (srcX > dstX)
+ bits = *src++;
+ if (startmask)
+ {
+ bits1 = FbScrLeft(bits, leftShift);
+ bits = *src++;
+ bits1 |= FbScrRight(bits, rightShift);
+ *dst = FbDoMaskMergeRop (bits1, *dst, startmask);
+ dst++;
+ }
+ n = nmiddle;
+ if (destInvarient)
+ {
+ while (n--)
+ {
+ bits1 = FbScrLeft(bits, leftShift);
+ bits = *src++;
+ bits1 |= FbScrRight(bits, rightShift);
+ *dst = FbDoDestInvarientMergeRop(bits1);
+ dst++;
+ }
+ }
+ else
+ {
+ while (n--)
+ {
+ bits1 = FbScrLeft(bits, leftShift);
+ bits = *src++;
+ bits1 |= FbScrRight(bits, rightShift);
+ *dst = FbDoMergeRop(bits1, *dst);
+ dst++;
+ }
+ }
+ if (endmask)
+ {
+ bits1 = FbScrLeft(bits, leftShift);
+ if (FbScrLeft(endmask, rightShift))
+ {
+ bits = *src;
+ bits1 |= FbScrRight(bits, rightShift);
+ }
+ *dst = FbDoMaskMergeRop (bits1, *dst, endmask);
+ }
+ }
+ }
+}
+
+void
+fbBltOdd24 (FbBits *srcLine,
+ FbStride srcStrideEven,
+ FbStride srcStrideOdd,
+ int srcXEven,
+ int srcXOdd,
+
+ FbBits *dstLine,
+ FbStride dstStrideEven,
+ FbStride dstStrideOdd,
+ int dstXEven,
+ int dstXOdd,
+
+ int width,
+ int height,
+
+ int alu,
+ FbBits pm)
+{
+ Bool even = TRUE;
+
+ while (height--)
+ {
+ if (even)
+ {
+ fbBlt24Line (srcLine, srcXEven, dstLine, dstXEven,
+ width, alu, pm, FALSE);
+ srcLine += srcStrideEven;
+ dstLine += dstStrideEven;
+ even = FALSE;
+ }
+ else
+ {
+ fbBlt24Line (srcLine, srcXOdd, dstLine, dstXOdd,
+ width, alu, pm, FALSE);
+ srcLine += srcStrideOdd;
+ dstLine += dstStrideOdd;
+ even = TRUE;
+ }
+ }
+#if 0
+ fprintf (stderr, "\n");
+#endif
+}
+
+#endif
+
+#if FB_STIP_SHIFT != FB_SHIFT
+void
+fbSetBltOdd (FbStip *stip,
+ FbStride stipStride,
+ int srcX,
+ FbBits **bits,
+ FbStride *strideEven,
+ FbStride *strideOdd,
+ int *srcXEven,
+ int *srcXOdd)
+{
+ int srcAdjust;
+ int strideAdjust;
+
+ /*
+ * bytes needed to align source
+ */
+ srcAdjust = (((int) stip) & (FB_MASK >> 3));
+ /*
+ * FbStip units needed to align stride
+ */
+ strideAdjust = stipStride & (FB_MASK >> FB_STIP_SHIFT);
+
+ *bits = (FbBits *) ((char *) stip - srcAdjust);
+ if (srcAdjust)
+ {
+ *strideEven = FbStipStrideToBitsStride (stipStride + 1);
+ *strideOdd = FbStipStrideToBitsStride (stipStride);
+
+ *srcXEven = srcX + (srcAdjust << 3);
+ *srcXOdd = srcX + (srcAdjust << 3) - (strideAdjust << FB_STIP_SHIFT);
+ }
+ else
+ {
+ *strideEven = FbStipStrideToBitsStride (stipStride);
+ *strideOdd = FbStipStrideToBitsStride (stipStride + 1);
+
+ *srcXEven = srcX;
+ *srcXOdd = srcX + (strideAdjust << FB_STIP_SHIFT);
+ }
+}
+#endif
+
+void
+fbBltStip (FbStip *src,
+ FbStride srcStride, /* in FbStip units, not FbBits units */
+ int srcX,
+
+ FbStip *dst,
+ FbStride dstStride, /* in FbStip units, not FbBits units */
+ int dstX,
+
+ int width,
+ int height,
+
+ int alu,
+ FbBits pm,
+ int bpp)
+{
+#if FB_STIP_SHIFT != FB_SHIFT
+ if (FB_STIP_ODDSTRIDE(srcStride) || FB_STIP_ODDPTR(src) ||
+ FB_STIP_ODDSTRIDE(dstStride) || FB_STIP_ODDPTR(dst))
+ {
+ FbStride srcStrideEven, srcStrideOdd;
+ FbStride dstStrideEven, dstStrideOdd;
+ int srcXEven, srcXOdd;
+ int dstXEven, dstXOdd;
+ FbBits *s, *d;
+ int sx, dx;
+
+ src += srcX >> FB_STIP_SHIFT;
+ srcX &= FB_STIP_MASK;
+ dst += dstX >> FB_STIP_SHIFT;
+ dstX &= FB_STIP_MASK;
+
+ fbSetBltOdd (src, srcStride, srcX,
+ &s,
+ &srcStrideEven, &srcStrideOdd,
+ &srcXEven, &srcXOdd);
+
+ fbSetBltOdd (dst, dstStride, dstX,
+ &d,
+ &dstStrideEven, &dstStrideOdd,
+ &dstXEven, &dstXOdd);
+
+ if (bpp == 24 && !FbCheck24Pix (pm))
+ {
+ fbBltOdd24 (s, srcStrideEven, srcStrideOdd,
+ srcXEven, srcXOdd,
+
+ d, dstStrideEven, dstStrideOdd,
+ dstXEven, dstXOdd,
+
+ width, height, alu, pm);
+ }
+ else
+ {
+ fbBltOdd (s, srcStrideEven, srcStrideOdd,
+ srcXEven, srcXOdd,
+
+ d, dstStrideEven, dstStrideOdd,
+ dstXEven, dstXOdd,
+
+ width, height, alu, pm, bpp);
+ }
+ }
+ else
+#endif
+ {
+ fbBlt ((FbBits *) src, FbStipStrideToBitsStride (srcStride),
+ srcX,
+ (FbBits *) dst, FbStipStrideToBitsStride (dstStride),
+ dstX,
+ width, height,
+ alu, pm, bpp, FALSE, FALSE);
+ }
+}
diff --git a/xc/programs/Xserver/fb/fbbltone.c b/xc/programs/Xserver/fb/fbbltone.c
new file mode 100644
index 000000000..ba659f316
--- /dev/null
+++ b/xc/programs/Xserver/fb/fbbltone.c
@@ -0,0 +1,732 @@
+/*
+ * $Id: fbbltone.c,v 1.1 2000/01/06 12:56:52 faith Exp $
+ *
+ * Copyright © 1998 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/fb/fbbltone.c,v 1.1 1999/11/19 13:53:42 hohndel Exp $ */
+
+#include "fb.h"
+
+/*
+ * Example: srcX = 13 dstX = 8 (FB unit 32 dstBpp 8)
+ *
+ * **** **** **** **** **** **** **** ****
+ * ^
+ * ******** ******** ******** ********
+ * ^
+ * leftShift = 12
+ * rightShift = 20
+ *
+ * Example: srcX = 0 dstX = 8 (FB unit 32 dstBpp 8)
+ *
+ * **** **** **** **** **** **** **** ****
+ * ^
+ * ******** ******** ******** ********
+ * ^
+ *
+ * leftShift = 24
+ * rightShift = 8
+ */
+
+#define LoadBits {\
+ if (leftShift) { \
+ bitsRight = *src++; \
+ bits = (FbStipLeft (bitsLeft, leftShift) | \
+ FbStipRight(bitsRight, rightShift)); \
+ bitsLeft = bitsRight; \
+ } else \
+ bits = *src++; \
+}
+
+void
+fbBltOne (FbStip *src,
+ FbStride srcStride, /* FbStip units per scanline */
+ int srcX, /* bit position of source */
+ FbBits *dst,
+ FbStride dstStride, /* FbBits units per scanline */
+ int dstX, /* bit position of dest */
+ int dstBpp, /* bits per destination unit */
+
+ int width, /* width in bits of destination */
+ int height, /* height in scanlines */
+
+ FbBits fgand, /* rrop values */
+ FbBits fgxor,
+ FbBits bgand,
+ FbBits bgxor)
+{
+ const FbBits *fbBits;
+ int pixelsPerDst; /* dst pixels per FbBits */
+ int unitsPerSrc; /* src patterns per FbStip */
+ int leftShift, rightShift; /* align source with dest */
+ FbBits startmask, endmask; /* dest scanline masks */
+ FbStip bits, bitsLeft, bitsRight; /* source bits */
+ FbBits mask;
+ int nDst; /* dest longwords (w.o. end) */
+ int w;
+ int n, nmiddle;
+ int nthistime;
+ int dstS; /* stipple-relative dst X coordinate */
+ Bool copy; /* accelerate dest-invariant */
+ int srcinc; /* source units consumed */
+ int dstinc; /* dest units produced */
+ Bool endNeedsLoad; /* need load for endmask */
+
+#ifdef FB_24BIT
+ if (dstBpp == 24)
+ {
+ fbBltOne24 (src, srcStride, srcX,
+ dst, dstStride, dstX, dstBpp,
+ width, height,
+ fgand, fgxor, bgand, bgxor);
+ return;
+ }
+#endif
+
+ /*
+ * Number of destination units in FbBits == number of stipple pixels
+ * used each time
+ */
+ pixelsPerDst = FB_UNIT / dstBpp;
+
+ /*
+ * Number of source stipple patterns in FbStip
+ */
+ unitsPerSrc = FB_STIP_UNIT / pixelsPerDst;
+
+ copy = FALSE;
+ if (bgand == 0 && fgand == 0)
+ copy = TRUE;
+
+ /*
+ * Adjust source and dest to nearest FbBits boundary
+ */
+ src += srcX >> FB_STIP_SHIFT;
+ dst += dstX >> FB_SHIFT;
+ srcX &= FB_STIP_MASK;
+ dstX &= FB_MASK;
+
+ FbMaskBits(dstX, width, startmask, nmiddle, endmask);
+
+ /*
+ * Compute effective dest alignment requirement for
+ * source -- must align source to dest unit boundary
+ */
+ dstS = dstX / dstBpp;
+ /*
+ * Compute shift constants for effective alignement
+ */
+ if (srcX >= dstS)
+ {
+ leftShift = srcX - dstS;
+ rightShift = FB_STIP_UNIT - leftShift;
+ }
+ else
+ {
+ rightShift = dstS - srcX;
+ leftShift = FB_STIP_UNIT - rightShift;
+ }
+ /*
+ * Get pointer to stipple mask array for this depth
+ */
+ fbBits = 0; /* unused */
+ if (pixelsPerDst <= 8)
+ fbBits = fbStippleTable[pixelsPerDst];
+
+ /*
+ * Compute total number of destination words written, but
+ * don't count endmask
+ */
+ nDst = nmiddle;
+ if (startmask)
+ nDst++;
+
+ dstStride -= nDst;
+
+ /*
+ * Compute total number of source words consumed
+ */
+
+ srcinc = (nDst + unitsPerSrc - 1) / unitsPerSrc;
+
+ if (srcX > dstS)
+ srcinc++;
+ if (endmask)
+ {
+ endNeedsLoad = nDst % unitsPerSrc == 0;
+ if (endNeedsLoad)
+ srcinc++;
+ }
+
+ srcStride -= srcinc;
+
+ /*
+ * Copy rectangle
+ */
+ while (height--)
+ {
+ w = nDst; /* total units across scanline */
+ n = unitsPerSrc; /* units avail in single stipple */
+ if (n > w)
+ n = w;
+
+ bitsLeft = 0;
+ if (srcX > dstS)
+ bitsLeft = *src++;
+ if (n)
+ {
+ /*
+ * Load first set of stipple bits
+ */
+ LoadBits;
+
+ /*
+ * Consume stipple bits for startmask
+ */
+ if (startmask)
+ {
+#if FB_UNIT > 32
+ if (pixelsPerDst == 16)
+ mask = FbStipple16Bits(FbLeftStipBits(bits,16));
+ else
+#endif
+ mask = fbBits[FbLeftStipBits(bits,pixelsPerDst)];
+ *dst = FbStippleRRopMask (*dst, mask,
+ fgand, fgxor, bgand, bgxor,
+ startmask);
+ bits = FbStipLeft (bits, pixelsPerDst);
+ dst++;
+ n--;
+ w--;
+ }
+ /*
+ * Consume stipple bits across scanline
+ */
+ for (;;)
+ {
+ w -= n;
+#if FB_UNIT > 32
+ if (pixelsPerDst == 16)
+ {
+ if (copy)
+ {
+ while (n--)
+ {
+ mask = FbStipple16Bits(FbLeftStipBits(bits,16));
+ *dst = FbOpaqueStipple (mask, fgxor, bgxor);
+ dst++;
+ bits = FbStipLeft(bits, 16);
+ }
+ }
+ else
+ {
+ while (n--)
+ {
+ mask = FbStipple16Bits(FbLeftStipBits(bits,16));
+ *dst = FbStippleRRop (*dst, mask,
+ fgand, fgxor, bgand, bgxor);
+ dst++;
+ bits = FbStipLeft(bits, 16);
+ }
+ }
+ }
+ else
+#endif
+ {
+ if (copy)
+ {
+ while (n--)
+ {
+ mask = fbBits[FbLeftStipBits(bits,pixelsPerDst)];
+ *dst = FbOpaqueStipple (mask, fgxor, bgxor);
+ dst++;
+ bits = FbStipLeft(bits, pixelsPerDst);
+ }
+ }
+ else
+ {
+ while (n--)
+ {
+ mask = fbBits[FbLeftStipBits(bits,pixelsPerDst)];
+ *dst = FbStippleRRop (*dst, mask,
+ fgand, fgxor, bgand, bgxor);
+ dst++;
+ bits = FbStipLeft(bits, pixelsPerDst);
+ }
+ }
+ }
+ if (!w)
+ break;
+ /*
+ * Load another set and reset number of available units
+ */
+ LoadBits;
+ n = unitsPerSrc;
+ if (n > w)
+ n = w;
+ }
+ }
+ /*
+ * Consume stipple bits for endmask
+ */
+ if (endmask)
+ {
+ if (endNeedsLoad)
+ {
+ LoadBits;
+ }
+#if FB_UNIT > 32
+ if (pixelsPerDst == 16)
+ mask = FbStipple16Bits(FbLeftStipBits(bits,16));
+ else
+#endif
+ mask = fbBits[FbLeftStipBits(bits,pixelsPerDst)];
+ *dst = FbStippleRRopMask (*dst, mask,
+ fgand, fgxor, bgand, bgxor,
+ endmask);
+ dst;
+ }
+ dst += dstStride;
+ src += srcStride;
+ }
+}
+
+#ifdef FB_24BIT
+
+/*
+ * Crufty macros to initialize the mask array, most of this
+ * is to avoid compile-time warnings about shift overflow
+ */
+
+#define Mask24Pos(x,r) ((x)*24-((r) ? 24 - (r) : 0))
+#define Mask24Neg(x,r) (Mask24Pos(x,r) < 0 ? -Mask24Pos(x,r) : 0)
+#define Mask24Check(x,r) (Mask24Pos(x,r) < 0 ? 0 : \
+ Mask24Pos(x,r) >= FB_UNIT ? 0 : Mask24Pos(x,r))
+#define Mask24(x,r) (Mask24Pos(x,r) < FB_UNIT ? \
+ (Mask24Pos(x,r) < 0 ? \
+ FbScrLeft (FbBitsMask(0,24),Mask24Neg(x,r)) : \
+ FbScrRight (FbBitsMask(0,24),Mask24Check(x,r))) \
+ : 0)
+
+#define SelMask24(b,n,r) ((((b) >> n) & 1) * Mask24(n,r))
+
+/*
+ * Untested for MSBFirst or FB_UNIT == 32
+ */
+
+#if FB_UNIT == 64
+#define C4_24(b,r) \
+ (SelMask24(b,0,r) | \
+ SelMask24(b,1,r) | \
+ SelMask24(b,2,r) | \
+ SelMask24(b,3,r))
+
+#define FbStip24New(rot) (2 + (rot != 0))
+#define FbStip24Len 4
+
+const FbBits fbStipple24Bits[3][1 << FbStip24Len] = {
+ /* rotate 0 */
+ {
+ C4_24( 0, 0), C4_24( 1, 0), C4_24( 2, 0), C4_24( 3, 0),
+ C4_24( 4, 0), C4_24( 5, 0), C4_24( 6, 0), C4_24( 7, 0),
+ C4_24( 8, 0), C4_24( 9, 0), C4_24(10, 0), C4_24(11, 0),
+ C4_24(12, 0), C4_24(13, 0), C4_24(14, 0), C4_24(15, 0),
+ },
+ /* rotate 8 */
+ {
+ C4_24( 0, 8), C4_24( 1, 8), C4_24( 2, 8), C4_24( 3, 8),
+ C4_24( 4, 8), C4_24( 5, 8), C4_24( 6, 8), C4_24( 7, 8),
+ C4_24( 8, 8), C4_24( 9, 8), C4_24(10, 8), C4_24(11, 8),
+ C4_24(12, 8), C4_24(13, 8), C4_24(14, 8), C4_24(15, 8),
+ },
+ /* rotate 16 */
+ {
+ C4_24( 0,16), C4_24( 1,16), C4_24( 2,16), C4_24( 3,16),
+ C4_24( 4,16), C4_24( 5,16), C4_24( 6,16), C4_24( 7,16),
+ C4_24( 8,16), C4_24( 9,16), C4_24(10,16), C4_24(11,16),
+ C4_24(12,16), C4_24(13,16), C4_24(14,16), C4_24(15,16),
+ }
+};
+
+#endif
+
+#if FB_UNIT == 32
+#define C2_24(b,r) \
+ (SelMask24(b,0,r) | \
+ SelMask24(b,1,r))
+
+#define FbStip24Len 2
+#define FbStip24New(rot) (1 + (rot == 8))
+
+const FbBits fbStipple24Bits[3][1 << FbStip24Len] = {
+ /* rotate 0 */
+ {
+ C2_24( 0, 0), C2_24 ( 1, 0), C2_24 ( 2, 0), C2_24 ( 3, 0),
+ },
+ /* rotate 8 */
+ {
+ C2_24( 0, 8), C2_24 ( 1, 8), C2_24 ( 2, 8), C2_24 ( 3, 8),
+ },
+ /* rotate 16 */
+ {
+ C2_24( 0,16), C2_24 ( 1,16), C2_24 ( 2,16), C2_24 ( 3,16),
+ }
+};
+#endif
+
+#define fbFirstStipBits(len,stip) {\
+ int __len = (len); \
+ if (len <= remain) { \
+ stip = FbLeftStipBits(bits, len); \
+ } else { \
+ stip = FbLeftStipBits(bits, remain); \
+ bits = *src++; \
+ __len = (len) - remain; \
+ stip |= FbStipRight(FbLeftStipBits(bits, __len), remain); \
+ remain = FB_STIP_UNIT; \
+ } \
+ bits = FbStipLeft (bits, __len); \
+ remain -= __len; \
+}
+
+#define fbInitStipBits(offset,len,stip) {\
+ bits = FbStipLeft (*src++,offset); \
+ remain = FB_STIP_UNIT - offset; \
+ fbFirstStipBits(len,stip); \
+ stip = FbStipRight (stip, FbStip24Len - len); \
+}
+
+#define fbNextStipBits(rot,stip) {\
+ int __new = FbStip24New(rot); \
+ FbStip __right; \
+ fbFirstStipBits(__new, __right); \
+ stip = (FbStipLeft (stip, __new) | \
+ FbStipRight (__right, FbStip24Len - __new)); \
+ rot = FbNext24Rot (rot); \
+}
+
+/*
+ * Use deep mask tables that incorporate rotation, pull
+ * a variable number of bits out of the stipple and
+ * reuse the right bits as needed for the next write
+ *
+ * Yes, this is probably too much code, but most 24-bpp screens
+ * have no acceleration so this code is used for stipples, copyplane
+ * and text
+ */
+void
+fbBltOne24 (FbStip *srcLine,
+ FbStride srcStride, /* FbStip units per scanline */
+ int srcX, /* bit position of source */
+ FbBits *dst,
+ FbStride dstStride, /* FbBits units per scanline */
+ int dstX, /* bit position of dest */
+ int dstBpp, /* bits per destination unit */
+
+ int width, /* width in bits of destination */
+ int height, /* height in scanlines */
+
+ FbBits fgand, /* rrop values */
+ FbBits fgxor,
+ FbBits bgand,
+ FbBits bgxor)
+{
+ FbStip *src;
+ FbBits leftMask, rightMask, mask;
+ int nlMiddle, nl;
+ FbStip stip, bits, right;
+ int remain;
+ int dstS;
+ int offset, firstlen;
+ int rot0, rot;
+ int nDst;
+
+ srcLine += srcX >> FB_STIP_SHIFT;
+ dst += dstX >> FB_SHIFT;
+ srcX &= FB_STIP_MASK;
+ dstX &= FB_MASK;
+ rot0 = dstX % 24;
+
+ FbMaskBits (dstX, width, leftMask, nlMiddle, rightMask);
+
+ dstS = (dstX + 23) / 24;
+ firstlen = FbStip24Len - dstS;
+
+ nDst = nlMiddle;
+ if (leftMask)
+ nDst++;
+ dstStride -= nDst;
+
+ /* opaque copy */
+ if (bgand == 0 && fgand == 0)
+ {
+ while (height--)
+ {
+ rot = rot0;
+ src = srcLine;
+ srcLine += srcStride;
+ fbInitStipBits (srcX,firstlen, stip);
+ if (leftMask)
+ {
+ mask = fbStipple24Bits[rot >> 3][stip];
+ *dst = *dst & ~leftMask | FbOpaqueStipple (mask,
+ FbRot24(fgxor, rot),
+ FbRot24(bgxor, rot)) & leftMask;
+ dst++;
+ fbNextStipBits(rot,stip);
+ }
+ nl = nlMiddle;
+ while (nl--)
+ {
+ mask = fbStipple24Bits[rot>>3][stip];
+ *dst = FbOpaqueStipple (mask,
+ FbRot24(fgxor, rot),
+ FbRot24(bgxor, rot));
+ dst++;
+ fbNextStipBits(rot,stip);
+ }
+ if (rightMask)
+ {
+ mask = fbStipple24Bits[rot >> 3][stip];
+ *dst = *dst & ~rightMask | FbOpaqueStipple (mask,
+ FbRot24(fgxor, rot),
+ FbRot24(bgxor, rot)) & rightMask;
+ }
+ dst += dstStride;
+ src += srcStride;
+ }
+ }
+ /* transparent copy */
+ else if (bgand == FB_ALLONES && bgxor == 0 && fgand == 0)
+ {
+ while (height--)
+ {
+ rot = rot0;
+ src = srcLine;
+ srcLine += srcStride;
+ fbInitStipBits (srcX, firstlen, stip);
+ if (leftMask)
+ {
+ if (stip)
+ {
+ mask = fbStipple24Bits[rot >> 3][stip] & leftMask;
+ *dst = *dst & ~mask | FbRot24(fgxor, rot) & mask;
+ }
+ dst++;
+ fbNextStipBits (rot, stip);
+ }
+ nl = nlMiddle;
+ while (nl--)
+ {
+ if (stip)
+ {
+ mask = fbStipple24Bits[rot>>3][stip];
+ *dst = *dst & ~mask | FbRot24(fgxor,rot) & mask;
+ }
+ dst++;
+ fbNextStipBits (rot, stip);
+ }
+ if (rightMask)
+ {
+ if (stip)
+ {
+ mask = fbStipple24Bits[rot >> 3][stip] & rightMask;
+ *dst = *dst & ~mask | FbRot24(fgxor, rot) & mask;
+ }
+ }
+ dst += dstStride;
+ }
+ }
+ else
+ {
+ while (height--)
+ {
+ rot = rot0;
+ src = srcLine;
+ srcLine += srcStride;
+ fbInitStipBits (srcX, firstlen, stip);
+ if (leftMask)
+ {
+ mask = fbStipple24Bits[rot >> 3][stip];
+ *dst = FbStippleRRopMask (*dst, mask,
+ FbRot24(fgand, rot),
+ FbRot24(fgxor, rot),
+ FbRot24(bgand, rot),
+ FbRot24(bgxor, rot),
+ leftMask);
+ dst++;
+ fbNextStipBits(rot,stip);
+ }
+ nl = nlMiddle;
+ while (nl--)
+ {
+ mask = fbStipple24Bits[rot >> 3][stip];
+ *dst = FbStippleRRop (*dst, mask,
+ FbRot24(fgand, rot),
+ FbRot24(fgxor, rot),
+ FbRot24(bgand, rot),
+ FbRot24(bgxor, rot));
+ dst++;
+ fbNextStipBits(rot,stip);
+ }
+ if (rightMask)
+ {
+ mask = fbStipple24Bits[rot >> 3][stip];
+ *dst = FbStippleRRopMask (*dst, mask,
+ FbRot24(fgand, rot),
+ FbRot24(fgxor, rot),
+ FbRot24(bgand, rot),
+ FbRot24(bgxor, rot),
+ rightMask);
+ }
+ dst += dstStride;
+ }
+ }
+}
+#endif
+
+/*
+ * Not very efficient, but simple -- copy a single plane
+ * from an N bit image to a 1 bit image
+ */
+
+void
+fbBltPlane (FbBits *src,
+ FbStride srcStride,
+ int srcX,
+ int srcBpp,
+
+ FbStip *dst,
+ FbStride dstStride,
+ int dstX,
+
+ int width,
+ int height,
+
+ FbStip fgand,
+ FbStip fgxor,
+ FbStip bgand,
+ FbStip bgxor,
+ Pixel planeMask)
+{
+ FbBits *s;
+ FbBits pm;
+ FbBits srcMask;
+ FbBits srcMaskFirst;
+ FbBits srcMask0;
+ FbBits srcBits;
+
+ FbStip pixel;
+ FbStip dstBits;
+ FbStip *d;
+ FbStip dstMask;
+ FbStip dstMaskFirst;
+ FbStip dstUnion;
+ int w;
+ int wt;
+ int dst_words;
+ int rot0;
+
+ if (!width)
+ return;
+
+ src += srcX >> FB_SHIFT;
+ srcX &= FB_MASK;
+
+ dst += dstX >> FB_STIP_SHIFT;
+ dstX &= FB_STIP_MASK;
+
+ w = width / srcBpp;
+
+ pm = fbReplicatePixel (planeMask, srcBpp);
+#ifdef FB_24BIT
+ if (srcBpp == 24)
+ {
+ int w = 24;
+
+ rot0 = srcX % 24;
+ if (srcX + w > FB_UNIT)
+ w = FB_UNIT - srcX;
+ srcMaskFirst = FbRot24(pm,rot0) & FbBitsMask(srcX,w);
+ }
+ else
+#endif
+ {
+ rot0 = 0;
+ srcMaskFirst = pm & FbBitsMask(srcX, srcBpp);
+ srcMask0 = pm & FbBitsMask(0, srcBpp);
+ }
+
+ dstMaskFirst = FbStipMask(dstX,1);
+ while (height--)
+ {
+ d = dst;
+ dst += dstStride;
+ s = src;
+ src += srcStride;
+
+ srcMask = srcMaskFirst;
+#ifdef FB_24BIT
+ if (srcBpp == 24)
+ srcMask0 = FbRot24(pm,rot0) & FbBitsMask(0, srcBpp);
+#endif
+ srcBits = *s++;
+
+ dstMask = dstMaskFirst;
+ dstUnion = 0;
+ dstBits = 0;
+
+ wt = w;
+
+ while (wt--)
+ {
+ if (!srcMask)
+ {
+ srcBits = *s++;
+#ifdef FB_24BIT
+ if (srcBpp == 24)
+ srcMask0 = FbNext24Pix(srcMask0) & FbBitsMask(0,24);
+#endif
+ srcMask = srcMask0;
+ }
+ if (!dstMask)
+ {
+ *d = FbStippleRRopMask(*d, dstBits,
+ fgand, fgxor, bgand, bgxor,
+ dstUnion);
+ d++;
+ dstMask = FbStipMask(0,1);
+ dstUnion = 0;
+ dstBits = 0;
+ }
+ if (srcBits & srcMask)
+ dstBits |= dstMask;
+ dstUnion |= dstMask;
+ srcMask = FbScrRight(srcMask,srcBpp);
+ dstMask = FbStipRight(dstMask,1);
+ }
+ if (dstUnion)
+ *d = FbStippleRRopMask(*d,dstBits,
+ fgand, fgxor, bgand, bgxor,
+ dstUnion);
+ }
+}
+
diff --git a/xc/programs/Xserver/fb/fbbstore.c b/xc/programs/Xserver/fb/fbbstore.c
new file mode 100644
index 000000000..98b424ca2
--- /dev/null
+++ b/xc/programs/Xserver/fb/fbbstore.c
@@ -0,0 +1,62 @@
+/*
+ * $Id: fbbstore.c,v 1.1 2000/01/06 12:56:52 faith Exp $
+ *
+ * Copyright © 1998 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/fb/fbbstore.c,v 1.1 1999/11/19 13:53:42 hohndel Exp $ */
+
+#include "fb.h"
+
+void
+fbSaveAreas(PixmapPtr pPixmap,
+ RegionPtr prgnSave,
+ int xorg,
+ int yorg,
+ WindowPtr pWin)
+{
+ fbCopyWindowProc (&pWin->drawable,
+ &pPixmap->drawable,
+ 0,
+ REGION_RECTS(prgnSave),
+ REGION_NUM_RECTS(prgnSave),
+ xorg, yorg,
+ FALSE,
+ FALSE,
+ 0,0);
+}
+
+void
+fbRestoreAreas(PixmapPtr pPixmap,
+ RegionPtr prgnRestore,
+ int xorg,
+ int yorg,
+ WindowPtr pWin)
+{
+ fbCopyWindowProc (&pPixmap->drawable,
+ &pWin->drawable,
+ 0,
+ REGION_RECTS(prgnRestore),
+ REGION_NUM_RECTS(prgnRestore),
+ -xorg, -yorg,
+ FALSE,
+ FALSE,
+ 0,0);
+}
diff --git a/xc/programs/Xserver/fb/fbcmap.c b/xc/programs/Xserver/fb/fbcmap.c
new file mode 100644
index 000000000..4f73aad63
--- /dev/null
+++ b/xc/programs/Xserver/fb/fbcmap.c
@@ -0,0 +1,593 @@
+/* $XConsortium: fbcmap.c,v 4.19 94/04/17 20:28:46 dpw Exp $ */
+/* $XFree86: xc/programs/Xserver/fb/fbcmap.c,v 1.2 1999/12/27 01:26:21 robin Exp $ */
+/************************************************************
+Copyright 1987 by Sun Microsystems, Inc. Mountain View, CA.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this
+software and its documentation for any purpose and without
+fee is hereby granted, provided that the above copyright no-
+tice appear in all copies and that both that copyright no-
+tice and this permission notice appear in supporting docu-
+mentation, and that the names of Sun or X Consortium
+not be used in advertising or publicity pertaining to
+distribution of the software without specific prior
+written permission. Sun and X Consortium make no
+representations about the suitability of this software for
+any purpose. It is provided "as is" without any express or
+implied warranty.
+
+SUN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT-
+NESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SUN BE LI-
+ABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
+THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+********************************************************/
+
+
+#include "X.h"
+#include "Xproto.h"
+#include "scrnintstr.h"
+#include "colormapst.h"
+#include "resource.h"
+
+ColormapPtr FbInstalledMaps[MAXSCREENS];
+
+int
+fbListInstalledColormaps(ScreenPtr pScreen, Colormap *pmaps)
+{
+ /* By the time we are processing requests, we can guarantee that there
+ * is always a colormap installed */
+ *pmaps = FbInstalledMaps[pScreen->myNum]->mid;
+ return (1);
+}
+
+
+void
+fbInstallColormap(ColormapPtr pmap)
+{
+ int index = pmap->pScreen->myNum;
+ ColormapPtr oldpmap = FbInstalledMaps[index];
+
+ if(pmap != oldpmap)
+ {
+ /* Uninstall pInstalledMap. No hardware changes required, just
+ * notify all interested parties. */
+ if(oldpmap != (ColormapPtr)None)
+ WalkTree(pmap->pScreen, TellLostMap, (char *)&oldpmap->mid);
+ /* Install pmap */
+ FbInstalledMaps[index] = pmap;
+ WalkTree(pmap->pScreen, TellGainedMap, (char *)&pmap->mid);
+ }
+}
+
+void
+fbUninstallColormap(ColormapPtr pmap)
+{
+ int index = pmap->pScreen->myNum;
+ ColormapPtr curpmap = FbInstalledMaps[index];
+
+ if(pmap == curpmap)
+ {
+ if (pmap->mid != pmap->pScreen->defColormap)
+ {
+ curpmap = (ColormapPtr) LookupIDByType(pmap->pScreen->defColormap,
+ RT_COLORMAP);
+ (*pmap->pScreen->InstallColormap)(curpmap);
+ }
+ }
+}
+
+void
+fbResolveColor(unsigned short *pred,
+ unsigned short *pgreen,
+ unsigned short *pblue,
+ VisualPtr pVisual)
+{
+ int shift = 16 - pVisual->bitsPerRGBValue;
+ unsigned lim = (1 << pVisual->bitsPerRGBValue) - 1;
+
+ if ((pVisual->class == PseudoColor) || (pVisual->class == DirectColor))
+ {
+ /* rescale to rgb bits */
+ *pred = ((*pred >> shift) * 65535) / lim;
+ *pgreen = ((*pgreen >> shift) * 65535) / lim;
+ *pblue = ((*pblue >> shift) * 65535) / lim;
+ }
+ else if (pVisual->class == GrayScale)
+ {
+ /* rescale to gray then rgb bits */
+ *pred = (30L * *pred + 59L * *pgreen + 11L * *pblue) / 100;
+ *pblue = *pgreen = *pred = ((*pred >> shift) * 65535) / lim;
+ }
+ else if (pVisual->class == StaticGray)
+ {
+ unsigned limg = pVisual->ColormapEntries - 1;
+ /* rescale to gray then [0..limg] then [0..65535] then rgb bits */
+ *pred = (30L * *pred + 59L * *pgreen + 11L * *pblue) / 100;
+ *pred = ((((*pred * (limg + 1))) >> 16) * 65535) / limg;
+ *pblue = *pgreen = *pred = ((*pred >> shift) * 65535) / lim;
+ }
+ else
+ {
+ unsigned limr, limg, limb;
+
+ limr = pVisual->redMask >> pVisual->offsetRed;
+ limg = pVisual->greenMask >> pVisual->offsetGreen;
+ limb = pVisual->blueMask >> pVisual->offsetBlue;
+ /* rescale to [0..limN] then [0..65535] then rgb bits */
+ *pred = ((((((*pred * (limr + 1)) >> 16) *
+ 65535) / limr) >> shift) * 65535) / lim;
+ *pgreen = ((((((*pgreen * (limg + 1)) >> 16) *
+ 65535) / limg) >> shift) * 65535) / lim;
+ *pblue = ((((((*pblue * (limb + 1)) >> 16) *
+ 65535) / limb) >> shift) * 65535) / lim;
+ }
+}
+
+Bool
+fbInitializeColormap(ColormapPtr pmap)
+{
+ register unsigned i;
+ register VisualPtr pVisual;
+ unsigned lim, maxent, shift;
+
+ pVisual = pmap->pVisual;
+ lim = (1 << pVisual->bitsPerRGBValue) - 1;
+ shift = 16 - pVisual->bitsPerRGBValue;
+ maxent = pVisual->ColormapEntries - 1;
+ if (pVisual->class == TrueColor)
+ {
+ unsigned limr, limg, limb;
+
+ limr = pVisual->redMask >> pVisual->offsetRed;
+ limg = pVisual->greenMask >> pVisual->offsetGreen;
+ limb = pVisual->blueMask >> pVisual->offsetBlue;
+ for(i = 0; i <= maxent; i++)
+ {
+ /* rescale to [0..65535] then rgb bits */
+ pmap->red[i].co.local.red =
+ ((((i * 65535) / limr) >> shift) * 65535) / lim;
+ pmap->green[i].co.local.green =
+ ((((i * 65535) / limg) >> shift) * 65535) / lim;
+ pmap->blue[i].co.local.blue =
+ ((((i * 65535) / limb) >> shift) * 65535) / lim;
+ }
+ }
+ else if (pVisual->class == StaticColor)
+ {
+ unsigned limr, limg, limb;
+
+ limr = pVisual->redMask >> pVisual->offsetRed;
+ limg = pVisual->greenMask >> pVisual->offsetGreen;
+ limb = pVisual->blueMask >> pVisual->offsetBlue;
+ for(i = 0; i <= maxent; i++)
+ {
+ /* rescale to [0..65535] then rgb bits */
+ pmap->red[i].co.local.red =
+ ((((((i & pVisual->redMask) >> pVisual->offsetRed)
+ * 65535) / limr) >> shift) * 65535) / lim;
+ pmap->red[i].co.local.green =
+ ((((((i & pVisual->greenMask) >> pVisual->offsetGreen)
+ * 65535) / limg) >> shift) * 65535) / lim;
+ pmap->red[i].co.local.blue =
+ ((((((i & pVisual->blueMask) >> pVisual->offsetBlue)
+ * 65535) / limb) >> shift) * 65535) / lim;
+ }
+ }
+ else if (pVisual->class == StaticGray)
+ {
+ for(i = 0; i <= maxent; i++)
+ {
+ /* rescale to [0..65535] then rgb bits */
+ pmap->red[i].co.local.red = ((((i * 65535) / maxent) >> shift)
+ * 65535) / lim;
+ pmap->red[i].co.local.green = pmap->red[i].co.local.red;
+ pmap->red[i].co.local.blue = pmap->red[i].co.local.red;
+ }
+ }
+ return TRUE;
+}
+
+/* When simulating DirectColor on PseudoColor hardware, multiple
+ entries of the colormap must be updated
+ */
+
+#define AddElement(mask) { \
+ pixel = red | green | blue; \
+ for (i = 0; i < nresult; i++) \
+ if (outdefs[i].pixel == pixel) \
+ break; \
+ if (i == nresult) \
+ { \
+ nresult++; \
+ outdefs[i].pixel = pixel; \
+ outdefs[i].flags = 0; \
+ } \
+ outdefs[i].flags |= (mask); \
+ outdefs[i].red = pmap->red[red >> pVisual->offsetRed].co.local.red; \
+ outdefs[i].green = pmap->green[green >> pVisual->offsetGreen].co.local.green; \
+ outdefs[i].blue = pmap->blue[blue >> pVisual->offsetBlue].co.local.blue; \
+}
+
+int
+fbExpandDirectColors (ColormapPtr pmap,
+ int ndef,
+ xColorItem *indefs,
+ xColorItem *outdefs)
+{
+ int minred, mingreen, minblue;
+ register int red, green, blue;
+ int maxred, maxgreen, maxblue;
+ int stepred, stepgreen, stepblue;
+ VisualPtr pVisual;
+ register int pixel;
+ register int nresult;
+ register int i;
+
+ pVisual = pmap->pVisual;
+
+ stepred = 1 << pVisual->offsetRed;
+ stepgreen = 1 << pVisual->offsetGreen;
+ stepblue = 1 << pVisual->offsetBlue;
+ maxred = pVisual->redMask;
+ maxgreen = pVisual->greenMask;
+ maxblue = pVisual->blueMask;
+ nresult = 0;
+ for (;ndef--; indefs++)
+ {
+ if (indefs->flags & DoRed)
+ {
+ red = indefs->pixel & pVisual->redMask;
+ for (green = 0; green <= maxgreen; green += stepgreen)
+ {
+ for (blue = 0; blue <= maxblue; blue += stepblue)
+ {
+ AddElement (DoRed)
+ }
+ }
+ }
+ if (indefs->flags & DoGreen)
+ {
+ green = indefs->pixel & pVisual->greenMask;
+ for (red = 0; red <= maxred; red += stepred)
+ {
+ for (blue = 0; blue <= maxblue; blue += stepblue)
+ {
+ AddElement (DoGreen)
+ }
+ }
+ }
+ if (indefs->flags & DoBlue)
+ {
+ blue = indefs->pixel & pVisual->blueMask;
+ for (red = 0; red <= maxred; red += stepred)
+ {
+ for (green = 0; green <= maxgreen; green += stepgreen)
+ {
+ AddElement (DoBlue)
+ }
+ }
+ }
+ }
+ return nresult;
+}
+
+Bool
+fbCreateDefColormap(ScreenPtr pScreen)
+{
+ unsigned short zero = 0, ones = 0xFFFF;
+ VisualPtr pVisual;
+ ColormapPtr cmap;
+ Pixel wp, bp;
+
+ for (pVisual = pScreen->visuals;
+ pVisual->vid != pScreen->rootVisual;
+ pVisual++)
+ ;
+
+ if (CreateColormap(pScreen->defColormap, pScreen, pVisual, &cmap,
+ (pVisual->class & DynamicClass) ? AllocNone : AllocAll,
+ 0)
+ != Success)
+ return FALSE;
+ wp = pScreen->whitePixel;
+ bp = pScreen->blackPixel;
+ if ((AllocColor(cmap, &ones, &ones, &ones, &wp, 0) !=
+ Success) ||
+ (AllocColor(cmap, &zero, &zero, &zero, &bp, 0) !=
+ Success))
+ return FALSE;
+ pScreen->whitePixel = wp;
+ pScreen->blackPixel = bp;
+ (*pScreen->InstallColormap)(cmap);
+ return TRUE;
+}
+
+extern int defaultColorVisualClass;
+
+#define _RZ(d) ((d + 2) / 3)
+#define _RS(d) 0
+#define _RM(d) ((1 << _RZ(d)) - 1)
+#define _GZ(d) ((d - _RZ(d) + 1) / 2)
+#define _GS(d) _RZ(d)
+#define _GM(d) (((1 << _GZ(d)) - 1) << _GS(d))
+#define _BZ(d) (d - _RZ(d) - _GZ(d))
+#define _BS(d) (_RZ(d) + _GZ(d))
+#define _BM(d) (((1 << _BZ(d)) - 1) << _BS(d))
+#define _CE(d) (1 << _RZ(d))
+
+#define MAX_PSEUDO_DEPTH 10 /* largest DAC size I know */
+
+#define StaticGrayMask (1 << StaticGray)
+#define GrayScaleMask (1 << GrayScale)
+#define StaticColorMask (1 << StaticColor)
+#define PseudoColorMask (1 << PseudoColor)
+#define TrueColorMask (1 << TrueColor)
+#define DirectColorMask (1 << DirectColor)
+
+#define ALL_VISUALS (StaticGrayMask|\
+ GrayScaleMask|\
+ StaticColorMask|\
+ PseudoColorMask|\
+ TrueColorMask|\
+ DirectColorMask)
+
+#define LARGE_VISUALS (TrueColorMask|\
+ DirectColorMask)
+
+typedef struct _fbVisuals {
+ struct _fbVisuals *next;
+ int depth;
+ int bitsPerRGB;
+ int visuals;
+ int count;
+ Pixel redMask, greenMask, blueMask;
+} fbVisualsRec, *fbVisualsPtr;
+
+static const int fbVisualPriority[] = {
+ PseudoColor, DirectColor, GrayScale, StaticColor, TrueColor, StaticGray
+};
+
+#define NUM_PRIORITY 6
+
+static fbVisualsPtr fbVisuals;
+
+static int
+popCount (int i)
+{
+ int count;
+
+ count = (i >> 1) & 033333333333;
+ count = i - count - ((count >> 1) & 033333333333);
+ count = (((count + (count >> 3)) & 030707070707) % 077); /* HAKMEM 169 */
+ return count;
+}
+
+/*
+ * Distance to least significant one bit
+ */
+static int
+maskShift (Pixel p)
+{
+ int s;
+
+ if (!p) return 0;
+ s = 0;
+ while (!(p & 1))
+ {
+ s++;
+ p >>= 1;
+ }
+ return s;
+}
+
+Bool
+fbSetVisualTypesAndMasks (int depth, int visuals, int bitsPerRGB,
+ Pixel redMask, Pixel greenMask, Pixel blueMask)
+{
+ fbVisualsPtr new, *prev, v;
+
+ new = (fbVisualsPtr) xalloc (sizeof *new);
+ if (!new)
+ return FALSE;
+ if (!redMask || !greenMask || !blueMask)
+ {
+ redMask = _RM(depth);
+ greenMask = _GM(depth);
+ blueMask = _BM(depth);
+ }
+ new->next = 0;
+ new->depth = depth;
+ new->visuals = visuals;
+ new->bitsPerRGB = bitsPerRGB;
+ new->redMask = redMask;
+ new->greenMask = greenMask;
+ new->blueMask = blueMask;
+ new->count = popCount (visuals);
+ for (prev = &fbVisuals; v = *prev; prev = &v->next);
+ *prev = new;
+ return TRUE;
+}
+
+Bool
+fbHasVisualTypes (int depth)
+{
+ fbVisualsPtr v;
+
+ for (v = fbVisuals; v; v = v->next)
+ if (v->depth == depth)
+ return TRUE;
+ return FALSE;
+}
+
+Bool
+fbSetVisualTypes (int depth, int visuals, int bitsPerRGB)
+{
+ fbSetVisualTypesAndMasks (depth, visuals, bitsPerRGB,
+ _RM(depth), _GM(depth), _BM(depth));
+}
+
+/*
+ * Given a list of formats for a screen, create a list
+ * of visuals and depths for the screen which coorespond to
+ * the set which can be used with this version of fb.
+ */
+
+Bool
+fbInitVisuals (VisualPtr *visualp,
+ DepthPtr *depthp,
+ int *nvisualp,
+ int *ndepthp,
+ int *rootDepthp,
+ VisualID *defaultVisp,
+ unsigned long sizes,
+ int bitsPerRGB)
+{
+ int i, j, k;
+ VisualPtr visual;
+ DepthPtr depth;
+ VisualID *vid;
+ int d, b;
+ int f;
+ int ndepth, nvisual;
+ int nvtype;
+ int vtype;
+ VisualID defaultVisual;
+ fbVisualsPtr visuals, nextVisuals;
+
+ /* none specified, we'll guess from pixmap formats */
+ if (!fbVisuals)
+ {
+ for (f = 0; f < screenInfo.numPixmapFormats; f++)
+ {
+ d = screenInfo.formats[f].depth;
+ b = screenInfo.formats[f].bitsPerPixel;
+ if (sizes & (1 << (b - 1)))
+ {
+ if (d > MAX_PSEUDO_DEPTH)
+ vtype = LARGE_VISUALS;
+ else if (d == 1)
+ vtype = StaticGrayMask;
+ else
+ vtype = ALL_VISUALS;
+ }
+ else
+ vtype = 0;
+ if (!fbSetVisualTypes (d, vtype, bitsPerRGB))
+ return FALSE;
+ }
+ }
+ nvisual = 0;
+ ndepth = 0;
+ for (visuals = fbVisuals; visuals; visuals = nextVisuals)
+ {
+ nextVisuals = visuals->next;
+ ndepth++;
+ nvisual += visuals->count;
+ }
+ depth = (DepthPtr) xalloc (ndepth * sizeof (DepthRec));
+ visual = (VisualPtr) xalloc (nvisual * sizeof (VisualRec));
+ if (!depth || !visual)
+ {
+ xfree (depth);
+ xfree (visual);
+ return FALSE;
+ }
+ *depthp = depth;
+ *visualp = visual;
+ *ndepthp = ndepth;
+ *nvisualp = nvisual;
+ for (visuals = fbVisuals; visuals; visuals = nextVisuals)
+ {
+ nextVisuals = visuals->next;
+ d = visuals->depth;
+ vtype = visuals->visuals;
+ nvtype = visuals->count;
+ vid = NULL;
+ if (nvtype)
+ {
+ vid = (VisualID *) xalloc (nvtype * sizeof (VisualID));
+ if (!vid)
+ return FALSE;
+ }
+ depth->depth = d;
+ depth->numVids = nvtype;
+ depth->vids = vid;
+ depth++;
+ for (i = 0; i < NUM_PRIORITY; i++) {
+ if (! (vtype & (1 << fbVisualPriority[i])))
+ continue;
+ visual->class = fbVisualPriority[i];
+ visual->bitsPerRGBValue = visuals->bitsPerRGB;
+ visual->ColormapEntries = 1 << d;
+ visual->nplanes = d;
+ visual->vid = *vid = FakeClientID (0);
+ switch (visual->class) {
+ case PseudoColor:
+ case GrayScale:
+ case StaticGray:
+ visual->redMask = 0;
+ visual->greenMask = 0;
+ visual->blueMask = 0;
+ visual->offsetRed = 0;
+ visual->offsetGreen = 0;
+ visual->offsetBlue = 0;
+ break;
+ case DirectColor:
+ case TrueColor:
+ visual->ColormapEntries = _CE(d);
+ /* fall through */
+ case StaticColor:
+ visual->redMask = visuals->redMask;
+ visual->greenMask = visuals->greenMask;
+ visual->blueMask = visuals->blueMask;
+ visual->offsetRed = maskShift (visuals->redMask);
+ visual->offsetGreen = maskShift (visuals->greenMask);
+ visual->offsetBlue = maskShift (visuals->blueMask);
+ }
+ vid++;
+ visual++;
+ }
+ xfree (visuals);
+ }
+ fbVisuals = NULL;
+ visual = *visualp;
+ depth = *depthp;
+ for (i = 0; i < ndepth; i++)
+ {
+ if (*rootDepthp && *rootDepthp != depth[i].depth)
+ continue;
+ for (j = 0; j < depth[i].numVids; j++)
+ {
+ for (k = 0; k < nvisual; k++)
+ if (visual[k].vid == depth[i].vids[j])
+ break;
+ if (k == nvisual)
+ continue;
+ if (defaultColorVisualClass < 0 ||
+ visual[k].class == defaultColorVisualClass)
+ break;
+ }
+ if (j != depth[i].numVids)
+ break;
+ }
+ if (i == ndepth) {
+ for (i = 0; i < ndepth; i++)
+ {
+ if (depth[i].numVids)
+ break;
+ }
+ if (i == ndepth)
+ return FALSE;
+ j = 0;
+ }
+ *rootDepthp = depth[i].depth;
+ *defaultVisp = depth[i].vids[j];
+ return TRUE;
+}
diff --git a/xc/programs/Xserver/fb/fbcopy.c b/xc/programs/Xserver/fb/fbcopy.c
new file mode 100644
index 000000000..70044ac80
--- /dev/null
+++ b/xc/programs/Xserver/fb/fbcopy.c
@@ -0,0 +1,629 @@
+/*
+ * $Id: fbcopy.c,v 1.1 2000/01/06 12:56:53 faith Exp $
+ *
+ * Copyright © 1998 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/fb/fbcopy.c,v 1.1 1999/11/19 13:53:42 hohndel Exp $ */
+
+#include "fb.h"
+
+void
+fbCopyNtoN (DrawablePtr pSrcDrawable,
+ DrawablePtr pDstDrawable,
+ GCPtr pGC,
+ BoxPtr pbox,
+ int nbox,
+ int dx,
+ int dy,
+ Bool reverse,
+ Bool upsidedown,
+ Pixel bitplane,
+ void *closure)
+{
+ FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
+ FbBits *src;
+ FbStride srcStride;
+ int srcBpp;
+ FbBits *dst;
+ FbStride dstStride;
+ int dstBpp;
+
+ fbGetDrawable (pSrcDrawable, src, srcStride, srcBpp);
+ fbGetDrawable (pDstDrawable, dst, dstStride, dstBpp);
+
+ while (nbox--)
+ {
+ fbBlt (src + (pbox->y1 + dy) * srcStride,
+ srcStride,
+ (pbox->x1 + dx) * srcBpp,
+
+ dst + (pbox->y1) * dstStride,
+ dstStride,
+ (pbox->x1) * dstBpp,
+
+ (pbox->x2 - pbox->x1) * dstBpp,
+ (pbox->y2 - pbox->y1),
+
+ pGC->alu,
+ pPriv->pm,
+ dstBpp,
+
+ reverse,
+ upsidedown);
+ pbox++;
+ }
+}
+
+void
+fbCopy1toN (DrawablePtr pSrcDrawable,
+ DrawablePtr pDstDrawable,
+ GCPtr pGC,
+ BoxPtr pbox,
+ int nbox,
+ int dx,
+ int dy,
+ Bool reverse,
+ Bool upsidedown,
+ Pixel bitplane,
+ void *closure)
+{
+ FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
+ FbBits *src;
+ FbStride srcStride;
+ int srcBpp;
+ FbBits *dst;
+ FbStride dstStride;
+ int dstBpp;
+
+ fbGetDrawable (pSrcDrawable, src, srcStride, srcBpp);
+ fbGetDrawable (pDstDrawable, dst, dstStride, dstBpp);
+
+ while (nbox--)
+ {
+ if (dstBpp == 1)
+ {
+ fbBlt (src + (pbox->y1 + dy) * srcStride,
+ srcStride,
+ (pbox->x1 + dx) * srcBpp,
+
+ dst + (pbox->y1) * dstStride,
+ dstStride,
+ (pbox->x1) * dstBpp,
+
+ (pbox->x2 - pbox->x1) * dstBpp,
+ (pbox->y2 - pbox->y1),
+
+ FbOpaqueStipple1Rop(pGC->alu,
+ pGC->fgPixel,pGC->bgPixel),
+ pPriv->pm,
+ dstBpp,
+
+ reverse,
+ upsidedown);
+ }
+ else
+ {
+ fbBltOne ((FbStip *) (src + (pbox->y1 + dy) * srcStride),
+ srcStride*(FB_UNIT/FB_STIP_UNIT),
+ (pbox->x1 + dx),
+
+ dst + (pbox->y1) * dstStride,
+ dstStride,
+ (pbox->x1) * dstBpp,
+ dstBpp,
+
+ (pbox->x2 - pbox->x1) * dstBpp,
+ (pbox->y2 - pbox->y1),
+
+ pPriv->and, pPriv->xor,
+ pPriv->bgand, pPriv->bgxor);
+ }
+ pbox++;
+ }
+}
+
+void
+fbCopyNto1 (DrawablePtr pSrcDrawable,
+ DrawablePtr pDstDrawable,
+ GCPtr pGC,
+ BoxPtr pbox,
+ int nbox,
+ int dx,
+ int dy,
+ Bool reverse,
+ Bool upsidedown,
+ Pixel bitplane,
+ void *closure)
+{
+ FbGCPrivPtr pPriv = fbGetGCPrivate (pGC);
+
+ while (nbox--)
+ {
+ if (pDstDrawable->bitsPerPixel == 1)
+ {
+ FbBits *src;
+ FbStride srcStride;
+ int srcBpp;
+
+ FbStip *dst;
+ FbStride dstStride;
+ int dstBpp;
+
+ fbGetDrawable (pSrcDrawable, src, srcStride, srcBpp);
+ fbGetStipDrawable (pDstDrawable, dst, dstStride, dstBpp);
+ fbBltPlane (src + (pbox->y1+ dy) * srcStride,
+ srcStride,
+ (pbox->x1 + dx) * srcBpp,
+ srcBpp,
+
+ dst + (pbox->y1) * dstStride,
+ dstStride,
+ (pbox->x1) * dstBpp,
+
+ (pbox->x2 - pbox->x1) * srcBpp,
+ (pbox->y2 - pbox->y1),
+
+ (FbStip) pPriv->and, (FbStip) pPriv->xor,
+ (FbStip) pPriv->bgand, (FbStip) pPriv->bgxor,
+ bitplane);
+ }
+ else
+ {
+ FbBits *src;
+ FbStride srcStride;
+ int srcBpp;
+
+ FbBits *dst;
+ FbStride dstStride;
+ int dstBpp;
+
+ FbStip *tmp;
+ FbStride tmpStride;
+ int width, height;
+
+ width = pbox->x2 - pbox->x1;
+ height = pbox->y2 - pbox->y1;
+
+ tmpStride = ((width + FB_STIP_MASK) >> FB_STIP_SHIFT);
+ tmp = xalloc (tmpStride * height * sizeof (FbStip));
+ if (!tmp)
+ return;
+
+ fbGetDrawable (pSrcDrawable, src, srcStride, srcBpp);
+ fbGetDrawable (pDstDrawable, dst, dstStride, dstBpp);
+
+ fbBltPlane (src + (pbox->y1+ dy) * srcStride,
+ srcStride,
+ (pbox->x1 + dx) * srcBpp,
+ srcBpp,
+
+ tmp,
+ tmpStride,
+ 0,
+
+ width * srcBpp,
+ height,
+
+ fbAndStip(GXcopy,FB_ALLONES,FB_ALLONES),
+ fbXorStip(GXcopy,FB_ALLONES,FB_ALLONES),
+ fbAndStip(GXcopy,0,FB_ALLONES),
+ fbXorStip(GXcopy,0,FB_ALLONES),
+ bitplane);
+ fbBltOne (tmp,
+ tmpStride,
+ 0,
+
+ dst + (pbox->y1) * dstStride,
+ dstStride,
+ (pbox->x1) * dstBpp,
+ dstBpp,
+
+ width * dstBpp,
+ height,
+
+ pPriv->and, pPriv->xor,
+ pPriv->bgand, pPriv->bgxor);
+ xfree (tmp);
+ }
+ pbox++;
+ }
+}
+
+void
+fbCopyRegion (DrawablePtr pSrcDrawable,
+ DrawablePtr pDstDrawable,
+ GCPtr pGC,
+ RegionPtr pDstRegion,
+ int dx,
+ int dy,
+ fbCopyProc copyProc,
+ Pixel bitPlane,
+ void *closure)
+{
+ int careful;
+ Bool reverse;
+ Bool upsidedown;
+ BoxPtr pbox;
+ int nbox;
+ BoxPtr pboxNew1, pboxNew2, pboxBase, pboxNext, pboxTmp;
+
+ pbox = REGION_RECTS(pDstRegion);
+ nbox = REGION_NUM_RECTS(pDstRegion);
+
+ /* XXX we have to err on the side of safety when both are windows,
+ * because we don't know if IncludeInferiors is being used.
+ */
+ careful = ((pSrcDrawable == pDstDrawable) ||
+ ((pSrcDrawable->type == DRAWABLE_WINDOW) &&
+ (pDstDrawable->type == DRAWABLE_WINDOW)));
+
+ pboxNew1 = NULL;
+ pboxNew2 = NULL;
+ if (careful && dy < 0)
+ {
+ upsidedown = TRUE;
+
+ if (nbox > 1)
+ {
+ /* keep ordering in each band, reverse order of bands */
+ pboxNew1 = (BoxPtr)ALLOCATE_LOCAL(sizeof(BoxRec) * nbox);
+ if(!pboxNew1)
+ return;
+ pboxBase = pboxNext = pbox+nbox-1;
+ while (pboxBase >= pbox)
+ {
+ while ((pboxNext >= pbox) &&
+ (pboxBase->y1 == pboxNext->y1))
+ pboxNext--;
+ pboxTmp = pboxNext+1;
+ while (pboxTmp <= pboxBase)
+ {
+ *pboxNew1++ = *pboxTmp++;
+ }
+ pboxBase = pboxNext;
+ }
+ pboxNew1 -= nbox;
+ pbox = pboxNew1;
+ }
+ }
+ else
+ {
+ /* walk source top to bottom */
+ upsidedown = FALSE;
+ }
+
+ if (careful && dx < 0)
+ {
+ /* walk source right to left */
+ if (dy <= 0)
+ reverse = TRUE;
+ else
+ reverse = FALSE;
+
+ if (nbox > 1)
+ {
+ /* reverse order of rects in each band */
+ pboxNew2 = (BoxPtr)ALLOCATE_LOCAL(sizeof(BoxRec) * nbox);
+ if(!pboxNew2)
+ {
+ if (pboxNew1)
+ DEALLOCATE_LOCAL(pboxNew1);
+ return;
+ }
+ pboxBase = pboxNext = pbox;
+ while (pboxBase < pbox+nbox)
+ {
+ while ((pboxNext < pbox+nbox) &&
+ (pboxNext->y1 == pboxBase->y1))
+ pboxNext++;
+ pboxTmp = pboxNext;
+ while (pboxTmp != pboxBase)
+ {
+ *pboxNew2++ = *--pboxTmp;
+ }
+ pboxBase = pboxNext;
+ }
+ pboxNew2 -= nbox;
+ pbox = pboxNew2;
+ }
+ }
+ else
+ {
+ /* walk source left to right */
+ reverse = FALSE;
+ }
+
+ (*copyProc) (pSrcDrawable,
+ pDstDrawable,
+ pGC,
+ pbox,
+ nbox,
+ dx, dy,
+ reverse, upsidedown, bitPlane, closure);
+
+ if (pboxNew1)
+ DEALLOCATE_LOCAL (pboxNew1);
+ if (pboxNew2)
+ DEALLOCATE_LOCAL (pboxNew2);
+}
+
+RegionPtr
+fbDoCopy (DrawablePtr pSrcDrawable,
+ DrawablePtr pDstDrawable,
+ GCPtr pGC,
+ int xIn,
+ int yIn,
+ int widthSrc,
+ int heightSrc,
+ int xOut,
+ int yOut,
+ fbCopyProc copyProc,
+ Pixel bitPlane,
+ void *closure)
+{
+ RegionPtr prgnSrcClip; /* may be a new region, or just a copy */
+ Bool freeSrcClip = FALSE;
+
+ RegionPtr prgnExposed = NULL;
+ RegionRec rgnDst;
+ register BoxPtr pbox;
+ int i;
+ register int dx;
+ register int dy;
+ xRectangle origSource;
+ DDXPointRec origDest;
+ int numRects;
+ BoxRec fastBox;
+ int fastClip = 0; /* for fast clipping with pixmap source */
+ int fastExpose = 0; /* for fast exposures with pixmap source */
+
+ origSource.x = xIn;
+ origSource.y = yIn;
+ origSource.width = widthSrc;
+ origSource.height = heightSrc;
+ origDest.x = xOut;
+ origDest.y = yOut;
+
+ if ((pSrcDrawable != pDstDrawable) &&
+ pSrcDrawable->pScreen->SourceValidate)
+ {
+ (*pSrcDrawable->pScreen->SourceValidate) (pSrcDrawable, xIn, yIn, widthSrc, heightSrc);
+ }
+
+ xIn += pSrcDrawable->x;
+ yIn += pSrcDrawable->y;
+
+ /* clip the source */
+
+ if (pSrcDrawable->type == DRAWABLE_PIXMAP)
+ {
+ if ((pSrcDrawable == pDstDrawable) && (pGC->clientClipType == CT_NONE))
+ prgnSrcClip = fbGetCompositeClip(pGC);
+ else
+ fastClip = 1;
+ }
+ else
+ {
+ if (pGC->subWindowMode == IncludeInferiors)
+ {
+ if (!((WindowPtr) pSrcDrawable)->parent)
+ {
+ /*
+ * special case bitblt from root window in
+ * IncludeInferiors mode; just like from a pixmap
+ */
+ fastClip = 1;
+ }
+ else if ((pSrcDrawable == pDstDrawable) &&
+ (pGC->clientClipType == CT_NONE))
+ {
+ prgnSrcClip = fbGetCompositeClip(pGC);
+ }
+ else
+ {
+ prgnSrcClip = NotClippedByChildren((WindowPtr)pSrcDrawable);
+ freeSrcClip = TRUE;
+ }
+ }
+ else
+ {
+ prgnSrcClip = &((WindowPtr)pSrcDrawable)->clipList;
+ }
+ }
+
+ fastBox.x1 = xIn;
+ fastBox.y1 = yIn;
+ fastBox.x2 = xIn + widthSrc;
+ fastBox.y2 = yIn + heightSrc;
+
+ /* Don't create a source region if we are doing a fast clip */
+ if (fastClip)
+ {
+ fastExpose = 1;
+ /*
+ * clip the source; if regions extend beyond the source size,
+ * make sure exposure events get sent
+ */
+ if (fastBox.x1 < pSrcDrawable->x)
+ {
+ fastBox.x1 = pSrcDrawable->x;
+ fastExpose = 0;
+ }
+ if (fastBox.y1 < pSrcDrawable->y)
+ {
+ fastBox.y1 = pSrcDrawable->y;
+ fastExpose = 0;
+ }
+ if (fastBox.x2 > pSrcDrawable->x + (int) pSrcDrawable->width)
+ {
+ fastBox.x2 = pSrcDrawable->x + (int) pSrcDrawable->width;
+ fastExpose = 0;
+ }
+ if (fastBox.y2 > pSrcDrawable->y + (int) pSrcDrawable->height)
+ {
+ fastBox.y2 = pSrcDrawable->y + (int) pSrcDrawable->height;
+ fastExpose = 0;
+ }
+ }
+ else
+ {
+ REGION_INIT(pGC->pScreen, &rgnDst, &fastBox, 1);
+ REGION_INTERSECT(pGC->pScreen, &rgnDst, &rgnDst, prgnSrcClip);
+ }
+
+ xOut += pDstDrawable->x;
+ yOut += pDstDrawable->y;
+
+ if (pDstDrawable->type == DRAWABLE_WINDOW)
+ {
+ if (!((WindowPtr)pDstDrawable)->realized)
+ {
+ if (!fastClip)
+ REGION_UNINIT(pGC->pScreen, &rgnDst);
+ if (freeSrcClip)
+ REGION_DESTROY(pGC->pScreen, prgnSrcClip);
+ return NULL;
+ }
+ }
+
+ dx = xIn - xOut;
+ dy = yIn - yOut;
+
+ /* Translate and clip the dst to the destination composite clip */
+ if (fastClip)
+ {
+ RegionPtr cclip;
+
+ /* Translate the region directly */
+ fastBox.x1 -= dx;
+ fastBox.x2 -= dx;
+ fastBox.y1 -= dy;
+ fastBox.y2 -= dy;
+
+ /* If the destination composite clip is one rectangle we can
+ do the clip directly. Otherwise we have to create a full
+ blown region and call intersect */
+
+ cclip = fbGetCompositeClip(pGC);
+ if (REGION_NUM_RECTS(cclip) == 1)
+ {
+ BoxPtr pBox = REGION_RECTS(cclip);
+
+ if (fastBox.x1 < pBox->x1) fastBox.x1 = pBox->x1;
+ if (fastBox.x2 > pBox->x2) fastBox.x2 = pBox->x2;
+ if (fastBox.y1 < pBox->y1) fastBox.y1 = pBox->y1;
+ if (fastBox.y2 > pBox->y2) fastBox.y2 = pBox->y2;
+
+ /* Check to see if the region is empty */
+ if (fastBox.x1 >= fastBox.x2 || fastBox.y1 >= fastBox.y2)
+ {
+ REGION_INIT(pGC->pScreen, &rgnDst, NullBox, 0);
+ }
+ else
+ {
+ REGION_INIT(pGC->pScreen, &rgnDst, &fastBox, 1);
+ }
+ }
+ else
+ {
+ /* We must turn off fastClip now, since we must create
+ a full blown region. It is intersected with the
+ composite clip below. */
+ fastClip = 0;
+ REGION_INIT(pGC->pScreen, &rgnDst, &fastBox,1);
+ }
+ }
+ else
+ {
+ REGION_TRANSLATE(pGC->pScreen, &rgnDst, -dx, -dy);
+ }
+
+ if (!fastClip)
+ {
+ REGION_INTERSECT(pGC->pScreen, &rgnDst,
+ &rgnDst,
+ fbGetCompositeClip(pGC));
+ }
+
+ /* Do bit blitting */
+ numRects = REGION_NUM_RECTS(&rgnDst);
+ if (numRects && widthSrc && heightSrc)
+ fbCopyRegion (pSrcDrawable, pDstDrawable, pGC,
+ &rgnDst, dx, dy, copyProc, bitPlane, closure);
+
+ /* Pixmap sources generate a NoExposed (we return NULL to do this) */
+ if (!fastExpose)
+ prgnExposed = miHandleExposures(pSrcDrawable, pDstDrawable, pGC,
+ origSource.x, origSource.y,
+ (int)origSource.width,
+ (int)origSource.height,
+ origDest.x, origDest.y,
+ (unsigned long) bitPlane);
+bail:
+ REGION_UNINIT(pGC->pScreen, &rgnDst);
+ if (freeSrcClip)
+ REGION_DESTROY(pGC->pScreen, prgnSrcClip);
+ fbValidateDrawable (pDstDrawable);
+ return prgnExposed;
+}
+
+RegionPtr
+fbCopyArea (DrawablePtr pSrcDrawable,
+ DrawablePtr pDstDrawable,
+ GCPtr pGC,
+ int xIn,
+ int yIn,
+ int widthSrc,
+ int heightSrc,
+ int xOut,
+ int yOut)
+{
+ return fbDoCopy (pSrcDrawable, pDstDrawable, pGC, xIn, yIn,
+ widthSrc, heightSrc, xOut, yOut, fbCopyNtoN, 0, 0);
+}
+
+RegionPtr
+fbCopyPlane (DrawablePtr pSrcDrawable,
+ DrawablePtr pDstDrawable,
+ GCPtr pGC,
+ int xIn,
+ int yIn,
+ int widthSrc,
+ int heightSrc,
+ int xOut,
+ int yOut,
+ unsigned long bitplane)
+{
+ if (pSrcDrawable->bitsPerPixel > 1)
+ return fbDoCopy (pSrcDrawable, pDstDrawable, pGC,
+ xIn, yIn, widthSrc, heightSrc,
+ xOut, yOut, fbCopyNto1, (Pixel) bitplane, 0);
+ else if (bitplane & 1)
+ return fbDoCopy (pSrcDrawable, pDstDrawable, pGC, xIn, yIn,
+ widthSrc, heightSrc, xOut, yOut, fbCopy1toN,
+ (Pixel) bitplane, 0);
+ else
+ return miHandleExposures(pSrcDrawable, pDstDrawable, pGC,
+ xIn, yIn,
+ widthSrc,
+ heightSrc,
+ xOut, yOut, bitplane);
+}
diff --git a/xc/programs/Xserver/fb/fbfill.c b/xc/programs/Xserver/fb/fbfill.c
new file mode 100644
index 000000000..44866e421
--- /dev/null
+++ b/xc/programs/Xserver/fb/fbfill.c
@@ -0,0 +1,206 @@
+/*
+ * $Id: fbfill.c,v 1.1 2000/01/06 12:56:53 faith Exp $
+ *
+ * Copyright © 1998 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/fb/fbfill.c,v 1.1 1999/11/19 13:53:43 hohndel Exp $ */
+
+#include "fb.h"
+
+void
+fbFill (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ int width,
+ int height)
+{
+ FbBits *dst;
+ FbStride dstStride;
+ int dstBpp;
+ FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
+
+ fbGetDrawable (pDrawable, dst, dstStride, dstBpp);
+
+ switch (pGC->fillStyle) {
+ case FillSolid:
+ fbSolid (dst + y * dstStride,
+ dstStride,
+ x * dstBpp,
+ dstBpp,
+ width * dstBpp, height,
+ pPriv->and, pPriv->xor);
+ break;
+ case FillStippled:
+ case FillOpaqueStippled: {
+ PixmapPtr pStip = pGC->stipple;
+ int stipWidth = pStip->drawable.width;
+ int stipHeight = pStip->drawable.height;
+
+ if (dstBpp == 1)
+ {
+ int alu;
+ FbBits *stip;
+ FbStride stipStride;
+ int stipBpp;
+
+ if (pGC->fillStyle == FillStippled)
+ alu = FbStipple1Rop(pGC->alu,pGC->fgPixel);
+ else
+ alu = FbOpaqueStipple1Rop(pGC->alu,pGC->fgPixel,pGC->bgPixel);
+ fbGetDrawable (&pStip->drawable, stip, stipStride, stipBpp);
+ fbTile (dst + y * dstStride,
+ dstStride,
+ x,
+ width, height,
+ stip,
+ stipStride,
+ stipWidth,
+ stipHeight,
+ alu,
+ pPriv->pm,
+ dstBpp,
+
+ (pGC->patOrg.x + pDrawable->x),
+ pGC->patOrg.y + pDrawable->y - y);
+ }
+ else
+ {
+ FbStip *stip;
+ FbStride stipStride;
+ int stipBpp;
+ FbBits fgand, fgxor, bgand, bgxor;
+
+ fgand = pPriv->and;
+ fgxor = pPriv->xor;
+ if (pGC->fillStyle == FillStippled)
+ {
+ bgand = fbAnd(GXnoop,(FbBits) 0,FB_ALLONES);
+ bgxor = fbXor(GXnoop,(FbBits) 0,FB_ALLONES);
+ }
+ else
+ {
+ bgand = pPriv->bgand;
+ bgxor = pPriv->bgxor;
+ }
+
+ fbGetStipDrawable (&pStip->drawable, stip, stipStride, stipBpp);
+ fbStipple (dst + y * dstStride,
+ dstStride,
+ x * dstBpp,
+ dstBpp,
+ width * dstBpp, height,
+ stip,
+ stipStride,
+ stipWidth,
+ stipHeight,
+ fgand, fgxor,
+ bgand, bgxor,
+ pGC->patOrg.x + pDrawable->x,
+ pGC->patOrg.y + pDrawable->y - y);
+ }
+ break;
+ }
+ case FillTiled: {
+ PixmapPtr pTile = pGC->tile.pixmap;
+ FbBits *tile;
+ FbStride tileStride;
+ int tileBpp;
+ int tileWidth;
+ int tileHeight;
+
+ fbGetDrawable (&pTile->drawable, tile, tileStride, tileBpp);
+ tileWidth = pTile->drawable.width;
+ tileHeight = pTile->drawable.height;
+ fbTile (dst + y * dstStride,
+ dstStride,
+ x * dstBpp,
+ width * dstBpp, height,
+ tile,
+ tileStride,
+ tileWidth * tileBpp,
+ tileHeight,
+ pGC->alu,
+ pPriv->pm,
+ dstBpp,
+ (pGC->patOrg.x + pDrawable->x) * dstBpp,
+ pGC->patOrg.y + pDrawable->y - y);
+ break;
+ }
+ }
+ fbValidateDrawable (pDrawable);
+}
+
+void
+fbSolidBoxClipped (DrawablePtr pDrawable,
+ RegionPtr pClip,
+ int x1,
+ int y1,
+ int x2,
+ int y2,
+ FbBits and,
+ FbBits xor)
+{
+ FbBits *dst;
+ FbStride dstStride;
+ int dstBpp;
+ BoxPtr pbox;
+ int nbox;
+ int partX1, partX2, partY1, partY2;
+
+ fbGetDrawable (pDrawable, dst, dstStride, dstBpp);
+
+ 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;
+
+ fbSolid (dst + partY1 * dstStride,
+ dstStride,
+ partX1 * dstBpp,
+ dstBpp,
+
+ (partX2 - partX1) * dstBpp,
+ (partY2 - partY1),
+ and, xor);
+ }
+}
diff --git a/xc/programs/Xserver/fb/fbfillrect.c b/xc/programs/Xserver/fb/fbfillrect.c
new file mode 100644
index 000000000..32a2cb82b
--- /dev/null
+++ b/xc/programs/Xserver/fb/fbfillrect.c
@@ -0,0 +1,111 @@
+/*
+ * $Id: fbfillrect.c,v 1.1 2000/01/06 12:56:53 faith Exp $
+ *
+ * Copyright © 1998 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/fb/fbfillrect.c,v 1.1 1999/11/19 13:53:43 hohndel Exp $ */
+
+#include "fb.h"
+
+void
+fbPolyFillRect(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nrect,
+ xRectangle *prect)
+{
+ RegionPtr pClip = fbGetCompositeClip(pGC);
+ register BoxPtr pbox;
+ BoxPtr pextent;
+ int extentX1, extentX2, extentY1, extentY2;
+ int fullX1, fullX2, fullY1, fullY2;
+ int partX1, partX2, partY1, partY2;
+ int xorg, yorg;
+ int n;
+
+ xorg = pDrawable->x;
+ yorg = pDrawable->y;
+
+ pextent = REGION_EXTENTS(pGC->pScreen, pClip);
+ extentX1 = pextent->x1;
+ extentY1 = pextent->y1;
+ extentX2 = pextent->x2;
+ extentY2 = pextent->y2;
+ while (nrect--)
+ {
+ fullX1 = prect->x + xorg;
+ fullY1 = prect->y + yorg;
+ fullX2 = fullX1 + (int) prect->width;
+ fullY2 = fullY1 + (int) prect->height;
+ prect++;
+
+ if (fullX1 < extentX1)
+ fullX1 = extentX1;
+
+ if (fullY1 < extentY1)
+ fullY1 = extentY1;
+
+ if (fullX2 > extentX2)
+ fullX2 = extentX2;
+
+ if (fullY2 > extentY2)
+ fullY2 = extentY2;
+
+ if ((fullX1 >= fullX2) || (fullY1 >= fullY2))
+ continue;
+ n = REGION_NUM_RECTS (pClip);
+ if (n == 1)
+ {
+ fbFill (pDrawable,
+ pGC,
+ fullX1, fullY1, fullX2-fullX1, fullY2-fullY1);
+ }
+ else
+ {
+ pbox = REGION_RECTS(pClip);
+ /*
+ * clip the rectangle to each box in the clip region
+ * this is logically equivalent to calling Intersect()
+ */
+ while(n--)
+ {
+ partX1 = pbox->x1;
+ if (partX1 < fullX1)
+ partX1 = fullX1;
+ partY1 = pbox->y1;
+ if (partY1 < fullY1)
+ partY1 = fullY1;
+ partX2 = pbox->x2;
+ if (partX2 > fullX2)
+ partX2 = fullX2;
+ partY2 = pbox->y2;
+ if (partY2 > fullY2)
+ partY2 = fullY2;
+
+ pbox++;
+
+ if (partX1 < partX2 && partY1 < partY2)
+ fbFill (pDrawable, pGC,
+ partX1, partY1,
+ partX2 - partX1, partY2 - partY1);
+ }
+ }
+ }
+}
diff --git a/xc/programs/Xserver/fb/fbfillsp.c b/xc/programs/Xserver/fb/fbfillsp.c
new file mode 100644
index 000000000..1067a42d9
--- /dev/null
+++ b/xc/programs/Xserver/fb/fbfillsp.c
@@ -0,0 +1,99 @@
+/*
+ * $Id: fbfillsp.c,v 1.1 2000/01/06 12:56:53 faith Exp $
+ *
+ * Copyright © 1998 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/fb/fbfillsp.c,v 1.1 1999/11/19 13:53:43 hohndel Exp $ */
+
+#include "fb.h"
+
+void
+fbFillSpans (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int n,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int fSorted)
+{
+ RegionPtr pClip = fbGetCompositeClip(pGC);
+ BoxPtr pextent, pbox;
+ int nbox;
+ int extentX1, extentX2, extentY1, extentY2;
+ int fullX1, fullX2, fullY1;
+ int partX1, partX2;
+
+ pextent = REGION_EXTENTS(pGC->pScreen, pClip);
+ extentX1 = pextent->x1;
+ extentY1 = pextent->y1;
+ extentX2 = pextent->x2;
+ extentY2 = pextent->y2;
+ while (n--)
+ {
+ fullX1 = ppt->x;
+ fullY1 = ppt->y;
+ fullX2 = fullX1 + (int) *pwidth;
+ ppt++;
+ pwidth++;
+
+ if (fullY1 < extentY1 || extentY2 <= fullY1)
+ continue;
+
+ if (fullX1 < extentX1)
+ fullX1 = extentX1;
+
+ if (fullX2 > extentX2)
+ fullX2 = extentX2;
+
+ if (fullX1 >= fullX2)
+ continue;
+
+ nbox = REGION_NUM_RECTS (pClip);
+ if (nbox == 1)
+ {
+ fbFill (pDrawable,
+ pGC,
+ fullX1, fullY1, fullX2-fullX1, 1);
+ }
+ else
+ {
+ pbox = REGION_RECTS(pClip);
+ while(nbox--)
+ {
+ if (pbox->y1 <= fullY1 && fullY1 < pbox->y2)
+ {
+ partX1 = pbox->x1;
+ if (partX1 < fullX1)
+ partX1 = fullX1;
+ partX2 = pbox->x2;
+ if (partX2 > fullX2)
+ partX2 = fullX2;
+ if (partX2 > partX1)
+ {
+ fbFill (pDrawable, pGC,
+ partX1, fullY1,
+ partX2 - partX1, 1);
+ }
+ }
+ pbox++;
+ }
+ }
+ }
+}
diff --git a/xc/programs/Xserver/fb/fbgc.c b/xc/programs/Xserver/fb/fbgc.c
new file mode 100644
index 000000000..adb3c8d4f
--- /dev/null
+++ b/xc/programs/Xserver/fb/fbgc.c
@@ -0,0 +1,192 @@
+/*
+ * $Id: fbgc.c,v 1.1 2000/01/06 12:56:53 faith Exp $
+ *
+ * Copyright © 1998 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/fb/fbgc.c,v 1.2 1999/12/30 02:33:58 robin Exp $ */
+
+#include "fb.h"
+
+const GCFuncs fbGCFuncs = {
+ fbValidateGC,
+ miChangeGC,
+ miCopyGC,
+ miDestroyGC,
+ miChangeClip,
+ miDestroyClip,
+ miCopyClip,
+};
+
+const GCOps fbGCOps = {
+ fbFillSpans,
+ fbSetSpans,
+ fbPutImage,
+ fbCopyArea,
+ fbCopyPlane,
+ fbPolyPoint,
+ fbPolyLine,
+ miPolySegment,
+ miPolyRectangle,
+ fbPolyArc,
+ miFillPolygon,
+ fbPolyFillRect,
+ miPolyFillArc,
+ miPolyText8,
+ miPolyText16,
+ miImageText8,
+ miImageText16,
+ fbImageGlyphBlt,
+ fbPolyGlyphBlt,
+ fbPushPixels
+#ifdef NEED_LINEHELPER
+ ,NULL
+#endif
+};
+
+Bool
+fbCreateGC(GCPtr pGC)
+{
+ FbGCPrivPtr pPriv;
+
+ pGC->clientClip = NULL;
+ pGC->clientClipType = CT_NONE;
+
+ pGC->ops = (GCOps *) &fbGCOps;
+ pGC->funcs = (GCFuncs *) &fbGCFuncs;
+
+ /* fb wants to translate before scan conversion */
+ pGC->miTranslate = 1;
+
+ fbGetRotatedPixmap(pGC) = 0;
+ fbGetExpose(pGC) = 1;
+ fbGetFreeCompClip(pGC) = 0;
+ fbGetCompositeClip(pGC) = 0;
+ return TRUE;
+}
+
+/*
+ * Pad pixmap to FB_UNIT bits wide
+ */
+void
+fbPadPixmap (PixmapPtr pPixmap)
+{
+ int width;
+ FbBits *bits;
+ FbBits b;
+ FbBits mask;
+ int height;
+ int w;
+
+ width = pPixmap->drawable.width * pPixmap->drawable.bitsPerPixel;
+ bits = pPixmap->devPrivate.ptr;
+ height = pPixmap->drawable.height;
+ mask = FbBitsMask (0, width);
+ while (height--)
+ {
+ b = *bits & mask;
+ w = width;
+ while (w < FB_UNIT)
+ {
+ b = b | FbScrRight(b, w);
+ w <<= 1;
+ }
+ *bits++ = b;
+ }
+}
+
+void
+fbValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable)
+{
+ FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
+ FbBits mask;
+
+ pGC->lastWinOrg.x = pDrawable->x;
+ pGC->lastWinOrg.y = pDrawable->y;
+
+ /*
+ * if the client clip is different or moved OR the subwindowMode has
+ * changed OR the window's clip has changed since the last validation
+ * we need to recompute the composite clip
+ */
+
+ if ((changes & (GCClipXOrigin|GCClipYOrigin|GCClipMask|GCSubwindowMode)) ||
+ (pDrawable->serialNumber != (pGC->serialNumber & DRAWABLE_SERIAL_BITS))
+ )
+ {
+ miComputeCompositeClip (pGC, pDrawable);
+ pPriv->oneRect = REGION_NUM_RECTS(fbGetCompositeClip(pGC)) == 1;
+ }
+
+ if (changes & GCTile)
+ {
+ if (!pGC->tileIsPixel &&
+ FbEvenTile (pGC->tile.pixmap->drawable.width *
+ pDrawable->bitsPerPixel))
+ fbPadPixmap (pGC->tile.pixmap);
+ }
+ if (changes & GCStipple)
+ {
+ if (pGC->stipple &&
+ FbEvenStip (pGC->stipple->drawable.width,
+ pDrawable->bitsPerPixel))
+ fbPadPixmap (pGC->stipple);
+ }
+ /*
+ * Recompute reduced rop values
+ */
+ if (changes & (GCForeground|GCBackground|GCPlaneMask|GCFunction))
+ {
+ int n;
+ int s;
+ FbBits depthMask;
+
+ mask = FbFullMask(pDrawable->bitsPerPixel);
+ depthMask = FbFullMask(pDrawable->depth);
+ if ((pGC->planemask & depthMask) == depthMask)
+ pGC->planemask = mask;
+ pPriv->fg = pGC->fgPixel & mask;
+ pPriv->bg = pGC->bgPixel & mask;
+ pPriv->pm = pGC->planemask & mask;
+
+ s = pDrawable->bitsPerPixel;
+ while (s < FB_UNIT)
+ {
+ pPriv->fg |= pPriv->fg << s;
+ pPriv->bg |= pPriv->bg << s;
+ pPriv->pm |= pPriv->pm << s;
+ s <<= 1;
+ }
+ pPriv->and = fbAnd(pGC->alu, pPriv->fg, pPriv->pm);
+ pPriv->xor = fbXor(pGC->alu, pPriv->fg, pPriv->pm);
+ pPriv->bgand = fbAnd(pGC->alu, pPriv->bg, pPriv->pm);
+ pPriv->bgxor = fbXor(pGC->alu, pPriv->bg, pPriv->pm);
+ }
+ if (changes & GCDashList)
+ {
+ unsigned short n = pGC->numInDashList;
+ unsigned char *dash = pGC->dash;
+ unsigned int dashLength = 0;
+
+ while (n--)
+ dashLength += (unsigned int ) *dash++;
+ pPriv->dashLength = dashLength;
+ }
+}
diff --git a/xc/programs/Xserver/fb/fbgetsp.c b/xc/programs/Xserver/fb/fbgetsp.c
new file mode 100644
index 000000000..6e4e318e4
--- /dev/null
+++ b/xc/programs/Xserver/fb/fbgetsp.c
@@ -0,0 +1,67 @@
+/*
+ * $Id: fbgetsp.c,v 1.1 2000/01/06 12:56:53 faith Exp $
+ *
+ * Copyright © 1998 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/fb/fbgetsp.c,v 1.1 1999/11/19 13:53:43 hohndel Exp $ */
+
+#include "fb.h"
+
+void
+fbGetSpans(DrawablePtr pDrawable,
+ int wMax,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int nspans,
+ char *pchardstStart)
+{
+ FbBits *src, *dst;
+ FbStride srcStride;
+ int srcBpp;
+ int xoff;
+
+ fbGetDrawable (pDrawable, src, srcStride, srcBpp);
+ while (nspans--)
+ {
+ xoff = (((int) pchardstStart) & (FB_MASK >> 3));
+ dst = (FbBits *) (pchardstStart - xoff);
+ xoff <<= 3;
+ fbBlt (src + ppt->y * srcStride, srcStride,
+ ppt->x * srcBpp,
+
+ dst,
+ 1,
+ xoff,
+
+ *pwidth * srcBpp,
+ 1,
+
+ GXcopy,
+ FB_ALLONES,
+ srcBpp,
+
+ FALSE,
+ FALSE);
+ pchardstStart += PixmapBytePad(*pwidth, pDrawable->depth);
+ ppt++;
+ pwidth++;
+ }
+}
diff --git a/xc/programs/Xserver/fb/fbglyph.c b/xc/programs/Xserver/fb/fbglyph.c
new file mode 100644
index 000000000..18821448c
--- /dev/null
+++ b/xc/programs/Xserver/fb/fbglyph.c
@@ -0,0 +1,404 @@
+/*
+ * $Id: fbglyph.c,v 1.1 2000/01/06 12:56:53 faith Exp $
+ *
+ * Copyright © 1998 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/fb/fbglyph.c,v 1.2 1999/12/30 02:33:59 robin Exp $ */
+
+#include "fb.h"
+#include "fontstruct.h"
+#include "dixfontstr.h"
+
+Bool
+fbGlyphIn (RegionPtr pRegion,
+ int x,
+ int y,
+ int width,
+ int height)
+{
+ BoxRec box;
+
+ if (x + width < 0) return FALSE;
+ if (y + height < 0) return FALSE;
+ box.x1 = x;
+ box.x2 = x + width;
+ box.y1 = y;
+ box.y2 = y + height;
+ return RECT_IN_REGION (0, pRegion, &box) == rgnIN;
+}
+
+#define WRITE1(d,n,fg) ((d)[n] = (CARD8) fg)
+#define WRITE2(d,n,fg) (*(CARD16 *) &(d[n]) = (CARD16) fg)
+#define WRITE4(d,n,fg) (*(CARD32 *) &(d[n]) = (CARD32) fg)
+#if FB_UNIT == 6
+#define WRITE8(d) (*(FbBits *) &(d[0]) = fg)
+#else
+#define WRITE8(d) WRITE4(d,0,f0), WRITE4(d,4,f1)
+#endif
+
+/*
+ * This is a bit tricky, but it's brief. Write 12 bytes worth
+ * of dest, which is four pixels, at a time. This gives constant
+ * code for each pattern as they're always aligned the same
+ *
+ * a b c d a b c d a b c d bytes
+ * A B C A B C A B C A B C pixels
+ * f0 f1 f2
+ */
+
+void
+fbGlyph24 (FbBits *dstBits,
+ FbStride dstStride,
+ int dstBpp,
+ FbStip *stipple,
+ FbBits fg,
+ int x,
+ int height)
+{
+ int lshift;
+ FbStip bits;
+ CARD8 *dstLine;
+ CARD8 *dst;
+ FbStip f0, f1, f2;
+ int n;
+ int shift;
+
+ f0 = fg;
+ f1 = FbRot24(f0,16);
+ f2 = FbRot24(f0,8);
+
+ dstLine = (CARD8 *) dstBits;
+ dstLine += (x & ~3) * 3;
+ dstStride *= (sizeof (FbBits) / sizeof (CARD8));
+ shift = x & 3;
+ lshift = 4 - shift;
+ while (height--)
+ {
+ bits = *stipple++;
+ n = lshift;
+ dst = dstLine;
+ while (bits)
+ {
+ switch (FbStipMoveLsb (FbLeftStipBits (bits, n), 4, n)) {
+ case 0:
+ break;
+ case 1:
+ WRITE2(dst,0,f0);
+ WRITE1(dst,2,f2);
+ break;
+ case 2:
+ WRITE1(dst,3,f0);
+ WRITE2(dst,4,f1);
+ break;
+ case 3:
+ WRITE4(dst,0,f0);
+ WRITE2(dst,4,f1);
+ break;
+ case 4:
+ WRITE2(dst,6,f0);
+ WRITE1(dst,8,f2);
+ break;
+ case 5:
+ WRITE2(dst,0,f0);
+ WRITE1(dst,2,f2);
+
+ WRITE2(dst,6,f0);
+ WRITE1(dst,8,f2);
+ break;
+ case 6:
+ WRITE1(dst,3,f0);
+ WRITE4(dst,4,f1);
+ WRITE1(dst,8,f2);
+ break;
+ case 7:
+ WRITE8(dst);
+ WRITE1(dst,8,f2);
+ break;
+ case 8:
+ WRITE1(dst,9,f0);
+ WRITE2(dst,10,f1);
+ break;
+ case 9:
+ WRITE2(dst,0,f0);
+ WRITE1(dst,2,f2);
+
+ WRITE1(dst,9,f0);
+ WRITE2(dst,10,f1);
+ break;
+ case 10:
+ WRITE1(dst,3,f0);
+ WRITE2(dst,4,f1);
+
+ WRITE1(dst,9,f0);
+ WRITE2(dst,10,f1);
+ break;
+ case 11:
+ WRITE4(dst,0,f0);
+ WRITE2(dst,4,f1);
+
+ WRITE1(dst,9,f0);
+ WRITE2(dst,10,f1);
+ break;
+ case 12:
+ WRITE2(dst,6,f0);
+ WRITE4(dst,8,f2);
+ break;
+ case 13:
+ WRITE2(dst,0,f0);
+ WRITE1(dst,2,f2);
+
+ WRITE2(dst,6,f0);
+ WRITE4(dst,8,f2);
+ break;
+ case 14:
+ WRITE1(dst,3,f0);
+ WRITE4(dst,4,f1);
+ WRITE4(dst,8,f2);
+ break;
+ case 15:
+ WRITE8(dst);
+ WRITE4(dst,8,f2);
+ break;
+ }
+ bits = FbStipLeft (bits, n);
+ n = 4;
+ dst += 12;
+ }
+ dstLine += dstStride;
+ }
+}
+
+void
+fbPolyGlyphBlt (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase)
+{
+ FbGCPrivPtr pPriv = fbGetGCPrivate (pGC);
+ CharInfoPtr pci;
+ unsigned char *pglyph; /* pointer bits in glyph */
+ int gx, gy;
+ int gWidth, gHeight; /* width and height of glyph */
+ FbStride gStride; /* stride of glyph */
+#ifndef FBNOPIXADDR
+ void (*glyph) (FbBits *,
+ FbStride,
+ int,
+ FbStip *,
+ FbBits,
+ int,
+ int);
+ FbBits *dst;
+ FbStride dstStride;
+ int dstBpp;
+
+ glyph = 0;
+ if (pGC->fillStyle == FillSolid && pPriv->and == 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;
+ }
+ }
+#endif
+ x += pDrawable->x;
+ y += pDrawable->y;
+
+ 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;
+#ifndef FBNOPIXADDR
+ if (glyph && gWidth <= sizeof (FbStip) * 8 &&
+ fbGlyphIn (fbGetCompositeClip(pGC), gx, gy, gWidth, gHeight))
+ {
+ (*glyph) (dst + gy * dstStride,
+ dstStride,
+ dstBpp,
+ (FbStip *) pglyph,
+ pPriv->xor,
+ gx,
+ gHeight);
+ }
+ else
+#endif
+ {
+ gStride = GLYPHWIDTHBYTESPADDED(pci) / sizeof (FbStip);
+ fbPushImage (pDrawable,
+ pGC,
+
+ (FbStip *) pglyph,
+ gStride,
+ 0,
+
+ gx,
+ gy,
+ gWidth, gHeight);
+ }
+ }
+ x += pci->metrics.characterWidth;
+ }
+}
+
+
+void
+fbImageGlyphBlt (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;
+#ifndef FBNOPIXADDR
+ void (*glyph) (FbBits *,
+ FbStride,
+ int,
+ FbStip *,
+ FbBits,
+ int,
+ int);
+ FbBits *dst;
+ FbStride dstStride;
+ int dstBpp;
+
+ glyph = 0;
+ if (pPriv->and == 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;
+ }
+ }
+#endif
+
+ x += pDrawable->x;
+ y += pDrawable->y;
+
+ if (TERMINALFONT (pGC->font)
+#ifndef FBNOPIXADDR
+ && !glyph
+#endif
+ )
+ {
+ 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);
+ fbSolidBoxClipped (pDrawable,
+ fbGetCompositeClip(pGC),
+ xBack,
+ yBack,
+ xBack + widthBack,
+ yBack + heightBack,
+ fbAnd(GXcopy,pPriv->bg,pPriv->pm),
+ fbXor(GXcopy,pPriv->bg,pPriv->pm));
+ 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;
+#ifndef FBNOPIXADDR
+ 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
+#endif
+ {
+ 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;
+ }
+}
diff --git a/xc/programs/Xserver/fb/fbimage.c b/xc/programs/Xserver/fb/fbimage.c
new file mode 100644
index 000000000..7219c20fb
--- /dev/null
+++ b/xc/programs/Xserver/fb/fbimage.c
@@ -0,0 +1,328 @@
+/*
+ * $Id: fbimage.c,v 1.1 2000/01/06 12:56:53 faith Exp $
+ *
+ * Copyright © 1998 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/fb/fbimage.c,v 1.1 1999/11/19 13:53:44 hohndel Exp $ */
+
+#include "fb.h"
+
+
+void
+fbPutImage (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int depth,
+ int x,
+ int y,
+ int w,
+ int h,
+ int leftPad,
+ int format,
+ char *pImage)
+{
+ FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
+ unsigned long i;
+ FbStride srcStride;
+ FbStip *src = (FbStip *) pImage;
+
+ x += pDrawable->x;
+ y += pDrawable->y;
+
+ switch (format)
+ {
+ case XYBitmap:
+ srcStride = BitmapBytePad(w + leftPad) / sizeof (FbStip);
+ fbPutXYImage (pDrawable,
+ fbGetCompositeClip(pGC),
+ pPriv->fg,
+ pPriv->bg,
+ pPriv->pm,
+ pGC->alu,
+ TRUE,
+ x, y, w, h,
+ src,
+ srcStride,
+ leftPad);
+ break;
+ case XYPixmap:
+ srcStride = BitmapBytePad(w + leftPad) / sizeof (FbStip);
+ for (i = 1 << (pDrawable->depth - 1); i; i >>= 1)
+ {
+ if (i & pGC->planemask)
+ {
+ fbPutXYImage (pDrawable,
+ fbGetCompositeClip(pGC),
+ FB_ALLONES,
+ 0,
+ fbReplicatePixel (i, pDrawable->bitsPerPixel),
+ pGC->alu,
+ TRUE,
+ x, y, w, h,
+ src,
+ srcStride,
+ leftPad);
+ src += srcStride * h;
+ }
+ }
+ break;
+ case ZPixmap:
+ srcStride = PixmapBytePad(w, pDrawable->depth) / sizeof (FbStip);
+ fbPutZImage (pDrawable,
+ fbGetCompositeClip(pGC),
+ pGC->alu,
+ pPriv->pm,
+ x, y, w, h,
+ src, srcStride);
+ }
+}
+
+void
+fbPutZImage (DrawablePtr pDrawable,
+ RegionPtr pClip,
+ int alu,
+ FbBits pm,
+ int x,
+ int y,
+ int width,
+ int height,
+ FbStip *src,
+ FbStride srcStride)
+{
+ FbStip *dst;
+ FbStride dstStride;
+ int dstBpp;
+ int nbox;
+ BoxPtr pbox;
+ int x1, y1, x2, y2;
+ FbBits fgand, fgxor, bgand, bgxor;
+ FbStip *d;
+ FbStride ds;
+
+ fbGetStipDrawable (pDrawable, dst, dstStride, dstBpp);
+
+ for (nbox = REGION_NUM_RECTS (pClip),
+ pbox = REGION_RECTS(pClip);
+ nbox--;
+ pbox++)
+ {
+ x1 = x;
+ y1 = y;
+ x2 = x + width;
+ y2 = y + height;
+ if (x1 < pbox->x1)
+ x1 = pbox->x1;
+ if (y1 < pbox->y1)
+ y1 = pbox->y1;
+ if (x2 > pbox->x2)
+ x2 = pbox->x2;
+ if (y2 > pbox->y2)
+ y2 = pbox->y2;
+ if (x1 >= x2 || y1 >= y2)
+ continue;
+ fbBltStip (src + (y1 - y) * srcStride,
+ srcStride,
+ (x1 - x) * dstBpp,
+
+ dst + y1 * dstStride,
+ dstStride,
+ x1 * dstBpp,
+
+ (x2 - x1) * dstBpp,
+ (y2 - y1),
+
+ alu,
+ pm,
+ dstBpp);
+ }
+}
+
+void
+fbPutXYImage (DrawablePtr pDrawable,
+ RegionPtr pClip,
+ FbBits fg,
+ FbBits bg,
+ FbBits pm,
+ int alu,
+ Bool opaque,
+
+ int x,
+ int y,
+ int width,
+ int height,
+
+ FbStip *src,
+ FbStride srcStride,
+ int srcX)
+{
+ FbBits *dst;
+ FbStride dstStride;
+ int dstBpp;
+ int nbox;
+ BoxPtr pbox;
+ int x1, y1, x2, y2;
+ FbBits fgand, fgxor, bgand, bgxor;
+
+ fbGetDrawable (pDrawable, dst, dstStride, dstBpp);
+
+ if (dstBpp == 1)
+ {
+ if (opaque)
+ alu = FbOpaqueStipple1Rop(alu,fg,bg);
+ else
+ alu = FbStipple1Rop(alu,fg);
+ }
+ else
+ {
+ fgand = fbAnd(alu,fg,pm);
+ fgxor = fbXor(alu,fg,pm);
+ if (opaque)
+ {
+ bgand = fbAnd(alu,bg,pm);
+ bgxor = fbXor(alu,bg,pm);
+ }
+ else
+ {
+ bgand = fbAnd(GXnoop,(FbBits)0,FB_ALLONES);
+ bgxor = fbXor(GXnoop,(FbBits)0,FB_ALLONES);
+ }
+ }
+
+ for (nbox = REGION_NUM_RECTS (pClip),
+ pbox = REGION_RECTS(pClip);
+ nbox--;
+ pbox++)
+ {
+ x1 = x;
+ y1 = y;
+ x2 = x + width;
+ y2 = y + height;
+ if (x1 < pbox->x1)
+ x1 = pbox->x1;
+ if (y1 < pbox->y1)
+ y1 = pbox->y1;
+ if (x2 > pbox->x2)
+ x2 = pbox->x2;
+ if (y2 > pbox->y2)
+ y2 = pbox->y2;
+ if (x1 >= x2 || y1 >= y2)
+ continue;
+ if (dstBpp == 1)
+ {
+ fbBltStip (src + (y1 - y) * srcStride,
+ srcStride,
+ (x1 - x) + srcX,
+
+ (FbStip *) (dst + y1 * dstStride),
+ FbBitsStrideToStipStride(dstStride),
+ x1 * dstBpp,
+
+ (x2 - x1) * dstBpp,
+ (y2 - y1),
+
+ alu,
+ pm,
+ dstBpp);
+ }
+ else
+ {
+ fbBltOne (src + (y1 - y) * srcStride,
+ srcStride,
+ (x1 - x) + srcX,
+
+ dst + y1 * dstStride,
+ dstStride,
+ x1 * dstBpp,
+ dstBpp,
+
+ (x2 - x1) * dstBpp,
+ (y2 - y1),
+
+ fgand, fgxor, bgand, bgxor);
+ }
+ }
+}
+
+void
+fbGetImage (DrawablePtr pDrawable,
+ int x,
+ int y,
+ int w,
+ int h,
+ unsigned int format,
+ unsigned long planeMask,
+ char *d)
+{
+ FbBits *src;
+ FbStride srcStride;
+ int srcBpp;
+ FbStip *dst;
+ FbStride dstStride;
+
+ fbGetDrawable (pDrawable, src, srcStride, srcBpp);
+
+ x += pDrawable->x;
+ y += pDrawable->y;
+
+ dst = (FbStip *) d;
+ if (format == ZPixmap || srcBpp == 1)
+ {
+ FbBits pm;
+
+ pm = fbReplicatePixel (planeMask, srcBpp);
+ dstStride = PixmapBytePad(w, pDrawable->depth);
+ if (pm != FB_ALLONES)
+ memset (d, 0, dstStride * h);
+ dstStride /= sizeof (FbStip);
+ fbBltStip ((FbStip *) (src + y * srcStride),
+ FbBitsStrideToStipStride(srcStride),
+ x * srcBpp,
+
+ dst,
+ dstStride,
+ 0,
+
+ w * srcBpp, h,
+
+ GXcopy,
+ pm,
+ srcBpp);
+ }
+ else
+ {
+ dstStride = BitmapBytePad(w) / sizeof (FbStip);
+ fbBltPlane (src + y * srcStride,
+ srcStride,
+ x * srcBpp,
+ srcBpp,
+
+ dst,
+ dstStride,
+ 0,
+
+ w * srcBpp, h,
+
+ fbAndStip(GXcopy,FB_STIP_ALLONES,FB_STIP_ALLONES),
+ fbXorStip(GXcopy,FB_STIP_ALLONES,FB_STIP_ALLONES),
+ fbAndStip(GXcopy,0,FB_STIP_ALLONES),
+ fbXorStip(GXcopy,0,FB_STIP_ALLONES),
+ planeMask);
+ }
+}
diff --git a/xc/programs/Xserver/fb/fbline.c b/xc/programs/Xserver/fb/fbline.c
new file mode 100644
index 000000000..1c632516e
--- /dev/null
+++ b/xc/programs/Xserver/fb/fbline.c
@@ -0,0 +1,90 @@
+/*
+ * $Id: fbline.c,v 1.1 2000/01/06 12:56:53 faith Exp $
+ *
+ * Copyright © 1998 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/fb/fbline.c,v 1.1 1999/11/19 13:53:44 hohndel Exp $ */
+
+#include "fb.h"
+
+void
+fbZeroLine (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ DDXPointPtr ppt)
+{
+ FbGCPrivPtr pPriv = fbGetGCPrivate (pGC);
+ int x1, y1, x2, y2;
+ int x, y;
+ int dashOffset;
+ int totalDash;
+ int n;
+ unsigned char *dash;
+
+ x = pDrawable->x;
+ y = pDrawable->y;
+ x1 = ppt->x;
+ y1 = ppt->y;
+ dashOffset = 0;
+ totalDash = 0;
+ if (pGC->lineStyle != LineSolid)
+ totalDash = pPriv->dashLength;
+ while (--npt)
+ {
+ ++ppt;
+ x2 = ppt->x;
+ y2 = ppt->y;
+ if (mode == CoordModePrevious)
+ {
+ x2 += x1;
+ y2 += y1;
+ }
+ fbSegment (pDrawable, pGC, x1 + x, y1 + y,
+ x2 + x, y2 + y,
+ npt == 1 && pGC->capStyle != CapNotLast,
+ &dashOffset);
+ if (totalDash)
+ dashOffset = dashOffset % totalDash;
+ x1 = x2;
+ y1 = y2;
+ }
+}
+
+void
+fbPolyLine (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ DDXPointPtr ppt)
+{
+ if (pGC->lineWidth == 0)
+ {
+ fbZeroLine (pDrawable, pGC, mode, npt, ppt);
+ }
+ else
+ {
+ if (pGC->lineStyle != LineSolid)
+ miWideDash (pDrawable, pGC, mode, npt, ppt);
+ else
+ miWideLine (pDrawable, pGC, mode, npt, ppt);
+ }
+}
diff --git a/xc/programs/Xserver/fb/fbpixmap.c b/xc/programs/Xserver/fb/fbpixmap.c
new file mode 100644
index 000000000..015a9361a
--- /dev/null
+++ b/xc/programs/Xserver/fb/fbpixmap.c
@@ -0,0 +1,362 @@
+/*
+ * $Id: fbpixmap.c,v 1.1 2000/01/06 12:56:53 faith Exp $
+ *
+ * Copyright © 1998 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/fb/fbpixmap.c,v 1.2 1999/12/27 01:26:21 robin Exp $ */
+
+#include "fb.h"
+
+PixmapPtr
+fbCreatePixmap (ScreenPtr pScreen, int width, int height, int depth)
+{
+ PixmapPtr pPixmap;
+ int datasize;
+ int paddedWidth;
+ int bpp;
+ int adjust;
+ int base;
+
+ bpp = BitsPerPixel(depth);
+ paddedWidth = ((width * bpp + FB_MASK) >> FB_SHIFT) * sizeof (FbBits);
+ datasize = height * paddedWidth;
+#ifdef PIXPRIV
+ base = pScreen->totalPixmapSize;
+#else
+ base = sizeof (PixmapRec);
+#endif
+ adjust = 0;
+ if (base & 7)
+ adjust = 8 - (base & 7);
+ datasize += adjust;
+#ifdef FB_DEBUG
+ datasize += 2 * paddedWidth;
+#endif
+ pPixmap = AllocatePixmap(pScreen, datasize);
+ if (!pPixmap)
+ return NullPixmap;
+ pPixmap->drawable.type = DRAWABLE_PIXMAP;
+ pPixmap->drawable.class = 0;
+ pPixmap->drawable.pScreen = pScreen;
+ pPixmap->drawable.depth = depth;
+ pPixmap->drawable.bitsPerPixel = bpp;
+ pPixmap->drawable.id = 0;
+ pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ pPixmap->drawable.x = 0;
+ pPixmap->drawable.y = 0;
+ pPixmap->drawable.width = width;
+ pPixmap->drawable.height = height;
+ pPixmap->devKind = paddedWidth;
+ pPixmap->refcnt = 1;
+ pPixmap->devPrivate.ptr = (pointer) ((char *)pPixmap + base + adjust);
+#ifdef FB_DEBUG
+ pPixmap->devPrivate.ptr = (void *) ((char *) pPixmap->devPrivate.ptr + paddedWidth);
+ fbInitializeDrawable (&pPixmap->drawable);
+#endif
+ return pPixmap;
+}
+
+Bool
+fbDestroyPixmap (PixmapPtr pPixmap)
+{
+ if(--pPixmap->refcnt)
+ return TRUE;
+ xfree(pPixmap);
+ return TRUE;
+}
+
+#define ADDRECT(reg,r,fr,rx1,ry1,rx2,ry2) \
+if (((rx1) < (rx2)) && ((ry1) < (ry2)) && \
+ (!((reg)->data->numRects && \
+ ((r-1)->y1 == (ry1)) && \
+ ((r-1)->y2 == (ry2)) && \
+ ((r-1)->x1 <= (rx1)) && \
+ ((r-1)->x2 >= (rx2))))) \
+{ \
+ if ((reg)->data->numRects == (reg)->data->size) \
+ { \
+ miRectAlloc(reg, 1); \
+ fr = REGION_BOXPTR(reg); \
+ r = fr + (reg)->data->numRects; \
+ } \
+ r->x1 = (rx1); \
+ r->y1 = (ry1); \
+ r->x2 = (rx2); \
+ r->y2 = (ry2); \
+ (reg)->data->numRects++; \
+ if(r->x1 < (reg)->extents.x1) \
+ (reg)->extents.x1 = r->x1; \
+ if(r->x2 > (reg)->extents.x2) \
+ (reg)->extents.x2 = r->x2; \
+ r++; \
+}
+
+/* Convert bitmap clip mask into clipping region.
+ * First, goes through each line and makes boxes by noting the transitions
+ * from 0 to 1 and 1 to 0.
+ * Then it coalesces the current line with the previous if they have boxes
+ * at the same X coordinates.
+ */
+RegionPtr
+fbPixmapToRegion(PixmapPtr pPix)
+{
+ register RegionPtr pReg;
+ FbBits *pw, w;
+ register int ib;
+ int width, h, base, rx1, crects;
+ FbBits *pwLineEnd;
+ int irectPrevStart, irectLineStart;
+ register BoxPtr prectO, prectN;
+ BoxPtr FirstRect, rects, prectLineStart;
+ Bool fInBox, fSame;
+ register FbBits mask0 = FB_ALLONES & ~FbScrRight(FB_ALLONES, 1);
+ FbBits *pwLine;
+ int nWidth;
+
+ pReg = REGION_CREATE(pPix->drawable.pScreen, NULL, 1);
+ if(!pReg)
+ return NullRegion;
+ FirstRect = REGION_BOXPTR(pReg);
+ rects = FirstRect;
+
+ pwLine = (FbBits *) pPix->devPrivate.ptr;
+ nWidth = pPix->devKind >> (FB_SHIFT-3);
+
+ width = pPix->drawable.width;
+ pReg->extents.x1 = width - 1;
+ pReg->extents.x2 = 0;
+ irectPrevStart = -1;
+ for(h = 0; h < pPix->drawable.height; h++)
+ {
+ pw = pwLine;
+ pwLine += nWidth;
+ irectLineStart = rects - FirstRect;
+ /* If the Screen left most bit of the word is set, we're starting in
+ * a box */
+ if(*pw & mask0)
+ {
+ fInBox = TRUE;
+ rx1 = 0;
+ }
+ else
+ fInBox = FALSE;
+ /* Process all words which are fully in the pixmap */
+ pwLineEnd = pw + (width >> FB_SHIFT);
+ for (base = 0; pw < pwLineEnd; base += FB_UNIT)
+ {
+ w = *pw++;
+ if (fInBox)
+ {
+ if (!~w)
+ continue;
+ }
+ else
+ {
+ if (!w)
+ continue;
+ }
+ for(ib = 0; ib < FB_UNIT; ib++)
+ {
+ /* If the Screen left most bit of the word is set, we're
+ * starting a box */
+ if(w & mask0)
+ {
+ if(!fInBox)
+ {
+ rx1 = base + ib;
+ /* start new box */
+ fInBox = TRUE;
+ }
+ }
+ else
+ {
+ if(fInBox)
+ {
+ /* end box */
+ ADDRECT(pReg, rects, FirstRect,
+ rx1, h, base + ib, h + 1);
+ fInBox = FALSE;
+ }
+ }
+ /* Shift the word VISUALLY left one. */
+ w = FbScrLeft(w, 1);
+ }
+ }
+ if(width & FB_MASK)
+ {
+ /* Process final partial word on line */
+ w = *pw++;
+ for(ib = 0; ib < (width & FB_MASK); ib++)
+ {
+ /* If the Screen left most bit of the word is set, we're
+ * starting a box */
+ if(w & mask0)
+ {
+ if(!fInBox)
+ {
+ rx1 = base + ib;
+ /* start new box */
+ fInBox = TRUE;
+ }
+ }
+ else
+ {
+ if(fInBox)
+ {
+ /* end box */
+ ADDRECT(pReg, rects, FirstRect,
+ rx1, h, base + ib, h + 1);
+ fInBox = FALSE;
+ }
+ }
+ /* Shift the word VISUALLY left one. */
+ w = FbScrLeft(w, 1);
+ }
+ }
+ /* If scanline ended with last bit set, end the box */
+ if(fInBox)
+ {
+ ADDRECT(pReg, rects, FirstRect,
+ rx1, h, base + (width & FB_MASK), h + 1);
+ }
+ /* if all rectangles on this line have the same x-coords as
+ * those on the previous line, then add 1 to all the previous y2s and
+ * throw away all the rectangles from this line
+ */
+ fSame = FALSE;
+ if(irectPrevStart != -1)
+ {
+ crects = irectLineStart - irectPrevStart;
+ if(crects == ((rects - FirstRect) - irectLineStart))
+ {
+ prectO = FirstRect + irectPrevStart;
+ prectN = prectLineStart = FirstRect + irectLineStart;
+ fSame = TRUE;
+ while(prectO < prectLineStart)
+ {
+ if((prectO->x1 != prectN->x1) || (prectO->x2 != prectN->x2))
+ {
+ fSame = FALSE;
+ break;
+ }
+ prectO++;
+ prectN++;
+ }
+ if (fSame)
+ {
+ prectO = FirstRect + irectPrevStart;
+ while(prectO < prectLineStart)
+ {
+ prectO->y2 += 1;
+ prectO++;
+ }
+ rects -= crects;
+ pReg->data->numRects -= crects;
+ }
+ }
+ }
+ if(!fSame)
+ irectPrevStart = irectLineStart;
+ }
+ if (!pReg->data->numRects)
+ pReg->extents.x1 = pReg->extents.x2 = 0;
+ else
+ {
+ pReg->extents.y1 = REGION_BOXPTR(pReg)->y1;
+ pReg->extents.y2 = REGION_END(pReg)->y2;
+ if (pReg->data->numRects == 1)
+ {
+ xfree(pReg->data);
+ pReg->data = (RegDataPtr)NULL;
+ }
+ }
+#ifdef DEBUG
+ if (!miValidRegion(pReg))
+ FatalError("Assertion failed file %s, line %d: expr\n", __FILE__, __LINE__);
+#endif
+ return(pReg);
+}
+
+#ifdef FB_DEBUG
+
+#ifndef WIN32
+#include <stdio.h>
+#else
+#include <dbg.h>
+#endif
+
+static Bool
+fbValidateBits (FbStip *bits, int stride, FbStip data)
+{
+ while (stride--)
+ {
+ if (*bits != data)
+ {
+#ifdef WIN32
+ NCD_DEBUG ((DEBUG_FAILURE, "fdValidateBits failed at 0x%x (is 0x%x want 0x%x)",
+ bits, *bits, data));
+#else
+ fprintf (stderr, "fbValidateBits failed\n");
+#endif
+ return FALSE;
+ }
+ bits++;
+ }
+}
+
+void
+fbValidateDrawable (DrawablePtr pDrawable)
+{
+ FbStip *bits, *first, *last;
+ int stride, bpp;
+ int height;
+ Bool failed;
+
+ if (pDrawable->type != DRAWABLE_PIXMAP)
+ pDrawable = (DrawablePtr) fbGetWindowPixmap(pDrawable);
+ fbGetStipDrawable(pDrawable, bits, stride, bpp);
+ first = bits - stride;
+ last = bits + stride * pDrawable->height;
+ if (!fbValidateBits (first, stride, FB_HEAD_BITS) ||
+ !fbValidateBits (last, stride, FB_TAIL_BITS))
+ fbInitializeDrawable(pDrawable);
+}
+
+void
+fbSetBits (FbStip *bits, int stride, FbStip data)
+{
+ while (stride--)
+ *bits++ = data;
+}
+
+void
+fbInitializeDrawable (DrawablePtr pDrawable)
+{
+ FbStip *bits, *first, *last;
+ int stride, bpp;
+
+ fbGetStipDrawable(pDrawable, bits, stride, bpp);
+ first = bits - stride;
+ last = bits + stride * pDrawable->height;
+ fbSetBits (first, stride, FB_HEAD_BITS);
+ fbSetBits (last, stride, FB_TAIL_BITS);
+}
+#endif /* FB_DEBUG */
diff --git a/xc/programs/Xserver/fb/fbpoint.c b/xc/programs/Xserver/fb/fbpoint.c
new file mode 100644
index 000000000..532508f7d
--- /dev/null
+++ b/xc/programs/Xserver/fb/fbpoint.c
@@ -0,0 +1,155 @@
+/*
+ * $Id: fbpoint.c,v 1.1 2000/01/06 12:56:53 faith Exp $
+ *
+ * Copyright © 1998 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/fb/fbpoint.c,v 1.2 1999/12/30 02:33:59 robin Exp $ */
+
+#include "fb.h"
+
+typedef void (*FbDots) (FbBits *dst,
+ FbStride dstStride,
+ int dstBpp,
+ BoxPtr pBox,
+ xPoint *pts,
+ int npt,
+ FbBits and,
+ FbBits xor);
+
+void
+fbDots (FbBits *dst,
+ FbStride dstStride,
+ int dstBpp,
+ BoxPtr pBox,
+ xPoint *pts,
+ int npt,
+ FbBits and,
+ FbBits xor)
+{
+ int x1, y1, x2, y2;
+ int x, y;
+ FbBits *d;
+
+ x1 = pBox->x1;
+ y1 = pBox->y1;
+ x2 = pBox->x2;
+ y2 = pBox->y2;
+ while (npt--)
+ {
+ x = pts->x;
+ y = pts->y;
+ pts++;
+ if (x1 <= x && x < x2 && y1 <= y && y < y2)
+ {
+ x *= dstBpp;
+ d = dst + (y * dstStride) + (x >> FB_SHIFT);
+ x &= FB_MASK;
+ if (dstBpp == 24)
+ {
+ FbBits leftMask, rightMask;
+ int n, rot;
+ FbBits andT, xorT;
+
+ rot = x % 24;
+ andT = FbRot24(and,rot);
+ xorT = FbRot24(xor,rot);
+ FbMaskBits (x, 24, leftMask, n, rightMask);
+ if (leftMask)
+ {
+ *d = FbDoMaskRRop (*d, andT, xorT, leftMask);
+ andT = FbNext24Pix(andT);
+ xorT = FbNext24Pix(xorT);
+ d++;
+ }
+ if (rightMask)
+ *d = FbDoMaskRRop(*d, andT, xorT, rightMask);
+ }
+ else
+ {
+ FbBits mask;
+ mask = FbBitsMask(x, dstBpp);
+ *d = FbDoMaskRRop (*d, and, xor, mask);
+ }
+ }
+ }
+}
+
+void
+fbPolyPoint (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int mode,
+ int nptInit,
+ xPoint *pptInit)
+{
+ FbGCPrivPtr pPriv = fbGetGCPrivate (pGC);
+ RegionPtr pClip = fbGetCompositeClip(pGC);
+ FbBits *dst;
+ FbStride dstStride;
+ int dstBpp;
+ FbDots dots;
+ FbBits and, xor;
+ xPoint *ppt;
+ int npt;
+ BoxPtr pBox;
+ int nBox;
+
+ /* make pointlist origin relative */
+ ppt = pptInit;
+ npt = nptInit;
+ if (mode == CoordModePrevious)
+ {
+ ppt->x += pDrawable->x;
+ ppt->y += pDrawable->y;
+ npt--;
+ while(npt--)
+ {
+ ppt++;
+ ppt->x += (ppt-1)->x;
+ ppt->y += (ppt-1)->y;
+ }
+ }
+ else
+ {
+ while (npt--)
+ {
+ ppt->x += pDrawable->x;
+ ppt->y += pDrawable->y;
+ ppt++;
+ }
+ }
+ fbGetDrawable (pDrawable, dst, dstStride, dstBpp);
+ and = pPriv->and;
+ xor = pPriv->xor;
+ dots = fbDots;
+#ifndef FBNOPIXADDR
+ if (and == 0)
+ {
+ switch (dstBpp) {
+ case 8: dots = fbDots8; break;
+ case 16: dots = fbDots16; break;
+ case 32: dots = fbDots32; break;
+ }
+ }
+#endif
+ for (nBox = REGION_NUM_RECTS (pClip), pBox = REGION_RECTS (pClip);
+ nBox--; pBox++)
+ (*dots) (dst, dstStride, dstBpp, pBox, pptInit, nptInit, and, xor);
+}
diff --git a/xc/programs/Xserver/fb/fbpush.c b/xc/programs/Xserver/fb/fbpush.c
new file mode 100644
index 000000000..e864305c7
--- /dev/null
+++ b/xc/programs/Xserver/fb/fbpush.c
@@ -0,0 +1,243 @@
+/*
+ * $Id: fbpush.c,v 1.1 2000/01/06 12:56:53 faith Exp $
+ *
+ * Copyright © 1998 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/fb/fbpush.c,v 1.2 1999/11/19 14:59:16 hohndel Exp $ */
+
+#include "fb.h"
+
+void
+fbPushPattern (DrawablePtr pDrawable,
+ GCPtr pGC,
+
+ FbStip *src,
+ FbStride srcStride,
+ int srcX,
+
+ int x,
+ int y,
+
+ int width,
+ int height)
+{
+ FbStip *s, bitsMask, bitsMask0, bits;
+ int xspan;
+ int w;
+ int rot;
+ int lenspan;
+ FbBits *d;
+
+ src += srcX >> FB_STIP_SHIFT;
+ srcX &= FB_STIP_MASK;
+
+ bitsMask0 = FbStipMask (srcX, 1);
+
+ while (height--)
+ {
+ bitsMask = bitsMask0;
+ w = width;
+ s = src;
+ src += srcStride;
+ bits = *s++;
+ xspan = x;
+ while (w)
+ {
+ if (bits & bitsMask)
+ {
+ lenspan = 0;
+ do
+ {
+ lenspan++;
+ if (lenspan == w)
+ break;
+ bitsMask = FbStipRight (bitsMask, 1);
+ if (!bitsMask)
+ {
+ bits = *s++;
+ bitsMask = FbBitsMask(0,1);
+ }
+ } while (bits & bitsMask);
+ fbFill (pDrawable, pGC, xspan, y, lenspan, 1);
+ xspan += lenspan;
+ w -= lenspan;
+ }
+ else
+ {
+ do
+ {
+ w--;
+ xspan++;
+ if (!w)
+ break;
+ bitsMask = FbStipRight (bitsMask, 1);
+ if (!bitsMask)
+ {
+ bits = *s++;
+ bitsMask = FbBitsMask(0,1);
+ }
+ } while (!(bits & bitsMask));
+ }
+ }
+ y++;
+ }
+}
+
+void
+fbPushFill (DrawablePtr pDrawable,
+ GCPtr pGC,
+
+ FbStip *src,
+ FbStride srcStride,
+ int srcX,
+
+ int x,
+ int y,
+ int width,
+ int height)
+{
+ FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
+
+ if (pGC->fillStyle == FillSolid)
+ {
+ FbBits *dst;
+ FbStride dstStride;
+ int dstBpp;
+ int dstX;
+ int dstWidth;
+
+ fbGetDrawable (pDrawable, dst, dstStride, dstBpp);
+ dst = dst + y * dstStride;
+ dstX = x * dstBpp;
+ dstWidth = width * dstBpp;
+ if (dstBpp == 1)
+ {
+ fbBltStip (src,
+ srcStride,
+ srcX,
+
+ (FbStip *) dst,
+ FbBitsStrideToStipStride (dstStride),
+ dstX,
+
+ dstWidth,
+ height,
+
+ FbStipple1Rop(pGC->alu,pGC->fgPixel),
+ pPriv->pm,
+ dstBpp);
+ }
+ else
+ {
+ fbBltOne (src,
+ srcStride,
+ srcX,
+
+ dst,
+ dstStride,
+ dstX,
+ dstBpp,
+
+ dstWidth,
+ height,
+
+ pPriv->and, pPriv->xor,
+ fbAnd(GXnoop,(FbBits) 0,FB_ALLONES),
+ fbXor(GXnoop,(FbBits) 0,FB_ALLONES));
+ }
+ }
+ else
+ {
+ fbPushPattern (pDrawable, pGC, src, srcStride, srcX,
+ x, y, width, height);
+ }
+}
+
+void
+fbPushImage (DrawablePtr pDrawable,
+ GCPtr pGC,
+
+ FbStip *src,
+ FbStride srcStride,
+ int srcX,
+
+ int x,
+ int y,
+ int width,
+ int height)
+{
+ RegionPtr pClip = fbGetCompositeClip (pGC);
+ int nbox;
+ BoxPtr pbox;
+ int x1, y1, x2, y2;
+
+ for (nbox = REGION_NUM_RECTS (pClip),
+ pbox = REGION_RECTS(pClip);
+ nbox--;
+ pbox++)
+ {
+ x1 = x;
+ y1 = y;
+ x2 = x + width;
+ y2 = y + height;
+ if (x1 < pbox->x1)
+ x1 = pbox->x1;
+ if (y1 < pbox->y1)
+ y1 = pbox->y1;
+ if (x2 > pbox->x2)
+ x2 = pbox->x2;
+ if (y2 > pbox->y2)
+ y2 = pbox->y2;
+ if (x1 >= x2 || y1 >= y2)
+ continue;
+ fbPushFill (pDrawable,
+ pGC,
+
+ src + (y1 - y) * srcStride,
+ srcStride,
+ srcX + (x1 - x),
+
+ x1,
+ y1,
+ x2 - x1,
+ y2 - y1);
+ }
+}
+
+void
+fbPushPixels (GCPtr pGC,
+ PixmapPtr pBitmap,
+ DrawablePtr pDrawable,
+ int dx,
+ int dy,
+ int xOrg,
+ int yOrg)
+{
+ FbStip *stip;
+ FbStride stipStride;
+ int stipBpp;
+
+ fbGetStipDrawable (&pBitmap->drawable, stip, stipStride, stipBpp);
+
+ fbPushImage (pDrawable, pGC,
+ stip, stipStride, 0,
+ xOrg, yOrg, dx, dy);
+}
diff --git a/xc/programs/Xserver/fb/fbrop.h b/xc/programs/Xserver/fb/fbrop.h
new file mode 100644
index 000000000..765dabcf1
--- /dev/null
+++ b/xc/programs/Xserver/fb/fbrop.h
@@ -0,0 +1,116 @@
+/*
+ * $Id: fbrop.h,v 1.1 2000/01/06 12:56:54 faith Exp $
+ *
+ * Copyright © 1998 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/fb/fbrop.h,v 1.1 1999/11/19 13:53:45 hohndel Exp $ */
+
+#ifndef _FBROP_H_
+#define _FBROP_H_
+
+typedef struct _mergeRopBits {
+ FbBits ca1, cx1, ca2, cx2;
+} FbMergeRopRec, *FbMergeRopPtr;
+
+extern const FbMergeRopRec FbMergeRopBits[16];
+
+#define FbDeclareMergeRop() FbBits _ca1, _cx1, _ca2, _cx2;
+#define FbDeclarePrebuiltMergeRop() FbBits _cca, _ccx;
+
+#define FbInitializeMergeRop(alu,pm) {\
+ const FbMergeRopRec *_bits; \
+ _bits = &FbMergeRopBits[alu]; \
+ _ca1 = _bits->ca1 & pm; \
+ _cx1 = _bits->cx1 | ~pm; \
+ _ca2 = _bits->ca2 & pm; \
+ _cx2 = _bits->cx2 & pm; \
+}
+
+#define FbDestInvarientMergeRop() (_ca1 == 0 && _cx1 == 0)
+
+/* AND has higher precedence than XOR */
+
+#define FbDoMergeRop(src, dst) \
+ ((dst) & ((src) & _ca1 ^ _cx1) ^ ((src) & _ca2 ^ _cx2))
+
+#define FbDoDestInvarientMergeRop(src) ((src) & _ca2 ^ _cx2)
+
+#define FbDoMaskMergeRop(src, dst, mask) \
+ ((dst) & (((src) & _ca1 ^ _cx1) | ~(mask)) ^ (((src) & _ca2 ^ _cx2) & (mask)))
+
+#define FbDoRRop(dst, and, xor) (((dst) & (and)) ^ (xor))
+
+#define FbDoMaskRRop(dst, and, xor, mask) \
+ (((dst) & ((and) | ~(mask))) ^ (xor & mask))
+
+/*
+ * Take a single bit (0 or 1) and generate a full mask
+ */
+#define fbFillFromBit(b,t) (~((t) ((b) & 1)-1))
+
+#define fbXorT(rop,fg,pm,t) ((((fg) & fbFillFromBit((rop) >> 1,t)) | \
+ (~(fg) & fbFillFromBit((rop) >> 3,t))) & (pm))
+
+#define fbAndT(rop,fg,pm,t) ((((fg) & fbFillFromBit (rop ^ (rop>>1),t)) | \
+ (~(fg) & fbFillFromBit((rop>>2) ^ (rop>>3),t))) | \
+ ~(pm))
+
+#define fbXor(rop,fg,pm) fbXorT(rop,fg,pm,FbBits)
+
+#define fbAnd(rop,fg,pm) fbAndT(rop,fg,pm,FbBits)
+
+#define fbXorStip(rop,fg,pm) fbXorT(rop,fg,pm,FbStip)
+
+#define fbAndStip(rop,fg,pm) fbAndT(rop,fg,pm,FbStip)
+
+/*
+ * Stippling operations;
+ */
+
+extern const FbBits fbStipple16Bits[256]; /* half of table */
+#define FbStipple16Bits(b) \
+ (fbStipple16Bits[(b)&0xff] | fbStipple16Bits[(b) >> 8] << FB_HALFUNIT)
+extern const FbBits fbStipple8Bits[256];
+extern const FbBits fbStipple4Bits[16];
+extern const FbBits fbStipple2Bits[4];
+extern const FbBits fbStipple1Bits[2];
+extern const FbBits *const fbStippleTable[];
+
+#define FbStippleRRop(dst, b, fa, fx, ba, bx) \
+ (FbDoRRop(dst, fa, fx) & b) | (FbDoRRop(dst, ba, bx) & ~b)
+
+#define FbStippleRRopMask(dst, b, fa, fx, ba, bx, m) \
+ (FbDoMaskRRop(dst, fa, fx, m) & (b)) | (FbDoMaskRRop(dst, ba, bx, m) & ~(b))
+
+#define FbOpaqueStipple(b, fg, bg) ((fg) & (b) | (bg) & ~(b))
+
+/*
+ * Compute rop for using tile code for 1-bit dest stipples; modifies
+ * existing rop to flip depending on pixel values
+ */
+#define FbStipple1RopPick(alu,b) (((alu) >> (2 - (((b) & 1) << 1))) & 3)
+
+#define FbOpaqueStipple1Rop(alu,fg,bg) (FbStipple1RopPick(alu,fg) | \
+ (FbStipple1RopPick(alu,bg) << 2))
+
+#define FbStipple1Rop(alu,fg) (FbStipple1RopPick(alu,fg) | 4)
+
+#endif
diff --git a/xc/programs/Xserver/fb/fbscreen.c b/xc/programs/Xserver/fb/fbscreen.c
new file mode 100644
index 000000000..5394d525f
--- /dev/null
+++ b/xc/programs/Xserver/fb/fbscreen.c
@@ -0,0 +1,222 @@
+/*
+ * $Id: fbscreen.c,v 1.1 2000/01/06 12:56:54 faith Exp $
+ *
+ * Copyright © 1998 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/fb/fbscreen.c,v 1.3 1999/12/30 02:33:59 robin Exp $ */
+
+#include "fb.h"
+
+Bool
+fbCloseScreen (int index, ScreenPtr pScreen)
+{
+ int d;
+ DepthPtr depths = pScreen->allowedDepths;
+
+ for (d = 0; d < pScreen->numDepths; d++)
+ xfree (depths[d].vids);
+ xfree (depths);
+ xfree (pScreen->visuals);
+ xfree (pScreen->devPrivate);
+ return TRUE;
+}
+
+Bool
+fbRealizeFont(ScreenPtr pScreen, FontPtr pFont)
+{
+ return (TRUE);
+}
+
+Bool
+fbUnrealizeFont(ScreenPtr pScreen, FontPtr pFont)
+{
+ return (TRUE);
+}
+
+void
+fbQueryBestSize (int class,
+ unsigned short *width, unsigned short *height,
+ ScreenPtr pScreen)
+{
+ unsigned short w;
+
+ switch (class) {
+ case TileShape:
+ case StippleShape:
+ w = *width;
+ if ((w & (w - 1)) && w < FB_UNIT)
+ {
+ for (w = 1; w < *width; w <<= 1)
+ ;
+ *width = w;
+ }
+ }
+}
+
+Bool
+fbSetupScreen(ScreenPtr pScreen,
+ pointer pbits, /* pointer to screen bitmap */
+ int xsize, /* in pixels */
+ int ysize,
+ int dpix, /* dots per inch */
+ int dpiy,
+ int width, /* pixel width of frame buffer */
+ int bpp) /* bits per pixel for screen */
+{
+ int i;
+
+ if (!fbAllocatePrivates(pScreen, (int *) 0))
+ return FALSE;
+ pScreen->defColormap = FakeClientID(0);
+ /* let CreateDefColormap do whatever it wants for pixels */
+ pScreen->blackPixel = pScreen->whitePixel = (Pixel) 0;
+ pScreen->QueryBestSize = fbQueryBestSize;
+ /* SaveScreen */
+ pScreen->GetImage = fbGetImage;
+ pScreen->GetSpans = fbGetSpans;
+ pScreen->CreateWindow = fbCreateWindow;
+ pScreen->DestroyWindow = fbDestroyWindow;
+ pScreen->PositionWindow = fbPositionWindow;
+ pScreen->ChangeWindowAttributes = fbChangeWindowAttributes;
+ pScreen->RealizeWindow = fbMapWindow;
+ pScreen->UnrealizeWindow = fbUnmapWindow;
+ pScreen->PaintWindowBackground = fbPaintWindow;
+ pScreen->PaintWindowBorder = fbPaintWindow;
+ pScreen->CopyWindow = fbCopyWindow;
+ pScreen->CreatePixmap = fbCreatePixmap;
+ pScreen->DestroyPixmap = fbDestroyPixmap;
+ pScreen->RealizeFont = fbRealizeFont;
+ pScreen->UnrealizeFont = fbUnrealizeFont;
+ pScreen->CreateGC = fbCreateGC;
+ pScreen->CreateColormap = fbInitializeColormap;
+ pScreen->DestroyColormap = (void (*)(ColormapPtr))NoopDDA;
+ pScreen->InstallColormap = fbInstallColormap;
+ pScreen->UninstallColormap = fbUninstallColormap;
+ pScreen->ListInstalledColormaps = fbListInstalledColormaps;
+ pScreen->StoreColors = (void (*)(ColormapPtr, int, xColorItem *))NoopDDA;
+ pScreen->ResolveColor = fbResolveColor;
+ pScreen->BitmapToRegion = fbPixmapToRegion;
+
+#ifndef FB_OLD_SCREEN
+ pScreen->BackingStoreFuncs.SaveAreas = fbSaveAreas;
+ pScreen->BackingStoreFuncs.RestoreAreas = fbRestoreAreas;
+ pScreen->BackingStoreFuncs.SetClipmaskRgn = 0;
+ pScreen->BackingStoreFuncs.GetImagePixmap = 0;
+ pScreen->BackingStoreFuncs.GetSpansPixmap = 0;
+#endif
+
+ return TRUE;
+}
+
+Bool
+fbFinishScreenInit(ScreenPtr pScreen,
+ pointer pbits,
+ int xsize,
+ int ysize,
+ int dpix,
+ int dpiy,
+ int width,
+ int bpp)
+{
+ int i, j;
+ VisualPtr visuals;
+ DepthPtr depths;
+ int nvisuals;
+ int ndepths;
+ int rootdepth;
+ VisualID defaultVisual;
+
+#ifdef FB_DEBUG
+ int stride;
+
+ ysize -= 2;
+ stride = (width * bpp) / 8;
+ fbSetBits ((FbStip *) pbits,
+ stride / sizeof (FbStip), FB_HEAD_BITS);
+ pbits = (void *) ((char *) pbits + stride);
+ fbSetBits ((FbStip *) ((char *) pbits + stride * ysize),
+ stride / sizeof (FbStip), FB_TAIL_BITS);
+#endif
+ rootdepth = 0;
+ if (!fbInitVisuals (&visuals, &depths, &nvisuals, &ndepths, &rootdepth,
+ &defaultVisual,((unsigned long)1<<(bpp-1)), 8))
+ return FALSE;
+ if (! miScreenInit(pScreen, pbits, xsize, ysize, dpix, dpiy, width,
+ rootdepth, ndepths, depths,
+ defaultVisual, nvisuals, visuals
+#ifdef FB_OLD_SCREEN
+ , (miBSFuncPtr) 0
+#endif
+ ))
+ return FALSE;
+ /* overwrite miCloseScreen with our own */
+ pScreen->CloseScreen = fbCloseScreen;
+#if 0
+ /* leave backing store initialization to the enclosing code so
+ * it can choose the correct order of wrappers
+ */
+ /* init backing store here so we can overwrite CloseScreen without stepping
+ * on the backing store wrapped version */
+ fbInitializeBackingStore (pScreen);
+#endif
+ return TRUE;
+}
+
+/* dts * (inch/dot) * (25.4 mm / inch) = mm */
+Bool
+fbScreenInit(ScreenPtr pScreen,
+ pointer pbits,
+ int xsize,
+ int ysize,
+ int dpix,
+ int dpiy,
+ int width,
+ int bpp)
+{
+ if (!fbSetupScreen(pScreen, pbits, xsize, ysize, dpix, dpiy, width, bpp))
+ return FALSE;
+ if (!fbFinishScreenInit(pScreen, pbits, xsize, ysize, dpix, dpiy,
+ width, bpp))
+ return FALSE;
+ fbInitializeBackingStore (pScreen);
+ return TRUE;
+}
+
+
+#ifdef FB_OLD_SCREEN
+const miBSFuncRec fbBSFuncRec = {
+ fbSaveAreas,
+ fbRestoreAreas,
+ (void (*)(GCPtr, RegionPtr)) 0,
+ (PixmapPtr (*)(void)) 0,
+ (PixmapPtr (*)(void)) 0,
+};
+#endif
+
+void
+fbInitializeBackingStore (ScreenPtr pScreen)
+{
+#ifdef FB_OLD_SCREEN
+ miInitializeBackingStore (pScreen, (miBSFuncRec *) &fbBSFuncRec);
+#else
+ miInitializeBackingStore (pScreen);
+#endif
+}
diff --git a/xc/programs/Xserver/fb/fbseg.c b/xc/programs/Xserver/fb/fbseg.c
new file mode 100644
index 000000000..1d6f6061a
--- /dev/null
+++ b/xc/programs/Xserver/fb/fbseg.c
@@ -0,0 +1,736 @@
+/*
+ * $Id: fbseg.c,v 1.1 2000/01/06 12:56:54 faith Exp $
+ *
+ * Copyright © 1998 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/fb/fbseg.c,v 1.1 1999/11/19 13:53:46 hohndel Exp $ */
+
+#include "fb.h"
+#include "miline.h"
+
+void
+fbBresSolid (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int dashOffset,
+ int signdx,
+ int signdy,
+ int axis,
+ int x1,
+ int y1,
+ int e,
+ int e1,
+ int e3,
+ int len)
+{
+ FbBits *dst;
+ FbStride dstStride;
+ int dstBpp;
+ FbGCPrivPtr pPriv = fbGetGCPrivate (pGC);
+ FbBits and = pPriv->and;
+ FbBits xor = pPriv->xor;
+ FbBits mask, mask0;
+ FbBits bits;
+
+ fbGetDrawable (pDrawable, dst, dstStride, dstBpp);
+ dst += (y1 * dstStride);
+ x1 *= dstBpp;
+ dst += x1 >> FB_SHIFT;
+ x1 &= FB_MASK;
+ mask0 = FbBitsMask(0, dstBpp);
+ mask = FbScrRight (mask0, x1);
+ if (signdx < 0)
+ mask0 = FbScrRight (mask0, FB_UNIT - dstBpp);
+ if (signdy < 0)
+ dstStride = -dstStride;
+ if (axis == X_AXIS)
+ {
+ bits = 0;
+ while (len--)
+ {
+ bits |= mask;
+ if (signdx > 0)
+ mask = FbScrRight(mask, dstBpp);
+ else
+ mask = FbScrLeft(mask, dstBpp);
+ if (!mask)
+ {
+ *dst = FbDoMaskRRop (*dst, and, xor, bits);
+ bits = 0;
+ dst += signdx;
+ mask = mask0;
+ }
+ e += e1;
+ if (e >= 0)
+ {
+ *dst = FbDoMaskRRop (*dst, and, xor, bits);
+ bits = 0;
+ dst += dstStride;
+ e += e3;
+ }
+ }
+ if (bits)
+ *dst = FbDoMaskRRop (*dst, and, xor, bits);
+ }
+ else
+ {
+ while (len--)
+ {
+ *dst = FbDoMaskRRop (*dst, and, xor, mask);
+ dst += dstStride;
+ e += e1;
+ if (e >= 0)
+ {
+ e += e3;
+ if (signdx > 0)
+ mask = FbScrRight(mask, dstBpp);
+ else
+ mask = FbScrLeft(mask, dstBpp);
+ if (!mask)
+ {
+ dst += signdx;
+ mask = mask0;
+ }
+ }
+ }
+ }
+}
+
+void
+fbBresDash (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int dashOffset,
+ int signdx,
+ int signdy,
+ int axis,
+ int x1,
+ int y1,
+ int e,
+ int e1,
+ int e3,
+ int len)
+{
+ FbBits *dst;
+ FbStride dstStride;
+ int dstBpp;
+ FbGCPrivPtr pPriv = fbGetGCPrivate (pGC);
+ FbBits and = pPriv->and;
+ FbBits xor = pPriv->xor;
+ FbBits bgand = pPriv->bgand;
+ FbBits bgxor = pPriv->bgxor;
+ FbBits mask, mask0;
+ unsigned char *dash, *lastDash;
+ int dashlen;
+ Bool even;
+ Bool doOdd;
+
+ fbGetDrawable (pDrawable, dst, dstStride, dstBpp);
+ doOdd = pGC->lineStyle == LineDoubleDash;
+ even = TRUE;
+ dash = pGC->dash;
+ lastDash = dash + pGC->numInDashList;
+ dashOffset %= pPriv->dashLength;
+ while (dashOffset >= *dash)
+ {
+ dashOffset -= *dash++;
+ if (dash == lastDash)
+ dash = pGC->dash;
+ even = !even;
+ }
+ dashlen = *dash - dashOffset;
+ dst += (y1 * dstStride);
+ x1 *= dstBpp;
+ dst += x1 >> FB_SHIFT;
+ x1 &= FB_MASK;
+ mask0 = FbBitsMask(0, dstBpp);
+ mask = FbScrRight (mask0, x1);
+ if (signdx < 0)
+ mask0 = FbScrRight (mask0, FB_UNIT - dstBpp);
+ if (signdy < 0)
+ dstStride = -dstStride;
+ while (len--)
+ {
+ if (even)
+ *dst = FbDoMaskRRop (*dst, and, xor, mask);
+ else if (doOdd)
+ *dst = FbDoMaskRRop (*dst, bgand, bgxor, mask);
+ if (axis == X_AXIS)
+ {
+ if (signdx > 0)
+ mask = FbScrRight(mask, dstBpp);
+ else
+ mask = FbScrLeft(mask, dstBpp);
+ if (!mask)
+ {
+ dst += signdx;
+ mask = mask0;
+ }
+ e += e1;
+ if (e >= 0)
+ {
+ dst += dstStride;
+ e += e3;
+ }
+ }
+ else
+ {
+ dst += dstStride;
+ e += e1;
+ if (e >= 0)
+ {
+ e += e3;
+ if (signdx > 0)
+ mask = FbScrRight(mask, dstBpp);
+ else
+ mask = FbScrLeft(mask, dstBpp);
+ if (!mask)
+ {
+ dst += signdx;
+ mask = mask0;
+ }
+ }
+ }
+ if (!--dashlen)
+ {
+ if (++dash == lastDash)
+ dash = pGC->dash;
+ dashlen = *dash;
+ even = !even;
+ }
+ }
+}
+
+void
+fbBresFill (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int dashOffset,
+ int signdx,
+ int signdy,
+ int axis,
+ int x1,
+ int y1,
+ int e,
+ int e1,
+ int e3,
+ int len)
+{
+ while (len--)
+ {
+ fbFill (pDrawable, pGC, x1, y1, 1, 1);
+ if (axis == X_AXIS)
+ {
+ x1 += signdx;
+ e += e1;
+ if (e >= 0)
+ {
+ e += e3;
+ y1 += signdy;
+ }
+ }
+ else
+ {
+ y1 += signdy;
+ e += e1;
+ if (e >= 0)
+ {
+ e += e3;
+ x1 += signdx;
+ }
+ }
+ }
+}
+
+static void
+fbSetFg (DrawablePtr pDrawable,
+ GCPtr pGC,
+ Pixel fg)
+{
+ if (fg != pGC->fgPixel)
+ {
+ DoChangeGC (pGC, GCForeground, (XID *) &fg, FALSE);
+ ValidateGC (pDrawable, pGC);
+ }
+}
+
+void
+fbBresFillDash (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int dashOffset,
+ int signdx,
+ int signdy,
+ int axis,
+ int x1,
+ int y1,
+ int e,
+ int e1,
+ int e3,
+ int len)
+{
+ FbGCPrivPtr pPriv = fbGetGCPrivate (pGC);
+ unsigned char *dash, *lastDash;
+ int dashlen;
+ Bool even;
+ Bool doOdd;
+ Bool doBg;
+ Pixel fg, bg;
+
+ fg = pGC->fgPixel;
+ bg = pGC->bgPixel;
+
+ /* whether to fill the odd dashes */
+ doOdd = pGC->lineStyle == LineDoubleDash;
+ /* whether to switch fg to bg when filling odd dashes */
+ doBg = doOdd && (pGC->fillStyle == FillSolid ||
+ pGC->fillStyle == FillStippled);
+ /* compute current dash position */
+ even = TRUE;
+ dash = pGC->dash;
+ lastDash = dash + pGC->numInDashList;
+ dashOffset %= pPriv->dashLength;
+ while (dashOffset >= *dash)
+ {
+ dashOffset -= *dash++;
+ if (dash == lastDash)
+ dash = pGC->dash;
+ even = !even;
+ }
+ dashlen = *dash - dashOffset;
+ while (len--)
+ {
+ if (even || doOdd)
+ {
+ if (doBg)
+ {
+ if (even)
+ fbSetFg (pDrawable, pGC, fg);
+ else
+ fbSetFg (pDrawable, pGC, bg);
+ }
+ fbFill (pDrawable, pGC, x1, y1, 1, 1);
+ }
+ if (axis == X_AXIS)
+ {
+ x1 += signdx;
+ e += e1;
+ if (e >= 0)
+ {
+ e += e3;
+ y1 += signdy;
+ }
+ }
+ else
+ {
+ y1 += signdy;
+ e += e1;
+ if (e >= 0)
+ {
+ e += e3;
+ x1 += signdx;
+ }
+ }
+ if (!--dashlen)
+ {
+ if (++dash == lastDash)
+ dash = pGC->dash;
+ dashlen = *dash;
+ even = !even;
+ }
+ }
+ if (doBg)
+ fbSetFg (pDrawable, pGC, fg);
+}
+
+#ifdef FB_24BIT
+void
+fbBresSolid24 (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int dashOffset,
+ int signdx,
+ int signdy,
+ int axis,
+ int x1,
+ int y1,
+ int e,
+ int e1,
+ int e3,
+ int len)
+{
+ FbBits *dst;
+ FbStride dstStride;
+ int dstBpp;
+ FbGCPrivPtr pPriv = fbGetGCPrivate (pGC);
+ FbBits and = pPriv->and;
+ FbBits xor = pPriv->xor;
+ FbBits leftMask, rightMask;
+ int nl;
+ FbBits bits;
+ FbBits *d;
+ int x;
+ int rot;
+ FbBits andT, xorT;
+
+ fbGetDrawable (pDrawable, dst, dstStride, dstBpp);
+ dst += (y1 * dstStride);
+ x1 *= 24;
+ if (signdy < 0)
+ dstStride = -dstStride;
+ signdx *= 24;
+ while (len--)
+ {
+ d = dst + (x1 >> FB_SHIFT);
+ x = x1 & FB_MASK;
+ rot = x % 24;
+ andT = FbRot24(and,rot);
+ xorT = FbRot24(xor,rot);
+ FbMaskBits (x, 24, leftMask, nl, rightMask);
+ if (leftMask)
+ {
+ *d = FbDoMaskRRop (*d, andT, xorT, leftMask);
+ d++;
+ andT = FbNext24Pix (andT);
+ xorT = FbNext24Pix (xorT);
+ }
+ if (rightMask)
+ *d = FbDoMaskRRop (*d, andT, xorT, rightMask);
+ if (axis == X_AXIS)
+ {
+ x1 += signdx;
+ e += e1;
+ if (e >= 0)
+ {
+ e += e3;
+ dst += dstStride;
+ }
+ }
+ else
+ {
+ dst += dstStride;
+ e += e1;
+ if (e >= 0)
+ {
+ e += e3;
+ x1 += signdx;
+ }
+ }
+ }
+}
+void
+fbBresDash24 (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int dashOffset,
+ int signdx,
+ int signdy,
+ int axis,
+ int x1,
+ int y1,
+ int e,
+ int e1,
+ int e3,
+ int len)
+{
+ FbBits *dst;
+ FbStride dstStride;
+ int dstBpp;
+ FbGCPrivPtr pPriv = fbGetGCPrivate (pGC);
+ FbBits andT, xorT;
+ FbBits fgand = pPriv->and;
+ FbBits fgxor = pPriv->xor;
+ FbBits bgand = pPriv->bgand;
+ FbBits bgxor = pPriv->bgxor;
+ FbBits leftMask, rightMask;
+ int nl;
+ FbBits bits;
+ FbBits *d;
+ int x;
+ int rot;
+ unsigned char *dash, *lastDash;
+ int dashlen;
+ Bool even;
+ Bool doOdd;
+
+ fbGetDrawable (pDrawable, dst, dstStride, dstBpp);
+ doOdd = pGC->lineStyle == LineDoubleDash;
+ even = TRUE;
+ dash = pGC->dash;
+ lastDash = dash + pGC->numInDashList;
+ dashOffset %= pPriv->dashLength;
+ while (dashOffset >= *dash)
+ {
+ dashOffset -= *dash++;
+ if (dash == lastDash)
+ dash = pGC->dash;
+ even = !even;
+ }
+ dashlen = *dash - dashOffset;
+ dst += (y1 * dstStride);
+ x1 *= 24;
+ if (signdy < 0)
+ dstStride = -dstStride;
+ signdx *= 24;
+ while (len--)
+ {
+ if (even || doOdd)
+ {
+ if (even)
+ {
+ andT = fgand;
+ xorT = fgxor;
+ }
+ else
+ {
+ andT = bgand;
+ xorT = bgxor;
+ }
+ d = dst + (x1 >> FB_SHIFT);
+ x = x1 & FB_MASK;
+ rot = x % 24;
+ andT = FbRot24 (andT, rot);
+ xorT = FbRot24 (xorT, rot);
+ FbMaskBits (x, 24, leftMask, nl, rightMask);
+ if (leftMask)
+ {
+ *d = FbDoMaskRRop (*d, andT, xorT, leftMask);
+ d++;
+ andT = FbNext24Pix (andT);
+ xorT = FbNext24Pix (xorT);
+ }
+ if (rightMask)
+ *d = FbDoMaskRRop (*d, andT, xorT, rightMask);
+ }
+ if (axis == X_AXIS)
+ {
+ x1 += signdx;
+ e += e1;
+ if (e >= 0)
+ {
+ e += e3;
+ dst += dstStride;
+ }
+ }
+ else
+ {
+ dst += dstStride;
+ e += e1;
+ if (e >= 0)
+ {
+ e += e3;
+ x1 += signdx;
+ }
+ }
+ if (!--dashlen)
+ {
+ if (++dash == lastDash)
+ dash = pGC->dash;
+ dashlen = *dash;
+ even = !even;
+ }
+ }
+}
+#endif
+
+void
+fbSegment (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x1,
+ int y1,
+ int x2,
+ int y2,
+ Bool drawLast,
+ int *dashOffset)
+{
+ FbBres bres;
+ FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
+ RegionPtr pClip = fbGetCompositeClip(pGC);
+ BoxPtr pBox;
+ int dstBpp = pDrawable->bitsPerPixel;
+ int nBox;
+ int tmp;
+ int adx; /* abs values of dx and dy */
+ int ady;
+ int signdx; /* sign of dx and dy */
+ int signdy;
+ int e, e1, e2, e3; /* bresenham error and increments */
+ int len; /* length of segment */
+ int axis; /* major axis */
+ int octant;
+ int dashoff;
+ int doff;
+ unsigned int bias = miGetZeroLineBias(pDrawable->pScreen);
+ unsigned int oc1; /* outcode of point 1 */
+ unsigned int oc2; /* outcode of point 2 */
+
+ nBox = REGION_NUM_RECTS (pClip);
+ pBox = REGION_RECTS (pClip);
+
+ if (pGC->lineStyle == LineSolid)
+ {
+ bres = fbBresFill;
+ if (pGC->fillStyle == FillSolid)
+ {
+ bres = fbBresSolid;
+#ifdef FB_24BIT
+ if (dstBpp == 24)
+ bres = fbBresSolid24;
+#ifndef FBNOPIXADDR
+ else
+#endif
+#endif
+#ifndef FBNOPIXADDR
+ if (pPriv->and == 0)
+ {
+ switch (dstBpp) {
+ case 8: bres = fbBresSolid8; break;
+ case 16: bres = fbBresSolid16; break;
+ case 32: bres = fbBresSolid32; break;
+ }
+ }
+#endif
+ }
+ }
+ else
+ {
+ bres = fbBresFillDash;
+ if (pGC->fillStyle == FillSolid)
+ {
+ bres = fbBresDash;
+#ifdef FB_24BIT
+ if (dstBpp == 24)
+ bres = fbBresDash24;
+ else
+#endif
+#ifndef FBNOPIXADDR
+ if (pPriv->and == 0 &&
+ (pGC->lineStyle == LineOnOffDash || pPriv->bgand == 0))
+ {
+ switch (dstBpp) {
+ case 8: bres = fbBresDash8; break;
+ case 16: bres = fbBresDash16; break;
+ case 32: bres = fbBresDash32; break;
+ }
+ }
+#endif
+ }
+ }
+
+ CalcLineDeltas(x1, y1, x2, y2, adx, ady, signdx, signdy,
+ 1, 1, octant);
+
+ if (adx > ady)
+ {
+ axis = X_AXIS;
+ e1 = ady << 1;
+ e2 = e1 - (adx << 1);
+ e = e1 - adx;
+ len = adx;
+ }
+ else
+ {
+ axis = Y_AXIS;
+ e1 = adx << 1;
+ e2 = e1 - (ady << 1);
+ e = e1 - ady;
+ SetYMajorOctant(octant);
+ len = ady;
+ }
+
+ FIXUP_ERROR (e, octant, bias);
+
+ /*
+ * Adjust error terms to compare against zero
+ */
+ e3 = e2 - e1;
+ e = e - e1;
+
+ /* we have bresenham parameters and two points.
+ all we have to do now is clip and draw.
+ */
+
+ if (drawLast)
+ len++;
+ dashoff = *dashOffset;
+ *dashOffset = dashoff + len;
+ while(nBox--)
+ {
+ oc1 = 0;
+ oc2 = 0;
+ OUTCODES(oc1, x1, y1, pBox);
+ OUTCODES(oc2, x2, y2, pBox);
+ if ((oc1 | oc2) == 0)
+ {
+ (*bres) (pDrawable, pGC, dashoff,
+ signdx, signdy, axis, x1, y1,
+ e, e1, e3, len);
+ break;
+ }
+ else if (oc1 & oc2)
+ {
+ pBox++;
+ }
+ else
+ {
+ int new_x1 = x1, new_y1 = y1, new_x2 = x2, new_y2 = y2;
+ int clip1 = 0, clip2 = 0;
+ int clipdx, clipdy;
+ int err;
+
+ if (miZeroClipLine(pBox->x1, pBox->y1, pBox->x2-1,
+ pBox->y2-1,
+ &new_x1, &new_y1, &new_x2, &new_y2,
+ adx, ady, &clip1, &clip2,
+ octant, bias, oc1, oc2) == -1)
+ {
+ pBox++;
+ continue;
+ }
+
+ if (axis == X_AXIS)
+ len = abs(new_x2 - new_x1);
+ else
+ len = abs(new_y2 - new_y1);
+ if (clip2 != 0 || drawLast)
+ len++;
+ if (len)
+ {
+ /* unwind bresenham error term to first point */
+ doff = dashoff;
+ err = e;
+ if (clip1)
+ {
+ clipdx = abs(new_x1 - x1);
+ clipdy = abs(new_y1 - y1);
+ if (axis == X_AXIS)
+ {
+ doff += clipdx;
+ err += e3 * clipdy + e1 * clipdx;
+ }
+ else
+ {
+ doff += clipdy;
+ err += e3 * clipdx + e1 * clipdy;
+ }
+ }
+ (*bres) (pDrawable, pGC, doff,
+ signdx, signdy, axis, new_x1, new_y1,
+ err, e1, e3, len);
+ }
+ pBox++;
+ }
+ } /* while (nBox--) */
+}
diff --git a/xc/programs/Xserver/fb/fbsetsp.c b/xc/programs/Xserver/fb/fbsetsp.c
new file mode 100644
index 000000000..6fdb4571d
--- /dev/null
+++ b/xc/programs/Xserver/fb/fbsetsp.c
@@ -0,0 +1,93 @@
+/*
+ * $Id: fbsetsp.c,v 1.1 2000/01/06 12:56:54 faith Exp $
+ *
+ * Copyright © 1998 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/fb/fbsetsp.c,v 1.1 1999/11/19 13:53:46 hohndel Exp $ */
+
+#include "fb.h"
+
+void
+fbSetSpans (DrawablePtr pDrawable,
+ GCPtr pGC,
+ char *src,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int nspans,
+ int fSorted)
+{
+ FbGCPrivPtr pPriv = fbGetGCPrivate (pGC);
+ RegionPtr pClip = fbGetCompositeClip(pGC);
+ FbBits *dst, *d, *s;
+ FbStride dstStride;
+ int dstBpp;
+ BoxPtr pbox;
+ int n;
+ int xoff;
+ int x1, x2;
+ FbBits srcpm, dstpm;
+
+ fbGetDrawable (pDrawable, dst, dstStride, dstBpp);
+ while (nspans--)
+ {
+ d = dst + ppt->y * dstStride;
+ xoff = (((int) src) & (FB_MASK >> 3));
+ s = (FbBits *) (src - xoff);
+ xoff <<= 3;
+ n = REGION_NUM_RECTS(pClip);
+ pbox = REGION_RECTS (pClip);
+ while (n--)
+ {
+ if (pbox->y1 > ppt->y)
+ break;
+ if (pbox->y2 > ppt->y)
+ {
+ x1 = ppt->x;
+ x2 = x1 + *pwidth;
+ if (pbox->x1 > x1)
+ x1 = pbox->x1;
+ if (pbox->x2 < x2)
+ x2 = pbox->x2;
+ if (x1 < x2)
+ fbBlt ((FbBits *) s,
+ 0,
+ (x1 - ppt->x) * dstBpp + xoff,
+ d,
+ dstStride,
+ x1 * dstBpp,
+
+ (x2 - x1) * dstBpp,
+ 1,
+ pGC->alu,
+ pPriv->pm,
+ dstBpp,
+
+ FALSE,
+ FALSE);
+ }
+ }
+ src += PixmapBytePad (*pwidth, pDrawable->depth);
+ ppt++;
+ pwidth++;
+ }
+ fbValidateDrawable (pDrawable);
+}
+
diff --git a/xc/programs/Xserver/fb/fbsolid.c b/xc/programs/Xserver/fb/fbsolid.c
new file mode 100644
index 000000000..44e6a5031
--- /dev/null
+++ b/xc/programs/Xserver/fb/fbsolid.c
@@ -0,0 +1,210 @@
+/*
+ * $Id: fbsolid.c,v 1.1 2000/01/06 12:56:54 faith Exp $
+ *
+ * Copyright © 1998 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/fb/fbsolid.c,v 1.1 1999/11/19 13:53:46 hohndel Exp $ */
+
+#include "fb.h"
+
+void
+fbSolid (FbBits *dst,
+ FbStride dstStride,
+ int dstX,
+ int bpp,
+
+ int width,
+ int height,
+
+ FbBits and,
+ FbBits xor)
+{
+ FbBits startmask, endmask;
+ int n, nmiddle;
+
+#ifdef FB_24BIT
+ if (bpp == 24 && (!FbCheck24Pix(and) || !FbCheck24Pix(xor)))
+ {
+ fbSolid24 (dst, dstStride, dstX, width, height, and, xor);
+ return;
+ }
+#endif
+
+ dst += dstX >> FB_SHIFT;
+ dstX &= FB_MASK;
+ FbMaskBits (dstX, width, startmask, nmiddle, endmask);
+ if (startmask)
+ dstStride--;
+ dstStride -= nmiddle;
+ while (height--)
+ {
+ if (startmask)
+ {
+ *dst = FbDoMaskRRop(*dst, and, xor, startmask);
+ dst++;
+ }
+ n = nmiddle;
+ if (!and)
+ while (n--)
+ *dst++ = xor;
+ else
+ while (n--)
+ {
+ *dst = FbDoRRop (*dst, and, xor);
+ dst++;
+ }
+ if (endmask)
+ *dst = FbDoMaskRRop (*dst, and, xor, endmask);
+ dst += dstStride;
+ }
+}
+
+#ifdef FB_24BIT
+void
+fbSolid24 (FbBits *dst,
+ FbStride dstStride,
+ int dstX,
+
+ int width,
+ int height,
+
+ FbBits and,
+ FbBits xor)
+{
+ FbBits startmask, endmask;
+ FbBits bits;
+ FbBits xor0, xor1, xor2;
+ FbBits and0, and1, and2;
+ FbBits xorS, andS, xorE, andE;
+ int n, nmiddle;
+ int rotS, rotE, rot;
+
+ dst += dstX >> FB_SHIFT;
+ dstX &= FB_MASK;
+ /*
+ * Rotate pixel values this far across the word to align on
+ * screen pixel boundaries
+ */
+ rot = dstX % 24;
+ FbMaskBits (dstX, width, startmask, nmiddle, endmask);
+ if (startmask)
+ dstStride--;
+ dstStride -= nmiddle;
+
+ /*
+ * Precompute rotated versions of the rasterop values
+ */
+ rotS = rot;
+ xor = FbRot24(xor,rotS);
+ and = FbRot24(and,rotS);
+ if (startmask)
+ {
+ xorS = xor;
+ andS = and;
+ xor = FbNext24Pix(xor);
+ and = FbNext24Pix(and);
+ }
+
+ if (nmiddle)
+ {
+ xor0 = xor;
+ and0 = and;
+ xor1 = FbNext24Pix(xor0);
+ and1 = FbNext24Pix(and0);
+ xor2 = FbNext24Pix(xor1);
+ and2 = FbNext24Pix(and1);
+ }
+
+ if (endmask)
+ {
+ switch (nmiddle % 3) {
+ case 0:
+ xorE = xor;
+ andE = and;
+ break;
+ case 1:
+ xorE = xor1;
+ andE = and1;
+ break;
+ case 2:
+ xorE = xor2;
+ andE = and2;
+ break;
+ }
+ }
+
+ while (height--)
+ {
+ if (startmask)
+ {
+ *dst = FbDoMaskRRop(*dst, andS, xorS, startmask);
+ dst++;
+ }
+ n = nmiddle;
+ if (!and0)
+ {
+ while (n >= 3)
+ {
+ *dst++ = xor0;
+ *dst++ = xor1;
+ *dst++ = xor2;
+ n -= 3;
+ }
+ if (n)
+ {
+ *dst++ = xor0;
+ n--;
+ if (n)
+ {
+ *dst++ = xor1;
+ }
+ }
+ }
+ else
+ {
+ while (n >= 3)
+ {
+ *dst = FbDoRRop (*dst, and0, xor0);
+ dst++;
+ *dst = FbDoRRop (*dst, and1, xor1);
+ dst++;
+ *dst = FbDoRRop (*dst, and2, xor2);
+ dst++;
+ n -= 3;
+ }
+ if (n)
+ {
+ *dst = FbDoRRop (*dst, and0, xor0);
+ dst++;
+ n--;
+ if (n)
+ {
+ *dst = FbDoRRop (*dst, and1, xor1);
+ dst++;
+ }
+ }
+ }
+ if (endmask)
+ *dst = FbDoMaskRRop (*dst, andE, xorE, endmask);
+ dst += dstStride;
+ }
+}
+#endif
diff --git a/xc/programs/Xserver/fb/fbstipple.c b/xc/programs/Xserver/fb/fbstipple.c
new file mode 100644
index 000000000..8c3e867ba
--- /dev/null
+++ b/xc/programs/Xserver/fb/fbstipple.c
@@ -0,0 +1,225 @@
+/*
+ * $Id: fbstipple.c,v 1.1 2000/01/06 12:56:54 faith Exp $
+ *
+ * Copyright © 1998 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/fb/fbstipple.c,v 1.1 1999/11/19 13:53:46 hohndel Exp $ */
+
+#include "fb.h"
+
+void
+fbEvenStipple (FbBits *dst,
+ FbStride dstStride,
+ int dstX,
+ int dstBpp,
+
+ int width,
+ int height,
+
+ FbStip *stip,
+ int stipHeight,
+
+ FbBits fgand,
+ FbBits fgxor,
+ FbBits bgand,
+ FbBits bgxor,
+
+ int xRot,
+ int yRot)
+{
+ FbBits startmask, endmask;
+ FbBits mask, and, xor;
+ int nmiddle, n;
+ FbStip *s, *stipEnd, bits;
+ int rot, stipX, stipY;
+ int pixelsPerDst;
+ const FbBits *fbBits;
+
+ pixelsPerDst = FB_UNIT / dstBpp;
+ /*
+ * Adjust dest pointers
+ */
+ dst += dstX >> FB_SHIFT;
+ dstX &= FB_MASK;
+ FbMaskBits(dstX, width, startmask, nmiddle, endmask);
+ if (startmask)
+ dstStride--;
+ dstStride -= nmiddle;
+
+ xRot *= dstBpp;
+ /*
+ * Compute stip start scanline and rotation parameters
+ */
+ stipEnd = stip + 2 * stipHeight;
+ modulus (- yRot, stipHeight, stipY);
+ s = stip + 2 * stipY;
+ modulus (- xRot, FB_UNIT, stipX);
+ rot = stipX;
+
+ /*
+ * Get pointer to stipple mask array for this depth
+ */
+ fbBits = 0; /* unused */
+ if (pixelsPerDst <= 8)
+ fbBits = fbStippleTable[pixelsPerDst];
+
+ while (height--)
+ {
+ /*
+ * Extract stipple bits for this scanline;
+ */
+ bits = *s;
+ s += 2;
+ if (s == stipEnd)
+ s = stip;
+#if FB_UNIT > 32
+ if (pixelsPerDst == 16)
+ mask = FbStipple16Bits(FbLeftStipBits(bits,16));
+ else
+#endif
+ mask = fbBits[FbLeftStipBits(bits,pixelsPerDst)];
+ /*
+ * Rotate into position and compute reduced rop values
+ */
+ mask = FbRotLeft(mask, rot);
+ and = fgand & mask | bgand & ~mask;
+ xor = fgxor & mask | bgxor & ~mask;
+
+ /*
+ * Fill scanline
+ */
+ if (startmask)
+ {
+ *dst = FbDoMaskRRop(*dst, and, xor, startmask);
+ dst++;
+ }
+ n = nmiddle;
+ if (!and)
+ while (n--)
+ *dst++ = xor;
+ else
+ while (n--)
+ {
+ *dst = FbDoRRop (*dst, and, xor);
+ dst++;
+ }
+ if (endmask)
+ *dst = FbDoMaskRRop (*dst, and, xor, endmask);
+ dst += dstStride;
+ }
+}
+
+void
+fbOddStipple (FbBits *dst,
+ FbStride dstStride,
+ int dstX,
+ int dstBpp,
+
+ int width,
+ int height,
+
+ FbStip *stip,
+ FbStride stipStride,
+ int stipWidth,
+ int stipHeight,
+
+ FbBits fgand,
+ FbBits fgxor,
+ FbBits bgand,
+ FbBits bgxor,
+
+ int xRot,
+ int yRot)
+{
+ int stipX, stipY, sx;
+ int widthTmp;
+ int h, w;
+ int x, y;
+
+ modulus (- yRot, stipHeight, stipY);
+ modulus (dstX / dstBpp - xRot, stipWidth, stipX);
+ y = 0;
+ while (height)
+ {
+ h = stipHeight - stipY;
+ if (h > height)
+ h = height;
+ height -= h;
+ widthTmp = width;
+ x = dstX;
+ sx = stipX;
+ while (widthTmp)
+ {
+ w = (stipWidth - sx) * dstBpp;
+ if (w > widthTmp)
+ w = widthTmp;
+ widthTmp -= w;
+ fbBltOne (stip + stipY * stipStride,
+ stipStride,
+ sx,
+
+ dst + y * dstStride,
+ dstStride,
+ x,
+ dstBpp,
+
+ w, h,
+
+ fgand, fgxor, bgand, bgxor);
+ x += w;
+ sx = 0;
+ }
+ y += h;
+ stipY = 0;
+ }
+}
+
+void
+fbStipple (FbBits *dst,
+ FbStride dstStride,
+ int dstX,
+ int dstBpp,
+
+ int width,
+ int height,
+
+ FbStip *stip,
+ FbStride stipStride,
+ int stipWidth,
+ int stipHeight,
+
+ FbBits fgand,
+ FbBits fgxor,
+ FbBits bgand,
+ FbBits bgxor,
+
+ int xRot,
+ int yRot)
+{
+ if (FbEvenStip (stipWidth, dstBpp))
+ fbEvenStipple (dst, dstStride, dstX, dstBpp, width, height,
+ stip, stipHeight,
+ fgand, fgxor, bgand, bgxor, xRot, yRot);
+ else
+ fbOddStipple (dst, dstStride, dstX, dstBpp, width, height,
+ stip, stipStride, stipWidth, stipHeight,
+ fgand, fgxor, bgand, bgxor, xRot, yRot);
+}
diff --git a/xc/programs/Xserver/fb/fbtile.c b/xc/programs/Xserver/fb/fbtile.c
new file mode 100644
index 000000000..1a43b383d
--- /dev/null
+++ b/xc/programs/Xserver/fb/fbtile.c
@@ -0,0 +1,198 @@
+/*
+ * $Id: fbtile.c,v 1.1 2000/01/06 12:56:54 faith Exp $
+ *
+ * Copyright © 1998 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/fb/fbtile.c,v 1.1 1999/11/19 13:53:47 hohndel Exp $ */
+
+#include "fb.h"
+
+/*
+ * Accelerated tile fill -- tile width is a power of two not greater
+ * than FB_UNIT
+ */
+
+void
+fbEvenTile (FbBits *dst,
+ FbStride dstStride,
+ int dstX,
+
+ int width,
+ int height,
+
+ FbBits *tile,
+ int tileHeight,
+
+ int alu,
+ FbBits pm,
+ int xRot,
+ int yRot)
+{
+ FbBits *t, *tileEnd, bits;
+ FbBits startmask, endmask;
+ FbBits and, xor;
+ int n, nmiddle;
+ int tileX, tileY;
+ int rot;
+
+ dst += dstX >> FB_SHIFT;
+ dstX &= FB_MASK;
+ FbMaskBits(dstX, width, startmask, nmiddle, endmask);
+ if (startmask)
+ dstStride--;
+ dstStride -= nmiddle;
+
+ /*
+ * Compute tile start scanline and rotation parameters
+ */
+ tileEnd = tile + tileHeight;
+ modulus (- yRot, tileHeight, tileY);
+ t = tile + tileY;
+ modulus (- xRot, FB_UNIT, tileX);
+ rot = tileX;
+
+ while (height--)
+ {
+
+ /*
+ * Pick up bits for this scanline
+ */
+ bits = *t++;
+ if (t == tileEnd) t = tile;
+ bits = FbRotLeft(bits,rot);
+ and = fbAnd(alu,bits,pm);
+ xor = fbXor(alu,bits,pm);
+
+ if (startmask)
+ {
+ *dst = FbDoMaskRRop(*dst, and, xor, startmask);
+ dst++;
+ }
+ n = nmiddle;
+ if (!and)
+ while (n--)
+ *dst++ = xor;
+ else
+ while (n--)
+ {
+ *dst = FbDoRRop (*dst, and, xor);
+ dst++;
+ }
+ if (endmask)
+ *dst = FbDoMaskRRop (*dst, and, xor, endmask);
+ dst += dstStride;
+ }
+}
+
+void
+fbOddTile(FbBits *dst,
+ FbStride dstStride,
+ int dstX,
+
+ int width,
+ int height,
+
+ FbBits *tile,
+ FbStride tileStride,
+ int tileWidth,
+ int tileHeight,
+
+ int alu,
+ FbBits pm,
+ int bpp,
+
+ int xRot,
+ int yRot)
+{
+ int tileX, tileY;
+ int widthTmp;
+ int h, w;
+ int x, y;
+
+ modulus (- yRot, tileHeight, tileY);
+ y = 0;
+ while (height)
+ {
+ h = tileHeight - tileY;
+ if (h > height)
+ h = height;
+ height -= h;
+ widthTmp = width;
+ x = dstX;
+ modulus (dstX - xRot, tileWidth, tileX);
+ while (widthTmp)
+ {
+ w = tileWidth - tileX;
+ if (w > widthTmp)
+ w = widthTmp;
+ widthTmp -= w;
+ fbBlt (tile + tileY * tileStride,
+ tileStride,
+ tileX,
+
+ dst + y * dstStride,
+ dstStride,
+ x,
+
+ w, h,
+ alu,
+ pm,
+ bpp,
+
+ FALSE,
+ FALSE);
+ x += w;
+ tileX = 0;
+ }
+ y += h;
+ tileY = 0;
+ }
+}
+
+void
+fbTile (FbBits *dst,
+ FbStride dstStride,
+ int dstX,
+
+ int width,
+ int height,
+
+ FbBits *tile,
+ FbStride tileStride,
+ int tileWidth,
+ int tileHeight,
+
+ int alu,
+ FbBits pm,
+ int bpp,
+
+ int xRot,
+ int yRot)
+{
+ if (FbEvenTile (tileWidth))
+ fbEvenTile (dst, dstStride, dstX, width, height,
+ tile, tileHeight,
+ alu, pm, xRot, yRot);
+ else
+ fbOddTile (dst, dstStride, dstX, width, height,
+ tile, tileStride, tileWidth, tileHeight,
+ alu, pm, bpp, xRot, yRot);
+}
diff --git a/xc/programs/Xserver/fb/fbutil.c b/xc/programs/Xserver/fb/fbutil.c
new file mode 100644
index 000000000..60cd50f2f
--- /dev/null
+++ b/xc/programs/Xserver/fb/fbutil.c
@@ -0,0 +1,337 @@
+/*
+ * $Id: fbutil.c,v 1.1 2000/01/06 12:56:54 faith Exp $
+ *
+ * Copyright © 1998 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/fb/fbutil.c,v 1.1 1999/11/19 13:53:47 hohndel Exp $ */
+
+#include "fb.h"
+
+FbBits
+fbReplicatePixel (Pixel p, int bpp)
+{
+ FbBits b = p;
+
+ b &= FbFullMask (bpp);
+ while (bpp < FB_UNIT)
+ {
+ b |= b << bpp;
+ bpp <<= 1;
+ }
+ return b;
+}
+
+void
+fbReduceRasterOp (int rop, FbBits fg, FbBits pm, FbBits *andp, FbBits *xorp)
+{
+ FbBits and, xor;
+
+ switch (rop)
+ {
+ case GXclear: /* 0 0 0 0 */
+ and = 0;
+ xor = 0;
+ break;
+ case GXand: /* 0 0 0 1 */
+ and = fg;
+ xor = 0;
+ break;
+ case GXandReverse: /* 0 0 1 0 */
+ and = fg;
+ xor = fg;
+ break;
+ case GXcopy: /* 0 0 1 1 */
+ and = 0;
+ xor = fg;
+ break;
+ case GXandInverted: /* 0 1 0 0 */
+ and = ~fg;
+ xor = 0;
+ break;
+ case GXnoop: /* 0 1 0 1 */
+ and = FB_ALLONES;
+ xor = 0;
+ break;
+ case GXxor: /* 0 1 1 0 */
+ and = FB_ALLONES;
+ xor = fg;
+ break;
+ case GXor: /* 0 1 1 1 */
+ and = ~fg;
+ xor = fg;
+ break;
+ case GXnor: /* 1 0 0 0 */
+ and = ~fg;
+ xor = ~fg;
+ break;
+ case GXequiv: /* 1 0 0 1 */
+ and = FB_ALLONES;
+ xor = ~fg;
+ break;
+ case GXinvert: /* 1 0 1 0 */
+ and = FB_ALLONES;
+ xor = FB_ALLONES;
+ break;
+ case GXorReverse: /* 1 0 1 1 */
+ and = ~fg;
+ xor = FB_ALLONES;
+ break;
+ case GXcopyInverted: /* 1 1 0 0 */
+ and = 0;
+ xor = ~fg;
+ break;
+ case GXorInverted: /* 1 1 0 1 */
+ and = fg;
+ xor = ~fg;
+ break;
+ case GXnand: /* 1 1 1 0 */
+ and = fg;
+ xor = FB_ALLONES;
+ break;
+ case GXset: /* 1 1 1 1 */
+ and = 0;
+ xor = FB_ALLONES;
+ break;
+ }
+ and |= ~pm;
+ xor &= pm;
+ *andp = and;
+ *xorp = xor;
+}
+
+#define O 0
+#define I FB_ALLONES
+
+const FbMergeRopRec FbMergeRopBits[16] = {
+O,O,O,O, /* clear 0x0 0 */
+I,O,O,O, /* and 0x1 src AND dst */
+I,O,I,O, /* andReverse 0x2 src AND NOT dst */
+O,O,I,O, /* copy 0x3 src */
+I,I,O,O, /* andInverted 0x4 NOT src AND dst */
+O,I,O,O, /* noop 0x5 dst */
+O,I,I,O, /* xor 0x6 src XOR dst */
+I,I,I,O, /* or 0x7 src OR dst */
+I,I,I,I, /* nor 0x8 NOT src AND NOT dst */
+O,I,I,I, /* equiv 0x9 NOT src XOR dst */
+O,I,O,I, /* invert 0xa NOT dst */
+I,I,O,I, /* orReverse 0xb src OR NOT dst */
+O,O,I,I, /* copyInverted 0xc NOT src */
+I,O,I,I, /* orInverted 0xd NOT src OR dst */
+I,O,O,I, /* nand 0xe NOT src OR NOT dst */
+O,O,O,I, /* set 0xf 1 */
+};
+
+#define Mask(x,w) FbBitsMask((x)*(w),(w))
+
+#define SelMask(b,n,w) ((((b) >> n) & 1) * Mask(n,w))
+
+#define C1(b,w) \
+ (SelMask(b,0,w))
+
+#define C2(b,w) \
+ (SelMask(b,0,w) | \
+ SelMask(b,1,w))
+
+#define C4(b,w) \
+ (SelMask(b,0,w) | \
+ SelMask(b,1,w) | \
+ SelMask(b,2,w) | \
+ SelMask(b,3,w))
+
+#define C8(b,w) \
+ (SelMask(b,0,w) | \
+ SelMask(b,1,w) | \
+ SelMask(b,2,w) | \
+ SelMask(b,3,w) | \
+ SelMask(b,4,w) | \
+ SelMask(b,5,w) | \
+ SelMask(b,6,w) | \
+ SelMask(b,7,w))
+
+#if FB_UNIT == 32
+#define fbStipple16Bits 0
+const FbBits fbStipple8Bits[256] = {
+ C8( 0,4), C8( 1,4), C8( 2,4), C8( 3,4), C8( 4,4), C8( 5,4),
+ C8( 6,4), C8( 7,4), C8( 8,4), C8( 9,4), C8( 10,4), C8( 11,4),
+ C8( 12,4), C8( 13,4), C8( 14,4), C8( 15,4), C8( 16,4), C8( 17,4),
+ C8( 18,4), C8( 19,4), C8( 20,4), C8( 21,4), C8( 22,4), C8( 23,4),
+ C8( 24,4), C8( 25,4), C8( 26,4), C8( 27,4), C8( 28,4), C8( 29,4),
+ C8( 30,4), C8( 31,4), C8( 32,4), C8( 33,4), C8( 34,4), C8( 35,4),
+ C8( 36,4), C8( 37,4), C8( 38,4), C8( 39,4), C8( 40,4), C8( 41,4),
+ C8( 42,4), C8( 43,4), C8( 44,4), C8( 45,4), C8( 46,4), C8( 47,4),
+ C8( 48,4), C8( 49,4), C8( 50,4), C8( 51,4), C8( 52,4), C8( 53,4),
+ C8( 54,4), C8( 55,4), C8( 56,4), C8( 57,4), C8( 58,4), C8( 59,4),
+ C8( 60,4), C8( 61,4), C8( 62,4), C8( 63,4), C8( 64,4), C8( 65,4),
+ C8( 66,4), C8( 67,4), C8( 68,4), C8( 69,4), C8( 70,4), C8( 71,4),
+ C8( 72,4), C8( 73,4), C8( 74,4), C8( 75,4), C8( 76,4), C8( 77,4),
+ C8( 78,4), C8( 79,4), C8( 80,4), C8( 81,4), C8( 82,4), C8( 83,4),
+ C8( 84,4), C8( 85,4), C8( 86,4), C8( 87,4), C8( 88,4), C8( 89,4),
+ C8( 90,4), C8( 91,4), C8( 92,4), C8( 93,4), C8( 94,4), C8( 95,4),
+ C8( 96,4), C8( 97,4), C8( 98,4), C8( 99,4), C8(100,4), C8(101,4),
+ C8(102,4), C8(103,4), C8(104,4), C8(105,4), C8(106,4), C8(107,4),
+ C8(108,4), C8(109,4), C8(110,4), C8(111,4), C8(112,4), C8(113,4),
+ C8(114,4), C8(115,4), C8(116,4), C8(117,4), C8(118,4), C8(119,4),
+ C8(120,4), C8(121,4), C8(122,4), C8(123,4), C8(124,4), C8(125,4),
+ C8(126,4), C8(127,4), C8(128,4), C8(129,4), C8(130,4), C8(131,4),
+ C8(132,4), C8(133,4), C8(134,4), C8(135,4), C8(136,4), C8(137,4),
+ C8(138,4), C8(139,4), C8(140,4), C8(141,4), C8(142,4), C8(143,4),
+ C8(144,4), C8(145,4), C8(146,4), C8(147,4), C8(148,4), C8(149,4),
+ C8(150,4), C8(151,4), C8(152,4), C8(153,4), C8(154,4), C8(155,4),
+ C8(156,4), C8(157,4), C8(158,4), C8(159,4), C8(160,4), C8(161,4),
+ C8(162,4), C8(163,4), C8(164,4), C8(165,4), C8(166,4), C8(167,4),
+ C8(168,4), C8(169,4), C8(170,4), C8(171,4), C8(172,4), C8(173,4),
+ C8(174,4), C8(175,4), C8(176,4), C8(177,4), C8(178,4), C8(179,4),
+ C8(180,4), C8(181,4), C8(182,4), C8(183,4), C8(184,4), C8(185,4),
+ C8(186,4), C8(187,4), C8(188,4), C8(189,4), C8(190,4), C8(191,4),
+ C8(192,4), C8(193,4), C8(194,4), C8(195,4), C8(196,4), C8(197,4),
+ C8(198,4), C8(199,4), C8(200,4), C8(201,4), C8(202,4), C8(203,4),
+ C8(204,4), C8(205,4), C8(206,4), C8(207,4), C8(208,4), C8(209,4),
+ C8(210,4), C8(211,4), C8(212,4), C8(213,4), C8(214,4), C8(215,4),
+ C8(216,4), C8(217,4), C8(218,4), C8(219,4), C8(220,4), C8(221,4),
+ C8(222,4), C8(223,4), C8(224,4), C8(225,4), C8(226,4), C8(227,4),
+ C8(228,4), C8(229,4), C8(230,4), C8(231,4), C8(232,4), C8(233,4),
+ C8(234,4), C8(235,4), C8(236,4), C8(237,4), C8(238,4), C8(239,4),
+ C8(240,4), C8(241,4), C8(242,4), C8(243,4), C8(244,4), C8(245,4),
+ C8(246,4), C8(247,4), C8(248,4), C8(249,4), C8(250,4), C8(251,4),
+ C8(252,4), C8(253,4), C8(254,4), C8(255,4),
+};
+const FbBits fbStipple4Bits[16] = {
+ C4( 0,8), C4( 1,8), C4( 2,8), C4( 3,8), C4( 4,8), C4( 5,8),
+ C4( 6,8), C4( 7,8), C4( 8,8), C4( 9,8), C4( 10,8), C4( 11,8),
+ C4( 12,8), C4( 13,8), C4( 14,8), C4( 15,8),};
+const FbBits fbStipple2Bits[4] = {
+ C2( 0,16), C2( 1,16), C2( 2,16), C2( 3,16),
+};
+const FbBits fbStipple1Bits[2] = {
+ C1( 0,32), C1( 1,32),
+};
+#endif
+#if FB_UNIT == 64
+const FbBits fbStipple16Bits[256] = {
+ C8( 0,4), C8( 1,4), C8( 2,4), C8( 3,4), C8( 4,4), C8( 5,4),
+ C8( 6,4), C8( 7,4), C8( 8,4), C8( 9,4), C8( 10,4), C8( 11,4),
+ C8( 12,4), C8( 13,4), C8( 14,4), C8( 15,4), C8( 16,4), C8( 17,4),
+ C8( 18,4), C8( 19,4), C8( 20,4), C8( 21,4), C8( 22,4), C8( 23,4),
+ C8( 24,4), C8( 25,4), C8( 26,4), C8( 27,4), C8( 28,4), C8( 29,4),
+ C8( 30,4), C8( 31,4), C8( 32,4), C8( 33,4), C8( 34,4), C8( 35,4),
+ C8( 36,4), C8( 37,4), C8( 38,4), C8( 39,4), C8( 40,4), C8( 41,4),
+ C8( 42,4), C8( 43,4), C8( 44,4), C8( 45,4), C8( 46,4), C8( 47,4),
+ C8( 48,4), C8( 49,4), C8( 50,4), C8( 51,4), C8( 52,4), C8( 53,4),
+ C8( 54,4), C8( 55,4), C8( 56,4), C8( 57,4), C8( 58,4), C8( 59,4),
+ C8( 60,4), C8( 61,4), C8( 62,4), C8( 63,4), C8( 64,4), C8( 65,4),
+ C8( 66,4), C8( 67,4), C8( 68,4), C8( 69,4), C8( 70,4), C8( 71,4),
+ C8( 72,4), C8( 73,4), C8( 74,4), C8( 75,4), C8( 76,4), C8( 77,4),
+ C8( 78,4), C8( 79,4), C8( 80,4), C8( 81,4), C8( 82,4), C8( 83,4),
+ C8( 84,4), C8( 85,4), C8( 86,4), C8( 87,4), C8( 88,4), C8( 89,4),
+ C8( 90,4), C8( 91,4), C8( 92,4), C8( 93,4), C8( 94,4), C8( 95,4),
+ C8( 96,4), C8( 97,4), C8( 98,4), C8( 99,4), C8(100,4), C8(101,4),
+ C8(102,4), C8(103,4), C8(104,4), C8(105,4), C8(106,4), C8(107,4),
+ C8(108,4), C8(109,4), C8(110,4), C8(111,4), C8(112,4), C8(113,4),
+ C8(114,4), C8(115,4), C8(116,4), C8(117,4), C8(118,4), C8(119,4),
+ C8(120,4), C8(121,4), C8(122,4), C8(123,4), C8(124,4), C8(125,4),
+ C8(126,4), C8(127,4), C8(128,4), C8(129,4), C8(130,4), C8(131,4),
+ C8(132,4), C8(133,4), C8(134,4), C8(135,4), C8(136,4), C8(137,4),
+ C8(138,4), C8(139,4), C8(140,4), C8(141,4), C8(142,4), C8(143,4),
+ C8(144,4), C8(145,4), C8(146,4), C8(147,4), C8(148,4), C8(149,4),
+ C8(150,4), C8(151,4), C8(152,4), C8(153,4), C8(154,4), C8(155,4),
+ C8(156,4), C8(157,4), C8(158,4), C8(159,4), C8(160,4), C8(161,4),
+ C8(162,4), C8(163,4), C8(164,4), C8(165,4), C8(166,4), C8(167,4),
+ C8(168,4), C8(169,4), C8(170,4), C8(171,4), C8(172,4), C8(173,4),
+ C8(174,4), C8(175,4), C8(176,4), C8(177,4), C8(178,4), C8(179,4),
+ C8(180,4), C8(181,4), C8(182,4), C8(183,4), C8(184,4), C8(185,4),
+ C8(186,4), C8(187,4), C8(188,4), C8(189,4), C8(190,4), C8(191,4),
+ C8(192,4), C8(193,4), C8(194,4), C8(195,4), C8(196,4), C8(197,4),
+ C8(198,4), C8(199,4), C8(200,4), C8(201,4), C8(202,4), C8(203,4),
+ C8(204,4), C8(205,4), C8(206,4), C8(207,4), C8(208,4), C8(209,4),
+ C8(210,4), C8(211,4), C8(212,4), C8(213,4), C8(214,4), C8(215,4),
+ C8(216,4), C8(217,4), C8(218,4), C8(219,4), C8(220,4), C8(221,4),
+ C8(222,4), C8(223,4), C8(224,4), C8(225,4), C8(226,4), C8(227,4),
+ C8(228,4), C8(229,4), C8(230,4), C8(231,4), C8(232,4), C8(233,4),
+ C8(234,4), C8(235,4), C8(236,4), C8(237,4), C8(238,4), C8(239,4),
+ C8(240,4), C8(241,4), C8(242,4), C8(243,4), C8(244,4), C8(245,4),
+ C8(246,4), C8(247,4), C8(248,4), C8(249,4), C8(250,4), C8(251,4),
+ C8(252,4), C8(253,4), C8(254,4), C8(255,4),
+};
+const FbBits fbStipple8Bits[256] = {
+ C8( 0,8), C8( 1,8), C8( 2,8), C8( 3,8), C8( 4,8), C8( 5,8),
+ C8( 6,8), C8( 7,8), C8( 8,8), C8( 9,8), C8( 10,8), C8( 11,8),
+ C8( 12,8), C8( 13,8), C8( 14,8), C8( 15,8), C8( 16,8), C8( 17,8),
+ C8( 18,8), C8( 19,8), C8( 20,8), C8( 21,8), C8( 22,8), C8( 23,8),
+ C8( 24,8), C8( 25,8), C8( 26,8), C8( 27,8), C8( 28,8), C8( 29,8),
+ C8( 30,8), C8( 31,8), C8( 32,8), C8( 33,8), C8( 34,8), C8( 35,8),
+ C8( 36,8), C8( 37,8), C8( 38,8), C8( 39,8), C8( 40,8), C8( 41,8),
+ C8( 42,8), C8( 43,8), C8( 44,8), C8( 45,8), C8( 46,8), C8( 47,8),
+ C8( 48,8), C8( 49,8), C8( 50,8), C8( 51,8), C8( 52,8), C8( 53,8),
+ C8( 54,8), C8( 55,8), C8( 56,8), C8( 57,8), C8( 58,8), C8( 59,8),
+ C8( 60,8), C8( 61,8), C8( 62,8), C8( 63,8), C8( 64,8), C8( 65,8),
+ C8( 66,8), C8( 67,8), C8( 68,8), C8( 69,8), C8( 70,8), C8( 71,8),
+ C8( 72,8), C8( 73,8), C8( 74,8), C8( 75,8), C8( 76,8), C8( 77,8),
+ C8( 78,8), C8( 79,8), C8( 80,8), C8( 81,8), C8( 82,8), C8( 83,8),
+ C8( 84,8), C8( 85,8), C8( 86,8), C8( 87,8), C8( 88,8), C8( 89,8),
+ C8( 90,8), C8( 91,8), C8( 92,8), C8( 93,8), C8( 94,8), C8( 95,8),
+ C8( 96,8), C8( 97,8), C8( 98,8), C8( 99,8), C8(100,8), C8(101,8),
+ C8(102,8), C8(103,8), C8(104,8), C8(105,8), C8(106,8), C8(107,8),
+ C8(108,8), C8(109,8), C8(110,8), C8(111,8), C8(112,8), C8(113,8),
+ C8(114,8), C8(115,8), C8(116,8), C8(117,8), C8(118,8), C8(119,8),
+ C8(120,8), C8(121,8), C8(122,8), C8(123,8), C8(124,8), C8(125,8),
+ C8(126,8), C8(127,8), C8(128,8), C8(129,8), C8(130,8), C8(131,8),
+ C8(132,8), C8(133,8), C8(134,8), C8(135,8), C8(136,8), C8(137,8),
+ C8(138,8), C8(139,8), C8(140,8), C8(141,8), C8(142,8), C8(143,8),
+ C8(144,8), C8(145,8), C8(146,8), C8(147,8), C8(148,8), C8(149,8),
+ C8(150,8), C8(151,8), C8(152,8), C8(153,8), C8(154,8), C8(155,8),
+ C8(156,8), C8(157,8), C8(158,8), C8(159,8), C8(160,8), C8(161,8),
+ C8(162,8), C8(163,8), C8(164,8), C8(165,8), C8(166,8), C8(167,8),
+ C8(168,8), C8(169,8), C8(170,8), C8(171,8), C8(172,8), C8(173,8),
+ C8(174,8), C8(175,8), C8(176,8), C8(177,8), C8(178,8), C8(179,8),
+ C8(180,8), C8(181,8), C8(182,8), C8(183,8), C8(184,8), C8(185,8),
+ C8(186,8), C8(187,8), C8(188,8), C8(189,8), C8(190,8), C8(191,8),
+ C8(192,8), C8(193,8), C8(194,8), C8(195,8), C8(196,8), C8(197,8),
+ C8(198,8), C8(199,8), C8(200,8), C8(201,8), C8(202,8), C8(203,8),
+ C8(204,8), C8(205,8), C8(206,8), C8(207,8), C8(208,8), C8(209,8),
+ C8(210,8), C8(211,8), C8(212,8), C8(213,8), C8(214,8), C8(215,8),
+ C8(216,8), C8(217,8), C8(218,8), C8(219,8), C8(220,8), C8(221,8),
+ C8(222,8), C8(223,8), C8(224,8), C8(225,8), C8(226,8), C8(227,8),
+ C8(228,8), C8(229,8), C8(230,8), C8(231,8), C8(232,8), C8(233,8),
+ C8(234,8), C8(235,8), C8(236,8), C8(237,8), C8(238,8), C8(239,8),
+ C8(240,8), C8(241,8), C8(242,8), C8(243,8), C8(244,8), C8(245,8),
+ C8(246,8), C8(247,8), C8(248,8), C8(249,8), C8(250,8), C8(251,8),
+ C8(252,8), C8(253,8), C8(254,8), C8(255,8),
+};
+const FbBits fbStipple4Bits[16] = {
+ C4( 0,16), C4( 1,16), C4( 2,16), C4( 3,16), C4( 4,16), C4( 5,16),
+ C4( 6,16), C4( 7,16), C4( 8,16), C4( 9,16), C4( 10,16), C4( 11,16),
+ C4( 12,16), C4( 13,16), C4( 14,16), C4( 15,16),};
+const FbBits fbStipple2Bits[4] = {
+ C2( 0,32), C2( 1,32), C2( 2,32), C2( 3,32),
+};
+#define fbStipple1Bits 0
+#endif
+const FbBits * const fbStippleTable[] = {
+ 0,
+ fbStipple1Bits,
+ fbStipple2Bits,
+ 0,
+ fbStipple4Bits,
+ 0,
+ 0,
+ 0,
+ fbStipple8Bits,
+};
diff --git a/xc/programs/Xserver/fb/fbwindow.c b/xc/programs/Xserver/fb/fbwindow.c
new file mode 100644
index 000000000..b7f8efbb7
--- /dev/null
+++ b/xc/programs/Xserver/fb/fbwindow.c
@@ -0,0 +1,284 @@
+/*
+ * $Id: fbwindow.c,v 1.1 2000/01/06 12:56:54 faith Exp $
+ *
+ * Copyright © 1998 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/fb/fbwindow.c,v 1.1 1999/11/19 13:53:47 hohndel Exp $ */
+
+#include "fb.h"
+
+Bool
+fbCreateWindow(WindowPtr pWin)
+{
+ return TRUE;
+}
+
+Bool
+fbDestroyWindow(WindowPtr pWin)
+{
+ return TRUE;
+}
+
+Bool
+fbMapWindow(WindowPtr pWindow)
+{
+ return TRUE;
+}
+
+Bool
+fbPositionWindow(WindowPtr pWin, int x, int y)
+{
+ return TRUE;
+}
+
+Bool
+fbUnmapWindow(WindowPtr pWindow)
+{
+ return TRUE;
+}
+
+extern WindowPtr *WindowTable;
+
+void
+fbCopyWindowProc (DrawablePtr pSrcDrawable,
+ DrawablePtr pDstDrawable,
+ GCPtr pGC,
+ BoxPtr pbox,
+ int nbox,
+ int dx,
+ int dy,
+ Bool reverse,
+ Bool upsidedown,
+ Pixel bitplane,
+ void *closure)
+{
+ FbBits *src;
+ FbStride srcStride;
+ int srcBpp;
+ FbBits *dst;
+ FbStride dstStride;
+ int dstBpp;
+
+ fbGetDrawable (pSrcDrawable, src, srcStride, srcBpp);
+ fbGetDrawable (pDstDrawable, dst, dstStride, dstBpp);
+
+ while (nbox--)
+ {
+ fbBlt (src + (pbox->y1 + dy) * srcStride,
+ srcStride,
+ (pbox->x1 + dx) * srcBpp,
+
+ dst + (pbox->y1) * dstStride,
+ dstStride,
+ (pbox->x1) * dstBpp,
+
+ (pbox->x2 - pbox->x1) * dstBpp,
+ (pbox->y2 - pbox->y1),
+
+ GXcopy,
+ FB_ALLONES,
+ dstBpp,
+
+ reverse,
+ upsidedown);
+ pbox++;
+ }
+}
+
+void
+fbCopyWindow(WindowPtr pWin,
+ DDXPointRec ptOldOrg,
+ RegionPtr prgnSrc)
+{
+ ScreenPtr pScreen = pWin->drawable.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, fbCopyWindowProc, 0, 0);
+
+ REGION_UNINIT(pWin->drawable.pScreen, &rgnDst);
+ fbValidateDrawable (&pWin->drawable);
+}
+
+Bool
+fbChangeWindowAttributes(WindowPtr pWin, unsigned long mask)
+{
+ PixmapPtr pPixmap;
+
+ if (mask & CWBackPixmap)
+ {
+ if (pWin->backgroundState == BackgroundPixmap)
+ {
+ pPixmap = pWin->background.pixmap;
+ if (FbEvenTile (pPixmap->drawable.width *
+ pPixmap->drawable.bitsPerPixel))
+ fbPadPixmap (pPixmap);
+ }
+ }
+ if (mask & CWBorderPixmap)
+ {
+ if (pWin->borderIsPixel == FALSE)
+ {
+ pPixmap = pWin->border.pixmap;
+ if (FbEvenTile (pPixmap->drawable.width *
+ pPixmap->drawable.bitsPerPixel))
+ fbPadPixmap (pPixmap);
+ }
+ }
+ return TRUE;
+}
+
+void
+fbFillRegionSolid (DrawablePtr pDrawable,
+ RegionPtr pRegion,
+ FbBits and,
+ FbBits xor)
+{
+ FbBits *dst;
+ FbStride dstStride;
+ int dstBpp;
+ int n = REGION_NUM_RECTS(pRegion);
+ BoxPtr pbox = REGION_RECTS(pRegion);
+
+ fbGetDrawable (pDrawable, dst, dstStride, dstBpp);
+
+ while (n--)
+ {
+ fbSolid (dst + pbox->y1 * dstStride,
+ dstStride,
+ pbox->x1 * dstBpp,
+ dstBpp,
+ (pbox->x2 - pbox->x1) * dstBpp,
+ pbox->y2 - pbox->y1,
+ and, xor);
+ fbValidateDrawable (pDrawable);
+ pbox++;
+ }
+}
+
+void
+fbFillRegionTiled (DrawablePtr pDrawable,
+ RegionPtr pRegion,
+ PixmapPtr pTile)
+{
+ FbBits *dst;
+ FbStride dstStride;
+ int dstBpp;
+ FbBits *tile;
+ FbStride tileStride;
+ int tileBpp;
+ int tileWidth, tileHeight;
+ int n = REGION_NUM_RECTS(pRegion);
+ BoxPtr pbox = REGION_RECTS(pRegion);
+
+ fbGetDrawable (pDrawable, dst, dstStride, dstBpp);
+ fbGetDrawable (&pTile->drawable, tile, tileStride, tileBpp);
+ tileWidth = pTile->drawable.width;
+ tileHeight = pTile->drawable.height;
+
+ while (n--)
+ {
+ fbTile (dst + pbox->y1 * dstStride,
+ dstStride,
+ pbox->x1 * dstBpp,
+ (pbox->x2 - pbox->x1) * dstBpp,
+ pbox->y2 - pbox->y1,
+ tile,
+ tileStride,
+ tileWidth * dstBpp,
+ tileHeight,
+ GXcopy,
+ FB_ALLONES,
+ dstBpp,
+ pDrawable->x * dstBpp,
+ pDrawable->y - pbox->y1);
+ pbox++;
+ }
+}
+
+void
+fbPaintWindow(WindowPtr pWin, RegionPtr pRegion, int what)
+{
+ int n;
+ WindowPtr pBgWin;
+
+ switch (what) {
+ case PW_BACKGROUND:
+ switch (pWin->backgroundState) {
+ case None:
+ break;
+ case ParentRelative:
+ do {
+ pWin = pWin->parent;
+ } while (pWin->backgroundState == ParentRelative);
+ (*pWin->drawable.pScreen->PaintWindowBackground)(pWin, pRegion,
+ what);
+ break;
+ case BackgroundPixmap:
+ fbFillRegionTiled (&pWin->drawable,
+ pRegion,
+ pWin->background.pixmap);
+ break;
+ case BackgroundPixel:
+ fbFillRegionSolid (&pWin->drawable,
+ pRegion,
+ 0,
+ fbReplicatePixel (pWin->background.pixel,
+ pWin->drawable.bitsPerPixel));
+ break;
+ }
+ break;
+ case PW_BORDER:
+ if (pWin->borderIsPixel)
+ {
+ fbFillRegionSolid (&pWin->drawable,
+ pRegion,
+ 0,
+ fbReplicatePixel (pWin->border.pixel,
+ pWin->drawable.bitsPerPixel));
+ }
+ else
+ {
+ for (pBgWin = pWin;
+ pBgWin->backgroundState == ParentRelative;
+ pBgWin = pBgWin->parent);
+
+ fbFillRegionTiled (&pBgWin->drawable,
+ pRegion,
+ pWin->border.pixmap);
+ }
+ break;
+ }
+ fbValidateDrawable (&pWin->drawable);
+}
diff --git a/xc/programs/Xserver/hw/kdrive/Imakefile b/xc/programs/Xserver/hw/kdrive/Imakefile
new file mode 100644
index 000000000..0f3229e68
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/Imakefile
@@ -0,0 +1,20 @@
+XCOMM $XConsortium: Imakefile /main/10 1996/12/02 10:20:33 lehors $
+XCOMM $XFree86: xc/programs/Xserver/hw/kdrive/Imakefile,v 1.2 1999/12/30 03:03:05 robin Exp $
+#include <Server.tmpl>
+
+SRCS = kcmap.c kcolor.c kdrive.c kinfo.c kinput.c kmap.c knoop.c ktest.c \
+ vga.c kasync.c kmode.c kcurscol.c
+
+OBJS = kcmap.o kcolor.o kdrive.o kinfo.o kinput.o kmap.o knoop.o ktest.o \
+ vga.o kasync.o kmode.o kcurscol.o
+
+INCLUDES = -I. -I$(XBUILDINCDIR) -I$(FONTINCSRC) \
+ -I../../fb -I../../mi -I../../include -I../../os \
+ -I$(EXTINCSRC) -I$(XINCLUDESRC)
+
+NormalLibraryObjectRule()
+NormalLibraryTarget(kdrive,$(OBJS))
+
+SpecialCObjectRule(kdrive,,$(EXT_DEFINES))
+
+DependTarget()
diff --git a/xc/programs/Xserver/hw/kdrive/fbdev/Imakefile b/xc/programs/Xserver/hw/kdrive/fbdev/Imakefile
new file mode 100644
index 000000000..7746abbbd
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/fbdev/Imakefile
@@ -0,0 +1,15 @@
+XCOMM $XConsortium: Imakefile /main/10 1996/12/02 10:20:33 lehors $
+XCOMM $XFree86: xc/programs/Xserver/hw/kdrive/fbdev/Imakefile,v 1.1 1999/11/19 13:53:52 hohndel Exp $
+#include <Server.tmpl>
+
+SRCS = fbdev.c fbinit.c
+
+OBJS = fbdev.o fbinit.o
+
+INCLUDES = -I.. -I. -I$(XBUILDINCDIR) -I$(FONTINCSRC) \
+ -I../../../fb -I../../../mi -I../../../include -I../../../os \
+ -I$(EXTINCSRC) -I$(XINCLUDESRC)
+
+NormalLibraryObjectRule()
+NormalLibraryTarget(fbdev,$(OBJS))
+DependTarget()
diff --git a/xc/programs/Xserver/hw/kdrive/fbdev/fbdev.c b/xc/programs/Xserver/hw/kdrive/fbdev/fbdev.c
new file mode 100644
index 000000000..67a48c302
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/fbdev/fbdev.c
@@ -0,0 +1,264 @@
+/*
+ * $Id: fbdev.c,v 1.1 2000/01/06 12:55:48 faith 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/fbdev/fbdev.c,v 1.2 1999/12/30 03:03:08 robin Exp $ */
+
+#include "fbdev.h"
+
+Bool
+fbdevInitialize (KdCardInfo *card, FbdevPriv *priv)
+{
+ int k;
+ if ((priv->fd = open("/dev/fb0", O_RDWR)) < 0) {
+ perror("Error opening /dev/fb0\n");
+ return FALSE;
+ }
+ if ((k=ioctl(priv->fd, FBIOGET_FSCREENINFO, &priv->fix)) < 0) {
+ perror("Error with /dev/fb ioctl FIOGET_FSCREENINFO");
+ close (priv->fd);
+ return FALSE;
+ }
+ if ((k=ioctl(priv->fd, FBIOGET_VSCREENINFO, &priv->var)) < 0) {
+ perror("Error with /dev/fb ioctl FIOGET_VSCREENINFO");
+ close (priv->fd);
+ return FALSE;
+ }
+
+ priv->fb = (unsigned char *) mmap ((caddr_t) NULL,
+ priv->fix.smem_len,
+ PROT_READ|PROT_WRITE,
+ MAP_SHARED,
+ priv->fd, 0);
+
+ if (priv->fb == (char *)-1)
+ {
+ perror("ERROR: mmap framebuffer fails!");
+ close (priv->fd);
+ return FALSE;
+ }
+}
+
+Bool
+fbdevCardInit (KdCardInfo *card)
+{
+ int k;
+ char *pixels;
+ FbdevPriv *priv;
+
+ priv = (FbdevPriv *) xalloc (sizeof (FbdevPriv));
+ if (!priv)
+ return FALSE;
+
+ if (!fbdevInitialize (card, priv))
+ {
+ xfree (priv);
+ return FALSE;
+ }
+ card->driver = priv;
+
+ return TRUE;
+}
+
+Bool
+fbdevScreenInit (KdScreenInfo *screen)
+{
+ FbdevPriv *priv = screen->card->driver;
+ Pixel allbits;
+ int depth;
+
+ screen->width = priv->var.xres;
+ screen->height = priv->var.yres;
+ screen->depth = priv->var.bits_per_pixel;
+ screen->bitsPerPixel = priv->var.bits_per_pixel;
+ screen->byteStride = priv->fix.line_length;
+ screen->pixelStride = (priv->fix.line_length * 8 /
+ priv->var.bits_per_pixel);
+ switch (priv->fix.visual) {
+ case FB_VISUAL_PSEUDOCOLOR:
+ screen->visuals = ((1 << StaticGray) |
+ (1 << GrayScale) |
+ (1 << StaticColor) |
+ (1 << PseudoColor) |
+ (1 << TrueColor) |
+ (1 << DirectColor));
+ screen->blueMask = 0x00;
+ screen->greenMask = 0x00;
+ screen->redMask = 0x00;
+ break;
+ case FB_VISUAL_TRUECOLOR:
+ screen->visuals = (1 << TrueColor);
+ screen->redMask = FbStipMask (priv->var.red.offset, priv->var.red.length);
+ screen->greenMask = FbStipMask (priv->var.green.offset, priv->var.green.length);
+ screen->blueMask = FbStipMask (priv->var.blue.offset, priv->var.blue.length);
+ allbits = screen->redMask | screen->greenMask | screen->blueMask;
+ depth = 32;
+ while (depth && !(allbits & (1 << (depth - 1))))
+ depth--;
+ screen->depth = depth;
+ break;
+ default:
+ return FALSE;
+ break;
+ }
+ screen->rate = 72;
+ screen->frameBuffer = (CARD8 *) (priv->fb);
+ return TRUE;
+}
+
+Bool
+fbdevInitScreen (ScreenPtr pScreen)
+{
+ return TRUE;
+}
+
+void
+fbdevPreserve (KdCardInfo *card)
+{
+}
+
+void
+fbdevEnable (ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ FbdevPriv *priv = pScreenPriv->card->driver;
+ int k;
+
+ priv->var.activate = FB_ACTIVATE_NOW|FB_CHANGE_CMAP_VBL;
+
+ /* display it on the LCD */
+ k = ioctl (priv->fd, FBIOPUT_VSCREENINFO, &priv->var);
+ if (k < 0)
+ perror ("FBIOPUT_VSCREENINFO");
+}
+
+Bool
+fbdevDPMS (ScreenPtr pScreen, int mode)
+{
+ KdScreenPriv(pScreen);
+ FbdevPriv *priv = pScreenPriv->card->driver;
+
+#ifdef FBIOPUT_POWERMODE
+ if (!ioctl (priv->fd, FBIOPUT_POWERMODE, &mode))
+ return TRUE;
+#endif
+ return FALSE;
+}
+
+void
+fbdevDisable (ScreenPtr pScreen)
+{
+}
+
+void
+fbdevRestore (KdCardInfo *card)
+{
+}
+
+void
+fbdevScreenFini (KdScreenInfo *screen)
+{
+}
+
+void
+fbdevCardFini (KdCardInfo *card)
+{
+ int k;
+ FbdevPriv *priv = card->driver;
+
+ munmap (priv->fb, priv->fix.smem_len);
+ close (priv->fd);
+ xfree (priv);
+}
+
+void
+fbdevGetColors (ScreenPtr pScreen, int n, xColorItem *pdefs)
+{
+ KdScreenPriv(pScreen);
+ FbdevPriv *priv = pScreenPriv->card->driver;
+ struct fb_cmap cmap;
+ int p;
+ int k;
+ int min, max;
+
+ min = 256;
+ max = 0;
+ for (k = 0; k < n; k++)
+ {
+ if (pdefs[k].pixel < min)
+ min = pdefs[k].pixel;
+ if (pdefs[k].pixel > max)
+ max = pdefs[k].pixel;
+ }
+ cmap.start = min;
+ cmap.len = max - min + 1;
+ cmap.red = &priv->red[min];
+ cmap.green = &priv->green[min];;
+ cmap.blue = &priv->blue[min];
+ cmap.transp = 0;
+ k = ioctl (priv->fd, FBIOGETCMAP, &cmap);
+ if (k < 0)
+ {
+ perror ("can't get colormap");
+ return;
+ }
+ while (n--)
+ {
+ p = pdefs->pixel;
+ pdefs->red = priv->red[p];
+ pdefs->green = priv->green[p];
+ pdefs->blue = priv->blue[p];
+ pdefs++;
+ }
+}
+
+void
+fbdevPutColors (ScreenPtr pScreen, int n, xColorItem *pdefs)
+{
+ KdScreenPriv(pScreen);
+ FbdevPriv *priv = pScreenPriv->card->driver;
+ struct fb_cmap cmap;
+ int p;
+ int min, max;
+
+ min = 256;
+ max = 0;
+ while (n--)
+ {
+ p = pdefs->pixel;
+ priv->red[p] = pdefs->red;
+ priv->green[p] = pdefs->green;
+ priv->blue[p] = pdefs->blue;
+ if (p < min)
+ min = p;
+ if (p > max)
+ max = p;
+ pdefs++;
+ }
+ cmap.start = min;
+ cmap.len = max - min + 1;
+ cmap.red = &priv->red[min];
+ cmap.green = &priv->green[min];
+ cmap.blue = &priv->blue[min];
+ cmap.transp = 0;
+ ioctl (priv->fd, FBIOPUTCMAP, &cmap);
+}
diff --git a/xc/programs/Xserver/hw/kdrive/fbdev/fbdev.h b/xc/programs/Xserver/hw/kdrive/fbdev/fbdev.h
new file mode 100644
index 000000000..889a8be00
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/fbdev/fbdev.h
@@ -0,0 +1,84 @@
+/*
+ * $Id: fbdev.h,v 1.1 2000/01/06 12:55:48 faith 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/fbdev/fbdev.h,v 1.2 1999/12/30 03:03:08 robin Exp $ */
+
+#ifndef _FBDEV_H_
+#define _FBDEV_H_
+#include "kdrive.h"
+#include <stdio.h>
+#include <linux/fb.h>
+#include <unistd.h>
+#include <sys/mman.h>
+
+typedef struct _fbdevPriv {
+ struct fb_var_screeninfo var;
+ struct fb_fix_screeninfo fix;
+ __u16 red[256];
+ __u16 green[256];
+ __u16 blue[256];
+ int fd;
+ char *fb;
+} FbdevPriv;
+
+Bool
+fbdevInitialize (KdCardInfo *card, FbdevPriv *priv);
+
+Bool
+fbdevCardInit (KdCardInfo *card);
+
+Bool
+fbdevScreenInit (KdScreenInfo *screen);
+
+Bool
+fbdevInitScreen (ScreenPtr pScreen);
+
+void
+fbdevPreserve (KdCardInfo *card);
+
+void
+fbdevEnable (ScreenPtr pScreen);
+
+Bool
+fbdevDPMS (ScreenPtr pScreen, int mode);
+
+void
+fbdevDisable (ScreenPtr pScreen);
+
+void
+fbdevRestore (KdCardInfo *card);
+
+void
+fbdevScreenFini (KdScreenInfo *screen);
+
+void
+fbdevCardFini (KdCardInfo *card);
+
+void
+fbdevGetColors (ScreenPtr pScreen, int n, xColorItem *pdefs);
+
+void
+fbdevPutColors (ScreenPtr pScreen, int n, xColorItem *pdefs);
+
+
+#endif /* _FBDEV_H_ */
diff --git a/xc/programs/Xserver/hw/kdrive/fbdev/fbinit.c b/xc/programs/Xserver/hw/kdrive/fbdev/fbinit.c
new file mode 100644
index 000000000..5f5ac67eb
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/fbdev/fbinit.c
@@ -0,0 +1,80 @@
+/*
+ * $Id: fbinit.c,v 1.1 2000/01/06 12:55:48 faith 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/fbdev/fbinit.c,v 1.2 1999/12/30 03:03:08 robin Exp $ */
+
+#include <fbdev.h>
+
+KdCardFuncs fbdevFuncs = {
+ fbdevCardInit, /* cardinit */
+ fbdevScreenInit, /* scrinit */
+ fbdevInitScreen, /* initScreen */
+ fbdevPreserve, /* preserve */
+ fbdevEnable, /* enable */
+ fbdevDPMS, /* dpms */
+ fbdevDisable, /* disable */
+ fbdevRestore, /* restore */
+ fbdevScreenFini, /* scrfini */
+ fbdevCardFini, /* cardfini */
+
+ 0, /* initCursor */
+ 0, /* enableCursor */
+ 0, /* disableCursor */
+ 0, /* finiCursor */
+ 0, /* recolorCursor */
+
+ 0, /* initAccel */
+ 0, /* enableAccel */
+ 0, /* syncAccel */
+ 0, /* disableAccel */
+ 0, /* finiAccel */
+
+ fbdevGetColors, /* getColors */
+ fbdevPutColors, /* putColors */
+};
+
+void
+InitCard (char *name)
+{
+ KdCardAttr attr;
+
+ KdCardInfoAdd (&fbdevFuncs, &attr, 0);
+}
+
+void
+InitOutput (ScreenInfo *pScreenInfo, int argc, char **argv)
+{
+ KdInitOutput (pScreenInfo, argc, argv);
+}
+
+void
+InitInput (int argc, char **argv)
+{
+ KdInitInput (&Ps2MouseFuncs, &LinuxKeyboardFuncs);
+}
+
+int
+ddxProcessArgument (int argc, char **argv, int i)
+{
+ return KdProcessArgument (argc, argv, i);
+}
diff --git a/xc/programs/Xserver/hw/kdrive/itsy/Imakefile b/xc/programs/Xserver/hw/kdrive/itsy/Imakefile
new file mode 100644
index 000000000..f121a7d9d
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/itsy/Imakefile
@@ -0,0 +1,15 @@
+XCOMM $XConsortium: Imakefile /main/10 1996/12/02 10:20:33 lehors $
+XCOMM $XFree86: xc/programs/Xserver/hw/kdrive/itsy/Imakefile,v 1.1 1999/11/19 13:53:53 hohndel Exp $
+#include <Server.tmpl>
+
+SRCS = itsy.c ts.c kbd.c
+
+OBJS = itsy.o ts.o kbd.o
+
+INCLUDES = -I.. -I. -I$(XBUILDINCDIR) -I$(FONTINCSRC) \
+ -I../../../fb -I../../../mi -I../../../include -I../../../os \
+ -I$(EXTINCSRC) -I$(XINCLUDESRC)
+
+NormalLibraryObjectRule()
+NormalLibraryTarget(itsy,$(OBJS))
+DependTarget()
diff --git a/xc/programs/Xserver/hw/kdrive/itsy/itsy.c b/xc/programs/Xserver/hw/kdrive/itsy/itsy.c
new file mode 100644
index 000000000..5b3343898
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/itsy/itsy.c
@@ -0,0 +1,318 @@
+/*
+ * $Id: itsy.c,v 1.1 2000/01/06 12:55:48 faith 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/itsy/itsy.c,v 1.2 1999/12/30 03:03:09 robin Exp $ */
+
+#include "itsy.h"
+
+/* struct with LCD characteristics defined in fb_brutus.h */
+static struct FbLcdParamsStruct fbLcdParams;
+static int fb_d;
+static int fbn;
+Bool
+itsyCardInit (KdCardInfo *card)
+{
+ int k;
+ char *fb;
+ char *pixels;
+
+ if ((fb_d = open("/dev/fbclone", O_RDWR)) < 0) {
+ perror("Error opening /dev/fb\n");
+ return FALSE;
+ }
+ if ((k=ioctl(fb_d, FB_LCD_PARAMS, &fbLcdParams)) != 0) {
+ perror("Error with /dev/fb ioctl FB_LCD_PARAMS call");
+ return FALSE;
+ }
+
+ fb = (char *) mmap ((caddr_t) NULL, fbLcdParams.frameBufferSize,
+ PROT_READ|PROT_WRITE, MAP_FILE|MAP_SHARED, fb_d, 0);
+
+ fprintf (stderr, "fb mapped at 0x%x\n", fb);
+ if (fb == (char *)-1) {
+ perror("ERROR: mmap framebuffer fails!");
+ return FALSE;
+ }
+
+ card->driver = fb;
+
+ return TRUE;
+}
+
+Bool
+itsyScreenInit (KdScreenInfo *screen)
+{
+ CARD8 *fb = screen->card->driver;
+
+ screen->width = fbLcdParams.screenSizeH;
+ screen->height = fbLcdParams.screenSizeV;
+ screen->depth = fbLcdParams.bitsPerPixel;
+ screen->bitsPerPixel = fbLcdParams.bitsPerPixel;
+ screen->byteStride = fbLcdParams.frameBufferSizeH;
+ screen->pixelStride = (fbLcdParams.frameBufferSizeH * 8 /
+ fbLcdParams.bitsPerPixel);
+ fprintf (stderr, "width %d height %d depth %d pstride %d bstride %d\n",
+ screen->width, screen->height, screen->depth,
+ screen->pixelStride, screen->byteStride);
+ screen->dumb = FALSE;
+ screen->softCursor = TRUE;
+ screen->blueMask = 0;
+ screen->greenMask = 0;
+ screen->redMask = 0;
+ screen->visuals = 1 << StaticGray;
+ screen->rate = 72;
+ screen->frameBuffer = (CARD8 *) (fb +
+ fbLcdParams.pixelDataOffset +
+ (fbLcdParams.reserveTopRows *
+ screen->byteStride));
+ fprintf (stderr, "Frame buffer 0x%x\n", screen->frameBuffer);
+ return TRUE;
+}
+
+static unsigned short itsyIntensity[16] = {
+ 0xffff,
+ 0xffff,
+ 0xedb6,
+ 0xdb6d,
+ 0xc924,
+ 0xb6db,
+ 0xa492,
+ 0x9249,
+ 0x8000,
+ 0x6db6,
+ 0x5b6d,
+ 0x4924,
+ 0x36db,
+ 0x2492,
+ 0x1249,
+ 0x0000,
+};
+
+Bool
+itsyCreateColormap (ColormapPtr pmap)
+{
+ int i;
+
+ for (i = 0; i < 16; i++)
+ {
+ pmap->red[i].co.local.red = itsyIntensity[i];
+ pmap->red[i].co.local.green = itsyIntensity[i];
+ pmap->red[i].co.local.blue = itsyIntensity[i];
+ }
+ return TRUE;
+}
+
+Bool
+itsyInitScreen (ScreenPtr pScreen)
+{
+ pScreen->CreateColormap = itsyCreateColormap;
+ return TRUE;
+}
+
+void
+itsyPreserve (KdCardInfo *card)
+{
+}
+
+void
+itsyEnable (ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+
+ fprintf (stderr, "Enabling LCD display\n");
+ /* display it on the LCD */
+ ioctl(fb_d, FB_LCD_SHOW, 0);
+}
+
+Bool
+itsyDPMS (ScreenPtr pScreen, int mode)
+{
+ if (mode)
+ ioctl (fb_d, FB_LCD_OFF, 0);
+ else
+ ioctl (fb_d, FB_LCD_ON, 0);
+ return TRUE;
+}
+
+void
+itsyDisable (ScreenPtr pScreen)
+{
+/* ioctl (fb_d, FB_LCD_SWITCH, 0); */
+/* fprintf (stderr, "Disabling LCD display\n");*/
+}
+
+void
+itsyRestore (KdCardInfo *card)
+{
+}
+
+void
+itsyScreenFini (KdScreenInfo *screen)
+{
+}
+
+void
+itsyCardFini (KdCardInfo *card)
+{
+ int k;
+
+ fprintf (stderr, "Unmapping driver at 0x%x\n", card->driver);
+ munmap (card->driver, fbLcdParams.frameBufferSize);
+ fprintf (stderr, "Releasing fbn %d\n", fbn);
+ /* release it */
+ if (ioctl(fb_d, FB_LCD_FREE, fbn) != 0) {
+ printf("FB_LCD_FREE of %d fails!\n", fbn);
+ }
+ close (fb_d);
+ fprintf (stderr, "itsyFini done\n");
+}
+
+KdCardFuncs itsyFuncs = {
+ itsyCardInit, /* cardinit */
+ itsyScreenInit, /* scrinit */
+ itsyInitScreen, /* initScreen */
+ itsyPreserve, /* preserve */
+ itsyEnable, /* enable */
+ itsyDPMS, /* dpms */
+ itsyDisable, /* disable */
+ itsyRestore, /* restore */
+ itsyScreenFini, /* scrfini */
+ itsyCardFini, /* cardfini */
+
+ 0, /* initCursor */
+ 0, /* enableCursor */
+ 0, /* disableCursor */
+ 0, /* finiCursor */
+ 0, /* recolorCursor */
+
+ 0, /* initAccel */
+ 0, /* enableAccel */
+ 0, /* disableAccel */
+ 0, /* finiAccel */
+
+ 0, /* getColors */
+ 0, /* putColors */
+};
+
+void
+InitCard (void)
+{
+ KdCardAttr attr;
+
+ KdCardInfoAdd (&itsyFuncs, &attr, 0);
+}
+
+void
+InitOutput (ScreenInfo *pScreenInfo, int argc, char **argv)
+{
+ KdInitOutput (pScreenInfo, argc, argv);
+}
+
+void
+InitInput (int argc, char **argv)
+{
+ KdInitInput (&itsyTsMouseFuncs, &itsyKeyboardFuncs);
+}
+
+int itsySessionFd = -1;
+
+int
+ItsyOsInit (void)
+{
+ pid_t sid;
+ int i;
+ itsy_session_info info;
+
+ if (itsySessionFd < 0)
+ {
+ itsySessionFd = open ("/dev/session", 0);
+ ErrorF("itsySessionFD %d\n", itsySessionFd);
+ }
+
+ (void) setsid ();
+ sid = getsid (0);
+ ErrorF ("Session ID %d PID %d\n", sid, getpid ());
+ info.sid = sid;
+ strcpy (info.name, "X");
+ if (itsySessionFd >= 0)
+ {
+ i = ioctl (itsySessionFd, SESSION_SET_INFO, &info);
+ if (i < 0)
+ perror ("SESSION_SET_INFO");
+ }
+ return 1;
+}
+
+void
+ItsyOsEnable (void)
+{
+ itsy_session_request req;
+ int i;
+
+#define MANAGER_SID_TO_FOREGROUND 2
+
+ req.operation = MANAGER_SID_TO_FOREGROUND;
+ req.data = 0;
+ if (itsySessionFd >= 0)
+ {
+ i = ioctl (itsySessionFd, SESSION_MANAGER_REQUEST, &req);
+ if (i < 0)
+ perror ("SESSION_MANAGER_REQUEST");
+ }
+}
+
+Bool
+ItsyOsSpecialKey (KeySym sym)
+{
+ return FALSE;
+}
+
+void
+ItsyOsDisable (void)
+{
+}
+
+void
+ItsyOsFini (void)
+{
+}
+
+KdOsFuncs ItsyOsFuncs = {
+ ItsyOsInit,
+ ItsyOsEnable,
+ ItsyOsSpecialKey,
+ ItsyOsDisable,
+ ItsyOsFini,
+};
+
+void
+OsVendorInit (void)
+{
+ KdOsInit (&ItsyOsFuncs);
+}
+
+int
+ddxProcessArgument (int argc, char **argv, int i)
+{
+ return KdProcessArgument (argc, argv, i);
+}
diff --git a/xc/programs/Xserver/hw/kdrive/itsy/itsy.h b/xc/programs/Xserver/hw/kdrive/itsy/itsy.h
new file mode 100644
index 000000000..141a3d880
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/itsy/itsy.h
@@ -0,0 +1,42 @@
+/*
+ * $Id: itsy.h,v 1.1 2000/01/06 12:55:48 faith 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/itsy/itsy.h,v 1.1 1999/11/19 13:53:53 hohndel Exp $ */
+
+#include "kdrive.h"
+#include <stdio.h>
+#include <sys/ioctl.h>
+#include <linux/itsy_fb.h>
+#include <linux/itsy_ts.h>
+#include <linux/itsy_buttons.h>
+#include <linux/itsy_session.h>
+#include <unistd.h>
+#include <sys/mman.h>
+
+#define FB_HEIGHT 200
+#define FB_WIDTH 320
+#define FB_DEPTH 4
+#define FB_PALETTE_SIZE 16
+
+extern KdMouseFuncs itsyTsMouseFuncs;
+extern KdKeyboardFuncs itsyKeyboardFuncs;
diff --git a/xc/programs/Xserver/hw/kdrive/itsy/kbd.c b/xc/programs/Xserver/hw/kdrive/itsy/kbd.c
new file mode 100644
index 000000000..ea3dc4bbf
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/itsy/kbd.c
@@ -0,0 +1,234 @@
+/*
+ * $Id: kbd.c,v 1.1 2000/01/06 12:55:49 faith 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/itsy/kbd.c,v 1.1 1999/11/19 13:53:53 hohndel Exp $ */
+
+#include "itsy.h"
+#include "kkeymap.h"
+#include <X11/keysym.h>
+#include <linux/itsy_buttons.h>
+
+#define ITSY_WIDTH 2
+
+KeySym ItsyKeymap[] = {
+/* 1 8 */ XK_Escape, NoSymbol,
+/* 2 9 */ XK_1, XK_exclam,
+/* 3 10 */ XK_2, XK_at,
+/* 4 11 */ XK_3, XK_numbersign,
+/* 5 12 */ XK_4, XK_dollar,
+/* 6 13 */ XK_5, XK_percent,
+/* 7 14 */ XK_6, XK_asciicircum,
+/* 8 15 */ XK_7, XK_ampersand,
+/* 9 16 */ XK_8, XK_asterisk,
+/* 10 17 */ XK_9, XK_parenleft,
+/* 11 18 */ XK_0, XK_parenright,
+/* 12 19 */ XK_minus, XK_underscore,
+/* 13 20 */ XK_equal, XK_plus,
+/* 14 21 */ XK_BackSpace, NoSymbol,
+/* 15 22 */ XK_Tab, NoSymbol,
+/* 16 23 */ XK_Q, NoSymbol,
+/* 17 24 */ XK_W, NoSymbol,
+/* 18 25 */ XK_E, NoSymbol,
+/* 19 26 */ XK_R, NoSymbol,
+/* 20 27 */ XK_T, NoSymbol,
+/* 21 28 */ XK_Y, NoSymbol,
+/* 22 29 */ XK_U, NoSymbol,
+/* 23 30 */ XK_I, NoSymbol,
+/* 24 31 */ XK_O, NoSymbol,
+/* 25 32 */ XK_P, NoSymbol,
+/* 26 33 */ XK_bracketleft, XK_braceleft,
+/* 27 34 */ XK_bracketright, XK_braceright,
+/* 28 35 */ XK_Return, NoSymbol,
+/* 29 36 */ XK_Control_L, NoSymbol,
+/* 30 37 */ XK_A, NoSymbol,
+/* 31 38 */ XK_S, NoSymbol,
+/* 32 39 */ XK_D, NoSymbol,
+/* 33 40 */ XK_F, NoSymbol,
+/* 34 41 */ XK_G, NoSymbol,
+/* 35 42 */ XK_H, NoSymbol,
+/* 36 43 */ XK_J, NoSymbol,
+/* 37 44 */ XK_K, NoSymbol,
+/* 38 45 */ XK_L, NoSymbol,
+/* 39 46 */ XK_semicolon, XK_colon,
+/* 40 47 */ XK_apostrophe, XK_quotedbl,
+/* 41 48 */ XK_grave, XK_asciitilde,
+/* 42 49 */ XK_Shift_L, NoSymbol,
+/* 43 50 */ XK_backslash, XK_bar,
+/* 44 51 */ XK_Z, NoSymbol,
+/* 45 52 */ XK_X, NoSymbol,
+/* 46 53 */ XK_C, NoSymbol,
+/* 47 54 */ XK_V, NoSymbol,
+/* 48 55 */ XK_B, NoSymbol,
+/* 49 56 */ XK_N, NoSymbol,
+/* 50 57 */ XK_M, NoSymbol,
+/* 51 58 */ XK_comma, XK_less,
+/* 52 59 */ XK_period, XK_greater,
+/* 53 60 */ XK_slash, XK_question,
+/* 54 61 */ XK_Shift_R, NoSymbol,
+/* 55 62 */ XK_KP_Multiply, NoSymbol,
+/* 56 63 */ XK_Alt_L, XK_Meta_L,
+/* 57 64 */ XK_space, NoSymbol,
+/* 58 65 */ XK_Caps_Lock, NoSymbol,
+/* 59 66 */ XK_F1, NoSymbol,
+/* 60 67 */ XK_F2, NoSymbol,
+/* 61 68 */ XK_F3, NoSymbol,
+/* 62 69 */ XK_F4, NoSymbol,
+/* 63 70 */ XK_F5, NoSymbol,
+/* 64 71 */ XK_F6, NoSymbol,
+/* 65 72 */ XK_F7, NoSymbol,
+/* 66 73 */ XK_F8, NoSymbol,
+/* 67 74 */ XK_F9, NoSymbol,
+/* 68 75 */ XK_F10, NoSymbol,
+/* 69 76 */ XK_Break, XK_Pause,
+/* 70 77 */ XK_Scroll_Lock, NoSymbol,
+/* 71 78 */ XK_KP_Home, XK_KP_7,
+/* 72 79 */ XK_KP_Up, XK_KP_8,
+/* 73 80 */ XK_KP_Page_Up, XK_KP_9,
+/* 74 81 */ XK_KP_Subtract, NoSymbol,
+/* 75 82 */ XK_KP_Left, XK_KP_4,
+/* 76 83 */ XK_KP_5, NoSymbol,
+/* 77 84 */ XK_KP_Right, XK_KP_6,
+/* 78 85 */ XK_KP_Add, NoSymbol,
+/* 79 86 */ XK_KP_End, XK_KP_1,
+/* 80 87 */ XK_KP_Down, XK_KP_2,
+/* 81 88 */ XK_KP_Page_Down, XK_KP_3,
+/* 82 89 */ XK_KP_Insert, XK_KP_0,
+/* 83 90 */ XK_KP_Delete, XK_KP_Decimal,
+/* 84 91 */ NoSymbol, NoSymbol,
+/* 85 92 */ NoSymbol, NoSymbol,
+/* 86 93 */ NoSymbol, NoSymbol,
+/* 87 94 */ XK_F11, NoSymbol,
+/* 88 95 */ XK_F12, NoSymbol,
+
+/* These are remapped from the extended set (using ExtendMap) */
+
+/* 89 96 */ XK_Control_R, NoSymbol,
+/* 90 97 */ XK_KP_Enter, NoSymbol,
+/* 91 98 */ XK_KP_Divide, NoSymbol,
+/* 92 99 */ XK_Sys_Req, XK_Print,
+/* 93 100 */ XK_Alt_R, XK_Meta_R,
+/* 94 101 */ XK_Num_Lock, NoSymbol,
+/* 95 102 */ XK_Home, NoSymbol,
+/* 96 103 */ XK_Up, NoSymbol,
+/* 97 104 */ XK_Page_Up, NoSymbol,
+/* 98 105 */ XK_Left, NoSymbol,
+/* 99 106 */ XK_Right, NoSymbol,
+/* 100 107 */ XK_End, NoSymbol,
+/* 101 108 */ XK_Down, NoSymbol,
+/* 102 109 */ XK_Page_Down, NoSymbol,
+/* 103 110 */ XK_Insert, NoSymbol,
+/* 104 111 */ XK_Delete, NoSymbol,
+/* 105 112 */ XK_Super_L, NoSymbol,
+/* 106 113 */ XK_Super_R, NoSymbol,
+/* 107 114 */ XK_Menu, NoSymbol,
+
+/* Itsy hardware buttons */
+#define ITSY_BUTTON_FIRST 108
+#define ITSY_BUTTON_LAST 116
+
+/* 108 115 */ XK_Next, NoSymbol, /* right button on side */
+/* 109 116 */ XK_Prior, NoSymbol, /* left button on side */
+/* 110 117 */ XK_Up, NoSymbol, /* joypad */
+/* 111 118 */ XK_Down, NoSymbol,
+/* 112 119 */ XK_Left, NoSymbol,
+/* 113 120 */ XK_Right, NoSymbol,
+/* 114 121 */ NoSymbol, NoSymbol, /* left near speaker */
+/* 115 122 */ NoSymbol, NoSymbol, /* right near speaker */
+/* 116 123 */ NoSymbol, NoSymbol, /* tiny button */
+};
+
+static unsigned long itsyButtonState;
+
+void
+ItsyKeyboardLoad (void)
+{
+ KeySym *k;
+
+ itsyButtonState = 0;
+ kdMinScanCode = 1;
+ kdKeymapWidth = ITSY_WIDTH;
+ kdMaxScanCode = (sizeof (ItsyKeymap) / sizeof (ItsyKeymap[0])) / ITSY_WIDTH;
+ memcpy (kdKeymap, ItsyKeymap, sizeof (ItsyKeymap));
+}
+
+int
+ItsyKeyboardInit (void)
+{
+ int butPort;
+
+ butPort = open ("/dev/buttons", 0);
+ fprintf (stderr, "butPort %d\n", butPort);
+ return butPort;
+}
+
+void
+ItsyKeyboardFini (int fd)
+{
+ if (fd >= 0)
+ close (fd);
+}
+
+void
+ItsyKeyboardRead (int fd)
+{
+ itsy_buttons_event event;
+ int b;
+ unsigned long bit;
+ unsigned long change;
+ unsigned long buttons;
+
+ if (read (fd, &event, sizeof (event)) == sizeof (event))
+ {
+ buttons = event.state;
+ change = buttons ^ itsyButtonState;
+ if (!change)
+ return;
+ for (b = ITSY_BUTTON_FIRST; b <= ITSY_BUTTON_LAST; b++)
+ {
+ bit = (1 << (b - ITSY_BUTTON_FIRST));
+ if (change & bit)
+ KdEnqueueKeyboardEvent (b, (buttons & bit) == 0);
+ }
+ itsyButtonState = buttons;
+ }
+}
+
+void
+ItsyKeyboardLeds (int leds)
+{
+}
+
+void
+ItsyKeyboardBell (int volume, int frequency, int duration)
+{
+}
+
+KdKeyboardFuncs itsyKeyboardFuncs = {
+ ItsyKeyboardLoad,
+ ItsyKeyboardInit,
+ ItsyKeyboardRead,
+ ItsyKeyboardLeds,
+ ItsyKeyboardBell,
+ ItsyKeyboardFini,
+ 0,
+};
diff --git a/xc/programs/Xserver/hw/kdrive/itsy/ts.c b/xc/programs/Xserver/hw/kdrive/itsy/ts.c
new file mode 100644
index 000000000..8b07c598c
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/itsy/ts.c
@@ -0,0 +1,209 @@
+/*
+ * $Id: ts.c,v 1.1 2000/01/06 12:55:49 faith 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/itsy/ts.c,v 1.1 1999/11/19 13:53:54 hohndel Exp $ */
+
+#define NEED_EVENTS
+#include "itsy.h"
+#include "Xproto.h"
+#include "inputstr.h"
+#include "Xpoll.h"
+
+int
+itsyTsReadBytes (int fd, char *buf, int len, int min)
+{
+ int n, tot;
+ fd_set set;
+ struct timeval tv;
+
+ tot = 0;
+ while (len)
+ {
+ n = read (fd, buf, len);
+ if (n > 0)
+ {
+ tot += n;
+ buf += n;
+ len -= n;
+ }
+ if (tot % min == 0)
+ break;
+ FD_ZERO (&set);
+ FD_SET (fd, &set);
+ tv.tv_sec = 0;
+ tv.tv_usec = 100 * 1000;
+ n = select (fd + 1, &set, 0, 0, &tv);
+ if (n <= 0)
+ break;
+ }
+ return tot;
+}
+
+void
+itsyTsRead (int tsPort)
+{
+ ts_event event;
+ long buf[3];
+ int n;
+ long pressure;
+ long x, y;
+ unsigned long flags;
+ unsigned long buttons;
+
+ n = itsyTsReadBytes (tsPort, (char *) &event,
+ sizeof (event), sizeof (event));
+ if (n == sizeof (event))
+ {
+ if (event.pressure)
+ {
+ flags = KD_BUTTON_1;
+ x = event.point.x;
+ y = event.point.y;
+ }
+ else
+ {
+ flags = KD_MOUSE_DELTA;
+ x = 0;
+ y = 0;
+ }
+ KdEnqueueMouseEvent (flags, x, y);
+ }
+}
+
+#if 0
+#define ITSY_DEBUG_LOW 1
+
+//
+// Touch screen parameters are stored
+// in the flash. This code is taken from 'wm1'.
+//
+void itsySetTouchCalibration (int mou_filedsc,
+ int xs, int xt, int ys, int yt, int xys)
+{
+ int k, ibuf[10];
+
+ ibuf[0] = xs;
+ ibuf[1] = xt;
+ ibuf[2] = ys;
+ ibuf[3] = yt;
+ ibuf[4] = xys;
+ if ((k=ioctl(mou_filedsc, TS_SET_CALM, ibuf)) != 0) {
+ fprintf(stderr, "ERROR: ioctl TS_SET_CALM returns %d\n", k);
+ }
+}
+
+
+int itsyReadFlashBlock(int location, signed char *data, int dbytes)
+{
+ int offset, bytes;
+ int flashfd;
+
+ flashfd = open("/dev/flash1", O_RDONLY);
+ if (flashfd < 0) return(0);
+
+ offset = lseek(flashfd, location, SEEK_SET);
+ if (offset != location) {
+ close(flashfd);
+ return(0);
+ }
+
+ bytes = read(flashfd, data, dbytes);
+ if (bytes != dbytes) {
+ close(flashfd);
+ return(0);
+ }
+
+ close(flashfd);
+ return(1);
+}
+
+/**********************************************************************/
+#define RAMSIZE (0x400000)
+#define MONITOR_BLOCKSIZE (32)
+/**********************************************************************/
+
+/* code for storing calibration into flash */
+
+#define CALIBRATE_BLOCKSIZE (32)
+#define CALIBRATE_OFFSET (RAMSIZE-MONITOR_BLOCKSIZE-CALIBRATE_BLOCKSIZE)
+#define CALIBRATE_MAGIC_NUM (0x0babedee)
+
+
+static int check_if_calibrated_and_set(int mou_filedsc)
+{
+ signed char cal_data[CALIBRATE_BLOCKSIZE];
+ int *iptr;
+
+ if (itsyReadFlashBlock(CALIBRATE_OFFSET,
+ cal_data, CALIBRATE_BLOCKSIZE) == 0) {
+ if ( ITSY_DEBUG_LOW ) {
+ fprintf(stderr,"unable to read calibration data for touch screen\n");
+ }
+ return(0);
+ }
+
+ iptr = (int *) cal_data;
+ if (iptr[0] == CALIBRATE_MAGIC_NUM) {
+ if ( ITSY_DEBUG_LOW ) {
+ fprintf(stderr,"Calibrating touch screen using %d, %d, %d, %d, %d\n",
+ iptr[1], iptr[2], iptr[3], iptr[4], iptr[5]);
+ }
+ itsySetTouchCalibration(mou_filedsc, iptr[1], iptr[2], iptr[3], iptr[4], iptr[5]);
+ return(1);
+ }
+ else {
+ if ( ITSY_DEBUG_LOW ) {
+ fprintf(stderr,"Couldn't calibrate screen\n");
+ }
+ return(0);
+ }
+}
+#endif
+
+int
+itsyTsInit (void)
+{
+ int tsPort;
+
+ tsPort = open ("/dev/ts", 0);
+ fprintf (stderr, "tsPort %d\n", tsPort);
+#if 0
+ if (tsPort >= 0)
+ check_if_calibrated_and_set (tsPort);
+#endif
+ return tsPort;
+}
+
+void
+itsyTsFini (int tsPort)
+{
+ if (tsPort >= 0)
+ close (tsPort);
+}
+
+KdMouseFuncs itsyTsMouseFuncs = {
+ itsyTsInit,
+ itsyTsRead,
+ itsyTsFini
+};
+
diff --git a/xc/programs/Xserver/hw/kdrive/kasync.c b/xc/programs/Xserver/hw/kdrive/kasync.c
new file mode 100644
index 000000000..84620a2e5
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/kasync.c
@@ -0,0 +1,294 @@
+/*
+ * $Id: kasync.c,v 1.1 2000/01/06 12:55:48 faith 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.
+ */
+
+#include "kdrive.h"
+
+/*
+ * These functions wrap the low-level fb rendering functions and
+ * synchronize framebuffer/accelerated drawing by stalling until
+ * the accelerator is idle
+ */
+
+void
+KdCheckFillSpans (DrawablePtr pDrawable, GCPtr pGC, int nspans,
+ DDXPointPtr ppt, int *pwidth, int fSorted)
+{
+ KdCheckSync (pDrawable->pScreen);
+ fbFillSpans (pDrawable, pGC, nspans, ppt, pwidth, fSorted);
+}
+
+void
+KdCheckSetSpans (DrawablePtr pDrawable, GCPtr pGC, char *psrc,
+ DDXPointPtr ppt, int *pwidth, int nspans, int fSorted)
+{
+ KdCheckSync (pDrawable->pScreen);
+ fbSetSpans (pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted);
+}
+
+void
+KdCheckPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth,
+ int x, int y, int w, int h, int leftPad, int format,
+ char *bits)
+{
+ KdCheckSync (pDrawable->pScreen);
+ fbPutImage (pDrawable, pGC, depth, x, y, w, h, leftPad, format, bits);
+}
+
+RegionPtr
+KdCheckCopyArea (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
+ int srcx, int srcy, int w, int h, int dstx, int dsty)
+{
+ KdCheckSync (pSrc->pScreen);
+ return fbCopyArea (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty);
+}
+
+RegionPtr
+KdCheckCopyPlane (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
+ int srcx, int srcy, int w, int h, int dstx, int dsty,
+ unsigned long bitPlane)
+{
+ KdCheckSync (pSrc->pScreen);
+ return fbCopyPlane (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty,
+ bitPlane);
+}
+
+void
+KdCheckPolyPoint (DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
+ DDXPointPtr pptInit)
+{
+ KdCheckSync (pDrawable->pScreen);
+ fbPolyPoint (pDrawable, pGC, mode, npt, pptInit);
+}
+
+void
+KdCheckPolylines (DrawablePtr pDrawable, GCPtr pGC,
+ int mode, int npt, DDXPointPtr ppt)
+{
+
+ if (pGC->lineWidth == 0)
+ {
+ KdCheckSync (pDrawable->pScreen);
+ fbZeroLine (pDrawable, pGC, mode, npt, ppt);
+ }
+ else
+ {
+ if (pGC->lineStyle != LineSolid)
+ miWideDash (pDrawable, pGC, mode, npt, ppt);
+ else
+ miWideLine (pDrawable, pGC, mode, npt, ppt);
+ }
+}
+
+#if 0
+void
+KdCheckPolySegment (DrawablePtr pDrawable, GCPtr pGC,
+ int nsegInit, xSegment *pSegInit)
+{
+ KdCheckSync(pDrawable->pScreen);
+ fbPolySegment (pDrawable, pGC, nsegInit, pSegInit);
+}
+
+void
+KdCheckPolyRectangle (DrawablePtr pDrawable, GCPtr pGC,
+ int nrects, xRectangle *prect)
+{
+ KdCheckSync(pDrawable->pScreen);
+ fbPolyRectangle (pDrawable, pGC, nrects, prect);
+}
+#endif
+
+void
+KdCheckPolyArc (DrawablePtr pDrawable, GCPtr pGC,
+ int narcs, xArc *pArcs)
+{
+ if (pGC->lineWidth == 0)
+ {
+ KdCheckSync(pDrawable->pScreen);
+ fbPolyArc (pDrawable, pGC, narcs, pArcs);
+ }
+ else
+ miPolyArc (pDrawable, pGC, narcs, pArcs);
+}
+
+#if 0
+void
+KdCheckFillPolygon (DrawablePtr pDrawable, GCPtr pGC,
+ int shape, int mode, int count, DDXPointPtr pPts)
+{
+ KdCheckSync(pDrawable->pScreen);
+ fbFillPolygon (pDrawable, pGC, mode, count, pPts);
+}
+#endif
+
+void
+KdCheckPolyFillRect (DrawablePtr pDrawable, GCPtr pGC,
+ int nrect, xRectangle *prect)
+{
+ KdCheckSync(pDrawable->pScreen);
+ fbPolyFillRect (pDrawable, pGC, nrect, prect);
+}
+
+#if 0
+void
+KdCheckPolyFillArc (DrawablePtr pDrawable, GCPtr pGC,
+ int narcs, xArc *pArcs)
+{
+ KdCheckSync(pDrawable->pScreen);
+ fbPolyFillArc (pDrawable, pGC, narcs, pArcs);
+}
+#endif
+
+void
+KdCheckImageGlyphBlt (DrawablePtr pDrawable, GCPtr pGC,
+ int x, int y, unsigned int nglyph,
+ CharInfoPtr *ppci, pointer pglyphBase)
+{
+ KdCheckSync(pDrawable->pScreen);
+ fbImageGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
+}
+
+void
+KdCheckPolyGlyphBlt (DrawablePtr pDrawable, GCPtr pGC,
+ int x, int y, unsigned int nglyph,
+ CharInfoPtr *ppci, pointer pglyphBase)
+{
+ KdCheckSync(pDrawable->pScreen);
+ fbPolyGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
+}
+
+void
+KdCheckPushPixels (GCPtr pGC, PixmapPtr pBitmap,
+ DrawablePtr pDrawable,
+ int w, int h, int x, int y)
+{
+ KdCheckSync(pDrawable->pScreen);
+ fbPushPixels (pGC, pBitmap, pDrawable, w, h, x, y);
+}
+
+void
+KdCheckGetImage (DrawablePtr pDrawable,
+ int x, int y, int w, int h,
+ unsigned int format, unsigned long planeMask,
+ char *d)
+{
+ KdCheckSync(pDrawable->pScreen);
+ fbGetImage (pDrawable, x, y, w, h, format, planeMask, d);
+}
+
+void
+KdCheckGetSpans (DrawablePtr pDrawable,
+ int wMax,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int nspans,
+ char *pdstStart)
+{
+ if (pDrawable->type != DRAWABLE_PIXMAP)
+ KdCheckSync(pDrawable->pScreen);
+ fbGetSpans (pDrawable, wMax, ppt, pwidth, nspans, pdstStart);
+}
+
+void
+KdCheckSaveAreas (PixmapPtr pPixmap,
+ RegionPtr prgnSave,
+ int xorg,
+ int yorg,
+ WindowPtr pWin)
+{
+ KdCheckSync(pWin->drawable.pScreen);
+ fbSaveAreas (pPixmap, prgnSave, xorg, yorg, pWin);
+}
+
+void
+KdCheckRestoreAreas (PixmapPtr pPixmap,
+ RegionPtr prgnSave,
+ int xorg,
+ int yorg,
+ WindowPtr pWin)
+{
+ KdCheckSync(pWin->drawable.pScreen);
+ fbRestoreAreas (pPixmap, prgnSave, xorg, yorg, pWin);
+}
+
+void
+KdCheckPaintWindow (WindowPtr pWin, RegionPtr pRegion, int what)
+{
+ KdCheckSync (pWin->drawable.pScreen);
+ fbPaintWindow (pWin, pRegion, what);
+}
+
+void
+KdCheckCopyWindow (WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
+{
+ KdCheckSync (pWin->drawable.pScreen);
+ fbCopyWindow (pWin, ptOldOrg, prgnSrc);
+}
+
+void
+KdScreenInitAsync (ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ pScreen->GetImage = KdCheckGetImage;
+ pScreen->GetSpans = KdCheckGetSpans;
+ pScreen->PaintWindowBackground = KdCheckPaintWindow;
+ pScreen->PaintWindowBorder = KdCheckPaintWindow;
+ pScreen->CopyWindow = KdCheckCopyWindow;
+
+#ifndef FB_OLD_SCREEN
+ pScreen->BackingStoreFuncs.SaveAreas = KdCheckSaveAreas;
+ pScreen->BackingStoreFuncs.RestoreAreas = KdCheckRestoreAreas;
+#else
+ pScreenPriv->BackingStoreFuncs.SaveAreas = KdCheckSaveAreas;
+ pScreenPriv->BackingStoreFuncs.RestoreAreas = KdCheckRestoreAreas;
+#endif
+}
+
+/*
+ * Only need to stall for copyarea/copyplane
+ */
+const GCOps kdAsyncPixmapGCOps = {
+ fbFillSpans,
+ fbSetSpans,
+ fbPutImage,
+ KdCheckCopyArea,
+ KdCheckCopyPlane,
+ fbPolyPoint,
+ fbPolyLine,
+ miPolySegment,
+ miPolyRectangle,
+ fbPolyArc,
+ miFillPolygon,
+ fbPolyFillRect,
+ miPolyFillArc,
+ miPolyText8,
+ miPolyText16,
+ miImageText8,
+ miImageText16,
+ fbImageGlyphBlt,
+ fbPolyGlyphBlt,
+ fbPushPixels
+#ifdef NEED_LINEHELPER
+ ,NULL
+#endif
+};
diff --git a/xc/programs/Xserver/hw/kdrive/kcmap.c b/xc/programs/Xserver/hw/kdrive/kcmap.c
new file mode 100644
index 000000000..d85066145
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/kcmap.c
@@ -0,0 +1,231 @@
+/*
+ * $Id: kcmap.c,v 1.1 2000/01/06 12:55:45 faith 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/kcmap.c,v 1.1 1999/11/19 13:53:48 hohndel Exp $ */
+
+#include "kdrive.h"
+
+/*
+ * Put the entire colormap into the DAC
+ */
+
+void
+KdSetColormap (ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ ColormapPtr pCmap = pScreenPriv->pInstalledmap;
+ Pixel pixels[KD_MAX_PSEUDO_SIZE];
+ xrgb colors[KD_MAX_PSEUDO_SIZE];
+ xColorItem defs[KD_MAX_PSEUDO_SIZE];
+ int i;
+
+ if (!pScreenPriv->card->cfuncs->putColors)
+ return;
+ if (pScreenPriv->screen->depth > KD_MAX_PSEUDO_DEPTH)
+ return;
+
+ if (!pScreenPriv->enabled)
+ return;
+
+ if (!pCmap)
+ return;
+
+ /*
+ * Make DIX convert pixels into RGB values -- this handles
+ * true/direct as well as pseudo/static visuals
+ */
+
+ for (i = 0; i < (1 << pScreenPriv->screen->depth); i++)
+ pixels[i] = i;
+
+ QueryColors (pCmap, (1 << pScreenPriv->screen->depth), pixels, colors);
+
+ for (i = 0; i < (1 << pScreenPriv->screen->depth); i++)
+ {
+ defs[i].pixel = i;
+ defs[i].red = colors[i].red;
+ defs[i].green = colors[i].green;
+ defs[i].blue = colors[i].blue;
+ defs[i].flags = DoRed|DoGreen|DoBlue;
+ }
+
+ (*pScreenPriv->card->cfuncs->putColors) (pCmap->pScreen,
+ (1 << pScreenPriv->screen->depth),
+ defs);
+
+ /* recolor hardware cursor */
+ if (pScreenPriv->card->cfuncs->recolorCursor)
+ (*pScreenPriv->card->cfuncs->recolorCursor) (pCmap->pScreen, 0, 0);
+}
+
+/*
+ * When the hardware is enabled, save the hardware colors and store
+ * the current colormap
+ */
+void
+KdEnableColormap (ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ int i;
+
+ if (!pScreenPriv->card->cfuncs->putColors)
+ return;
+ if (pScreenPriv->screen->depth <= KD_MAX_PSEUDO_DEPTH)
+ {
+ for (i = 0; i < (1 << pScreenPriv->screen->depth); i++)
+ pScreenPriv->systemPalette[i].pixel = i;
+ (*pScreenPriv->card->cfuncs->getColors) (pScreen,
+ (1 << pScreenPriv->screen->depth),
+ pScreenPriv->systemPalette);
+ }
+ KdSetColormap (pScreen);
+}
+
+void
+KdDisableColormap (ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+
+ if (!pScreenPriv->card->cfuncs->putColors)
+ return;
+ if (pScreenPriv->screen->depth > KD_MAX_PSEUDO_DEPTH)
+ return;
+
+ (*pScreenPriv->card->cfuncs->putColors) (pScreen,
+ (1 << pScreenPriv->screen->depth),
+ pScreenPriv->systemPalette);
+}
+
+/*
+ * KdInstallColormap
+ *
+ * This function is called when the server receives a request to install a
+ * colormap or when the server needs to install one on its own, like when
+ * there's no window manager running and the user has moved the pointer over
+ * an X client window. It needs to build an identity Windows palette for the
+ * colormap and realize it into the Windows system palette.
+ */
+void
+KdInstallColormap (ColormapPtr pCmap)
+{
+ KdScreenPriv(pCmap->pScreen);
+
+ if (pCmap == pScreenPriv->pInstalledmap)
+ return;
+
+ /* Tell X clients that the installed colormap is going away. */
+ if (pScreenPriv->pInstalledmap)
+ WalkTree(pScreenPriv->pInstalledmap->pScreen, TellLostMap,
+ (pointer) &(pScreenPriv->pInstalledmap->mid));
+
+ /* Take note of the new installed colorscreen-> */
+ pScreenPriv->pInstalledmap = pCmap;
+
+ KdSetColormap (pCmap->pScreen);
+
+ /* Tell X clients of the new colorscreen-> */
+ WalkTree(pCmap->pScreen, TellGainedMap, (pointer) &(pCmap->mid));
+}
+
+/*
+ * KdUninstallColormap
+ *
+ * This function uninstalls a colormap by installing the default X colorscreen->
+ * The default X colormap itself cannot be uninstalled.
+ */
+void
+KdUninstallColormap (ColormapPtr pCmap)
+{
+ KdScreenPriv(pCmap->pScreen);
+
+ if (pCmap == pScreenPriv->pInstalledmap)
+ {
+ Colormap defMapID = pCmap->pScreen->defColormap;
+
+ if ((Colormap) pCmap->mid != defMapID)
+ {
+ ColormapPtr defMap = (ColormapPtr) LookupIDByType(defMapID,
+ RT_COLORMAP);
+ if (defMap)
+ (*pCmap->pScreen->InstallColormap)(defMap);
+ }
+ }
+}
+
+int
+KdListInstalledColormaps (ScreenPtr pScreen, Colormap *pCmaps)
+{
+ KdScreenPriv(pScreen);
+
+ if (pScreenPriv->pInstalledmap)
+ {
+ *pCmaps = pScreenPriv->pInstalledmap->mid;
+ return 1;
+ }
+ return 0;
+}
+
+/*
+ * KdStoreColors
+ *
+ * This function is called whenever the server receives a request to store
+ * color values into one or more entries in the currently installed X
+ * colormap; it can be either the default colormap or a private colorscreen->
+ */
+void
+KdStoreColors (ColormapPtr pCmap, int ndef, xColorItem *pdefs)
+{
+ KdScreenPriv(pCmap->pScreen);
+ VisualPtr pVisual;
+ xColorItem expanddefs[KD_MAX_PSEUDO_SIZE];
+
+ if (pCmap != pScreenPriv->pInstalledmap)
+ return;
+
+ if (!pScreenPriv->card->cfuncs->putColors)
+ return;
+
+ if (pScreenPriv->screen->depth > KD_MAX_PSEUDO_DEPTH)
+ return;
+
+ if (!pScreenPriv->enabled)
+ return;
+
+ /* Check for DirectColor or TrueColor being simulated on a PseudoColor device. */
+ pVisual = pCmap->pVisual;
+ if ((pVisual->class | DynamicClass) == DirectColor)
+ {
+ /*
+ * Expand DirectColor or TrueColor color values into a PseudoColor
+ * format. Defer to the Color Framebuffer (CFB) code to do that.
+ */
+ ndef = fbExpandDirectColors(pCmap, ndef, pdefs, expanddefs);
+ pdefs = expanddefs;
+ }
+
+ (*pScreenPriv->card->cfuncs->putColors) (pCmap->pScreen, ndef, pdefs);
+
+ /* recolor hardware cursor */
+ if (pScreenPriv->card->cfuncs->recolorCursor)
+ (*pScreenPriv->card->cfuncs->recolorCursor) (pCmap->pScreen, ndef, pdefs);
+}
diff --git a/xc/programs/Xserver/hw/kdrive/kcolor.c b/xc/programs/Xserver/hw/kdrive/kcolor.c
new file mode 100644
index 000000000..623c1164b
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/kcolor.c
@@ -0,0 +1,881 @@
+/*
+ * $Id: kcolor.c,v 1.1 2000/01/06 12:55:46 faith 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/kcolor.c,v 1.2 1999/12/30 03:03:05 robin Exp $ */
+
+#include "kdrive.h"
+#include <stdio.h>
+#include "os.h"
+#include "opaque.h"
+#include <X11/keysym.h>
+
+unsigned char
+KdToLower (unsigned char a)
+{
+ if ((a >= XK_A) && (a <= XK_Z))
+ return a + (XK_a - XK_A);
+ else if ((a >= XK_Agrave) && (a <= XK_Odiaeresis))
+ return a + (XK_agrave - XK_Agrave);
+ else if ((a >= XK_Ooblique) && (a <= XK_Thorn))
+ return a + (XK_oslash - XK_Ooblique);
+ else
+ return a;
+}
+
+int
+KdStrCaseCmp (const unsigned char *s1, const unsigned char *s2, int l2)
+{
+ unsigned char c1, c2;
+
+ for (;;)
+ {
+ c1 = KdToLower (*s1++);
+ if (l2 == 0)
+ c2 = '\0';
+ else
+ c2 = KdToLower (*s2++);
+ if (!c1 || !c2)
+ break;
+ if (c1 != c2)
+ break;
+ l2--;
+ }
+ return c2 - c1;
+}
+
+typedef struct _kdNamedColor {
+ unsigned short red;
+ unsigned short green;
+ unsigned short blue;
+ const unsigned char *name;
+} KdNamedColor;
+
+#define C 0x101
+
+const KdNamedColor KdColors[] = {
+240*C, 248*C, 255*C, "alice blue",
+240*C, 248*C, 255*C, "AliceBlue",
+250*C, 235*C, 215*C, "antique white",
+250*C, 235*C, 215*C, "AntiqueWhite",
+255*C, 239*C, 219*C, "AntiqueWhite1",
+238*C, 223*C, 204*C, "AntiqueWhite2",
+205*C, 192*C, 176*C, "AntiqueWhite3",
+139*C, 131*C, 120*C, "AntiqueWhite4",
+127*C, 255*C, 212*C, "aquamarine",
+127*C, 255*C, 212*C, "aquamarine1",
+118*C, 238*C, 198*C, "aquamarine2",
+102*C, 205*C, 170*C, "aquamarine3",
+ 69*C, 139*C, 116*C, "aquamarine4",
+240*C, 255*C, 255*C, "azure",
+240*C, 255*C, 255*C, "azure1",
+224*C, 238*C, 238*C, "azure2",
+193*C, 205*C, 205*C, "azure3",
+131*C, 139*C, 139*C, "azure4",
+245*C, 245*C, 220*C, "beige",
+255*C, 228*C, 196*C, "bisque",
+255*C, 228*C, 196*C, "bisque1",
+238*C, 213*C, 183*C, "bisque2",
+205*C, 183*C, 158*C, "bisque3",
+139*C, 125*C, 107*C, "bisque4",
+ 0*C, 0*C, 0*C, "black",
+255*C, 235*C, 205*C, "blanched almond",
+255*C, 235*C, 205*C, "BlanchedAlmond",
+ 0*C, 0*C, 255*C, "blue",
+138*C, 43*C, 226*C, "blue violet",
+ 0*C, 0*C, 255*C, "blue1",
+ 0*C, 0*C, 238*C, "blue2",
+ 0*C, 0*C, 205*C, "blue3",
+ 0*C, 0*C, 139*C, "blue4",
+138*C, 43*C, 226*C, "BlueViolet",
+165*C, 42*C, 42*C, "brown",
+255*C, 64*C, 64*C, "brown1",
+238*C, 59*C, 59*C, "brown2",
+205*C, 51*C, 51*C, "brown3",
+139*C, 35*C, 35*C, "brown4",
+222*C, 184*C, 135*C, "burlywood",
+255*C, 211*C, 155*C, "burlywood1",
+238*C, 197*C, 145*C, "burlywood2",
+205*C, 170*C, 125*C, "burlywood3",
+139*C, 115*C, 85*C, "burlywood4",
+ 95*C, 158*C, 160*C, "cadet blue",
+ 95*C, 158*C, 160*C, "CadetBlue",
+152*C, 245*C, 255*C, "CadetBlue1",
+142*C, 229*C, 238*C, "CadetBlue2",
+122*C, 197*C, 205*C, "CadetBlue3",
+ 83*C, 134*C, 139*C, "CadetBlue4",
+127*C, 255*C, 0*C, "chartreuse",
+127*C, 255*C, 0*C, "chartreuse1",
+118*C, 238*C, 0*C, "chartreuse2",
+102*C, 205*C, 0*C, "chartreuse3",
+69*C, 139*C, 0*C, "chartreuse4",
+210*C, 105*C, 30*C, "chocolate",
+255*C, 127*C, 36*C, "chocolate1",
+238*C, 118*C, 33*C, "chocolate2",
+205*C, 102*C, 29*C, "chocolate3",
+139*C, 69*C, 19*C, "chocolate4",
+255*C, 127*C, 80*C, "coral",
+255*C, 114*C, 86*C, "coral1",
+238*C, 106*C, 80*C, "coral2",
+205*C, 91*C, 69*C, "coral3",
+139*C, 62*C, 47*C, "coral4",
+100*C, 149*C, 237*C, "cornflower blue",
+100*C, 149*C, 237*C, "CornflowerBlue",
+255*C, 248*C, 220*C, "cornsilk",
+255*C, 248*C, 220*C, "cornsilk1",
+238*C, 232*C, 205*C, "cornsilk2",
+205*C, 200*C, 177*C, "cornsilk3",
+139*C, 136*C, 120*C, "cornsilk4",
+ 0*C, 255*C, 255*C, "cyan",
+ 0*C, 255*C, 255*C, "cyan1",
+ 0*C, 238*C, 238*C, "cyan2",
+ 0*C, 205*C, 205*C, "cyan3",
+ 0*C, 139*C, 139*C, "cyan4",
+0*C, 0*C, 139*C, "dark blue",
+0*C, 139*C, 139*C, "dark cyan",
+184*C, 134*C, 11*C, "dark goldenrod",
+169*C, 169*C, 169*C, "dark gray",
+ 0*C, 100*C, 0*C, "dark green",
+169*C, 169*C, 169*C, "dark grey",
+189*C, 183*C, 107*C, "dark khaki",
+139*C, 0*C, 139*C, "dark magenta",
+ 85*C, 107*C, 47*C, "dark olive green",
+255*C, 140*C, 0*C, "dark orange",
+153*C, 50*C, 204*C, "dark orchid",
+139*C, 0*C, 0*C, "dark red",
+233*C, 150*C, 122*C, "dark salmon",
+143*C, 188*C, 143*C, "dark sea green",
+ 72*C, 61*C, 139*C, "dark slate blue",
+ 47*C, 79*C, 79*C, "dark slate gray",
+ 47*C, 79*C, 79*C, "dark slate grey",
+ 0*C, 206*C, 209*C, "dark turquoise",
+148*C, 0*C, 211*C, "dark violet",
+0*C, 0*C, 139*C, "DarkBlue",
+0*C, 139*C, 139*C, "DarkCyan",
+184*C, 134*C, 11*C, "DarkGoldenrod",
+255*C, 185*C, 15*C, "DarkGoldenrod1",
+238*C, 173*C, 14*C, "DarkGoldenrod2",
+205*C, 149*C, 12*C, "DarkGoldenrod3",
+139*C, 101*C, 8*C, "DarkGoldenrod4",
+169*C, 169*C, 169*C, "DarkGray",
+ 0*C, 100*C, 0*C, "DarkGreen",
+169*C, 169*C, 169*C, "DarkGrey",
+189*C, 183*C, 107*C, "DarkKhaki",
+139*C, 0*C, 139*C, "DarkMagenta",
+ 85*C, 107*C, 47*C, "DarkOliveGreen",
+202*C, 255*C, 112*C, "DarkOliveGreen1",
+188*C, 238*C, 104*C, "DarkOliveGreen2",
+162*C, 205*C, 90*C, "DarkOliveGreen3",
+110*C, 139*C, 61*C, "DarkOliveGreen4",
+255*C, 140*C, 0*C, "DarkOrange",
+255*C, 127*C, 0*C, "DarkOrange1",
+238*C, 118*C, 0*C, "DarkOrange2",
+205*C, 102*C, 0*C, "DarkOrange3",
+139*C, 69*C, 0*C, "DarkOrange4",
+153*C, 50*C, 204*C, "DarkOrchid",
+191*C, 62*C, 255*C, "DarkOrchid1",
+178*C, 58*C, 238*C, "DarkOrchid2",
+154*C, 50*C, 205*C, "DarkOrchid3",
+104*C, 34*C, 139*C, "DarkOrchid4",
+139*C, 0*C, 0*C, "DarkRed",
+233*C, 150*C, 122*C, "DarkSalmon",
+143*C, 188*C, 143*C, "DarkSeaGreen",
+193*C, 255*C, 193*C, "DarkSeaGreen1",
+180*C, 238*C, 180*C, "DarkSeaGreen2",
+155*C, 205*C, 155*C, "DarkSeaGreen3",
+105*C, 139*C, 105*C, "DarkSeaGreen4",
+ 72*C, 61*C, 139*C, "DarkSlateBlue",
+ 47*C, 79*C, 79*C, "DarkSlateGray",
+151*C, 255*C, 255*C, "DarkSlateGray1",
+141*C, 238*C, 238*C, "DarkSlateGray2",
+121*C, 205*C, 205*C, "DarkSlateGray3",
+ 82*C, 139*C, 139*C, "DarkSlateGray4",
+ 47*C, 79*C, 79*C, "DarkSlateGrey",
+ 0*C, 206*C, 209*C, "DarkTurquoise",
+148*C, 0*C, 211*C, "DarkViolet",
+255*C, 20*C, 147*C, "deep pink",
+ 0*C, 191*C, 255*C, "deep sky blue",
+255*C, 20*C, 147*C, "DeepPink",
+255*C, 20*C, 147*C, "DeepPink1",
+238*C, 18*C, 137*C, "DeepPink2",
+205*C, 16*C, 118*C, "DeepPink3",
+139*C, 10*C, 80*C, "DeepPink4",
+ 0*C, 191*C, 255*C, "DeepSkyBlue",
+ 0*C, 191*C, 255*C, "DeepSkyBlue1",
+ 0*C, 178*C, 238*C, "DeepSkyBlue2",
+ 0*C, 154*C, 205*C, "DeepSkyBlue3",
+ 0*C, 104*C, 139*C, "DeepSkyBlue4",
+105*C, 105*C, 105*C, "dim gray",
+105*C, 105*C, 105*C, "dim grey",
+105*C, 105*C, 105*C, "DimGray",
+105*C, 105*C, 105*C, "DimGrey",
+ 30*C, 144*C, 255*C, "dodger blue",
+ 30*C, 144*C, 255*C, "DodgerBlue",
+ 30*C, 144*C, 255*C, "DodgerBlue1",
+ 28*C, 134*C, 238*C, "DodgerBlue2",
+ 24*C, 116*C, 205*C, "DodgerBlue3",
+ 16*C, 78*C, 139*C, "DodgerBlue4",
+178*C, 34*C, 34*C, "firebrick",
+255*C, 48*C, 48*C, "firebrick1",
+238*C, 44*C, 44*C, "firebrick2",
+205*C, 38*C, 38*C, "firebrick3",
+139*C, 26*C, 26*C, "firebrick4",
+255*C, 250*C, 240*C, "floral white",
+255*C, 250*C, 240*C, "FloralWhite",
+ 34*C, 139*C, 34*C, "forest green",
+ 34*C, 139*C, 34*C, "ForestGreen",
+220*C, 220*C, 220*C, "gainsboro",
+248*C, 248*C, 255*C, "ghost white",
+248*C, 248*C, 255*C, "GhostWhite",
+255*C, 215*C, 0*C, "gold",
+255*C, 215*C, 0*C, "gold1",
+238*C, 201*C, 0*C, "gold2",
+205*C, 173*C, 0*C, "gold3",
+139*C, 117*C, 0*C, "gold4",
+218*C, 165*C, 32*C, "goldenrod",
+255*C, 193*C, 37*C, "goldenrod1",
+238*C, 180*C, 34*C, "goldenrod2",
+205*C, 155*C, 29*C, "goldenrod3",
+139*C, 105*C, 20*C, "goldenrod4",
+190*C, 190*C, 190*C, "gray",
+ 0*C, 0*C, 0*C, "gray0",
+ 3*C, 3*C, 3*C, "gray1",
+ 26*C, 26*C, 26*C, "gray10",
+255*C, 255*C, 255*C, "gray100",
+ 28*C, 28*C, 28*C, "gray11",
+ 31*C, 31*C, 31*C, "gray12",
+ 33*C, 33*C, 33*C, "gray13",
+ 36*C, 36*C, 36*C, "gray14",
+ 38*C, 38*C, 38*C, "gray15",
+ 41*C, 41*C, 41*C, "gray16",
+ 43*C, 43*C, 43*C, "gray17",
+ 46*C, 46*C, 46*C, "gray18",
+ 48*C, 48*C, 48*C, "gray19",
+ 5*C, 5*C, 5*C, "gray2",
+ 51*C, 51*C, 51*C, "gray20",
+ 54*C, 54*C, 54*C, "gray21",
+ 56*C, 56*C, 56*C, "gray22",
+ 59*C, 59*C, 59*C, "gray23",
+ 61*C, 61*C, 61*C, "gray24",
+ 64*C, 64*C, 64*C, "gray25",
+ 66*C, 66*C, 66*C, "gray26",
+ 69*C, 69*C, 69*C, "gray27",
+ 71*C, 71*C, 71*C, "gray28",
+ 74*C, 74*C, 74*C, "gray29",
+ 8*C, 8*C, 8*C, "gray3",
+ 77*C, 77*C, 77*C, "gray30",
+ 79*C, 79*C, 79*C, "gray31",
+ 82*C, 82*C, 82*C, "gray32",
+ 84*C, 84*C, 84*C, "gray33",
+ 87*C, 87*C, 87*C, "gray34",
+ 89*C, 89*C, 89*C, "gray35",
+ 92*C, 92*C, 92*C, "gray36",
+ 94*C, 94*C, 94*C, "gray37",
+ 97*C, 97*C, 97*C, "gray38",
+ 99*C, 99*C, 99*C, "gray39",
+ 10*C, 10*C, 10*C, "gray4",
+102*C, 102*C, 102*C, "gray40",
+105*C, 105*C, 105*C, "gray41",
+107*C, 107*C, 107*C, "gray42",
+110*C, 110*C, 110*C, "gray43",
+112*C, 112*C, 112*C, "gray44",
+115*C, 115*C, 115*C, "gray45",
+117*C, 117*C, 117*C, "gray46",
+120*C, 120*C, 120*C, "gray47",
+122*C, 122*C, 122*C, "gray48",
+125*C, 125*C, 125*C, "gray49",
+ 13*C, 13*C, 13*C, "gray5",
+127*C, 127*C, 127*C, "gray50",
+130*C, 130*C, 130*C, "gray51",
+133*C, 133*C, 133*C, "gray52",
+135*C, 135*C, 135*C, "gray53",
+138*C, 138*C, 138*C, "gray54",
+140*C, 140*C, 140*C, "gray55",
+143*C, 143*C, 143*C, "gray56",
+145*C, 145*C, 145*C, "gray57",
+148*C, 148*C, 148*C, "gray58",
+150*C, 150*C, 150*C, "gray59",
+ 15*C, 15*C, 15*C, "gray6",
+153*C, 153*C, 153*C, "gray60",
+156*C, 156*C, 156*C, "gray61",
+158*C, 158*C, 158*C, "gray62",
+161*C, 161*C, 161*C, "gray63",
+163*C, 163*C, 163*C, "gray64",
+166*C, 166*C, 166*C, "gray65",
+168*C, 168*C, 168*C, "gray66",
+171*C, 171*C, 171*C, "gray67",
+173*C, 173*C, 173*C, "gray68",
+176*C, 176*C, 176*C, "gray69",
+ 18*C, 18*C, 18*C, "gray7",
+179*C, 179*C, 179*C, "gray70",
+181*C, 181*C, 181*C, "gray71",
+184*C, 184*C, 184*C, "gray72",
+186*C, 186*C, 186*C, "gray73",
+189*C, 189*C, 189*C, "gray74",
+191*C, 191*C, 191*C, "gray75",
+194*C, 194*C, 194*C, "gray76",
+196*C, 196*C, 196*C, "gray77",
+199*C, 199*C, 199*C, "gray78",
+201*C, 201*C, 201*C, "gray79",
+ 20*C, 20*C, 20*C, "gray8",
+204*C, 204*C, 204*C, "gray80",
+207*C, 207*C, 207*C, "gray81",
+209*C, 209*C, 209*C, "gray82",
+212*C, 212*C, 212*C, "gray83",
+214*C, 214*C, 214*C, "gray84",
+217*C, 217*C, 217*C, "gray85",
+219*C, 219*C, 219*C, "gray86",
+222*C, 222*C, 222*C, "gray87",
+224*C, 224*C, 224*C, "gray88",
+227*C, 227*C, 227*C, "gray89",
+ 23*C, 23*C, 23*C, "gray9",
+229*C, 229*C, 229*C, "gray90",
+232*C, 232*C, 232*C, "gray91",
+235*C, 235*C, 235*C, "gray92",
+237*C, 237*C, 237*C, "gray93",
+240*C, 240*C, 240*C, "gray94",
+242*C, 242*C, 242*C, "gray95",
+245*C, 245*C, 245*C, "gray96",
+247*C, 247*C, 247*C, "gray97",
+250*C, 250*C, 250*C, "gray98",
+252*C, 252*C, 252*C, "gray99",
+ 0*C, 255*C, 0*C, "green",
+173*C, 255*C, 47*C, "green yellow",
+0*C, 255*C, 0*C, "green1",
+0*C, 238*C, 0*C, "green2",
+0*C, 205*C, 0*C, "green3",
+0*C, 139*C, 0*C, "green4",
+173*C, 255*C, 47*C, "GreenYellow",
+190*C, 190*C, 190*C, "grey",
+ 0*C, 0*C, 0*C, "grey0",
+ 3*C, 3*C, 3*C, "grey1",
+ 26*C, 26*C, 26*C, "grey10",
+255*C, 255*C, 255*C, "grey100",
+ 28*C, 28*C, 28*C, "grey11",
+ 31*C, 31*C, 31*C, "grey12",
+ 33*C, 33*C, 33*C, "grey13",
+ 36*C, 36*C, 36*C, "grey14",
+ 38*C, 38*C, 38*C, "grey15",
+ 41*C, 41*C, 41*C, "grey16",
+ 43*C, 43*C, 43*C, "grey17",
+ 46*C, 46*C, 46*C, "grey18",
+ 48*C, 48*C, 48*C, "grey19",
+ 5*C, 5*C, 5*C, "grey2",
+ 51*C, 51*C, 51*C, "grey20",
+ 54*C, 54*C, 54*C, "grey21",
+ 56*C, 56*C, 56*C, "grey22",
+ 59*C, 59*C, 59*C, "grey23",
+ 61*C, 61*C, 61*C, "grey24",
+ 64*C, 64*C, 64*C, "grey25",
+ 66*C, 66*C, 66*C, "grey26",
+ 69*C, 69*C, 69*C, "grey27",
+ 71*C, 71*C, 71*C, "grey28",
+ 74*C, 74*C, 74*C, "grey29",
+ 8*C, 8*C, 8*C, "grey3",
+ 77*C, 77*C, 77*C, "grey30",
+ 79*C, 79*C, 79*C, "grey31",
+ 82*C, 82*C, 82*C, "grey32",
+ 84*C, 84*C, 84*C, "grey33",
+ 87*C, 87*C, 87*C, "grey34",
+ 89*C, 89*C, 89*C, "grey35",
+ 92*C, 92*C, 92*C, "grey36",
+ 94*C, 94*C, 94*C, "grey37",
+ 97*C, 97*C, 97*C, "grey38",
+ 99*C, 99*C, 99*C, "grey39",
+ 10*C, 10*C, 10*C, "grey4",
+102*C, 102*C, 102*C, "grey40",
+105*C, 105*C, 105*C, "grey41",
+107*C, 107*C, 107*C, "grey42",
+110*C, 110*C, 110*C, "grey43",
+112*C, 112*C, 112*C, "grey44",
+115*C, 115*C, 115*C, "grey45",
+117*C, 117*C, 117*C, "grey46",
+120*C, 120*C, 120*C, "grey47",
+122*C, 122*C, 122*C, "grey48",
+125*C, 125*C, 125*C, "grey49",
+ 13*C, 13*C, 13*C, "grey5",
+127*C, 127*C, 127*C, "grey50",
+130*C, 130*C, 130*C, "grey51",
+133*C, 133*C, 133*C, "grey52",
+135*C, 135*C, 135*C, "grey53",
+138*C, 138*C, 138*C, "grey54",
+140*C, 140*C, 140*C, "grey55",
+143*C, 143*C, 143*C, "grey56",
+145*C, 145*C, 145*C, "grey57",
+148*C, 148*C, 148*C, "grey58",
+150*C, 150*C, 150*C, "grey59",
+ 15*C, 15*C, 15*C, "grey6",
+153*C, 153*C, 153*C, "grey60",
+156*C, 156*C, 156*C, "grey61",
+158*C, 158*C, 158*C, "grey62",
+161*C, 161*C, 161*C, "grey63",
+163*C, 163*C, 163*C, "grey64",
+166*C, 166*C, 166*C, "grey65",
+168*C, 168*C, 168*C, "grey66",
+171*C, 171*C, 171*C, "grey67",
+173*C, 173*C, 173*C, "grey68",
+176*C, 176*C, 176*C, "grey69",
+ 18*C, 18*C, 18*C, "grey7",
+179*C, 179*C, 179*C, "grey70",
+181*C, 181*C, 181*C, "grey71",
+184*C, 184*C, 184*C, "grey72",
+186*C, 186*C, 186*C, "grey73",
+189*C, 189*C, 189*C, "grey74",
+191*C, 191*C, 191*C, "grey75",
+194*C, 194*C, 194*C, "grey76",
+196*C, 196*C, 196*C, "grey77",
+199*C, 199*C, 199*C, "grey78",
+201*C, 201*C, 201*C, "grey79",
+ 20*C, 20*C, 20*C, "grey8",
+204*C, 204*C, 204*C, "grey80",
+207*C, 207*C, 207*C, "grey81",
+209*C, 209*C, 209*C, "grey82",
+212*C, 212*C, 212*C, "grey83",
+214*C, 214*C, 214*C, "grey84",
+217*C, 217*C, 217*C, "grey85",
+219*C, 219*C, 219*C, "grey86",
+222*C, 222*C, 222*C, "grey87",
+224*C, 224*C, 224*C, "grey88",
+227*C, 227*C, 227*C, "grey89",
+ 23*C, 23*C, 23*C, "grey9",
+229*C, 229*C, 229*C, "grey90",
+232*C, 232*C, 232*C, "grey91",
+235*C, 235*C, 235*C, "grey92",
+237*C, 237*C, 237*C, "grey93",
+240*C, 240*C, 240*C, "grey94",
+242*C, 242*C, 242*C, "grey95",
+245*C, 245*C, 245*C, "grey96",
+247*C, 247*C, 247*C, "grey97",
+250*C, 250*C, 250*C, "grey98",
+252*C, 252*C, 252*C, "grey99",
+240*C, 255*C, 240*C, "honeydew",
+240*C, 255*C, 240*C, "honeydew1",
+224*C, 238*C, 224*C, "honeydew2",
+193*C, 205*C, 193*C, "honeydew3",
+131*C, 139*C, 131*C, "honeydew4",
+255*C, 105*C, 180*C, "hot pink",
+255*C, 105*C, 180*C, "HotPink",
+255*C, 110*C, 180*C, "HotPink1",
+238*C, 106*C, 167*C, "HotPink2",
+205*C, 96*C, 144*C, "HotPink3",
+139*C, 58*C, 98*C, "HotPink4",
+205*C, 92*C, 92*C, "indian red",
+205*C, 92*C, 92*C, "IndianRed",
+255*C, 106*C, 106*C, "IndianRed1",
+238*C, 99*C, 99*C, "IndianRed2",
+205*C, 85*C, 85*C, "IndianRed3",
+139*C, 58*C, 58*C, "IndianRed4",
+255*C, 255*C, 240*C, "ivory",
+255*C, 255*C, 240*C, "ivory1",
+238*C, 238*C, 224*C, "ivory2",
+205*C, 205*C, 193*C, "ivory3",
+139*C, 139*C, 131*C, "ivory4",
+240*C, 230*C, 140*C, "khaki",
+255*C, 246*C, 143*C, "khaki1",
+238*C, 230*C, 133*C, "khaki2",
+205*C, 198*C, 115*C, "khaki3",
+139*C, 134*C, 78*C, "khaki4",
+230*C, 230*C, 250*C, "lavender",
+255*C, 240*C, 245*C, "lavender blush",
+255*C, 240*C, 245*C, "LavenderBlush",
+255*C, 240*C, 245*C, "LavenderBlush1",
+238*C, 224*C, 229*C, "LavenderBlush2",
+205*C, 193*C, 197*C, "LavenderBlush3",
+139*C, 131*C, 134*C, "LavenderBlush4",
+124*C, 252*C, 0*C, "lawn green",
+124*C, 252*C, 0*C, "LawnGreen",
+255*C, 250*C, 205*C, "lemon chiffon",
+255*C, 250*C, 205*C, "LemonChiffon",
+255*C, 250*C, 205*C, "LemonChiffon1",
+238*C, 233*C, 191*C, "LemonChiffon2",
+205*C, 201*C, 165*C, "LemonChiffon3",
+139*C, 137*C, 112*C, "LemonChiffon4",
+173*C, 216*C, 230*C, "light blue",
+240*C, 128*C, 128*C, "light coral",
+224*C, 255*C, 255*C, "light cyan",
+238*C, 221*C, 130*C, "light goldenrod",
+250*C, 250*C, 210*C, "light goldenrod yellow",
+211*C, 211*C, 211*C, "light gray",
+144*C, 238*C, 144*C, "light green",
+211*C, 211*C, 211*C, "light grey",
+255*C, 182*C, 193*C, "light pink",
+255*C, 160*C, 122*C, "light salmon",
+ 32*C, 178*C, 170*C, "light sea green",
+135*C, 206*C, 250*C, "light sky blue",
+132*C, 112*C, 255*C, "light slate blue",
+119*C, 136*C, 153*C, "light slate gray",
+119*C, 136*C, 153*C, "light slate grey",
+176*C, 196*C, 222*C, "light steel blue",
+255*C, 255*C, 224*C, "light yellow",
+173*C, 216*C, 230*C, "LightBlue",
+191*C, 239*C, 255*C, "LightBlue1",
+178*C, 223*C, 238*C, "LightBlue2",
+154*C, 192*C, 205*C, "LightBlue3",
+104*C, 131*C, 139*C, "LightBlue4",
+240*C, 128*C, 128*C, "LightCoral",
+224*C, 255*C, 255*C, "LightCyan",
+224*C, 255*C, 255*C, "LightCyan1",
+209*C, 238*C, 238*C, "LightCyan2",
+180*C, 205*C, 205*C, "LightCyan3",
+122*C, 139*C, 139*C, "LightCyan4",
+238*C, 221*C, 130*C, "LightGoldenrod",
+255*C, 236*C, 139*C, "LightGoldenrod1",
+238*C, 220*C, 130*C, "LightGoldenrod2",
+205*C, 190*C, 112*C, "LightGoldenrod3",
+139*C, 129*C, 76*C, "LightGoldenrod4",
+250*C, 250*C, 210*C, "LightGoldenrodYellow",
+211*C, 211*C, 211*C, "LightGray",
+144*C, 238*C, 144*C, "LightGreen",
+211*C, 211*C, 211*C, "LightGrey",
+255*C, 182*C, 193*C, "LightPink",
+255*C, 174*C, 185*C, "LightPink1",
+238*C, 162*C, 173*C, "LightPink2",
+205*C, 140*C, 149*C, "LightPink3",
+139*C, 95*C, 101*C, "LightPink4",
+255*C, 160*C, 122*C, "LightSalmon",
+255*C, 160*C, 122*C, "LightSalmon1",
+238*C, 149*C, 114*C, "LightSalmon2",
+205*C, 129*C, 98*C, "LightSalmon3",
+139*C, 87*C, 66*C, "LightSalmon4",
+ 32*C, 178*C, 170*C, "LightSeaGreen",
+135*C, 206*C, 250*C, "LightSkyBlue",
+176*C, 226*C, 255*C, "LightSkyBlue1",
+164*C, 211*C, 238*C, "LightSkyBlue2",
+141*C, 182*C, 205*C, "LightSkyBlue3",
+ 96*C, 123*C, 139*C, "LightSkyBlue4",
+132*C, 112*C, 255*C, "LightSlateBlue",
+119*C, 136*C, 153*C, "LightSlateGray",
+119*C, 136*C, 153*C, "LightSlateGrey",
+176*C, 196*C, 222*C, "LightSteelBlue",
+202*C, 225*C, 255*C, "LightSteelBlue1",
+188*C, 210*C, 238*C, "LightSteelBlue2",
+162*C, 181*C, 205*C, "LightSteelBlue3",
+110*C, 123*C, 139*C, "LightSteelBlue4",
+255*C, 255*C, 224*C, "LightYellow",
+255*C, 255*C, 224*C, "LightYellow1",
+238*C, 238*C, 209*C, "LightYellow2",
+205*C, 205*C, 180*C, "LightYellow3",
+139*C, 139*C, 122*C, "LightYellow4",
+ 50*C, 205*C, 50*C, "lime green",
+ 50*C, 205*C, 50*C, "LimeGreen",
+250*C, 240*C, 230*C, "linen",
+255*C, 0*C, 255*C, "magenta",
+255*C, 0*C, 255*C, "magenta1",
+238*C, 0*C, 238*C, "magenta2",
+205*C, 0*C, 205*C, "magenta3",
+139*C, 0*C, 139*C, "magenta4",
+176*C, 48*C, 96*C, "maroon",
+255*C, 52*C, 179*C, "maroon1",
+238*C, 48*C, 167*C, "maroon2",
+205*C, 41*C, 144*C, "maroon3",
+139*C, 28*C, 98*C, "maroon4",
+102*C, 205*C, 170*C, "medium aquamarine",
+ 0*C, 0*C, 205*C, "medium blue",
+186*C, 85*C, 211*C, "medium orchid",
+147*C, 112*C, 219*C, "medium purple",
+ 60*C, 179*C, 113*C, "medium sea green",
+123*C, 104*C, 238*C, "medium slate blue",
+ 0*C, 250*C, 154*C, "medium spring green",
+ 72*C, 209*C, 204*C, "medium turquoise",
+199*C, 21*C, 133*C, "medium violet red",
+102*C, 205*C, 170*C, "MediumAquamarine",
+ 0*C, 0*C, 205*C, "MediumBlue",
+186*C, 85*C, 211*C, "MediumOrchid",
+224*C, 102*C, 255*C, "MediumOrchid1",
+209*C, 95*C, 238*C, "MediumOrchid2",
+180*C, 82*C, 205*C, "MediumOrchid3",
+122*C, 55*C, 139*C, "MediumOrchid4",
+147*C, 112*C, 219*C, "MediumPurple",
+171*C, 130*C, 255*C, "MediumPurple1",
+159*C, 121*C, 238*C, "MediumPurple2",
+137*C, 104*C, 205*C, "MediumPurple3",
+ 93*C, 71*C, 139*C, "MediumPurple4",
+ 60*C, 179*C, 113*C, "MediumSeaGreen",
+123*C, 104*C, 238*C, "MediumSlateBlue",
+ 0*C, 250*C, 154*C, "MediumSpringGreen",
+ 72*C, 209*C, 204*C, "MediumTurquoise",
+199*C, 21*C, 133*C, "MediumVioletRed",
+ 25*C, 25*C, 112*C, "midnight blue",
+ 25*C, 25*C, 112*C, "MidnightBlue",
+245*C, 255*C, 250*C, "mint cream",
+245*C, 255*C, 250*C, "MintCream",
+255*C, 228*C, 225*C, "misty rose",
+255*C, 228*C, 225*C, "MistyRose",
+255*C, 228*C, 225*C, "MistyRose1",
+238*C, 213*C, 210*C, "MistyRose2",
+205*C, 183*C, 181*C, "MistyRose3",
+139*C, 125*C, 123*C, "MistyRose4",
+255*C, 228*C, 181*C, "moccasin",
+255*C, 222*C, 173*C, "navajo white",
+255*C, 222*C, 173*C, "NavajoWhite",
+255*C, 222*C, 173*C, "NavajoWhite1",
+238*C, 207*C, 161*C, "NavajoWhite2",
+205*C, 179*C, 139*C, "NavajoWhite3",
+139*C, 121*C, 94*C, "NavajoWhite4",
+ 0*C, 0*C, 128*C, "navy",
+ 0*C, 0*C, 128*C, "navy blue",
+ 0*C, 0*C, 128*C, "NavyBlue",
+253*C, 245*C, 230*C, "old lace",
+253*C, 245*C, 230*C, "OldLace",
+107*C, 142*C, 35*C, "olive drab",
+107*C, 142*C, 35*C, "OliveDrab",
+192*C, 255*C, 62*C, "OliveDrab1",
+179*C, 238*C, 58*C, "OliveDrab2",
+154*C, 205*C, 50*C, "OliveDrab3",
+105*C, 139*C, 34*C, "OliveDrab4",
+255*C, 165*C, 0*C, "orange",
+255*C, 69*C, 0*C, "orange red",
+255*C, 165*C, 0*C, "orange1",
+238*C, 154*C, 0*C, "orange2",
+205*C, 133*C, 0*C, "orange3",
+139*C, 90*C, 0*C, "orange4",
+255*C, 69*C, 0*C, "OrangeRed",
+255*C, 69*C, 0*C, "OrangeRed1",
+238*C, 64*C, 0*C, "OrangeRed2",
+205*C, 55*C, 0*C, "OrangeRed3",
+139*C, 37*C, 0*C, "OrangeRed4",
+218*C, 112*C, 214*C, "orchid",
+255*C, 131*C, 250*C, "orchid1",
+238*C, 122*C, 233*C, "orchid2",
+205*C, 105*C, 201*C, "orchid3",
+139*C, 71*C, 137*C, "orchid4",
+238*C, 232*C, 170*C, "pale goldenrod",
+152*C, 251*C, 152*C, "pale green",
+175*C, 238*C, 238*C, "pale turquoise",
+219*C, 112*C, 147*C, "pale violet red",
+238*C, 232*C, 170*C, "PaleGoldenrod",
+152*C, 251*C, 152*C, "PaleGreen",
+154*C, 255*C, 154*C, "PaleGreen1",
+144*C, 238*C, 144*C, "PaleGreen2",
+124*C, 205*C, 124*C, "PaleGreen3",
+84*C, 139*C, 84*C, "PaleGreen4",
+175*C, 238*C, 238*C, "PaleTurquoise",
+187*C, 255*C, 255*C, "PaleTurquoise1",
+174*C, 238*C, 238*C, "PaleTurquoise2",
+150*C, 205*C, 205*C, "PaleTurquoise3",
+102*C, 139*C, 139*C, "PaleTurquoise4",
+219*C, 112*C, 147*C, "PaleVioletRed",
+255*C, 130*C, 171*C, "PaleVioletRed1",
+238*C, 121*C, 159*C, "PaleVioletRed2",
+205*C, 104*C, 137*C, "PaleVioletRed3",
+139*C, 71*C, 93*C, "PaleVioletRed4",
+255*C, 239*C, 213*C, "papaya whip",
+255*C, 239*C, 213*C, "PapayaWhip",
+255*C, 218*C, 185*C, "peach puff",
+255*C, 218*C, 185*C, "PeachPuff",
+255*C, 218*C, 185*C, "PeachPuff1",
+238*C, 203*C, 173*C, "PeachPuff2",
+205*C, 175*C, 149*C, "PeachPuff3",
+139*C, 119*C, 101*C, "PeachPuff4",
+205*C, 133*C, 63*C, "peru",
+255*C, 192*C, 203*C, "pink",
+255*C, 181*C, 197*C, "pink1",
+238*C, 169*C, 184*C, "pink2",
+205*C, 145*C, 158*C, "pink3",
+139*C, 99*C, 108*C, "pink4",
+221*C, 160*C, 221*C, "plum",
+255*C, 187*C, 255*C, "plum1",
+238*C, 174*C, 238*C, "plum2",
+205*C, 150*C, 205*C, "plum3",
+139*C, 102*C, 139*C, "plum4",
+176*C, 224*C, 230*C, "powder blue",
+176*C, 224*C, 230*C, "PowderBlue",
+160*C, 32*C, 240*C, "purple",
+155*C, 48*C, 255*C, "purple1",
+145*C, 44*C, 238*C, "purple2",
+125*C, 38*C, 205*C, "purple3",
+ 85*C, 26*C, 139*C, "purple4",
+255*C, 0*C, 0*C, "red",
+255*C, 0*C, 0*C, "red1",
+238*C, 0*C, 0*C, "red2",
+205*C, 0*C, 0*C, "red3",
+139*C, 0*C, 0*C, "red4",
+188*C, 143*C, 143*C, "rosy brown",
+188*C, 143*C, 143*C, "RosyBrown",
+255*C, 193*C, 193*C, "RosyBrown1",
+238*C, 180*C, 180*C, "RosyBrown2",
+205*C, 155*C, 155*C, "RosyBrown3",
+139*C, 105*C, 105*C, "RosyBrown4",
+ 65*C, 105*C, 225*C, "royal blue",
+ 65*C, 105*C, 225*C, "RoyalBlue",
+ 72*C, 118*C, 255*C, "RoyalBlue1",
+ 67*C, 110*C, 238*C, "RoyalBlue2",
+ 58*C, 95*C, 205*C, "RoyalBlue3",
+ 39*C, 64*C, 139*C, "RoyalBlue4",
+139*C, 69*C, 19*C, "saddle brown",
+139*C, 69*C, 19*C, "SaddleBrown",
+250*C, 128*C, 114*C, "salmon",
+255*C, 140*C, 105*C, "salmon1",
+238*C, 130*C, 98*C, "salmon2",
+205*C, 112*C, 84*C, "salmon3",
+139*C, 76*C, 57*C, "salmon4",
+244*C, 164*C, 96*C, "sandy brown",
+244*C, 164*C, 96*C, "SandyBrown",
+ 46*C, 139*C, 87*C, "sea green",
+ 46*C, 139*C, 87*C, "SeaGreen",
+ 84*C, 255*C, 159*C, "SeaGreen1",
+ 78*C, 238*C, 148*C, "SeaGreen2",
+ 67*C, 205*C, 128*C, "SeaGreen3",
+46*C, 139*C, 87*C, "SeaGreen4",
+255*C, 245*C, 238*C, "seashell",
+255*C, 245*C, 238*C, "seashell1",
+238*C, 229*C, 222*C, "seashell2",
+205*C, 197*C, 191*C, "seashell3",
+139*C, 134*C, 130*C, "seashell4",
+160*C, 82*C, 45*C, "sienna",
+255*C, 130*C, 71*C, "sienna1",
+238*C, 121*C, 66*C, "sienna2",
+205*C, 104*C, 57*C, "sienna3",
+139*C, 71*C, 38*C, "sienna4",
+135*C, 206*C, 235*C, "sky blue",
+135*C, 206*C, 235*C, "SkyBlue",
+135*C, 206*C, 255*C, "SkyBlue1",
+126*C, 192*C, 238*C, "SkyBlue2",
+108*C, 166*C, 205*C, "SkyBlue3",
+ 74*C, 112*C, 139*C, "SkyBlue4",
+106*C, 90*C, 205*C, "slate blue",
+112*C, 128*C, 144*C, "slate gray",
+112*C, 128*C, 144*C, "slate grey",
+106*C, 90*C, 205*C, "SlateBlue",
+131*C, 111*C, 255*C, "SlateBlue1",
+122*C, 103*C, 238*C, "SlateBlue2",
+105*C, 89*C, 205*C, "SlateBlue3",
+ 71*C, 60*C, 139*C, "SlateBlue4",
+112*C, 128*C, 144*C, "SlateGray",
+198*C, 226*C, 255*C, "SlateGray1",
+185*C, 211*C, 238*C, "SlateGray2",
+159*C, 182*C, 205*C, "SlateGray3",
+108*C, 123*C, 139*C, "SlateGray4",
+112*C, 128*C, 144*C, "SlateGrey",
+255*C, 250*C, 250*C, "snow",
+255*C, 250*C, 250*C, "snow1",
+238*C, 233*C, 233*C, "snow2",
+205*C, 201*C, 201*C, "snow3",
+139*C, 137*C, 137*C, "snow4",
+ 0*C, 255*C, 127*C, "spring green",
+ 0*C, 255*C, 127*C, "SpringGreen",
+ 0*C, 255*C, 127*C, "SpringGreen1",
+ 0*C, 238*C, 118*C, "SpringGreen2",
+ 0*C, 205*C, 102*C, "SpringGreen3",
+0*C, 139*C, 69*C, "SpringGreen4",
+ 70*C, 130*C, 180*C, "steel blue",
+ 70*C, 130*C, 180*C, "SteelBlue",
+ 99*C, 184*C, 255*C, "SteelBlue1",
+ 92*C, 172*C, 238*C, "SteelBlue2",
+ 79*C, 148*C, 205*C, "SteelBlue3",
+ 54*C, 100*C, 139*C, "SteelBlue4",
+210*C, 180*C, 140*C, "tan",
+255*C, 165*C, 79*C, "tan1",
+238*C, 154*C, 73*C, "tan2",
+205*C, 133*C, 63*C, "tan3",
+139*C, 90*C, 43*C, "tan4",
+216*C, 191*C, 216*C, "thistle",
+255*C, 225*C, 255*C, "thistle1",
+238*C, 210*C, 238*C, "thistle2",
+205*C, 181*C, 205*C, "thistle3",
+139*C, 123*C, 139*C, "thistle4",
+255*C, 99*C, 71*C, "tomato",
+255*C, 99*C, 71*C, "tomato1",
+238*C, 92*C, 66*C, "tomato2",
+205*C, 79*C, 57*C, "tomato3",
+139*C, 54*C, 38*C, "tomato4",
+ 64*C, 224*C, 208*C, "turquoise",
+ 0*C, 245*C, 255*C, "turquoise1",
+ 0*C, 229*C, 238*C, "turquoise2",
+ 0*C, 197*C, 205*C, "turquoise3",
+ 0*C, 134*C, 139*C, "turquoise4",
+238*C, 130*C, 238*C, "violet",
+208*C, 32*C, 144*C, "violet red",
+208*C, 32*C, 144*C, "VioletRed",
+255*C, 62*C, 150*C, "VioletRed1",
+238*C, 58*C, 140*C, "VioletRed2",
+205*C, 50*C, 120*C, "VioletRed3",
+139*C, 34*C, 82*C, "VioletRed4",
+245*C, 222*C, 179*C, "wheat",
+255*C, 231*C, 186*C, "wheat1",
+238*C, 216*C, 174*C, "wheat2",
+205*C, 186*C, 150*C, "wheat3",
+139*C, 126*C, 102*C, "wheat4",
+255*C, 255*C, 255*C, "white",
+245*C, 245*C, 245*C, "white smoke",
+245*C, 245*C, 245*C, "WhiteSmoke",
+255*C, 255*C, 0*C, "yellow",
+154*C, 205*C, 50*C, "yellow green",
+255*C, 255*C, 0*C, "yellow1",
+238*C, 238*C, 0*C, "yellow2",
+205*C, 205*C, 0*C, "yellow3",
+139*C, 139*C, 0*C, "yellow4",
+154*C, 205*C, 50*C, "YellowGreen",
+};
+
+#undef C
+
+#define NUM_KD_COLORS (sizeof (KdColors) / sizeof (KdColors[0]))
+
+Bool
+OsInitColors()
+{
+ return TRUE;
+}
+
+Bool
+OsLookupColor(int screen,
+ char *s_name,
+ unsigned int len,
+ unsigned short *pred,
+ unsigned short *pgreen,
+ unsigned short *pblue)
+{
+ const KdNamedColor *c;
+ unsigned char *name = (unsigned char *) s_name;
+ int low, mid, high;
+ int r;
+
+ low = 0;
+ high = NUM_KD_COLORS;
+ while (high - low > 0)
+ {
+ mid = (low + high) / 2;
+ c = &KdColors[mid];
+ r = KdStrCaseCmp (c->name, name, len);
+ if (r == 0)
+ {
+ *pred = c->red;
+ *pgreen = c->green;
+ *pblue = c->blue;
+ return TRUE;
+ }
+ if (r < 0)
+ {
+ if (high == mid)
+ break;
+ high = mid;
+ }
+ else
+ {
+ if (low == mid)
+ break;
+ low = mid;
+ }
+ }
+ return FALSE;
+}
diff --git a/xc/programs/Xserver/hw/kdrive/kcurscol.c b/xc/programs/Xserver/hw/kdrive/kcurscol.c
new file mode 100644
index 000000000..e446d81bd
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/kcurscol.c
@@ -0,0 +1,92 @@
+/*
+ * $Id: kcurscol.c,v 1.1 2000/01/06 12:55:48 faith 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.
+ */
+
+#include "kdrive.h"
+#include "cursorstr.h"
+
+static int
+KdComputeCmapShift (unsigned long mask)
+{
+ int shift;
+ unsigned long bit;
+
+ shift = 16;
+ bit = 0x80000000;
+ while (!(mask & bit))
+ {
+ shift--;
+ bit >>= 1;
+ }
+ return shift;
+}
+
+#define Shift(v,d) ((d) < 0 ? ((v) >> (-d)) : ((v) << (d)))
+
+void
+KdAllocateCursorPixels (ScreenPtr pScreen,
+ CursorPtr pCursor,
+ Pixel *source,
+ Pixel *mask)
+{
+ xColorItem sourceColor, maskColor;
+ int r, g, b;
+ KdScreenPriv(pScreen);
+
+ if (pScreenPriv->screen->redMask)
+ {
+
+ r = KdComputeCmapShift (pScreenPriv->screen->redMask);
+ g = KdComputeCmapShift (pScreenPriv->screen->greenMask);
+ b = KdComputeCmapShift (pScreenPriv->screen->blueMask);
+ *source = ((Shift(pCursor->foreRed,r) & pScreenPriv->screen->redMask) |
+ (Shift(pCursor->foreGreen,g) & pScreenPriv->screen->greenMask) |
+ (Shift(pCursor->foreBlue,b) & pScreenPriv->screen->blueMask));
+ *mask = ((Shift(pCursor->backRed,r) & pScreenPriv->screen->redMask) |
+ (Shift(pCursor->backGreen,g) & pScreenPriv->screen->greenMask) |
+ (Shift(pCursor->backBlue,b) & pScreenPriv->screen->blueMask));
+ }
+ else
+ {
+ /*
+ * Set these to an invalid pixel value so that
+ * when the store colors comes through, the cursor
+ * won't get recolored
+ */
+ *source = ~0;
+ *mask = ~0;
+
+ 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);
+ *source = sourceColor.pixel;
+ *mask = maskColor.pixel;
+ }
+}
diff --git a/xc/programs/Xserver/hw/kdrive/kdrive.c b/xc/programs/Xserver/hw/kdrive/kdrive.c
new file mode 100644
index 000000000..ec8a87f87
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/kdrive.c
@@ -0,0 +1,897 @@
+/*
+ * $Id: kdrive.c,v 1.1 2000/01/06 12:55:46 faith 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/kdrive.c,v 1.2 1999/12/30 03:03:05 robin Exp $ */
+
+#include "kdrive.h"
+#ifdef PSEUDO8
+#include "pseudo8/pseudo8.h"
+#endif
+#include <mivalidate.h>
+#include <dixstruct.h>
+
+CARD8 kdBpp[] = { 1, 4, 8, 16, 24, 32 };
+
+#define NUM_KD_BPP (sizeof (kdBpp) / sizeof (kdBpp[0]))
+
+int kdScreenPrivateIndex;
+unsigned long kdGeneration;
+
+Bool kdVideoTest;
+unsigned long kdVideoTestTime;
+Bool kdEmulateMiddleButton;
+Bool kdDisableZaphod;
+Bool kdEnabled;
+Bool kdSwitchPending;
+
+/*
+ * Carry arguments from InitOutput through driver initialization
+ * to KdScreenInit
+ */
+
+KdOsFuncs *kdOsFuncs;
+extern WindowPtr *WindowTable;
+
+void
+KdSetRootClip (ScreenPtr pScreen, BOOL enable)
+{
+#ifndef FB_OLD_SCREEN
+ WindowPtr pWin = WindowTable[pScreen->myNum];
+ WindowPtr pChild;
+ Bool WasViewable = (Bool)(pWin->viewable);
+ Bool anyMarked;
+ RegionPtr pOldClip, bsExposed;
+#ifdef DO_SAVE_UNDERS
+ Bool dosave = FALSE;
+#endif
+ WindowPtr pLayerWin;
+ BoxRec box;
+
+ if (WasViewable)
+ {
+ for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib)
+ {
+ (void) (*pScreen->MarkOverlappedWindows)(pChild,
+ pChild,
+ &pLayerWin);
+ }
+ (*pScreen->MarkWindow) (pWin);
+ anyMarked = TRUE;
+ if (pWin->valdata)
+ {
+ if (HasBorder (pWin))
+ {
+ RegionPtr borderVisible;
+
+ borderVisible = REGION_CREATE(pScreen, NullBox, 1);
+ REGION_SUBTRACT(pScreen, borderVisible,
+ &pWin->borderClip, &pWin->winSize);
+ pWin->valdata->before.borderVisible = borderVisible;
+ }
+ pWin->valdata->before.resized = TRUE;
+ }
+ }
+
+ if (enable)
+ {
+ box.x1 = 0;
+ box.y1 = 0;
+ box.x2 = pScreen->width;
+ box.y2 = pScreen->height;
+ REGION_RESET(pScreen, &pWin->borderClip, &box);
+ REGION_BREAK (pWin->drawable.pScreen, &pWin->clipList);
+ }
+ else
+ {
+ REGION_EMPTY(pScreen, &pWin->borderClip);
+ REGION_BREAK (pWin->drawable.pScreen, &pWin->clipList);
+ }
+
+ ResizeChildrenWinSize (pWin, 0, 0, 0, 0);
+
+ if (WasViewable)
+ {
+ if (pWin->backStorage)
+ {
+ pOldClip = REGION_CREATE(pScreen, NullBox, 1);
+ REGION_COPY(pScreen, pOldClip, &pWin->clipList);
+ }
+
+ if (pWin->firstChild)
+ {
+ anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin->firstChild,
+ pWin->firstChild,
+ (WindowPtr *)NULL);
+ }
+ else
+ {
+ (*pScreen->MarkWindow) (pWin);
+ anyMarked = TRUE;
+ }
+
+#ifdef DO_SAVE_UNDERS
+ if (DO_SAVE_UNDERS(pWin))
+ {
+ dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, pLayerWin);
+ }
+#endif /* DO_SAVE_UNDERS */
+
+ if (anyMarked)
+ (*pScreen->ValidateTree)(pWin, NullWindow, VTOther);
+ }
+
+ if (pWin->backStorage &&
+ ((pWin->backingStore == Always) || WasViewable))
+ {
+ if (!WasViewable)
+ pOldClip = &pWin->clipList; /* a convenient empty region */
+ bsExposed = (*pScreen->TranslateBackingStore)
+ (pWin, 0, 0, pOldClip,
+ pWin->drawable.x, pWin->drawable.y);
+ if (WasViewable)
+ REGION_DESTROY(pScreen, pOldClip);
+ if (bsExposed)
+ {
+ RegionPtr valExposed = NullRegion;
+
+ if (pWin->valdata)
+ valExposed = &pWin->valdata->after.exposed;
+ (*pScreen->WindowExposures) (pWin, valExposed, bsExposed);
+ if (valExposed)
+ REGION_EMPTY(pScreen, valExposed);
+ REGION_DESTROY(pScreen, bsExposed);
+ }
+ }
+ if (WasViewable)
+ {
+ if (anyMarked)
+ (*pScreen->HandleExposures)(pWin);
+#ifdef DO_SAVE_UNDERS
+ if (dosave)
+ (*pScreen->PostChangeSaveUnder)(pLayerWin, pLayerWin);
+#endif /* DO_SAVE_UNDERS */
+ if (anyMarked && pScreen->PostValidateTree)
+ (*pScreen->PostValidateTree)(pWin, NullWindow, VTOther);
+ }
+ if (pWin->realized)
+ WindowsRestructured ();
+#endif /* !FB_OLD_SCREEN */
+}
+
+void
+KdDisableScreen (ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+
+ if (!pScreenPriv->enabled)
+ return;
+ KdCheckSync (pScreen);
+ if (!pScreenPriv->closed)
+ KdSetRootClip (pScreen, FALSE);
+ KdDisableColormap (pScreen);
+ if (!pScreenPriv->screen->dumb)
+ (*pScreenPriv->card->cfuncs->disableAccel) (pScreen);
+ if (!pScreenPriv->screen->softCursor)
+ (*pScreenPriv->card->cfuncs->disableCursor) (pScreen);
+ if (pScreenPriv->card->cfuncs->dpms)
+ (*pScreenPriv->card->cfuncs->dpms) (pScreen, KD_DPMS_NORMAL);
+ pScreenPriv->enabled = FALSE;
+ (*pScreenPriv->card->cfuncs->disable) (pScreen);
+}
+
+void
+KdDisableScreens (void)
+{
+ KdCardInfo *card;
+ KdScreenInfo *screen;
+
+ if (kdEnabled)
+ {
+ kdEnabled = FALSE;
+ for (card = kdCardInfo; card; card = card->next)
+ {
+ for (screen = card->screenList; screen; screen = screen->next)
+ if (screen->mynum == card->selected && screen->pScreen)
+ KdDisableScreen (screen->pScreen);
+ if (card->driver)
+ (*card->cfuncs->restore) (card);
+ }
+ (*kdOsFuncs->Disable) ();
+ KdDisableInput ();
+ }
+}
+
+void
+KdEnableScreen (ScreenPtr pScreen)
+{
+ KdScreenPriv (pScreen);
+
+ if (pScreenPriv->enabled)
+ return;
+ (*pScreenPriv->card->cfuncs->enable) (pScreen);
+ pScreenPriv->enabled = TRUE;
+ pScreenPriv->card->selected = pScreenPriv->screen->mynum;
+ if (!pScreenPriv->screen->softCursor)
+ (*pScreenPriv->card->cfuncs->enableCursor) (pScreen);
+ if (!pScreenPriv->screen->dumb)
+ (*pScreenPriv->card->cfuncs->enableAccel) (pScreen);
+ KdEnableColormap (pScreen);
+ KdSetRootClip (pScreen, TRUE);
+ if (pScreenPriv->card->cfuncs->dpms)
+ (*pScreenPriv->card->cfuncs->dpms) (pScreen, pScreenPriv->dpmsState);
+}
+
+void
+KdEnableScreens (void)
+{
+ KdCardInfo *card;
+ KdScreenInfo *screen;
+
+ if (!kdEnabled)
+ {
+ kdEnabled = TRUE;
+ (*kdOsFuncs->Enable) ();
+ for (card = kdCardInfo; card; card = card->next)
+ {
+ (*card->cfuncs->preserve) (card);
+ for (screen = card->screenList; screen; screen = screen->next)
+ if (screen->mynum == card->selected && screen->pScreen)
+ KdEnableScreen (screen->pScreen);
+ }
+ KdEnableInput ();
+ }
+}
+
+void
+KdProcessSwitch (void)
+{
+ if (kdEnabled)
+ KdDisableScreens ();
+ else
+ {
+ KdReleaseAllKeys ();
+ KdEnableScreens ();
+ }
+}
+
+void
+AbortDDX(void)
+{
+ KdDisableScreens ();
+ if (kdOsFuncs)
+ {
+ if (kdEnabled)
+ (*kdOsFuncs->Disable) ();
+ (*kdOsFuncs->Fini) ();
+ }
+}
+
+void
+ddxUseMsg()
+{
+}
+
+void
+ddxGiveUp ()
+{
+ AbortDDX ();
+}
+
+void
+KdParseScreen (KdScreenInfo *screen,
+ char *arg)
+{
+ screen->width = 0;
+ screen->height = 0;
+ screen->depth = 0;
+ screen->rate = 0;
+ if (!arg)
+ return;
+
+ screen->width = atoi(arg);
+ arg = strchr (arg, 'x');
+ if (!arg)
+ return;
+ arg++;
+
+ screen->height = atoi(arg);
+ arg = strchr (arg, 'x');
+ if (!arg)
+ return;
+ arg++;
+
+ screen->depth = atoi(arg);
+ arg = strchr (arg, 'x');
+ if (!arg)
+ return;
+ arg++;
+
+ screen->rate = atoi(arg);
+ arg = strchr (arg, 'x');
+ if (!arg)
+ return;
+ arg++;
+}
+
+Bool kdDumbDriver;
+Bool kdSoftCursor;
+
+int
+KdProcessArgument (int argc, char **argv, int i)
+{
+ KdCardInfo *card;
+ KdScreenInfo *screen;
+
+ if (!strcmp (argv[i], "-card"))
+ {
+ if ((i+1) < argc)
+ InitCard (argv[i+1]);
+ else
+ UseMsg ();
+ return 2;
+ }
+ if (!strcmp (argv[i], "-screen"))
+ {
+ if ((i+1) < argc)
+ {
+ card = KdCardInfoLast ();
+ if (!card)
+ {
+ InitCard (0);
+ card = KdCardInfoLast ();
+ }
+ screen = KdScreenInfoAdd (card);
+ KdParseScreen (screen, argv[i+1]);
+ screen->dumb = kdDumbDriver;
+ screen->softCursor = kdSoftCursor;
+ kdDumbDriver = FALSE;
+ kdSoftCursor = FALSE;
+ }
+ else
+ UseMsg ();
+ return 2;
+ }
+ if (!strcmp (argv[i], "-zaphod"))
+ {
+ kdDisableZaphod = TRUE;
+ return 1;
+ }
+ if (!strcmp (argv[i], "-3button"))
+ {
+ kdEmulateMiddleButton = FALSE;
+ return 1;
+ }
+ if (!strcmp (argv[i], "-2button"))
+ {
+ kdEmulateMiddleButton = TRUE;
+ return 1;
+ }
+ if (!strcmp (argv[i], "-dumb"))
+ {
+ kdDumbDriver = TRUE;
+ return 1;
+ }
+ if (!strcmp (argv[i], "-softCursor"))
+ {
+ kdSoftCursor = TRUE;
+ return 1;
+ }
+ if (!strcmp (argv[i], "-videoTest"))
+ {
+ kdVideoTest = TRUE;
+ return 1;
+ }
+ if (!strcmp (argv[i], "-standalone"))
+ return 1;
+#ifdef PSEUDO8
+ return p8ProcessArgument (argc, argv, i);
+#else
+ return 0;
+#endif
+}
+
+/*
+ * These are getting tossed in here until I can think of where
+ * they really belong
+ */
+
+void
+KdOsInit (KdOsFuncs *pOsFuncs)
+{
+ kdOsFuncs = pOsFuncs;
+ if (pOsFuncs)
+ {
+ if (serverGeneration == 1)
+ (*pOsFuncs->Init) ();
+ }
+}
+
+Bool
+KdAllocatePrivates (ScreenPtr pScreen)
+{
+ KdPrivScreenPtr pScreenPriv;
+
+ if (kdGeneration != serverGeneration)
+ {
+ kdScreenPrivateIndex = AllocateScreenPrivateIndex();
+ kdGeneration = serverGeneration;
+ }
+ pScreenPriv = (KdPrivScreenPtr) xalloc(sizeof (*pScreenPriv));
+ memset (pScreenPriv, '\0', sizeof (KdPrivScreenRec));
+ if (!pScreenPriv)
+ return FALSE;
+ KdSetScreenPriv (pScreen, pScreenPriv);
+ return TRUE;
+}
+
+Bool
+KdCloseScreen (int index, ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ KdCardInfo *card = pScreenPriv->card;
+ Bool ret;
+
+ pScreenPriv->closed = TRUE;
+ pScreen->CloseScreen = pScreenPriv->CloseScreen;
+ ret = (*pScreen->CloseScreen) (index, pScreen);
+
+ if (pScreenPriv->dpmsState != KD_DPMS_NORMAL)
+ (*card->cfuncs->dpms) (pScreen, KD_DPMS_NORMAL);
+
+ if (screen->mynum == card->selected)
+ KdDisableScreen (pScreen);
+
+ /*
+ * Restore video hardware when last screen is closed
+ */
+ if (screen == card->screenList)
+ (*card->cfuncs->restore) (card);
+
+ if (!pScreenPriv->screen->dumb)
+ (*card->cfuncs->finiAccel) (pScreen);
+
+ if (!pScreenPriv->screen->softCursor)
+ (*card->cfuncs->finiCursor) (pScreen);
+
+ (*card->cfuncs->scrfini) (screen);
+
+ /*
+ * Clean up card when last screen is closed, DIX closes them in
+ * reverse order, thus we check for when the first in the list is closed
+ */
+ if (screen == card->screenList)
+ {
+ (*card->cfuncs->cardfini) (card);
+ /*
+ * Clean up OS when last card is closed
+ */
+ if (card == kdCardInfo)
+ {
+ if (kdEnabled)
+ {
+ kdEnabled = FALSE;
+ (*kdOsFuncs->Disable) ();
+ }
+ }
+ }
+
+ pScreenPriv->screen->pScreen = 0;
+
+ xfree ((pointer) pScreenPriv);
+ return ret;
+}
+
+Bool
+KdSaveScreen (ScreenPtr pScreen, int on)
+{
+ KdScreenPriv(pScreen);
+ int dpmsState;
+
+ if (!pScreenPriv->card->cfuncs->dpms)
+ return FALSE;
+
+ dpmsState = pScreenPriv->dpmsState;
+ switch (on) {
+ case SCREEN_SAVER_OFF:
+ dpmsState = KD_DPMS_NORMAL;
+ break;
+ case SCREEN_SAVER_ON:
+ if (dpmsState == KD_DPMS_NORMAL)
+ dpmsState = KD_DPMS_NORMAL+1;
+ break;
+ case SCREEN_SAVER_CYCLE:
+ if (dpmsState < KD_DPMS_MAX)
+ dpmsState++;
+ break;
+ case SCREEN_SAVER_FORCER:
+ break;
+ }
+ if (dpmsState != pScreenPriv->dpmsState)
+ {
+ if (pScreenPriv->enabled)
+ (*pScreenPriv->card->cfuncs->dpms) (pScreen, dpmsState);
+ pScreenPriv->dpmsState = dpmsState;
+ }
+ return TRUE;
+}
+
+Bool
+KdCreateWindow (WindowPtr pWin)
+{
+#ifndef PHOENIX
+ if (!pWin->parent)
+ {
+ KdScreenPriv(pWin->drawable.pScreen);
+
+ if (!pScreenPriv->enabled)
+ {
+ REGION_EMPTY (pWin->drawable.pScreen, &pWin->borderClip);
+ REGION_BREAK (pWin->drawable.pScreen, &pWin->clipList);
+ }
+ }
+#endif
+ return TRUE;
+}
+
+/* Pass through AddScreen, which doesn't take any closure */
+static KdScreenInfo *kdCurrentScreen;
+
+Bool
+KdScreenInit(int index, ScreenPtr pScreen, int argc, char **argv)
+{
+ KdScreenInfo *screen = kdCurrentScreen;
+ KdCardInfo *card = screen->card;
+ KdPrivScreenPtr pScreenPriv;
+
+ KdAllocatePrivates (pScreen);
+
+ pScreenPriv = KdGetScreenPriv(pScreen);
+
+ screen->pScreen = pScreen;
+ pScreenPriv->screen = screen;
+ pScreenPriv->card = card;
+ pScreenPriv->bytesPerPixel = screen->bitsPerPixel >> 3;
+ pScreenPriv->dpmsState = KD_DPMS_NORMAL;
+
+ /*
+ * This is done in this order so that backing store wraps
+ * our GC functions; fbFinishScreenInit initializes MI
+ * backing store
+ */
+ if (!fbSetupScreen (pScreen,
+ screen->frameBuffer,
+ screen->width, screen->height,
+ screen->dpix, screen->dpiy,
+ screen->pixelStride,
+ screen->bitsPerPixel))
+ {
+ return FALSE;
+ }
+
+ /*
+ * Set colormap functions
+ */
+ pScreen->InstallColormap = KdInstallColormap;
+ pScreen->UninstallColormap = KdUninstallColormap;
+ pScreen->ListInstalledColormaps = KdListInstalledColormaps;
+ pScreen->StoreColors = KdStoreColors;
+
+ pScreen->SaveScreen = KdSaveScreen;
+ pScreen->CreateWindow = KdCreateWindow;
+
+#ifdef FB_OLD_SCREEN
+ pScreenPriv->BackingStoreFuncs.SaveAreas = fbSaveAreas;
+ pScreenPriv->BackingStoreFuncs.RestoreAreas = fbSaveAreas;
+ pScreenPriv->BackingStoreFuncs.SetClipmaskRgn = 0;
+ pScreenPriv->BackingStoreFuncs.GetImagePixmap = 0;
+ pScreenPriv->BackingStoreFuncs.GetSpansPixmap = 0;
+#endif
+
+ if (!fbFinishScreenInit (pScreen,
+ screen->frameBuffer,
+ screen->width, screen->height,
+ screen->dpix, screen->dpiy,
+ screen->pixelStride,
+ screen->bitsPerPixel))
+ {
+ return FALSE;
+ }
+
+ /*
+ * Plug in our own block/wakeup handlers.
+ * miScreenInit installs NoopDDA in both places
+ */
+ pScreen->BlockHandler = KdBlockHandler;
+ pScreen->WakeupHandler = KdWakeupHandler;
+
+ if (card->cfuncs->initScreen)
+ if (!(*card->cfuncs->initScreen) (pScreen))
+ return FALSE;
+
+ if (!screen->dumb && card->cfuncs->initAccel)
+ if (!(*card->cfuncs->initAccel) (pScreen))
+ screen->dumb = TRUE;
+
+#ifdef PSEUDO8
+ (void) p8Init (pScreen, PSEUDO8_USE_DEFAULT);
+#endif
+
+ pScreen->backingStoreSupport = Always;
+#ifdef FB_OLD_SCREEN
+ miInitializeBackingStore (pScreen, &pScreenPriv->BackingStoreFuncs);
+#else
+ miInitializeBackingStore (pScreen);
+#endif
+ /*
+ * Wrap CloseScreen, the order now is:
+ * KdCloseScreen
+ * miBSCloseScreen
+ * fbCloseScreen
+ */
+ pScreenPriv->CloseScreen = pScreen->CloseScreen;
+ pScreen->CloseScreen = KdCloseScreen;
+
+ if (screen->softCursor ||
+ !card->cfuncs->initCursor ||
+ !(*card->cfuncs->initCursor) (pScreen))
+ {
+ /* Use MI for cursor display and event queueing. */
+ screen->softCursor = TRUE;
+ miDCInitialize(pScreen, &kdPointerScreenFuncs);
+ }
+
+ if (!fbCreateDefColormap (pScreen))
+ {
+ return FALSE;
+ }
+
+ /*
+ * Enable the hardware
+ */
+ if (!kdEnabled)
+ {
+ kdEnabled = TRUE;
+ (*kdOsFuncs->Enable) ();
+ }
+
+ if (screen->mynum == card->selected)
+ {
+ (*card->cfuncs->preserve) (card);
+ (*card->cfuncs->enable) (pScreen);
+ pScreenPriv->enabled = TRUE;
+ if (!screen->softCursor)
+ (*card->cfuncs->enableCursor) (pScreen);
+ KdEnableColormap (pScreen);
+ if (!screen->dumb)
+ (*card->cfuncs->enableAccel) (pScreen);
+ }
+
+ return TRUE;
+}
+
+void
+KdInitScreen (ScreenInfo *pScreenInfo,
+ KdScreenInfo *screen,
+ int argc,
+ char **argv)
+{
+ KdCardInfo *card = screen->card;
+ int i;
+
+ (*card->cfuncs->scrinit) (screen);
+
+ if (!screen->dpix)
+ screen->dpix = 75;
+
+ if (!screen->dpiy)
+ screen->dpiy = 75;
+ if (!card->cfuncs->initAccel)
+ screen->dumb = TRUE;
+ if (!card->cfuncs->initCursor)
+ screen->softCursor = TRUE;
+
+}
+
+Bool
+KdSetPixmapFormats (ScreenInfo *pScreenInfo)
+{
+ CARD8 depthToBpp[33]; /* depth -> bpp map */
+ KdCardInfo *card;
+ KdScreenInfo *screen;
+ int i;
+ PixmapFormatRec *format;
+
+ for (i = 1; i <= 32; i++)
+ depthToBpp[i] = 0;
+
+ /*
+ * Generate mappings between bitsPerPixel and depth,
+ * also ensure that all screens comply with protocol
+ * restrictions on equivalent formats for the same
+ * depth on different screens
+ */
+ for (card = kdCardInfo; card; card = card->next)
+ {
+ for (screen = card->screenList; screen; screen = screen->next)
+ {
+ if (!depthToBpp[screen->depth])
+ depthToBpp[screen->depth] = screen->bitsPerPixel;
+ else if (depthToBpp[screen->depth] != screen->bitsPerPixel)
+ return FALSE;
+ }
+ }
+
+ /*
+ * Fill in additional formats
+ */
+ for (i = 0; i < NUM_KD_BPP; i++)
+ if (!depthToBpp[kdBpp[i]])
+ depthToBpp[kdBpp[i]] = kdBpp[i];
+
+ pScreenInfo->imageByteOrder = IMAGE_BYTE_ORDER;
+ pScreenInfo->bitmapScanlineUnit = BITMAP_SCANLINE_UNIT;
+ pScreenInfo->bitmapScanlinePad = BITMAP_SCANLINE_PAD;
+ pScreenInfo->bitmapBitOrder = BITMAP_BIT_ORDER;
+
+ pScreenInfo->numPixmapFormats = 0;
+
+ for (i = 1; i <= 32; i++)
+ {
+ if (depthToBpp[i])
+ {
+ format = &pScreenInfo->formats[pScreenInfo->numPixmapFormats++];
+ format->depth = i;
+ format->bitsPerPixel = depthToBpp[i];
+ format->scanlinePad = BITMAP_SCANLINE_PAD;
+ }
+ }
+
+ return TRUE;
+}
+
+void
+KdAddScreen (ScreenInfo *pScreenInfo,
+ KdScreenInfo *screen,
+ int argc,
+ char **argv)
+{
+ int i;
+ /*
+ * Fill in fb visual type masks for this screen
+ */
+ for (i = 0; i < pScreenInfo->numPixmapFormats; i++)
+ {
+ unsigned long visuals;
+ Pixel rm, gm, bm;
+
+ if (pScreenInfo->formats[i].depth == screen->depth)
+ {
+ visuals = screen->visuals;
+ rm = screen->redMask;
+ gm = screen->greenMask;
+ bm = screen->blueMask;
+ }
+ else
+ {
+ visuals = 0;
+ rm = gm = bm = 0;
+ }
+ fbSetVisualTypesAndMasks (pScreenInfo->formats[i].depth,
+ visuals,
+ 8,
+ rm, gm, bm);
+ }
+
+ kdCurrentScreen = screen;
+
+ AddScreen (KdScreenInit, argc, argv);
+}
+
+void
+KdInitOutput (ScreenInfo *pScreenInfo,
+ int argc,
+ char **argv)
+{
+ int i;
+ KdCardInfo *card;
+ KdScreenInfo *screen;
+
+ if (!kdCardInfo)
+ {
+ InitCard (0);
+ card = KdCardInfoLast ();
+ screen = KdScreenInfoAdd (card);
+ KdParseScreen (screen, 0);
+ }
+ /*
+ * Initialize all of the screens for all of the cards
+ */
+ for (card = kdCardInfo; card; card = card->next)
+ {
+ if ((*card->cfuncs->cardinit) (card))
+ {
+ for (screen = card->screenList; screen; screen = screen->next)
+ KdInitScreen (pScreenInfo, screen, argc, argv);
+ }
+ }
+
+ /*
+ * Merge the various pixmap formats together, this can fail
+ * when two screens share depth but not bitsPerPixel
+ */
+ if (!KdSetPixmapFormats (pScreenInfo))
+ return;
+
+ /*
+ * Add all of the screens
+ */
+ for (card = kdCardInfo; card; card = card->next)
+ for (screen = card->screenList; screen; screen = screen->next)
+ KdAddScreen (pScreenInfo, screen, argc, argv);
+}
+
+#ifdef XTESTEXT1
+void
+XTestGenerateEvent(dev_type, keycode, keystate, mousex, mousey)
+ int dev_type;
+ int keycode;
+ int keystate;
+ int mousex;
+ int mousey;
+{
+}
+
+void
+XTestGetPointerPos(fmousex, fmousey)
+ short *fmousex, *fmousey;
+{
+}
+
+void
+XTestJumpPointer(jx, jy, dev_type)
+ int jx;
+ int jy;
+ int dev_type;
+{
+}
+#endif
+
+#ifdef DPMSExtension
+void
+DPMSSet(int level)
+{
+}
+
+int
+DPMSGet (int *level)
+{
+ return -1;
+}
+
+Bool
+DPMSSupported (void)
+{
+ return FALSE;
+}
+#endif
diff --git a/xc/programs/Xserver/hw/kdrive/kdrive.h b/xc/programs/Xserver/hw/kdrive/kdrive.h
new file mode 100644
index 000000000..ba5f5caaf
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/kdrive.h
@@ -0,0 +1,527 @@
+/*
+ * $Id: kdrive.h,v 1.1 2000/01/06 12:55:46 faith 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/kdrive.h,v 1.2 1999/12/30 03:03:06 robin Exp $ */
+
+#include <stdio.h>
+#include "X.h"
+#define NEED_EVENTS
+#include "Xproto.h"
+#include "Xos.h"
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "windowstr.h"
+#include "servermd.h"
+#include "mibstore.h"
+#include "colormapst.h"
+#include "gcstruct.h"
+#include "input.h"
+#include "mipointer.h"
+#include "mi.h"
+#include "dix.h"
+#include "fb.h"
+
+extern WindowPtr *WindowTable;
+
+#define KD_DPMS_NORMAL 0
+#define KD_DPMS_STANDBY 1
+#define KD_DPMS_SUSPEND 2
+#define KD_DPMS_POWERDOWN 3
+#define KD_DPMS_MAX KD_DPMS_POWERDOWN
+
+/*
+ * Configuration information per video card
+ */
+#define KD_MAX_CARD_ADDRESS 8
+typedef struct _KdCardAttr {
+ CARD32 io;
+ CARD32 address[KD_MAX_CARD_ADDRESS];
+ int naddr;
+} KdCardAttr;
+
+typedef struct _KdCardInfo {
+ struct _KdCardFuncs *cfuncs;
+ void *closure;
+ KdCardAttr attr;
+ void *driver;
+ struct _KdScreenInfo *screenList;
+ int selected;
+ struct _KdCardInfo *next;
+ Bool needSync;
+} KdCardInfo;
+
+extern KdCardInfo *kdCardInfo;
+
+/*
+ * Configuration information per X screen
+ */
+typedef struct _KdScreenInfo {
+ struct _KdScreenInfo *next;
+ KdCardInfo *card;
+ ScreenPtr pScreen;
+ void *driver;
+ CARD8 *frameBuffer;
+ int width;
+ int height;
+ int depth;
+ int rate;
+ int bitsPerPixel;
+ int pixelStride;
+ int byteStride;
+ int dpix, dpiy;
+ unsigned long visuals;
+ Pixel redMask, greenMask, blueMask;
+ Bool dumb;
+ Bool softCursor;
+ int mynum;
+} KdScreenInfo;
+
+typedef struct _KdCardFuncs {
+ Bool (*cardinit) (KdCardInfo *); /* detect and map device */
+ Bool (*scrinit) (KdScreenInfo *);/* initialize screen information */
+ Bool (*initScreen) (ScreenPtr); /* initialize ScreenRec */
+ void (*preserve) (KdCardInfo *); /* save graphics card state */
+ void (*enable) (ScreenPtr); /* set up for rendering */
+ Bool (*dpms) (ScreenPtr, int); /* set DPMS screen saver */
+ void (*disable) (ScreenPtr); /* turn off rendering */
+ void (*restore) (KdCardInfo *); /* restore graphics card state */
+ void (*scrfini) (KdScreenInfo *);/* close down screen */
+ void (*cardfini) (KdCardInfo *); /* close down */
+
+ Bool (*initCursor) (ScreenPtr); /* detect and map cursor */
+ void (*enableCursor) (ScreenPtr); /* enable cursor */
+ void (*disableCursor) (ScreenPtr); /* disable cursor */
+ void (*finiCursor) (ScreenPtr); /* close down */
+ void (*recolorCursor) (ScreenPtr, int, xColorItem *);
+
+ Bool (*initAccel) (ScreenPtr);
+ void (*enableAccel) (ScreenPtr);
+ void (*syncAccel) (ScreenPtr);
+ void (*disableAccel) (ScreenPtr);
+ void (*finiAccel) (ScreenPtr);
+
+ void (*getColors) (ScreenPtr, int, xColorItem *);
+ void (*putColors) (ScreenPtr, int, xColorItem *);
+} KdCardFuncs;
+
+#define KD_MAX_PSEUDO_DEPTH 8
+#define KD_MAX_PSEUDO_SIZE (1 << KD_MAX_PSEUDO_DEPTH)
+
+typedef struct {
+ KdScreenInfo *screen;
+ KdCardInfo *card;
+
+ Bool enabled;
+ Bool closed;
+ int bytesPerPixel;
+
+ int dpmsState;
+
+ ColormapPtr pInstalledmap; /* current colormap */
+ xColorItem systemPalette[KD_MAX_PSEUDO_SIZE];/* saved windows colors */
+
+ CloseScreenProcPtr CloseScreen;
+#ifdef FB_OLD_SCREEN
+ miBSFuncRec BackingStoreFuncs;
+#endif
+} KdPrivScreenRec, *KdPrivScreenPtr;
+
+typedef struct _KdMouseFuncs {
+ int (*Init) (void);
+ void (*Read) (int);
+ void (*Fini) (int);
+} KdMouseFuncs;
+
+typedef struct _KdKeyboardFuncs {
+ void (*Load) (void);
+ int (*Init) (void);
+ void (*Read) (int);
+ void (*Leds) (int);
+ void (*Bell) (int, int, int);
+ void (*Fini) (int);
+ int LockLed;
+} KdKeyboardFuncs;
+
+typedef struct _KdOsFuncs {
+ int (*Init) (void);
+ void (*Enable) (void);
+ Bool (*SpecialKey) (KeySym);
+ void (*Disable) (void);
+ void (*Fini) (void);
+} KdOsFuncs;
+
+typedef enum _KdSyncPolarity {
+ KdSyncNegative, KdSyncPositive
+} KdSyncPolarity;
+
+typedef struct _KdMonitorTiming {
+ /* label */
+ int horizontal;
+ int vertical;
+ int rate;
+ /* pixel clock */
+ int clock; /* in KHz */
+ /* horizontal timing */
+ int hfp; /* front porch */
+ int hbp; /* back porch */
+ int hblank; /* blanking */
+ KdSyncPolarity hpol; /* polarity */
+ /* vertical timing */
+ int vfp; /* front porch */
+ int vbp; /* back porch */
+ int vblank; /* blanking */
+ KdSyncPolarity vpol; /* polarity */
+} KdMonitorTiming;
+
+extern const KdMonitorTiming kdMonitorTimings[];
+extern const int kdNumMonitorTimings;
+
+/*
+ * This is the only completely portable way to
+ * compute this info.
+ */
+
+#ifndef BitsPerPixel
+#define BitsPerPixel(d) (\
+ PixmapWidthPaddingInfo[d].notPower2 ? \
+ (PixmapWidthPaddingInfo[d].bytesPerPixel * 8) : \
+ ((1 << PixmapWidthPaddingInfo[d].padBytesLog2) * 8 / \
+ (PixmapWidthPaddingInfo[d].padRoundUp+1)))
+#endif
+
+extern int kdScreenPrivateIndex;
+extern unsigned long kdGeneration;
+extern Bool kdEnabled;
+extern Bool kdSwitchPending;
+extern Bool kdEmulateMiddleButton;
+extern Bool kdDisableZaphod;
+extern KdOsFuncs *kdOsFuncs;
+
+#define KdGetScreenPriv(pScreen) ((KdPrivScreenPtr) \
+ (pScreen)->devPrivates[kdScreenPrivateIndex].ptr)
+#define KdSetScreenPriv(pScreen,v) ((pScreen)->devPrivates[kdScreenPrivateIndex].ptr = \
+ (pointer) v)
+#define KdScreenPriv(pScreen) KdPrivScreenPtr pScreenPriv = KdGetScreenPriv(pScreen)
+
+#define KdCheckSync(s) { \
+ KdScreenPriv(s); \
+ KdCardInfo *card = pScreenPriv->card; \
+ if (card->needSync) { \
+ card->needSync = FALSE; \
+ (*card->cfuncs->syncAccel) (s); \
+ } \
+}
+
+#define KdMarkSync(s) (KdGetScreenPriv(s)->card->needSync = TRUE)
+
+/* kasync.c */
+void
+KdCheckFillSpans (DrawablePtr pDrawable, GCPtr pGC, int nspans,
+ DDXPointPtr ppt, int *pwidth, int fSorted);
+
+void
+KdCheckSetSpans (DrawablePtr pDrawable, GCPtr pGC, char *psrc,
+ DDXPointPtr ppt, int *pwidth, int nspans, int fSorted);
+
+void
+KdCheckPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth,
+ int x, int y, int w, int h, int leftPad, int format,
+ char *bits);
+
+RegionPtr
+KdCheckCopyArea (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
+ int srcx, int srcy, int w, int h, int dstx, int dsty);
+
+RegionPtr
+KdCheckCopyPlane (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
+ int srcx, int srcy, int w, int h, int dstx, int dsty,
+ unsigned long bitPlane);
+
+void
+KdCheckPolyPoint (DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
+ DDXPointPtr pptInit);
+
+void
+KdCheckPolylines (DrawablePtr pDrawable, GCPtr pGC,
+ int mode, int npt, DDXPointPtr ppt);
+
+#define KdCheckPolySegment miPolySegment
+#define KdCheckPolyRectangle miPolyRectangle
+
+void
+KdCheckPolyArc (DrawablePtr pDrawable, GCPtr pGC,
+ int narcs, xArc *pArcs);
+
+#define KdCheckFillPolygon miFillPolygon
+
+void
+KdCheckPolyFillRect (DrawablePtr pDrawable, GCPtr pGC,
+ int nrect, xRectangle *prect);
+
+#define KdCheckPolyFillArc miPolyFillArc
+
+void
+KdCheckImageGlyphBlt (DrawablePtr pDrawable, GCPtr pGC,
+ int x, int y, unsigned int nglyph,
+ CharInfoPtr *ppci, pointer pglyphBase);
+
+void
+KdCheckPolyGlyphBlt (DrawablePtr pDrawable, GCPtr pGC,
+ int x, int y, unsigned int nglyph,
+ CharInfoPtr *ppci, pointer pglyphBase);
+
+void
+KdCheckPushPixels (GCPtr pGC, PixmapPtr pBitmap,
+ DrawablePtr pDrawable,
+ int w, int h, int x, int y);
+
+void
+KdCheckGetImage (DrawablePtr pDrawable,
+ int x, int y, int w, int h,
+ unsigned int format, unsigned long planeMask,
+ char *d);
+
+void
+KdCheckGetSpans (DrawablePtr pDrawable,
+ int wMax,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int nspans,
+ char *pdstStart);
+
+void
+KdCheckSaveAreas (PixmapPtr pPixmap,
+ RegionPtr prgnSave,
+ int xorg,
+ int yorg,
+ WindowPtr pWin);
+
+void
+KdCheckRestoreAreas (PixmapPtr pPixmap,
+ RegionPtr prgnSave,
+ int xorg,
+ int yorg,
+ WindowPtr pWin);
+
+void
+KdScreenInitAsync (ScreenPtr pScreen);
+
+void
+KdCheckPaintWindow (WindowPtr pWin, RegionPtr pRegion, int what);
+
+extern const GCOps kdAsyncPixmapGCOps;
+
+/* knoop.c */
+extern GCOps kdNoopOps;
+
+/* kcmap.c */
+void
+KdSetColormap (ScreenPtr pScreen);
+
+void
+KdEnableColormap (ScreenPtr pScreen);
+
+void
+KdDisableColormap (ScreenPtr pScreen);
+
+void
+KdInstallColormap (ColormapPtr pCmap);
+
+void
+KdUninstallColormap (ColormapPtr pCmap);
+
+int
+KdListInstalledColormaps (ScreenPtr pScreen, Colormap *pCmaps);
+
+void
+KdStoreColors (ColormapPtr pCmap, int ndef, xColorItem *pdefs);
+
+/* kcurscol.c */
+void
+KdAllocateCursorPixels (ScreenPtr pScreen,
+ CursorPtr pCursor,
+ Pixel *source,
+ Pixel *mask);
+
+/* kdrive.c */
+extern miPointerScreenFuncRec kdPointerScreenFuncs;
+
+void
+KdSetRootClip (ScreenPtr pScreen, BOOL enable);
+
+void
+KdDisableScreen (ScreenPtr pScreen);
+
+void
+KdDisableScreens (void);
+
+void
+KdEnableScreen (ScreenPtr pScreen);
+
+void
+KdEnableScreens (void);
+
+void
+KdProcessSwitch (void);
+
+void
+KdParseScreen (KdScreenInfo *screen,
+ char *arg);
+
+void
+KdOsInit (KdOsFuncs *pOsFuncs);
+
+Bool
+KdAllocatePrivates (ScreenPtr pScreen);
+
+Bool
+KdCloseScreen (int index, ScreenPtr pScreen);
+
+Bool
+KdSaveScreen (ScreenPtr pScreen, int on);
+
+Bool
+KdScreenInit(int index, ScreenPtr pScreen, int argc, char **argv);
+
+void
+KdInitScreen (ScreenInfo *pScreenInfo,
+ KdScreenInfo *screen,
+ int argc,
+ char **argv);
+
+void
+KdInitCard (ScreenInfo *pScreenInfo,
+ KdCardInfo *card,
+ int argc,
+ char **argv);
+
+void
+KdInitOutput (ScreenInfo *pScreenInfo,
+ int argc,
+ char **argv);
+
+
+
+void
+KdInitOutput (ScreenInfo *pScreenInfo,
+ int argc, char **argv);
+
+/* kinfo.c */
+KdCardInfo *
+KdCardInfoAdd (KdCardFuncs *funcs,
+ KdCardAttr *attr,
+ void *closure);
+
+KdCardInfo *
+KdCardInfoLast (void);
+
+void
+KdCardInfoDispose (KdCardInfo *ci);
+
+KdScreenInfo *
+KdScreenInfoAdd (KdCardInfo *ci);
+
+void
+KdScreenInfoDispose (KdScreenInfo *si);
+
+
+/* kinput.c */
+void
+KdInitInput(KdMouseFuncs *, KdKeyboardFuncs *);
+
+void
+KdEnqueueKeyboardEvent(unsigned char scan_code,
+ unsigned char is_up);
+
+#define KD_BUTTON_1 0x01
+#define KD_BUTTON_2 0x02
+#define KD_BUTTON_3 0x04
+#define KD_MOUSE_DELTA 0x80000000
+
+void
+KdEnqueueMouseEvent(unsigned long flags, int x, int y);
+
+void
+KdEnqueueMotionEvent (int x, int y);
+
+void
+KdReleaseAllKeys (void);
+
+void
+KdSetLed (int led, Bool on);
+
+void
+KdBlockHandler (int screen,
+ pointer blockData,
+ pointer timeout,
+ pointer readmask);
+
+void
+KdWakeupHandler (int screen,
+ pointer data,
+ unsigned long result,
+ pointer readmask);
+
+void
+KdDisableInput (void);
+
+void
+KdEnableInput (void);
+
+void
+ProcessInputEvents ();
+
+extern KdMouseFuncs Ps2MouseFuncs;
+extern KdKeyboardFuncs LinuxKeyboardFuncs;
+extern KdOsFuncs LinuxFuncs;
+
+extern KdMouseFuncs VxWorksMouseFuncs;
+extern KdKeyboardFuncs VxWorksKeyboardFuncs;
+extern KdOsFuncs VxWorksFuncs;
+
+/* kmap.c */
+void *
+KdMapDevice (CARD32 addr, CARD32 size);
+
+void
+KdUnmapDevice (void *addr, CARD32 size);
+
+/* kmode.c */
+const KdMonitorTiming *
+KdFindMode (KdScreenInfo *screen,
+ Bool (*supported) (KdScreenInfo *,
+ const KdMonitorTiming *));
+
+Bool
+KdTuneMode (KdScreenInfo *screen,
+ Bool (*usable) (KdScreenInfo *),
+ Bool (*supported) (KdScreenInfo *,
+ const KdMonitorTiming *));
+
+/* ktest.c */
+Bool
+KdFrameBufferValid (CARD8 *base, int size);
+
+int
+KdFrameBufferSize (CARD8 *base, int max);
+
diff --git a/xc/programs/Xserver/hw/kdrive/keyboard.c b/xc/programs/Xserver/hw/kdrive/keyboard.c
new file mode 100644
index 000000000..cd8b7e129
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/keyboard.c
@@ -0,0 +1,440 @@
+/*
+ * $Id: keyboard.c,v 1.1 2000/01/06 12:55:47 faith 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/keyboard.c,v 1.1 1999/11/19 13:53:49 hohndel Exp $ */
+
+#include "kdrive.h"
+#include "kkeymap.h"
+#include <linux/keyboard.h>
+#include <linux/kd.h>
+#include <X11/keysym.h>
+#include <termios.h>
+
+extern int LinuxConsoleFd;
+
+static KeySym linux_to_x[256] = {
+ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+ XK_BackSpace, XK_Tab, XK_Linefeed, NoSymbol,
+ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+ NoSymbol, NoSymbol, NoSymbol, XK_Escape,
+ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+ XK_space, XK_exclam, XK_quotedbl, XK_numbersign,
+ XK_dollar, XK_percent, XK_ampersand, XK_apostrophe,
+ XK_parenleft, XK_parenright, XK_asterisk, XK_plus,
+ XK_comma, XK_minus, XK_period, XK_slash,
+ XK_0, XK_1, XK_2, XK_3,
+ XK_4, XK_5, XK_6, XK_7,
+ XK_8, XK_9, XK_colon, XK_semicolon,
+ XK_less, XK_equal, XK_greater, XK_question,
+ XK_at, XK_A, XK_B, XK_C,
+ XK_D, XK_E, XK_F, XK_G,
+ XK_H, XK_I, XK_J, XK_K,
+ XK_L, XK_M, XK_N, XK_O,
+ XK_P, XK_Q, XK_R, XK_S,
+ XK_T, XK_U, XK_V, XK_W,
+ XK_X, XK_Y, XK_Z, XK_bracketleft,
+ XK_backslash, XK_bracketright,XK_asciicircum, XK_underscore,
+ XK_grave, XK_a, XK_b, XK_c,
+ XK_d, XK_e, XK_f, XK_g,
+ XK_h, XK_i, XK_j, XK_k,
+ XK_l, XK_m, XK_n, XK_o,
+ XK_p, XK_q, XK_r, XK_s,
+ XK_t, XK_u, XK_v, XK_w,
+ XK_x, XK_y, XK_z, XK_braceleft,
+ XK_bar, XK_braceright, XK_asciitilde, XK_Delete,
+ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+ XK_nobreakspace,XK_exclamdown, XK_cent, XK_sterling,
+ XK_currency, XK_yen, XK_brokenbar, XK_section,
+ XK_diaeresis, XK_copyright, XK_ordfeminine, XK_guillemotleft,
+ XK_notsign, XK_hyphen, XK_registered, XK_macron,
+ XK_degree, XK_plusminus, XK_twosuperior, XK_threesuperior,
+ XK_acute, XK_mu, XK_paragraph, XK_periodcentered,
+ XK_cedilla, XK_onesuperior, XK_masculine, XK_guillemotright,
+ XK_onequarter, XK_onehalf, XK_threequarters,XK_questiondown,
+ XK_Agrave, XK_Aacute, XK_Acircumflex, XK_Atilde,
+ XK_Adiaeresis, XK_Aring, XK_AE, XK_Ccedilla,
+ XK_Egrave, XK_Eacute, XK_Ecircumflex, XK_Ediaeresis,
+ XK_Igrave, XK_Iacute, XK_Icircumflex, XK_Idiaeresis,
+ XK_ETH, XK_Ntilde, XK_Ograve, XK_Oacute,
+ XK_Ocircumflex, XK_Otilde, XK_Odiaeresis, XK_multiply,
+ XK_Ooblique, XK_Ugrave, XK_Uacute, XK_Ucircumflex,
+ XK_Udiaeresis, XK_Yacute, XK_THORN, XK_ssharp,
+ XK_agrave, XK_aacute, XK_acircumflex, XK_atilde,
+ XK_adiaeresis, XK_aring, XK_ae, XK_ccedilla,
+ XK_egrave, XK_eacute, XK_ecircumflex, XK_ediaeresis,
+ XK_igrave, XK_iacute, XK_icircumflex, XK_idiaeresis,
+ XK_eth, XK_ntilde, XK_ograve, XK_oacute,
+ XK_ocircumflex, XK_otilde, XK_odiaeresis, XK_division,
+ XK_oslash, XK_ugrave, XK_uacute, XK_ucircumflex,
+ XK_udiaeresis, XK_yacute, XK_thorn, XK_ydiaeresis
+};
+
+static unsigned char tbl[KD_MAX_WIDTH] =
+{
+ 0,
+ 1 << KG_SHIFT,
+ (1 << KG_ALT),
+ (1 << KG_ALT) | (1 << KG_SHIFT)
+};
+
+static void
+readKernelMapping()
+{
+ KeySym *k;
+ int i, j;
+ struct kbentry kbe;
+ int minKeyCode, maxKeyCode;
+
+ minKeyCode = NR_KEYS;
+ maxKeyCode = 0;
+ k = kdKeymap;
+ for (i = 0;
+ i < NR_KEYS && (maxKeyCode - minKeyCode + 1) < KD_MAX_LENGTH;
+ ++i)
+ {
+ kbe.kb_index = i;
+
+ for (j = 0; j < KD_MAX_WIDTH; ++j)
+ {
+ unsigned short kval;
+
+ k[j] = NoSymbol;
+
+ kbe.kb_table = tbl[j];
+ if (ioctl(LinuxConsoleFd, KDGKBENT, &kbe))
+ continue;
+
+ kval = KVAL(kbe.kb_value);
+ switch (KTYP(kbe.kb_value))
+ {
+ case KT_LATIN:
+ case KT_LETTER:
+ k[j] = linux_to_x[kval];
+ break;
+
+ case KT_FN:
+ if (kval <= 19)
+ k[j] = XK_F1 + kval;
+ else switch (kbe.kb_value)
+ {
+ case K_FIND:
+ k[j] = XK_Home; /* or XK_Find */
+ break;
+ case K_INSERT:
+ k[j] = XK_Insert;
+ break;
+ case K_REMOVE:
+ k[j] = XK_Delete;
+ break;
+ case K_SELECT:
+ k[j] = XK_End; /* or XK_Select */
+ break;
+ case K_PGUP:
+ k[j] = XK_Prior;
+ break;
+ case K_PGDN:
+ k[j] = XK_Next;
+ break;
+ case K_HELP:
+ k[j] = XK_Help;
+ break;
+ case K_DO:
+ k[j] = XK_Execute;
+ break;
+ case K_PAUSE:
+ k[j] = XK_Pause;
+ break;
+ case K_MACRO:
+ k[j] = XK_Menu;
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case KT_SPEC:
+ switch (kbe.kb_value)
+ {
+ case K_ENTER:
+ k[j] = XK_Return;
+ break;
+ case K_BREAK:
+ k[j] = XK_Break;
+ break;
+ case K_CAPS:
+ k[j] = XK_Caps_Lock;
+ break;
+ case K_NUM:
+ k[j] = XK_Num_Lock;
+ break;
+ case K_HOLD:
+ k[j] = XK_Scroll_Lock;
+ break;
+ case K_COMPOSE:
+ k[j] = XK_Multi_key;
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case KT_PAD:
+ switch (kbe.kb_value)
+ {
+ case K_PPLUS:
+ k[j] = XK_KP_Add;
+ break;
+ case K_PMINUS:
+ k[j] = XK_KP_Subtract;
+ break;
+ case K_PSTAR:
+ k[j] = XK_KP_Multiply;
+ break;
+ case K_PSLASH:
+ k[j] = XK_KP_Divide;
+ break;
+ case K_PENTER:
+ k[j] = XK_KP_Enter;
+ break;
+ case K_PCOMMA:
+ k[j] = XK_KP_Separator;
+ break;
+ case K_PDOT:
+ k[j] = XK_KP_Decimal;
+ break;
+ case K_PPLUSMINUS:
+ k[j] = XK_KP_Subtract;
+ break;
+ default:
+ if (kval <= 9)
+ k[j] = XK_KP_0 + kval;
+ break;
+ }
+ break;
+
+ /*
+ * KT_DEAD keys are for accelerated diacritical creation.
+ */
+ case KT_DEAD:
+ switch (kbe.kb_value)
+ {
+ case K_DGRAVE:
+ k[j] = XK_dead_grave;
+ break;
+ case K_DACUTE:
+ k[j] = XK_dead_acute;
+ break;
+ case K_DCIRCM:
+ k[j] = XK_dead_circumflex;
+ break;
+ case K_DTILDE:
+ k[j] = XK_dead_tilde;
+ break;
+ case K_DDIERE:
+ k[j] = XK_dead_diaeresis;
+ break;
+ }
+ break;
+
+ case KT_CUR:
+ switch (kbe.kb_value)
+ {
+ case K_DOWN:
+ k[j] = XK_Down;
+ break;
+ case K_LEFT:
+ k[j] = XK_Left;
+ break;
+ case K_RIGHT:
+ k[j] = XK_Right;
+ break;
+ case K_UP:
+ k[j] = XK_Up;
+ break;
+ }
+ break;
+
+ case KT_SHIFT:
+ switch (kbe.kb_value)
+ {
+ case K_ALTGR:
+ k[j] = XK_Alt_R;
+ break;
+ case K_ALT:
+ k[j] = (kbe.kb_index == 0x64 ?
+ XK_Alt_R : XK_Alt_L);
+ break;
+ case K_CTRL:
+ k[j] = (kbe.kb_index == 0x61 ?
+ XK_Control_R : XK_Control_L);
+ break;
+ case K_CTRLL:
+ k[j] = XK_Control_L;
+ break;
+ case K_CTRLR:
+ k[j] = XK_Control_R;
+ break;
+ case K_SHIFT:
+ k[j] = (kbe.kb_index == 0x36 ?
+ XK_Shift_R : XK_Shift_L);
+ break;
+ case K_SHIFTL:
+ k[j] = XK_Shift_L;
+ break;
+ case K_SHIFTR:
+ k[j] = XK_Shift_R;
+ break;
+ default:
+ break;
+ }
+ break;
+
+ /*
+ * KT_ASCII keys accumulate a 3 digit decimal number that gets
+ * emitted when the shift state changes. We can't emulate that.
+ */
+ case KT_ASCII:
+ break;
+
+ case KT_LOCK:
+ if (kbe.kb_value == K_SHIFTLOCK)
+ k[j] = XK_Shift_Lock;
+ break;
+
+ default:
+ break;
+ }
+ if (i < minKeyCode)
+ minKeyCode = i;
+ if (i > maxKeyCode)
+ maxKeyCode = i;
+ }
+
+ if (minKeyCode == NR_KEYS)
+ continue;
+
+ if (k[3] == k[2]) k[3] = NoSymbol;
+ if (k[2] == k[1]) k[2] = NoSymbol;
+ if (k[1] == k[0]) k[1] = NoSymbol;
+ if (k[0] == k[2] && k[1] == k[3]) k[2] = k[3] = NoSymbol;
+ if (k[3] == k[0] && k[2] == k[1] && k[2] == NoSymbol) k[3] =NoSymbol;
+
+ k += KD_MAX_WIDTH;
+ }
+ kdMinScanCode = minKeyCode;
+ kdMaxScanCode = maxKeyCode;
+}
+
+void
+LinuxKeyboardLoad (void)
+{
+ readKernelMapping ();
+}
+
+static int LinuxKbdTrans;
+static struct termios LinuxTermios;
+
+int
+LinuxKeyboardInit (void)
+{
+ struct termios nTty;
+
+ ioctl (LinuxConsoleFd, KDGKBMODE, &LinuxKbdTrans);
+ tcgetattr (LinuxConsoleFd, &LinuxTermios);
+
+ ioctl(LinuxConsoleFd, KDSKBMODE, K_MEDIUMRAW);
+ nTty = LinuxTermios;
+ nTty.c_iflag = (IGNPAR | IGNBRK) & (~PARMRK) & (~ISTRIP);
+ nTty.c_oflag = 0;
+ nTty.c_cflag = CREAD | CS8;
+ nTty.c_lflag = 0;
+ nTty.c_cc[VTIME]=0;
+ nTty.c_cc[VMIN]=1;
+ cfsetispeed(&nTty, 9600);
+ cfsetospeed(&nTty, 9600);
+ tcsetattr(LinuxConsoleFd, TCSANOW, &nTty);
+ return LinuxConsoleFd;
+}
+
+void
+LinuxKeyboardFini (int fd)
+{
+ ioctl(LinuxConsoleFd, KDSKBMODE, LinuxKbdTrans);
+ tcsetattr(LinuxConsoleFd, TCSANOW, &LinuxTermios);
+}
+
+void
+LinuxKeyboardRead (int fd)
+{
+ unsigned char buf[256], *b;
+ int n;
+
+ while ((n = read (fd, buf, sizeof (buf))) > 0)
+ {
+ b = buf;
+ while (n--)
+ {
+ KdEnqueueKeyboardEvent (b[0] & 0x7f, b[0] & 0x80);
+ b++;
+ }
+ }
+}
+
+void
+LinuxKeyboardLeds (int leds)
+{
+ ioctl (LinuxConsoleFd, KDSETLED, leds & 7);
+}
+
+void
+LinuxKeyboardBell (int volume, int pitch, int duration)
+{
+ if (volume && pitch)
+ {
+ ioctl(LinuxConsoleFd, KDMKTONE,
+ ((1193190 / pitch) & 0xffff) |
+ (((unsigned long)duration *
+ volume / 50) << 16));
+
+ }
+}
+
+KdKeyboardFuncs LinuxKeyboardFuncs = {
+ LinuxKeyboardLoad,
+ LinuxKeyboardInit,
+ LinuxKeyboardRead,
+ LinuxKeyboardLeds,
+ LinuxKeyboardBell,
+ LinuxKeyboardFini,
+ 3,
+};
diff --git a/xc/programs/Xserver/hw/kdrive/kinfo.c b/xc/programs/Xserver/hw/kdrive/kinfo.c
new file mode 100644
index 000000000..b2adaf5c8
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/kinfo.c
@@ -0,0 +1,110 @@
+/*
+ * $Id: kinfo.c,v 1.1 2000/01/06 12:55:47 faith 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/kinfo.c,v 1.1 1999/11/19 13:53:49 hohndel Exp $ */
+
+#include "kdrive.h"
+
+KdCardInfo *kdCardInfo;
+
+KdCardInfo *
+KdCardInfoAdd (KdCardFuncs *funcs,
+ KdCardAttr *attr,
+ void *closure)
+{
+ KdCardInfo *ci, **prev;
+
+ ci = (KdCardInfo *) xalloc (sizeof (KdCardInfo));
+ if (!ci)
+ return 0;
+ bzero (ci, sizeof (KdCardInfo));
+ for (prev = &kdCardInfo; *prev; prev = &(*prev)->next);
+ *prev = ci;
+ ci->cfuncs = funcs;
+ ci->attr = *attr;
+ ci->closure = closure;
+ ci->screenList = 0;
+ ci->selected = 0;
+ ci->next = 0;
+ return ci;
+}
+
+KdCardInfo *
+KdCardInfoLast (void)
+{
+ KdCardInfo *ci;
+
+ if (!kdCardInfo)
+ return 0;
+ for (ci = kdCardInfo; ci->next; ci = ci->next);
+ return ci;
+}
+
+void
+KdCardInfoDispose (KdCardInfo *ci)
+{
+ KdCardInfo **prev;
+
+ for (prev = &kdCardInfo; *prev; prev = &(*prev)->next)
+ if (*prev == ci)
+ {
+ *prev = ci->next;
+ xfree (ci);
+ break;
+ }
+}
+
+KdScreenInfo *
+KdScreenInfoAdd (KdCardInfo *ci)
+{
+ KdScreenInfo *si, **prev;
+ int n;
+
+ si = (KdScreenInfo *) xalloc (sizeof (KdScreenInfo));
+ if (!si)
+ return 0;
+ bzero (si, sizeof (KdScreenInfo));
+ for (prev = &ci->screenList, n = 0; *prev; prev = &(*prev)->next, n++);
+ *prev = si;
+ si->next = 0;
+ si->card = ci;
+ si->mynum = n;
+ return si;
+}
+
+void
+KdScreenInfoDispose (KdScreenInfo *si)
+{
+ KdCardInfo *ci = si->card;
+ KdScreenInfo **prev;
+
+ for (prev = &ci->screenList; *prev; prev = &(*prev)->next)
+ if (*prev == si)
+ {
+ *prev = si->next;
+ xfree (si);
+ if (!ci->screenList)
+ KdCardInfoDispose (ci);
+ break;
+ }
+}
diff --git a/xc/programs/Xserver/hw/kdrive/kinput.c b/xc/programs/Xserver/hw/kdrive/kinput.c
new file mode 100644
index 000000000..e8281232c
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/kinput.c
@@ -0,0 +1,1335 @@
+/*
+ * $Id: kinput.c,v 1.1 2000/01/06 12:55:47 faith 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/kinput.c,v 1.2 1999/12/30 03:03:06 robin Exp $ */
+
+#include "kdrive.h"
+#include "inputstr.h"
+
+#include <X11/keysym.h>
+#include "kkeymap.h"
+#include <signal.h>
+#include <stdio.h>
+
+static DeviceIntPtr pKdKeyboard, pKdPointer;
+
+static KdMouseFuncs *kdMouseFuncs;
+static KdKeyboardFuncs *kdKeyboardFuncs;
+static int kdMouseFd = -1;
+static int kdKeyboardFd = -1;
+static unsigned long kdEmulationTimeout;
+static Bool kdTimeoutPending;
+static int kdBellPitch;
+static int kdBellDuration;
+static int kdLeds;
+
+int kdMinScanCode;
+int kdMaxScanCode;
+int kdMinKeyCode;
+int kdMaxKeyCode;
+int kdKeymapWidth = KD_MAX_WIDTH;
+KeySym kdKeymap[KD_MAX_LENGTH * KD_MAX_WIDTH];
+CARD8 kdModMap[MAP_LENGTH];
+KeySymsRec kdKeySyms;
+
+
+void
+KdResetInputMachine (void);
+
+#define KD_MOUSEBUTTON_COUNT 3
+
+#define KD_KEY_COUNT 248
+
+CARD8 kdKeyState[KD_KEY_COUNT/8];
+
+#define IsKeyDown(key) ((kdKeyState[(key) >> 3] >> ((key) & 7)) & 1)
+
+void
+KdSigio (int sig)
+{
+ if (kdMouseFd >= 0)
+ (*kdMouseFuncs->Read) (kdMouseFd);
+ if (kdKeyboardFd >= 0)
+ (*kdKeyboardFuncs->Read) (kdKeyboardFd);
+}
+
+void
+KdBlockSigio (void)
+{
+ sigset_t set;
+
+ sigemptyset (&set);
+ sigaddset (&set, SIGIO);
+ sigprocmask (SIG_BLOCK, &set, 0);
+}
+
+void
+KdUnblockSigio (void)
+{
+ sigset_t set;
+
+ sigemptyset (&set);
+ sigaddset (&set, SIGIO);
+ sigprocmask (SIG_UNBLOCK, &set, 0);
+}
+
+#define VERIFY_SIGIO
+#ifdef VERIFY_SIGIO
+
+void
+KdAssertSigioBlocked (char *where)
+{
+ sigset_t set, old;
+
+ sigemptyset (&set);
+ sigprocmask (SIG_BLOCK, &set, &old);
+ if (!sigismember (&old, SIGIO))
+ ErrorF ("SIGIO not blocked at %s\n", where);
+}
+
+#else
+
+#define KdVerifySigioBlocked(s)
+
+#endif
+
+static int kdnFds;
+
+#ifdef FNONBLOCK
+#define NOBLOCK FNONBLOCK
+#else
+#define NOBLOCK FNDELAY
+#endif
+
+void
+KdAddFd (int fd)
+{
+ int flags;
+ struct sigaction act;
+ sigset_t set;
+
+ kdnFds++;
+ fcntl (fd, F_SETOWN, getpid());
+ flags = fcntl (fd, F_GETFL);
+ flags |= FASYNC|NOBLOCK;
+ fcntl (fd, F_SETFL, flags);
+ AddEnabledDevice (fd);
+ memset (&act, '\0', sizeof act);
+ act.sa_handler = KdSigio;
+ sigemptyset (&act.sa_mask);
+ sigaction (SIGIO, &act, 0);
+ sigemptyset (&set);
+ sigprocmask (SIG_SETMASK, &set, 0);
+}
+
+void
+KdRemoveFd (int fd)
+{
+ struct sigaction act;
+ int flags;
+
+ kdnFds--;
+ RemoveEnabledDevice (fd);
+ flags = fcntl (fd, F_GETFL);
+ flags &= ~(FASYNC|NOBLOCK);
+ fcntl (fd, F_SETFL, flags);
+ if (kdnFds == 0)
+ {
+ memset (&act, '\0', sizeof act);
+ act.sa_handler = SIG_IGN;
+ sigemptyset (&act.sa_mask);
+ sigaction (SIGIO, &act, 0);
+ }
+}
+
+void
+KdDisableInput (void)
+{
+ if (kdMouseFd >= 0)
+ KdRemoveFd (kdMouseFd);
+ if (kdKeyboardFd >= 0)
+ KdRemoveFd (kdKeyboardFd);
+}
+
+void
+KdEnableInput (void)
+{
+ if (kdMouseFd >= 0)
+ KdAddFd (kdMouseFd);
+ if (kdKeyboardFd >= 0)
+ KdAddFd (kdKeyboardFd);
+}
+
+static int
+KdMouseProc(DeviceIntPtr pDevice, int onoff)
+{
+ BYTE map[4];
+ DevicePtr pDev = (DevicePtr)pDevice;
+ int i;
+
+ if (!pDev)
+ return BadImplementation;
+
+ switch (onoff)
+ {
+ case DEVICE_INIT:
+ for (i = 1; i <= KD_MOUSEBUTTON_COUNT; i++)
+ map[i] = i;
+ InitPointerDeviceStruct(pDev, map, KD_MOUSEBUTTON_COUNT,
+ miPointerGetMotionEvents,
+ (PtrCtrlProcPtr)NoopDDA,
+ miPointerGetMotionBufferSize());
+ break;
+
+ case DEVICE_ON:
+ pDev->on = TRUE;
+ pKdPointer = pDevice;
+ if (kdMouseFuncs)
+ {
+ kdMouseFd = (*kdMouseFuncs->Init) ();
+ if (kdMouseFd >= 0)
+ KdAddFd (kdMouseFd);
+ }
+ break;
+ case DEVICE_OFF:
+ case DEVICE_CLOSE:
+ if (pDev->on)
+ {
+ pDev->on = FALSE;
+ pKdPointer = 0;
+ if (kdMouseFd >= 0)
+ {
+ KdRemoveFd (kdMouseFd);
+ (*kdMouseFuncs->Fini) (kdMouseFd);
+ kdMouseFd = -1;
+ }
+ }
+ break;
+ }
+ return Success;
+}
+
+Bool
+LegalModifier(unsigned int key, DevicePtr pDev)
+{
+ return TRUE;
+}
+
+static void
+KdBell (int volume, DeviceIntPtr pDev, pointer ctrl, int something)
+{
+ (*kdKeyboardFuncs->Bell) (volume, kdBellPitch, kdBellDuration);
+}
+
+
+static void
+KdSetLeds (void)
+{
+ (*kdKeyboardFuncs->Leds) (kdLeds);
+}
+
+void
+KdSetLed (int led, Bool on)
+{
+ NoteLedState (pKdKeyboard, led, on);
+ kdLeds = pKdKeyboard->kbdfeed->ctrl.leds;
+ KdSetLeds ();
+}
+
+static void
+KdKbdCtrl (DeviceIntPtr pDevice, KeybdCtrl *ctrl)
+{
+ kdLeds = ctrl->leds;
+ kdBellPitch = ctrl->bell_pitch;
+ kdBellDuration = ctrl->bell_duration;
+ KdSetLeds ();
+}
+
+static int
+KdKeybdProc(DeviceIntPtr pDevice, int onoff)
+{
+ Bool ret;
+ DevicePtr pDev = (DevicePtr)pDevice;
+
+ if (!pDev)
+ return BadImplementation;
+
+ switch (onoff)
+ {
+ case DEVICE_INIT:
+ if (pDev != LookupKeyboardDevice())
+ {
+ return !Success;
+ }
+ ret = InitKeyboardDeviceStruct(pDev,
+ &kdKeySyms,
+ kdModMap,
+ KdBell, KdKbdCtrl);
+ if (!ret)
+ return BadImplementation;
+ break;
+ case DEVICE_ON:
+ pDev->on = TRUE;
+ pKdKeyboard = pDevice;
+ if (kdKeyboardFuncs)
+ {
+ kdKeyboardFd = (*kdKeyboardFuncs->Init) ();
+ if (kdKeyboardFd >= 0)
+ KdAddFd (kdKeyboardFd);
+ }
+ break;
+ case DEVICE_OFF:
+ case DEVICE_CLOSE:
+ pKdKeyboard = 0;
+ if (pDev->on)
+ {
+ pDev->on = FALSE;
+ if (kdKeyboardFd >= 0)
+ {
+ KdRemoveFd (kdKeyboardFd);
+ (*kdKeyboardFuncs->Fini) (kdKeyboardFd);
+ kdKeyboardFd = -1;
+ }
+ }
+ break;
+ }
+ return Success;
+}
+
+extern KeybdCtrl defaultKeyboardControl;
+
+static void
+KdInitAutoRepeats (void)
+{
+ int key_code;
+ unsigned char mask;
+ int i;
+ unsigned char *repeats;
+
+ repeats = defaultKeyboardControl.autoRepeats;
+ memset (repeats, '\0', 32);
+ for (key_code = KD_MIN_KEYCODE; key_code <= KD_MAX_KEYCODE; key_code++)
+ {
+ if (!kdModMap[key_code])
+ {
+ i = key_code >> 3;
+ mask = 1 << (key_code & 7);
+ repeats[i] |= mask;
+ }
+ }
+}
+
+static void
+KdInitModMap (void)
+{
+ int key_code;
+ int row;
+ int width;
+ KeySym *syms;
+
+ width = kdKeySyms.mapWidth;
+ for (key_code = kdMinKeyCode; key_code <= kdMaxKeyCode; key_code++)
+ {
+ kdModMap[key_code] = 0;
+ syms = kdKeymap + (key_code - kdMinKeyCode) * width;
+ for (row = 0; row < width; row++, syms++)
+ {
+ switch (*syms) {
+ case XK_Control_L:
+ case XK_Control_R:
+ kdModMap[key_code] |= ControlMask;
+ break;
+ case XK_Shift_L:
+ case XK_Shift_R:
+ kdModMap[key_code] |= ShiftMask;
+ break;
+ case XK_Caps_Lock:
+ case XK_Shift_Lock:
+ kdModMap[key_code] |= LockMask;
+ break;
+ case XK_Alt_L:
+ case XK_Alt_R:
+ case XK_Meta_L:
+ case XK_Meta_R:
+ kdModMap[key_code] |= Mod1Mask;
+ break;
+ case XK_Num_Lock:
+ kdModMap[key_code] |= Mod2Mask;
+ break;
+ case XK_Super_L:
+ case XK_Super_R:
+ case XK_Hyper_L:
+ case XK_Hyper_R:
+ kdModMap[key_code] |= Mod3Mask;
+ break;
+ case XK_Mode_switch:
+ kdModMap[key_code] |= Mod4Mask;
+ break;
+ }
+ }
+ }
+}
+
+void
+KdInitInput(KdMouseFuncs *pMouseFuncs,
+ KdKeyboardFuncs *pKeyboardFuncs)
+{
+ DeviceIntPtr pKeyboard, pPointer;
+
+ kdMouseFuncs = pMouseFuncs;
+ kdKeyboardFuncs = pKeyboardFuncs;
+ memset (kdKeyState, '\0', sizeof (kdKeyState));
+ if (kdKeyboardFuncs)
+ (*kdKeyboardFuncs->Load) ();
+ kdMinKeyCode = kdMinScanCode + KD_KEY_OFFSET;
+ kdMaxKeyCode = kdMaxScanCode + KD_KEY_OFFSET;
+ kdKeySyms.map = kdKeymap;
+ kdKeySyms.minKeyCode = kdMinKeyCode;
+ kdKeySyms.maxKeyCode = kdMaxKeyCode;
+ kdKeySyms.mapWidth = kdKeymapWidth;
+ kdLeds = 0;
+ kdBellPitch = 1000;
+ kdBellDuration = 200;
+ KdInitModMap ();
+ KdInitAutoRepeats ();
+ KdResetInputMachine ();
+ pPointer = AddInputDevice(KdMouseProc, TRUE);
+ pKeyboard = AddInputDevice(KdKeybdProc, TRUE);
+ RegisterPointerDevice(pPointer);
+ RegisterKeyboardDevice(pKeyboard);
+ miRegisterPointerDevice(screenInfo.screens[0], pPointer);
+ mieqInit(&pKeyboard->public, &pPointer->public);
+#ifdef XINPUT
+ {
+ static long zero1, zero2;
+
+ SetExtInputCheck (&zero1, &zero2);
+ }
+#endif
+}
+
+/*
+ * Middle button emulation state machine
+ *
+ * Possible transitions:
+ * Button 1 press v1
+ * Button 1 release ^1
+ * Button 2 press v2
+ * Button 2 release ^2
+ * Button 3 press v3
+ * Button 3 release ^3
+ * Mouse motion <>
+ * Keyboard event k
+ * timeout ...
+ * outside box <->
+ *
+ * States:
+ * start
+ * button_1_pend
+ * button_1_down
+ * button_2_down
+ * button_3_pend
+ * button_3_down
+ * synthetic_2_down_13
+ * synthetic_2_down_3
+ * synthetic_2_down_1
+ *
+ * Transition diagram
+ *
+ * start
+ * v1 -> (hold) (settimeout) button_1_pend
+ * ^1 -> (deliver) start
+ * v2 -> (deliver) button_2_down
+ * ^2 -> (deliever) start
+ * v3 -> (hold) (settimeout) button_3_pend
+ * ^3 -> (deliver) start
+ * <> -> (deliver) start
+ * k -> (deliver) start
+ *
+ * button_1_pend (button 1 is down, timeout pending)
+ * ^1 -> (release) (deliver) start
+ * v2 -> (release) (deliver) button_1_down
+ * ^2 -> (release) (deliver) button_1_down
+ * v3 -> (cleartimeout) (generate v2) synthetic_2_down_13
+ * ^3 -> (release) (deliver) button_1_down
+ * <-> -> (release) (deliver) button_1_down
+ * <> -> (deliver) button_1_pend
+ * k -> (release) (deliver) button_1_down
+ * ... -> (release) button_1_down
+ *
+ * button_1_down (button 1 is down)
+ * ^1 -> (deliver) start
+ * v2 -> (deliver) button_1_down
+ * ^2 -> (deliver) button_1_down
+ * v3 -> (deliver) button_1_down
+ * ^3 -> (deliver) button_1_down
+ * <> -> (deliver) button_1_down
+ * k -> (deliver) button_1_down
+ *
+ * button_2_down (button 2 is down)
+ * v1 -> (deliver) button_2_down
+ * ^1 -> (deliver) button_2_down
+ * ^2 -> (deliver) start
+ * v3 -> (deliver) button_2_down
+ * ^3 -> (deliver) button_2_down
+ * <> -> (deliver) button_2_down
+ * k -> (deliver) button_2_down
+ *
+ * button_3_pend (button 3 is down, timeout pending)
+ * v1 -> (generate v2) synthetic_2_down
+ * ^1 -> (release) (deliver) button_3_down
+ * v2 -> (release) (deliver) button_3_down
+ * ^2 -> (release) (deliver) button_3_down
+ * ^3 -> (release) (deliver) start
+ * <-> -> (release) (deliver) button_3_down
+ * <> -> (deliver) button_3_pend
+ * k -> (release) (deliver) button_3_down
+ * ... -> (release) button_3_down
+ *
+ * button_3_down (button 3 is down)
+ * v1 -> (deliver) button_3_down
+ * ^1 -> (deliver) button_3_down
+ * v2 -> (deliver) button_3_down
+ * ^2 -> (deliver) button_3_down
+ * ^3 -> (deliver) start
+ * <> -> (deliver) button_3_down
+ * k -> (deliver) button_3_down
+ *
+ * synthetic_2_down_13 (button 1 and 3 are down)
+ * ^1 -> (generate ^2) synthetic_2_down_3
+ * v2 -> synthetic_2_down_13
+ * ^2 -> synthetic_2_down_13
+ * ^3 -> (generate ^2) synthetic_2_down_1
+ * <> -> (deliver) synthetic_2_down_13
+ * k -> (deliver) synthetic_2_down_13
+ *
+ * synthetic_2_down_3 (button 3 is down)
+ * v1 -> (deliver) synthetic_2_down_3
+ * ^1 -> (deliver) synthetic_2_down_3
+ * v2 -> synthetic_2_down_3
+ * ^2 -> synthetic_2_down_3
+ * ^3 -> start
+ * <> -> (deliver) synthetic_2_down_3
+ * k -> (deliver) synthetic_2_down_3
+ *
+ * synthetic_2_down_1 (button 1 is down)
+ * ^1 -> start
+ * v2 -> synthetic_2_down_1
+ * ^2 -> synthetic_2_down_1
+ * v3 -> (deliver) synthetic_2_down_1
+ * ^3 -> (deliver) synthetic_2_down_1
+ * <> -> (deliver) synthetic_2_down_1
+ * k -> (deliver) synthetic_2_down_1
+ */
+
+typedef enum _inputState {
+ start,
+ button_1_pend,
+ button_1_down,
+ button_2_down,
+ button_3_pend,
+ button_3_down,
+ synth_2_down_13,
+ synth_2_down_3,
+ synth_2_down_1,
+ num_input_states
+} KdInputState;
+
+typedef enum _inputClass {
+ down_1, up_1,
+ down_2, up_2,
+ down_3, up_3,
+ motion, outside_box,
+ keyboard, timeout,
+ num_input_class
+} KdInputClass;
+
+typedef enum _inputAction {
+ noop,
+ hold,
+ setto,
+ deliver,
+ release,
+ clearto,
+ gen_down_2,
+ gen_up_2
+} KdInputAction;
+
+#define MAX_ACTIONS 2
+
+typedef struct _inputTransition {
+ KdInputAction actions[MAX_ACTIONS];
+ KdInputState nextState;
+} KdInputTransition;
+
+KdInputTransition kdInputMachine[num_input_states][num_input_class] = {
+ /* start */
+ {
+ { { hold, setto }, button_1_pend }, /* v1 */
+ { { deliver, noop }, start }, /* ^1 */
+ { { deliver, noop }, button_2_down }, /* v2 */
+ { { deliver, noop }, start }, /* ^2 */
+ { { hold, setto }, button_3_pend }, /* v3 */
+ { { deliver, noop }, start }, /* ^3 */
+ { { deliver, noop }, start }, /* <> */
+ { { deliver, noop }, start }, /* <-> */
+ { { deliver, noop }, start }, /* k */
+ { { noop, noop }, start }, /* ... */
+ },
+ /* button_1_pend */
+ {
+ { { noop, noop }, button_1_pend }, /* v1 */
+ { { release, deliver }, start }, /* ^1 */
+ { { release, deliver }, button_1_down }, /* v2 */
+ { { release, deliver }, button_1_down }, /* ^2 */
+ { { clearto, gen_down_2 }, synth_2_down_13 }, /* v3 */
+ { { release, deliver }, button_1_down }, /* ^3 */
+ { { deliver, noop }, button_1_pend }, /* <> */
+ { { release, deliver }, button_1_down }, /* <-> */
+ { { release, deliver }, button_1_down }, /* k */
+ { { release, noop }, button_1_down }, /* ... */
+ },
+ /* button_1_down */
+ {
+ { { noop, noop }, button_1_down }, /* v1 */
+ { { deliver, noop }, start }, /* ^1 */
+ { { deliver, noop }, button_1_down }, /* v2 */
+ { { deliver, noop }, button_1_down }, /* ^2 */
+ { { deliver, noop }, button_1_down }, /* v3 */
+ { { deliver, noop }, button_1_down }, /* ^3 */
+ { { deliver, noop }, button_1_down }, /* <> */
+ { { deliver, noop }, button_1_down }, /* <-> */
+ { { deliver, noop }, button_1_down }, /* k */
+ { { noop, noop }, button_1_down }, /* ... */
+ },
+ /* button_2_down */
+ {
+ { { deliver, noop }, button_2_down }, /* v1 */
+ { { deliver, noop }, button_2_down }, /* ^1 */
+ { { noop, noop }, button_2_down }, /* v2 */
+ { { deliver, noop }, start }, /* ^2 */
+ { { deliver, noop }, button_2_down }, /* v3 */
+ { { deliver, noop }, button_2_down }, /* ^3 */
+ { { deliver, noop }, button_2_down }, /* <> */
+ { { deliver, noop }, button_2_down }, /* <-> */
+ { { deliver, noop }, button_2_down }, /* k */
+ { { noop, noop }, button_2_down }, /* ... */
+ },
+ /* button_3_pend */
+ {
+ { { clearto, gen_down_2 }, synth_2_down_13 }, /* v1 */
+ { { release, deliver }, button_3_down }, /* ^1 */
+ { { release, deliver }, button_3_down }, /* v2 */
+ { { release, deliver }, button_3_down }, /* ^2 */
+ { { release, deliver }, button_3_down }, /* v3 */
+ { { release, deliver }, start }, /* ^3 */
+ { { deliver, noop }, button_3_pend }, /* <> */
+ { { release, deliver }, button_3_down }, /* <-> */
+ { { release, deliver }, button_3_down }, /* k */
+ { { release, noop }, button_3_down }, /* ... */
+ },
+ /* button_3_down */
+ {
+ { { deliver, noop }, button_3_down }, /* v1 */
+ { { deliver, noop }, button_3_down }, /* ^1 */
+ { { deliver, noop }, button_3_down }, /* v2 */
+ { { deliver, noop }, button_3_down }, /* ^2 */
+ { { noop, noop }, button_3_down }, /* v3 */
+ { { deliver, noop }, start }, /* ^3 */
+ { { deliver, noop }, button_3_down }, /* <> */
+ { { deliver, noop }, button_3_down }, /* <-> */
+ { { deliver, noop }, button_3_down }, /* k */
+ { { noop, noop }, button_3_down }, /* ... */
+ },
+ /* synthetic_2_down_13 */
+ {
+ { { noop, noop }, synth_2_down_13 }, /* v1 */
+ { { gen_up_2, noop }, synth_2_down_3 }, /* ^1 */
+ { { noop, noop }, synth_2_down_13 }, /* v2 */
+ { { noop, noop }, synth_2_down_13 }, /* ^2 */
+ { { noop, noop }, synth_2_down_13 }, /* v3 */
+ { { gen_up_2, noop }, synth_2_down_1 }, /* ^3 */
+ { { deliver, noop }, synth_2_down_13 }, /* <> */
+ { { deliver, noop }, synth_2_down_13 }, /* <-> */
+ { { deliver, noop }, synth_2_down_13 }, /* k */
+ { { noop, noop }, synth_2_down_13 }, /* ... */
+ },
+ /* synthetic_2_down_3 */
+ {
+ { { deliver, noop }, synth_2_down_3 }, /* v1 */
+ { { deliver, noop }, synth_2_down_3 }, /* ^1 */
+ { { deliver, noop }, synth_2_down_3 }, /* v2 */
+ { { deliver, noop }, synth_2_down_3 }, /* ^2 */
+ { { noop, noop }, synth_2_down_3 }, /* v3 */
+ { { noop, noop }, start }, /* ^3 */
+ { { deliver, noop }, synth_2_down_3 }, /* <> */
+ { { deliver, noop }, synth_2_down_3 }, /* <-> */
+ { { deliver, noop }, synth_2_down_3 }, /* k */
+ { { noop, noop }, synth_2_down_3 }, /* ... */
+ },
+ /* synthetic_2_down_1 */
+ {
+ { { noop, noop }, synth_2_down_1 }, /* v1 */
+ { { noop, noop }, start }, /* ^1 */
+ { { deliver, noop }, synth_2_down_1 }, /* v2 */
+ { { deliver, noop }, synth_2_down_1 }, /* ^2 */
+ { { deliver, noop }, synth_2_down_1 }, /* v3 */
+ { { deliver, noop }, synth_2_down_1 }, /* ^3 */
+ { { deliver, noop }, synth_2_down_1 }, /* <> */
+ { { deliver, noop }, synth_2_down_1 }, /* <-> */
+ { { deliver, noop }, synth_2_down_1 }, /* k */
+ { { noop, noop }, synth_2_down_1 }, /* ... */
+ },
+};
+
+Bool kdEventHeld;
+xEvent kdHeldEvent;
+int kdEmulationDx, kdEmulationDy;
+
+#define EMULATION_WINDOW 10
+#define EMULATION_TIMEOUT 30
+
+#define EventX(e) ((e)->u.keyButtonPointer.rootX)
+#define EventY(e) ((e)->u.keyButtonPointer.rootY)
+
+KdInsideEmulationWindow (xEvent *ev)
+{
+ if (ev->u.keyButtonPointer.pad1)
+ {
+ kdEmulationDx += EventX(ev);
+ kdEmulationDy += EventY(ev);
+ }
+ else
+ {
+ kdEmulationDx = EventX(&kdHeldEvent) - EventX(ev);
+ kdEmulationDy = EventY(&kdHeldEvent) - EventY(ev);
+ }
+ return (abs (kdEmulationDx) < EMULATION_WINDOW &&
+ abs (kdEmulationDy) < EMULATION_WINDOW);
+}
+
+KdInputClass
+KdClassifyInput (xEvent *ev)
+{
+ switch (ev->u.u.type) {
+ case ButtonPress:
+ switch (ev->u.u.detail) {
+ case 1: return down_1;
+ case 2: return down_2;
+ case 3: return down_3;
+ }
+ break;
+ case ButtonRelease:
+ switch (ev->u.u.detail) {
+ case 1: return up_1;
+ case 2: return up_2;
+ case 3: return up_3;
+ }
+ break;
+ case MotionNotify:
+ if (kdEventHeld && !KdInsideEmulationWindow(ev))
+ return outside_box;
+ else
+ return motion;
+ default:
+ return keyboard;
+ }
+}
+
+#ifndef NDEBUG
+char *kdStateNames[] = {
+ "start",
+ "button_1_pend",
+ "button_1_down",
+ "button_2_down",
+ "button_3_pend",
+ "button_3_down",
+ "synth_2_down_13",
+ "synth_2_down_3",
+ "synthetic_2_down_1",
+ "num_input_states"
+};
+
+char *kdClassNames[] = {
+ "down_1", "up_1",
+ "down_2", "up_2",
+ "down_3", "up_3",
+ "motion", "ouside_box",
+ "keyboard", "timeout",
+ "num_input_class"
+};
+
+char *kdActionNames[] = {
+ "noop",
+ "hold",
+ "setto",
+ "deliver",
+ "release",
+ "clearto",
+ "gen_down_2",
+ "gen_up_2",
+};
+#endif
+
+static void
+KdQueueEvent (xEvent *ev)
+{
+ KdAssertSigioBlocked ("KdQueueEvent");
+ if (ev->u.u.type == MotionNotify)
+ {
+ if (ev->u.keyButtonPointer.pad1)
+ {
+ ev->u.keyButtonPointer.pad1 = 0;
+ miPointerDeltaCursor (ev->u.keyButtonPointer.rootX,
+ ev->u.keyButtonPointer.rootY,
+ ev->u.keyButtonPointer.time);
+ }
+ else
+ {
+ miPointerAbsoluteCursor(ev->u.keyButtonPointer.rootX,
+ ev->u.keyButtonPointer.rootY,
+ ev->u.keyButtonPointer.time);
+ }
+ }
+ else
+ {
+ mieqEnqueue (ev);
+ }
+}
+
+KdInputState kdInputState;
+
+static void
+KdRunInputMachine (KdInputClass c, xEvent *ev)
+{
+ KdInputTransition *t;
+ int a;
+
+ t = &kdInputMachine[kdInputState][c];
+ for (a = 0; a < MAX_ACTIONS; a++)
+ {
+ switch (t->actions[a]) {
+ case noop:
+ break;
+ case hold:
+ kdEventHeld = TRUE;
+ kdEmulationDx = 0;
+ kdEmulationDy = 0;
+ kdHeldEvent = *ev;
+ break;
+ case setto:
+ kdEmulationTimeout = GetTimeInMillis () + EMULATION_TIMEOUT;
+ kdTimeoutPending = TRUE;
+ break;
+ case deliver:
+ KdQueueEvent (ev);
+ break;
+ case release:
+ kdEventHeld = FALSE;
+ kdTimeoutPending = FALSE;
+ KdQueueEvent (&kdHeldEvent);
+ break;
+ case clearto:
+ kdTimeoutPending = FALSE;
+ break;
+ case gen_down_2:
+ ev->u.u.detail = 2;
+ kdEventHeld = FALSE;
+ KdQueueEvent (ev);
+ break;
+ case gen_up_2:
+ ev->u.u.detail = 2;
+ KdQueueEvent (ev);
+ break;
+ }
+ }
+ kdInputState = t->nextState;
+}
+
+void
+KdResetInputMachine (void)
+{
+ kdInputState = start;
+ kdEventHeld = FALSE;
+}
+
+void
+KdHandleEvent (xEvent *ev)
+{
+ if (kdEmulateMiddleButton)
+ KdRunInputMachine (KdClassifyInput (ev), ev);
+ else
+ KdQueueEvent (ev);
+}
+
+void
+KdReceiveTimeout (void)
+{
+ KdRunInputMachine (timeout, 0);
+}
+
+#define KILL_SEQUENCE ((1L << KK_CONTROL)|(1L << KK_ALT)|(1L << KK_F8)|(1L << KK_F10))
+#define SPECIAL_SEQUENCE ((1L << KK_CONTROL) | (1L << KK_ALT))
+#define SETKILLKEY(b) (KdSpecialKeys |= (1L << (b)))
+#define CLEARKILLKEY(b) (KdSpecialKeys &= ~(1L << (b)))
+#define KEYMAP (pKdKeyboard->key->curKeySyms)
+#define KEYCOL1(k) (KEYMAP.map[((k)-kdMinKeyCode)*KEYMAP.mapWidth])
+
+CARD32 KdSpecialKeys = 0;
+
+extern char dispatchException;
+
+/*
+ * kdCheckTermination
+ *
+ * This function checks for the key sequence that terminates the server. When
+ * detected, it sets the dispatchException flag and returns. The key sequence
+ * is:
+ * Control-Alt
+ * It's assumed that the server will be waken up by the caller when this
+ * function returns.
+ */
+
+extern int nClients;
+
+void
+KdCheckSpecialKeys(xEvent *xE)
+{
+ KeySym sym;
+
+ if (!pKdKeyboard) return;
+
+ /*
+ * Ignore key releases
+ */
+
+ if (xE->u.u.type == KeyRelease) return;
+
+ /*
+ * Check for control/alt pressed
+ */
+ if ((pKdKeyboard->key->state & (ControlMask|Mod1Mask)) !=
+ (ControlMask|Mod1Mask))
+ return;
+
+ sym = KEYCOL1(xE->u.u.detail);
+
+ /*
+ * Let OS function see keysym first
+ */
+
+ if (kdOsFuncs->SpecialKey)
+ if ((*kdOsFuncs->SpecialKey) (sym))
+ return;
+
+ /*
+ * Now check for backspace or delete; these signal the
+ * X server to terminate
+ */
+ switch (sym) {
+ case XK_BackSpace:
+ case XK_Delete:
+ case XK_KP_Delete:
+ /*
+ * Set the dispatch exception flag so the server will terminate the
+ * next time through the dispatch loop.
+ */
+ dispatchException |= DE_TERMINATE;
+ break;
+ }
+}
+
+/*
+ * kdEnqueueKeyboardEvent
+ *
+ * This function converts hardware keyboard event information into an X event
+ * and enqueues it using MI. It wakes up the server before returning so that
+ * the event will be processed normally.
+ *
+ */
+
+void
+KdHandleKeyboardEvent (xEvent *ev)
+{
+ int key = ev->u.u.detail;
+ int byte;
+ CARD8 bit;
+
+ byte = key >> 3;
+ bit = 1 << (key & 7);
+ switch (ev->u.u.type) {
+ case KeyPress:
+ kdKeyState[byte] |= bit;
+ break;
+ case KeyRelease:
+ kdKeyState[byte] &= ~bit;
+ break;
+ }
+ KdHandleEvent (ev);
+}
+
+void
+KdReleaseAllKeys (void)
+{
+ xEvent xE;
+ int key;
+
+ for (key = 0; key < KD_KEY_COUNT; key++)
+ if (IsKeyDown(key))
+ {
+ xE.u.keyButtonPointer.time = GetTimeInMillis();
+ xE.u.u.type = KeyRelease;
+ xE.u.u.detail = key;
+ KdHandleKeyboardEvent (&xE);
+ }
+}
+
+void
+KdCheckLock (void)
+{
+ KeyClassPtr keyc = pKdKeyboard->key;
+ Bool isSet, shouldBeSet;
+
+ if (kdKeyboardFuncs->LockLed)
+ {
+ isSet = (kdLeds & (1 << (kdKeyboardFuncs->LockLed-1))) != 0;
+ shouldBeSet = (keyc->state & LockMask) != 0;
+ if (isSet != shouldBeSet)
+ {
+ KdSetLed (kdKeyboardFuncs->LockLed, shouldBeSet);
+ }
+ }
+}
+
+void
+KdEnqueueKeyboardEvent(unsigned char scan_code,
+ unsigned char is_up)
+{
+ unsigned char key_code;
+ xEvent xE;
+ int e;
+ KeyClassPtr keyc;
+
+ if (!pKdKeyboard)
+ return;
+ keyc = pKdKeyboard->key;
+
+ xE.u.keyButtonPointer.time = GetTimeInMillis();
+
+ if (kdMinScanCode <= scan_code && scan_code <= kdMaxScanCode)
+ {
+ key_code = scan_code + KD_MIN_KEYCODE - kdMinScanCode;
+
+ /*
+ * Set up this event -- the type may be modified below
+ */
+ if (is_up)
+ xE.u.u.type = KeyRelease;
+ else
+ xE.u.u.type = KeyPress;
+ xE.u.u.detail = key_code;
+
+ switch (KEYCOL1(key_code))
+ {
+ case XK_Num_Lock:
+ case XK_Scroll_Lock:
+ case XK_Shift_Lock:
+ case XK_Caps_Lock:
+ if (xE.u.u.type == KeyRelease)
+ return;
+ if (IsKeyDown (key_code))
+ xE.u.u.type = KeyRelease;
+ else
+ xE.u.u.type = KeyPress;
+ }
+
+ /*
+ * Check pressed keys which are already down
+ */
+ if (IsKeyDown (key_code) && xE.u.u.type == KeyPress)
+ {
+ KeybdCtrl *ctrl = &pKdKeyboard->kbdfeed->ctrl;
+
+ /*
+ * Check auto repeat
+ */
+ if (!ctrl->autoRepeat || keyc->modifierMap[key_code] ||
+ !(ctrl->autoRepeats[key_code >> 3] & (1 << (key_code & 7))))
+ {
+ return;
+ }
+ }
+ if (xE.u.u.type == KeyRelease && !IsKeyDown (key_code))
+ {
+ xE.u.u.type = KeyPress;
+ KdHandleKeyboardEvent (&xE);
+ xE.u.u.type = KeyRelease;
+ }
+ KdCheckSpecialKeys (&xE);
+ KdHandleKeyboardEvent (&xE);
+ }
+}
+
+#define SetButton(b,v, s) \
+{\
+ xE.u.u.detail = b; \
+ xE.u.u.type = v; \
+ KdHandleEvent (&xE); \
+}
+
+#define Press(b) SetButton(b+1,ButtonPress,"Down")
+#define Release(b) SetButton(b+1,ButtonRelease,"Up")
+
+static unsigned char kdButtonState = 0;
+
+/*
+ * kdEnqueueMouseEvent
+ *
+ * This function converts hardware mouse event information into X event
+ * information. A mouse movement event is passed off to MI to generate
+ * a MotionNotify event, if appropriate. Button events are created and
+ * passed off to MI for enqueueing.
+ */
+
+static int
+KdMouseAccelerate (DeviceIntPtr device, int delta)
+{
+ PtrCtrl *pCtrl = &device->ptrfeed->ctrl;
+
+ if (abs(delta) > pCtrl->threshold)
+ delta = (delta * pCtrl->num) / pCtrl->den;
+ return delta;
+}
+
+void
+KdEnqueueMouseEvent(unsigned long flags, int x, int y)
+{
+ CARD32 ms;
+ xEvent xE;
+ unsigned char buttons;
+
+ if (!pKdPointer)
+ return;
+
+ ms = GetTimeInMillis();
+
+ if (flags & KD_MOUSE_DELTA)
+ {
+ x = KdMouseAccelerate (pKdPointer, x);
+ y = KdMouseAccelerate (pKdPointer, y);
+ xE.u.keyButtonPointer.pad1 = 1;
+ }
+ else
+ xE.u.keyButtonPointer.pad1 = 0;
+ xE.u.keyButtonPointer.time = ms;
+ xE.u.keyButtonPointer.rootX = x;
+ xE.u.keyButtonPointer.rootY = y;
+
+ xE.u.u.type = MotionNotify;
+ xE.u.u.detail = 0;
+ KdHandleEvent (&xE);
+
+ buttons = flags;
+
+ if ((kdButtonState & KD_BUTTON_1) ^ (buttons & KD_BUTTON_1))
+ {
+ if (buttons & KD_BUTTON_1)
+ {
+ Press(0);
+ }
+ else
+ {
+ Release(0);
+ }
+ }
+ if ((kdButtonState & KD_BUTTON_2) ^ (buttons & KD_BUTTON_2))
+ {
+ if (buttons & KD_BUTTON_2)
+ {
+ Press(1);
+ }
+ else
+ {
+ Release(1);
+ }
+ }
+ if ((kdButtonState & KD_BUTTON_3) ^ (buttons & KD_BUTTON_3))
+ {
+ if (buttons & KD_BUTTON_3)
+ {
+ Press(2);
+ }
+ else
+ {
+ Release(2);
+ }
+ }
+ kdButtonState = buttons;
+}
+
+void
+KdEnqueueMotionEvent (int x, int y)
+{
+ xEvent xE;
+ CARD32 ms;
+
+ ms = GetTimeInMillis();
+
+ xE.u.u.type = MotionNotify;
+ xE.u.keyButtonPointer.time = ms;
+ xE.u.keyButtonPointer.rootX = x;
+ xE.u.keyButtonPointer.rootY = y;
+
+ KdHandleEvent (&xE);
+}
+
+void
+KdBlockHandler (int screen,
+ pointer blockData,
+ pointer timeout,
+ pointer readmask)
+{
+ struct timeval **pTimeout = timeout;
+
+ if (kdTimeoutPending)
+ {
+ static struct timeval tv;
+ int ms;
+
+ ms = kdEmulationTimeout - GetTimeInMillis ();
+ if (ms < 0)
+ ms = 0;
+ tv.tv_sec = ms / 1000;
+ tv.tv_usec = (ms % 1000) * 1000;
+ if (*pTimeout)
+ {
+ if ((*pTimeout)->tv_sec > tv.tv_sec ||
+ ((*pTimeout)->tv_sec == tv.tv_sec &&
+ (*pTimeout)->tv_usec > tv.tv_usec))
+ {
+ *pTimeout = &tv;
+ }
+ }
+ else
+ *pTimeout = &tv;
+ }
+}
+
+void
+KdWakeupHandler (int screen,
+ pointer data,
+ unsigned long result,
+ pointer readmask)
+{
+ fd_set *pReadmask = (fd_set *) readmask;
+
+ if (kdMouseFd >= 0 && FD_ISSET (kdMouseFd, pReadmask))
+ {
+ KdBlockSigio ();
+ (*kdMouseFuncs->Read) (kdMouseFd);
+ KdUnblockSigio ();
+ }
+ if (kdKeyboardFd >= 0 && FD_ISSET (kdKeyboardFd, pReadmask))
+ {
+ KdBlockSigio ();
+ (*kdKeyboardFuncs->Read) (kdKeyboardFd);
+ KdUnblockSigio ();
+ }
+ if (kdTimeoutPending)
+ {
+ if ((long) (GetTimeInMillis () - kdEmulationTimeout) >= 0)
+ {
+ kdTimeoutPending = FALSE;
+ KdBlockSigio ();
+ KdReceiveTimeout ();
+ KdUnblockSigio ();
+ }
+ }
+ if (kdSwitchPending)
+ KdProcessSwitch ();
+}
+
+static Bool
+KdCursorOffScreen(ScreenPtr *ppScreen, int *x, int *y)
+{
+ ScreenPtr pScreen = *ppScreen;
+ int n;
+
+ if (kdDisableZaphod || screenInfo.numScreens <= 1)
+ return FALSE;
+ if (*x < 0)
+ {
+ n = pScreen->myNum - 1;
+ if (n < 0)
+ n = screenInfo.numScreens - 1;
+ pScreen = screenInfo.screens[n];
+ *x += pScreen->width;
+ *ppScreen = pScreen;
+ return TRUE;
+ }
+ else if (*x >= pScreen->width)
+ {
+ n = pScreen->myNum + 1;
+ if (n >= screenInfo.numScreens)
+ n = 0;
+ *x -= pScreen->width;
+ pScreen = screenInfo.screens[n];
+ *ppScreen = pScreen;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static void
+KdCrossScreen(ScreenPtr pScreen, Bool entering)
+{
+ if (entering)
+ KdEnableScreen (pScreen);
+ else
+ KdDisableScreen (pScreen);
+}
+
+static void
+KdWarpCursor (ScreenPtr pScreen, int x, int y)
+{
+ KdBlockSigio ();
+ miPointerWarpCursor (pScreen, x, y);
+ KdUnblockSigio ();
+}
+
+miPointerScreenFuncRec kdPointerScreenFuncs =
+{
+ KdCursorOffScreen,
+ KdCrossScreen,
+ KdWarpCursor
+};
+
+void
+ProcessInputEvents ()
+{
+ (void)mieqProcessInputEvents();
+ miPointerUpdate();
+ if (kdSwitchPending)
+ KdProcessSwitch ();
+ KdCheckLock ();
+}
diff --git a/xc/programs/Xserver/hw/kdrive/kkeymap.c b/xc/programs/Xserver/hw/kdrive/kkeymap.c
new file mode 100644
index 000000000..b8111b07c
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/kkeymap.c
@@ -0,0 +1,235 @@
+/*
+ * $Id: kkeymap.c,v 1.1 2000/01/06 12:55:47 faith 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/kkeymap.c,v 1.1 1999/11/19 13:53:49 hohndel Exp $ */
+
+#include "kdrive.h"
+#include <X11/keysym.h>
+#include "kkeymap.h"
+
+/*
+ * Map scan codes (both regular and synthesized from extended keys)
+ * to X keysyms
+ */
+
+KeySym kdKeymap[(MAX_SCANCODE - MIN_SCANCODE + 1) * MAX_WIDTH] = {
+/* These are directly mapped from DOS scanset 0 */
+/* 1 8 */ XK_Escape, NoSymbol,
+/* 2 9 */ XK_1, XK_exclam,
+/* 3 10 */ XK_2, XK_at,
+/* 4 11 */ XK_3, XK_numbersign,
+/* 5 12 */ XK_4, XK_dollar,
+/* 6 13 */ XK_5, XK_percent,
+/* 7 14 */ XK_6, XK_asciicircum,
+/* 8 15 */ XK_7, XK_ampersand,
+/* 9 16 */ XK_8, XK_asterisk,
+/* 10 17 */ XK_9, XK_parenleft,
+/* 11 18 */ XK_0, XK_parenright,
+/* 12 19 */ XK_minus, XK_underscore,
+/* 13 20 */ XK_equal, XK_plus,
+/* 14 21 */ XK_BackSpace, NoSymbol,
+/* 15 22 */ XK_Tab, NoSymbol,
+/* 16 23 */ XK_Q, NoSymbol,
+/* 17 24 */ XK_W, NoSymbol,
+/* 18 25 */ XK_E, NoSymbol,
+/* 19 26 */ XK_R, NoSymbol,
+/* 20 27 */ XK_T, NoSymbol,
+/* 21 28 */ XK_Y, NoSymbol,
+/* 22 29 */ XK_U, NoSymbol,
+/* 23 30 */ XK_I, NoSymbol,
+/* 24 31 */ XK_O, NoSymbol,
+/* 25 32 */ XK_P, NoSymbol,
+/* 26 33 */ XK_bracketleft, XK_braceleft,
+/* 27 34 */ XK_bracketright, XK_braceright,
+/* 28 35 */ XK_Return, NoSymbol,
+/* 29 36 */ XK_Control_L, NoSymbol,
+/* 30 37 */ XK_A, NoSymbol,
+/* 31 38 */ XK_S, NoSymbol,
+/* 32 39 */ XK_D, NoSymbol,
+/* 33 40 */ XK_F, NoSymbol,
+/* 34 41 */ XK_G, NoSymbol,
+/* 35 42 */ XK_H, NoSymbol,
+/* 36 43 */ XK_J, NoSymbol,
+/* 37 44 */ XK_K, NoSymbol,
+/* 38 45 */ XK_L, NoSymbol,
+/* 39 46 */ XK_semicolon, XK_colon,
+/* 40 47 */ XK_apostrophe, XK_quotedbl,
+/* 41 48 */ XK_grave, XK_asciitilde,
+/* 42 49 */ XK_Shift_L, NoSymbol,
+/* 43 50 */ XK_backslash, XK_bar,
+/* 44 51 */ XK_Z, NoSymbol,
+/* 45 52 */ XK_X, NoSymbol,
+/* 46 53 */ XK_C, NoSymbol,
+/* 47 54 */ XK_V, NoSymbol,
+/* 48 55 */ XK_B, NoSymbol,
+/* 49 56 */ XK_N, NoSymbol,
+/* 50 57 */ XK_M, NoSymbol,
+/* 51 58 */ XK_comma, XK_less,
+/* 52 59 */ XK_period, XK_greater,
+/* 53 60 */ XK_slash, XK_question,
+/* 54 61 */ XK_Shift_R, NoSymbol,
+/* 55 62 */ XK_KP_Multiply, NoSymbol,
+/* 56 63 */ XK_Alt_L, XK_Meta_L,
+/* 57 64 */ XK_space, NoSymbol,
+/* 58 65 */ XK_Caps_Lock, NoSymbol,
+/* 59 66 */ XK_F1, NoSymbol,
+/* 60 67 */ XK_F2, NoSymbol,
+/* 61 68 */ XK_F3, NoSymbol,
+/* 62 69 */ XK_F4, NoSymbol,
+/* 63 70 */ XK_F5, NoSymbol,
+/* 64 71 */ XK_F6, NoSymbol,
+/* 65 72 */ XK_F7, NoSymbol,
+/* 66 73 */ XK_F8, NoSymbol,
+/* 67 74 */ XK_F9, NoSymbol,
+/* 68 75 */ XK_F10, NoSymbol,
+/* 69 76 */ XK_Break, XK_Pause,
+/* 70 77 */ XK_Scroll_Lock, NoSymbol,
+/* 71 78 */ XK_KP_Home, XK_KP_7,
+/* 72 79 */ XK_KP_Up, XK_KP_8,
+/* 73 80 */ XK_KP_Page_Up, XK_KP_9,
+/* 74 81 */ XK_KP_Subtract, NoSymbol,
+/* 75 82 */ XK_KP_Left, XK_KP_4,
+/* 76 83 */ XK_KP_5, NoSymbol,
+/* 77 84 */ XK_KP_Right, XK_KP_6,
+/* 78 85 */ XK_KP_Add, NoSymbol,
+/* 79 86 */ XK_KP_End, XK_KP_1,
+/* 80 87 */ XK_KP_Down, XK_KP_2,
+/* 81 88 */ XK_KP_Page_Down, XK_KP_3,
+/* 82 89 */ XK_KP_Insert, XK_KP_0,
+/* 83 90 */ XK_KP_Delete, XK_KP_Decimal,
+/* 84 91 */ NoSymbol, NoSymbol,
+/* 85 92 */ NoSymbol, NoSymbol,
+/* 86 93 */ NoSymbol, NoSymbol,
+/* 87 94 */ XK_F11, NoSymbol,
+/* 88 95 */ XK_F12, NoSymbol,
+
+/* These are remapped from the extended set (using ExtendMap) */
+
+/* 89 96 */ XK_Control_R, NoSymbol,
+/* 90 97 */ XK_KP_Enter, NoSymbol,
+/* 91 98 */ XK_KP_Divide, NoSymbol,
+/* 92 99 */ XK_Sys_Req, XK_Print,
+/* 93 100 */ XK_Alt_R, XK_Meta_R,
+/* 94 101 */ XK_Num_Lock, NoSymbol,
+/* 95 102 */ XK_Home, NoSymbol,
+/* 96 103 */ XK_Up, NoSymbol,
+/* 97 104 */ XK_Page_Up, NoSymbol,
+/* 98 105 */ XK_Left, NoSymbol,
+/* 99 106 */ XK_Right, NoSymbol,
+/* 100 107 */ XK_End, NoSymbol,
+/* 101 108 */ XK_Down, NoSymbol,
+/* 102 109 */ XK_Page_Down, NoSymbol,
+/* 103 110 */ XK_Insert, NoSymbol,
+/* 104 111 */ XK_Delete, NoSymbol,
+/* 105 112 */ XK_Super_L, NoSymbol,
+/* 106 113 */ XK_Super_R, NoSymbol,
+/* 107 114 */ XK_Menu, NoSymbol,
+/* 108 115 */ NoSymbol, NoSymbol,
+/* 109 116 */ NoSymbol, NoSymbol,
+/* 110 117 */ NoSymbol, NoSymbol,
+/* 111 118 */ NoSymbol, NoSymbol,
+/* 112 119 */ NoSymbol, NoSymbol,
+;
+
+/*
+ * Map extended keys to additional scancodes
+ */
+KdExtendMap kdExtendMap[] = {
+ 0x1d, 89, /* Control_R */
+ 0x1c, 90, /* KP_Enter */
+ 0x35, 91, /* KP_Divide */
+ 0x37, 92, /* Sys_Req */
+ 0x38, 93, /* Alt_R */
+ 0x45, 94, /* Num_Lock */
+ 0x47, 95, /* Home */
+ 0x48, 96, /* Up */
+ 0x49, 97, /* Page_Up */
+ 0x4b, 98, /* Left */
+ 0x4d, 99, /* Right */
+ 0x4f, 100, /* End */
+ 0x50, 101, /* Down */
+ 0x51, 102, /* Page_Down */
+ 0x52, 103, /* Insert */
+ 0x53, 104, /* Delete */
+ 0x5b, 105, /* Super_L (Windows_L) */
+ 0x5c, 106, /* Super_R (Windows_R) */
+ 0x5d, 107, /* Menu */
+ 0x46, 69, /* Break (with control pressed) */
+};
+
+#define NUM_EXTEND (sizeof (kdExtendMap)/ sizeof (kdExtendMap[0]))
+
+int kdNumExtend = NUM_EXTEND;
+
+/*
+ * Map keys on Japanese keyboard far from zero back to reasonable values
+ */
+KdExtendMap kdJapanMap[] = {
+ 0x70, 108, /* next to Alt key */
+ 0x73, 109, /* dash/vbar */
+ 0x79, 110, /* right of space bar */
+ 0x7b, 111, /* left of space bar */
+ 0x7d, 112, /* Yen */
+};
+
+#define NUM_JAPAN (sizeof (kdJapanMap)/sizeof (kdJapanMap[0]))
+
+int kdNumJapan = NUM_JAPAN;
+
+/*
+ * List of locking key codes
+ */
+
+CARD8 kdLockMap[] = {
+ 65,
+ 101,
+ 77,
+};
+
+#define NUM_LOCK (sizeof (kdLockMap) / sizeof (kdLockMap[0]))
+
+int kdNumLock = NUM_LOCK;
+
+/*
+ * Map containing list of keys which the X server makes locking when
+ * the KEYMAP_LOCKING_ALTGR flag is set in CEKeymapFlags
+ */
+
+CARD8 kdOptionalLockMap[] = {
+ 100,
+};
+
+#define NUM_OPTIONAL_LOCK (sizeof (kdOptionalLockMap) / sizeof (kdOptionalLockMap[0]))
+
+int kdNumOptionalLock = NUM_OPTIONAL_LOCK;
+
+CARD8 kdModMap[MAP_LENGTH];
+
+unsigned long kdKeymapFlags = 0;
+
+KeySymsRec kdKeySyms = {
+ kdKeymap,
+ MIN_KEYCODE,
+ MAX_KEYCODE,
+ 2
+};
diff --git a/xc/programs/Xserver/hw/kdrive/kkeymap.h b/xc/programs/Xserver/hw/kdrive/kkeymap.h
new file mode 100644
index 000000000..d129c28a3
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/kkeymap.h
@@ -0,0 +1,53 @@
+/*
+ * $Id: kkeymap.h,v 1.1 2000/01/06 12:55:47 faith 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/kkeymap.h,v 1.1 1999/11/19 13:53:50 hohndel Exp $ */
+/*
+ * All global variables and functions pertaining to keyboard key mapping
+ * live in this header file.
+ */
+
+#ifndef _KDKEYMP_H
+#define _KDKEYMP_H
+
+/* Offset of MIN_SCANCODE to 8 (X minimum scancode value) */
+#define KD_KEY_OFFSET (8 - kdMinScanCode)
+
+#define KD_MIN_KEYCODE 8
+#define KD_MAX_KEYCODE 254
+#define KD_MAX_WIDTH 4
+#define KD_MAX_LENGTH (KD_MAX_KEYCODE - KD_MIN_KEYCODE + 1)
+
+extern int kdMinScanCode;
+extern int kdMaxScanCode;
+extern int kdMinKeyCode;
+extern int kdMaxKeyCode;
+extern int kdKeymapWidth;
+
+extern KeySym kdKeymap[KD_MAX_LENGTH * KD_MAX_WIDTH];
+
+extern CARD8 kdModMap[MAP_LENGTH];
+
+extern KeySymsRec kdKeySyms;
+
+#endif /* _WINKEYMP_H */
diff --git a/xc/programs/Xserver/hw/kdrive/kloadmap.c b/xc/programs/Xserver/hw/kdrive/kloadmap.c
new file mode 100644
index 000000000..0ae836844
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/kloadmap.c
@@ -0,0 +1,200 @@
+/*
+ * $Id: kloadmap.c,v 1.1 2000/01/06 12:55:47 faith 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/kloadmap.c,v 1.1 1999/11/19 13:53:50 hohndel Exp $ */
+
+#include "kdrive.h"
+#include "kkeymap.h"
+
+#ifdef WINDOWS
+#define KM_BUF 1024
+#define KM_EOF -1
+
+typedef struct _km_file {
+ HANDLE handle;
+ char buf[KM_BUF];
+ char *bufptr;
+ DWORD remain;
+} km_file;
+
+int
+km_fill (km_file *kf)
+{
+ BOOL r;
+
+ NCD_DEBUG ((DEBUG_INIT, "km_fill"));
+ r = ReadFile (kf->handle, kf->buf, KM_BUF,
+ &kf->remain, NULL);
+ NCD_DEBUG ((DEBUG_INIT, "Got %d", kf->remain));
+ if (!r || !kf->remain)
+ return KM_EOF;
+ kf->bufptr = kf->buf;
+ --kf->remain;
+ return *kf->bufptr++;
+}
+
+#define km_getchar(kf) ((kf)->remain-- ? *kf->bufptr++ : km_fill (kf))
+#else
+#define km_getchar(kf) getc(kf)
+#endif
+
+BOOL
+km_word (km_file *kf, char *buf, int len)
+{
+ int c;
+
+ for (;;)
+ {
+ switch (c = km_getchar (kf)) {
+ case KM_EOF:
+ return FALSE;
+ case ' ':
+ case '\t':
+ case '\n':
+ case '\r':
+ continue;
+ }
+ break;
+ }
+ len--;
+ while (len--)
+ {
+ *buf++ = c;
+ switch (c = km_getchar (kf)) {
+ case KM_EOF:
+ case ' ':
+ case '\t':
+ case '\n':
+ case '\r':
+ *buf++ = '\0';
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+BOOL
+km_int (km_file *kf, int *r)
+{
+ char word[64];
+
+ if (km_word (kf, word, sizeof (word)))
+ {
+ *r = strtol (word, NULL, 0);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+WCHAR *winKbdExtensions[] = {
+ L".xku",
+ L".xkb"
+};
+
+#define NUM_KBD_EXTENSIONS (sizeof (winKbdExtensions) / sizeof (winKbdExtensions[0]))
+
+BOOL
+winLoadKeymap (void)
+{
+ WCHAR file[32 + KL_NAMELENGTH];
+ WCHAR name[KL_NAMELENGTH];
+ HKL layout;
+ km_file kf;
+ int width;
+ BOOL ret;
+ KeySym *m;
+ int scancode;
+ int w;
+ int e;
+
+ layout = GetKeyboardLayout (0);
+ /*
+ * Pre-build 46 versions of ThinSTAR software return 0
+ * for all layouts
+ */
+ if (!layout)
+ return FALSE;
+ NCD_DEBUG ((DEBUG_INIT, "Keyboard layout 0x%x", layout));
+ for (e = 0; e < NUM_KBD_EXTENSIONS; e++)
+ {
+ wstrcpy (file, L"\\Storage Card\\");
+ wsprintf (name, TEXT("%08x"), layout);
+ wstrcat (file, name);
+ wstrcat (file, winKbdExtensions[e]);
+ NCD_DEBUG ((DEBUG_INIT, "Loading keymap from %S", file));
+ kf.handle = CreateFile (file,
+ GENERIC_READ,
+ FILE_SHARE_READ|FILE_SHARE_WRITE,
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+ if (kf.handle != INVALID_HANDLE_VALUE)
+ break;
+ }
+ if (kf.handle == INVALID_HANDLE_VALUE)
+ {
+ NCD_DEBUG ((DEBUG_INIT, "No such file"));
+ return FALSE;
+ }
+ ret = FALSE;
+ kf.remain = 0;
+ /*
+ * Keymap format:
+ *
+ * flags (optional)
+ * width
+ * keycode -> keysym array (num_keycodes * width)
+ */
+ if (!km_int (&kf, &width))
+ goto bail1;
+ if (width & KEYMAP_FLAGS)
+ {
+ CEKeymapFlags = (unsigned long) width;
+ if (!km_int (&kf, &width))
+ goto bail1;
+ }
+ else
+ CEKeymapFlags = 0;
+ if (width > MAX_WIDTH)
+ goto bail1;
+ NCD_DEBUG ((DEBUG_INIT, "Keymap width %d flags 0x%x",
+ width, CEKeymapFlags));
+ m = CEKeymap;
+ for (scancode = MIN_SCANCODE; scancode <= MAX_SCANCODE; scancode++)
+ {
+ for (w = 0; w < width; w++)
+ {
+ if (!km_int (&kf, m))
+ break;
+ m++;
+ }
+ if (w != width)
+ break;
+ }
+ CEKeySyms.mapWidth = width;
+ ret = TRUE;
+bail1:
+ CloseHandle (kf.handle);
+ return ret;
+}
diff --git a/xc/programs/Xserver/hw/kdrive/kmap.c b/xc/programs/Xserver/hw/kdrive/kmap.c
new file mode 100644
index 000000000..d8279b242
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/kmap.c
@@ -0,0 +1,92 @@
+/*
+ * $Id: kmap.c,v 1.1 2000/01/06 12:55:47 faith 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/kmap.c,v 1.2 1999/12/30 03:03:06 robin Exp $ */
+
+#include "kdrive.h"
+
+#ifdef linux
+#include <errno.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#endif
+
+void *
+KdMapDevice (CARD32 addr, CARD32 size)
+{
+#ifdef WINDOWS
+ void *a;
+ void *d;
+
+ d = VirtualAlloc (NULL, size, MEM_RESERVE, PAGE_NOACCESS);
+ if (!d)
+ return NULL;
+ DRAW_DEBUG ((DEBUG_S3INIT, "Virtual address of 0x%x is 0x%x", addr, d));
+ a = VirtualCopyAddr (addr);
+ DRAW_DEBUG ((DEBUG_S3INIT, "Translated address is 0x%x", a));
+ if (!VirtualCopy (d, a, size,
+ PAGE_READWRITE|PAGE_NOCACHE|PAGE_PHYSICAL))
+ {
+ DRAW_DEBUG ((DEBUG_FAILURE, "VirtualCopy failed %d",
+ GetLastError ()));
+ return NULL;
+ }
+ DRAW_DEBUG ((DEBUG_S3INIT, "Device mapped successfully"));
+ return d;
+#endif
+#ifdef linux
+ void *a;
+ int fd;
+
+ fd = open ("/dev/mem", O_RDWR);
+ if (fd < 0)
+ FatalError ("KdMapDevice: failed to open /dev/mem (%s)\n",
+ strerror (errno));
+
+ a = mmap ((caddr_t) 0, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, addr);
+ close (fd);
+ if ((long) a == -1)
+ FatalError ("KdMapDevice: failed to map frame buffer (%s)\n",
+ strerror (errno));
+ return a;
+#endif
+#ifdef VXWORKS
+ return (void *) addr;
+#endif
+}
+
+void
+KdUnmapDevice (void *addr, CARD32 size)
+{
+#ifdef WINDOWS
+ VirtualFree (addr, size, MEM_DECOMMIT);
+ VirtualFree (addr, 0, MEM_RELEASE);
+#endif
+#ifdef linux
+ munmap (addr, size);
+#endif
+#ifdef VXWORKS
+ ;
+#endif
+}
+
diff --git a/xc/programs/Xserver/hw/kdrive/kmode.c b/xc/programs/Xserver/hw/kdrive/kmode.c
new file mode 100644
index 000000000..d632ac7bc
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/kmode.c
@@ -0,0 +1,313 @@
+/*
+ * $Id: kmode.c,v 1.1 2000/01/06 12:55:48 faith 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.
+ */
+
+#include "kdrive.h"
+
+const KdMonitorTiming kdMonitorTimings[] = {
+ /* H V Hz KHz */
+ /* FP BP BLANK POLARITY */
+ /* Other VESA modes */
+ { 640, 350, 85, 31500, /* VESA */
+ 32, 96, 192, KdSyncPositive, /* 37.861 */
+ 32, 60, 95, KdSyncNegative, /* 85.080 */
+ },
+ { 640, 400, 85, 31500, /* VESA */
+ 32, 96, 192, KdSyncNegative, /* 37.861 */
+ 1, 41, 45, KdSyncPositive, /* 85.080 */
+ },
+ { 720, 400, 85, 35500, /* VESA */
+ 36, 108, 216, KdSyncNegative, /* 37.927 */
+ 1, 42, 46, KdSyncPositive, /* 85.039 */
+ },
+
+ /* 640x480 modes */
+ { 640, 480, 85, 36000, /* VESA */
+ 56, 80, 192, KdSyncNegative, /* 43.269 */
+ 1, 25, 29, KdSyncNegative, /* 85.008 */
+ },
+ { 640, 480, 75, 31500, /* VESA */
+ 16, 120, 200, KdSyncNegative, /* 37.500 */
+ 1, 16, 20, KdSyncNegative, /* 75.000 */
+ },
+ { 640, 480, 72, 31500, /* VESA */
+ 16, 120, 176, KdSyncNegative, /* 37.861 */
+ 1, 20, 24, KdSyncNegative, /* 72.809 */
+ },
+ { 640, 480, 60, 25175, /* VESA */
+ 8, 40, 144, KdSyncNegative, /* 31.469 */
+ 2, 25, 29, KdSyncNegative, /* 59.940 */
+ },
+
+ /* 800x600 modes */
+ { 800, 600, 85, 56250, /* VESA */
+ 32, 152, 248, KdSyncPositive, /* 53.674 */
+ 1, 27, 31, KdSyncPositive, /* 85.061 */
+ },
+ { 800, 600, 75, 49500, /* VESA */
+ 16, 160, 256, KdSyncPositive, /* 46.875 */
+ 1, 21, 25, KdSyncPositive, /* 75.000 */
+ },
+ /* DEFAULT */
+#define MONITOR_TIMING_DEFAULT 9
+ { 800, 600, 72, 50000, /* VESA */
+ 56, 64, 240, KdSyncPositive, /* 48.077 */
+ 37, 23, 66, KdSyncPositive, /* 72.188 */
+ },
+ { 800, 600, 60, 40000, /* VESA */
+ 40, 88, 256, KdSyncPositive, /* 37.879 */
+ 1, 23, 28, KdSyncPositive, /* 60.317 */
+ },
+ { 800, 600, 56, 36000, /* VESA */
+ 24, 128, 224, KdSyncPositive, /* 35.156 */
+ 1, 22, 25, KdSyncPositive, /* 56.250 */
+ },
+
+ /* 1024x768 modes */
+ { 1024, 768, 85, 94500, /* VESA */
+ 48, 208, 352, KdSyncPositive, /* 68.677 */
+ 1, 36, 40, KdSyncPositive, /* 84.997 */
+ },
+ { 1024, 768, 75, 78750, /* VESA */
+ 16, 176, 288, KdSyncPositive, /* 60.023 */
+ 1, 28, 32, KdSyncPositive, /* 75.029 */
+ },
+ { 1024, 768, 70, 75000, /* VESA */
+ 24, 144, 304, KdSyncNegative, /* 56.476 */
+ 3, 29, 38, KdSyncNegative, /* 70.069 */
+ },
+ { 1024, 768, 60, 65000, /* VESA */
+ 24, 160, 320, KdSyncNegative, /* 48.363 */
+ 3, 29, 38, KdSyncNegative, /* 60.004 */
+ },
+
+ /* 1152x864 mode */
+ { 1152, 864, 75, 108000, /* VESA */
+ 64, 256, 448, KdSyncPositive, /* 67.500 */
+ 1, 32, 36, KdSyncPositive, /* 75.000 */
+ },
+
+ /* 1152x900 modes */
+ { 1152, 900, 85, 122500, /* ADDED */
+ 48, 208, 384, KdSyncPositive, /* 79.753 */
+ 1, 32, 38, KdSyncPositive, /* 85.024 */
+ },
+ { 1152, 900, 75, 108250, /* ADDED */
+ 32, 208, 384, KdSyncPositive, /* 70.475 */
+ 1, 32, 38, KdSyncPositive, /* 75.133 */
+ },
+ { 1152, 900, 70, 100250, /* ADDED */
+ 32, 208, 384, KdSyncPositive, /* 65.267 */
+ 2, 32, 38, KdSyncPositive, /* 69.581 */
+ },
+ { 1152, 900, 66, 95000, /* ADDED */
+ 32, 208, 384, KdSyncPositive, /* 61.849 */
+ 1, 32, 38, KdSyncPositive, /* 65.937 */
+ },
+
+ /* 1280x960 modes */
+ { 1280, 960, 85, 148500, /* VESA */
+ 64, 224, 448, KdSyncPositive, /* 85.938 */
+ 1, 47, 51, KdSyncPositive, /* 85.002 */
+ },
+ { 1280, 960, 60, 108000, /* VESA */
+ 96, 312, 520, KdSyncPositive, /* 60.000 */
+ 1, 36, 40, KdSyncPositive, /* 60.000 */
+ },
+
+ /* 1280x1024 modes */
+ { 1280, 1024, 85, 157500, /* VESA */
+ 64, 224, 448, KdSyncPositive, /* 91.146 */
+ 1, 44, 48, KdSyncPositive, /* 85.024 */
+ },
+ { 1280, 1024, 75, 135000, /* VESA */
+ 16, 248, 408, KdSyncPositive, /* 79.976 */
+ 1, 38, 42, KdSyncPositive, /* 75.025 */
+ },
+ { 1280, 1024, 60, 108000, /* VESA */
+ 48, 248, 408, KdSyncPositive, /* 63.981 */
+ 1, 38, 42, KdSyncPositive, /* 60.020 */
+ },
+
+ /* 1600x1200 modes */
+ { 1600, 1200, 85, 229500, /* VESA */
+ 64, 304, 560, KdSyncPositive, /* 106.250 */
+ 1, 46, 50, KdSyncPositive, /* 85.000 */
+ },
+ { 1600, 1200, 75, 202500, /* VESA */
+ 64, 304, 560, KdSyncPositive, /* 93.750 */
+ 1, 46, 50, KdSyncPositive, /* 75.000 */
+ },
+ { 1600, 1200, 70, 189000, /* VESA */
+ 64, 304, 560, KdSyncPositive, /* 87.500 */
+ 1, 46, 50, KdSyncPositive, /* 70.000 */
+ },
+ { 1600, 1200, 65, 175500, /* VESA */
+ 64, 304, 560, KdSyncPositive, /* 81.250 */
+ 1, 46, 50, KdSyncPositive, /* 65.000 */
+ },
+ { 1600, 1200, 60, 162000, /* VESA */
+ 64, 304, 560, KdSyncPositive, /* 75.000 */
+ 1, 46, 50, KdSyncPositive, /* 60.000 */
+ },
+
+ /* 1792x1344 modes */
+ { 1792, 1344, 85, 301500, /* ADDED */
+ 96, 352, 672, KdSyncNegative, /* 122.362 */
+ 1, 92, 96, KdSyncPositive, /* 84.974 */
+ },
+ { 1792, 1344, 75, 261000, /* VESA */
+ 96, 352, 664, KdSyncNegative, /* 106.270 */
+ 1, 69, 73, KdSyncPositive, /* 74.997 */
+ },
+ { 1792, 1344, 60, 204750, /* VESA */
+ 128, 328, 656, KdSyncNegative, /* 83.640 */
+ 1, 46, 50, KdSyncPositive, /* 60.000 */
+ },
+
+#if 0
+ { 1800, 1012, 75 },
+ { 1906, 1072, 68 },
+#endif
+
+ /* 1856x1392 modes */
+ { 1856, 1392, 85, 330500, /* ADDED */
+ 160, 352, 736, KdSyncNegative, /* 127.508 */
+ 1, 104, 108, KdSyncPositive, /* 85.001 */
+ },
+ { 1856, 1392, 75, 288000, /* VESA */
+ 128, 352, 704, KdSyncNegative, /* 112.500 */
+ 1, 104, 108, KdSyncPositive, /* 75.000 */
+ },
+ { 1856, 1392, 60, 218250, /* VESA */
+ 96, 352, 672, KdSyncNegative, /* 86.333 */
+ 1, 43, 47, KdSyncPositive, /* 59.995 */
+ },
+
+ /* 1920x1440 modes */
+ { 1920, 1440, 85, 341750, /* ADDED */
+ 160, 352, 760, KdSyncNegative, /* 127.512 */
+ 1, 56, 60, KdSyncPositive, /* 85.012 */
+ },
+ { 1920, 1440, 75, 297000, /* VESA */
+ 144, 352, 720, KdSyncNegative, /* 112.500 */
+ 1, 56, 60, KdSyncPositive, /* 75.000 */
+ },
+ { 1920, 1440, 60, 234000, /* VESA */
+ 128, 244, 680, KdSyncNegative, /* 90.000 */
+ 1, 56, 60, KdSyncPositive, /* 60.000 */
+ },
+};
+
+#define NUM_MONITOR_TIMINGS (sizeof kdMonitorTimings/sizeof kdMonitorTimings[0])
+
+const int kdNumMonitorTimings = NUM_MONITOR_TIMINGS;
+
+const KdMonitorTiming *
+KdFindMode (KdScreenInfo *screen,
+ Bool (*supported) (KdScreenInfo *,
+ const KdMonitorTiming *))
+{
+ int i;
+ const KdMonitorTiming *t;
+
+ for (i = 0, t = kdMonitorTimings; i < NUM_MONITOR_TIMINGS; i++, t++)
+ {
+ if ((*supported) (screen, t) &&
+ t->horizontal == screen->width &&
+ t->vertical == screen->height &&
+ (!screen->rate || t->rate <= screen->rate))
+ {
+ return t;
+ }
+ }
+ return &kdMonitorTimings[MONITOR_TIMING_DEFAULT];
+}
+
+static const KdMonitorTiming *
+kdFindPrevSize (const KdMonitorTiming *old)
+{
+ const KdMonitorTiming *new, *prev;
+
+ if (old == kdMonitorTimings)
+ return 0;
+ new = old;
+ /*
+ * Search for the previous size
+ */
+ while (new != kdMonitorTimings)
+ {
+ new--;
+ if (new->horizontal != old->horizontal &&
+ new->vertical != old->vertical)
+ {
+ break;
+ }
+ }
+ /*
+ * Match the refresh rate (<=)
+ */
+ while (new != kdMonitorTimings)
+ {
+ prev = new - 1;
+ if (prev->horizontal == new->horizontal &&
+ prev->vertical == new->vertical &&
+ prev->rate > old->rate)
+ {
+ break;
+ }
+ new--;
+ }
+ return new;
+}
+
+Bool
+KdTuneMode (KdScreenInfo *screen,
+ Bool (*usable) (KdScreenInfo *),
+ Bool (*supported) (KdScreenInfo *,
+ const KdMonitorTiming *))
+{
+ const KdMonitorTiming *t, *new;
+
+ while (!(*usable) (screen))
+ {
+ /*
+ * Fix requested depth and geometry until it works
+ */
+ if (screen->depth > 16)
+ screen->depth = 16;
+ else if (screen->depth > 8)
+ screen->depth = 8;
+ else
+ {
+ t = kdFindPrevSize (KdFindMode (screen, supported));
+ if (!t)
+ return FALSE;
+ screen->width = t->horizontal;
+ screen->height = t->vertical;
+ screen->rate = t->rate;
+ }
+ }
+ return TRUE;
+}
diff --git a/xc/programs/Xserver/hw/kdrive/knoop.c b/xc/programs/Xserver/hw/kdrive/knoop.c
new file mode 100644
index 000000000..6b8f83de8
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/knoop.c
@@ -0,0 +1,294 @@
+/*
+ * $Id: knoop.c,v 1.1 2000/01/06 12:55:48 faith 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/knoop.c,v 1.1 1999/11/19 13:53:50 hohndel Exp $ */
+
+/*
+ * GC ops that don't do anything
+ */
+
+#include "kdrive.h"
+#include <gcstruct.h>
+
+typedef void (* typeFillSpans)(
+#if NeedNestedPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*nInit*/,
+ DDXPointPtr /*pptInit*/,
+ int * /*pwidthInit*/,
+ int /*fSorted*/
+#endif
+);
+
+typedef void (* typeSetSpans)(
+#if NeedNestedPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ char * /*psrc*/,
+ DDXPointPtr /*ppt*/,
+ int * /*pwidth*/,
+ int /*nspans*/,
+ int /*fSorted*/
+#endif
+);
+
+typedef void (* typePutImage)(
+#if NeedNestedPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*depth*/,
+ int /*x*/,
+ int /*y*/,
+ int /*w*/,
+ int /*h*/,
+ int /*leftPad*/,
+ int /*format*/,
+ char * /*pBits*/
+#endif
+);
+
+typedef RegionPtr (* typeCopyArea)(
+#if NeedNestedPrototypes
+ DrawablePtr /*pSrc*/,
+ DrawablePtr /*pDst*/,
+ GCPtr /*pGC*/,
+ int /*srcx*/,
+ int /*srcy*/,
+ int /*w*/,
+ int /*h*/,
+ int /*dstx*/,
+ int /*dsty*/
+#endif
+);
+
+typedef RegionPtr (* typeCopyPlane)(
+#if NeedNestedPrototypes
+ DrawablePtr /*pSrcDrawable*/,
+ DrawablePtr /*pDstDrawable*/,
+ GCPtr /*pGC*/,
+ int /*srcx*/,
+ int /*srcy*/,
+ int /*width*/,
+ int /*height*/,
+ int /*dstx*/,
+ int /*dsty*/,
+ unsigned long /*bitPlane*/
+#endif
+);
+typedef void (* typePolyPoint)(
+#if NeedNestedPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*mode*/,
+ int /*npt*/,
+ DDXPointPtr /*pptInit*/
+#endif
+);
+
+typedef void (* typePolylines)(
+#if NeedNestedPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*mode*/,
+ int /*npt*/,
+ DDXPointPtr /*pptInit*/
+#endif
+);
+
+typedef void (* typePolySegment)(
+#if NeedNestedPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*nseg*/,
+ xSegment * /*pSegs*/
+#endif
+);
+
+typedef void (* typePolyRectangle)(
+#if NeedNestedPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*nrects*/,
+ xRectangle * /*pRects*/
+#endif
+);
+
+typedef void (* typePolyArc)(
+#if NeedNestedPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*narcs*/,
+ xArc * /*parcs*/
+#endif
+);
+
+typedef void (* typeFillPolygon)(
+#if NeedNestedPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*shape*/,
+ int /*mode*/,
+ int /*count*/,
+ DDXPointPtr /*pPts*/
+#endif
+);
+
+typedef void (* typePolyFillRect)(
+#if NeedNestedPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*nrectFill*/,
+ xRectangle * /*prectInit*/
+#endif
+);
+
+typedef void (* typePolyFillArc)(
+#if NeedNestedPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*narcs*/,
+ xArc * /*parcs*/
+#endif
+);
+
+typedef int (* typePolyText8)(
+#if NeedNestedPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*x*/,
+ int /*y*/,
+ int /*count*/,
+ char * /*chars*/
+#endif
+);
+
+typedef int (* typePolyText16)(
+#if NeedNestedPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*x*/,
+ int /*y*/,
+ int /*count*/,
+ unsigned short * /*chars*/
+#endif
+);
+
+typedef void (* typeImageText8)(
+#if NeedNestedPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*x*/,
+ int /*y*/,
+ int /*count*/,
+ char * /*chars*/
+#endif
+);
+
+typedef void (* typeImageText16)(
+#if NeedNestedPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*x*/,
+ int /*y*/,
+ int /*count*/,
+ unsigned short * /*chars*/
+#endif
+);
+
+typedef void (* typeImageGlyphBlt)(
+#if NeedNestedPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*x*/,
+ int /*y*/,
+ unsigned int /*nglyph*/,
+ CharInfoPtr * /*ppci*/,
+ pointer /*pglyphBase*/
+#endif
+);
+
+typedef void (* typePolyGlyphBlt)(
+#if NeedNestedPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*x*/,
+ int /*y*/,
+ unsigned int /*nglyph*/,
+ CharInfoPtr * /*ppci*/,
+ pointer /*pglyphBase*/
+#endif
+);
+
+typedef void (* typePushPixels)(
+#if NeedNestedPrototypes
+ GCPtr /*pGC*/,
+ PixmapPtr /*pBitMap*/,
+ DrawablePtr /*pDst*/,
+ int /*w*/,
+ int /*h*/,
+ int /*x*/,
+ int /*y*/
+#endif
+);
+
+RegionPtr
+KdNoopCopyArea(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC,
+ int srcx, int srcy, int width, int height, int dstx, int dsty)
+{
+ return NullRegion;
+}
+
+RegionPtr
+KdNoopCopyPlane(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC,
+ int srcx, int srcy, int width, int height,
+ int dstx, int dsty, unsigned long bitPlane)
+{
+ return NullRegion;
+}
+
+GCOps kdNoopOps = {
+ (typeFillSpans) NoopDDA, /* fill spans */
+ (typeSetSpans) NoopDDA, /* set spans */
+ (typePutImage) NoopDDA, /* put image */
+ KdNoopCopyArea, /* copy area */
+ KdNoopCopyPlane, /* copy plane */
+ (typePolyPoint) NoopDDA, /* poly point */
+ (typePolylines) NoopDDA, /* poly lines */
+ (typePolySegment) NoopDDA, /* poly segment */
+ (typePolyRectangle) NoopDDA, /* poly rectangle */
+ (typePolyArc) NoopDDA, /* poly arc */
+ (typeFillPolygon) NoopDDA, /* fill polygon */
+ (typePolyFillRect) NoopDDA, /* poly fillrect */
+ (typePolyFillArc) NoopDDA, /* poly fillarc */
+ (typePolyText8) NoopDDA, /* text 8 */
+ (typePolyText16) NoopDDA, /* text 16 */
+ (typeImageText8) NoopDDA, /* itext 8 */
+ (typeImageText16) NoopDDA, /* itext 16 */
+ (typePolyGlyphBlt) NoopDDA, /* glyph blt */
+ (typeImageGlyphBlt) NoopDDA, /* iglyph blt */
+ (typePushPixels) NoopDDA, /* push pixels */
+#ifdef NEED_LINEHELPER
+ (typeLineHelper) NULL,
+#endif
+};
diff --git a/xc/programs/Xserver/hw/kdrive/ktest.c b/xc/programs/Xserver/hw/kdrive/ktest.c
new file mode 100644
index 000000000..38c0b8604
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/ktest.c
@@ -0,0 +1,76 @@
+/*
+ * $Id: ktest.c,v 1.1 2000/01/06 12:55:48 faith 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/ktest.c,v 1.1 1999/11/19 13:53:50 hohndel Exp $ */
+
+#include "kdrive.h"
+
+
+static CARD8 memoryPatterns[] = { 0xff, 0x00, 0x5a, 0xa5, 0xaa, 0x55 };
+
+#define NUM_PATTERNS (sizeof (memoryPatterns) / sizeof (memoryPatterns[0]))
+
+Bool
+KdFrameBufferValid (CARD8 *base, int size)
+{
+ volatile CARD8 *b = (volatile CARD8 *) base;
+ CARD8 save, test, compare;
+ int i, j;
+
+ b = base + (size - 1);
+ save = *b;
+
+ for (i = 0; i < NUM_PATTERNS; i++)
+ {
+ test = memoryPatterns[i];
+ *b = test;
+ for (j = 0; j < 1000; j++)
+ {
+ compare = *b;
+ if (compare != test)
+ return FALSE;
+ }
+ }
+ *b = save;
+ return TRUE;
+}
+
+int
+KdFrameBufferSize (CARD8 *base, int max)
+{
+ int min, cur;
+
+ min = 0;
+ while (min + 1 < max)
+ {
+ cur = (max + min) / 2;
+ if (KdFrameBufferValid (base, cur))
+ min = cur;
+ else
+ max = cur;
+ }
+ if (KdFrameBufferValid (base, max))
+ return max;
+ else
+ return min;
+}
diff --git a/xc/programs/Xserver/hw/kdrive/linux.c b/xc/programs/Xserver/hw/kdrive/linux.c
new file mode 100644
index 000000000..7b2e49e11
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/linux.c
@@ -0,0 +1,322 @@
+/*
+ * $Id: linux.c,v 1.1 2000/01/06 12:55:48 faith 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/linux.c,v 1.1 1999/11/19 13:53:51 hohndel Exp $ */
+
+#include "kdrive.h"
+#include <errno.h>
+#include <signal.h>
+#include <linux/vt.h>
+#include <linux/kd.h>
+#include <sys/stat.h>
+#include <keysym.h>
+
+static int vtno;
+int LinuxConsoleFd;
+static int activeVT;
+static Bool enabled;
+
+void
+LinuxVTRequest (int sig)
+{
+ kdSwitchPending = TRUE;
+}
+
+/* Check before chowning -- this avoids touching the file system */
+void
+LinuxCheckChown (char *file)
+{
+ struct stat st;
+ __uid_t u;
+ __gid_t g;
+
+ if (stat (file, &st) < 0)
+ return;
+ u = getuid ();
+ g = getgid ();
+ if (st.st_uid != u || st.st_gid != g)
+ chown (file, u, g);
+}
+
+int
+LinuxInit ()
+{
+ int i, fd;
+ char vtname[11];
+ struct vt_stat vts;
+ struct stat statb;
+
+ LinuxConsoleFd = -1;
+ /* check if we're run with euid==0 */
+ if (geteuid() != 0)
+ {
+ FatalError("LinuxInit: Server must be suid root\n");
+ }
+
+ if ((fd = open("/dev/tty0",O_WRONLY,0)) < 0)
+ {
+ FatalError(
+ "LinuxInit: Cannot open /dev/tty0 (%s)\n",
+ strerror(errno));
+ }
+ if ((ioctl(fd, VT_OPENQRY, &vtno) < 0) ||
+ (vtno == -1))
+ {
+ FatalError("xf86OpenConsole: Cannot find a free VT\n");
+ }
+ close(fd);
+
+/* ErrorF("(using VT number %d)\n\n", vtno); */
+
+ sprintf(vtname,"/dev/tty%d",vtno); /* /dev/tty1-64 */
+
+ if ((LinuxConsoleFd = open(vtname, O_RDWR|O_NDELAY, 0)) < 0)
+ {
+ FatalError("LinuxInit: Cannot open %s (%s)\n",
+ vtname, strerror(errno));
+ }
+
+ /* change ownership of the vt */
+ LinuxCheckChown (vtname);
+
+ /*
+ * the current VT device we're running on is not "console", we want
+ * to grab all consoles too
+ *
+ * Why is this needed?
+ */
+ LinuxCheckChown ("/dev/tty0");
+ /*
+ * Linux doesn't switch to an active vt after the last close of a vt,
+ * so we do this ourselves by remembering which is active now.
+ */
+ if (ioctl(LinuxConsoleFd, VT_GETSTATE, &vts) == 0)
+ {
+ activeVT = vts.v_active;
+ }
+
+ return 1;
+}
+
+Bool
+LinuxFindPci (CARD16 vendor, CARD16 device, CARD32 count, KdCardAttr *attr)
+{
+ FILE *f;
+ char line[2048], *l, *end;
+ CARD32 bus, id, mode, addr;
+ int n;
+ CARD32 ven_dev;
+ Bool ret = FALSE;
+
+ ven_dev = (((CARD32) vendor) << 16) | ((CARD32) device);
+ f = fopen ("/proc/bus/pci/devices", "r");
+ if (!f)
+ return FALSE;
+ while (fgets (line, sizeof (line)-1, f))
+ {
+ line[sizeof(line)-1] = '\0';
+ l = line;
+ bus = strtoul (l, &end, 16);
+ if (end == l)
+ continue;
+ l = end;
+ id = strtoul (l, &end, 16);
+ if (end == l)
+ continue;
+ l = end;
+ if (id != ven_dev)
+ continue;
+ if (count--)
+ continue;
+ (void) strtoul (l, &end, 16);
+ if (end == l)
+ continue;
+ l = end;
+ n = 0;
+ for (;;)
+ {
+ addr = strtoul (l, &end, 16);
+ if (end == l)
+ break;
+ if (addr & 1)
+ attr->io = addr & ~0xf;
+ else
+ {
+ if (n == KD_MAX_CARD_ADDRESS)
+ break;
+ attr->address[n++] = addr & ~0xf;
+ }
+ l = end;
+ }
+ while (n > 0)
+ {
+ if (attr->address[n-1] != 0)
+ break;
+ n--;
+ }
+ attr->naddr = n;
+ ret = TRUE;
+ break;
+ }
+ fclose (f);
+ return ret;
+}
+
+void
+LinuxEnable (void)
+{
+ struct sigaction act;
+ struct vt_mode VT;
+
+ if (enabled)
+ return;
+ if (kdSwitchPending)
+ {
+ kdSwitchPending = FALSE;
+ ioctl (LinuxConsoleFd, VT_RELDISP, VT_ACKACQ);
+ }
+ /*
+ * now get the VT
+ */
+ if (ioctl(LinuxConsoleFd, VT_ACTIVATE, vtno) != 0)
+ {
+ ErrorF("LinuxInit: VT_ACTIVATE failed\n");
+ }
+ if (ioctl(LinuxConsoleFd, VT_WAITACTIVE, vtno) != 0)
+ {
+ ErrorF("LinuxInit: VT_WAITACTIVE failed\n");
+ }
+ if (ioctl(LinuxConsoleFd, VT_GETMODE, &VT) < 0)
+ {
+ FatalError ("LinuxInit: VT_GETMODE failed\n");
+ }
+
+ act.sa_handler = LinuxVTRequest;
+ sigemptyset (&act.sa_mask);
+ act.sa_flags = 0;
+ act.sa_restorer = 0;
+ sigaction (SIGUSR1, &act, 0);
+
+ VT.mode = VT_PROCESS;
+ VT.relsig = SIGUSR1;
+ VT.acqsig = SIGUSR1;
+ if (ioctl(LinuxConsoleFd, VT_SETMODE, &VT) < 0)
+ {
+ FatalError("LinuxInit: VT_SETMODE VT_PROCESS failed\n");
+ }
+ if (ioctl(LinuxConsoleFd, KDSETMODE, KD_GRAPHICS) < 0)
+ {
+ FatalError("LinuxInit: KDSETMODE KD_GRAPHICS failed\n");
+ }
+ enabled = TRUE;
+}
+
+Bool
+LinuxSpecialKey (KeySym sym)
+{
+ struct vt_stat vts;
+ int con;
+
+ if (XK_F1 <= sym && sym <= XK_F12)
+ {
+ con = sym - XK_F1 + 1;
+ ioctl (LinuxConsoleFd, VT_GETSTATE, &vts);
+ if (con != vts.v_active && (vts.v_state & (1 << con)))
+ {
+ ioctl (LinuxConsoleFd, VT_ACTIVATE, con);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+void
+LinuxDisable (void)
+{
+ ioctl(LinuxConsoleFd, KDSETMODE, KD_TEXT); /* Back to text mode ... */
+ if (kdSwitchPending)
+ {
+ kdSwitchPending = FALSE;
+ ioctl (LinuxConsoleFd, VT_RELDISP, 1);
+ }
+ enabled = FALSE;
+}
+
+void
+LinuxFini (void)
+{
+ struct vt_mode VT;
+ struct vt_stat vts;
+ int fd;
+
+ if (LinuxConsoleFd < 0)
+ return;
+
+ if (ioctl(LinuxConsoleFd, VT_GETMODE, &VT) != -1)
+ {
+ VT.mode = VT_AUTO;
+ ioctl(LinuxConsoleFd, VT_SETMODE, &VT); /* set dflt vt handling */
+ }
+ ioctl (LinuxConsoleFd, VT_GETSTATE, &vts);
+ /*
+ * Find a legal VT to switch to, either the one we started from
+ * or the lowest active one that isn't ours
+ */
+ if (activeVT < 0 ||
+ activeVT == vts.v_active ||
+ !(vts.v_state & (1 << activeVT)))
+ {
+ for (activeVT = 1; activeVT < 16; activeVT++)
+ if (activeVT != vtno && (vts.v_state & (1 << activeVT)))
+ break;
+ if (activeVT == 16)
+ activeVT = -1;
+ }
+ /*
+ * Perform a switch back to the active VT when we were started
+ */
+ if (activeVT >= -1)
+ {
+ ioctl (LinuxConsoleFd, VT_ACTIVATE, activeVT);
+ ioctl (LinuxConsoleFd, VT_WAITACTIVE, activeVT);
+ activeVT = -1;
+ }
+ close(LinuxConsoleFd); /* make the vt-manager happy */
+ fd = open ("/dev/tty0", O_RDWR|O_NDELAY, 0);
+ if (fd >= 0)
+ {
+ ioctl (fd, VT_GETSTATE, &vts);
+ if (ioctl (fd, VT_DISALLOCATE, vtno) < 0)
+ fprintf (stderr, "Can't deallocate console %d errno %d\n", vtno, errno);
+ close (fd);
+ }
+ return;
+}
+
+KdOsFuncs LinuxFuncs = {
+ LinuxInit,
+ LinuxEnable,
+ LinuxSpecialKey,
+ LinuxDisable,
+ LinuxFini,
+};
diff --git a/xc/programs/Xserver/hw/kdrive/linux/Imakefile b/xc/programs/Xserver/hw/kdrive/linux/Imakefile
new file mode 100644
index 000000000..2871bb463
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/linux/Imakefile
@@ -0,0 +1,16 @@
+XCOMM $XConsortium: Imakefile /main/10 1996/12/02 10:20:33 lehors $
+XCOMM $XFree86: xc/programs/Xserver/hw/kdrive/linux/Imakefile,v 1.1 1999/12/30 03:03:09 robin Exp $
+#include <Server.tmpl>
+
+SRCS = keyboard.c linux.c ps2.c
+
+OBJS = keyboard.o linux.o ps2.o
+
+INCLUDES = -I. -I.. -I$(XBUILDINCDIR) -I$(FONTINCSRC) \
+ -I../../../fb -I../../../mi -I../../../include -I../../../os \
+ -I$(EXTINCSRC) -I$(XINCLUDESRC)
+
+NormalLibraryObjectRule()
+NormalLibraryTarget(linux,$(OBJS))
+
+DependTarget()
diff --git a/xc/programs/Xserver/hw/kdrive/linux/keyboard.c b/xc/programs/Xserver/hw/kdrive/linux/keyboard.c
new file mode 100644
index 000000000..dab78a436
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/linux/keyboard.c
@@ -0,0 +1,439 @@
+/*
+ * $Id: keyboard.c,v 1.1 2000/01/06 12:55:56 faith 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.
+ */
+
+#include "kdrive.h"
+#include "kkeymap.h"
+#include <linux/keyboard.h>
+#include <linux/kd.h>
+#include <X11/keysym.h>
+#include <termios.h>
+
+extern int LinuxConsoleFd;
+
+static const KeySym linux_to_x[256] = {
+ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+ XK_BackSpace, XK_Tab, XK_Linefeed, NoSymbol,
+ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+ NoSymbol, NoSymbol, NoSymbol, XK_Escape,
+ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+ XK_space, XK_exclam, XK_quotedbl, XK_numbersign,
+ XK_dollar, XK_percent, XK_ampersand, XK_apostrophe,
+ XK_parenleft, XK_parenright, XK_asterisk, XK_plus,
+ XK_comma, XK_minus, XK_period, XK_slash,
+ XK_0, XK_1, XK_2, XK_3,
+ XK_4, XK_5, XK_6, XK_7,
+ XK_8, XK_9, XK_colon, XK_semicolon,
+ XK_less, XK_equal, XK_greater, XK_question,
+ XK_at, XK_A, XK_B, XK_C,
+ XK_D, XK_E, XK_F, XK_G,
+ XK_H, XK_I, XK_J, XK_K,
+ XK_L, XK_M, XK_N, XK_O,
+ XK_P, XK_Q, XK_R, XK_S,
+ XK_T, XK_U, XK_V, XK_W,
+ XK_X, XK_Y, XK_Z, XK_bracketleft,
+ XK_backslash, XK_bracketright,XK_asciicircum, XK_underscore,
+ XK_grave, XK_a, XK_b, XK_c,
+ XK_d, XK_e, XK_f, XK_g,
+ XK_h, XK_i, XK_j, XK_k,
+ XK_l, XK_m, XK_n, XK_o,
+ XK_p, XK_q, XK_r, XK_s,
+ XK_t, XK_u, XK_v, XK_w,
+ XK_x, XK_y, XK_z, XK_braceleft,
+ XK_bar, XK_braceright, XK_asciitilde, XK_Delete,
+ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+ XK_nobreakspace,XK_exclamdown, XK_cent, XK_sterling,
+ XK_currency, XK_yen, XK_brokenbar, XK_section,
+ XK_diaeresis, XK_copyright, XK_ordfeminine, XK_guillemotleft,
+ XK_notsign, XK_hyphen, XK_registered, XK_macron,
+ XK_degree, XK_plusminus, XK_twosuperior, XK_threesuperior,
+ XK_acute, XK_mu, XK_paragraph, XK_periodcentered,
+ XK_cedilla, XK_onesuperior, XK_masculine, XK_guillemotright,
+ XK_onequarter, XK_onehalf, XK_threequarters,XK_questiondown,
+ XK_Agrave, XK_Aacute, XK_Acircumflex, XK_Atilde,
+ XK_Adiaeresis, XK_Aring, XK_AE, XK_Ccedilla,
+ XK_Egrave, XK_Eacute, XK_Ecircumflex, XK_Ediaeresis,
+ XK_Igrave, XK_Iacute, XK_Icircumflex, XK_Idiaeresis,
+ XK_ETH, XK_Ntilde, XK_Ograve, XK_Oacute,
+ XK_Ocircumflex, XK_Otilde, XK_Odiaeresis, XK_multiply,
+ XK_Ooblique, XK_Ugrave, XK_Uacute, XK_Ucircumflex,
+ XK_Udiaeresis, XK_Yacute, XK_THORN, XK_ssharp,
+ XK_agrave, XK_aacute, XK_acircumflex, XK_atilde,
+ XK_adiaeresis, XK_aring, XK_ae, XK_ccedilla,
+ XK_egrave, XK_eacute, XK_ecircumflex, XK_ediaeresis,
+ XK_igrave, XK_iacute, XK_icircumflex, XK_idiaeresis,
+ XK_eth, XK_ntilde, XK_ograve, XK_oacute,
+ XK_ocircumflex, XK_otilde, XK_odiaeresis, XK_division,
+ XK_oslash, XK_ugrave, XK_uacute, XK_ucircumflex,
+ XK_udiaeresis, XK_yacute, XK_thorn, XK_ydiaeresis
+};
+
+static unsigned char tbl[KD_MAX_WIDTH] =
+{
+ 0,
+ 1 << KG_SHIFT,
+ (1 << KG_ALT),
+ (1 << KG_ALT) | (1 << KG_SHIFT)
+};
+
+static void
+readKernelMapping()
+{
+ KeySym *k;
+ int i, j;
+ struct kbentry kbe;
+ int minKeyCode, maxKeyCode;
+
+ minKeyCode = NR_KEYS;
+ maxKeyCode = 0;
+ k = kdKeymap;
+ for (i = 0;
+ i < NR_KEYS && (maxKeyCode - minKeyCode + 1) < KD_MAX_LENGTH;
+ ++i)
+ {
+ kbe.kb_index = i;
+
+ for (j = 0; j < KD_MAX_WIDTH; ++j)
+ {
+ unsigned short kval;
+
+ k[j] = NoSymbol;
+
+ kbe.kb_table = tbl[j];
+ if (ioctl(LinuxConsoleFd, KDGKBENT, &kbe))
+ continue;
+
+ kval = KVAL(kbe.kb_value);
+ switch (KTYP(kbe.kb_value))
+ {
+ case KT_LATIN:
+ case KT_LETTER:
+ k[j] = linux_to_x[kval];
+ break;
+
+ case KT_FN:
+ if (kval <= 19)
+ k[j] = XK_F1 + kval;
+ else switch (kbe.kb_value)
+ {
+ case K_FIND:
+ k[j] = XK_Home; /* or XK_Find */
+ break;
+ case K_INSERT:
+ k[j] = XK_Insert;
+ break;
+ case K_REMOVE:
+ k[j] = XK_Delete;
+ break;
+ case K_SELECT:
+ k[j] = XK_End; /* or XK_Select */
+ break;
+ case K_PGUP:
+ k[j] = XK_Prior;
+ break;
+ case K_PGDN:
+ k[j] = XK_Next;
+ break;
+ case K_HELP:
+ k[j] = XK_Help;
+ break;
+ case K_DO:
+ k[j] = XK_Execute;
+ break;
+ case K_PAUSE:
+ k[j] = XK_Pause;
+ break;
+ case K_MACRO:
+ k[j] = XK_Menu;
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case KT_SPEC:
+ switch (kbe.kb_value)
+ {
+ case K_ENTER:
+ k[j] = XK_Return;
+ break;
+ case K_BREAK:
+ k[j] = XK_Break;
+ break;
+ case K_CAPS:
+ k[j] = XK_Caps_Lock;
+ break;
+ case K_NUM:
+ k[j] = XK_Num_Lock;
+ break;
+ case K_HOLD:
+ k[j] = XK_Scroll_Lock;
+ break;
+ case K_COMPOSE:
+ k[j] = XK_Multi_key;
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case KT_PAD:
+ switch (kbe.kb_value)
+ {
+ case K_PPLUS:
+ k[j] = XK_KP_Add;
+ break;
+ case K_PMINUS:
+ k[j] = XK_KP_Subtract;
+ break;
+ case K_PSTAR:
+ k[j] = XK_KP_Multiply;
+ break;
+ case K_PSLASH:
+ k[j] = XK_KP_Divide;
+ break;
+ case K_PENTER:
+ k[j] = XK_KP_Enter;
+ break;
+ case K_PCOMMA:
+ k[j] = XK_KP_Separator;
+ break;
+ case K_PDOT:
+ k[j] = XK_KP_Decimal;
+ break;
+ case K_PPLUSMINUS:
+ k[j] = XK_KP_Subtract;
+ break;
+ default:
+ if (kval <= 9)
+ k[j] = XK_KP_0 + kval;
+ break;
+ }
+ break;
+
+ /*
+ * KT_DEAD keys are for accelerated diacritical creation.
+ */
+ case KT_DEAD:
+ switch (kbe.kb_value)
+ {
+ case K_DGRAVE:
+ k[j] = XK_dead_grave;
+ break;
+ case K_DACUTE:
+ k[j] = XK_dead_acute;
+ break;
+ case K_DCIRCM:
+ k[j] = XK_dead_circumflex;
+ break;
+ case K_DTILDE:
+ k[j] = XK_dead_tilde;
+ break;
+ case K_DDIERE:
+ k[j] = XK_dead_diaeresis;
+ break;
+ }
+ break;
+
+ case KT_CUR:
+ switch (kbe.kb_value)
+ {
+ case K_DOWN:
+ k[j] = XK_Down;
+ break;
+ case K_LEFT:
+ k[j] = XK_Left;
+ break;
+ case K_RIGHT:
+ k[j] = XK_Right;
+ break;
+ case K_UP:
+ k[j] = XK_Up;
+ break;
+ }
+ break;
+
+ case KT_SHIFT:
+ switch (kbe.kb_value)
+ {
+ case K_ALTGR:
+ k[j] = XK_Alt_R;
+ break;
+ case K_ALT:
+ k[j] = (kbe.kb_index == 0x64 ?
+ XK_Alt_R : XK_Alt_L);
+ break;
+ case K_CTRL:
+ k[j] = (kbe.kb_index == 0x61 ?
+ XK_Control_R : XK_Control_L);
+ break;
+ case K_CTRLL:
+ k[j] = XK_Control_L;
+ break;
+ case K_CTRLR:
+ k[j] = XK_Control_R;
+ break;
+ case K_SHIFT:
+ k[j] = (kbe.kb_index == 0x36 ?
+ XK_Shift_R : XK_Shift_L);
+ break;
+ case K_SHIFTL:
+ k[j] = XK_Shift_L;
+ break;
+ case K_SHIFTR:
+ k[j] = XK_Shift_R;
+ break;
+ default:
+ break;
+ }
+ break;
+
+ /*
+ * KT_ASCII keys accumulate a 3 digit decimal number that gets
+ * emitted when the shift state changes. We can't emulate that.
+ */
+ case KT_ASCII:
+ break;
+
+ case KT_LOCK:
+ if (kbe.kb_value == K_SHIFTLOCK)
+ k[j] = XK_Shift_Lock;
+ break;
+
+ default:
+ break;
+ }
+ if (i < minKeyCode)
+ minKeyCode = i;
+ if (i > maxKeyCode)
+ maxKeyCode = i;
+ }
+
+ if (minKeyCode == NR_KEYS)
+ continue;
+
+ if (k[3] == k[2]) k[3] = NoSymbol;
+ if (k[2] == k[1]) k[2] = NoSymbol;
+ if (k[1] == k[0]) k[1] = NoSymbol;
+ if (k[0] == k[2] && k[1] == k[3]) k[2] = k[3] = NoSymbol;
+ if (k[3] == k[0] && k[2] == k[1] && k[2] == NoSymbol) k[3] =NoSymbol;
+
+ k += KD_MAX_WIDTH;
+ }
+ kdMinScanCode = minKeyCode;
+ kdMaxScanCode = maxKeyCode;
+}
+
+void
+LinuxKeyboardLoad (void)
+{
+ readKernelMapping ();
+}
+
+static int LinuxKbdTrans;
+static struct termios LinuxTermios;
+
+int
+LinuxKeyboardInit (void)
+{
+ struct termios nTty;
+
+ ioctl (LinuxConsoleFd, KDGKBMODE, &LinuxKbdTrans);
+ tcgetattr (LinuxConsoleFd, &LinuxTermios);
+
+ ioctl(LinuxConsoleFd, KDSKBMODE, K_MEDIUMRAW);
+ nTty = LinuxTermios;
+ nTty.c_iflag = (IGNPAR | IGNBRK) & (~PARMRK) & (~ISTRIP);
+ nTty.c_oflag = 0;
+ nTty.c_cflag = CREAD | CS8;
+ nTty.c_lflag = 0;
+ nTty.c_cc[VTIME]=0;
+ nTty.c_cc[VMIN]=1;
+ cfsetispeed(&nTty, 9600);
+ cfsetospeed(&nTty, 9600);
+ tcsetattr(LinuxConsoleFd, TCSANOW, &nTty);
+ return LinuxConsoleFd;
+}
+
+void
+LinuxKeyboardFini (int fd)
+{
+ ioctl(LinuxConsoleFd, KDSKBMODE, LinuxKbdTrans);
+ tcsetattr(LinuxConsoleFd, TCSANOW, &LinuxTermios);
+}
+
+void
+LinuxKeyboardRead (int fd)
+{
+ unsigned char buf[256], *b;
+ int n;
+
+ while ((n = read (fd, buf, sizeof (buf))) > 0)
+ {
+ b = buf;
+ while (n--)
+ {
+ KdEnqueueKeyboardEvent (b[0] & 0x7f, b[0] & 0x80);
+ b++;
+ }
+ }
+}
+
+void
+LinuxKeyboardLeds (int leds)
+{
+ ioctl (LinuxConsoleFd, KDSETLED, leds & 7);
+}
+
+void
+LinuxKeyboardBell (int volume, int pitch, int duration)
+{
+ if (volume && pitch)
+ {
+ ioctl(LinuxConsoleFd, KDMKTONE,
+ ((1193190 / pitch) & 0xffff) |
+ (((unsigned long)duration *
+ volume / 50) << 16));
+
+ }
+}
+
+KdKeyboardFuncs LinuxKeyboardFuncs = {
+ LinuxKeyboardLoad,
+ LinuxKeyboardInit,
+ LinuxKeyboardRead,
+ LinuxKeyboardLeds,
+ LinuxKeyboardBell,
+ LinuxKeyboardFini,
+ 3,
+};
diff --git a/xc/programs/Xserver/hw/kdrive/linux/linux.c b/xc/programs/Xserver/hw/kdrive/linux/linux.c
new file mode 100644
index 000000000..63018e909
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/linux/linux.c
@@ -0,0 +1,329 @@
+/*
+ * $Id: linux.c,v 1.1 2000/01/06 12:55:56 faith 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.
+ */
+
+#include "kdrive.h"
+#include <errno.h>
+#include <signal.h>
+#include <linux/vt.h>
+#include <linux/kd.h>
+#include <sys/stat.h>
+#include <keysym.h>
+
+static int vtno;
+int LinuxConsoleFd;
+static int activeVT;
+static Bool enabled;
+
+void
+LinuxVTRequest (int sig)
+{
+ kdSwitchPending = TRUE;
+}
+
+/* Check before chowning -- this avoids touching the file system */
+void
+LinuxCheckChown (char *file)
+{
+ struct stat st;
+ __uid_t u;
+ __gid_t g;
+
+ if (stat (file, &st) < 0)
+ return;
+ u = getuid ();
+ g = getgid ();
+ if (st.st_uid != u || st.st_gid != g)
+ chown (file, u, g);
+}
+
+int
+LinuxInit ()
+{
+ int i, fd;
+ char vtname[11];
+ struct vt_stat vts;
+ struct stat statb;
+
+ LinuxConsoleFd = -1;
+ /* check if we're run with euid==0 */
+ if (geteuid() != 0)
+ {
+ FatalError("LinuxInit: Server must be suid root\n");
+ }
+
+ if ((fd = open("/dev/tty0",O_WRONLY,0)) < 0)
+ {
+ FatalError(
+ "LinuxInit: Cannot open /dev/tty0 (%s)\n",
+ strerror(errno));
+ }
+ if ((ioctl(fd, VT_OPENQRY, &vtno) < 0) ||
+ (vtno == -1))
+ {
+ FatalError("xf86OpenConsole: Cannot find a free VT\n");
+ }
+ close(fd);
+
+/* ErrorF("(using VT number %d)\n\n", vtno); */
+
+ sprintf(vtname,"/dev/tty%d",vtno); /* /dev/tty1-64 */
+
+ if ((LinuxConsoleFd = open(vtname, O_RDWR|O_NDELAY, 0)) < 0)
+ {
+ FatalError("LinuxInit: Cannot open %s (%s)\n",
+ vtname, strerror(errno));
+ }
+
+ /* change ownership of the vt */
+ LinuxCheckChown (vtname);
+
+ /*
+ * the current VT device we're running on is not "console", we want
+ * to grab all consoles too
+ *
+ * Why is this needed?
+ */
+ LinuxCheckChown ("/dev/tty0");
+ /*
+ * Linux doesn't switch to an active vt after the last close of a vt,
+ * so we do this ourselves by remembering which is active now.
+ */
+ if (ioctl(LinuxConsoleFd, VT_GETSTATE, &vts) == 0)
+ {
+ activeVT = vts.v_active;
+ }
+
+ return 1;
+}
+
+Bool
+LinuxFindPci (CARD16 vendor, CARD16 device, CARD32 count, KdCardAttr *attr)
+{
+ FILE *f;
+ char line[2048], *l, *end;
+ CARD32 bus, id, mode, addr;
+ int n;
+ CARD32 ven_dev;
+ Bool ret = FALSE;
+ int i;
+
+ ven_dev = (((CARD32) vendor) << 16) | ((CARD32) device);
+ f = fopen ("/proc/bus/pci/devices", "r");
+ if (!f)
+ return FALSE;
+ attr->io = 0;
+ while (fgets (line, sizeof (line)-1, f))
+ {
+ line[sizeof(line)-1] = '\0';
+ l = line;
+ bus = strtoul (l, &end, 16);
+ if (end == l)
+ continue;
+ l = end;
+ id = strtoul (l, &end, 16);
+ if (end == l)
+ continue;
+ l = end;
+ if (id != ven_dev)
+ continue;
+ if (count--)
+ continue;
+ (void) strtoul (l, &end, 16);
+ if (end == l)
+ continue;
+ l = end;
+ n = 0;
+ for (i = 0; i < 6; i++)
+ {
+ addr = strtoul (l, &end, 16);
+ if (end == l)
+ break;
+ if (addr & 1)
+ attr->io = addr & ~0xf;
+ else
+ {
+ if (n == KD_MAX_CARD_ADDRESS)
+ break;
+ attr->address[n++] = addr & ~0xf;
+ }
+ l = end;
+ }
+ while (n > 0)
+ {
+ if (attr->address[n-1] != 0)
+ break;
+ n--;
+ }
+ attr->naddr = n;
+ ret = TRUE;
+ break;
+ }
+ fclose (f);
+ return ret;
+}
+
+void
+LinuxEnable (void)
+{
+ struct sigaction act;
+ struct vt_mode VT;
+
+ if (enabled)
+ return;
+ if (kdSwitchPending)
+ {
+ kdSwitchPending = FALSE;
+ ioctl (LinuxConsoleFd, VT_RELDISP, VT_ACKACQ);
+ }
+ /*
+ * now get the VT
+ */
+ if (ioctl(LinuxConsoleFd, VT_ACTIVATE, vtno) != 0)
+ {
+ ErrorF("LinuxInit: VT_ACTIVATE failed\n");
+ }
+ if (ioctl(LinuxConsoleFd, VT_WAITACTIVE, vtno) != 0)
+ {
+ ErrorF("LinuxInit: VT_WAITACTIVE failed\n");
+ }
+ if (ioctl(LinuxConsoleFd, VT_GETMODE, &VT) < 0)
+ {
+ FatalError ("LinuxInit: VT_GETMODE failed\n");
+ }
+
+ act.sa_handler = LinuxVTRequest;
+ sigemptyset (&act.sa_mask);
+ act.sa_flags = 0;
+ act.sa_restorer = 0;
+ sigaction (SIGUSR1, &act, 0);
+
+ VT.mode = VT_PROCESS;
+ VT.relsig = SIGUSR1;
+ VT.acqsig = SIGUSR1;
+ if (ioctl(LinuxConsoleFd, VT_SETMODE, &VT) < 0)
+ {
+ FatalError("LinuxInit: VT_SETMODE VT_PROCESS failed\n");
+ }
+ if (ioctl(LinuxConsoleFd, KDSETMODE, KD_GRAPHICS) < 0)
+ {
+ FatalError("LinuxInit: KDSETMODE KD_GRAPHICS failed\n");
+ }
+ enabled = TRUE;
+}
+
+Bool
+LinuxSpecialKey (KeySym sym)
+{
+ struct vt_stat vts;
+ int con;
+
+ if (XK_F1 <= sym && sym <= XK_F12)
+ {
+ con = sym - XK_F1 + 1;
+ ioctl (LinuxConsoleFd, VT_GETSTATE, &vts);
+ if (con != vts.v_active && (vts.v_state & (1 << con)))
+ {
+ ioctl (LinuxConsoleFd, VT_ACTIVATE, con);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+void
+LinuxDisable (void)
+{
+ ioctl(LinuxConsoleFd, KDSETMODE, KD_TEXT); /* Back to text mode ... */
+ if (kdSwitchPending)
+ {
+ kdSwitchPending = FALSE;
+ ioctl (LinuxConsoleFd, VT_RELDISP, 1);
+ }
+ enabled = FALSE;
+}
+
+void
+LinuxFini (void)
+{
+ struct vt_mode VT;
+ struct vt_stat vts;
+ int fd;
+
+ if (LinuxConsoleFd < 0)
+ return;
+
+ if (ioctl(LinuxConsoleFd, VT_GETMODE, &VT) != -1)
+ {
+ VT.mode = VT_AUTO;
+ ioctl(LinuxConsoleFd, VT_SETMODE, &VT); /* set dflt vt handling */
+ }
+ ioctl (LinuxConsoleFd, VT_GETSTATE, &vts);
+ /*
+ * Find a legal VT to switch to, either the one we started from
+ * or the lowest active one that isn't ours
+ */
+ if (activeVT < 0 ||
+ activeVT == vts.v_active ||
+ !(vts.v_state & (1 << activeVT)))
+ {
+ for (activeVT = 1; activeVT < 16; activeVT++)
+ if (activeVT != vtno && (vts.v_state & (1 << activeVT)))
+ break;
+ if (activeVT == 16)
+ activeVT = -1;
+ }
+ /*
+ * Perform a switch back to the active VT when we were started
+ */
+ if (activeVT >= -1)
+ {
+ ioctl (LinuxConsoleFd, VT_ACTIVATE, activeVT);
+ ioctl (LinuxConsoleFd, VT_WAITACTIVE, activeVT);
+ activeVT = -1;
+ }
+ close(LinuxConsoleFd); /* make the vt-manager happy */
+ fd = open ("/dev/tty0", O_RDWR|O_NDELAY, 0);
+ if (fd >= 0)
+ {
+ ioctl (fd, VT_GETSTATE, &vts);
+ if (ioctl (fd, VT_DISALLOCATE, vtno) < 0)
+ fprintf (stderr, "Can't deallocate console %d errno %d\n", vtno, errno);
+ close (fd);
+ }
+ return;
+}
+
+KdOsFuncs LinuxFuncs = {
+ LinuxInit,
+ LinuxEnable,
+ LinuxSpecialKey,
+ LinuxDisable,
+ LinuxFini,
+};
+
+void
+OsVendorInit (void)
+{
+ KdOsInit (&LinuxFuncs);
+}
diff --git a/xc/programs/Xserver/hw/kdrive/linux/ps2.c b/xc/programs/Xserver/hw/kdrive/linux/ps2.c
new file mode 100644
index 000000000..57805d104
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/linux/ps2.c
@@ -0,0 +1,131 @@
+/*
+ * $Id: ps2.c,v 1.1 2000/01/06 12:55:56 faith 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.
+ */
+
+#define NEED_EVENTS
+#include "X.h"
+#include "Xproto.h"
+#include "inputstr.h"
+#include "scrnintstr.h"
+#include "kdrive.h"
+#include "Xpoll.h"
+
+int
+Ps2ReadBytes (int fd, char *buf, int len, int min)
+{
+ int n, tot;
+ fd_set set;
+ struct timeval tv;
+
+ tot = 0;
+ while (len)
+ {
+ n = read (fd, buf, len);
+ if (n > 0)
+ {
+ tot += n;
+ buf += n;
+ len -= n;
+ }
+ if (tot % min == 0)
+ break;
+ FD_ZERO (&set);
+ FD_SET (fd, &set);
+ tv.tv_sec = 0;
+ tv.tv_usec = 100 * 1000;
+ n = select (fd + 1, &set, 0, 0, &tv);
+ if (n <= 0)
+ break;
+ }
+ return tot;
+}
+
+void
+Ps2Read (int ps2Port)
+{
+ unsigned char buf[3 * 200];
+ unsigned char *b;
+ int n;
+ int dx, dy;
+ unsigned long flags;
+
+ while ((n = Ps2ReadBytes (ps2Port, buf, sizeof (buf), 3)) > 0)
+ {
+ b = buf;
+ while (n >= 3)
+ {
+ flags = KD_MOUSE_DELTA;
+ if (b[0] & 4)
+ flags |= KD_BUTTON_2;
+ if (b[0] & 2)
+ flags |= KD_BUTTON_3;
+ if (b[0] & 1)
+ flags |= KD_BUTTON_1;
+
+ dx = b[1];
+ if (b[0] & 0x10)
+ dx -= 256;
+ dy = b[2];
+ if (b[0] & 0x20)
+ dy -= 256;
+ dy = -dy;
+ n -= 3;
+ b += 3;
+ KdEnqueueMouseEvent (flags, dx, dy);
+ }
+ }
+}
+
+char *Ps2Names[] = {
+ "/dev/psaux",
+ "/dev/mouse",
+};
+
+#define NUM_PS2_NAMES (sizeof (Ps2Names) / sizeof (Ps2Names[0]))
+
+int
+Ps2Init (void)
+{
+ int i;
+ int ps2Port;
+
+ for (i = 0; i < NUM_PS2_NAMES; i++)
+ {
+ ps2Port = open (Ps2Names[i], 0);
+ if (ps2Port >= 0)
+ return ps2Port;
+ }
+}
+
+void
+Ps2Fini (int ps2Port)
+{
+ if (ps2Port >= 0)
+ close (ps2Port);
+}
+
+KdMouseFuncs Ps2MouseFuncs = {
+ Ps2Init,
+ Ps2Read,
+ Ps2Fini
+};
diff --git a/xc/programs/Xserver/hw/kdrive/ps2.c b/xc/programs/Xserver/hw/kdrive/ps2.c
new file mode 100644
index 000000000..c0ae9332f
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/ps2.c
@@ -0,0 +1,132 @@
+/*
+ * $Id: ps2.c,v 1.1 2000/01/06 12:55:48 faith 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/ps2.c,v 1.1 1999/11/19 13:53:51 hohndel Exp $ */
+
+#define NEED_EVENTS
+#include "X.h"
+#include "Xproto.h"
+#include "inputstr.h"
+#include "scrnintstr.h"
+#include "kdrive.h"
+#include "Xpoll.h"
+
+int
+Ps2ReadBytes (int fd, char *buf, int len, int min)
+{
+ int n, tot;
+ fd_set set;
+ struct timeval tv;
+
+ tot = 0;
+ while (len)
+ {
+ n = read (fd, buf, len);
+ if (n > 0)
+ {
+ tot += n;
+ buf += n;
+ len -= n;
+ }
+ if (tot % min == 0)
+ break;
+ FD_ZERO (&set);
+ FD_SET (fd, &set);
+ tv.tv_sec = 0;
+ tv.tv_usec = 100 * 1000;
+ n = select (fd + 1, &set, 0, 0, &tv);
+ if (n <= 0)
+ break;
+ }
+ return tot;
+}
+
+void
+Ps2Read (int ps2Port)
+{
+ unsigned char buf[3 * 200];
+ unsigned char *b;
+ int n;
+ int dx, dy;
+ unsigned long flags;
+
+ while ((n = Ps2ReadBytes (ps2Port, buf, sizeof (buf), 3)) > 0)
+ {
+ b = buf;
+ while (n >= 3)
+ {
+ flags = KD_MOUSE_DELTA;
+ if (b[0] & 4)
+ flags |= KD_BUTTON_2;
+ if (b[0] & 2)
+ flags |= KD_BUTTON_3;
+ if (b[0] & 1)
+ flags |= KD_BUTTON_1;
+
+ dx = b[1];
+ if (b[0] & 0x10)
+ dx -= 256;
+ dy = b[2];
+ if (b[0] & 0x20)
+ dy -= 256;
+ dy = -dy;
+ n -= 3;
+ b += 3;
+ KdEnqueueMouseEvent (flags, dx, dy);
+ }
+ }
+}
+
+char *Ps2Names[] = {
+ "/dev/psaux",
+ "/dev/mouse",
+};
+
+#define NUM_PS2_NAMES (sizeof (Ps2Names) / sizeof (Ps2Names[0]))
+
+int
+Ps2Init (void)
+{
+ int i;
+ int ps2Port;
+
+ for (i = 0; i < NUM_PS2_NAMES; i++)
+ {
+ ps2Port = open (Ps2Names[i], 0);
+ if (ps2Port >= 0)
+ return ps2Port;
+ }
+}
+
+void
+Ps2Fini (int ps2Port)
+{
+ if (ps2Port >= 0)
+ close (ps2Port);
+}
+
+KdMouseFuncs Ps2MouseFuncs = {
+ Ps2Init,
+ Ps2Read,
+ Ps2Fini
+};
diff --git a/xc/programs/Xserver/hw/kdrive/savage/Imakefile b/xc/programs/Xserver/hw/kdrive/savage/Imakefile
new file mode 100644
index 000000000..74aee23d5
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/savage/Imakefile
@@ -0,0 +1,15 @@
+XCOMM $XConsortium: Imakefile /main/10 1996/12/02 10:20:33 lehors $
+XCOMM $XFree86: xc/programs/Xserver/hw/kdrive/savage/Imakefile,v 1.1 1999/11/19 13:53:54 hohndel Exp $
+#include <Server.tmpl>
+
+SRCS = s3.c s3clock.c s3cmap.c s3curs.c s3draw.c s3gc.c s3reg.c s3stub.c
+
+OBJS = s3.o s3clock.o s3cmap.o s3curs.o s3draw.o s3gc.o s3reg.o s3stub.o
+
+INCLUDES = -I.. -I. -I$(XBUILDINCDIR) -I$(FONTINCSRC) \
+ -I../../../fb -I../../../mi -I../../../include -I../../../os \
+ -I$(EXTINCSRC) -I$(XINCLUDESRC)
+
+NormalLibraryObjectRule()
+NormalLibraryTarget(savage,$(OBJS))
+DependTarget()
diff --git a/xc/programs/Xserver/hw/kdrive/savage/s3.c b/xc/programs/Xserver/hw/kdrive/savage/s3.c
new file mode 100644
index 000000000..8d9a48a91
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/savage/s3.c
@@ -0,0 +1,1462 @@
+/*
+ * $Id: s3.c,v 1.1 2000/01/06 12:55:49 faith 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/savage/s3.c,v 1.2 1999/12/30 03:03:10 robin Exp $ */
+
+#include "s3.h"
+
+#define REGISTERS_OFFSET (0x1000000)
+#define PACKED_OFFSET (0x8100)
+#define IOMAP_OFFSET (0x8000)
+
+static void
+_s3SetBlank (S3Ptr s3, S3Vga *s3vga, Bool blank)
+{
+ CARD8 clock_mode;
+
+ s3SetImm(s3vga, s3_screen_off, blank ? 1 : 0);
+}
+
+Bool
+s3CardInit (KdCardInfo *card)
+{
+ S3CardInfo *s3c;
+ S3Ptr s3;
+ S3Vga *s3vga;
+ int size;
+ CARD8 *registers;
+ CARD32 s3FrameBuffer;
+ CARD32 s3Registers;
+ CARD8 *temp_buffer;
+ CARD32 max_memory;
+ VGA32 save_linear_window_size;
+ VGA32 save_enable_linear;
+ VGA32 save_register_lock_2;
+ VGA32 save_misc_output;
+
+ s3c = (S3CardInfo *) xalloc (sizeof (S3CardInfo));
+ if (!s3c)
+ {
+ goto bail0;
+ }
+
+ memset (s3c, '\0', sizeof (S3CardInfo));
+
+ card->driver = s3c;
+
+#ifdef VXWORKS
+ s3c->bios_initialized = 0;
+#else
+ s3c->bios_initialized = 1;
+#endif
+
+ if (card->attr.naddr > 1 && card->attr.address[1])
+ {
+ s3FrameBuffer = card->attr.address[1];
+ s3Registers = card->attr.address[0];
+ max_memory = 32 * 1024 * 1024;
+ }
+ else
+ {
+ s3FrameBuffer = card->attr.address[0];
+ s3Registers = s3FrameBuffer + REGISTERS_OFFSET;
+ max_memory = 16 * 1024 * 1024;
+ }
+
+#ifdef DEBUG
+ fprintf (stderr, "S3 at 0x%x/0x%x\n", s3Registers, s3FrameBuffer);
+#endif
+ registers = KdMapDevice (s3Registers,
+ sizeof (S3) + PACKED_OFFSET);
+ if (!registers)
+ {
+ ErrorF ("Can't map s3 device\n");
+ goto bail2;
+ }
+ s3 = (S3Ptr) (registers + PACKED_OFFSET);
+ s3c->registers = registers;
+ s3c->s3 = s3;
+
+ s3vga = &s3c->s3vga;
+ s3RegInit (s3vga, (VGAVOL8 *) (registers + IOMAP_OFFSET));
+
+ if (!s3c->bios_initialized)
+ {
+ volatile CARD32 *wakeup;
+
+ wakeup = (volatile CARD32 *) (registers + 0x8510);
+ ErrorF ("Wakeup S3 chip at 0x%x\n", wakeup);
+ ErrorF ("Wakeup was 0x%x\n", *wakeup);
+ /* wakeup the chip */
+ *(volatile CARD32 *) (registers + 0x8510) = 1;
+ ErrorF ("Wakeup is 0x%x\n", *wakeup);
+ }
+ s3Set (s3vga, s3_io_addr_select, 1);
+ s3Set (s3vga, s3_enable_ram, 1);
+ VgaFlush (&s3vga->card);
+
+ save_register_lock_2 = s3Get (s3vga, s3_register_lock_2);
+ s3SetImm (s3vga, s3_register_lock_2, 0xa0);
+ save_linear_window_size = s3Get (s3vga, s3_linear_window_size);
+ save_enable_linear = s3Get (s3vga, s3_enable_linear);
+ s3Set (s3vga, s3_linear_window_size, 3);
+ s3Set (s3vga, s3_enable_linear, 1);
+ VgaFlush (&s3vga->card);
+ VgaFinish (&s3vga->card);
+
+ /*
+ * Can't trust S3 register value for frame buffer amount, must compute
+ */
+ temp_buffer = KdMapDevice (s3FrameBuffer, max_memory);
+
+ s3c->memory = KdFrameBufferSize (temp_buffer, max_memory);
+
+ s3Set (s3vga, s3_linear_window_size, save_linear_window_size);
+ s3Set (s3vga, s3_enable_linear, save_enable_linear);
+ VgaFlush (&s3vga->card);
+ s3SetImm (s3vga, s3_register_lock_2, save_register_lock_2);
+ VgaFinish (&s3vga->card);
+#ifdef DEBUG
+ fprintf (stderr, "Frame buffer 0x%x\n", s3c->memory);
+#endif
+ KdUnmapDevice (temp_buffer, max_memory);
+
+ if (!s3c->memory)
+ {
+ ErrorF ("Can't detect s3 frame buffer at 0x%x\n", s3FrameBuffer);
+ goto bail3;
+ }
+
+ s3c->frameBuffer = KdMapDevice (s3FrameBuffer, s3c->memory);
+ if (!s3c->frameBuffer)
+ {
+ ErrorF ("Can't map s3 frame buffer\n");
+ goto bail3;
+ }
+
+ card->driver = s3c;
+
+ return TRUE;
+bail3:
+ KdUnmapDevice ((void *) s3, sizeof (S3));
+bail2:
+bail1:
+ xfree (s3c);
+bail0:
+ return FALSE;
+}
+
+Bool
+s3ModeSupported (KdScreenInfo *screen,
+ const KdMonitorTiming *t)
+{
+ /* make sure the clock isn't too fast */
+ if (t->clock > S3_MAX_CLOCK * 2)
+ return FALSE;
+ /* width must be a multiple of 16 */
+ if (t->horizontal & 0xf)
+ return FALSE;
+ return TRUE;
+}
+
+Bool
+s3ModeUsable (KdScreenInfo *screen)
+{
+ KdCardInfo *card = screen->card;
+ S3CardInfo *s3c = (S3CardInfo *) card->driver;
+ int screen_size;
+ int pixel_width;
+ int byte_width;
+
+ if (screen->depth >= 24)
+ {
+ screen->depth = 24;
+ screen->bitsPerPixel = 32;
+ }
+ else if (screen->depth >= 16)
+ {
+ screen->depth = 16;
+ screen->bitsPerPixel = 16;
+ }
+ else if (screen->depth >= 15)
+ {
+ screen->depth = 15;
+ screen->bitsPerPixel = 16;
+ }
+ else
+ {
+ screen->depth = 8;
+ screen->bitsPerPixel = 8;
+ }
+
+ byte_width = screen->width * (screen->bitsPerPixel >> 3);
+ pixel_width = screen->width;
+ screen->pixelStride = pixel_width;
+ screen->byteStride = byte_width;
+
+ screen_size = byte_width * screen->height;
+
+ return screen_size <= s3c->memory;
+}
+
+Bool
+s3ScreenInit (KdScreenInfo *screen)
+{
+ KdCardInfo *card = screen->card;
+ S3CardInfo *s3c = (S3CardInfo *) card->driver;
+ S3ScreenInfo *s3s;
+ int memory;
+ int requested_memory;
+ int v_total, h_total;
+ int m, n, r;
+ int i;
+ const KdMonitorTiming *t;
+ int screen_size;
+
+ s3s = (S3ScreenInfo *) xalloc (sizeof (S3ScreenInfo));
+ if (!s3s)
+ return FALSE;
+
+ memset (s3s, '\0', sizeof (S3ScreenInfo));
+
+#ifdef PHOENIX
+ screen->width = 1152;
+ screen->height = 900;
+ screen->rate = 85;
+ screen->depth = 32;
+#endif
+ if (!screen->width || !screen->height)
+ {
+ screen->width = 800;
+ screen->height = 600;
+ screen->rate = 72;
+ }
+ if (!screen->depth)
+ screen->depth = 8;
+
+ t = KdFindMode (screen, s3ModeSupported);
+ screen->rate = t->rate;
+ screen->width = t->horizontal;
+ screen->height = t->vertical;
+ s3GetClock (t->clock, &m, &n, &r, 511, 127, 4);
+#ifdef DEBUG
+ fprintf (stderr, "computed %d,%d,%d (%d)\n",
+ m, n, r, S3_CLOCK(m,n,r));
+#endif
+ /*
+ * Can only operate in pixel-doubled mode at 8 or 16 bits per pixel
+ */
+ if (screen->depth > 16 && S3_CLOCK(m,n,r) > S3_MAX_CLOCK)
+ screen->depth = 16;
+
+ if (!KdTuneMode (screen, s3ModeUsable, s3ModeSupported))
+ {
+ xfree (s3s);
+ return FALSE;
+ }
+
+ screen_size = screen->byteStride * screen->height;
+
+ memory = s3c->memory - screen_size;
+
+ /*
+ * Stick frame buffer at start of memory
+ */
+ screen->frameBuffer = s3c->frameBuffer;
+
+ /*
+ * Stick cursor at end of memory
+ */
+ if (memory >= 2048)
+ {
+ s3s->cursor_base = s3c->frameBuffer + (s3c->memory - 2048);
+ memory -= 2048;
+ }
+ else
+ s3s->cursor_base = 0;
+
+ /*
+ * Use remaining memory for off-screen storage, but only use
+ * one piece (either right or bottom).
+ */
+ if (memory >= screen->byteStride * S3_TILE_SIZE)
+ {
+ s3s->offscreen = s3c->frameBuffer + screen_size;
+ s3s->offscreen_x = 0;
+ s3s->offscreen_y = screen_size / screen->byteStride;
+ s3s->offscreen_width = screen->pixelStride;
+ s3s->offscreen_height = memory / screen->byteStride;
+ memory -= s3s->offscreen_height * screen->byteStride;
+ }
+ else if (screen->pixelStride - screen->width >= S3_TILE_SIZE)
+ {
+ s3s->offscreen = s3c->frameBuffer + screen->width;
+ s3s->offscreen_x = screen->width;
+ s3s->offscreen_y = 0;
+ s3s->offscreen_width = screen->pixelStride - screen->width;
+ s3s->offscreen_height = screen->height;
+ }
+ else
+ s3s->offscreen = 0;
+
+ switch (screen->depth) {
+ case 8:
+ screen->visuals = ((1 << StaticGray) |
+ (1 << GrayScale) |
+ (1 << StaticColor) |
+ (1 << PseudoColor) |
+ (1 << TrueColor) |
+ (1 << DirectColor));
+ screen->blueMask = 0x00;
+ screen->greenMask = 0x00;
+ screen->redMask = 0x00;
+ break;
+ case 15:
+ screen->visuals = (1 << TrueColor);
+ screen->blueMask = 0x001f;
+ screen->greenMask = 0x03e0;
+ screen->redMask = 0x7c00;
+ break;
+ case 16:
+ screen->visuals = (1 << TrueColor);
+ screen->blueMask = 0x001f;
+ screen->greenMask = 0x07e0;
+ screen->redMask = 0xf800;
+ break;
+ case 24:
+ screen->visuals = (1 << TrueColor);
+ screen->blueMask = 0x0000ff;
+ screen->greenMask = 0x00ff00;
+ screen->redMask = 0xff0000;
+ break;
+ }
+
+ screen->driver = s3s;
+
+ return TRUE;
+}
+
+typedef struct _biosInit {
+ VGA16 reg;
+ VGA8 value;
+} s3BiosInit;
+
+s3BiosInit s3BiosReg[] = {
+ S3_SR +0x15, 0x23,
+ S3_MISC_OUT, 0x2f,
+ 0xffff, 1,
+ S3_SR +0x15, 0x03,
+
+ S3_SR + 0x0, 0x03,
+ S3_SR + 0x1, 0x00,
+ S3_SR + 0x2, 0x03,
+ S3_SR + 0x3, 0x00,
+ S3_SR + 0x4, 0x02,
+ S3_SR + 0x5, 0x05,
+ S3_SR + 0x6, 0x06,
+ S3_SR + 0x7, 0x07,
+/* S3_SR + 0x8, 0x06, */
+ S3_SR + 0x9, 0x00,
+ S3_SR + 0xa, 0x0a,
+ S3_SR + 0xb, 0x00,
+ S3_SR + 0xc, 0x0c,
+ S3_SR + 0xd, 0x00,
+ S3_SR + 0xe, 0x0e,
+ S3_SR + 0xf, 0x0f,
+
+/* S3_SR +0x10, 0x00, */
+/* S3_SR +0x11, 0x0c, */
+ S3_SR +0x12, 0x01,
+ S3_SR +0x13, 0x52,
+ S3_SR +0x14, 0x00,
+
+/* S3_SR +0x15, 0x03, */
+
+ S3_SR +0x16, 0xc5,
+ S3_SR +0x17, 0xfc,
+ S3_SR +0x18, 0x40,
+ S3_SR +0x19, 0x00,
+ S3_SR +0x1a, 0x01,
+ S3_SR +0x1b, 0x02,
+ S3_SR +0x1c, 0x5d,
+ S3_SR +0x1d, 0x00,
+ S3_SR +0x1e, 0x00,
+ S3_SR +0x1f, 0x00,
+ S3_SR +0x20, 0x20,
+ S3_SR +0x21, 0x21,
+ S3_SR +0x22, 0x22,
+ S3_SR +0x23, 0x23,
+ S3_SR +0x24, 0x24,
+ S3_SR +0x25, 0x25,
+ S3_SR +0x26, 0x26,
+ S3_SR +0x27, 0x04,
+ S3_SR +0x28, 0xff,
+ S3_SR +0x29, 0x00,
+ S3_SR +0x2a, 0x2a,
+ S3_SR +0x2b, 0x2b,
+ S3_SR +0x2c, 0x2c,
+ S3_SR +0x2d, 0x2d,
+ S3_SR +0x2e, 0x2e,
+ S3_SR +0x2f, 0x2f,
+ S3_SR +0x30, 0x00,
+ S3_SR +0x31, 0x06,
+ S3_SR +0x32, 0x41,
+ S3_SR +0x33, 0x67,
+ S3_SR +0x34, 0x00,
+ S3_SR +0x35, 0x00,
+ S3_SR +0x36, 0x01,
+ S3_SR +0x37, 0x52,
+ S3_SR +0x38, 0x5d,
+ S3_SR +0x39, 0x05,
+ S3_SR +0x3a, 0x3a,
+ S3_SR +0x3b, 0x3b,
+ S3_SR +0x3c, 0x3c,
+ S3_SR +0x3d, 0x00,
+ S3_SR +0x3e, 0x3e,
+ S3_SR +0x3f, 0x00,
+ S3_SR +0x40, 0x40,
+ S3_SR +0x41, 0x41,
+ S3_SR +0x42, 0x42,
+ S3_SR +0x43, 0x43,
+ S3_SR +0x44, 0x44,
+ S3_SR +0x45, 0x45,
+ S3_SR +0x46, 0x46,
+ S3_SR +0x47, 0x47,
+ S3_SR +0x48, 0x48,
+ S3_SR +0x49, 0x49,
+ S3_SR +0x4a, 0x4a,
+ S3_SR +0x4b, 0x4b,
+ S3_SR +0x4c, 0x4c,
+ S3_SR +0x4d, 0x4d,
+ S3_SR +0x4e, 0x4e,
+ S3_SR +0x4f, 0x4f,
+ S3_SR +0x50, 0x00,
+ S3_SR +0x51, 0x00,
+ S3_SR +0x52, 0x00,
+ S3_SR +0x53, 0x00,
+ S3_SR +0x54, 0x00,
+ S3_SR +0x55, 0x00,
+ S3_SR +0x56, 0x00,
+ S3_SR +0x57, 0x00,
+ S3_SR +0x58, 0x00,
+ S3_SR +0x59, 0x70,
+ S3_SR +0x5a, 0x38,
+ S3_SR +0x5b, 0x08,
+ S3_SR +0x5c, 0x77,
+ S3_SR +0x5d, 0x77,
+ S3_SR +0x5e, 0x00,
+ S3_SR +0x5f, 0x00,
+ S3_SR +0x60, 0xff,
+ S3_SR +0x61, 0xbf,
+ S3_SR +0x62, 0xff,
+ S3_SR +0x63, 0xff,
+ S3_SR +0x64, 0xf7,
+ S3_SR +0x65, 0xff,
+ S3_SR +0x66, 0xff,
+ S3_SR +0x67, 0xff,
+ S3_SR +0x68, 0xff,
+ S3_SR +0x69, 0xff,
+ S3_SR +0x6a, 0xff,
+ S3_SR +0x6b, 0xff,
+ S3_SR +0x6c, 0xff,
+ S3_SR +0x6d, 0xff,
+ S3_SR +0x6e, 0x9b,
+ S3_SR +0x6f, 0xbf,
+
+ S3_AR + 0x00, 0x00,
+ S3_AR + 0x01, 0x01,
+ S3_AR + 0x02, 0x02,
+ S3_AR + 0x03, 0x03,
+ S3_AR + 0x04, 0x04,
+ S3_AR + 0x05, 0x05,
+ S3_AR + 0x06, 0x06,
+ S3_AR + 0x07, 0x07,
+ S3_AR + 0x08, 0x08,
+ S3_AR + 0x09, 0x09,
+ S3_AR + 0x0a, 0x0a,
+ S3_AR + 0x0b, 0x0b,
+ S3_AR + 0x0c, 0x0c,
+ S3_AR + 0x0d, 0x0d,
+ S3_AR + 0x0e, 0x0e,
+ S3_AR + 0x0f, 0x0f,
+ S3_AR + 0x10, 0x05,
+ S3_AR + 0x11, 0x00,
+ S3_AR + 0x12, 0x0f,
+ S3_AR + 0x13, 0x08,
+ S3_AR + 0x14, 0x00,
+
+ S3_GR + 0x00, 0x00,
+ S3_GR + 0x01, 0x00,
+ S3_GR + 0x02, 0x00,
+ S3_GR + 0x03, 0x00,
+ S3_GR + 0x04, 0x00,
+ S3_GR + 0x05, 0x10,
+ S3_GR + 0x06, 0x0e,
+ S3_GR + 0x07, 0x00,
+
+ S3_CR + 0x00, 0x5f,
+ S3_CR + 0x01, 0x4f,
+ S3_CR + 0x02, 0x50,
+ S3_CR + 0x03, 0x82,
+ S3_CR + 0x04, 0x55,
+ S3_CR + 0x05, 0x81,
+ S3_CR + 0x06, 0xbf,
+ S3_CR + 0x07, 0x1f,
+ S3_CR + 0x08, 0x00,
+ S3_CR + 0x09, 0x4f,
+ S3_CR + 0x0a, 0x0d,
+ S3_CR + 0x0b, 0x0e,
+ S3_CR + 0x0c, 0x00,
+ S3_CR + 0x0d, 0x00,
+ S3_CR + 0x0e, 0x3f,
+ S3_CR + 0x0f, 0xff,
+ S3_CR + 0x10, 0x9c,
+ S3_CR + 0x11, 0x0e,
+ S3_CR + 0x12, 0x8f,
+ S3_CR + 0x13, 0x28,
+ S3_CR + 0x14, 0x1f,
+ S3_CR + 0x15, 0x96,
+ S3_CR + 0x16, 0xb9,
+ S3_CR + 0x17, 0xa3,
+ S3_CR + 0x18, 0xff,
+ S3_CR + 0x19, 0xdf,
+ S3_CR + 0x1a, 0xdf,
+ S3_CR + 0x1b, 0xdf,
+ S3_CR + 0x1c, 0xdf,
+ S3_CR + 0x1d, 0xdf,
+ S3_CR + 0x1e, 0xdf,
+ S3_CR + 0x1f, 0xdf,
+ S3_CR + 0x20, 0xdf,
+ S3_CR + 0x21, 0x00,
+/* S3_CR + 0x22, 0x07, */
+ S3_CR + 0x23, 0x00,
+ S3_CR + 0x24, 0xdf,
+ S3_CR + 0x25, 0xdf,
+ S3_CR + 0x26, 0x00,
+ S3_CR + 0x27, 0xdf,
+ S3_CR + 0x28, 0xdf,
+ S3_CR + 0x29, 0xdf,
+ S3_CR + 0x2a, 0xdf,
+ S3_CR + 0x2b, 0xdf,
+ S3_CR + 0x2c, 0xdf,
+ S3_CR + 0x2d, 0x8a,
+ S3_CR + 0x2e, 0x22,
+ S3_CR + 0x2f, 0x02,
+ S3_CR + 0x30, 0xe1,
+ S3_CR + 0x31, 0x05,
+ S3_CR + 0x32, 0x40,
+ S3_CR + 0x33, 0x08,
+ S3_CR + 0x34, 0x00,
+ S3_CR + 0x35, 0x00,
+ S3_CR + 0x36, 0xbf,
+ S3_CR + 0x37, 0x9b,
+/* S3_CR + 0x38, 0x7b, */
+/* S3_CR + 0x39, 0xb8, */
+ S3_CR + 0x3a, 0x45,
+ S3_CR + 0x3b, 0x5a,
+ S3_CR + 0x3c, 0x10,
+ S3_CR + 0x3d, 0x00,
+ S3_CR + 0x3e, 0xfd,
+ S3_CR + 0x3f, 0x00,
+ S3_CR + 0x40, 0x00,
+ S3_CR + 0x41, 0x92,
+ S3_CR + 0x42, 0xc0,
+ S3_CR + 0x43, 0x68,
+ S3_CR + 0x44, 0xff,
+ S3_CR + 0x45, 0xe8,
+ S3_CR + 0x46, 0xff,
+ S3_CR + 0x47, 0xff,
+ S3_CR + 0x48, 0xf8,
+ S3_CR + 0x49, 0xff,
+ S3_CR + 0x4a, 0xfe,
+ S3_CR + 0x4b, 0xff,
+ S3_CR + 0x4c, 0xff,
+ S3_CR + 0x4d, 0xff,
+ S3_CR + 0x4e, 0xff,
+ S3_CR + 0x4f, 0xff,
+ S3_CR + 0x50, 0x00,
+ S3_CR + 0x51, 0x00,
+ S3_CR + 0x52, 0x00,
+ S3_CR + 0x53, 0x00,
+ S3_CR + 0x54, 0x00,
+ S3_CR + 0x55, 0x00,
+ S3_CR + 0x56, 0x00,
+ S3_CR + 0x57, 0x00,
+#if 0
+ S3_CR + 0x58, 0x00,
+ S3_CR + 0x59, 0xf0,
+#endif
+ S3_CR + 0x5a, 0x00,
+ S3_CR + 0x5b, 0x00,
+#if 0
+ S3_CR + 0x5c, 0x00,
+#endif
+ S3_CR + 0x5d, 0x00,
+ S3_CR + 0x5e, 0x00,
+ S3_CR + 0x5f, 0x00,
+ S3_CR + 0x60, 0x09,
+ S3_CR + 0x61, 0x9d,
+ S3_CR + 0x62, 0xff,
+ S3_CR + 0x63, 0x00,
+ S3_CR + 0x64, 0xfd,
+ S3_CR + 0x65, 0x04,
+ S3_CR + 0x66, 0x88,
+ S3_CR + 0x67, 0x00,
+ S3_CR + 0x68, 0x7f,
+ S3_CR + 0x69, 0x00,
+ S3_CR + 0x6a, 0x00,
+ S3_CR + 0x6b, 0x00,
+ S3_CR + 0x6c, 0x00,
+ S3_CR + 0x6d, 0x11,
+ S3_CR + 0x6e, 0xff,
+ S3_CR + 0x6f, 0xfe,
+
+ S3_CR + 0x70, 0x30,
+ S3_CR + 0x71, 0xc0,
+ S3_CR + 0x72, 0x07,
+ S3_CR + 0x73, 0x1f,
+ S3_CR + 0x74, 0x1f,
+ S3_CR + 0x75, 0x1f,
+ S3_CR + 0x76, 0x0f,
+ S3_CR + 0x77, 0x1f,
+ S3_CR + 0x78, 0x01,
+ S3_CR + 0x79, 0x01,
+ S3_CR + 0x7a, 0x1f,
+ S3_CR + 0x7b, 0x1f,
+ S3_CR + 0x7c, 0x17,
+ S3_CR + 0x7d, 0x17,
+ S3_CR + 0x7e, 0x17,
+ S3_CR + 0x7f, 0xfd,
+ S3_CR + 0x80, 0x00,
+ S3_CR + 0x81, 0x92,
+ S3_CR + 0x82, 0x10,
+ S3_CR + 0x83, 0x07,
+ S3_CR + 0x84, 0x42,
+ S3_CR + 0x85, 0x00,
+ S3_CR + 0x86, 0x00,
+ S3_CR + 0x87, 0x00,
+ S3_CR + 0x88, 0x10,
+ S3_CR + 0x89, 0xfd,
+ S3_CR + 0x8a, 0xfd,
+ S3_CR + 0x8b, 0xfd,
+ S3_CR + 0x8c, 0xfd,
+ S3_CR + 0x8d, 0xfd,
+ S3_CR + 0x8e, 0xfd,
+ S3_CR + 0x8f, 0xfd,
+ S3_CR + 0x90, 0x00,
+ S3_CR + 0x91, 0x4f,
+ S3_CR + 0x92, 0x10,
+ S3_CR + 0x93, 0x00,
+ S3_CR + 0x94, 0xfd,
+ S3_CR + 0x95, 0xfd,
+ S3_CR + 0x96, 0xfd,
+ S3_CR + 0x97, 0xfd,
+ S3_CR + 0x98, 0xfd,
+ S3_CR + 0x99, 0xff,
+ S3_CR + 0x9a, 0xfd,
+ S3_CR + 0x9b, 0xff,
+ S3_CR + 0x9c, 0xfd,
+ S3_CR + 0x9d, 0xfd,
+ S3_CR + 0x9e, 0xfd,
+ S3_CR + 0x9f, 0xff,
+ S3_CR + 0xa0, 0x0f,
+#if 0
+ S3_CR + 0xa1, 0x00,
+ S3_CR + 0xa2, 0x00,
+ S3_CR + 0xa3, 0x00,
+ S3_CR + 0xa4, 0x55,
+#endif
+ S3_CR + 0xa5, 0x09,
+ S3_CR + 0xa6, 0x20,
+#if 0
+ S3_CR + 0xa7, 0x00,
+ S3_CR + 0xa8, 0x00,
+ S3_CR + 0xa9, 0x00,
+ S3_CR + 0xaa, 0x00,
+ S3_CR + 0xab, 0x00,
+ S3_CR + 0xac, 0x00,
+ S3_CR + 0xad, 0x00,
+ S3_CR + 0xae, 0x00,
+ S3_CR + 0xaf, 0x00,
+ S3_CR + 0xb0, 0xff,
+#endif
+ S3_CR + 0xb1, 0x0e,
+#if 0
+ S3_CR + 0xb2, 0x55,
+ S3_CR + 0xb3, 0x00,
+ S3_CR + 0xb4, 0x55,
+ S3_CR + 0xb5, 0x00,
+ S3_CR + 0xb6, 0x00,
+#endif
+ S3_CR + 0xb7, 0x84,
+#if 0
+ S3_CR + 0xb8, 0xff,
+ S3_CR + 0xb9, 0xff,
+ S3_CR + 0xba, 0xff,
+ S3_CR + 0xbb, 0xff,
+ S3_CR + 0xbc, 0xff,
+ S3_CR + 0xbd, 0xff,
+ S3_CR + 0xbe, 0xff,
+ S3_CR + 0xbf, 0xff,
+#endif
+
+ S3_SR +0x15, 0x23,
+ 0xffff, 1,
+ S3_SR +0x15, 0x03,
+ 0xffff, 1,
+};
+
+#define S3_NUM_BIOS_REG (sizeof (s3BiosReg) / sizeof (s3BiosReg[0]))
+
+typedef struct _bios32Init {
+ VGA16 offset;
+ VGA32 value;
+} s3Bios32Init;
+
+s3Bios32Init s3Bios32Reg[] = {
+ 0x8168, 0x00000000,
+ 0x816c, 0x00000001,
+ 0x8170, 0x00000000,
+ 0x8174, 0x00000000,
+ 0x8178, 0x00000000,
+ 0x817c, 0x00000000,
+#if 0
+ 0x8180, 0x00140000,
+ 0x8184, 0x00000000,
+ 0x8188, 0x00000000,
+ 0x8190, 0x00000000,
+ 0x8194, 0x00000000,
+ 0x8198, 0x00000000,
+ 0x819c, 0x00000000,
+ 0x81a0, 0x00000000,
+#endif
+ 0x81c0, 0x00000000,
+ 0x81c4, 0x01fbffff,
+ 0x81c8, 0x00f7ffbf,
+ 0x81cc, 0x00f7ff00,
+ 0x81d0, 0x11ffff7f,
+ 0x81d4, 0x7fffffdf,
+ 0x81d8, 0xfdfff9ff,
+ 0x81e0, 0xfd000000,
+ 0x81e4, 0x00000000,
+ 0x81e8, 0x00000000,
+ 0x81ec, 0x00010000,
+ 0x81f0, 0x07ff057f,
+ 0x81f4, 0x07ff07ff,
+ 0x81f8, 0x00000000,
+ 0x81fc, 0x00000000,
+ 0x8200, 0x00000000,
+ 0x8204, 0x00000000,
+ 0x8208, 0x33000000,
+ 0x820c, 0x7f000000,
+ 0x8210, 0x80000000,
+ 0x8214, 0x00000000,
+ 0x8218, 0xffffffff,
+ 0x8300, 0xff007fef,
+ 0x8304, 0xfffdf7bf,
+ 0x8308, 0xfdfffbff,
+};
+
+#define S3_NUM_BIOS32_REG (sizeof (s3Bios32Reg) / sizeof (s3Bios32Reg[0]))
+
+/*
+ * Initialize the card precisely as the bios does
+ */
+s3DoBiosInit (KdCardInfo *card)
+{
+ S3CardInfo *s3c = card->driver;
+ CARD32 *regs = (CARD32 *) s3c->registers;
+ S3Vga *s3vga = &s3c->s3vga;
+ int r;
+
+ for (r = 0; r < S3_NUM_BIOS_REG; r++)
+ {
+ if (s3BiosReg[r].reg == 0xffff)
+ sleep (s3BiosReg[r].value);
+ else
+ VgaStore (&s3vga->card, s3BiosReg[r].reg, s3BiosReg[r].value);
+ }
+ VgaStore (&s3vga->card, S3_SR+0x10, 0x22);
+ VgaStore (&s3vga->card, S3_SR+0x11, 0x44);
+ VgaStore (&s3vga->card, S3_SR+0x15, 0x01);
+ sleep (1);
+ VgaStore (&s3vga->card, S3_SR+0x15, 0x03);
+ VgaStore (&s3vga->card, S3_CR+0x6f, 0xff);
+ VgaStore (&s3vga->card, S3_CR+0x3f, 0x3f);
+ sleep (1);
+ VgaStore (&s3vga->card, S3_CR+0x3f, 0x00);
+ VgaStore (&s3vga->card, S3_CR+0x6f, 0xfe);
+ VgaInvalidate (&s3vga->card);
+ for (r = 0; r < S3_NUM_BIOS32_REG; r++)
+ regs[s3Bios32Reg[r].offset/4] = s3Bios32Reg[r].value;
+}
+
+void
+s3Preserve (KdCardInfo *card)
+{
+ S3CardInfo *s3c = card->driver;
+ S3Ptr s3 = s3c->s3;
+ S3Vga *s3vga = &s3c->s3vga;
+ S3Save *save = &s3c->save;
+ CARD8 t1, t2;
+ CARD8 *cursor_base;
+
+ s3Save (s3vga);
+ if (!s3c->bios_initialized)
+ s3DoBiosInit (card);
+
+ _s3SetBlank (s3, s3vga, TRUE);
+ /*
+ * Preserve the first part of the frame buffer which holds
+ * the text mode fonts and data
+ */
+ s3Set (s3vga, s3_linear_window_size, 3);
+ s3Set (s3vga, s3_enable_linear, 1);
+ VgaFlush (&s3vga->card);
+ memcpy (save->text_save, s3c->frameBuffer, S3_TEXT_SAVE);
+ /*
+ * Preserve graphics engine state
+ */
+ save->alt_mix = s3->alt_mix;
+ save->write_mask = s3->write_mask;
+ save->fg = s3->fg;
+ save->bg = s3->bg;
+ save->global_bitmap_1 = s3->global_bitmap_1;
+ save->global_bitmap_2 = s3->global_bitmap_2;
+ save->primary_bitmap_1 = s3->primary_bitmap_1;
+ _s3SetBlank (s3, s3vga, FALSE);
+}
+
+/*
+ * Enable the card for rendering. Manipulate the initial settings
+ * of the card here.
+ */
+int s3CpuTimeout, s3AccelTimeout;
+
+void
+s3Enable (ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ KdCardInfo *card = pScreenPriv->card;
+ KdScreenInfo *screen = pScreenPriv->screen;
+ s3CardInfo (pScreenPriv);
+ s3ScreenInfo (pScreenPriv);
+
+ S3Vga *s3vga = &s3c->s3vga;
+ S3Ptr s3 = s3c->s3;
+ int hactive, hblank, hfp, hbp;
+ int vactive, vblank, vfp, vbp;
+ int hsize;
+
+ int h_total;
+ int h_display_end;
+ int h_blank_start;
+ int h_blank_end;
+ int h_sync_start;
+ int h_sync_end;
+ int h_screen_off;
+ int h_start_fifo_fetch;
+
+ int primary_stream_l1;
+
+ int v_total;
+ int v_retrace_start;
+ int v_retrace_end;
+ int v_display_end;
+ int v_blank_start;
+ int v_blank_end;
+
+ int h_blank_start_adjust;
+ int h_blank_end_adjust;
+ int h_sync_extend;
+ int h_blank_extend;
+ int i;
+ CARD16 cursor_address;
+ const KdMonitorTiming *t;
+ int m, n, r;
+ Bool clock_double;
+ int cpu_timeout;
+ int accel_timeout;
+ int bytes_per_ms;
+
+ t = KdFindMode (screen, s3ModeSupported);
+
+ hfp = t->hfp;
+ hbp = t->hbp;
+ hblank = t->hblank;
+ hactive = t->horizontal;
+
+ vfp = t->vfp;
+ vbp = t->vbp;
+ vblank = t->vblank;
+ vactive = t->vertical;
+
+ m = s3Get (s3vga, s3_dclk_m);
+ n = s3Get (s3vga, s3_dclk_n);
+ r = s3Get (s3vga, s3_dclk_r);
+#ifdef DEBUG
+ fprintf (stderr, "old clock %d, %d, %d\n", m, n, r);
+#endif
+ clock_double = FALSE;
+ s3GetClock (t->clock, &m, &n, &r, 511, 127, 4);
+ if (S3_CLOCK(m,n,r) > S3_MAX_CLOCK)
+ clock_double = TRUE;
+ s3Set (s3vga, s3_clock_select, 3);
+ s3Set (s3vga, s3_dclk_m, m);
+ s3Set (s3vga, s3_dclk_n, n);
+ s3Set (s3vga, s3_dclk_r, r);
+#ifdef DEBUG
+ fprintf (stderr, "new clock %d, %d, %d (%d)\n", m, n, r, S3_CLOCK(m,n,r));
+#endif
+
+ s3Set (s3vga, s3_select_graphics_mode, 1);
+ s3Set (s3vga, s3_enable_blinking, 0);
+ s3Set (s3vga, s3_enable_vga_16bit, 0);
+ s3Set (s3vga, s3_enhanced_memory_mapping, 1);
+ s3Set (s3vga, s3_enable_sff, 1);
+ s3Set (s3vga, s3_enable_2d_access, 1);
+ s3Set (s3vga, s3_2bk_cga, 1);
+ s3Set (s3vga, s3_4bk_hga, 1);
+ s3Set (s3vga, s3_v_total_double, 0);
+ s3Set (s3vga, s3_address_16k_wrap, 1);
+ s3Set (s3vga, s3_word_mode, 0);
+ s3Set (s3vga, s3_byte_mode, 1);
+ s3Set (s3vga, s3_hardware_reset, 1);
+ s3Set (s3vga, s3_max_scan_line, 0);
+ s3Set (s3vga, s3_linear_window_size, 3);
+ s3Set (s3vga, s3_enable_linear, 1);
+ s3Set (s3vga, s3_enable_2d_3d, 1);
+ s3Set (s3vga, s3_refresh_control, 1);
+ s3Set (s3vga, s3_disable_pci_read_bursts, 0);
+ s3Set (s3vga, s3_pci_retry_enable, 1);
+ s3Set (s3vga, s3_enable_256, 1);
+/* s3Set (s3vga, s3_border_select, 1); /* eliminate white border */
+ s3Set (s3vga, s3_border_select, 0); /* eliminate white border */
+ s3SetImm (s3vga, s3_lock_palette, 0); /* unlock palette/border regs */
+ s3Set (s3vga, s3_disable_v_retrace_int, 1);
+ if (t->hpol == KdSyncPositive)
+ s3Set (s3vga, s3_horz_sync_neg, 0);
+ else
+ s3Set (s3vga, s3_horz_sync_neg, 1);
+ if (t->vpol == KdSyncPositive)
+ s3Set (s3vga, s3_vert_sync_neg, 0);
+ else
+ s3Set (s3vga, s3_vert_sync_neg, 1);
+
+ s3Set (s3vga, s3_dot_clock_8, 1);
+ s3Set (s3vga, s3_enable_write_plane, 0xf);
+ s3Set (s3vga, s3_extended_memory_access, 1);
+ s3Set (s3vga, s3_sequential_addressing_mode, 1);
+ s3Set (s3vga, s3_select_chain_4_mode, 1);
+ s3Set (s3vga, s3_linear_addressing_control, 1);
+ s3Set (s3vga, s3_enable_8_bit_luts, 1);
+
+ s3Set (s3vga, s3_dclk_invert, 0);
+ s3Set (s3vga, s3_enable_clock_double, 0);
+ s3Set (s3vga, s3_dclk_over_2, 0);
+
+ s3Set (s3vga, s3_fifo_fetch_timing, 1);
+ s3Set (s3vga, s3_fifo_drain_delay, 7);
+
+
+ s3Set (s3vga, s3_delay_h_enable, 0);
+ s3Set (s3vga, s3_sdclk_skew, 0);
+
+ s3Set (s3vga, s3_dac_mask, 0xff);
+
+ s3Set (s3vga, s3_dac_power_saving_disable, 1);
+
+ s3s->manage_border = FALSE;
+ /*
+ * Compute character lengths for horizontal timing values
+ */
+ hactive = screen->width / 8;
+ hblank /= 8;
+ hfp /= 8;
+ hbp /= 8;
+ /*
+ * Set pixel size, choose clock doubling mode
+ */
+ h_blank_start_adjust = 0;
+ h_blank_end_adjust = 0;
+
+ switch (screen->bitsPerPixel) {
+ case 8:
+ h_screen_off = hactive;
+ s3Set (s3vga, s3_pixel_length, 0);
+ s3Set (s3vga, s3_color_mode, 0);
+ /*
+ * Set up for double-pixel mode, switch color modes,
+ * divide the dclk and delay h blank by 2 dclks
+ */
+ if (clock_double)
+ {
+ s3Set (s3vga, s3_color_mode, 1);
+ s3Set (s3vga, s3_dclk_over_2, 1);
+ s3Set (s3vga, s3_enable_clock_double, 1);
+ s3Set (s3vga, s3_border_select, 0);
+/* s3Set (s3vga, s3_border_color, pScreen->blackPixel); */
+ h_blank_start_adjust = 4;
+ h_blank_end_adjust = -4;
+ s3s->manage_border = TRUE;
+ }
+ break;
+ case 16:
+ h_screen_off = hactive * 2;
+ s3Set (s3vga, s3_pixel_length, 1);
+ if (clock_double)
+ {
+ if (screen->depth == 15)
+ s3Set (s3vga, s3_color_mode, 3);
+ else
+ s3Set (s3vga, s3_color_mode, 5);
+ s3Set (s3vga, s3_dclk_over_2, 1);
+ s3Set (s3vga, s3_enable_clock_double, 1);
+ s3Set (s3vga, s3_border_select, 0);
+ h_blank_start_adjust = 4;
+ h_blank_end_adjust = -4;
+ }
+ else
+ {
+ if (screen->depth == 15)
+ s3Set (s3vga, s3_color_mode, 2);
+ else
+ s3Set (s3vga, s3_color_mode, 4);
+ s3Set (s3vga, s3_dclk_over_2, 0);
+ s3Set (s3vga, s3_enable_clock_double, 0);
+ s3Set (s3vga, s3_delay_blank, 0);
+ }
+ break;
+ case 32:
+ h_screen_off = hactive * 4;
+ s3Set (s3vga, s3_pixel_length, 3);
+ s3Set (s3vga, s3_color_mode, 0xd);
+ break;
+ }
+
+ /*
+ * X server starts frame buffer at top of memory
+ */
+ s3Set (s3vga, s3_start_address, 0);
+
+
+ /*
+ * Set various registers to avoid snow on the screen
+ */
+ bytes_per_ms = t->clock * (screen->bitsPerPixel / 8);
+
+ fprintf (stderr, "bytes_per_ms %d\n", bytes_per_ms);
+ fprintf (stderr, "primary 0x%x master 0x%x command 0x%x lpb 0x%x cpu 0x%x 2d 0x%x\n",
+ s3Get (s3vga, s3_primary_stream_timeout),
+ s3Get (s3vga, s3_master_control_unit_timeout),
+ s3Get (s3vga, s3_command_buffer_timeout),
+ s3Get (s3vga, s3_lpb_timeout),
+ s3Get (s3vga, s3_cpu_timeout),
+ s3Get (s3vga, s3_2d_graphics_engine_timeout));
+
+ /* cpu 2d
+ * 576000
+ * 288000 0x1f 0x19
+
+ */
+ if (s3CpuTimeout)
+ {
+ cpu_timeout = s3CpuTimeout;
+ if (s3AccelTimeout)
+ accel_timeout = s3AccelTimeout;
+ else
+ accel_timeout = s3CpuTimeout;
+ }
+ else if (bytes_per_ms > 400000)
+ {
+ cpu_timeout = 0x10;
+ accel_timeout = 0x7;
+ }
+ else if (bytes_per_ms > 250000)
+ {
+ cpu_timeout = 0x10;
+ accel_timeout = 0x18;
+ }
+ else
+ {
+ cpu_timeout = 0x1f;
+ accel_timeout = 0x1f;
+ }
+
+ s3Set (s3vga, s3_primary_stream_timeout, 0xc0);
+ s3Set (s3vga, s3_master_control_unit_timeout, 0xf);
+ s3Set (s3vga, s3_command_buffer_timeout, 0x1f);
+ s3Set (s3vga, s3_lpb_timeout, 0xf);
+ s3Set (s3vga, s3_2d_graphics_engine_timeout, accel_timeout);
+ s3Set (s3vga, s3_cpu_timeout, cpu_timeout);
+
+ /*
+ * Compute horizontal register values from timings
+ */
+ h_total = hactive + hblank - 5;
+ h_display_end = hactive - 1;
+
+ h_sync_start = hactive + hfp;
+ h_sync_end = hactive + hblank - hbp;
+ /*
+ * pad the blank values narrow a bit and use the border_select to
+ * eliminate the remaining border; don't know why, but it doesn't
+ * work in the documented fashion
+ */
+ h_blank_start = hactive + 1 + h_blank_start_adjust;
+ h_blank_end = hactive + hblank - 2 + h_blank_end_adjust;
+ /*
+ * The manual says h_total - 5, but the
+ * bios does differently...
+ */
+ if (screen->width >= 1600)
+ h_start_fifo_fetch = h_total - 24;
+ else if (screen->width >= 1280)
+ h_start_fifo_fetch = h_total - 19;
+ else if (screen->width >= 1024)
+ h_start_fifo_fetch = h_total - 14;
+ else if (screen->width >= 800)
+ h_start_fifo_fetch = h_total - 10;
+ else
+ h_start_fifo_fetch = h_total - 5;
+
+ if (h_blank_end - h_blank_start >= 0x40)
+ h_blank_extend = 1;
+ else
+ h_blank_extend = 0;
+
+ if (h_sync_end - h_sync_start >= 0x20)
+ h_sync_extend = 1;
+ else
+ h_sync_extend = 0;
+
+ primary_stream_l1 = (screen->width * screen->bitsPerPixel / (8 * 8)) - 1;
+
+#ifdef DEBUG
+ fprintf (stderr, "h_total %d h_display_end %d\n",
+ h_total, h_display_end);
+ fprintf (stderr, "h_sync_start %d h_sync_end %d h_sync_extend %d\n",
+ h_sync_start, h_sync_end, h_sync_extend);
+ fprintf (stderr, "h_blank_start %d h_blank_end %d h_blank_extend %d\n",
+ h_blank_start, h_blank_end, h_blank_extend);
+#endif
+
+ s3Set (s3vga, s3_h_total, h_total);
+ s3Set (s3vga, s3_h_display_end, h_display_end);
+ s3Set (s3vga, s3_h_blank_start, h_blank_start);
+ s3Set (s3vga, s3_h_blank_end, h_blank_end);
+ s3Set (s3vga, s3_h_sync_start, h_sync_start);
+ s3Set (s3vga, s3_h_sync_end, h_sync_end);
+ s3Set (s3vga, s3_screen_offset, h_screen_off);
+ s3Set (s3vga, s3_h_start_fifo_fetch, h_start_fifo_fetch);
+ s3Set (s3vga, s3_h_sync_extend, h_sync_extend);
+ s3Set (s3vga, s3_h_blank_extend, h_blank_extend);
+
+ s3Set (s3vga, s3_primary_stream_l1, primary_stream_l1);
+
+ v_total = vactive + vblank - 2;
+ v_display_end = vactive - 1;
+
+#if 0
+ v_blank_start = vactive - 1;
+ v_blank_end = v_blank_start + vblank - 1;
+#else
+ v_blank_start = vactive - 1;
+ v_blank_end = v_blank_start + vblank - 1;
+#endif
+
+ v_retrace_start = vactive + vfp;
+ v_retrace_end = vactive + vblank - vbp;
+
+ s3Set (s3vga, s3_v_total, v_total);
+ s3Set (s3vga, s3_v_retrace_start, v_retrace_start);
+ s3Set (s3vga, s3_v_retrace_end, v_retrace_end);
+ s3Set (s3vga, s3_v_display_end, v_display_end);
+ s3Set (s3vga, s3_v_blank_start, v_blank_start);
+ s3Set (s3vga, s3_v_blank_end, v_blank_end);
+
+ if (vactive >= 1024)
+ s3Set (s3vga, s3_line_compare, 0x7ff);
+ else
+ s3Set (s3vga, s3_line_compare, 0x3ff);
+
+ /*
+ * Set cursor
+ */
+ if (!screen->softCursor)
+ {
+ cursor_address = (s3s->cursor_base - screen->frameBuffer) / 1024;
+
+ s3Set (s3vga, s3_cursor_address, cursor_address);
+ s3Set (s3vga, s3_cursor_ms_x11, 0);
+ s3Set (s3vga, s3_cursor_enable, 1);
+ }
+ else
+ s3Set (s3vga, s3_cursor_enable, 0);
+
+#define MAKE_GBF(bds,be,stride,bpp,tile) (\
+ ((bds) << 0) | \
+ ((be) << 3) | \
+ ((stride) << 4) | \
+ ((bpp) << 16) | \
+ ((tile) << 24))
+ /*
+ * Set accelerator
+ */
+ switch (screen->width) {
+ case 640: s3Set (s3vga, s3_ge_screen_width, 1); break;
+ case 800: s3Set (s3vga, s3_ge_screen_width, 2); break;
+ case 1024: s3Set (s3vga, s3_ge_screen_width, 0); break;
+ case 1152: s3Set (s3vga, s3_ge_screen_width, 4); break;
+ case 1280: s3Set (s3vga, s3_ge_screen_width, 3); break;
+ case 1600: s3Set (s3vga, s3_ge_screen_width, 6); break;
+ default:
+ s3Set (s3vga, s3_ge_screen_width, 7); /* use global bitmap descriptor */
+ }
+
+#if 0
+ crtc->l_parm_0_7 = screen->width / 4; /* Undocumented. */
+#endif
+
+ /*
+ * Set DPMS to normal
+ */
+ s3Set (s3vga, s3_hsync_control, 0);
+ s3Set (s3vga, s3_vsync_control, 0);
+
+ _s3SetBlank (s3, s3vga, TRUE);
+ VgaFlush(&s3vga->card);
+ VgaSetImm (&s3vga->card, s3_clock_load_imm, 1);
+ VgaSetImm(&s3vga->card, s3_clock_load_imm, 0);
+ s3->global_bitmap_1 = 0;
+ s3->global_bitmap_2 = MAKE_GBF (1, /* 64 bit bitmap descriptor size */
+ 0, /* disable BCI */
+ pScreenPriv->screen->pixelStride >> 4,
+ pScreenPriv->screen->bitsPerPixel,
+ 0); /* tile format */
+ _s3SetBlank (s3, s3vga, FALSE);
+#if 1
+ {
+ VGA16 r;
+ static CARD32 streams[][2] = {
+ /* PCI registers */
+ 0x8000, 0x8024,
+ 0x802c, 0x8034,
+ 0x803c, 0x8040,
+#if 0
+ 0x8080, 0x808c, /* AGP */
+#endif
+ 0x80dc, 0x80e0,
+
+ /* 2D registers */
+ 0x8168, 0x8188,
+ 0x8190, 0x81a0,
+ 0x81c0, 0x81d8,
+ 0x81e0, 0x8218,
+ 0x8300, 0x8308,
+ 0x8504, 0x8510,
+
+ /* LPB/VIP registers */
+ 0xff00, 0xff18,
+ 0xff20, 0xff38,
+ 0xff40, 0xff40,
+ 0xff70, 0xff78,
+ 0xff8c, 0xffa0,
+
+#if 0
+ /* 3D registers */
+ 0x48508, 0x48508,
+ 0x48528, 0x48528,
+ 0x48548, 0x48548,
+ 0x48584, 0x485f0,
+#endif
+
+ /* motion compensation registers */
+ 0x48900, 0x48924,
+#if 0
+ 0x48928, 0x48928,
+#endif
+
+ /* Mastered data transfer registers */
+ 0x48a00, 0x48a1c,
+
+ /* configuation/status registers */
+ 0x48c00, 0x48c18,
+ 0x48c20, 0x48c24,
+ 0x48c40, 0x48c50,
+ 0x48c60, 0x48c64,
+
+ 0, 0,
+ };
+#ifdef PHOENIX
+#undef stderr
+#define stderr stdout
+#endif
+ CARD32 *regs = (CARD32 *) s3c->registers;
+ int i;
+ CARD32 reg;
+
+
+ for (r = S3_SR + 0; r < S3_SR + S3_NSR; r++)
+ fprintf (stderr, "SR%02x = %02x\n", r-S3_SR, VgaFetch (&s3vga->card, r));
+ for (r = S3_GR + 0; r < S3_GR + S3_NGR; r++)
+ fprintf (stderr, "GR%02x = %02x\n", r-S3_GR, VgaFetch (&s3vga->card, r));
+ for (r = S3_AR + 0; r < S3_AR + S3_NAR; r++)
+ fprintf (stderr, "AR%02x = %02x\n", r-S3_AR, VgaFetch (&s3vga->card, r));
+ for (r = S3_CR + 0; r < S3_CR + S3_NCR; r++)
+ fprintf (stderr, "CR%02x = %02x\n", r-S3_CR, VgaFetch (&s3vga->card, r));
+ for (r = S3_DAC + 0; r < S3_DAC + S3_NDAC; r++)
+ fprintf (stderr, "DAC%02x = %02x\n", r-S3_DAC, VgaFetch (&s3vga->card, r));
+ fprintf (stderr, "MISC_OUT = %02x\n", VgaFetch (&s3vga->card, S3_MISC_OUT));
+ fprintf (stderr, "INPUT_STATUS = %02x\n", VgaFetch (&s3vga->card, S3_INPUT_STATUS_1));
+
+
+ for (i = 0; streams[i][0]; i++)
+ {
+ for (reg = streams[i][0]; reg <= streams[i][1]; reg += 4)
+ fprintf (stderr, "0x%4x: 0x%08x\n", reg, regs[reg/4]);
+ }
+ }
+#endif
+}
+
+void
+s3Disable (ScreenPtr pScreen)
+{
+}
+
+void
+s3Restore (KdCardInfo *card)
+{
+ S3CardInfo *s3c = card->driver;
+ S3Ptr s3 = s3c->s3;
+ S3Vga *s3vga = &s3c->s3vga;
+ S3Save *save = &s3c->save;
+ CARD8 *cursor_base;
+
+ /* graphics engine state */
+ s3->global_bitmap_1 = save->global_bitmap_1;
+ s3->global_bitmap_2 = save->global_bitmap_2;
+ s3->alt_mix = save->alt_mix;
+ s3->write_mask = save->write_mask;
+ s3->fg = save->fg;
+ s3->bg = save->bg;
+ /* XXX should save and restore real values? */
+ s3->scissors_tl = 0x00000000;
+ s3->scissors_br = 0x0fff0fff;
+
+ _s3SetBlank (s3, s3vga, TRUE);
+ VgaRestore (&s3vga->card);
+ s3Set (s3vga, s3_linear_window_size, 3);
+ s3Set (s3vga, s3_enable_linear, 1);
+ VgaFlush (&s3vga->card);
+ memcpy (s3c->frameBuffer, save->text_save, S3_TEXT_SAVE);
+ s3Reset (s3vga);
+ _s3SetBlank (s3, s3vga, FALSE);
+}
+
+void
+_s3SetSync (S3CardInfo *s3c, int hsync, int vsync)
+{
+ /* this abuses the macros defined to access the crtc structure */
+ S3Ptr s3 = s3c->s3;
+ S3Vga *s3vga = &s3c->s3vga;
+
+ s3Set (s3vga, s3_hsync_control, hsync);
+ s3Set (s3vga, s3_vsync_control, vsync);
+ VgaFlush (&s3vga->card);
+}
+
+Bool
+s3DPMS (ScreenPtr pScreen, int mode)
+{
+ KdScreenPriv(pScreen);
+ s3CardInfo(pScreenPriv);
+ S3Vga *s3vga = &s3c->s3vga;
+
+ switch (mode) {
+ case KD_DPMS_NORMAL:
+ _s3SetSync (s3c, 0, 0);
+ _s3SetBlank (s3c->s3, s3vga, FALSE);
+ break;
+ case KD_DPMS_STANDBY:
+ _s3SetBlank (s3c->s3, s3vga, TRUE);
+ _s3SetSync (s3c, 1, 0);
+ break;
+ case KD_DPMS_SUSPEND:
+ _s3SetBlank (s3c->s3, s3vga, TRUE);
+ _s3SetSync (s3c, 0, 1);
+ break;
+ case KD_DPMS_POWERDOWN:
+ _s3SetBlank (s3c->s3, s3vga, TRUE);
+ _s3SetSync (s3c, 1, 1);
+ break;
+ }
+ return TRUE;
+}
+
+void
+s3ScreenFini (KdScreenInfo *screen)
+{
+ S3ScreenInfo *s3s = (S3ScreenInfo *) screen->driver;
+
+ xfree (s3s);
+ screen->driver = 0;
+}
+
+void
+s3CardFini (KdCardInfo *card)
+{
+ S3CardInfo *s3c = (S3CardInfo *) card->driver;
+
+ KdUnmapDevice (s3c->frameBuffer, s3c->memory);
+ KdUnmapDevice (s3c->registers, sizeof (S3) + PACKED_OFFSET);
+ xfree (s3c);
+ card->driver = 0;
+}
+
+KdCardFuncs s3Funcs = {
+ s3CardInit,
+ s3ScreenInit,
+ 0,
+ s3Preserve,
+ s3Enable,
+ s3DPMS,
+ s3Disable,
+ s3Restore,
+ s3ScreenFini,
+ s3CardFini,
+ s3CursorInit,
+ s3CursorEnable,
+ s3CursorDisable,
+ s3CursorFini,
+ s3RecolorCursor,
+ s3DrawInit,
+ s3DrawEnable,
+ s3DrawSync,
+ s3DrawDisable,
+ s3DrawFini,
+ s3GetColors,
+ s3PutColors,
+};
diff --git a/xc/programs/Xserver/hw/kdrive/savage/s3.h b/xc/programs/Xserver/hw/kdrive/savage/s3.h
new file mode 100644
index 000000000..9a08e4fdf
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/savage/s3.h
@@ -0,0 +1,559 @@
+/*
+ * $Id: s3.h,v 1.1 2000/01/06 12:55:50 faith 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/savage/s3.h,v 1.2 1999/12/30 03:03:10 robin Exp $ */
+
+#ifndef _S3_H_
+#define _S3_H_
+
+#include "kdrive.h"
+#include "s3reg.h"
+
+/* VESA Approved Register Definitions */
+
+/*
+ * Linear Addressing 000 0000 - 0ff ffff (16m)
+ * Image data transfer 100 0000 - 100 7fff (32k)
+ * PCI config 100 8000 - 100 8043
+ * Packed enhanced regs 100 8100 - 100 814a
+ * Streams regs 100 8180 - 100 81ff
+ * Current Y pos 100 82e8
+ * CRT VGA 3b? regs 100 83b0 - 100 83bf
+ * CRT VGA 3c? regs 100 83c0 - 100 83cf
+ * CRT VGA 3d? regs 100 83d0 - 100 83df
+ * Subsystem status (42e8h) 100 8504
+ * Advanced function (42e8h) 100 850c
+ * Enhanced regs 100 86e8 - 100 eeea
+ * Local peripheral bus 100 ff00 - 100 ff5c
+ *
+ * We don't care about the image transfer or PCI regs, so
+ * this structure starts at the packed enhanced regs
+ */
+
+typedef volatile CARD32 VOL32;
+typedef volatile CARD16 VOL16;
+typedef volatile CARD8 VOL8;
+
+typedef volatile struct _s3 {
+ VOL32 alt_curxy; /* 8100 */
+ VOL32 _pad0; /* 8104 */
+ VOL32 alt_step; /* 8108 */
+ VOL32 _pad1; /* 810c */
+ VOL32 err_term; /* 8110 */
+ VOL32 _pad2; /* 8114 */
+ VOL32 cmd_gp_stat; /* 8118 */
+ VOL32 short_stroke; /* 811c */
+ VOL32 bg; /* 8120 */
+ VOL32 fg; /* 8124 */
+ VOL32 write_mask; /* 8128 */
+ VOL32 read_mask; /* 812c */
+ VOL32 color_cmp; /* 8130 */
+ VOL32 alt_mix; /* 8134 */
+ VOL32 scissors_tl; /* 8138 */
+ VOL32 scissors_br; /* 813c */
+#if 0
+ VOL16 pix_cntl; /* 8140 */
+ VOL16 mult_misc2; /* 8142 */
+#else
+ VOL32 pix_cntl_mult_misc2; /* 8140 */
+#endif
+ VOL32 mult_misc_read_sel; /* 8144 */
+ VOL32 alt_pcnt; /* 8148 min_axis_pcnt, maj_axis_pcnt */
+ VOL8 _pad3a[0x1c]; /* 814c */
+ VOL32 global_bitmap_1; /* 8168 */
+ VOL32 global_bitmap_2; /* 816c */
+ VOL32 primary_bitmap_1; /* 8170 */
+ VOL32 primary_bitmap_2; /* 8174 */
+ VOL32 secondary_bitmap_1; /* 8178 */
+ VOL32 secondary_bitmap_2; /* 817c */
+ VOL32 primary_stream_control; /* 8180 */
+ VOL32 chroma_key_control; /* 8184 */
+ VOL32 genlocking_control; /* 8188 */
+ VOL8 _pad3b[0x4]; /* 818c */
+ VOL32 secondary_stream_control; /* 8190 */
+ VOL32 chroma_key_upper_bound; /* 8194 */
+ VOL32 secondary_stream_h_scale; /* 8198 */
+ VOL32 color_adjustment; /* 819c */
+ VOL32 blend_control; /* 81a0 */
+ VOL8 _pad3c[0x1c]; /* 81a4 */
+ VOL32 primary_stream_addr_0; /* 81c0 */
+ VOL8 _pad3d[0x124]; /* 81c4 */
+#if 0
+ VOL16 cur_y; /* 82e8 */
+ VOL8 _pad4[0xc6]; /* 82ea */
+#else
+ VOL32 cur_y; /* 82e8 */
+ VOL8 _pad4[0xc4]; /* 82ec */
+#endif
+
+#if 0
+ VOL8 crt_vga_3b0; /* 83b0 */
+ VOL8 crt_vga_3b1; /* 83b1 */
+ VOL8 crt_vga_3b2; /* 83b2 */
+ VOL8 crt_vga_3b3; /* 83b3 */
+ VOL8 crt_vga_3b4; /* 83b4 */
+ VOL8 crt_vga_3b5; /* 83b5 */
+ VOL8 crt_vga_3b6; /* 83b6 */
+ VOL8 crt_vga_3b7; /* 83b7 */
+ VOL8 crt_vga_3b8; /* 83b8 */
+ VOL8 crt_vga_3b9; /* 83b9 */
+ VOL8 crt_vga_3ba; /* 83ba */
+ VOL8 crt_vga_3bb; /* 83bb */
+ VOL8 crt_vga_3bc; /* 83bc */
+ VOL8 crt_vga_3bd; /* 83bd */
+ VOL8 crt_vga_3be; /* 83be */
+ VOL8 crt_vga_3bf; /* 83bf */
+
+ VOL8 crt_vga_3c0; /* 83c0 */
+ VOL8 crt_vga_3c1; /* 83c1 */
+ VOL8 crt_vga_3c2; /* 83c2 */
+ VOL8 crt_vga_3c3; /* 83c3 */
+ VOL8 crt_vga_3c4; /* 83c4 */
+ VOL8 crt_vga_3c5; /* 83c5 */
+ VOL8 crt_vga_dac_ad_mk; /* 83c6 */
+ VOL8 crt_vga_dac_rd_ad; /* 83c7 */
+ VOL8 crt_vga_dac_wt_ad; /* 83c8 */
+ VOL8 crt_vga_dac_data; /* 83c9 */
+ VOL8 crt_vga_3ca; /* 83ca */
+ VOL8 crt_vga_3cb; /* 83cb */
+ VOL8 crt_vga_3cc; /* 83cc */
+ VOL8 crt_vga_3cd; /* 83cd */
+ VOL8 crt_vga_3ce; /* 83ce */
+ VOL8 crt_vga_3cf; /* 83cf */
+
+ VOL8 crt_vga_3d0; /* 83d0 */
+ VOL8 crt_vga_3d1; /* 83d1 */
+ VOL8 crt_vga_3d2; /* 83d2 */
+ VOL8 crt_vga_3d3; /* 83d3 */
+ VOL8 crt_vga_3d4; /* 83d4 */
+ VOL8 crt_vga_3d5; /* 83d5 */
+ VOL8 crt_vga_3d6; /* 83d6 */
+ VOL8 crt_vga_3d7; /* 83d7 */
+ VOL8 crt_vga_3d8; /* 83d8 */
+ VOL8 crt_vga_3d9; /* 83d9 */
+ VOL8 crt_vga_status_1; /* 83da */
+ VOL8 crt_vga_3db; /* 83db */
+ VOL8 crt_vga_3dc; /* 83dc */
+ VOL8 crt_vga_3dd; /* 83dd */
+ VOL8 crt_vga_3de; /* 83de */
+ VOL8 crt_vga_3df; /* 83df */
+
+ VOL8 _pad5[0x124]; /* 83e0 */
+ VOL16 subsys_status; /* 8504 */
+ VOL8 _pad6[0x6]; /* 8506 */
+ VOL32 subsys_status; /* 8504 */
+ VOL8 _pad6[0x4]; /* 8508 */
+ VOL16 adv_control; /* 850c */
+ VOL8 _pad7[0x1da]; /* 850e */
+ VOL16 cur_x; /* 86e8 */
+ VOL8 _pad8[0x3fe]; /* 86ea */
+ VOL16 desty_axstp; /* 8ae8 */
+ VOL8 _pad9[0x3fe]; /* 8aea */
+ VOL16 destx_diastp; /* 8ee8 */
+ VOL8 _pad10[0x3fe]; /* 8eea */
+ VOL16 enh_err_term; /* 92e8 */
+ VOL8 _pad11[0x3fe]; /* 92ea */
+ VOL16 maj_axis_pcnt; /* 96e8 */
+ VOL8 _pad12[0x3fe]; /* 96ea */
+ VOL16 enh_cmd_gp_stat; /* 9ae8 */
+ VOL8 _pad13[0x3fe]; /* 9aea */
+ VOL16 enh_short_stroke; /* 9ee8 */
+ VOL8 _pad14[0x3fe]; /* 9eea */
+ VOL16 enh_bg; /* a2e8 */
+ VOL8 _pad15[0x3fe]; /* a2ea */
+ VOL16 enh_fg; /* a6e8 */
+ VOL8 _pad16[0x3fe]; /* a6ea */
+ VOL16 enh_wrt_mask; /* aae8 */
+ VOL8 _pad17[0x3fe]; /* aaea */
+ VOL16 enh_rd_mask; /* aee8 */
+ VOL8 _pad18[0x3fe]; /* aeea */
+ VOL16 enh_color_cmp; /* b2e8 */
+ VOL8 _pad19[0x3fe]; /* b2ea */
+ VOL16 enh_bg_mix; /* b6e8 */
+ VOL8 _pad20[0x3fe]; /* b6ea */
+ VOL16 enh_fg_mix; /* bae8 */
+ VOL8 _pad21[0x3fe]; /* baea */
+ VOL16 enh_rd_reg_dt; /* bee8 */
+ VOL8 _pad22[0x23fe]; /* beea */
+#else
+ VOL8 _pad_reg[0x5f38]; /* 83b0 */
+#endif
+ VOL32 pix_trans; /* e2e8 */
+
+ VOL8 _pad23[0x3a974]; /* e2ec */
+ VOL32 alt_status_0; /* 48c60 */
+ VOL32 alt_status_1; /* 48c64 */
+} S3, *S3Ptr;
+
+#define VGA_STATUS_1_DTM 0x01
+#define VGA_STATUS_1_VSY 0x08
+
+#define DAC_MASK 0x03c6
+#define DAC_R_INDEX 0x03c7
+#define DAC_W_INDEX 0x03c8
+#define DAC_DATA 0x03c9
+#define DISP_STAT 0x02e8
+#define H_TOTAL 0x02e8
+#define H_DISP 0x06e8
+#define H_SYNC_STRT 0x0ae8
+#define H_SYNC_WID 0x0ee8
+#define V_TOTAL 0x12e8
+#define V_DISP 0x16e8
+#define V_SYNC_STRT 0x1ae8
+#define V_SYNC_WID 0x1ee8
+#define DISP_CNTL 0x22e8
+#define ADVFUNC_CNTL 0x4ae8
+#define SUBSYS_STAT 0x42e8
+#define SUBSYS_CNTL 0x42e8
+#define ROM_PAGE_SEL 0x46e8
+#define CUR_Y 0x82e8
+#define CUR_X 0x86e8
+#define DESTY_AXSTP 0x8ae8
+#define DESTX_DIASTP 0x8ee8
+#define ERR_TERM 0x92e8
+#define MAJ_AXIS_PCNT 0x96e8
+#define GP_STAT 0x9ae8
+#define CMD 0x9ae8
+#define SHORT_STROKE 0x9ee8
+#define BKGD_COLOR 0xa2e8
+#define FRGD_COLOR 0xa6e8
+#define WRT_MASK 0xaae8
+#define RD_MASK 0xaee8
+#define COLOR_CMP 0xb2e8
+#define BKGD_MIX 0xb6e8
+#define FRGD_MIX 0xbae8
+#define MULTIFUNC_CNTL 0xbee8
+#define MIN_AXIS_PCNT 0x0000
+#define SCISSORS_T 0x1000
+#define SCISSORS_L 0x2000
+#define SCISSORS_B 0x3000
+#define SCISSORS_R 0x4000
+#define MEM_CNTL 0x5000
+#define PATTERN_L 0x8000
+#define PATTERN_H 0x9000
+#define PIX_CNTL 0xa000
+#define CONTROL_MISC2 0xd000
+#define PIX_TRANS 0xe2e8
+
+/* Advanced Function Control Regsiter */
+#define CLKSEL 0x0004
+#define DISABPASSTHRU 0x0001
+
+/* Graphics Processor Status Register */
+
+#define GPNSLOT 13
+
+#define GPBUSY_1 0x0080
+#define GPBUSY_2 0x0040
+#define GPBUSY_3 0x0020
+#define GPBUSY_4 0x0010
+#define GPBUSY_5 0x0008
+#define GPBUSY_6 0x0004
+#define GPBUSY_7 0x0002
+#define GPBUSY_8 0x0001
+#define GPBUSY_9 0x8000
+#define GPBUSY_10 0x4000
+#define GPBUSY_11 0x2000
+#define GPBUSY_12 0x1000
+#define GPBUSY_13 0x0800
+
+#define GPEMPTY 0x0400
+#define GPBUSY 0x0200
+#define DATDRDY 0x0100
+
+/* Command Register */
+#define CMD_NOP 0x0000
+#define CMD_LINE 0x2000
+#define CMD_RECT 0x4000
+#define CMD_RECTV1 0x6000
+#define CMD_RECTV2 0x8000
+#define CMD_LINEAF 0xa000
+#define CMD_BITBLT 0xc000
+#define CMD_PATBLT 0xe000
+#define CMD_OP_MSK 0xe000
+#define BYTSEQ 0x1000
+#define _32BITNOPAD 0x0600
+#define _32BIT 0x0400
+#define _16BIT 0x0200
+#define _8BIT 0x0000
+#define PCDATA 0x0100
+#define INC_Y 0x0080
+#define YMAJAXIS 0x0040
+#define INC_X 0x0020
+#define DRAW 0x0010
+#define LINETYPE 0x0008
+#define LASTPIX 0x0004 /* Draw last pixel in line */
+#define PLANAR 0x0002
+#define WRTDATA 0x0001
+
+/* Background Mix Register */
+#define BSS_BKGDCOL 0x0000
+#define BSS_FRGDCOL 0x0020
+#define BSS_PCDATA 0x0040
+#define BSS_BITBLT 0x0060
+
+/* Foreground Mix Register */
+#define FSS_BKGDCOL 0x0000
+#define FSS_FRGDCOL 0x0020
+#define FSS_PCDATA 0x0040
+#define FSS_BITBLT 0x0060
+
+/* The Mixes */
+#define MIX_MASK 0x001f
+
+#define MIX_NOT_DST 0x0000
+#define MIX_0 0x0001
+#define MIX_1 0x0002
+#define MIX_DST 0x0003
+#define MIX_NOT_SRC 0x0004
+#define MIX_XOR 0x0005
+#define MIX_XNOR 0x0006
+#define MIX_SRC 0x0007
+#define MIX_NAND 0x0008
+#define MIX_NOT_SRC_OR_DST 0x0009
+#define MIX_SRC_OR_NOT_DST 0x000a
+#define MIX_OR 0x000b
+#define MIX_AND 0x000c
+#define MIX_SRC_AND_NOT_DST 0x000d
+#define MIX_NOT_SRC_AND_DST 0x000e
+#define MIX_NOR 0x000f
+
+#define MIX_MIN 0x0010
+#define MIX_DST_MINUS_SRC 0x0011
+#define MIX_SRC_MINUS_DST 0x0012
+#define MIX_PLUS 0x0013
+#define MIX_MAX 0x0014
+#define MIX_HALF__DST_MINUS_SRC 0x0015
+#define MIX_HALF__SRC_MINUS_DST 0x0016
+#define MIX_AVERAGE 0x0017
+#define MIX_DST_MINUS_SRC_SAT 0x0018
+#define MIX_SRC_MINUS_DST_SAT 0x001a
+#define MIX_HALF__DST_MINUS_SRC_SAT 0x001c
+#define MIX_HALF__SRC_MINUS_DST_SAT 0x001e
+#define MIX_AVERAGE_SAT 0x001f
+
+/* Pixel Control Register */
+#define MIXSEL_FRGDMIX 0x0000
+#define MIXSEL_PATT 0x0040
+#define MIXSEL_EXPPC 0x0080
+#define MIXSEL_EXPBLT 0x00c0
+#define COLCMPOP_F 0x0000
+#define COLCMPOP_T 0x0008
+#define COLCMPOP_GE 0x0010
+#define COLCMPOP_LT 0x0018
+#define COLCMPOP_NE 0x0020
+#define COLCMPOP_EQ 0x0028
+#define COLCMPOP_LE 0x0030
+#define COLCMPOP_GT 0x0038
+#define PLANEMODE 0x0004
+
+
+#define S3_SAVAGE4_SLOTS 0x0001ffff
+#define S3_SAVAGE4_2DI 0x00800000
+
+#define _s3WaitLoop(s3,mask,value){ \
+ int __loop = 1000000; \
+ while (((s3)->alt_status_0 & (mask)) != (value)) \
+ if (--__loop == 0) { \
+ ErrorF ("savage wait loop failed 0x%x\n", s3->alt_status_0); \
+ break; \
+ } \
+}
+
+#define S3_SAVAGE4_ROOM 10
+
+#define _s3WaitSlots(s3,n) { \
+ int __loop = 1000000; \
+ while (((s3)->alt_status_0 & S3_SAVAGE4_SLOTS) >= S3_SAVAGE4_ROOM-(n)) \
+ if (--__loop == 0) { \
+ ErrorF ("savage wait loop failed 0x%x\n", s3->alt_status_0); \
+ break; \
+ } \
+}
+
+#define _s3WaitEmpty(s3) _s3WaitLoop(s3,S3_SAVAGE4_SLOTS, 0)
+#define _s3WaitIdleEmpty(s3) _s3WaitLoop(s3,S3_SAVAGE4_SLOTS|S3_SAVAGE4_2DI, \
+ S3_SAVAGE4_2DI)
+#define _s3WaitIdle(s3) _s3WaitLoop(s3,S3_SAVAGE4_2DI, S3_SAVAGE4_2DI)
+
+typedef struct _s3Cursor {
+ int width, height;
+ int xhot, yhot;
+ Bool has_cursor;
+ CursorPtr pCursor;
+ Pixel source, mask;
+} S3Cursor;
+
+typedef struct _s3PatternCache {
+ int id;
+ int x, y;
+} S3PatternCache;
+
+typedef struct _s3Patterns {
+ S3PatternCache *cache;
+ int ncache;
+ int last_used;
+ int last_id;
+} S3Patterns;
+
+#define S3_CLOCK_REF 14318 /* KHz */
+
+#define S3_CLOCK(m,n,r) ((S3_CLOCK_REF * ((m) + 2)) / (((n) + 2) * (1 << (r))))
+
+#define S3_MAX_CLOCK 150000 /* KHz */
+
+typedef struct _s3Timing {
+ /* label */
+ int horizontal;
+ int vertical;
+ int rate;
+ /* horizontal timing */
+ int hfp; /* front porch */
+ int hbp; /* back porch */
+ int hblank; /* blanking */
+ /* vertical timing */
+ int vfp; /* front porch */
+ int vbp; /* back porch */
+ int vblank; /* blanking */
+ /* clock values */
+ int dac_m;
+ int dac_n;
+ int dac_r;
+} S3Timing;
+
+#define S3_TEXT_SAVE (64*1024)
+
+typedef struct _s3Save {
+ CARD8 cursor_fg;
+ CARD8 cursor_bg;
+ CARD8 lock1;
+ CARD8 lock2;
+ CARD8 locksrtc;
+ CARD8 clock_mode;
+ CARD32 alt_mix;
+ CARD32 write_mask;
+ CARD32 fg;
+ CARD32 bg;
+ CARD32 global_bitmap_1;
+ CARD32 global_bitmap_2;
+ CARD32 primary_bitmap_1;
+ CARD32 primary_bitmap_2;
+ CARD8 text_save[S3_TEXT_SAVE];
+} S3Save;
+
+typedef struct _s3CardInfo {
+ S3Ptr s3; /* pointer to register structure */
+ int memory; /* amount of memory */
+ CARD8 *frameBuffer; /* pointer to frame buffer */
+ CARD8 *registers; /* pointer to register map */
+ S3Vga s3vga;
+ S3Save save;
+ Bool need_sync;
+ Bool bios_initialized; /* whether the bios has been run */
+} S3CardInfo;
+
+typedef struct _s3ScreenInfo {
+ CARD8 *cursor_base; /* pointer to cursor area */
+ CARD8 *offscreen; /* pointer to offscreen area */
+ int offscreen_y; /* top y coordinate of offscreen area */
+ int offscreen_x; /* top x coordinate of offscreen area */
+ int offscreen_width; /* width of offscreen area */
+ int offscreen_height; /* height of offscreen area */
+ S3Cursor cursor;
+ S3Patterns patterns;
+ Bool manage_border;
+ Bool managing_border;
+ CARD32 border_pixel;
+} S3ScreenInfo;
+
+#define getS3CardInfo(kd) ((S3CardInfo *) ((kd)->card->driver))
+#define s3CardInfo(kd) S3CardInfo *s3c = getS3CardInfo(kd)
+
+#define getS3ScreenInfo(kd) ((S3ScreenInfo *) ((kd)->screen->driver))
+#define s3ScreenInfo(kd) S3ScreenInfo *s3s = getS3ScreenInfo(kd)
+
+Bool s3CardInit (KdCardInfo *);
+Bool s3ScreenInit (KdScreenInfo *);
+void s3Enable (ScreenPtr pScreen);
+void s3Disable (ScreenPtr pScreen);
+void s3Fini (ScreenPtr pScreen);
+
+Bool s3CursorInit (ScreenPtr pScreen);
+void s3CursorEnable (ScreenPtr pScreen);
+void s3CursorDisable (ScreenPtr pScreen);
+void s3CursorFini (ScreenPtr pScreen);
+void s3RecolorCursor (ScreenPtr pScreen, int ndef, xColorItem *pdefs);
+
+Bool s3DrawInit (ScreenPtr pScreen);
+void s3DrawEnable (ScreenPtr pScreen);
+void s3DrawSync (ScreenPtr pScreen);
+void s3DrawDisable (ScreenPtr pScreen);
+void s3DrawFini (ScreenPtr pScreen);
+
+void s3GetColors (ScreenPtr pScreen, int ndef, xColorItem *pdefs);
+void s3PutColors (ScreenPtr pScreen, int ndef, xColorItem *pdefs);
+
+void S3InitCard (KdCardAttr *attr);
+
+void s3GetClock (int target, int *Mp, int *Np, int *Rp, int maxM, int maxN, int maxR);
+
+extern KdCardFuncs s3Funcs;
+
+/*
+ * Wait for the begining of the retrace interval
+ */
+
+#define S3_RETRACE_LOOP_CHECK if (++_loop_count > 300000) {\
+ DRAW_DEBUG ((DEBUG_FAILURE, "S3 wait loop failed at %s:%d", \
+ __FILE__, __LINE__)); \
+ break; \
+}
+
+#define DRAW_DEBUG(a)
+
+#define _s3WaitVRetrace(s3vga) { \
+ int _loop_count; \
+ _loop_count = 0; \
+ while (s3GetImm(s3vga, s3_vertical_sync_active) != 0) S3_RETRACE_LOOP_CHECK; \
+ _loop_count = 0; \
+ while (s3GetImm(s3vga, s3_vertical_sync_active) == 0) S3_RETRACE_LOOP_CHECK; \
+}
+/*
+ * Wait for the begining of the retrace interval
+ */
+#define _s3WaitVRetraceEnd(s3vga) { \
+ int _loop_count; \
+ _loop_count = 0; \
+ while (s3GetImm(s3vga, s3_vertical_sync_active) == 0) S3_RETRACE_LOOP_CHECK; \
+ _loop_count = 0; \
+ while (s3GetImm(s3vga, s3_vertical_sync_active) != 0) S3_RETRACE_LOOP_CHECK; \
+}
+
+#define S3_CURSOR_WIDTH 64
+#define S3_CURSOR_HEIGHT 64
+#define S3_CURSOR_SIZE ((S3_CURSOR_WIDTH * S3_CURSOR_HEIGHT + 7) / 8)
+
+#define S3_TILE_SIZE 8
+
+#endif /* _S3_H_ */
diff --git a/xc/programs/Xserver/hw/kdrive/savage/s3.nick b/xc/programs/Xserver/hw/kdrive/savage/s3.nick
new file mode 100644
index 000000000..0cb51b837
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/savage/s3.nick
@@ -0,0 +1,41 @@
+/* $XFree86: xc/programs/Xserver/hw/kdrive/savage/s3.nick,v 1.1 1999/11/19 13:53:55 hohndel Exp $ */
+
+global f_ref = 14318000;
+
+function s3_clock (m, n, r)
+{
+ return f_ref * (m + 2) / ((n + 2) * (2 ^ r));
+}
+
+function s3_near (f1, f2)
+{
+ return abs (f1 - f2) < f1 / 10;
+}
+
+function s3_clocks (f)
+{
+ auto m, n, r, ft;
+ auto dist, min_dist;
+ auto min_m, min_n, min_r;
+
+ min_dist = f / 5;
+ for (r = 0; r <= 3; r++)
+ for (n = 0; n <= 31; n++)
+ for (m = 0; m <= 127; m++)
+ {
+ ft = s3_clock (m, n, r);
+ if (s3_near (ft, f))
+ printf ("m %d n %d r %d = %d\n",
+ m, n, r, ft);
+ dist = abs (f - ft);
+ if (dist < min_dist)
+ {
+ min_dist = dist;
+ min_m = m;
+ min_n = n;
+ min_r = r;
+ }
+ }
+ printf ("m %d n %d r %d f %d dist %d\n",
+ min_m, min_n, min_r, s3_clock(min_m, min_n, min_r), min_dist);
+}
diff --git a/xc/programs/Xserver/hw/kdrive/savage/s3clock.c b/xc/programs/Xserver/hw/kdrive/savage/s3clock.c
new file mode 100644
index 000000000..a481e92fb
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/savage/s3clock.c
@@ -0,0 +1,86 @@
+/*
+ * $Id: s3clock.c,v 1.1 2000/01/06 12:55:50 faith 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/savage/s3clock.c,v 1.2 1999/12/30 03:03:11 robin Exp $ */
+
+#include "s3.h"
+
+/*
+ * Clock synthesis:
+ *
+ * f_out = f_ref * ((M + 2) / ((N + 2) * (1 << R)))
+ *
+ * Constraints:
+ *
+ * 1. 135MHz <= f_ref * ((M + 2) / (N + 2)) <= 270 MHz
+ * 2. N >= 1
+ *
+ * Vertical refresh rate = clock / ((hsize + hblank) * (vsize + vblank))
+ * Horizontal refresh rate = clock / (hsize + hblank)
+ */
+
+/* all in kHz */
+#define MIN_VCO 135000.0
+#define MAX_VCO 270000.0
+
+void
+s3GetClock (int target, int *Mp, int *Np, int *Rp, int maxM, int maxN, int maxR)
+{
+ int M, N, R, bestM, bestN;
+ int f_vco, f_out;
+ int err, abserr, besterr;
+
+ /*
+ * Compute correct R value to keep VCO in range
+ */
+ for (R = 0; R <= maxR; R++)
+ {
+ f_vco = target * (1 << R);
+ if (f_vco >= MIN_VCO)
+ break;
+ }
+
+ /* M = f_out / f_ref * ((N + 2) * (1 << R)); */
+ besterr = target;
+ for (N = 0; N <= maxN; N++)
+ {
+ M = (target * (N + 2) * (1 << R) + (S3_CLOCK_REF/2)) / S3_CLOCK_REF - 2;
+ if (0 <= M && M <= maxM)
+ {
+ f_out = S3_CLOCK(M,N,R);
+ err = target - f_out;
+ if (err < 0)
+ err = -err;
+ if (err < besterr)
+ {
+ besterr = err;
+ bestM = M;
+ bestN = N;
+ }
+ }
+ }
+ *Mp = bestM;
+ *Np = bestN;
+ *Rp = R;
+}
diff --git a/xc/programs/Xserver/hw/kdrive/savage/s3cmap.c b/xc/programs/Xserver/hw/kdrive/savage/s3cmap.c
new file mode 100644
index 000000000..dc0d711ab
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/savage/s3cmap.c
@@ -0,0 +1,87 @@
+/*
+ * $Id: s3cmap.c,v 1.1 2000/01/06 12:55:50 faith 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/savage/s3cmap.c,v 1.2 1999/12/30 03:03:11 robin Exp $ */
+
+#include "s3.h"
+
+void
+s3GetColors (ScreenPtr pScreen, int ndef, xColorItem *pdefs)
+{
+ KdScreenPriv(pScreen);
+ s3CardInfo(pScreenPriv);
+ S3Vga *s3vga = &s3c->s3vga;
+
+ while (ndef--)
+ {
+ s3SetImm (s3vga, s3_dac_read_index, pdefs->pixel);
+ pdefs->red = s3GetImm (s3vga, s3_dac_data) << 8;
+ pdefs->green = s3GetImm (s3vga, s3_dac_data) << 8;
+ pdefs->blue = s3GetImm (s3vga, s3_dac_data) << 8;
+ pdefs++;
+ }
+}
+
+void
+s3PutColors (ScreenPtr pScreen, int ndef, xColorItem *pdefs)
+{
+ KdScreenPriv(pScreen);
+ s3CardInfo(pScreenPriv);
+ s3ScreenInfo(pScreenPriv);
+ S3Vga *s3vga = &s3c->s3vga;
+ Bool hit_border = FALSE;
+ Bool check_border = FALSE;
+
+ _s3WaitVRetrace (s3vga);
+ if (pScreenPriv->enabled && s3s->manage_border && !s3s->managing_border)
+ check_border = TRUE;
+ while (ndef--)
+ {
+ if (check_border && pdefs->pixel == s3s->border_pixel)
+ {
+ if (pdefs->red || pdefs->green || pdefs->blue)
+ hit_border = TRUE;
+ }
+ s3SetImm (s3vga, s3_dac_write_index, pdefs->pixel);
+ s3SetImm (s3vga, s3_dac_data, pdefs->red >> 8);
+ s3SetImm (s3vga, s3_dac_data, pdefs->green >> 8);
+ s3SetImm (s3vga, s3_dac_data, pdefs->blue >> 8);
+ pdefs++;
+ }
+ if (hit_border)
+ {
+ xColorItem black;
+
+ black.red = 0;
+ black.green = 0;
+ black.blue = 0;
+ s3s->managing_border = TRUE;
+ FakeAllocColor (pScreenPriv->pInstalledmap,
+ &black);
+ s3s->border_pixel = black.pixel;
+ FakeFreeColor (pScreenPriv->pInstalledmap, s3s->border_pixel);
+/* s3SetImm (&s3c->s3vga, s3_border_color, (VGA8) s3s->border_pixel); */
+ }
+}
+
diff --git a/xc/programs/Xserver/hw/kdrive/savage/s3curs.c b/xc/programs/Xserver/hw/kdrive/savage/s3curs.c
new file mode 100644
index 000000000..8c2296a7d
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/savage/s3curs.c
@@ -0,0 +1,405 @@
+/*
+ * $Id: s3curs.c,v 1.1 2000/01/06 12:55:50 faith 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/savage/s3curs.c,v 1.2 1999/12/30 03:03:11 robin Exp $ */
+
+#include "s3.h"
+#include "s3draw.h"
+#include "cursorstr.h"
+
+#define SetupCursor(s) KdScreenPriv(s); \
+ s3CardInfo(pScreenPriv); \
+ s3ScreenInfo(pScreenPriv); \
+ S3Ptr s3 = s3c->s3; \
+ S3Vga *s3vga = &s3c->s3vga; \
+ S3Cursor *pCurPriv = &s3s->cursor
+
+static void
+_s3MoveCursor (ScreenPtr pScreen, int x, int y)
+{
+ SetupCursor(pScreen);
+ CARD8 xlow, xhigh, ylow, yhigh;
+ CARD8 xoff, yoff;
+
+ DRAW_DEBUG ((DEBUG_CURSOR, "s3MoveCursor %d %d", x, y));
+
+ 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 */
+
+ s3SetImm (s3vga, s3_cursor_xhigh, xhigh);
+ s3SetImm (s3vga, s3_cursor_xlow, xlow);
+ s3SetImm (s3vga, s3_cursor_ylow, ylow);
+ s3SetImm (s3vga, s3_cursor_xoff, xoff);
+ s3SetImm (s3vga, s3_cursor_yoff, yoff);
+ s3SetImm (s3vga, s3_cursor_yhigh, yhigh);
+
+ DRAW_DEBUG ((DEBUG_CURSOR, "s3MoveCursor done"));
+}
+
+static void
+s3MoveCursor (ScreenPtr pScreen, int x, int y)
+{
+ SetupCursor (pScreen);
+
+ if (!pCurPriv->has_cursor)
+ return;
+
+ if (!pScreenPriv->enabled)
+ return;
+
+ _s3MoveCursor (pScreen, x, y);
+}
+
+static void
+s3AllocCursorColors (ScreenPtr pScreen)
+{
+ SetupCursor (pScreen);
+ CursorPtr pCursor = pCurPriv->pCursor;
+
+ KdAllocateCursorPixels (pScreen, pCursor,
+ &pCurPriv->source, &pCurPriv->mask);
+ 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
+_s3SetCursorColors (ScreenPtr pScreen)
+{
+ SetupCursor (pScreen);
+ /* set foreground */
+ /* Reset cursor color stack pointers */
+ (void) s3GetImm (s3vga, s3_cursor_enable);
+ s3SetImm (s3vga, s3_cursor_fg, pCurPriv->source);
+ s3SetImm (s3vga, s3_cursor_fg, pCurPriv->source >> 8);
+ s3SetImm (s3vga, s3_cursor_fg, pCurPriv->source >> 16);
+
+ /* set background */
+ /* Reset cursor color stack pointers */
+ (void) s3GetImm (s3vga, s3_cursor_enable);
+ s3SetImm (s3vga, s3_cursor_bg, pCurPriv->mask);
+ s3SetImm (s3vga, s3_cursor_bg, pCurPriv->mask >> 8);
+ s3SetImm (s3vga, s3_cursor_bg, pCurPriv->mask >> 16);
+}
+
+void
+s3RecolorCursor (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;
+ }
+ s3AllocCursorColors (pScreen);
+ _s3SetCursorColors (pScreen);
+}
+
+static void
+s3LoadCursor (ScreenPtr pScreen, int x, int y)
+{
+ SetupCursor(pScreen);
+ CursorPtr pCursor = pCurPriv->pCursor;
+ CursorBitsPtr bits = pCursor->bits;
+ int w, h;
+ unsigned char r[2], g[2], b[2];
+ unsigned long *ram;
+ unsigned long *msk, *mskLine, *src, *srcLine;
+ unsigned long and, xor;
+ int i, j;
+ int cursor_address;
+ int wsrc;
+ unsigned char ramdac_control_;
+
+ /*
+ * Allocate new colors
+ */
+ s3AllocCursorColors (pScreen);
+
+ pCurPriv->pCursor = pCursor;
+ pCurPriv->xhot = pCursor->bits->xhot;
+ pCurPriv->yhot = pCursor->bits->yhot;
+
+ /*
+ * Stick new image into cursor memory
+ */
+ ram = (unsigned long *) s3s->cursor_base;
+ mskLine = (unsigned long *) bits->mask;
+ srcLine = (unsigned long *) bits->source;
+
+ h = bits->height;
+ if (h > S3_CURSOR_HEIGHT)
+ h = S3_CURSOR_HEIGHT;
+
+ wsrc = BitmapBytePad(bits->width) / 4; /* ulongs per line */
+
+ for (i = 0; i < S3_CURSOR_HEIGHT; i++) {
+ msk = mskLine;
+ src = srcLine;
+ mskLine += wsrc;
+ srcLine += wsrc;
+ for (j = 0; j < S3_CURSOR_WIDTH / 32; j++) {
+
+ unsigned long m, s;
+
+ if (i < h && j < wsrc)
+ {
+ m = *msk++;
+ s = *src++;
+ xor = m & s;
+ and = ~m;
+ }
+ else
+ {
+ and = 0xffffffff;
+ xor = 0x00000000;
+ }
+
+ S3AdjustBits32(and);
+ S3AdjustBits32(xor);
+ *ram++ = (and & 0xffff) | (xor << 16);
+ *ram++ = (and >> 16) | (xor & 0xffff0000);
+ }
+ }
+
+ _s3WaitIdle (s3);
+
+ /* Set new color */
+ _s3SetCursorColors (pScreen);
+
+ /* Enable the cursor */
+ s3SetImm (s3vga, s3_cursor_ms_x11, 0);
+ s3SetImm (s3vga, s3_cursor_enable, 1);
+
+ /* Wait for VRetrace to make sure the position is read */
+ _s3WaitVRetrace (s3vga);
+
+ /* Move to new position */
+ _s3MoveCursor (pScreen, x, y);
+}
+
+static void
+s3UnloadCursor (ScreenPtr pScreen)
+{
+ SetupCursor (pScreen);
+
+ /* Disable cursor */
+ s3SetImm (s3vga, s3_cursor_enable, 0);
+}
+
+static Bool
+s3RealizeCursor (ScreenPtr pScreen, CursorPtr pCursor)
+{
+ SetupCursor(pScreen);
+
+ if (!pScreenPriv->enabled)
+ return TRUE;
+
+ /* miRecolorCursor does this */
+ if (pCurPriv->pCursor == pCursor)
+ {
+ if (pCursor)
+ {
+#ifdef FB_OLD_SCREEN
+ short x, y;
+#else
+ int x, y;
+#endif
+
+ miPointerPosition (&x, &y);
+ s3LoadCursor (pScreen, x, y);
+ }
+ }
+ return TRUE;
+}
+
+static Bool
+s3UnrealizeCursor (ScreenPtr pScreen, CursorPtr pCursor)
+{
+ return TRUE;
+}
+
+static void
+s3SetCursor (ScreenPtr pScreen, CursorPtr pCursor, int x, int y)
+{
+ SetupCursor(pScreen);
+
+ pCurPriv->pCursor = pCursor;
+
+ if (!pScreenPriv->enabled)
+ return;
+
+ if (pCursor)
+ s3LoadCursor (pScreen, x, y);
+ else
+ s3UnloadCursor (pScreen);
+}
+
+miPointerSpriteFuncRec s3PointerSpriteFuncs = {
+ s3RealizeCursor,
+ s3UnrealizeCursor,
+ s3SetCursor,
+ s3MoveCursor,
+};
+
+static void
+s3QueryBestSize (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
+s3CursorInit (ScreenPtr pScreen)
+{
+ SetupCursor (pScreen);
+
+ if (!s3s->cursor_base)
+ {
+ DRAW_DEBUG ((DEBUG_CURSOR,"Not enough screen memory for cursor %d", s3d->memory));
+ pCurPriv->has_cursor = FALSE;
+ return FALSE;
+ }
+
+ pCurPriv->width = S3_CURSOR_WIDTH;
+ pCurPriv->height= S3_CURSOR_HEIGHT;
+ pScreen->QueryBestSize = s3QueryBestSize;
+ miPointerInitialize (pScreen,
+ &s3PointerSpriteFuncs,
+ &kdPointerScreenFuncs,
+ FALSE);
+ pCurPriv->has_cursor = TRUE;
+ pCurPriv->pCursor = NULL;
+ return TRUE;
+}
+
+void
+s3CursorEnable (ScreenPtr pScreen)
+{
+ SetupCursor (pScreen);
+
+ DRAW_DEBUG ((DEBUG_INIT, "s3CursorEnable"));
+ if (pCurPriv->has_cursor)
+ {
+ if (pCurPriv->pCursor)
+ {
+#ifdef FB_OLD_SCREEN
+ short x, y;
+#else
+ int x, y;
+#endif
+
+ miPointerPosition (&x, &y);
+ s3LoadCursor (pScreen, x, y);
+ }
+ else
+ s3UnloadCursor (pScreen);
+ }
+}
+
+void
+s3CursorDisable (ScreenPtr pScreen)
+{
+ SetupCursor (pScreen);
+
+ if (!pScreenPriv->enabled)
+ return;
+
+ if (pCurPriv->has_cursor)
+ {
+ if (pCurPriv->pCursor)
+ {
+ s3UnloadCursor (pScreen);
+ }
+ }
+}
+
+void
+s3CursorFini (ScreenPtr pScreen)
+{
+ SetupCursor (pScreen);
+
+ pCurPriv->pCursor = NULL;
+}
diff --git a/xc/programs/Xserver/hw/kdrive/savage/s3draw.c b/xc/programs/Xserver/hw/kdrive/savage/s3draw.c
new file mode 100644
index 000000000..059da022d
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/savage/s3draw.c
@@ -0,0 +1,2432 @@
+/*
+ * $Id: s3draw.c,v 1.1 2000/01/06 12:55:51 faith 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/savage/s3draw.c,v 1.2 1999/12/30 03:03:11 robin Exp $ */
+
+#include "s3.h"
+#include "s3draw.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"
+
+/*
+ * Map X rops to S3 rops
+ */
+
+short s3alu[16] = {
+ MIX_0,
+ MIX_AND,
+ MIX_SRC_AND_NOT_DST,
+ MIX_SRC,
+ MIX_NOT_SRC_AND_DST,
+ MIX_DST,
+ MIX_XOR,
+ MIX_OR,
+ MIX_NOR,
+ MIX_XNOR,
+ MIX_NOT_DST,
+ MIX_SRC_OR_NOT_DST,
+ MIX_NOT_SRC,
+ MIX_NOT_SRC_OR_DST,
+ MIX_NAND,
+ MIX_1
+};
+
+/*
+ * Handle pixel transfers
+ */
+
+#define BURST
+#ifdef BURST
+#define PixTransDeclare VOL32 *pix_trans_base = (VOL32 *) (s3c->registers),\
+ *pix_trans = pix_trans_base
+#define PixTransStart(n) if (pix_trans + (n) > pix_trans_base + 8192) pix_trans = pix_trans_base
+#define PixTransStore(t) *pix_trans++ = (t)
+#else
+#define PixTransDeclare VOL32 *pix_trans = &s3->pix_trans
+#define PixTransStart(n)
+#define PixTransStore(t) *pix_trans = (t)
+#endif
+
+int s3GCPrivateIndex;
+int s3WindowPrivateIndex;
+int s3Generation;
+
+/*
+ s3DoBitBlt
+ =============
+ Bit Blit for all window to window blits.
+*/
+
+#define sourceInvarient(alu) (((alu) & 3) == (((alu) >> 2) & 3))
+
+void
+s3CopyNtoN (DrawablePtr pSrcDrawable,
+ DrawablePtr pDstDrawable,
+ GCPtr pGC,
+ BoxPtr pbox,
+ int nbox,
+ int dx,
+ int dy,
+ Bool reverse,
+ Bool upsidedown,
+ Pixel bitplane,
+ void *closure)
+{
+ SetupS3(pDstDrawable->pScreen);
+ int srcX, srcY, dstX, dstY;
+ int w, h;
+ int flags;
+
+ if (sourceInvarient (pGC->alu))
+ {
+ s3FillBoxSolid (pDstDrawable, nbox, pbox, 0, pGC->alu, pGC->planemask);
+ return;
+ }
+
+ _s3SetBlt(s3,pGC->alu,pGC->planemask);
+ DRAW_DEBUG ((DEBUG_RENDER, "s3CopyNtoN alu %d planemask 0x%x",
+ pGC->alu, pGC->planemask));
+ while (nbox--)
+ {
+ w = pbox->x2 - pbox->x1;
+ h = pbox->y2 - pbox->y1;
+ flags = 0;
+ if (reverse)
+ {
+ dstX = pbox->x2 - 1;
+ }
+ else
+ {
+ dstX = pbox->x1;
+ flags |= INC_X;
+ }
+ srcX = dstX + dx;
+
+ if (upsidedown)
+ {
+ dstY = pbox->y2 - 1;
+ }
+ else
+ {
+ dstY = pbox->y1;
+ flags |= INC_Y;
+ }
+ srcY = dstY + dy;
+
+ _s3Blt (s3, srcX, srcY, dstX, dstY, w, h, flags);
+ pbox++;
+ }
+ MarkSyncS3 (pSrcDrawable->pScreen);
+}
+
+RegionPtr
+s3CopyArea(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC,
+ int srcx, int srcy, int width, int height, int dstx, int dsty)
+{
+ SetupS3(pDstDrawable->pScreen);
+
+ if (pSrcDrawable->type == DRAWABLE_WINDOW &&
+ pDstDrawable->type == DRAWABLE_WINDOW)
+ {
+ return fbDoCopy (pSrcDrawable, pDstDrawable, pGC,
+ srcx, srcy, width, height,
+ dstx, dsty, s3CopyNtoN, 0, 0);
+ }
+ return KdCheckCopyArea (pSrcDrawable, pDstDrawable, pGC,
+ srcx, srcy, width, height, dstx, dsty);
+}
+
+typedef struct _s31toNargs {
+ unsigned long copyPlaneFG, copyPlaneBG;
+ Bool opaque;
+} s31toNargs;
+
+void
+_s3Stipple (S3CardInfo *s3c,
+ FbStip *psrcBase,
+ FbStride widthSrc,
+ int srcx,
+ int srcy,
+ int dstx,
+ int dsty,
+ int width,
+ int height)
+{
+ S3Ptr s3 = s3c->s3;
+ FbStip *psrcLine, *psrc;
+ FbStride widthRest;
+ FbStip bits, tmp, lastTmp;
+ int leftShift, rightShift;
+ int nl, nlMiddle;
+ int r;
+ PixTransDeclare;
+
+ /* Compute blt address and parameters */
+ psrc = psrcBase + srcy * widthSrc + (srcx >> 5);
+ nlMiddle = (width + 31) >> 5;
+ leftShift = srcx & 0x1f;
+ rightShift = 32 - leftShift;
+ widthRest = widthSrc - nlMiddle;
+
+ _s3PlaneBlt(s3,dstx,dsty,width,height);
+
+ if (leftShift == 0)
+ {
+ while (height--)
+ {
+ nl = nlMiddle;
+ PixTransStart(nl);
+ while (nl--)
+ {
+ tmp = *psrc++;
+ S3AdjustBits32 (tmp);
+ PixTransStore (tmp);
+ }
+ psrc += widthRest;
+ }
+ }
+ else
+ {
+ widthRest--;
+ while (height--)
+ {
+ bits = *psrc++;
+ nl = nlMiddle;
+ PixTransStart(nl);
+ while (nl--)
+ {
+ tmp = FbStipLeft(bits, leftShift);
+ bits = *psrc++;
+ tmp |= FbStipRight(bits, rightShift);
+ S3AdjustBits32(tmp);
+ PixTransStore (tmp);
+ }
+ psrc += widthRest;
+ }
+ }
+}
+
+void
+s3Copy1toN (DrawablePtr pSrcDrawable,
+ DrawablePtr pDstDrawable,
+ GCPtr pGC,
+ BoxPtr pbox,
+ int nbox,
+ int dx,
+ int dy,
+ Bool reverse,
+ Bool upsidedown,
+ Pixel bitplane,
+ void *closure)
+{
+ SetupS3(pDstDrawable->pScreen);
+
+ s31toNargs *args = closure;
+ int dstx, dsty;
+ FbStip *psrcBase;
+ FbStride widthSrc;
+ int srcBpp;
+
+ if (args->opaque && sourceInvarient (pGC->alu))
+ {
+ s3FillBoxSolid (pDstDrawable, nbox, pbox,
+ pGC->bgPixel, pGC->alu, pGC->planemask);
+ return;
+ }
+
+ fbGetStipDrawable (pSrcDrawable, psrcBase, widthSrc, srcBpp);
+
+ if (args->opaque)
+ {
+ _s3SetOpaquePlaneBlt(s3,pGC->alu,pGC->planemask,args->copyPlaneFG,
+ args->copyPlaneBG);
+ }
+ else
+ {
+ _s3SetTransparentPlaneBlt (s3, pGC->alu,
+ pGC->planemask, args->copyPlaneFG);
+ }
+
+ while (nbox--)
+ {
+ dstx = pbox->x1;
+ dsty = pbox->y1;
+
+ _s3Stipple (s3c,
+ psrcBase, widthSrc,
+ dstx + dx, dsty + dy,
+ dstx, dsty,
+ pbox->x2 - dstx, pbox->y2 - dsty);
+ pbox++;
+ }
+ MarkSyncS3 (pDstDrawable->pScreen);
+}
+
+RegionPtr
+s3CopyPlane(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC,
+ int srcx, int srcy, int width, int height,
+ int dstx, int dsty, unsigned long bitPlane)
+{
+ SetupS3 (pDstDrawable->pScreen);
+ RegionPtr ret;
+ s31toNargs args;
+
+ if (pDstDrawable->type == DRAWABLE_WINDOW &&
+ pSrcDrawable->depth == 1)
+ {
+ args.copyPlaneFG = pGC->fgPixel;
+ args.copyPlaneBG = pGC->bgPixel;
+ args.opaque = TRUE;
+ return fbDoCopy (pSrcDrawable, pDstDrawable, pGC,
+ srcx, srcy, width, height,
+ dstx, dsty, s3Copy1toN, bitPlane, &args);
+ }
+ return KdCheckCopyPlane(pSrcDrawable, pDstDrawable, pGC,
+ srcx, srcy, width, height,
+ dstx, dsty, bitPlane);
+}
+
+void
+s3PushPixels (GCPtr pGC, PixmapPtr pBitmap,
+ DrawablePtr pDrawable,
+ int w, int h, int x, int y)
+{
+ SetupS3 (pDrawable->pScreen);
+ s31toNargs args;
+
+ if (pDrawable->type == DRAWABLE_WINDOW && pGC->fillStyle == FillSolid)
+ {
+ args.opaque = FALSE;
+ args.copyPlaneFG = pGC->fgPixel;
+ (void) fbDoCopy ((DrawablePtr) pBitmap, pDrawable, pGC,
+ 0, 0, w, h, x, y, s3Copy1toN, 1, &args);
+ }
+ else
+ {
+ KdCheckPushPixels (pGC, pBitmap, pDrawable, w, h, x, y);
+ }
+}
+
+void
+s3FillBoxSolid (DrawablePtr pDrawable, int nBox, BoxPtr pBox,
+ unsigned long pixel, int alu, unsigned long planemask)
+{
+ SetupS3(pDrawable->pScreen);
+ register int r;
+
+ _s3SetSolidFill(s3,pixel,alu,planemask);
+
+ while (nBox--) {
+ _s3SolidRect(s3,pBox->x1,pBox->y1,pBox->x2-pBox->x1,pBox->y2-pBox->y1);
+ pBox++;
+ }
+ MarkSyncS3 (pDrawable->pScreen);
+}
+
+void
+_s3SetPattern (ScreenPtr pScreen,
+ int alu, unsigned long planemask, s3PatternPtr pPattern)
+{
+ SetupS3(pScreen);
+ S3PatternCache *cache;
+
+ _s3LoadPattern (pScreen, pPattern);
+ cache = pPattern->cache;
+
+ switch (pPattern->fillStyle) {
+ case FillTiled:
+ _s3SetTile(s3,alu,planemask);
+ break;
+ case FillStippled:
+ _s3SetStipple(s3,alu,planemask,pPattern->fore);
+ break;
+ case FillOpaqueStippled:
+ _s3SetOpaqueStipple(s3,alu,planemask,pPattern->fore,pPattern->back);
+ break;
+ }
+}
+
+void
+s3FillBoxPattern (DrawablePtr pDrawable, int nBox, BoxPtr pBox,
+ int alu, unsigned long planemask, s3PatternPtr pPattern)
+{
+ SetupS3(pDrawable->pScreen);
+ S3PatternCache *cache;
+ int patx, paty;
+
+ _s3SetPattern (pDrawable->pScreen, alu, planemask, pPattern);
+ cache = pPattern->cache;
+ while (nBox--)
+ {
+ _s3PatRect(s3,cache->x, cache->y,
+ pBox->x1, pBox->y1,
+ pBox->x2-pBox->x1, pBox->y2-pBox->y1);
+ pBox++;
+ }
+ MarkSyncS3 (pDrawable->pScreen);
+}
+
+void
+s3FillBoxLargeStipple (DrawablePtr pDrawable, GCPtr pGC,
+ int nBox, BoxPtr pBox)
+{
+ SetupS3(pDrawable->pScreen);
+ DrawablePtr pStipple = &pGC->stipple->drawable;
+ int xRot = pGC->patOrg.x + pDrawable->x;
+ int yRot = pGC->patOrg.y + pDrawable->y;
+ FbStip *stip;
+ FbStride stipStride;
+ int stipBpp;
+ int stipWidth, stipHeight;
+ int dstX, dstY, width, height;
+
+ stipWidth = pStipple->width;
+ stipHeight = pStipple->height;
+ fbGetStipDrawable (pStipple, stip, stipStride, stipBpp);
+
+ if (pGC->fillStyle == FillOpaqueStippled)
+ {
+ _s3SetOpaquePlaneBlt(s3,pGC->alu,pGC->planemask,
+ pGC->fgPixel, pGC->bgPixel);
+
+ }
+ else
+ {
+ _s3SetTransparentPlaneBlt(s3,pGC->alu,pGC->planemask, pGC->fgPixel);
+ }
+
+ while (nBox--)
+ {
+ int stipX, stipY, sx;
+ int widthTmp;
+ int h, w;
+ int x, y;
+
+ dstX = pBox->x1;
+ dstY = pBox->y1;
+ width = pBox->x2 - pBox->x1;
+ height = pBox->y2 - pBox->y1;
+ pBox++;
+ modulus (dstY - yRot, stipHeight, stipY);
+ modulus (dstX - xRot, stipWidth, stipX);
+ y = dstY;
+ while (height)
+ {
+ h = stipHeight - stipY;
+ if (h > height)
+ h = height;
+ height -= h;
+ widthTmp = width;
+ x = dstX;
+ sx = stipX;
+ while (widthTmp)
+ {
+ w = (stipWidth - sx);
+ if (w > widthTmp)
+ w = widthTmp;
+ widthTmp -= w;
+ _s3Stipple (s3c,
+ stip,
+ stipStride,
+ sx, stipY,
+ x, y,
+ w, h);
+ x += w;
+ sx = 0;
+ }
+ y += h;
+ stipY = 0;
+ }
+ }
+ MarkSyncS3 (pDrawable->pScreen);
+}
+
+#define NUM_STACK_RECTS 1024
+
+void
+s3PolyFillRect (DrawablePtr pDrawable, GCPtr pGC,
+ int nrectFill, xRectangle *prectInit)
+{
+ s3GCPrivate(pGC);
+ 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;
+
+ prgnClip = fbGetCompositeClip(pGC);
+ xorg = pDrawable->x;
+ yorg = pDrawable->y;
+
+ if (xorg || yorg)
+ {
+ prect = prectInit;
+ n = nrectFill;
+ while(n--)
+ {
+ prect->x += xorg;
+ prect->y += yorg;
+ prect++;
+ }
+ }
+
+ prect = prectInit;
+
+ numRects = REGION_NUM_RECTS(prgnClip) * nrectFill;
+ if (numRects > NUM_STACK_RECTS)
+ {
+ pboxClippedBase = (BoxPtr)ALLOCATE_LOCAL(numRects * sizeof(BoxRec));
+ if (!pboxClippedBase)
+ return;
+ }
+ else
+ pboxClippedBase = stackRects;
+
+ pboxClipped = pboxClippedBase;
+
+ if (REGION_NUM_RECTS(prgnClip) == 1)
+ {
+ int x1, y1, x2, y2, bx2, by2;
+
+ pextent = REGION_RECTS(prgnClip);
+ x1 = pextent->x1;
+ y1 = pextent->y1;
+ x2 = pextent->x2;
+ y2 = pextent->y2;
+ while (nrectFill--)
+ {
+ if ((pboxClipped->x1 = prect->x) < x1)
+ pboxClipped->x1 = x1;
+
+ if ((pboxClipped->y1 = prect->y) < y1)
+ pboxClipped->y1 = y1;
+
+ bx2 = (int) prect->x + (int) prect->width;
+ if (bx2 > x2)
+ bx2 = x2;
+ pboxClipped->x2 = bx2;
+
+ by2 = (int) prect->y + (int) prect->height;
+ if (by2 > y2)
+ by2 = y2;
+ pboxClipped->y2 = by2;
+
+ prect++;
+ if ((pboxClipped->x1 < pboxClipped->x2) &&
+ (pboxClipped->y1 < pboxClipped->y2))
+ {
+ pboxClipped++;
+ }
+ }
+ }
+ else
+ {
+ int x1, y1, x2, y2, bx2, by2;
+
+ pextent = REGION_EXTENTS(pGC->pScreen, prgnClip);
+ x1 = pextent->x1;
+ y1 = pextent->y1;
+ x2 = pextent->x2;
+ y2 = pextent->y2;
+ while (nrectFill--)
+ {
+ BoxRec box;
+
+ if ((box.x1 = prect->x) < x1)
+ box.x1 = x1;
+
+ if ((box.y1 = prect->y) < y1)
+ box.y1 = y1;
+
+ bx2 = (int) prect->x + (int) prect->width;
+ if (bx2 > x2)
+ bx2 = x2;
+ box.x2 = bx2;
+
+ by2 = (int) prect->y + (int) prect->height;
+ if (by2 > y2)
+ by2 = y2;
+ box.y2 = by2;
+
+ prect++;
+
+ if ((box.x1 >= box.x2) || (box.y1 >= box.y2))
+ continue;
+
+ n = REGION_NUM_RECTS (prgnClip);
+ pbox = REGION_RECTS(prgnClip);
+
+ /* clip the rectangle to each box in the clip region
+ this is logically equivalent to calling Intersect()
+ */
+ while(n--)
+ {
+ pboxClipped->x1 = max(box.x1, pbox->x1);
+ pboxClipped->y1 = max(box.y1, pbox->y1);
+ pboxClipped->x2 = min(box.x2, pbox->x2);
+ pboxClipped->y2 = min(box.y2, pbox->y2);
+ pbox++;
+
+ /* see if clipping left anything */
+ if(pboxClipped->x1 < pboxClipped->x2 &&
+ pboxClipped->y1 < pboxClipped->y2)
+ {
+ pboxClipped++;
+ }
+ }
+ }
+ }
+ if (pboxClipped != pboxClippedBase)
+ {
+ if (pGC->fillStyle == FillSolid)
+ s3FillBoxSolid(pDrawable,
+ pboxClipped-pboxClippedBase, pboxClippedBase,
+ pGC->fgPixel, pGC->alu, pGC->planemask);
+ else if (s3Priv->pPattern)
+ s3FillBoxPattern (pDrawable,
+ pboxClipped-pboxClippedBase, pboxClippedBase,
+ pGC->alu, pGC->planemask,
+ s3Priv->pPattern);
+ else
+ s3FillBoxLargeStipple (pDrawable, pGC,
+ pboxClipped-pboxClippedBase,
+ pboxClippedBase);
+ }
+ if (pboxClippedBase != stackRects)
+ DEALLOCATE_LOCAL(pboxClippedBase);
+}
+
+void
+_s3FillSpanLargeStipple (DrawablePtr pDrawable, GCPtr pGC,
+ int n, DDXPointPtr ppt, int *pwidth)
+{
+ SetupS3 (pDrawable->pScreen);
+ DrawablePtr pStipple = &pGC->stipple->drawable;
+ int xRot = pGC->patOrg.x + pDrawable->x;
+ int yRot = pGC->patOrg.y + pDrawable->y;
+ FbStip *stip;
+ FbStride stipStride;
+ int stipBpp;
+ int stipWidth, stipHeight;
+ int dstX, dstY, width, height;
+
+ stipWidth = pStipple->width;
+ stipHeight = pStipple->height;
+ fbGetStipDrawable (pStipple, stip, stipStride, stipBpp);
+ if (pGC->fillStyle == FillOpaqueStippled)
+ {
+ _s3SetOpaquePlaneBlt(s3,pGC->alu,pGC->planemask,
+ pGC->fgPixel, pGC->bgPixel);
+
+ }
+ else
+ {
+ _s3SetTransparentPlaneBlt(s3,pGC->alu,pGC->planemask, pGC->fgPixel);
+ }
+ while (n--)
+ {
+ int stipX, stipY, sx;
+ int w;
+ int x, y;
+
+ dstX = ppt->x;
+ dstY = ppt->y;
+ ppt++;
+ width = *pwidth++;
+ modulus (dstY - yRot, stipHeight, stipY);
+ modulus (dstX - xRot, stipWidth, stipX);
+ y = dstY;
+ x = dstX;
+ sx = stipX;
+ while (width)
+ {
+ w = (stipWidth - sx);
+ if (w > width)
+ w = width;
+ width -= w;
+ _s3Stipple (s3c,
+ stip,
+ stipStride,
+ sx, stipY,
+ x, y,
+ w, 1);
+ x += w;
+ sx = 0;
+ }
+ }
+}
+
+void
+s3FillSpans (DrawablePtr pDrawable, GCPtr pGC, int n,
+ DDXPointPtr ppt, int *pwidth, int fSorted)
+{
+ s3GCPrivate(pGC);
+ SetupS3(pDrawable->pScreen);
+ int x, y, x1, y1, x2, y2;
+ int width;
+ /* next three parameters are post-clip */
+ int nTmp;
+ int *pwidthFree;/* copies of the pointers to free */
+ DDXPointPtr pptFree;
+ FbGCPrivPtr fbPriv = fbGetGCPrivate(pGC);
+ BoxPtr extents;
+ S3PatternCache *cache;
+ RegionPtr pClip = fbGetCompositeClip (pGC);
+
+ if (REGION_NUM_RECTS(pClip) == 1 &&
+ (pGC->fillStyle == FillSolid || s3Priv->pPattern))
+ {
+ extents = REGION_RECTS(pClip);
+ x1 = extents->x1;
+ x2 = extents->x2;
+ y1 = extents->y1;
+ y2 = extents->y2;
+ if (pGC->fillStyle == FillSolid)
+ {
+ _s3SetSolidFill(s3,pGC->fgPixel,pGC->alu,pGC->planemask);
+ cache = 0;
+ }
+ else
+ {
+ _s3SetPattern (pDrawable->pScreen, pGC->alu, pGC->planemask,
+ s3Priv->pPattern);
+ cache = s3Priv->pPattern->cache;
+ }
+ while (n--)
+ {
+ y = ppt->y;
+ if (y1 <= y && y < y2)
+ {
+ x = ppt->x;
+ width = *pwidth;
+ if (x < x1)
+ {
+ width -= (x1 - x);
+ x = x1;
+ }
+ if (x2 < x + width)
+ width = x2 - x;
+ if (width > 0)
+ {
+ if (cache)
+ {
+ _s3PatRect(s3, cache->x, cache->y, x, y, width, 1);
+ }
+ else
+ {
+ _s3SolidRect(s3,x,y,width,1);
+ }
+ }
+ }
+ ppt++;
+ pwidth++;
+ }
+ }
+ else
+ {
+ nTmp = n * miFindMaxBand(pClip);
+ 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;
+ if (pGC->fillStyle == FillSolid)
+ {
+ _s3SetSolidFill(s3,pGC->fgPixel,pGC->alu,pGC->planemask);
+ while (n--)
+ {
+ x = ppt->x;
+ y = ppt->y;
+ ppt++;
+ width = *pwidth++;
+ if (width)
+ {
+ _s3SolidRect(s3,x,y,width,1);
+ }
+ }
+ }
+ else if (s3Priv->pPattern)
+ {
+ _s3SetPattern (pDrawable->pScreen, pGC->alu, pGC->planemask,
+ s3Priv->pPattern);
+ cache = s3Priv->pPattern->cache;
+ while (n--)
+ {
+ x = ppt->x;
+ y = ppt->y;
+ ppt++;
+ width = *pwidth++;
+ if (width)
+ {
+ _s3PatRect(s3, cache->x, cache->y, x, y, width, 1);
+ }
+ }
+ }
+ else
+ {
+ _s3FillSpanLargeStipple (pDrawable, pGC, n, ppt, pwidth);
+ }
+ DEALLOCATE_LOCAL(pptFree);
+ DEALLOCATE_LOCAL(pwidthFree);
+ }
+ MarkSyncS3 (pDrawable->pScreen);
+}
+
+#include "mifillarc.h"
+
+#define FILLSPAN(s3,y,__x1,__x2) {\
+ DRAW_DEBUG ((DEBUG_ARCS, "FILLSPAN %d: %d->%d", y, __x1, __x2)); \
+ if ((__x2) >= (__x1)) {\
+ _s3SolidRect(s3,(__x1),(y),(__x2)-(__x1)+1,1); \
+ } \
+}
+
+#define FILLSLICESPANS(flip,__y) \
+ if (!flip) \
+ { \
+ FILLSPAN(s3,__y,xl,xr) \
+ } \
+ else \
+ { \
+ xc = xorg - x; \
+ FILLSPAN(s3, __y, xc, xr) \
+ xc += slw - 1; \
+ FILLSPAN(s3, __y, xl, xc) \
+ }
+
+static void
+_s3FillEllipse (DrawablePtr pDraw, S3Ptr s3, xArc *arc)
+{
+ int x, y, e;
+ int yk, xk, ym, xm, dx, dy, xorg, yorg;
+ int y_top, y_bot;
+ miFillArcRec info;
+ register int xpos;
+ int slw;
+
+ miFillArcSetup(arc, &info);
+ MIFILLARCSETUP();
+ y_top = pDraw->y + yorg - y;
+ y_bot = pDraw->y + yorg + y + dy;
+ xorg += pDraw->x;
+ while (y)
+ {
+ y_top++;
+ y_bot--;
+ MIFILLARCSTEP(slw);
+ if (!slw)
+ continue;
+ xpos = xorg - x;
+ _s3SolidRect (s3,xpos,y_top,slw,1);
+ if (miFillArcLower(slw))
+ _s3SolidRect (s3,xpos,y_bot,slw,1);
+ }
+}
+
+
+static void
+_s3FillArcSlice (DrawablePtr pDraw, GCPtr pGC, S3Ptr s3, xArc *arc)
+{
+ int yk, xk, ym, xm, dx, dy, xorg, yorg, slw;
+ register int x, y, e;
+ miFillArcRec info;
+ miArcSliceRec slice;
+ int xl, xr, xc;
+ int y_top, y_bot;
+
+ DRAW_DEBUG ((DEBUG_ARCS, "slice %dx%d+%d+%d %d->%d",
+ arc->width, arc->height, arc->x, arc->y,
+ arc->angle1, arc->angle2));
+ miFillArcSetup(arc, &info);
+ miFillArcSliceSetup(arc, &slice, pGC);
+ DRAW_DEBUG ((DEBUG_ARCS, "edge1.x %d edge2.x %d",
+ slice.edge1.x, slice.edge2.x));
+ MIFILLARCSETUP();
+ DRAW_DEBUG ((DEBUG_ARCS, "xorg %d yorg %d",
+ xorg, yorg));
+ xorg += pDraw->x;
+ yorg += pDraw->y;
+ y_top = yorg - y;
+ y_bot = yorg + y + dy;
+ slice.edge1.x += pDraw->x;
+ slice.edge2.x += pDraw->x;
+ DRAW_DEBUG ((DEBUG_ARCS, "xorg %d y_top %d y_bot %d",
+ xorg, y_top, y_bot));
+ while (y > 0)
+ {
+ y_top++;
+ y_bot--;
+ MIFILLARCSTEP(slw);
+ MIARCSLICESTEP(slice.edge1);
+ MIARCSLICESTEP(slice.edge2);
+ if (miFillSliceUpper(slice))
+ {
+ MIARCSLICEUPPER(xl, xr, slice, slw);
+ FILLSLICESPANS(slice.flip_top, y_top);
+ }
+ if (miFillSliceLower(slice))
+ {
+ MIARCSLICELOWER(xl, xr, slice, slw);
+ FILLSLICESPANS(slice.flip_bot, y_bot);
+ }
+ }
+}
+
+void
+s3PolyFillArcSolid (DrawablePtr pDraw, GCPtr pGC, int narcs, xArc *parcs)
+{
+ SetupS3(pDraw->pScreen);
+ xArc *arc;
+ int i;
+ int x, y;
+ BoxRec box;
+ RegionPtr pClip = fbGetCompositeClip(pGC);
+ BOOL set;
+
+ set = FALSE;
+ for (; --narcs >= 0; parcs++)
+ {
+ if (miFillArcEmpty(parcs))
+ continue;
+ if (miCanFillArc(parcs))
+ {
+ box.x1 = parcs->x + pDraw->x;
+ box.y1 = parcs->y + pDraw->y;
+ box.x2 = box.x1 + (int)parcs->width + 1;
+ box.y2 = box.y1 + (int)parcs->height + 1;
+ switch (RECT_IN_REGION(pDraw->pScreen, pClip, &box))
+ {
+ case rgnIN:
+ if (!set)
+ {
+ _s3SetSolidFill (s3, pGC->fgPixel, pGC->alu, pGC->planemask);
+ set = TRUE;
+ }
+ if ((parcs->angle2 >= FULLCIRCLE) ||
+ (parcs->angle2 <= -FULLCIRCLE))
+ {
+ DRAW_DEBUG ((DEBUG_ARCS, "Full circle ellipse %dx%d",
+ parcs->width, parcs->height));
+ _s3FillEllipse (pDraw, s3, parcs);
+ }
+ else
+ {
+ DRAW_DEBUG ((DEBUG_ARCS, "Partial ellipse %dx%d",
+ parcs->width, parcs->height));
+ _s3FillArcSlice (pDraw, pGC, s3, parcs);
+ }
+ /* fall through ... */
+ case rgnOUT:
+ continue;
+ case rgnPART:
+ break;
+ }
+ }
+ if (set)
+ {
+ MarkSyncS3 (pDraw->pScreen);
+ set = FALSE;
+ }
+ KdCheckPolyFillArc(pDraw, pGC, 1, parcs);
+ }
+ if (set)
+ {
+ MarkSyncS3 (pDraw->pScreen);
+ set = FALSE;
+ }
+}
+
+void
+s3FillPoly1Rect (DrawablePtr pDrawable, GCPtr pGC, int shape,
+ int mode, int countInit, DDXPointPtr ptsIn)
+{
+ SetupS3(pDrawable->pScreen);
+ FbGCPrivPtr fbPriv;
+ int nwidth;
+ int maxy;
+ int count;
+ register int vertex1, vertex2;
+ int c;
+ BoxPtr extents;
+ int y, sy;
+ int *vertex1p, *vertex2p;
+ int *endp;
+ int x1, x2, sx;
+ int dx1, dx2;
+ int dy1, dy2;
+ int e1, e2;
+ int step1, step2;
+ int sign1, sign2;
+ int h;
+ int l, r;
+ int nmiddle;
+
+ if (mode == CoordModePrevious)
+ {
+ KdCheckFillPolygon (pDrawable, pGC, shape, mode, countInit, ptsIn);
+ return;
+ }
+
+ fbPriv = fbGetGCPrivate(pGC);
+ sy = pDrawable->y;
+ sx = pDrawable->x;
+ extents = &fbGetCompositeClip(pGC)->extents;
+
+ y = 32767;
+ maxy = 0;
+ vertex2p = (int *) ptsIn;
+ endp = vertex2p + countInit;
+ if (shape == Convex)
+ {
+ count = countInit;
+ while (count--)
+ {
+ c = *vertex2p;
+ /*
+ * Check for negative or over S3 limits
+ */
+ if (c & 0xe000e000)
+ {
+ KdCheckFillPolygon (pDrawable, pGC, shape, mode, countInit, ptsIn);
+ return;
+ }
+ c = intToY(c);
+ DRAW_DEBUG ((DEBUG_POLYGON, "Y coordinate %d", c));
+ if (c < y)
+ {
+ y = c;
+ vertex1p = vertex2p;
+ }
+ vertex2p++;
+ if (c > maxy)
+ maxy = c;
+ }
+ }
+ else
+ {
+ int yFlip = 0;
+ dx1 = 1;
+ x2 = -1;
+ x1 = -1;
+ count = countInit;
+ while (count--)
+ {
+ c = *vertex2p;
+ /*
+ * Check for negative or over S3 limits
+ */
+ if (c & 0xe000e000)
+ {
+ KdCheckFillPolygon (pDrawable, pGC, shape, mode, countInit, ptsIn);
+ return;
+ }
+ c = intToY(c);
+ DRAW_DEBUG ((DEBUG_POLYGON, "Y coordinate %d", c));
+ if (c < y)
+ {
+ y = c;
+ vertex1p = vertex2p;
+ }
+ vertex2p++;
+ if (c > maxy)
+ maxy = c;
+ if (c == x1)
+ continue;
+ if (dx1 > 0)
+ {
+ if (x2 < 0)
+ x2 = c;
+ else
+ dx2 = dx1 = (c - x1) >> 31;
+ }
+ else
+ if ((c - x1) >> 31 != dx1)
+ {
+ dx1 = ~dx1;
+ yFlip++;
+ }
+ x1 = c;
+ }
+ x1 = (x2 - c) >> 31;
+ if (x1 != dx1)
+ yFlip++;
+ if (x1 != dx2)
+ yFlip++;
+ if (yFlip != 2)
+ {
+ KdCheckFillPolygon (pDrawable, pGC, shape, mode, countInit, ptsIn);
+ return;
+ }
+ }
+ if (y == maxy)
+ return;
+
+ _s3SetSolidFill(s3,pGC->fgPixel,pGC->alu,pGC->planemask);
+ _s3SetClip(s3,extents);
+
+ vertex2p = vertex1p;
+ vertex2 = vertex1 = *vertex2p++;
+ if (vertex2p == endp)
+ vertex2p = (int *) ptsIn;
+#define Setup(c,x,vertex,dx,dy,e,sign,step) {\
+ x = intToX(vertex); \
+ if (dy = intToY(c) - y) { \
+ dx = intToX(c) - x; \
+ step = 0; \
+ if (dx >= 0) \
+ { \
+ e = 0; \
+ sign = 1; \
+ if (dx >= dy) {\
+ step = dx / dy; \
+ dx = dx % dy; \
+ } \
+ } \
+ else \
+ { \
+ e = 1 - dy; \
+ sign = -1; \
+ dx = -dx; \
+ if (dx >= dy) { \
+ step = - (dx / dy); \
+ dx = dx % dy; \
+ } \
+ } \
+ } \
+ x += sx; \
+ vertex = c; \
+}
+
+#define Step(x,dx,dy,e,sign,step) {\
+ x += step; \
+ if ((e += dx) > 0) \
+ { \
+ x += sign; \
+ e -= dy; \
+ } \
+}
+ sy += y;
+ DRAW_DEBUG ((DEBUG_POLYGON, "Starting polygon at %d", sy));
+ for (;;)
+ {
+ DRAW_DEBUG ((DEBUG_POLYGON, "vertex1 0x%x vertex2 0x%x y %d vy1 %d vy2 %d",
+ vertex1, vertex2,
+ y, intToY(vertex1), intToY (vertex2)));
+ if (y == intToY(vertex1))
+ {
+ DRAW_DEBUG ((DEBUG_POLYGON, "Find next -- vertext"));
+ do
+ {
+ if (vertex1p == (int *) ptsIn)
+ vertex1p = endp;
+ c = *--vertex1p;
+ Setup (c,x1,vertex1,dx1,dy1,e1,sign1,step1);
+ DRAW_DEBUG ((DEBUG_POLYGON, "-- vertex 0x%x y %d",
+ vertex1, intToY(vertex1)));
+ } while (y >= intToY(vertex1));
+ h = dy1;
+ }
+ else
+ {
+ Step(x1,dx1,dy1,e1,sign1,step1)
+ h = intToY(vertex1) - y;
+ }
+ if (y == intToY(vertex2))
+ {
+ DRAW_DEBUG ((DEBUG_POLYGON, "Find next ++ vertext"));
+ do
+ {
+ c = *vertex2p++;
+ if (vertex2p == endp)
+ vertex2p = (int *) ptsIn;
+ Setup (c,x2,vertex2,dx2,dy2,e2,sign2,step2)
+ DRAW_DEBUG ((DEBUG_POLYGON, "++ vertex 0x%x y %d",
+ vertex1, intToY(vertex1)));
+ } while (y >= intToY(vertex2));
+ if (dy2 < h)
+ h = dy2;
+ }
+ else
+ {
+ Step(x2,dx2,dy2,e2,sign2,step2)
+ if ((c = (intToY(vertex2) - y)) < h)
+ h = c;
+ }
+ DRAW_DEBUG ((DEBUG_POLYGON, "This band %d", h));
+ /* fill spans for this segment */
+ for (;;)
+ {
+ nmiddle = x2 - x1;
+ DRAW_DEBUG ((DEBUG_POLYGON, "This span %d->%d", x1, x2));
+ if (nmiddle)
+ {
+ l = x1;
+ if (nmiddle < 0)
+ {
+ nmiddle = -nmiddle;
+ l = x2;
+ }
+ _s3SolidRect(s3,l,sy,nmiddle,1);
+ }
+ y++;
+ sy++;
+ if (!--h)
+ break;
+ Step(x1,dx1,dy1,e1,sign1,step1)
+ Step(x2,dx2,dy2,e2,sign2,step2)
+ }
+ if (y == maxy)
+ break;
+ }
+ _s3ResetClip (s3, pDrawable->pScreen);
+ MarkSyncS3 (pDrawable->pScreen);
+}
+
+void
+s3PolyGlyphBltClipped (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x, int y,
+ unsigned int nglyph,
+ CharInfoPtr *ppciInit,
+ pointer pglyphBase)
+{
+ SetupS3(pDrawable->pScreen);
+ int h;
+ int w;
+ int xBack, yBack;
+ int hBack, wBack;
+ int lw;
+ FontPtr pfont = pGC->font;
+ CharInfoPtr pci;
+ unsigned long *bits;
+ BoxPtr extents;
+ BoxRec bbox;
+ CARD32 b;
+ CharInfoPtr *ppci;
+ FbGCPrivPtr fbPriv = fbGetGCPrivate(pGC);
+ RegionPtr pClip = fbGetCompositeClip(pGC);
+ BoxPtr pBox;
+ int nbox;
+ int x1, y1, x2, y2;
+ unsigned char alu;
+ Bool set;
+ PixTransDeclare;
+
+ x += pDrawable->x;
+ y += pDrawable->y;
+
+ if (pglyphBase == (pointer) 1)
+ {
+ xBack = x;
+ yBack = y - FONTASCENT(pGC->font);
+ wBack = 0;
+ hBack = FONTASCENT(pGC->font) + FONTDESCENT(pGC->font);
+ if (hBack)
+ {
+ h = nglyph;
+ ppci = ppciInit;
+ while (h--)
+ wBack += (*ppci++)->metrics.characterWidth;
+ }
+ if (wBack < 0)
+ {
+ xBack = xBack + wBack;
+ wBack = -wBack;
+ }
+ if (hBack < 0)
+ {
+ yBack = yBack + hBack;
+ hBack = -hBack;
+ }
+ alu = GXcopy;
+ }
+ else
+ {
+ wBack = 0;
+ alu = pGC->alu;
+ }
+
+ if (wBack)
+ {
+ _s3SetSolidFill (s3, pGC->bgPixel, GXcopy, pGC->planemask);
+ for (nbox = REGION_NUM_RECTS (pClip),
+ pBox = REGION_RECTS (pClip);
+ nbox--;
+ pBox++)
+ {
+ x1 = xBack;
+ x2 = xBack + wBack;
+ y1 = yBack;
+ y2 = yBack + hBack;
+ if (x1 < pBox->x1) x1 = pBox->x1;
+ if (x2 > pBox->x2) x2 = pBox->x2;
+ if (y1 < pBox->y1) y1 = pBox->y1;
+ if (y2 > pBox->y2) y2 = pBox->y2;
+ if (x1 < x2 && y1 < y2)
+ {
+ _s3SolidRect (s3, x1, y1, x2 - x1, y2 - y1);
+ }
+ }
+ MarkSyncS3 (pDrawable->pScreen);
+ }
+ ppci = ppciInit;
+ set = FALSE;
+ while (nglyph--)
+ {
+ pci = *ppci++;
+ h = pci->metrics.ascent + pci->metrics.descent;
+ w = pci->metrics.rightSideBearing - pci->metrics.leftSideBearing;
+ x1 = x + pci->metrics.leftSideBearing;
+ y1 = y - pci->metrics.ascent;
+ bbox.x1 = x1;
+ bbox.y1 = y1;
+ bbox.x2 = x1 + w;
+ bbox.y2 = y1 + h;
+ switch (RECT_IN_REGION(pGC->pScreen, pClip, &bbox))
+ {
+ case rgnIN:
+#if 1
+ lw = h * ((w + 31) >> 5);
+ if (lw)
+ {
+ if (!set)
+ {
+ _s3SetTransparentPlaneBlt (s3, alu, pGC->planemask, pGC->fgPixel);
+ set = TRUE;
+ }
+ _s3PlaneBlt(s3,
+ x + pci->metrics.leftSideBearing,
+ y - pci->metrics.ascent,
+ w, h);
+ bits = (unsigned long *) pci->bits;
+ PixTransStart (lw);
+ while (lw--)
+ {
+ b = *bits++;
+ S3AdjustBits32 (b);
+ PixTransStore(b);
+ }
+ MarkSyncS3 (pDrawable->pScreen);
+ }
+ break;
+#endif
+ case rgnPART:
+ set = FALSE;
+ CheckSyncS3 (pDrawable->pScreen);
+ fbPutXYImage (pDrawable,
+ pClip,
+ fbPriv->fg,
+ fbPriv->bg,
+ fbPriv->pm,
+ alu,
+ FALSE,
+ x1, y1,
+ w, h,
+ (FbStip *) pci->bits,
+ (w + 31) >> 5,
+ 0);
+ break;
+ case rgnOUT:
+ break;
+ }
+ x += pci->metrics.characterWidth;
+ }
+}
+
+/*
+ * Blt glyphs using S3 image transfer register, this does both
+ * poly glyph blt and image glyph blt (when pglyphBase == 1)
+ */
+
+void
+s3PolyGlyphBlt (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x, int y,
+ unsigned int nglyph,
+ CharInfoPtr *ppciInit,
+ pointer pglyphBase)
+{
+ SetupS3(pDrawable->pScreen);
+ int h;
+ int w;
+ int xBack, yBack;
+ int hBack, wBack;
+ int lw;
+ FontPtr pfont = pGC->font;
+ CharInfoPtr pci;
+ unsigned long *bits;
+ BoxPtr extents;
+ BoxRec bbox;
+ CARD32 b;
+ CharInfoPtr *ppci;
+ unsigned char alu;
+ PixTransDeclare;
+
+ x += pDrawable->x;
+ y += pDrawable->y;
+
+ /* compute an approximate (but covering) bounding box */
+ ppci = ppciInit;
+ w = 0;
+ h = nglyph;
+ while (h--)
+ w += (*ppci++)->metrics.characterWidth;
+ if (w < 0)
+ {
+ bbox.x1 = x + w;
+ bbox.x2 = x;
+ }
+ else
+ {
+ bbox.x1 = x;
+ bbox.x2 = x + w;
+ }
+ w = FONTMINBOUNDS(pfont,leftSideBearing);
+ if (w < 0)
+ bbox.x1 += w;
+ w = FONTMAXBOUNDS(pfont, rightSideBearing) - FONTMINBOUNDS(pfont, characterWidth);
+ if (w > 0)
+ bbox.x2 += w;
+ bbox.y1 = y - FONTMAXBOUNDS(pfont,ascent);
+ bbox.y2 = y + FONTMAXBOUNDS(pfont,descent);
+
+ DRAW_DEBUG ((DEBUG_TEXT, "PolyGlyphBlt %d box is %d %d", nglyph,
+ bbox.x1, bbox.x2));
+ switch (RECT_IN_REGION(pGC->pScreen, fbGetCompositeClip(pGC), &bbox))
+ {
+ case rgnIN:
+ break;
+ case rgnPART:
+ s3PolyGlyphBltClipped(pDrawable, pGC, x - pDrawable->x,
+ y - pDrawable->y,
+ nglyph, ppciInit, pglyphBase);
+ case rgnOUT:
+ return;
+ }
+
+ if (pglyphBase == (pointer) 1)
+ {
+ xBack = x;
+ yBack = y - FONTASCENT(pGC->font);
+ wBack = 0;
+ hBack = FONTASCENT(pGC->font) + FONTDESCENT(pGC->font);
+ if (hBack)
+ {
+ h = nglyph;
+ ppci = ppciInit;
+ while (h--)
+ wBack += (*ppci++)->metrics.characterWidth;
+ }
+ if (wBack < 0)
+ {
+ xBack = xBack + wBack;
+ wBack = -wBack;
+ }
+ if (hBack < 0)
+ {
+ yBack = yBack + hBack;
+ hBack = -hBack;
+ }
+ alu = GXcopy;
+ }
+ else
+ {
+ wBack = 0;
+ alu = pGC->alu;
+ }
+
+ if (wBack)
+ {
+ _s3SetSolidFill (s3, pGC->bgPixel, GXcopy, pGC->planemask);
+ _s3SolidRect (s3, xBack, yBack, wBack, hBack);
+ }
+ _s3SetTransparentPlaneBlt (s3, alu, pGC->planemask, pGC->fgPixel);
+ ppci = ppciInit;
+ while (nglyph--)
+ {
+ pci = *ppci++;
+ h = pci->metrics.ascent + pci->metrics.descent;
+ w = pci->metrics.rightSideBearing - pci->metrics.leftSideBearing;
+ lw = h * ((w + 31) >> 5);
+ if (lw)
+ {
+ _s3PlaneBlt(s3,
+ x + pci->metrics.leftSideBearing,
+ y - pci->metrics.ascent,
+ w, h);
+ bits = (unsigned long *) pci->bits;
+ PixTransStart(lw);
+ while (lw--)
+ {
+ b = *bits++;
+ S3AdjustBits32 (b);
+ PixTransStore(b);
+ }
+ }
+ x += pci->metrics.characterWidth;
+ }
+ MarkSyncS3 (pDrawable->pScreen);
+}
+
+void
+s3ImageGlyphBlt (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x, int y,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase)
+{
+ s3PolyGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, (pointer) 1);
+}
+
+/*
+ * Blt TE fonts using S3 image transfer. Differs from
+ * above in that it doesn't need to fill a solid rect for
+ * the background and it can draw multiple characters at a time
+ */
+
+void
+s3ImageTEGlyphBlt (DrawablePtr pDrawable, GCPtr pGC,
+ int xInit, int yInit,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase)
+{
+ SetupS3(pDrawable->pScreen);
+ int x, y;
+ int h, lw, lwTmp;
+ int w;
+ FontPtr pfont = pGC->font;
+ unsigned long *char1, *char2, *char3, *char4;
+ int widthGlyphs, widthGlyph;
+ BoxRec bbox;
+ CARD32 tmp;
+ PixTransDeclare;
+
+ widthGlyph = FONTMAXBOUNDS(pfont,characterWidth);
+ if (!widthGlyph)
+ return;
+
+ h = FONTASCENT(pfont) + FONTDESCENT(pfont);
+ if (!h)
+ return;
+
+ DRAW_DEBUG ((DEBUG_TEXT, "ImageTEGlyphBlt chars are %d %d",
+ widthGlyph, h));
+
+ x = xInit + FONTMAXBOUNDS(pfont,leftSideBearing) + pDrawable->x;
+ y = yInit - FONTASCENT(pfont) + pDrawable->y;
+
+ bbox.x1 = x;
+ bbox.x2 = x + (widthGlyph * nglyph);
+ bbox.y1 = y;
+ bbox.y2 = y + h;
+
+ switch (RECT_IN_REGION(pGC->pScreen, fbGetCompositeClip(pGC), &bbox))
+ {
+ case rgnIN:
+ break;
+ case rgnPART:
+ if (pglyphBase == (pointer) 1)
+ pglyphBase = 0;
+ else
+ pglyphBase = (pointer) 1;
+ s3PolyGlyphBltClipped(pDrawable, pGC,
+ xInit,
+ yInit,
+ nglyph, ppci,
+ pglyphBase);
+ case rgnOUT:
+ return;
+ }
+
+ if (pglyphBase == (pointer) 1)
+ {
+ _s3SetTransparentPlaneBlt (s3, pGC->alu, pGC->planemask, pGC->fgPixel);
+ }
+ else
+ {
+ _s3SetOpaquePlaneBlt (s3, GXcopy, pGC->planemask, pGC->fgPixel, pGC->bgPixel);
+ }
+
+#if BITMAP_BIT_ORDER == LSBFirst
+#define SHIFT <<
+#else
+#define SHIFT >>
+#endif
+
+#define LoopIt(count, w, loadup, fetch) \
+ while (nglyph >= count) \
+ { \
+ nglyph -= count; \
+ _s3PlaneBlt (s3, x, y, w, h); \
+ x += w; \
+ loadup \
+ lwTmp = h; \
+ PixTransStart(h); \
+ while (lwTmp--) { \
+ tmp = fetch; \
+ S3AdjustBits32(tmp); \
+ PixTransStore(tmp); \
+ } \
+ }
+
+ if (widthGlyph <= 8)
+ {
+ widthGlyphs = widthGlyph << 2;
+ LoopIt(4, widthGlyphs,
+ char1 = (unsigned long *) (*ppci++)->bits;
+ char2 = (unsigned long *) (*ppci++)->bits;
+ char3 = (unsigned long *) (*ppci++)->bits;
+ char4 = (unsigned long *) (*ppci++)->bits;,
+ (*char1++ | ((*char2++ | ((*char3++ | (*char4++
+ SHIFT widthGlyph))
+ SHIFT widthGlyph))
+ SHIFT widthGlyph)))
+ }
+ else if (widthGlyph <= 10)
+ {
+ widthGlyphs = (widthGlyph << 1) + widthGlyph;
+ LoopIt(3, widthGlyphs,
+ char1 = (unsigned long *) (*ppci++)->bits;
+ char2 = (unsigned long *) (*ppci++)->bits;
+ char3 = (unsigned long *) (*ppci++)->bits;,
+ (*char1++ | ((*char2++ | (*char3++ SHIFT widthGlyph)) SHIFT widthGlyph)))
+ }
+ else if (widthGlyph <= 16)
+ {
+ widthGlyphs = widthGlyph << 1;
+ LoopIt(2, widthGlyphs,
+ char1 = (unsigned long *) (*ppci++)->bits;
+ char2 = (unsigned long *) (*ppci++)->bits;,
+ (*char1++ | (*char2++ SHIFT widthGlyph)))
+ }
+ lw = h * ((widthGlyph + 31) >> 5);
+ while (nglyph--)
+ {
+ _s3PlaneBlt (s3, x, y, widthGlyph, h);
+ x += widthGlyph;
+ char1 = (unsigned long *) (*ppci++)->bits;
+ lwTmp = lw;
+ PixTransStart(lw);
+ while (lwTmp--)
+ {
+ tmp = *char1++;
+ S3AdjustBits32(tmp);
+ PixTransStore(tmp);
+ }
+ }
+ MarkSyncS3 (pDrawable->pScreen);
+}
+
+void
+s3PolyTEGlyphBlt (DrawablePtr pDrawable, GCPtr pGC,
+ int x, int y,
+ unsigned int nglyph, CharInfoPtr *ppci,
+ pointer pglyphBase)
+{
+ s3ImageTEGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, (pointer) 1);
+}
+
+void
+_s3Segment (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x1,
+ int y1,
+ int x2,
+ int y2,
+ Bool drawLast)
+{
+ SetupS3(pDrawable->pScreen);
+ FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
+ RegionPtr pClip = fbGetCompositeClip(pGC);
+ BoxPtr pBox;
+ int nBox;
+ int adx; /* abs values of dx and dy */
+ int ady;
+ int signdx; /* sign of dx and dy */
+ int signdy;
+ int e, e1, e2; /* bresenham error and increments */
+ int len; /* length of segment */
+ int axis; /* major axis */
+ int octant;
+ int cmd;
+ unsigned int bias = miGetZeroLineBias(pDrawable->pScreen);
+ unsigned int oc1; /* outcode of point 1 */
+ unsigned int oc2; /* outcode of point 2 */
+
+ nBox = REGION_NUM_RECTS (pClip);
+ pBox = REGION_RECTS (pClip);
+ CalcLineDeltas(x1, y1, x2, y2, adx, ady, signdx, signdy,
+ 1, 1, octant);
+
+ cmd = LASTPIX;
+
+ if (signdx > 0)
+ cmd |= INC_X;
+ if (signdy > 0)
+ cmd |= INC_Y;
+
+ if (adx > ady)
+ {
+ axis = X_AXIS;
+ e1 = ady << 1;
+ e2 = e1 - (adx << 1);
+ e = e1 - adx;
+ len = adx;
+ }
+ else
+ {
+ cmd |= YMAJAXIS;
+ axis = Y_AXIS;
+ e1 = adx << 1;
+ e2 = e1 - (ady << 1);
+ e = e1 - ady;
+ SetYMajorOctant(octant);
+ len = ady;
+ }
+
+ FIXUP_ERROR (e, octant, bias);
+
+ /* we have bresenham parameters and two points.
+ all we have to do now is clip and draw.
+ */
+
+ if (drawLast)
+ len++;
+ while(nBox--)
+ {
+ oc1 = 0;
+ oc2 = 0;
+ OUTCODES(oc1, x1, y1, pBox);
+ OUTCODES(oc2, x2, y2, pBox);
+ if ((oc1 | oc2) == 0)
+ {
+ _s3SetCur (s3, x1, y1);
+ _s3ClipLine (s3, cmd, e1, e2, e, len);
+ break;
+ }
+ else if (oc1 & oc2)
+ {
+ pBox++;
+ }
+ else
+ {
+ int new_x1 = x1, new_y1 = y1, new_x2 = x2, new_y2 = y2;
+ int clip1 = 0, clip2 = 0;
+ int clipdx, clipdy;
+ int err;
+
+ if (miZeroClipLine(pBox->x1, pBox->y1, pBox->x2-1,
+ pBox->y2-1,
+ &new_x1, &new_y1, &new_x2, &new_y2,
+ adx, ady, &clip1, &clip2,
+ octant, bias, oc1, oc2) == -1)
+ {
+ pBox++;
+ continue;
+ }
+
+ if (axis == X_AXIS)
+ len = abs(new_x2 - new_x1);
+ else
+ len = abs(new_y2 - new_y1);
+ if (clip2 != 0 || drawLast)
+ len++;
+ if (len)
+ {
+ /* unwind bresenham error term to first point */
+ err = e;
+ if (clip1)
+ {
+ clipdx = abs(new_x1 - x1);
+ clipdy = abs(new_y1 - y1);
+ if (axis == X_AXIS)
+ err += (e2 - e1) * clipdy + e1 * clipdx;
+ else
+ err += (e2 - e1) * clipdx + e1 * clipdy;
+ }
+ _s3SetCur (s3, new_x1, new_y1);
+ _s3ClipLine (s3, cmd, e1, e2, err, len);
+ }
+ pBox++;
+ }
+ } /* while (nBox--) */
+}
+
+void
+s3Polylines (DrawablePtr pDrawable, GCPtr pGC,
+ int mode, int npt, DDXPointPtr ppt)
+{
+ SetupS3(pDrawable->pScreen);
+ int x, y, nx, ny;
+ int ox = pDrawable->x, oy = pDrawable->y;
+
+ if (!npt)
+ return;
+
+ _s3SetSolidFill (s3, pGC->fgPixel, pGC->alu, pGC->planemask);
+ x = ppt->x + ox;
+ y = ppt->y + oy;
+ while (--npt)
+ {
+ ++ppt;
+ if (mode == CoordModePrevious)
+ {
+ nx = x + ppt->x;
+ ny = y + ppt->y;
+ }
+ else
+ {
+ nx = ppt->x + ox;
+ ny = ppt->y + oy;
+ }
+ _s3Segment (pDrawable, pGC, x, y, nx, ny,
+ npt == 1 && pGC->capStyle != CapNotLast);
+ x = nx;
+ y = ny;
+ }
+ MarkSyncS3 (pDrawable->pScreen);
+}
+
+void
+s3PolySegment (DrawablePtr pDrawable, GCPtr pGC,
+ int nsegInit, xSegment *pSegInit)
+{
+ SetupS3(pDrawable->pScreen);
+ int x, y;
+ int ox = pDrawable->x, oy = pDrawable->y;
+ RegionPtr pClip = fbGetCompositeClip (pGC);
+ BoxPtr pBox;
+ int nbox;
+ int nseg;
+ xSegment *pSeg;
+ int dx, dy;
+ int maj, min, len, inc;
+ int t;
+ CARD32 cmd;
+ CARD32 init_cmd;
+ Bool drawLast;
+
+ drawLast = pGC->capStyle != CapNotLast;
+ _s3SetSolidFill (s3, pGC->fgPixel, pGC->alu, pGC->planemask);
+
+ for (nseg = nsegInit, pSeg = pSegInit; nseg--; pSeg++)
+ {
+ _s3Segment (pDrawable, pGC, pSeg->x1 + ox, pSeg->y1 + oy,
+ pSeg->x2 + ox, pSeg->y2 + oy, drawLast);
+
+ }
+ MarkSyncS3 (pDrawable->pScreen);
+}
+
+/*
+ * Check to see if a pattern can be painted with the S3
+ */
+
+#define _s3CheckPatternSize(s) ((s) <= S3_TILE_SIZE && ((s) & ((s) - 1)) == 0)
+#define s3CheckPattern(w,h) (_s3CheckPatternSize(w) && _s3CheckPatternSize(h))
+
+Bool
+s3AllocPattern (ScreenPtr pScreen,
+ PixmapPtr pPixmap,
+ int xorg, int yorg,
+ int fillStyle, Pixel fg, Pixel bg,
+ s3PatternPtr *ppPattern)
+{
+ KdScreenPriv(pScreen);
+ s3ScreenInfo(pScreenPriv);
+ s3PatternPtr pPattern;
+
+ if (s3s->patterns.cache && fillStyle != FillSolid &&
+ s3CheckPattern (pPixmap->drawable.width, pPixmap->drawable.height))
+ {
+ if (!(pPattern = *ppPattern))
+ {
+ pPattern = (s3PatternPtr) xalloc (sizeof (s3PatternRec));
+ if (!pPattern)
+ return FALSE;
+ *ppPattern = pPattern;
+ }
+
+ pPattern->cache = 0;
+ pPattern->id = 0;
+ pPattern->pPixmap = pPixmap;
+ pPattern->fillStyle = fillStyle;
+ pPattern->xrot = (-xorg) & (S3_TILE_SIZE-1);
+ pPattern->yrot = (-yorg) & (S3_TILE_SIZE-1);
+ pPattern->fore = fg;
+ pPattern->back = bg;
+ return TRUE;
+ }
+ else
+ {
+ if (*ppPattern)
+ {
+ xfree (*ppPattern);
+ *ppPattern = 0;
+ }
+ return FALSE;
+ }
+}
+
+void
+s3CheckGCFill (GCPtr pGC)
+{
+ s3PrivGCPtr s3Priv = s3GetGCPrivate (pGC);
+ PixmapPtr pPixmap;
+
+ switch (pGC->fillStyle) {
+ case FillSolid:
+ pPixmap = 0;
+ break;
+ case FillOpaqueStippled:
+ case FillStippled:
+ pPixmap = pGC->stipple;
+ break;
+ case FillTiled:
+ pPixmap = pGC->tile.pixmap;
+ break;
+ }
+ s3AllocPattern (pGC->pScreen,
+ pPixmap,
+ pGC->patOrg.x + pGC->lastWinOrg.x,
+ pGC->patOrg.y + pGC->lastWinOrg.y,
+ pGC->fillStyle, pGC->fgPixel, pGC->bgPixel,
+ &s3Priv->pPattern);
+}
+
+void
+s3MoveGCFill (GCPtr pGC)
+{
+ s3PrivGCPtr s3Priv = s3GetGCPrivate (pGC);
+ int xorg, yorg;
+ s3PatternPtr pPattern;
+
+ if (pPattern = s3Priv->pPattern)
+ {
+ /*
+ * Reset origin
+ */
+ xorg = pGC->patOrg.x + pGC->lastWinOrg.x;
+ yorg = pGC->patOrg.y + pGC->lastWinOrg.y;
+ pPattern->xrot = (-xorg) & (S3_TILE_SIZE - 1);
+ pPattern->yrot = (-yorg) & (S3_TILE_SIZE - 1);
+ /*
+ * Invalidate cache entry
+ */
+ pPattern->id = 0;
+ pPattern->cache = 0;
+ }
+}
+
+/*
+ * S3 Patterns. These are always full-depth images, stored in off-screen
+ * memory.
+ */
+
+Pixel
+s3FetchPatternPixel (s3PatternPtr pPattern, int x, int y)
+{
+ CARD8 *src;
+ CARD16 *src16;
+ CARD32 *src32;
+ PixmapPtr pPixmap = pPattern->pPixmap;
+
+ x = (x + pPattern->xrot) % pPixmap->drawable.width;
+ y = (y + pPattern->yrot) % pPixmap->drawable.height;
+ src = (CARD8 *) pPixmap->devPrivate.ptr + y * pPixmap->devKind;
+ switch (pPixmap->drawable.bitsPerPixel) {
+ case 1:
+ return (src[x>>3] >> (x & 7)) & 1 ? 0xffffffff : 0x00;
+ case 4:
+ if (x & 1)
+ return src[x>>1] >> 4;
+ else
+ return src[x>>1] & 0xf;
+ case 8:
+ return src[x];
+ case 16:
+ src16 = (CARD16 *) src;
+ return src16[x];
+ case 32:
+ src32 = (CARD32 *) src;
+ return src32[x];
+ }
+}
+
+/*
+ * Place pattern image on screen; done with S3 locked
+ */
+void
+_s3PutPattern (ScreenPtr pScreen, s3PatternPtr pPattern)
+{
+ SetupS3(pScreen);
+ int x, y;
+ CARD8 *dstLine, *dst8;
+ CARD16 *dst16;
+ CARD32 *dst32;
+ S3PatternCache *cache = pPattern->cache;
+
+ DRAW_DEBUG ((DEBUG_PATTERN, "_s3PutPattern 0x%x id %d to %d %d",
+ pPattern, pPattern->id, cache->x, cache->y));
+
+ dstLine = (pScreenPriv->screen->frameBuffer +
+ cache->y * pScreenPriv->screen->byteStride +
+ cache->x * pScreenPriv->bytesPerPixel);
+
+ CheckSyncS3 (pScreen);
+
+ for (y = 0; y < S3_TILE_SIZE; y++)
+ {
+ switch (pScreenPriv->screen->bitsPerPixel) {
+ case 8:
+ dst8 = dstLine;
+ for (x = 0; x < S3_TILE_SIZE; x++)
+ *dst8++ = s3FetchPatternPixel (pPattern, x, y);
+ DRAW_DEBUG ((DEBUG_PATTERN, "%c%c%c%c%c%c%c%c",
+ dstLine[0] ? 'X' : ' ',
+ dstLine[1] ? 'X' : ' ',
+ dstLine[2] ? 'X' : ' ',
+ dstLine[3] ? 'X' : ' ',
+ dstLine[4] ? 'X' : ' ',
+ dstLine[5] ? 'X' : ' ',
+ dstLine[6] ? 'X' : ' ',
+ dstLine[7] ? 'X' : ' '));
+ break;
+ case 16:
+ dst16 = (CARD16 *) dstLine;
+ for (x = 0; x < S3_TILE_SIZE; x++)
+ *dst16++ = s3FetchPatternPixel (pPattern, x, y);
+ break;
+ case 32:
+ dst32 = (CARD32 *) dstLine;
+ for (x = 0; x < S3_TILE_SIZE; x++)
+ *dst32++ = s3FetchPatternPixel (pPattern, x, y);
+ break;
+ }
+ dstLine += pScreenPriv->screen->byteStride;
+ }
+}
+
+/*
+ * Load a stipple to off-screen memory; done with S3 locked
+ */
+void
+_s3LoadPattern (ScreenPtr pScreen, s3PatternPtr pPattern)
+{
+ SetupS3(pScreen);
+ s3ScreenInfo(pScreenPriv);
+ S3PatternCache *cache;
+
+ DRAW_DEBUG((DEBUG_PATTERN,
+ "s3LoadPattern 0x%x id %d cache 0x%x cacheid %d",
+ pPattern, pPattern->id, pPattern->cache,
+ pPattern->cache ? pPattern->cache->id : -1));
+ /*
+ * Check to see if its still loaded
+ */
+ cache = pPattern->cache;
+ if (cache && cache->id == pPattern->id)
+ return;
+ /*
+ * Lame replacement strategy; assume we'll have plenty of room.
+ */
+ cache = &s3s->patterns.cache[s3s->patterns.last_used];
+ if (++s3s->patterns.last_used == s3s->patterns.ncache)
+ s3s->patterns.last_used = 0;
+ cache->id = ++s3s->patterns.last_id;
+ pPattern->id = cache->id;
+ pPattern->cache = cache;
+ _s3PutPattern (pScreen, pPattern);
+}
+
+void
+s3DestroyGC (GCPtr pGC)
+{
+ s3PrivGCPtr s3Priv = s3GetGCPrivate (pGC);
+
+ if (s3Priv->pPattern)
+ xfree (s3Priv->pPattern);
+ miDestroyGC (pGC);
+}
+
+GCFuncs s3GCFuncs = {
+ s3ValidateGC,
+ miChangeGC,
+ miCopyGC,
+ s3DestroyGC,
+ miChangeClip,
+ miDestroyClip,
+ miCopyClip
+};
+
+int
+s3CreateGC (GCPtr pGC)
+{
+ s3PrivGCPtr s3Priv;
+
+ if (!fbCreateGC (pGC))
+ return FALSE;
+
+ if (pGC->depth != 1)
+ pGC->funcs = &s3GCFuncs;
+
+ s3Priv = s3GetGCPrivate(pGC);
+ s3Priv->type = DRAWABLE_PIXMAP;
+ s3Priv->pPattern = 0;
+
+ return TRUE;
+}
+
+Bool
+s3CreateWindow (WindowPtr pWin)
+{
+ if (!KdCreateWindow (pWin))
+ return FALSE;
+ pWin->devPrivates[s3WindowPrivateIndex].ptr = 0;
+ return TRUE;
+}
+
+Bool
+s3DestroyWindow (WindowPtr pWin)
+{
+ s3PatternPtr pPattern;
+ if (pPattern = s3GetWindowPrivate(pWin))
+ xfree (pPattern);
+ return fbDestroyWindow (pWin);
+}
+
+Bool
+s3ChangeWindowAttributes (WindowPtr pWin, Mask mask)
+{
+ Bool ret;
+ s3PatternPtr pPattern;
+ PixmapPtr pPixmap;
+ int fillStyle;
+
+ ret = fbChangeWindowAttributes (pWin, mask);
+ if (mask & CWBackPixmap)
+ {
+ if (pWin->backgroundState == BackgroundPixmap)
+ {
+ pPixmap = pWin->background.pixmap;
+ fillStyle = FillTiled;
+ }
+ else
+ {
+ pPixmap = 0;
+ fillStyle = FillSolid;
+ }
+ pPattern = s3GetWindowPrivate(pWin);
+ s3AllocPattern (pWin->drawable.pScreen, pPixmap,
+ pWin->drawable.x, pWin->drawable.y,
+ fillStyle, 0, 0, &pPattern);
+ DRAW_DEBUG ((DEBUG_PAINT_WINDOW, "Background pattern 0x%x pixmap 0x%x style %d",
+ pPattern, pPixmap, fillStyle));
+ s3SetWindowPrivate (pWin, pPattern);
+ }
+ return ret;
+}
+
+void
+s3PaintWindow(WindowPtr pWin, RegionPtr pRegion, int what)
+{
+ SetupS3(pWin->drawable.pScreen);
+ s3PatternPtr pPattern;
+
+ DRAW_DEBUG ((DEBUG_PAINT_WINDOW, "s3PaintWindow 0x%x extents %d %d %d %d n %d",
+ pWin->drawable.id,
+ pRegion->extents.x1, pRegion->extents.y1,
+ pRegion->extents.x2, pRegion->extents.y2,
+ REGION_NUM_RECTS(pRegion)));
+ if (!REGION_NUM_RECTS(pRegion))
+ return;
+ switch (what) {
+ case PW_BACKGROUND:
+ switch (pWin->backgroundState) {
+ case None:
+ return;
+ case ParentRelative:
+ do {
+ pWin = pWin->parent;
+ } while (pWin->backgroundState == ParentRelative);
+ (*pWin->drawable.pScreen->PaintWindowBackground)(pWin, pRegion,
+ what);
+ return;
+ case BackgroundPixmap:
+ pPattern = s3GetWindowPrivate(pWin);
+ if (pPattern)
+ {
+ s3FillBoxPattern ((DrawablePtr)pWin,
+ (int)REGION_NUM_RECTS(pRegion),
+ REGION_RECTS(pRegion),
+ GXcopy, ~0, pPattern);
+ return;
+ }
+ break;
+ case BackgroundPixel:
+ s3FillBoxSolid((DrawablePtr)pWin,
+ (int)REGION_NUM_RECTS(pRegion),
+ REGION_RECTS(pRegion),
+ pWin->background.pixel, GXcopy, ~0);
+ return;
+ }
+ break;
+ case PW_BORDER:
+ if (pWin->borderIsPixel)
+ {
+ s3FillBoxSolid((DrawablePtr)pWin,
+ (int)REGION_NUM_RECTS(pRegion),
+ REGION_RECTS(pRegion),
+ pWin->border.pixel, GXcopy, ~0);
+ return;
+ }
+ break;
+ }
+ KdCheckPaintWindow (pWin, pRegion, what);
+}
+
+void
+s3CopyWindowProc (DrawablePtr pSrcDrawable,
+ DrawablePtr pDstDrawable,
+ GCPtr pGC,
+ BoxPtr pbox,
+ int nbox,
+ int dx,
+ int dy,
+ Bool reverse,
+ Bool upsidedown,
+ Pixel bitplane,
+ void *closure)
+{
+ SetupS3(pDstDrawable->pScreen);
+ int srcX, srcY, dstX, dstY;
+ int w, h;
+ int flags;
+
+ _s3SetBlt(s3,GXcopy,~0);
+ while (nbox--)
+ {
+ w = pbox->x2 - pbox->x1;
+ h = pbox->y2 - pbox->y1;
+ flags = 0;
+ if (reverse)
+ {
+ dstX = pbox->x2 - 1;
+ }
+ else
+ {
+ dstX = pbox->x1;
+ flags |= INC_X;
+ }
+ srcX = dstX + dx;
+
+ if (upsidedown)
+ {
+ dstY = pbox->y2 - 1;
+ }
+ else
+ {
+ dstY = pbox->y1;
+ flags |= INC_Y;
+ }
+ srcY = dstY + dy;
+
+ _s3Blt (s3, srcX, srcY, dstX, dstY, w, h, flags);
+ pbox++;
+ }
+ MarkSyncS3 (pDstDrawable->pScreen);
+}
+
+void
+s3CopyWindow(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, s3CopyWindowProc, 0, 0);
+
+ REGION_UNINIT(pWin->drawable.pScreen, &rgnDst);
+}
+
+Bool
+s3DrawInit (ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ s3ScreenInfo(pScreenPriv);
+ int ncache_w, ncache_h, ncache;
+ int px, py;
+ S3PatternCache *cache;
+
+ switch (pScreenPriv->screen->bitsPerPixel) {
+ case 8:
+ case 16:
+ case 32:
+ break;
+ default:
+ return FALSE;
+ }
+ if (serverGeneration != s3Generation)
+ {
+ s3GCPrivateIndex = AllocateGCPrivateIndex ();
+ s3WindowPrivateIndex = AllocateWindowPrivateIndex ();
+ s3Generation = serverGeneration;
+ }
+ if (!AllocateWindowPrivate(pScreen, s3WindowPrivateIndex, 0))
+ return FALSE;
+ if (!AllocateGCPrivate(pScreen, s3GCPrivateIndex, sizeof (s3PrivGCRec)))
+ return FALSE;
+ /*
+ * Hook up asynchronous drawing
+ */
+ RegisterSync (pScreen);
+ /*
+ * Replace various fb screen functions
+ */
+ pScreen->CreateGC = s3CreateGC;
+ pScreen->CreateWindow = s3CreateWindow;
+ pScreen->ChangeWindowAttributes = s3ChangeWindowAttributes;
+ pScreen->DestroyWindow = s3DestroyWindow;
+ pScreen->PaintWindowBackground = s3PaintWindow;
+ pScreen->PaintWindowBorder = s3PaintWindow;
+ pScreen->CopyWindow = s3CopyWindow;
+
+ /*
+ * Initialize patterns
+ */
+ ncache_w = s3s->offscreen_width / S3_TILE_SIZE;
+ ncache_h = s3s->offscreen_height / S3_TILE_SIZE;
+ ncache = ncache_w * ncache_h;
+ DRAW_DEBUG ((DEBUG_S3INIT, "ncache_w %d ncache_h %d ncache %d",
+ ncache_w, ncache_h, ncache));
+ s3s->patterns.cache = (S3PatternCache *) xalloc (ncache * sizeof (S3PatternCache));
+ if (s3s->patterns.cache)
+ {
+ DRAW_DEBUG ((DEBUG_S3INIT, "Have pattern cache"));
+ s3s->patterns.ncache = ncache;
+ s3s->patterns.last_used = 0;
+ s3s->patterns.last_id = 0;
+ cache = s3s->patterns.cache;
+ for (py = 0; py < ncache_h; py++)
+ for (px = 0; px < ncache_w; px++)
+ {
+ cache->id = 0;
+ cache->x = s3s->offscreen_x + px * S3_TILE_SIZE;
+ cache->y = s3s->offscreen_y + py * S3_TILE_SIZE;
+ cache++;
+ }
+ }
+ return TRUE;
+}
+
+void
+s3DrawEnable (ScreenPtr pScreen)
+{
+ SetupS3(pScreen);
+ s3ScreenInfo(pScreenPriv);
+ int c;
+
+ /*
+ * Flush pattern cache
+ */
+ for (c = 0; c < s3s->patterns.ncache; c++)
+ s3s->patterns.cache[c].id = 0;
+
+ _s3WaitIdleEmpty (s3);
+ _s3SetScissorsTl(s3, 0, 0);
+ _s3SetScissorsBr(s3, pScreenPriv->screen->width - 1, pScreenPriv->screen->height - 1);
+ _s3SetSolidFill(s3, pScreen->blackPixel, GXcopy, ~0);
+ _s3SolidRect (s3, 0, 0, pScreenPriv->screen->width, pScreenPriv->screen->height);
+ MarkSyncS3 (pScreen);
+}
+
+void
+s3DrawDisable (ScreenPtr pScreen)
+{
+ SetupS3 (pScreen);
+ _s3WaitIdleEmpty (s3);
+}
+
+void
+s3DrawFini (ScreenPtr pScreen)
+{
+ SetupS3(pScreen);
+ s3ScreenInfo(pScreenPriv);
+
+ if (s3s->patterns.cache)
+ {
+ xfree (s3s->patterns.cache);
+ s3s->patterns.cache = 0;
+ s3s->patterns.ncache = 0;
+ }
+}
+
+void
+s3DrawSync (ScreenPtr pScreen)
+{
+ SetupS3(pScreen);
+
+ _s3WaitIdleEmpty(s3c->s3);
+}
diff --git a/xc/programs/Xserver/hw/kdrive/savage/s3draw.h b/xc/programs/Xserver/hw/kdrive/savage/s3draw.h
new file mode 100644
index 000000000..d9c2972ec
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/savage/s3draw.h
@@ -0,0 +1,459 @@
+/*
+ * $Id: s3draw.h,v 1.1 2000/01/06 12:55:51 faith 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/savage/s3draw.h,v 1.2 1999/12/30 03:03:12 robin Exp $ */
+
+#ifndef _S3DRAW_H_
+#define _S3DRAW_H_
+
+extern int s3GCPrivateIndex;
+extern int s3WindowPrivateIndex;
+
+typedef struct _s3Pattern {
+ S3PatternCache *cache;
+ int id;
+ PixmapPtr pPixmap;
+ int fillStyle;
+ int xrot, yrot;
+ unsigned int fore, back;
+} s3PatternRec, *s3PatternPtr;
+
+typedef struct _s3PrivGC {
+ int type; /* type of drawable validated against */
+ s3PatternPtr pPattern; /* pattern */
+} s3PrivGCRec, *s3PrivGCPtr;
+
+#define s3GetGCPrivate(g) ((s3PrivGCPtr) \
+ (g)->devPrivates[s3GCPrivateIndex].ptr)
+
+#define s3GCPrivate(g) s3PrivGCPtr s3Priv = s3GetGCPrivate(g)
+
+#define s3GetWindowPrivate(w) ((s3PatternPtr) \
+ (w)->devPrivates[s3WindowPrivateIndex].ptr)
+
+#define s3SetWindowPrivate(w,p) (\
+ (w)->devPrivates[s3WindowPrivateIndex].ptr = (pointer) p)
+
+
+void _s3LoadPattern (ScreenPtr pScreen, s3PatternPtr pPattern);
+
+#define SetupS3(s) KdScreenPriv(s); \
+ s3CardInfo(pScreenPriv); \
+ S3Ptr s3 = s3c->s3
+
+#ifdef S3_SYNC_DEBUG
+#define SYNC_DEBUG() fprintf (stderr, "Sync at %s:%d\n", __FILE__,__LINE__)
+#else
+#define SYNC_DEBUG()
+#endif
+
+#define S3_ASYNC
+#ifdef S3_ASYNC
+#define CheckSyncS3(s) KdCheckSync(s)
+#define MarkSyncS3(s) KdMarkSync(s)
+#define RegisterSync(screen) KdScreenInitAsync (screen)
+#else
+#define CheckSyncS3(s3c)
+#define MarkSyncS3(s3c) _s3WaitIdleEmpty(s3c->s3)
+#define RegisterSync(screen)
+#endif
+
+#define WIDEN(x) ((unsigned long) (x))
+#define MERGE(a,b) ((WIDEN(a) << 16) | WIDEN(b))
+
+/*
+ * Ok, so the S3 is broken -- it expects bitmaps to come MSB bit order,
+ * but it's willing to take them in LSB byte order. These macros
+ * flip bits around without flipping bytes. Instead of using a table
+ * and burning memory bandwidth, do them in place with the CPU.
+ */
+
+/* The MIPS compiler automatically places these constants in registers */
+#define S3InvertBits32(v) { \
+ v = ((v & 0x55555555) << 1) | ((v >> 1) & 0x55555555); \
+ v = ((v & 0x33333333) << 2) | ((v >> 2) & 0x33333333); \
+ v = ((v & 0x0f0f0f0f) << 4) | ((v >> 4) & 0x0f0f0f0f); \
+}
+
+#define S3InvertBits16(v) { \
+ v = ((v & 0x5555) << 1) | ((v >> 1) & 0x5555); \
+ v = ((v & 0x3333) << 2) | ((v >> 2) & 0x3333); \
+ v = ((v & 0x0f0f) << 4) | ((v >> 4) & 0x0f0f); \
+}
+
+#define S3InvertBits8(v) { \
+ v = ((v & 0x55) << 1) | ((v >> 1) & 0x55); \
+ v = ((v & 0x33) << 2) | ((v >> 2) & 0x33); \
+ v = ((v & 0x0f) << 4) | ((v >> 4) & 0x0f); \
+}
+
+#define S3ByteSwap32(x) ((x) = (((x) >> 24) | \
+ (((x) >> 8) & 0xff00) | \
+ (((x) << 8) & 0xff0000) | \
+ ((x) << 24)))
+
+#define S3ByteSwap16(x) ((x) = ((x) << 8) | ((x) >> 8))
+
+#if BITMAP_BIT_ORDER == LSBFirst
+#define S3AdjustBits32(x) S3InvertBits32(x)
+#define S3AdjustBits16(x) S3InvertBits16(x)
+#else
+#define S3AdjustBits32(x) S3ByteSwap32(x)
+#define S3AdjustBits16(x) S3ByteSwap16(x)
+#endif
+
+#define _s3WaitSlot(s3) _s3WaitSlots(s3,1)
+
+#define _s3SetFg(s3,_fg) { \
+ DRAW_DEBUG ((DEBUG_REGISTERS, " fg <- 0x%x", _fg));\
+ s3->fg = (_fg); \
+}
+
+#define _s3SetBg(s3,_bg) { \
+ DRAW_DEBUG ((DEBUG_REGISTERS, " bg <- 0x%x", _bg));\
+ s3->bg = (_bg); \
+}
+
+#define _s3SetWriteMask(s3,_mask) {\
+ DRAW_DEBUG((DEBUG_REGISTERS," write_mask <- 0x%x", _mask)); \
+ s3->write_mask = (_mask); \
+}
+
+#define _s3SetReadMask(s3,_mask) {\
+ DRAW_DEBUG((DEBUG_REGISTERS," read_mask <- 0x%x", _mask)); \
+ s3->read_mask = (_mask); \
+}
+
+#define _s3SetPixelControl(s3,_ctl) { \
+ DRAW_DEBUG((DEBUG_REGISTERS, " pix_cntl <- 0x%x", PIX_CNTL | (_ctl))); \
+ s3->pix_cntl_mult_misc2 = MERGE (CONTROL_MISC2, PIX_CNTL | (_ctl)); \
+}
+
+#define _s3SetFgMix(s3,_mix) { \
+ DRAW_DEBUG((DEBUG_REGISTERS, " fg_mix <- 0x%x", _mix)); \
+ s3->enh_fg_mix = (_mix); \
+}
+
+#define _s3SetBgMix(s3,_mix) { \
+ DRAW_DEBUG((DEBUG_REGISTERS, " bg_mix <- 0x%x", _mix)); \
+ s3->enh_bg_mix = (_mix); \
+}
+
+#define _s3SetMix(s3,fg_mix,bg_mix) { \
+ DRAW_DEBUG((DEBUG_REGISTERS, " alt_mix <- 0x%x", MERGE(fg_mix,bg_mix))); \
+ s3->alt_mix = MERGE(fg_mix,bg_mix); \
+}
+
+#define _s3SetCur(s3,_x,_y) { \
+ DRAW_DEBUG ((DEBUG_REGISTERS, " alt_curxy <- 0x%x", MERGE(_x,_y))); \
+ s3->alt_curxy = MERGE(_x,_y); \
+}
+
+#define _s3SetStep(s3,_x,_y) { \
+ DRAW_DEBUG ((DEBUG_REGISTERS, " alt_step <- 0x%x", MERGE(_x,_y))); \
+ s3->alt_step = MERGE(_x,_y); \
+}
+
+#define _s3SetErr(s3,_e) { \
+ DRAW_DEBUG ((DEBUG_REGISTERS, " err_term <- 0x%x", _e)); \
+ s3->err_term = (_e); \
+}
+
+#define _s3SetPcnt(s3,_x,_y) { \
+ DRAW_DEBUG ((DEBUG_REGISTERS, " alt_pcnt <- 0x%x", MERGE(_x,_y))); \
+ s3->alt_pcnt = MERGE(_x,_y); \
+}
+
+#define _s3SetScissorsTl(s3,t,l) {\
+ DRAW_DEBUG ((DEBUG_REGISTERS, " scissors_tl <- 0x%x", MERGE(t,l))); \
+ s3->scissors_tl = MERGE(t,l); \
+}
+
+#define _s3SetScissorsBr(s3,b,r) {\
+ DRAW_DEBUG ((DEBUG_REGISTERS, " scissors_br <- 0x%x", MERGE(b,r))); \
+ s3->scissors_br = MERGE(b,r); \
+}
+
+#define _s3CmdWait(s3)
+
+#define _s3SetCmd(s3,_cmd) { \
+ DRAW_DEBUG((DEBUG_REGISTERS, " cmd <- 0x%x", _cmd)); \
+ _s3CmdWait(s3); \
+ s3->cmd_gp_stat = (_cmd); \
+ /* { CARD32 __junk__; __junk__ = s3->cmd_gp_stat; } */ \
+}
+
+#define _s3SetSolidFill(s3,pix,alu,mask) { \
+ DRAW_DEBUG((DEBUG_SET,"set fill 0x%x %d 0x%x",pix,alu,mask)); \
+ _s3WaitSlots(s3,4); \
+ _s3SetFg (s3, pix); \
+ _s3SetWriteMask(s3,mask); \
+ _s3SetMix (s3, FSS_FRGDCOL | s3alu[alu], BSS_BKGDCOL | MIX_SRC); \
+ _s3SetPixelControl (s3, MIXSEL_FRGDMIX); \
+ DRAW_DEBUG((DEBUG_SET," done")); \
+}
+
+#define _s3SolidRect(s3,x,y,w,h) {\
+ DRAW_DEBUG((DEBUG_RENDER,"solid rect %d,%d %dx%d",x,y,w,h)); \
+ _s3WaitSlots(s3,3); \
+ _s3SetCur(s3, x, y); \
+ _s3SetPcnt (s3, (w)-1, (h)-1); \
+ _s3SetCmd (s3, CMD_RECT|INC_X|INC_Y|DRAW|WRTDATA); \
+ DRAW_DEBUG((DEBUG_RENDER," done")); \
+}
+
+#define _s3SolidLine(s3,maj,min,len,cmd) { \
+ DRAW_DEBUG ((DEBUG_RENDER, "solid line 0x%x 0x%x 0x%x", maj, min, cmd)); \
+ _s3WaitSlots(s3,4); \
+ _s3SetPcnt(s3, (len), 0); \
+ _s3SetStep(s3, 2*((min) - (maj)), 2*(min)); \
+ _s3SetErr(s3, 2*(min) - (maj)); \
+ _s3SetCmd (s3, CMD_LINE | (cmd) | DRAW | WRTDATA); \
+}
+
+#define _s3ClipLine(s3,cmd,e1,e2,e,len) {\
+ DRAW_DEBUG ((DEBUG_RENDER, "clip line 0x%x 0x%x 0x%x 0x%x 0x%x", cmd,e1,e2,e,len)); \
+ _s3WaitSlots(s3, 4); \
+ _s3SetPcnt (s3, (len), 0); \
+ _s3SetStep (s3, e2, e1); \
+ _s3SetErr (s3, e); \
+ _s3SetCmd (s3, CMD_LINE | (cmd) | DRAW | WRTDATA); \
+}
+
+#define _s3SetTile(s3,alu,mask) { \
+ DRAW_DEBUG ((DEBUG_SET,"set tile %d 0x%x", alu, mask)); \
+ _s3WaitSlots(s3,3); \
+ _s3SetWriteMask(s3, mask); \
+ _s3SetMix(s3, FSS_BITBLT | s3alu[alu], BSS_BITBLT|s3alu[alu]); \
+ _s3SetPixelControl (s3, MIXSEL_FRGDMIX); \
+ DRAW_DEBUG((DEBUG_SET," done")); \
+}
+
+/*
+ * For some reason, MIX_DST doesn't work in this mode; use MIX_OR with
+ * an explicit 0 pixel value
+ */
+#define _s3SetStipple(s3,alu,mask,_fg) {\
+ DRAW_DEBUG ((DEBUG_SET,"set stipple 0x%x %d 0x%x", _fg, alu, mask)); \
+ _s3WaitSlots(s3,5); \
+ _s3SetFg (s3, _fg); \
+ _s3SetBg (s3, 0); \
+ _s3SetWriteMask(s3,mask); \
+ _s3SetMix (s3, FSS_FRGDCOL | s3alu[alu], BSS_BKGDCOL|MIX_OR); \
+ _s3SetPixelControl (s3, MIXSEL_EXPBLT); \
+ DRAW_DEBUG((DEBUG_SET," done")); \
+}
+
+#define _s3SetOpaqueStipple(s3,alu,mask,_fg,_bg) {\
+ DRAW_DEBUG ((DEBUG_SET,"set opaque stipple 0x%x 0x%x %d 0x%x", _fg, _bg, alu, mask)); \
+ _s3WaitSlots(s3,5); \
+ _s3SetFg (s3, _fg); \
+ _s3SetBg (s3, _bg); \
+ _s3SetWriteMask(s3,mask); \
+ _s3SetMix (s3, FSS_FRGDCOL | s3alu[alu], BSS_BKGDCOL|s3alu[alu]); \
+ _s3SetPixelControl (s3, MIXSEL_EXPBLT); \
+ DRAW_DEBUG((DEBUG_SET," done")); \
+}
+
+#define _s3PatRect(s3,px,py,x,y,w,h) {\
+ DRAW_DEBUG ((DEBUG_RENDER, "pat rect %d,%d %dx%d", x,y,w,h)); \
+ _s3WaitSlots(s3, 4); \
+ _s3SetCur (s3, px, py); \
+ _s3SetStep (s3, x, y); \
+ _s3SetPcnt (s3, (w)-1, (h)-1); \
+ _s3SetCmd (s3, CMD_PATBLT|INC_X|INC_Y|DRAW|PLANAR|WRTDATA); \
+ DRAW_DEBUG((DEBUG_RENDER," done")); \
+}
+
+#define _s3SetBlt(s3,alu,mask) { \
+ DRAW_DEBUG ((DEBUG_SET,"set blt %d 0x%x", alu, mask)); \
+ _s3WaitSlots(s3,3); \
+ _s3SetPixelControl (s3, MIXSEL_FRGDMIX); \
+ _s3SetMix(s3, FSS_BITBLT | s3alu[alu], BSS_BITBLT | s3alu[alu]); \
+ _s3SetWriteMask(s3, mask); \
+ DRAW_DEBUG((DEBUG_SET," done")); \
+}
+
+#define _s3Blt(s3,_sx,_sy,_dx,_dy,_w,_h,_dir) { \
+ DRAW_DEBUG ((DEBUG_RENDER, "blt %d,%d -> %d,%d %dx%d 0x%x", \
+ _sx,_sy,_dx,_dy,_w,_h,_dir)); \
+ _s3WaitSlots(s3,4); \
+ _s3SetCur(s3,_sx,_sy); \
+ _s3SetStep(s3,_dx,_dy); \
+ _s3SetPcnt(s3,(_w)-1,(_h)-1); \
+ _s3SetCmd (s3, CMD_BITBLT | (_dir) | DRAW | WRTDATA); \
+ DRAW_DEBUG((DEBUG_RENDER," done")); \
+}
+
+#define _s3SetOpaquePlaneBlt(s3,alu,mask,_fg,_bg) {\
+ DRAW_DEBUG ((DEBUG_SET,"set opaque plane blt 0x%x 0x%x %d 0x%x", \
+ _fg, _bg, alu, mask)); \
+ /* _s3WaitSlots(s3, 5); */ \
+ _s3WaitIdleEmpty (s3); \
+ _s3SetFg(s3,_fg); \
+ _s3SetBg(s3,_bg); \
+ _s3SetWriteMask(s3,mask); \
+ _s3SetMix(s3,FSS_FRGDCOL|s3alu[alu], BSS_BKGDCOL|s3alu[alu]); \
+ _s3SetPixelControl(s3,MIXSEL_EXPPC); \
+ DRAW_DEBUG((DEBUG_SET," done")); \
+}
+
+#define _s3SetTransparentPlaneBlt(s3,alu,mask,_fg) {\
+ DRAW_DEBUG ((DEBUG_SET,"set transparent plane blt 0x%x %d 0x%x", \
+ _fg, alu, mask)); \
+ /*_s3WaitSlots(s3, 4); */ \
+ _s3WaitIdleEmpty (s3); \
+ _s3SetFg(s3,_fg); \
+ _s3SetWriteMask(s3,mask); \
+ _s3SetMix(s3,FSS_FRGDCOL|s3alu[alu], BSS_BKGDCOL|MIX_DST); \
+ _s3SetPixelControl(s3,MIXSEL_EXPPC); \
+ DRAW_DEBUG((DEBUG_SET," done")); \
+}
+
+/* Across the plane blt */
+#define _s3PlaneBlt(s3,x,y,w,h) {\
+ DRAW_DEBUG ((DEBUG_RENDER, "plane blt %d,%d %dx%d", x,y,w,h)); \
+ _s3WaitSlots(s3, 4); \
+ _s3SetPixelControl(s3,MIXSEL_EXPPC); \
+ _s3SetCur(s3, x, y); \
+ _s3SetPcnt (s3, (w)-1, (h)-1); \
+ _s3SetCmd (s3, \
+ CMD_RECT| /* Fill rectangle */ \
+ BYTSEQ| /* LSB byte order */ \
+ _32BIT| /* 32 bit data on 32 bit boundaries */ \
+ PCDATA| /* Data from CPU */ \
+ INC_X|INC_Y| /* X and Y both increasing */ \
+ DRAW| /* Draw, not move */ \
+ PLANAR| /* multi pixel */ \
+ WRTDATA); \
+ DRAW_DEBUG((DEBUG_RENDER," done")); \
+}
+
+#define _s3SetClip(s3,pbox) {\
+ DRAW_DEBUG ((DEBUG_SET, "set clip %dx%d -> %dx%d ", \
+ pbox->x1, pbox->y1, pbox->x2, pbox->y2)); \
+ _s3WaitSlots(s3, 2); \
+ _s3SetScissorsTl(s3,(pbox)->x1, (pbox)->y1); \
+ _s3SetScissorsBr(s3,(pbox)->x2 - 1, (pbox)->y2 - 1); \
+ DRAW_DEBUG((DEBUG_SET," done")); \
+}
+
+#define _s3ResetClip(s3,pScreen) { \
+ DRAW_DEBUG ((DEBUG_SET, "reset clip")); \
+ _s3WaitSlots(s3, 2); \
+ _s3SetScissorsTl(s3,0,0); \
+ _s3SetScissorsBr(s3,pScreen->width - 1, pScreen->height - 1); \
+ DRAW_DEBUG((DEBUG_SET," done")); \
+}
+
+RegionPtr
+s3CopyArea(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC,
+ int srcx, int srcy, int width, int height, int dstx, int dsty);
+
+RegionPtr
+s3CopyPlane(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC,
+ int srcx, int srcy, int width, int height,
+ int dstx, int dsty, unsigned long bitPlane);
+
+void
+s3PushPixels (GCPtr pGC, PixmapPtr pBitmap,
+ DrawablePtr pDrawable,
+ int w, int h, int x, int y);
+
+void
+s3FillBoxSolid (DrawablePtr pDrawable, int nBox, BoxPtr pBox,
+ unsigned long pixel, int alu, unsigned long planemask);
+
+void
+s3FillBoxPattern (DrawablePtr pDrawable, int nBox, BoxPtr pBox,
+ int alu, unsigned long planemask, s3PatternPtr pPattern);
+
+void
+s3PolyFillRect (DrawablePtr pDrawable, GCPtr pGC,
+ int nrectFill, xRectangle *prectInit);
+
+void
+s3FillSpans (DrawablePtr pDrawable, GCPtr pGC, int n,
+ DDXPointPtr ppt, int *pwidth, int fSorted);
+
+void
+s3PolyFillArcSolid (DrawablePtr pDraw, GCPtr pGC, int narcs, xArc *parcs);
+
+void
+s3FillPoly1Rect (DrawablePtr pDrawable, GCPtr pGC, int shape,
+ int mode, int count, DDXPointPtr ptsIn);
+
+void
+s3PolyGlyphBlt (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int xInit, int y,
+ unsigned int nglyphInit,
+ CharInfoPtr *ppciInit,
+ pointer pglyphBase);
+
+void
+s3ImageGlyphBlt (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x, int y,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase);
+
+void
+s3ImageTEGlyphBlt (DrawablePtr pDrawable, GCPtr pGC,
+ int xInit, int y,
+ unsigned int nglyphInit,
+ CharInfoPtr *ppciInit,
+ pointer pglyphBase);
+
+void
+s3PolyTEGlyphBlt (DrawablePtr pDrawable, GCPtr pGC,
+ int x, int y,
+ unsigned int nglyph, CharInfoPtr *ppci,
+ pointer pglyphBase);
+
+void
+s3Polylines (DrawablePtr pDrawable, GCPtr pGC,
+ int mode, int nptInit, DDXPointPtr pptInit);
+
+void
+s3PolySegment (DrawablePtr pDrawable, GCPtr pGC,
+ int nsegInit, xSegment *pSegInit);
+
+void
+s3FillBoxSolid (DrawablePtr pDrawable, int nBox, BoxPtr pBox,
+ unsigned long pixel, int alu, unsigned long planemask);
+
+void s3ValidateGC (GCPtr pGC, Mask changes, DrawablePtr pDrawable);
+
+void
+s3CheckGCFill (GCPtr pGC);
+
+void
+s3MoveGCFill (GCPtr pGC);
+
+void
+s3SyncProc (DrawablePtr pDrawable);
+
+#endif
diff --git a/xc/programs/Xserver/hw/kdrive/savage/s3gc.c b/xc/programs/Xserver/hw/kdrive/savage/s3gc.c
new file mode 100644
index 000000000..3460a00c8
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/savage/s3gc.c
@@ -0,0 +1,384 @@
+/*
+ * $Id: s3gc.c,v 1.1 2000/01/06 12:55:51 faith 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/savage/s3gc.c,v 1.2 1999/12/30 03:03:12 robin Exp $ */
+
+#include "s3.h"
+#include "s3draw.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 "migc.h"
+
+/*
+ * Common op groups. Common assumptions:
+ *
+ * lineWidth 0
+ * lineStyle LineSolid
+ * fillStyle FillSolid
+ * rop GXcopy
+ * font <= 32 pixels wide
+ */
+
+/* TE font, >= 4 pixels wide, one clip rectangle */
+static const GCOps s3TEOps1Rect = {
+ s3FillSpans,
+ KdCheckSetSpans,
+ KdCheckPutImage,
+ s3CopyArea,
+ s3CopyPlane,
+ KdCheckPolyPoint,
+ s3Polylines,
+ s3PolySegment,
+ miPolyRectangle,
+ KdCheckPolyArc,
+ s3FillPoly1Rect,
+ s3PolyFillRect,
+ s3PolyFillArcSolid,
+ miPolyText8,
+ miPolyText16,
+ miImageText8,
+ miImageText16,
+ s3ImageTEGlyphBlt,
+ s3PolyTEGlyphBlt,
+ s3PushPixels,
+#ifdef NEED_LINEHELPER
+ ,NULL
+#endif
+};
+
+extern GCOps fbGCOps;
+
+/* Non TE font, one clip rectangle */
+static const GCOps s3NonTEOps1Rect = {
+ s3FillSpans,
+ KdCheckSetSpans,
+ KdCheckPutImage,
+ s3CopyArea,
+ s3CopyPlane,
+ KdCheckPolyPoint,
+ s3Polylines,
+ s3PolySegment,
+ miPolyRectangle,
+ KdCheckPolyArc,
+ s3FillPoly1Rect,
+ s3PolyFillRect,
+ s3PolyFillArcSolid,
+ miPolyText8,
+ miPolyText16,
+ miImageText8,
+ miImageText16,
+ s3ImageGlyphBlt,
+ s3PolyGlyphBlt,
+ s3PushPixels
+#ifdef NEED_LINEHELPER
+ ,NULL
+#endif
+};
+
+/* TE font, != 1 clip rect (including 0) */
+static const GCOps s3TEOps = {
+ s3FillSpans,
+ KdCheckSetSpans,
+ KdCheckPutImage,
+ s3CopyArea,
+ s3CopyPlane,
+ KdCheckPolyPoint,
+ s3Polylines,
+ s3PolySegment,
+ miPolyRectangle,
+ KdCheckPolyArc,
+ miFillPolygon,
+ s3PolyFillRect,
+ s3PolyFillArcSolid,
+ miPolyText8,
+ miPolyText16,
+ miImageText8,
+ miImageText16,
+ s3ImageTEGlyphBlt,
+ s3PolyTEGlyphBlt,
+ s3PushPixels
+#ifdef NEED_LINEHELPER
+ ,NULL
+#endif
+};
+
+/* Non TE font, != 1 clip rect (including 0) */
+static const GCOps s3NonTEOps = {
+ s3FillSpans,
+ KdCheckSetSpans,
+ KdCheckPutImage,
+ s3CopyArea,
+ s3CopyPlane,
+ KdCheckPolyPoint,
+ s3Polylines,
+ s3PolySegment,
+ miPolyRectangle,
+ KdCheckPolyArc,
+ miFillPolygon,
+ s3PolyFillRect,
+ s3PolyFillArcSolid,
+ miPolyText8,
+ miPolyText16,
+ miImageText8,
+ miImageText16,
+ s3ImageGlyphBlt,
+ s3PolyGlyphBlt,
+ s3PushPixels
+#ifdef NEED_LINEHELPER
+ ,NULL
+#endif
+};
+
+static GCOps *
+s3MatchCommon (DrawablePtr pDraw, GCPtr pGC, FbGCPrivPtr fbPriv)
+{
+ KdScreenPriv (pDraw->pScreen);
+
+ if (!REGION_NOTEMPTY(pDraw->pScreen,fbGetCompositeClip(pGC)))
+ {
+ DRAW_DEBUG ((DEBUG_CLIP, "Empty composite clip, clipping all ops"));
+ return &kdNoopOps;
+ }
+
+ if (pDraw->type != DRAWABLE_WINDOW)
+ return (GCOps *) &kdAsyncPixmapGCOps;
+
+ if (pGC->lineWidth != 0)
+ return 0;
+ if (pGC->lineStyle != LineSolid)
+ return 0;
+ if (pGC->fillStyle != FillSolid)
+ return 0;
+ if (fbPriv->and != 0)
+ return 0;
+ if (pGC->font)
+ {
+ if (TERMINALFONT(pGC->font))
+ {
+ if (fbPriv->oneRect)
+ return (GCOps *) &s3TEOps1Rect;
+ else
+ return (GCOps *) &s3TEOps;
+ }
+ else
+ {
+ if (fbPriv->oneRect)
+ return (GCOps *) &s3NonTEOps1Rect;
+ else
+ return (GCOps *) &s3NonTEOps;
+ }
+ }
+ return 0;
+}
+
+void
+s3ValidateGC (GCPtr pGC, Mask changes, DrawablePtr pDrawable)
+{
+ int new_type; /* drawable type has changed */
+ int new_onerect; /* onerect value has changed */
+ int new_origin;
+
+ /* flags for changing the proc vector */
+ FbGCPrivPtr fbPriv;
+ s3PrivGCPtr s3Priv;
+ int oneRect;
+
+ fbPriv = fbGetGCPrivate(pGC);
+ s3Priv = s3GetGCPrivate(pGC);
+
+ new_type = FALSE;
+ new_onerect = FALSE;
+ new_origin = FALSE;
+
+ /*
+ * If the type of drawable has changed, fix up accelerated functions
+ */
+ if (s3Priv->type != pDrawable->type)
+ {
+ new_type = TRUE;
+ s3Priv->type = pDrawable->type;
+ }
+
+ /*
+ * Check tile/stipple origin
+ */
+ if (pGC->lastWinOrg.x != pDrawable->x || pGC->lastWinOrg.y != pDrawable->y)
+ new_origin = TRUE;
+
+ /*
+ * Call down to FB to set clip list and rrop values
+ */
+ oneRect = fbPriv->oneRect;
+
+ fbValidateGC (pGC, changes, pDrawable);
+
+ if (oneRect != fbPriv->oneRect)
+ new_onerect = TRUE;
+
+ /*
+ * Check accelerated pattern if necessary
+ */
+ if (changes & (GCFillStyle|GCStipple|GCTile))
+ s3CheckGCFill (pGC);
+ else if (s3Priv->pPattern &&
+ (new_origin || changes & (GCTileStipXOrigin|GCTileStipYOrigin)))
+ s3MoveGCFill (pGC);
+
+ /*
+ * Try to match common vector
+ */
+
+ if (new_type || new_onerect ||
+ (changes & (GCLineWidth|GCLineStyle|GCFillStyle|
+ GCFont|GCForeground|GCFunction|GCPlaneMask)))
+ {
+ GCOps *newops;
+
+ if (newops = s3MatchCommon (pDrawable, pGC, fbPriv))
+ {
+ if (pGC->ops->devPrivate.val)
+ miDestroyGCOps (pGC->ops);
+ pGC->ops = newops;
+ return;
+ }
+ }
+
+ /*
+ * No common vector matched, create private ops vector and
+ * fill it in
+ */
+ if (!pGC->ops->devPrivate.val)
+ {
+ /*
+ * Switch from noop vector by first switching to fb
+ * vector and fixing it up
+ */
+ if (pGC->ops == &kdNoopOps)
+ {
+ pGC->ops = (GCOps *) &kdAsyncPixmapGCOps;
+ new_type = TRUE;
+ }
+ pGC->ops = miCreateGCOps (pGC->ops);
+ pGC->ops->devPrivate.val = 1;
+ }
+
+ /*
+ * Fills
+ */
+ if (new_type || (changes & (GCFillStyle|GCTile|GCStipple)))
+ {
+ pGC->ops->FillSpans = KdCheckFillSpans;
+ pGC->ops->PolyFillRect = KdCheckPolyFillRect;
+ if (s3Priv->type == DRAWABLE_WINDOW &&
+ (pGC->fillStyle != FillTiled || s3Priv->pPattern))
+ {
+ pGC->ops->FillSpans = s3FillSpans;
+ pGC->ops->PolyFillRect = s3PolyFillRect;
+ }
+ }
+
+ /*
+ * Blt
+ */
+ if (new_type)
+ {
+ pGC->ops->CopyArea = s3CopyArea;
+ pGC->ops->CopyPlane = s3CopyPlane;
+ pGC->ops->PushPixels = s3PushPixels;
+ }
+
+ /*
+ * Lines
+ */
+ if (new_type || (changes & (GCLineStyle|GCLineWidth|GCFillStyle)))
+ {
+ pGC->ops->Polylines = KdCheckPolylines;
+ pGC->ops->PolySegment = miPolySegment;
+ if (pGC->lineStyle == LineSolid &&
+ pGC->lineWidth == 0 &&
+ pGC->fillStyle == FillSolid &&
+ s3Priv->type == DRAWABLE_WINDOW)
+ {
+ pGC->ops->Polylines = s3Polylines;
+ pGC->ops->PolySegment = s3PolySegment;
+ }
+ }
+
+ /*
+ * Polygons
+ */
+ if (new_type || new_onerect || (changes & (GCFillStyle)))
+ {
+ pGC->ops->FillPolygon = miFillPolygon;
+ if (s3Priv->type == DRAWABLE_WINDOW &&
+ fbPriv->oneRect &&
+ pGC->fillStyle == FillSolid)
+ {
+ pGC->ops->FillPolygon = s3FillPoly1Rect;
+ }
+ }
+
+ /*
+ * Filled arcs
+ */
+ if (new_type || (changes & GCFillStyle))
+ {
+ pGC->ops->PolyFillArc = miPolyFillArc;
+ if (s3Priv->type == DRAWABLE_WINDOW &&
+ pGC->fillStyle == FillSolid)
+ {
+ pGC->ops->PolyFillArc = s3PolyFillArcSolid;
+ }
+ }
+
+ /*
+ * Text
+ */
+ if (new_type || (changes & (GCFont|GCFillStyle)))
+ {
+ pGC->ops->PolyGlyphBlt = KdCheckPolyGlyphBlt;
+ pGC->ops->ImageGlyphBlt = KdCheckImageGlyphBlt;
+ if (s3Priv->type == DRAWABLE_WINDOW && pGC->font)
+ {
+ if (pGC->fillStyle == FillSolid)
+ {
+ if (TERMINALFONT(pGC->font))
+ pGC->ops->PolyGlyphBlt = s3PolyTEGlyphBlt;
+ else
+ pGC->ops->PolyGlyphBlt = s3PolyGlyphBlt;
+ }
+ if (TERMINALFONT(pGC->font))
+ pGC->ops->ImageGlyphBlt = s3ImageTEGlyphBlt;
+ else
+ pGC->ops->ImageGlyphBlt = s3ImageGlyphBlt;
+ }
+ }
+}
diff --git a/xc/programs/Xserver/hw/kdrive/savage/s3reg.c b/xc/programs/Xserver/hw/kdrive/savage/s3reg.c
new file mode 100644
index 000000000..0eb191c17
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/savage/s3reg.c
@@ -0,0 +1,1241 @@
+/*
+ * $Id: s3reg.c,v 1.1 2000/01/06 12:55:52 faith 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/savage/s3reg.c,v 1.2 1999/12/30 03:03:12 robin Exp $ */
+
+#include "s3reg.h"
+
+#define CR00 S3_CR+0x00
+#define CR01 S3_CR+0x01
+#define CR02 S3_CR+0x02
+#define CR03 S3_CR+0x03
+#define CR04 S3_CR+0x04
+#define CR05 S3_CR+0x05
+#define CR06 S3_CR+0x06
+#define CR07 S3_CR+0x07
+#define CR08 S3_CR+0x08
+#define CR09 S3_CR+0x09
+#define CR0A S3_CR+0x0A
+#define CR0B S3_CR+0x0B
+#define CR0C S3_CR+0x0C
+#define CR0D S3_CR+0x0D
+#define CR0E S3_CR+0x0E
+#define CR0F S3_CR+0x0F
+#define CR10 S3_CR+0x10
+#define CR11 S3_CR+0x11
+#define CR12 S3_CR+0x12
+#define CR13 S3_CR+0x13
+#define CR14 S3_CR+0x14
+#define CR15 S3_CR+0x15
+#define CR16 S3_CR+0x16
+#define CR17 S3_CR+0x17
+#define CR18 S3_CR+0x18
+#define CR19 S3_CR+0x19
+#define CR1A S3_CR+0x1A
+#define CR1B S3_CR+0x1B
+#define CR1C S3_CR+0x1C
+#define CR1D S3_CR+0x1D
+#define CR1E S3_CR+0x1E
+#define CR1F S3_CR+0x1F
+#define CR20 S3_CR+0x20
+#define CR21 S3_CR+0x21
+#define CR22 S3_CR+0x22
+#define CR23 S3_CR+0x23
+#define CR24 S3_CR+0x24
+#define CR25 S3_CR+0x25
+#define CR26 S3_CR+0x26
+#define CR27 S3_CR+0x27
+#define CR28 S3_CR+0x28
+#define CR29 S3_CR+0x29
+#define CR2A S3_CR+0x2A
+#define CR2B S3_CR+0x2B
+#define CR2C S3_CR+0x2C
+#define CR2D S3_CR+0x2D
+#define CR2E S3_CR+0x2E
+#define CR2F S3_CR+0x2F
+#define CR30 S3_CR+0x30
+#define CR31 S3_CR+0x31
+#define CR32 S3_CR+0x32
+#define CR33 S3_CR+0x33
+#define CR34 S3_CR+0x34
+#define CR35 S3_CR+0x35
+#define CR36 S3_CR+0x36
+#define CR37 S3_CR+0x37
+#define CR38 S3_CR+0x38
+#define CR39 S3_CR+0x39
+#define CR3A S3_CR+0x3A
+#define CR3B S3_CR+0x3B
+#define CR3C S3_CR+0x3C
+#define CR3D S3_CR+0x3D
+#define CR3E S3_CR+0x3E
+#define CR3F S3_CR+0x3F
+#define CR40 S3_CR+0x40
+#define CR41 S3_CR+0x41
+#define CR42 S3_CR+0x42
+#define CR43 S3_CR+0x43
+#define CR44 S3_CR+0x44
+#define CR45 S3_CR+0x45
+#define CR46 S3_CR+0x46
+#define CR47 S3_CR+0x47
+#define CR48 S3_CR+0x48
+#define CR49 S3_CR+0x49
+#define CR4A S3_CR+0x4A
+#define CR4B S3_CR+0x4B
+#define CR4C S3_CR+0x4C
+#define CR4D S3_CR+0x4D
+#define CR4E S3_CR+0x4E
+#define CR4F S3_CR+0x4F
+#define CR50 S3_CR+0x50
+#define CR51 S3_CR+0x51
+#define CR52 S3_CR+0x52
+#define CR53 S3_CR+0x53
+#define CR54 S3_CR+0x54
+#define CR55 S3_CR+0x55
+#define CR56 S3_CR+0x56
+#define CR57 S3_CR+0x57
+#define CR58 S3_CR+0x58
+#define CR59 S3_CR+0x59
+#define CR5A S3_CR+0x5A
+#define CR5B S3_CR+0x5B
+#define CR5C S3_CR+0x5C
+#define CR5D S3_CR+0x5D
+#define CR5E S3_CR+0x5E
+#define CR5F S3_CR+0x5F
+#define CR60 S3_CR+0x60
+#define CR61 S3_CR+0x61
+#define CR62 S3_CR+0x62
+#define CR63 S3_CR+0x63
+#define CR64 S3_CR+0x64
+#define CR65 S3_CR+0x65
+#define CR66 S3_CR+0x66
+#define CR67 S3_CR+0x67
+#define CR68 S3_CR+0x68
+#define CR69 S3_CR+0x69
+#define CR6A S3_CR+0x6A
+#define CR6B S3_CR+0x6B
+#define CR6C S3_CR+0x6C
+#define CR6D S3_CR+0x6D
+#define CR6E S3_CR+0x6E
+#define CR6F S3_CR+0x6F
+#define CR70 S3_CR+0x70
+#define CR71 S3_CR+0x71
+#define CR72 S3_CR+0x72
+#define CR73 S3_CR+0x73
+#define CR74 S3_CR+0x74
+#define CR75 S3_CR+0x75
+#define CR76 S3_CR+0x76
+#define CR77 S3_CR+0x77
+#define CR78 S3_CR+0x78
+#define CR79 S3_CR+0x79
+#define CR7A S3_CR+0x7A
+#define CR7B S3_CR+0x7B
+#define CR7C S3_CR+0x7C
+#define CR7D S3_CR+0x7D
+#define CR7E S3_CR+0x7E
+#define CR7F S3_CR+0x7F
+#define CR80 S3_CR+0x80
+#define CR81 S3_CR+0x81
+#define CR82 S3_CR+0x82
+#define CR83 S3_CR+0x83
+#define CR84 S3_CR+0x84
+#define CR85 S3_CR+0x85
+#define CR86 S3_CR+0x86
+#define CR87 S3_CR+0x87
+#define CR88 S3_CR+0x88
+#define CR89 S3_CR+0x89
+#define CR8A S3_CR+0x8A
+#define CR8B S3_CR+0x8B
+#define CR8C S3_CR+0x8C
+#define CR8D S3_CR+0x8D
+#define CR8E S3_CR+0x8E
+#define CR8F S3_CR+0x8F
+#define CR90 S3_CR+0x90
+#define CR91 S3_CR+0x91
+#define CR92 S3_CR+0x92
+#define CR93 S3_CR+0x93
+#define CR94 S3_CR+0x94
+#define CR95 S3_CR+0x95
+#define CR96 S3_CR+0x96
+#define CR97 S3_CR+0x97
+#define CR98 S3_CR+0x98
+#define CR99 S3_CR+0x99
+#define CR9A S3_CR+0x9A
+#define CR9B S3_CR+0x9B
+#define CR9C S3_CR+0x9C
+#define CR9D S3_CR+0x9D
+#define CR9E S3_CR+0x9E
+#define CR9F S3_CR+0x9F
+#define CRA0 S3_CR+0xA0
+#define CRA1 S3_CR+0xA1
+#define CRA2 S3_CR+0xA2
+#define CRA3 S3_CR+0xA3
+#define CRA4 S3_CR+0xA4
+#define CRA5 S3_CR+0xA5
+#define CRA6 S3_CR+0xA6
+#define CRA7 S3_CR+0xA7
+#define CRA8 S3_CR+0xA8
+#define CRA9 S3_CR+0xA9
+#define CRAA S3_CR+0xAA
+#define CRAB S3_CR+0xAB
+#define CRAC S3_CR+0xAC
+#define CRAD S3_CR+0xAD
+#define CRAE S3_CR+0xAE
+#define CRAF S3_CR+0xAF
+#define CRB0 S3_CR+0xB0
+#define CRB1 S3_CR+0xB1
+#define CRB2 S3_CR+0xB2
+#define CRB3 S3_CR+0xB3
+#define CRB4 S3_CR+0xB4
+#define CRB5 S3_CR+0xB5
+#define CRB6 S3_CR+0xB6
+#define CRB7 S3_CR+0xB7
+#define CRB8 S3_CR+0xB8
+#define CRB9 S3_CR+0xB9
+#define CRBA S3_CR+0xBA
+#define CRBB S3_CR+0xBB
+#define CRBC S3_CR+0xBC
+#define CRBD S3_CR+0xBD
+#define CRBE S3_CR+0xBE
+#define CRBF S3_CR+0xBF
+
+#define CR_FIRST CR00
+
+VgaReg s3_h_total[] = {
+ CR00, 0, 8,
+ CR5D, 0, 1,
+ CR5F, 0, 2,
+ VGA_REG_END
+};
+
+VgaReg s3_h_display_end[] = {
+ CR01, 0, 8,
+ CR5D, 1, 1,
+ CR5F, 2, 2,
+ VGA_REG_END
+};
+
+VgaReg s3_h_blank_start[] = {
+ CR02, 0, 8,
+ CR5D, 2, 1,
+ CR5F, 4, 2,
+ VGA_REG_END
+};
+
+VgaReg s3_h_blank_end[] = {
+ CR03, 0, 5,
+ CR05, 7, 1,
+ VGA_REG_END
+};
+
+VgaReg s3_display_skew[] = {
+ CR03, 5, 2,
+ VGA_REG_END
+};
+
+VgaReg s3_h_sync_start[] = {
+ CR04, 0, 8,
+ CR5D, 4, 1,
+ CR5F, 6, 2,
+ VGA_REG_END
+};
+
+VgaReg s3_h_sync_end[] = {
+ CR05, 0, 5,
+ VGA_REG_END
+};
+
+VgaReg s3_h_skew[] = {
+ CR05, 5, 2,
+ VGA_REG_END
+};
+
+VgaReg s3_v_total[] = {
+ CR06, 0, 8,
+ CR07, 0, 1,
+ CR07, 5, 1,
+ CR5E, 0, 1,
+ VGA_REG_END
+};
+
+VgaReg s3_preset_row_scan[] = {
+ CR08, 0, 8,
+ VGA_REG_END
+};
+
+VgaReg s3_max_scan_line[] = {
+ CR09, 0, 5,
+ VGA_REG_END
+};
+
+VgaReg s3_start_address[] = {
+ CR0D, 0, 8,
+ CR0C, 0, 8,
+ CR69, 0, 7,
+ VGA_REG_END
+};
+
+VgaReg s3_v_retrace_start[] = {
+ CR10, 0, 8,
+ CR07, 2, 1,
+ CR07, 7, 1,
+ CR5E, 4, 1,
+ VGA_REG_END
+};
+
+VgaReg s3_v_retrace_end[] = {
+ CR11, 0, 4,
+ VGA_REG_END
+};
+
+VgaReg s3_clear_v_retrace_int[] = {
+ CR11, 4, 1,
+ VGA_REG_END
+};
+
+VgaReg s3_disable_v_retrace_int[] = {
+ CR11, 5, 1,
+ VGA_REG_END
+};
+
+VgaReg s3_lock_crtc[] = {
+ CR11, 7, 1,
+ VGA_REG_END
+};
+
+VgaReg s3_v_display_end[] = {
+ CR12, 0, 8,
+ CR07, 1, 1,
+ CR07, 6, 1,
+ CR5E, 1, 1,
+ VGA_REG_END
+};
+
+VgaReg s3_screen_offset[] = {
+ CR13, 0, 8,
+ CR51, 4, 2,
+ VGA_REG_END
+};
+
+VgaReg s3_count_by_4_mode[] = {
+ CR14, 5, 1,
+ VGA_REG_END
+};
+
+VgaReg s3_doubleword_mode[] = {
+ CR14, 6, 1,
+ VGA_REG_END
+};
+
+VgaReg s3_v_blank_start[] = {
+ CR15, 0, 8,
+ CR07, 3, 1,
+ CR09, 5, 1,
+ CR5E, 2, 1,
+ VGA_REG_END
+};
+
+VgaReg s3_v_blank_end[] = {
+ CR16, 0, 8,
+ VGA_REG_END
+};
+
+VgaReg s3_2bk_cga[] = {
+ CR17, 0, 1,
+ VGA_REG_END
+};
+
+VgaReg s3_4bk_hga[] = {
+ CR17, 1, 1,
+ VGA_REG_END
+};
+
+VgaReg s3_v_total_double[] = {
+ CR17, 2, 1,
+ VGA_REG_END
+};
+
+VgaReg s3_word_mode[] = {
+ CR17, 3, 1,
+ VGA_REG_END
+};
+
+VgaReg s3_address_16k_wrap[] = {
+ CR17, 5, 1,
+ VGA_REG_END
+};
+
+VgaReg s3_byte_mode[] = {
+ CR17, 6, 1,
+ VGA_REG_END
+};
+
+VgaReg s3_hardware_reset[] = {
+ CR17, 7, 1,
+ VGA_REG_END
+};
+
+VgaReg s3_line_compare[] = {
+ CR18, 0, 8,
+ CR07, 4, 1,
+ CR09, 6, 1,
+ CR5E, 6, 1,
+ VGA_REG_END
+};
+
+VgaReg s3_device_id[] = {
+ CR2E, 0, 8,
+ CR2D, 0, 8,
+ VGA_REG_END
+};
+
+VgaReg s3_revision[] = {
+ CR2F, 0, 8,
+ VGA_REG_END
+};
+
+VgaReg s3_enable_vga_16bit[] = {
+ CR31, 2, 1,
+ VGA_REG_END
+};
+
+VgaReg s3_enhanced_memory_mapping[] = {
+ CR31, 3, 1,
+ VGA_REG_END
+};
+
+VgaReg s3_lock_dac_writes[] = {
+ CR33, 4, 1,
+ VGA_REG_END
+};
+
+VgaReg s3_border_select[] = {
+ CR33, 5, 1,
+ VGA_REG_END
+};
+
+VgaReg s3_lock_palette[] = {
+ CR33, 6, 1,
+ VGA_REG_END
+};
+
+VgaReg s3_enable_sff[] = {
+ CR34, 4, 1,
+ VGA_REG_END
+};
+
+VgaReg s3_lock_vert[] = {
+ CR35, 4, 1,
+ VGA_REG_END
+};
+
+VgaReg s3_lock_horz[] = {
+ CR35, 5, 1,
+ VGA_REG_END
+};
+
+VgaReg s3_io_disable[] = {
+ CR36, 4, 1,
+ VGA_REG_END
+};
+
+VgaReg s3_mem_size[] = {
+ CR36, 5, 3,
+ VGA_REG_END
+};
+
+VgaReg s3_register_lock_1 [] = {
+ CR38, 0, 8, /* load with 0x48 */
+ VGA_REG_END
+};
+
+VgaReg s3_register_lock_2 [] = {
+ CR39, 0, 8, /* load with 0xa0 */
+ VGA_REG_END
+};
+
+VgaReg s3_refresh_control[] = {
+ CR3A, 0, 2,
+ VGA_REG_END
+};
+
+VgaReg s3_enable_256[] = {
+ CR3A, 4, 1,
+ VGA_REG_END
+};
+
+VgaReg s3_disable_pci_read_bursts[] = {
+ CR3A, 7, 1,
+ VGA_REG_END
+};
+
+VgaReg s3_h_start_fifo_fetch[] = {
+ CR3B, 0, 8,
+ CR5D, 6, 1,
+ CR5B, 2, 2,
+ VGA_REG_END
+};
+
+VgaReg s3_enable_2d_access[] = {
+ CR40, 0, 1,
+ VGA_REG_END
+};
+
+VgaReg s3_interlace[] = {
+ CR42, 5, 1,
+ VGA_REG_END
+};
+
+VgaReg s3_old_screen_off_8[] = {
+ CR43, 2, 1,
+ VGA_REG_END
+};
+
+VgaReg s3_h_counter_double_mode[] = {
+ CR43, 7, 1,
+ VGA_REG_END
+};
+
+VgaReg s3_cursor_enable[] = {
+ CR45, 0, 1,
+ VGA_REG_END
+};
+
+VgaReg s3_cursor_right[] = {
+ CR45, 4, 1,
+ VGA_REG_END
+};
+
+VgaReg s3_cursor_xhigh[] = {
+ CR46, 0, 3,
+ VGA_REG_END
+};
+
+VgaReg s3_cursor_xlow[] = {
+ CR47, 0, 8,
+ VGA_REG_END
+};
+
+VgaReg s3_cursor_yhigh[] = {
+ CR48, 0, 3,
+ VGA_REG_END
+};
+
+VgaReg s3_cursor_ylow[] = {
+ CR49, 0, 8,
+ VGA_REG_END
+};
+
+VgaReg s3_cursor_fg[] = {
+ CR4A, 0, 8,
+ VGA_REG_END
+};
+
+VgaReg s3_cursor_bg[] = {
+ CR4B, 0, 8,
+ VGA_REG_END
+};
+
+VgaReg s3_cursor_address[] = {
+ CR4D, 0, 8,
+ CR4C, 0, 8,
+ VGA_REG_END
+};
+
+VgaReg s3_cursor_xoff[] = {
+ CR4E, 0, 6,
+ VGA_REG_END
+};
+
+VgaReg s3_cursor_yoff[] = {
+ CR4F, 0, 6,
+ VGA_REG_END
+};
+
+VgaReg s3_ge_screen_width[] = {
+ CR50, 6, 2,
+ CR50, 0, 1,
+ VGA_REG_END
+};
+
+VgaReg s3_pixel_length[] = {
+ CR50, 4, 2,
+ VGA_REG_END
+};
+
+VgaReg s3_big_endian_linear[] = {
+ CR53, 1, 2,
+ VGA_REG_END
+};
+
+VgaReg s3_mmio_select[] = {
+ CR53, 3, 2,
+ VGA_REG_END
+};
+
+VgaReg s3_mmio_window[] = {
+ CR53, 5, 1,
+ VGA_REG_END
+};
+
+VgaReg s3_swap_nibbles[] = {
+ CR53, 6, 1,
+ VGA_REG_END
+};
+
+VgaReg s3_cursor_ms_x11[] = {
+ CR55, 4, 1,
+ VGA_REG_END
+};
+
+VgaReg s3_linear_window_size[] = {
+ CR58, 0, 2,
+ VGA_REG_END
+};
+
+VgaReg s3_enable_linear[] = {
+ CR58, 4, 1,
+ VGA_REG_END
+};
+
+VgaReg s3_h_blank_extend[] = {
+ CR5D, 3, 1,
+ VGA_REG_END
+};
+
+VgaReg s3_h_sync_extend[] = {
+ CR5D, 5, 1,
+ VGA_REG_END
+};
+
+VgaReg s3_sdclk_skew[] = {
+ CR60, 0, 4,
+ VGA_REG_END
+};
+
+VgaReg s3_delay_blank[] = {
+ CR65, 3, 2,
+ VGA_REG_END
+};
+
+VgaReg s3_delay_h_enable[] = {
+ CR65, 6, 2,
+ CR65, 0, 1,
+ VGA_REG_END
+};
+
+VgaReg s3_enable_2d_3d[] = {
+ CR66, 0, 1,
+ VGA_REG_END
+};
+
+VgaReg s3_pci_disconnect_enable[] = {
+ CR66, 3, 1,
+ VGA_REG_END
+};
+
+VgaReg s3_pci_retry_enable[] = {
+ CR66, 7, 1,
+ VGA_REG_END
+};
+
+VgaReg s3_color_mode[] = {
+ CR67, 4, 4,
+ VGA_REG_END
+};
+
+VgaReg s3_primary_stream_timeout[] = {
+ CR71, 0, 8,
+ VGA_REG_END
+};
+
+VgaReg s3_master_control_unit_timeout[] = {
+ CR74, 0, 8,
+ VGA_REG_END
+};
+
+VgaReg s3_command_buffer_timeout[] = {
+ CR75, 0, 8,
+ VGA_REG_END
+};
+
+VgaReg s3_lpb_timeout[] = {
+ CR76, 0, 8,
+ VGA_REG_END
+};
+
+VgaReg s3_cpu_timeout[] = {
+ CR78, 0, 8,
+ VGA_REG_END
+};
+
+VgaReg s3_2d_graphics_engine_timeout[] = {
+ CR79, 0, 8,
+ VGA_REG_END
+};
+
+VgaReg s3_fifo_drain_delay[] = {
+ CR85, 0, 3,
+ VGA_REG_END
+};
+
+VgaReg s3_fifo_fetch_timing[] = {
+ CR85, 4, 1,
+ VGA_REG_END
+};
+
+VgaReg s3_dac_power_up_time[] = {
+ CR86, 0, 7,
+ VGA_REG_END
+};
+
+VgaReg s3_dac_power_saving_disable[] = {
+ CR86, 7, 1,
+ VGA_REG_END
+};
+
+VgaReg s3_primary_stream_l1[] = {
+ CR91, 0, 8,
+ CR90, 0, 3,
+ VGA_REG_END
+};
+
+#define CR_LAST CR91
+
+#define SR00 S3_SR+0x00
+#define SR01 S3_SR+0x01
+#define SR02 S3_SR+0x02
+#define SR03 S3_SR+0x03
+#define SR04 S3_SR+0x04
+#define SR05 S3_SR+0x05
+#define SR06 S3_SR+0x06
+#define SR07 S3_SR+0x07
+#define SR08 S3_SR+0x08
+#define SR09 S3_SR+0x09
+#define SR0A S3_SR+0x0A
+#define SR0B S3_SR+0x0B
+#define SR0C S3_SR+0x0C
+#define SR0D S3_SR+0x0D
+#define SR0E S3_SR+0x0E
+#define SR0F S3_SR+0x0F
+#define SR10 S3_SR+0x10
+#define SR11 S3_SR+0x11
+#define SR12 S3_SR+0x12
+#define SR13 S3_SR+0x13
+#define SR14 S3_SR+0x14
+#define SR15 S3_SR+0x15
+#define SR16 S3_SR+0x16
+#define SR17 S3_SR+0x17
+#define SR18 S3_SR+0x18
+#define SR19 S3_SR+0x19
+#define SR1A S3_SR+0x1A
+#define SR1B S3_SR+0x1B
+#define SR1C S3_SR+0x1C
+#define SR1D S3_SR+0x1D
+#define SR1E S3_SR+0x1E
+#define SR1F S3_SR+0x1F
+#define SR20 S3_SR+0x20
+#define SR21 S3_SR+0x21
+#define SR22 S3_SR+0x22
+#define SR23 S3_SR+0x23
+#define SR24 S3_SR+0x24
+#define SR25 S3_SR+0x25
+#define SR26 S3_SR+0x26
+#define SR27 S3_SR+0x27
+#define SR28 S3_SR+0x28
+#define SR29 S3_SR+0x29
+#define SR2A S3_SR+0x2A
+#define SR2B S3_SR+0x2B
+#define SR2C S3_SR+0x2C
+#define SR2D S3_SR+0x2D
+#define SR2E S3_SR+0x2E
+#define SR2F S3_SR+0x2F
+#define SR30 S3_SR+0x30
+#define SR31 S3_SR+0x31
+#define SR32 S3_SR+0x32
+#define SR33 S3_SR+0x33
+#define SR34 S3_SR+0x34
+#define SR35 S3_SR+0x35
+#define SR36 S3_SR+0x36
+#define SR37 S3_SR+0x37
+#define SR38 S3_SR+0x38
+#define SR39 S3_SR+0x39
+#define SR3A S3_SR+0x3A
+#define SR3B S3_SR+0x3B
+#define SR3C S3_SR+0x3C
+#define SR3D S3_SR+0x3D
+#define SR3E S3_SR+0x3E
+#define SR3F S3_SR+0x3F
+#define SR40 S3_SR+0x40
+#define SR41 S3_SR+0x41
+#define SR42 S3_SR+0x42
+#define SR43 S3_SR+0x43
+#define SR44 S3_SR+0x44
+#define SR45 S3_SR+0x45
+#define SR46 S3_SR+0x46
+#define SR47 S3_SR+0x47
+#define SR48 S3_SR+0x48
+#define SR49 S3_SR+0x49
+#define SR4A S3_SR+0x4A
+#define SR4B S3_SR+0x4B
+#define SR4C S3_SR+0x4C
+#define SR4D S3_SR+0x4D
+#define SR4E S3_SR+0x4E
+#define SR4F S3_SR+0x4F
+#define SR50 S3_SR+0x50
+#define SR51 S3_SR+0x51
+#define SR52 S3_SR+0x52
+#define SR53 S3_SR+0x53
+#define SR54 S3_SR+0x54
+#define SR55 S3_SR+0x55
+#define SR56 S3_SR+0x56
+#define SR57 S3_SR+0x57
+#define SR58 S3_SR+0x58
+#define SR59 S3_SR+0x59
+#define SR5A S3_SR+0x5A
+#define SR5B S3_SR+0x5B
+#define SR5C S3_SR+0x5C
+#define SR5D S3_SR+0x5D
+#define SR5E S3_SR+0x5E
+#define SR5F S3_SR+0x5F
+#define SR60 S3_SR+0x60
+#define SR61 S3_SR+0x61
+#define SR62 S3_SR+0x62
+#define SR63 S3_SR+0x63
+#define SR64 S3_SR+0x64
+#define SR65 S3_SR+0x65
+#define SR66 S3_SR+0x66
+#define SR67 S3_SR+0x67
+#define SR68 S3_SR+0x68
+#define SR69 S3_SR+0x69
+#define SR6A S3_SR+0x6A
+#define SR6B S3_SR+0x6B
+#define SR6C S3_SR+0x6C
+#define SR6D S3_SR+0x6D
+#define SR6E S3_SR+0x6E
+#define SR6F S3_SR+0x6F
+
+#define SR_FIRST SR02
+
+VgaReg s3_dot_clock_8[] = {
+ SR01, 0, 1,
+ VGA_REG_END
+};
+
+VgaReg s3_screen_off[] = {
+ SR01, 5, 1,
+ VGA_REG_END
+};
+
+VgaReg s3_enable_write_plane[] = {
+ SR02, 0, 4,
+ VGA_REG_END
+};
+
+VgaReg s3_extended_memory_access[] = {
+ SR04, 1, 1,
+ VGA_REG_END
+};
+
+VgaReg s3_sequential_addressing_mode[] = {
+ SR04, 2, 1,
+ VGA_REG_END
+};
+
+VgaReg s3_select_chain_4_mode[] = {
+ SR04, 3, 1,
+ VGA_REG_END
+};
+
+VgaReg s3_unlock_extended_sequencer[] = {
+ SR08, 0, 8, /* write 0x06 */
+ VGA_REG_END
+};
+
+VgaReg s3_linear_addressing_control[] = {
+ SR09, 0, 1,
+ VGA_REG_END
+};
+
+VgaReg s3_disable_io_ports[] = {
+ SR09, 7, 1,
+ VGA_REG_END
+};
+
+VgaReg s3_hsync_control[] = {
+ SR0D, 4, 2,
+ VGA_REG_END
+};
+
+VgaReg s3_vsync_control[] = {
+ SR0D, 6, 2,
+ VGA_REG_END
+};
+
+VgaReg s3_mclk_n[] = {
+ SR10, 0, 5,
+ VGA_REG_END
+};
+
+VgaReg s3_mclk_r[] = {
+ SR10, 5, 2,
+ VGA_REG_END
+};
+
+VgaReg s3_mclk_m[] = {
+ SR11, 0, 7,
+ VGA_REG_END
+};
+
+VgaReg s3_dclk_n[] = {
+ SR12, 0, 6,
+ SR29, 4, 1,
+ VGA_REG_END
+};
+
+VgaReg s3_dclk_r[] = {
+ SR12, 6, 2,
+ SR29, 2, 1,
+ VGA_REG_END
+};
+
+VgaReg s3_dclk_m[] = {
+ SR13, 0, 8,
+ SR29, 3, 1,
+ VGA_REG_END
+};
+
+VgaReg s3_mclk_load[] = {
+ SR15, 0, 1,
+ VGA_REG_END
+};
+
+VgaReg s3_dclk_load[] = {
+ SR15, 1, 1,
+ VGA_REG_END
+};
+
+VgaReg s3_dclk_over_2[] = {
+ SR15, 4, 1,
+ VGA_REG_END
+};
+
+VgaReg s3_clock_load_imm[] = {
+ SR15, 5, 1,
+ VGA_REG_END
+};
+
+VgaReg s3_dclk_invert[] = {
+ SR15, 6, 1,
+ VGA_REG_END
+};
+
+VgaReg s3_enable_clock_double[] = {
+ SR18, 7, 1,
+ VGA_REG_END
+};
+
+VgaReg s3_dclk_double_15_16_invert[] = {
+ SR1A, 0, 1,
+ VGA_REG_END
+};
+
+VgaReg s3_enable_gamma_correction[] = {
+ SR1B, 3, 1,
+ VGA_REG_END
+};
+
+VgaReg s3_enable_8_bit_luts[] = {
+ SR1B, 4, 1,
+ VGA_REG_END
+};
+
+VgaReg s3_dclk_control[] = {
+ SR1B, 7, 1,
+ VGA_REG_END
+};
+
+VgaReg s3_vga_dclk_n[] = {
+ SR36, 0, 6,
+ SR39, 4, 1,
+ VGA_REG_END
+};
+
+VgaReg s3_vga_dclk_r[] = {
+ SR36, 6, 2,
+ SR39, 2, 1,
+ VGA_REG_END
+};
+
+VgaReg s3_vga_dclk_m1[] = {
+ SR37, 0, 8,
+ SR39, 3, 1,
+ VGA_REG_END
+};
+
+VgaReg s3_vga_dclk_m2[] = {
+ SR38, 0, 8,
+ SR39, 3, 1,
+ VGA_REG_END
+};
+
+VgaReg s3_vga_clk_select[] = {
+ SR39, 0, 1,
+ VGA_REG_END
+};
+
+#define SR_LAST SR39
+
+#define AR00 (S3_AR+0x00)
+#define AR10 (S3_AR+0x10)
+#define AR11 (S3_AR+0x11)
+#define AR12 (S3_AR+0x12)
+#define AR13 (S3_AR+0x13)
+#define AR14 (S3_AR+0x14)
+
+#define AR_FIRST AR00
+
+VgaReg s3_select_graphics_mode[] = {
+ AR10, 0, 1,
+ VGA_REG_END
+};
+
+VgaReg s3_enable_blinking[] = {
+ AR10, 3, 1,
+ VGA_REG_END
+};
+
+VgaReg s3_border_color[] = {
+ AR11, 0, 8,
+ VGA_REG_END
+};
+
+#define AR_LAST AR11
+
+VgaReg s3_io_addr_select[] = {
+ S3_MISC_OUT, 0, 1,
+ VGA_REG_END
+};
+
+VgaReg s3_enable_ram[] = {
+ S3_MISC_OUT, 1, 1,
+ VGA_REG_END
+};
+
+VgaReg s3_clock_select[] = {
+ S3_MISC_OUT, 2, 2,
+ VGA_REG_END
+};
+
+VgaReg s3_horz_sync_neg[] = {
+ S3_MISC_OUT, 6, 1,
+ VGA_REG_END
+};
+
+VgaReg s3_vert_sync_neg[] = {
+ S3_MISC_OUT, 7, 1,
+ VGA_REG_END
+};
+
+VgaReg s3_display_mode_inactive[] = {
+ S3_INPUT_STATUS_1, 0, 1,
+ VGA_REG_END
+};
+
+VgaReg s3_vertical_sync_active[] = {
+ S3_INPUT_STATUS_1, 3, 1,
+ VGA_REG_END
+};
+
+VgaReg s3_dac_mask[] = {
+ S3_DAC + 0, 0, 8,
+ VGA_REG_END
+};
+
+VgaReg s3_dac_read_index[] = {
+ S3_DAC + 1, 0, 8,
+ VGA_REG_END
+};
+
+VgaReg s3_dac_write_index[] = {
+ S3_DAC + 2, 0, 8,
+ VGA_REG_END
+};
+
+VgaReg s3_dac_data[] = {
+ S3_DAC + 3, 0, 8,
+ VGA_REG_END
+};
+
+VGA8
+_s3Inb (VgaCard *card, VGA16 port)
+{
+ VGAVOL8 *reg;
+
+ if (card->closure)
+ return VgaReadMemb ((VGA32) card->closure + port);
+ else
+ return VgaInb (port);
+}
+
+void
+_s3Outb (VgaCard *card, VGA8 value, VGA16 port)
+{
+ if (card->closure)
+ VgaWriteMemb (value, (VGA32) card->closure + port);
+ else
+ VgaOutb (value, port);
+}
+
+void
+_s3RegMap (VgaCard *card, VGA16 reg, VgaMap *map, VGABOOL write)
+{
+
+ if (reg < S3_SR + S3_NSR)
+ {
+ map->access = VgaAccessIndIo;
+ map->port = 0x3c4;
+ map->addr = 0;
+ map->value = 1;
+ map->index = reg - S3_SR;
+ }
+ else if (reg < S3_GR + S3_NGR)
+ {
+ map->access = VgaAccessIndIo;
+ map->port = 0x3ce;
+ map->addr = 0;
+ map->value = 1;
+ map->index = reg - S3_GR;
+ }
+ else if (reg < S3_AR + S3_NAR)
+ {
+ reg -= S3_AR;
+ map->access = VgaAccessDone;
+ /* reset AFF to index */
+ (void) _s3Inb (card, 0x3da);
+ if (reg >= 16)
+ reg |= 0x20;
+ _s3Outb (card, reg, 0x3c0);
+ if (write)
+ _s3Outb (card, map->value, 0x3c0);
+ else
+ map->value = _s3Inb (card, 0x3c1);
+ if (!(reg & 0x20))
+ {
+ /* enable video display again */
+ (void) _s3Inb (card, 0x3da);
+ _s3Outb (card, 0x20, 0x3c0);
+ }
+ return;
+ }
+ else if (reg < S3_CR + S3_NCR)
+ {
+ map->access = VgaAccessIndIo;
+ map->port = 0x3d4;
+ map->addr = 0;
+ map->value = 1;
+ map->index = reg - S3_CR;
+ }
+ else if (reg < S3_DAC + S3_NDAC)
+ {
+ map->access = VgaAccessIo;
+ map->port = 0x3c6 + reg - S3_DAC;
+ }
+ else switch (reg) {
+ case S3_MISC_OUT:
+ map->access = VgaAccessIo;
+ if (write)
+ map->port = 0x3c2;
+ else
+ map->port = 0x3cc;
+ break;
+ case S3_INPUT_STATUS_1:
+ map->access = VgaAccessIo;
+ map->port = 0x3da;
+ break;
+ }
+ if (card->closure)
+ {
+ map->port = map->port + (VGA32) card->closure;
+ if (map->access == VgaAccessIo)
+ map->access = VgaAccessMem;
+ if (map->access == VgaAccessIndIo)
+ map->access = VgaAccessIndMem;
+ }
+}
+
+VgaSave s3Saves[] = {
+ CR_FIRST, CR18,
+ CR31, CR_LAST,
+ SR_FIRST, SR15,
+ SR18, SR_LAST,
+ AR_FIRST, AR_LAST,
+ S3_MISC_OUT, S3_MISC_OUT,
+ VGA_SAVE_END
+};
+
+void
+s3RegInit (S3Vga *s3vga, VGAVOL8 *mmio)
+{
+ s3vga->card.map = _s3RegMap;
+ s3vga->card.closure = (void *) mmio;
+ s3vga->card.max = S3_NREG;
+ s3vga->card.values = s3vga->values;
+ s3vga->card.saves = s3Saves;
+}
+
+void
+s3Save (S3Vga *s3vga)
+{
+ s3vga->save_lock_crtc = s3Get(s3vga, s3_lock_crtc);
+ s3SetImm (s3vga, s3_lock_crtc, 0);
+ s3vga->save_register_lock_1 = s3Get (s3vga, s3_register_lock_1);
+ s3SetImm (s3vga, s3_register_lock_1, 0x48);
+ s3vga->save_register_lock_2 = s3Get (s3vga, s3_register_lock_2);
+ s3SetImm (s3vga, s3_register_lock_2, 0xa5);
+ s3vga->save_unlock_extended_sequencer = s3Get (s3vga, s3_unlock_extended_sequencer);
+ s3SetImm (s3vga, s3_unlock_extended_sequencer, 0x06);
+ s3vga->save_lock_horz = s3Get (s3vga, s3_lock_horz);
+ s3SetImm (s3vga, s3_lock_horz, 0);
+ s3vga->save_lock_vert = s3Get (s3vga, s3_lock_vert);
+ s3SetImm (s3vga, s3_lock_vert, 0);
+ s3vga->save_dot_clock_8 = s3Get (s3vga, s3_dot_clock_8);
+ VgaPreserve (&s3vga->card);
+}
+
+void
+s3Reset (S3Vga *s3vga)
+{
+ VgaRestore (&s3vga->card);
+ s3SetImm (s3vga, s3_clock_load_imm, 1);
+ s3SetImm (s3vga, s3_clock_load_imm, 0);
+ s3SetImm (s3vga, s3_dot_clock_8, s3vga->save_dot_clock_8);
+ s3SetImm (s3vga, s3_lock_vert, s3vga->save_lock_vert);
+ s3SetImm (s3vga, s3_lock_horz, s3vga->save_lock_horz);
+ s3SetImm (s3vga, s3_lock_dac_writes, s3vga->save_lock_dac_writes);
+ s3SetImm (s3vga, s3_unlock_extended_sequencer, s3vga->save_unlock_extended_sequencer);
+ s3SetImm (s3vga, s3_register_lock_2, s3vga->save_register_lock_2);
+ s3SetImm (s3vga, s3_register_lock_1, s3vga->save_register_lock_1);
+ s3SetImm (s3vga, s3_lock_crtc, s3vga->save_lock_crtc);
+ VgaFinish (&s3vga->card);
+}
diff --git a/xc/programs/Xserver/hw/kdrive/savage/s3reg.h b/xc/programs/Xserver/hw/kdrive/savage/s3reg.h
new file mode 100644
index 000000000..7482cd8db
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/savage/s3reg.h
@@ -0,0 +1,218 @@
+/*
+ * $Id: s3reg.h,v 1.1 2000/01/06 12:55:52 faith 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/savage/s3reg.h,v 1.2 1999/12/30 03:03:12 robin Exp $ */
+
+#ifndef _S3REG_H_
+#define _S3REG_H_
+
+#include "vga.h"
+
+#define S3_SR 0
+#define S3_NSR 0x70
+#define S3_GR (S3_SR+S3_NSR)
+#define S3_NGR 0x09
+#define S3_AR (S3_GR+S3_NGR)
+#define S3_NAR 0x15
+#define S3_CR (S3_AR+S3_NAR)
+#define S3_NCR 0xc0
+#define S3_DAC (S3_CR+S3_NCR)
+#define S3_NDAC 4
+#define S3_MISC_OUT (S3_DAC + S3_NDAC)
+#define S3_INPUT_STATUS_1 (S3_MISC_OUT+1)
+#define S3_NREG (S3_INPUT_STATUS_1+1)
+
+extern VgaReg s3_h_total[];
+extern VgaReg s3_h_display_end[];
+extern VgaReg s3_h_blank_start[];
+extern VgaReg s3_h_blank_end[];
+extern VgaReg s3_display_skew[];
+extern VgaReg s3_h_sync_start[];
+extern VgaReg s3_h_sync_end[];
+extern VgaReg s3_h_skew[];
+extern VgaReg s3_v_total[];
+extern VgaReg s3_preset_row_scan[];
+extern VgaReg s3_max_scan_line[];
+extern VgaReg s3_start_address[];
+extern VgaReg s3_v_retrace_start[];
+extern VgaReg s3_v_retrace_end[];
+extern VgaReg s3_clear_v_retrace_int[];
+extern VgaReg s3_disable_v_retrace_int[];
+extern VgaReg s3_lock_crtc[];
+extern VgaReg s3_v_display_end[];
+extern VgaReg s3_screen_offset[];
+extern VgaReg s3_count_by_4_mode[];
+extern VgaReg s3_doubleword_mode[];
+extern VgaReg s3_v_blank_start[];
+extern VgaReg s3_v_blank_end[];
+extern VgaReg s3_2bk_cga[];
+extern VgaReg s3_4bk_hga[];
+extern VgaReg s3_v_total_double[];
+extern VgaReg s3_address_16k_wrap[];
+extern VgaReg s3_word_mode[];
+extern VgaReg s3_byte_mode[];
+extern VgaReg s3_hardware_reset[];
+extern VgaReg s3_line_compare[];
+extern VgaReg s3_device_id[];
+extern VgaReg s3_revision[];
+extern VgaReg s3_enable_vga_16bit[];
+extern VgaReg s3_enhanced_memory_mapping[];
+extern VgaReg s3_enable_sff[];
+extern VgaReg s3_lock_dac_writes[];
+extern VgaReg s3_border_select[];
+extern VgaReg s3_lock_palette[];
+extern VgaReg s3_lock_vert[];
+extern VgaReg s3_lock_horz[];
+extern VgaReg s3_io_disable[];
+extern VgaReg s3_mem_size[];
+extern VgaReg s3_register_lock_1 [];
+extern VgaReg s3_register_lock_2 [];
+extern VgaReg s3_refresh_control[];
+extern VgaReg s3_enable_256[];
+extern VgaReg s3_disable_pci_read_bursts[];
+extern VgaReg s3_h_start_fifo_fetch[];
+extern VgaReg s3_enable_2d_access[];
+extern VgaReg s3_interlace[];
+extern VgaReg s3_old_screen_off_8[];
+extern VgaReg s3_h_counter_double_mode[];
+extern VgaReg s3_cursor_enable[];
+extern VgaReg s3_cursor_right[];
+extern VgaReg s3_cursor_xhigh[];
+extern VgaReg s3_cursor_xlow[];
+extern VgaReg s3_cursor_yhigh[];
+extern VgaReg s3_cursor_ylow[];
+extern VgaReg s3_cursor_fg[];
+extern VgaReg s3_cursor_bg[];
+extern VgaReg s3_cursor_address[];
+extern VgaReg s3_cursor_xoff[];
+extern VgaReg s3_cursor_yoff[];
+extern VgaReg s3_ge_screen_width[];
+extern VgaReg s3_pixel_length[];
+extern VgaReg s3_big_endian_linear[];
+extern VgaReg s3_mmio_select[];
+extern VgaReg s3_mmio_window[];
+extern VgaReg s3_swap_nibbles[];
+extern VgaReg s3_cursor_ms_x11[];
+extern VgaReg s3_linear_window_size[];
+extern VgaReg s3_enable_linear[];
+extern VgaReg s3_h_blank_extend[];
+extern VgaReg s3_h_sync_extend[];
+extern VgaReg s3_sdclk_skew[];
+extern VgaReg s3_delay_blank[];
+extern VgaReg s3_delay_h_enable[];
+extern VgaReg s3_enable_2d_3d[];
+extern VgaReg s3_pci_disconnect_enable[];
+extern VgaReg s3_pci_retry_enable[];
+extern VgaReg s3_color_mode[];
+extern VgaReg s3_primary_stream_timeout[];
+extern VgaReg s3_master_control_unit_timeout[];
+extern VgaReg s3_command_buffer_timeout[];
+extern VgaReg s3_lpb_timeout[];
+extern VgaReg s3_cpu_timeout[];
+extern VgaReg s3_2d_graphics_engine_timeout[];
+extern VgaReg s3_fifo_drain_delay[];
+extern VgaReg s3_fifo_fetch_timing[];
+extern VgaReg s3_dac_power_up_time[];
+extern VgaReg s3_dac_power_saving_disable[];
+extern VgaReg s3_primary_stream_l1[];
+
+extern VgaReg s3_dot_clock_8[];
+extern VgaReg s3_screen_off[];
+extern VgaReg s3_enable_write_plane[];
+extern VgaReg s3_extended_memory_access[];
+extern VgaReg s3_sequential_addressing_mode[];
+extern VgaReg s3_select_chain_4_mode[];
+
+extern VgaReg s3_unlock_extended_sequencer[];
+extern VgaReg s3_linear_addressing_control[];
+extern VgaReg s3_disable_io_ports[];
+extern VgaReg s3_hsync_control[];
+extern VgaReg s3_vsync_control[];
+extern VgaReg s3_mclk_n[];
+extern VgaReg s3_mclk_r[];
+extern VgaReg s3_mclk_m[];
+extern VgaReg s3_dclk_n[];
+extern VgaReg s3_dclk_r[];
+extern VgaReg s3_dclk_m[];
+extern VgaReg s3_mclk_load[];
+extern VgaReg s3_dclk_load[];
+extern VgaReg s3_dclk_over_2[];
+extern VgaReg s3_clock_load_imm[];
+extern VgaReg s3_dclk_invert[];
+extern VgaReg s3_enable_clock_double[];
+extern VgaReg s3_dclk_double_15_16_invert[];
+extern VgaReg s3_enable_gamma_correction[];
+extern VgaReg s3_enable_8_bit_luts[];
+extern VgaReg s3_dclk_control[];
+extern VgaReg s3_vga_dclk_n[];
+extern VgaReg s3_vga_dclk_r[];
+extern VgaReg s3_vga_dclk_m1[];
+extern VgaReg s3_vga_dclk_m2[];
+extern VgaReg s3_vga_clk_select[];
+extern VgaReg s3_select_graphics_mode[];
+extern VgaReg s3_enable_blinking[];
+extern VgaReg s3_border_color[];
+
+extern VgaReg s3_io_addr_select[];
+extern VgaReg s3_enable_ram[];
+extern VgaReg s3_clock_select[];
+extern VgaReg s3_horz_sync_neg[];
+extern VgaReg s3_vert_sync_neg[];
+
+extern VgaReg s3_display_mode_inactive[];
+extern VgaReg s3_vertical_sync_active[];
+
+extern VgaReg s3_dac_mask[];
+extern VgaReg s3_dac_read_index[];
+extern VgaReg s3_dac_write_index[];
+extern VgaReg s3_dac_data[];
+
+#define s3Get(sv,r) VgaGet(&(sv)->card, (r))
+#define s3GetImm(sv,r) VgaGetImm(&(sv)->card, (r))
+#define s3Set(sv,r,v) VgaSet(&(sv)->card, (r), (v))
+#define s3SetImm(sv,r,v) VgaSetImm(&(sv)->card, (r), (v))
+
+typedef struct _s3Vga {
+ VgaCard card;
+ VgaValue values[S3_NREG];
+ VGA32 save_lock_crtc;
+ VGA32 save_register_lock_1;
+ VGA32 save_register_lock_2;
+ VGA32 save_unlock_extended_sequencer;
+ VGA32 save_lock_dac_writes;
+ VGA32 save_lock_horz;
+ VGA32 save_lock_vert;
+ VGA32 save_dot_clock_8;
+} S3Vga;
+
+void
+s3RegInit (S3Vga *s3vga, VGAVOL8 *mmio);
+
+void
+s3Save (S3Vga *s3vga);
+
+void
+s3Reset (S3Vga *s3vga);
+
+#endif /* _S3REG_H_ */
diff --git a/xc/programs/Xserver/hw/kdrive/savage/s3rtst.c b/xc/programs/Xserver/hw/kdrive/savage/s3rtst.c
new file mode 100644
index 000000000..f3bb57f87
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/savage/s3rtst.c
@@ -0,0 +1,141 @@
+/*
+ * $Id: s3rtst.c,v 1.1 2000/01/06 12:55:52 faith 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/savage/s3rtst.c,v 1.1 1999/11/19 13:53:57 hohndel Exp $ */
+
+#include <stdio.h>
+#include "s3reg.h"
+
+typedef struct {
+ VgaReg *reg;
+ char *name;
+} NamedVgaReg;
+
+NamedVgaReg s3VRegs[] = {
+ s3_h_total, "h_total",
+ s3_h_display_end, "h_display_end",
+ s3_h_blank_start, "h_blank_start",
+ s3_h_blank_end, "h_blank_end",
+ s3_display_skew, "display_skew",
+ s3_h_sync_start, "h_sync_start",
+ s3_h_sync_end, "h_sync_end",
+ s3_h_skew, "h_skew",
+ s3_v_total, "v_total",
+ s3_preset_row_scan, "preset_row_scan",
+ s3_max_scan_line, "max_scan_line",
+ s3_start_address, "start_address",
+ s3_v_retrace_start, "v_retrace_start",
+ s3_v_retrace_end, "v_retrace_end",
+ s3_clear_v_retrace_int, "clear_v_retrace_int",
+ s3_disable_v_retrace_int, "disable_v_retrace_int",
+ s3_lock_crtc, "lock_crtc",
+ s3_v_display_end, "v_display_end",
+ s3_screen_offset, "screen_offset",
+ s3_count_by_4_mode, "count_by_4_mode",
+ s3_doubleword_mode, "doubleword_mode",
+ s3_v_blank_start, "v_blank_start",
+ s3_v_blank_end, "v_blank_end",
+ s3_v_total_double, "v_total_double",
+ s3_word_mode, "word_mode",
+ s3_byte_mode, "byte_mode",
+ s3_line_compare, "line_compare",
+ s3_device_id, "device_id",
+ s3_revision, "revision",
+ s3_lock_vert, "lock_vert",
+ s3_lock_horz, "lock_horz",
+ s3_io_disable, "io_disable",
+ s3_mem_size, "mem_size",
+ s3_register_lock_1 , "register_lock_1 ",
+ s3_register_lock_2 , "register_lock_2 ",
+ s3_refresh_control, "refresh_control",
+ s3_enable_256, "enable_256",
+ s3_enable_pci_read_bursts, "enable_pci_read_bursts",
+ s3_h_start_fifo_fetch, "h_start_fifo_fetch",
+ s3_interlace, "interlace",
+ s3_old_screen_off_8, "old_screen_off_8",
+ s3_h_counter_double_mode, "h_counter_double_mode",
+ s3_hardware_cursor_enable, "hardware_cursor_enable",
+ s3_hardware_cursor_right, "hardware_cursor_right",
+ s3_hardware_cursor_x, "hardware_cursor_x",
+ s3_hardware_cursor_y, "hardware_cursor_y",
+ s3_hardware_cursor_fg, "hardware_cursor_fg",
+ s3_cursor_address, "cursor_address",
+ s3_cursor_start_x, "cursor_start_x",
+ s3_cursor_start_y, "cursor_start_y",
+ s3_ge_screen_width, "ge_screen_width",
+ s3_pixel_length, "pixel_length",
+ s3_big_endian_linear, "big_endian_linear",
+ s3_mmio_select, "mmio_select",
+ s3_mmio_window, "mmio_window",
+ s3_swap_nibbles, "swap_nibbles",
+ s3_hardware_cursor_ms_x11, "hardware_cursor_ms_x11",
+ s3_h_blank_extend, "h_blank_extend",
+ s3_h_sync_extend, "h_sync_extend",
+ s3_enable_2d_3d, "enable_2d_3d",
+ s3_pci_disconnect_enable, "pci_disconnect_enable",
+ s3_pci_retry_enable, "pci_retry_enable",
+ s3_color_mode, "color_mode",
+ s3_screen_off, "screen_off",
+ s3_unlock_extended_sequencer, "unlock_extended_sequencer",
+ s3_disable_io_ports, "disable_io_ports",
+ s3_hsync_control, "hsync_control",
+ s3_vsync_control, "vsync_control",
+ s3_mclk_n, "mclk_n",
+ s3_mclk_r, "mclk_r",
+ s3_mclk_m, "mclk_m",
+ s3_dclk_n, "dclk_n",
+ s3_dclk_r, "dclk_r",
+ s3_dclk_m, "dclk_m",
+ s3_mclk_load, "mclk_load",
+ s3_dclk_load, "dclk_load",
+ s3_dclk_over_2, "dclk_over_2",
+ s3_clock_load_imm, "clock_load_imm",
+ s3_dclk_invert, "dclk_invert",
+ s3_enable_clock_double, "enable_clock_double",
+ s3_dclk_double_15_16_invert, "dclk_double_15_16_invert",
+ s3_enable_gamma_correction, "enable_gamma_correction",
+ s3_enable_8_bit_luts, "enable_8_bit_luts",
+ s3_dclk_control, "dclk_control",
+ s3_vga_dclk_n, "vga_dclk_n",
+ s3_vga_dclk_r, "vga_dclk_r",
+ s3_vga_dclk_m1, "vga_dclk_m1",
+ s3_vga_dclk_m2, "vga_dclk_m2",
+ s3_vga_clk_select, "vga_clk_select",
+ s3_clock_select, "clock_select",
+};
+
+#define NUM_S3_VREGS (sizeof (s3VRegs)/ sizeof (s3VRegs[0]))
+
+main (int argc, char **argv)
+{
+ int i;
+
+ iopl(3);
+ s3SetImm(s3_register_lock_1, 0x48);
+ s3SetImm(s3_register_lock_2, 0xa0);
+ s3SetImm(s3_unlock_extended_sequencer, 0x06);
+ for (i = 0; i < NUM_S3_VREGS; i++)
+ printf ("%-20.20s %8x\n", s3VRegs[i].name, s3Get (s3VRegs[i].reg));
+ s3Restore ();
+}
diff --git a/xc/programs/Xserver/hw/kdrive/savage/s3stub.c b/xc/programs/Xserver/hw/kdrive/savage/s3stub.c
new file mode 100644
index 000000000..8819e62e1
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/savage/s3stub.c
@@ -0,0 +1,87 @@
+/*
+ * $Id: s3stub.c,v 1.1 2000/01/06 12:55:52 faith 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/savage/s3stub.c,v 1.2 1999/12/30 03:03:13 robin Exp $ */
+
+#include "s3.h"
+
+void
+InitCard (char *name)
+{
+ KdCardAttr attr;
+#ifdef VXWORKS
+ attr.naddr = 2;
+ attr.io = 0;
+ attr.address[0] = 0xbc000000; /* registers */
+ attr.address[1] = 0xba000000; /* frame buffer */
+ KdCardInfoAdd (&s3Funcs, &attr, 0);
+#else
+ CARD32 count;
+
+ count = 0;
+ while (LinuxFindPci (0x5333, 0x8a22, count, &attr))
+ {
+ KdCardInfoAdd (&s3Funcs, &attr, 0);
+ count++;
+ }
+#endif
+}
+
+void
+InitOutput (ScreenInfo *pScreenInfo, int argc, char **argv)
+{
+ KdInitOutput (pScreenInfo, argc, argv);
+}
+
+void
+InitInput (int argc, char **argv)
+{
+#ifdef VXWORKS
+ KdInitInput (&VxWorksMouseFuncs, &VxWorksKeyboardFuncs);
+#endif
+#ifdef linux
+ KdInitInput (&Ps2MouseFuncs, &LinuxKeyboardFuncs);
+#endif
+}
+
+extern int s3CpuTimeout;
+extern int s3AccelTimeout;
+
+int
+ddxProcessArgument (int argc, char **argv, int i)
+{
+ int ret;
+
+ if (!strcmp (argv[i], "-cpu"))
+ {
+ s3CpuTimeout = strtol(argv[i+1], NULL, 0);
+ return 2;
+ }
+ if (!strcmp (argv[i], "-accel"))
+ {
+ s3AccelTimeout = strtol (argv[i+1], NULL, 0);
+ return 2;
+ }
+ return KdProcessArgument (argc, argv, i);
+}
diff --git a/xc/programs/Xserver/hw/kdrive/sis530/Imakefile b/xc/programs/Xserver/hw/kdrive/sis530/Imakefile
new file mode 100644
index 000000000..eb750d928
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/sis530/Imakefile
@@ -0,0 +1,15 @@
+XCOMM $XConsortium: Imakefile /main/10 1996/12/02 10:20:33 lehors $
+XCOMM $XFree86: xc/programs/Xserver/hw/kdrive/sis530/Imakefile,v 1.1 1999/11/19 13:53:58 hohndel Exp $
+#include <Server.tmpl>
+
+SRCS = sis.c sisclock.c siscmap.c siscurs.c sisdraw.c sisio.c sisstub.c
+
+OBJS = sis.o sisclock.o siscmap.o siscurs.o sisdraw.o sisio.o sisstub.o
+
+INCLUDES = -I.. -I. -I$(XBUILDINCDIR) -I$(FONTINCSRC) \
+ -I../../../fb -I../../../mi -I../../../include -I../../../os \
+ -I$(EXTINCSRC) -I$(XINCLUDESRC)
+
+NormalLibraryObjectRule()
+NormalLibraryTarget(sis530,$(OBJS))
+DependTarget()
diff --git a/xc/programs/Xserver/hw/kdrive/sis530/sis.c b/xc/programs/Xserver/hw/kdrive/sis530/sis.c
new file mode 100644
index 000000000..20efd5aa0
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/sis530/sis.c
@@ -0,0 +1,955 @@
+/*
+ * $Id: sis.c,v 1.1 2000/01/06 12:55:52 faith 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/sis530/sis.c,v 1.2 1999/12/30 03:03:14 robin Exp $ */
+
+#include "sis.h"
+
+#define MAX_FB_SIZE (4096 * 1024)
+
+#define MMIO_SIZE (64 * 1024)
+
+#define SIS_TIMING_BAIL 2
+
+SisTiming sisTimings[] = {
+ /* FP BP BLANK */
+ { 640, 480, 85,
+ 56, 80, 192, /* horizontal 43.265 KHz */
+ 1, 25, 29, /* vertical 85.000 Hz */
+ /* pixel 35.996 MHz */
+ },
+
+ { 640, 480, 75,
+ 16, 120, 200, /* horizontal 37.500 KHz */
+ 1, 16, 20, /* vertical 75.000 Hz */
+ /* pixel 31.500 MHz */
+ },
+
+ { 640, 480, 60,
+ 16, 48, 160, /* horizontal 31.321 KHz */
+ 10, 33, 45, /* vertical 59.568 Hz */
+ /* pixel 25.057 MHz */
+ },
+
+ { 800, 600, 85,
+ 32, 152, 248, /* horizontal 53.673 KHz */
+ 1, 27, 31, /* vertical 85.060 Hz */
+ /* pixel 56.249 MHz */
+ },
+ { 800, 600, 75,
+ 16, 160, 256, /* horizontal 46.891 KHz */
+ 1, 21, 25, /* vertical 75.025 Hz */
+ /* pixel 49.516 MHz */
+ },
+ { 800, 600, 72,
+ 56, 64, 240, /* horizontal 48.186 KHz */
+ 37, 23, 66, /* vertical 72.351 Hz */
+ /* pixel 50.113 MHz */
+ },
+
+ { 1024, 768, 85,
+ 48, 208, 352, /* horizontal 68.676 KHz */
+ 1, 36, 40, /* vertical 84.996 Hz */
+ /* pixel 94.499 MHz */
+ },
+ { 1024, 768, 75,
+ 16, 176, 288, /* horizontal 60.022 KHz */
+ 1, 28, 32, /* vertical 75.028 Hz */
+ /* pixel 78.749 MHz */
+ },
+ { 1024, 768, 70,
+ 24, 144, 304, /* horizontal 56.604 KHz */
+ 3, 29, 38, /* vertical 70.227 Hz */
+ /* pixel 75.170 MHz */
+ },
+ { 1024, 768, 66,
+ 24, 144, 304, /* horizontal 53.234 KHz */
+ 3, 29, 38, /* vertical 66.047 Hz */
+ /* pixel 70.695 MHz */
+ },
+
+ { 1152, 900, 85,
+ 48, 208, 384, /* horizontal 79.900 KHz */
+ 1, 32, 38, /* vertical 85.181 Hz */
+ /* pixel 122.726 MHz */
+ },
+ { 1152, 900, 75,
+ 32, 208, 384, /* horizontal 70.495 Khz */
+ 1, 32, 38, /* vertical 75.154 Hz */
+ /* pixel 108.280 MHz */
+ },
+ { 1152, 900, 70,
+ 32, 208, 384, /* horizontal 65.251 KHz */
+ 2, 32, 38, /* vertical 69.564 Hz */
+ /* pixel 100.226 MHz */
+ },
+ { 1152, 900, 66,
+ 32, 208, 384, /* horizontal 61.817 KHz */
+ 1, 32, 38, /* vertical 65.903 Hz */
+ /* pixel 94.951 MHz */
+ },
+ { 1280, 1024, 85,
+ 16, 248, 416, /* horizontal 90.561 KHz */
+ 1, 40, 45, /* vertical 84.717 Hz */
+ /* pixel 153.593 MHz */
+ },
+ { 1280, 1024, 75,
+ 16, 248, 408, /* horizontal 80.255 KHz */
+ 1, 38, 42, /* vertical 75.285 Hz */
+ /* pixel 134.828 MHz */
+ },
+ { 1280, 1024, 70,
+ 32, 248, 400, /* horizontal 74.573 KHz */
+ 0, 36, 39, /* vertical 70.153 Hz */
+ /* pixel 125.283 MHz */
+ },
+ { 1280, 1024, 66,
+ 32, 248, 400, /* horizontal 70.007 KHz */
+ 0, 36, 39, /* vertical 65.858 Hz */
+ /* pixel 117.612 MHz */
+ },
+
+ { 1600, 1200, 85,
+ 64, 304, 560, /* horizontal 106.059 KHz */
+ 1, 46, 50, /* vertical 84.847 Hz */
+ /* pixel 229.088 MHz */
+ },
+ { 1600, 1200, 75,
+ 64, 304, 560, /* horizontal 93.748 KHz */
+ 1, 46, 50, /* vertical 74.999 Hz */
+ /* pixel 202.497 MHz */
+ },
+ { 1600, 1200, 70,
+ 56, 304, 588, /* horizontal 87.524 KHz */
+ 1, 46, 50, /* vertical 70.019 Hz */
+ /* pixel 191.503 MHz */
+ },
+ { 1600, 1200, 65,
+ 56, 308, 524, /* horizontal 80.050 KHz */
+ 1, 38, 42, /* vertical 64.453 Hz */
+ /* pixel 170.026 MHz */
+ },
+};
+
+#define NUM_SIS_TIMINGS (sizeof (sisTimings) / sizeof (sisTimings[0]))
+
+Bool
+sisCardInit (KdCardInfo *card)
+{
+ SisCardInfo *sisc;
+ SisPtr sis;
+ int size;
+ CARD8 *registers;
+ CARD8 *temp_buffer;
+
+ sisc = (SisCardInfo *) xalloc (sizeof (SisCardInfo));
+ if (!sisc)
+ goto bail0;
+
+ temp_buffer = KdMapDevice (card->attr.address[0], MAX_FB_SIZE);
+ if (!temp_buffer)
+ goto bail1;
+
+ sisc->memory = KdFrameBufferSize (temp_buffer, MAX_FB_SIZE);
+
+ KdUnmapDevice (temp_buffer, MAX_FB_SIZE);
+
+ if (!sisc->memory)
+ {
+ ErrorF ("Can't detect SiS530 frame buffer\n");
+ goto bail1;
+ }
+
+ /*
+ * Map frame buffer and MMIO registers
+ */
+ sisc->frameBuffer = KdMapDevice (card->attr.address[0], sisc->memory);
+ if (!sisc->frameBuffer)
+ goto bail1;
+
+ sisc->registers = KdMapDevice (card->attr.address[1], MMIO_SIZE);
+ if (!sisc->registers)
+ goto bail2;
+
+ /*
+ * Offset from base of MMIO to registers
+ */
+ sisc->sis = (SisPtr) (sisc->registers + SIS_MMIO_OFFSET);
+ sisc->cpu_bitblt = (VOL32 *) sisc->registers;
+ sisc->io_base = card->attr.io;
+
+ /*
+ * enable access to SiS ports (no MMIO available)
+ */
+ ioperm (sisc->io_base, 0x80, 1);
+ card->driver = sisc;
+
+ return TRUE;
+bail2:
+ KdUnmapDevice (sisc->frameBuffer, sisc->memory);
+bail1:
+ xfree (sisc);
+bail0:
+ return FALSE;
+}
+
+SisTiming *
+sisGetTiming (int width, int height, int rate)
+{
+ int i;
+ SisTiming *t;
+
+ for (i = 0; i < NUM_SIS_TIMINGS; i++)
+ {
+ t = &sisTimings[i];
+ if (t->horizontal >= width &&
+ t->vertical >= height &&
+ (!rate || t->rate <= rate))
+ return t;
+ }
+ return &sisTimings[SIS_TIMING_BAIL];
+}
+
+Bool
+sisScreenInit (KdScreenInfo *screen)
+{
+ KdCardInfo *card = screen->card;
+ SisCardInfo *sisc = (SisCardInfo *) card->driver;
+ SisScreenInfo *siss;
+ int i;
+ SisTiming *t;
+ CARD32 memory;
+ int byte_width, pixel_width, screen_size;
+
+ siss = (SisScreenInfo *) xalloc (sizeof (SisScreenInfo));
+ if (!siss)
+ return FALSE;
+
+ memset (siss, '\0', sizeof (SisScreenInfo));
+
+ if (!screen->width || !screen->height)
+ {
+ screen->width = 800;
+ screen->height = 600;
+ screen->rate = 72;
+ }
+ if (!screen->depth)
+ screen->depth = 8;
+
+ for (;;)
+ {
+ if (screen->depth >= 24)
+ {
+ screen->depth = 24;
+ screen->bitsPerPixel = 24;
+ }
+ else if (screen->depth >= 16)
+ {
+ screen->depth = 16;
+ screen->bitsPerPixel = 16;
+ }
+ else if (screen->depth >= 15)
+ {
+ screen->depth = 15;
+ screen->bitsPerPixel = 16;
+ }
+ else
+ {
+ screen->depth = 8;
+ screen->bitsPerPixel = 8;
+ }
+
+ /* Normalize width to supported values */
+
+ if (screen->width >= 1600)
+ screen->width = 1600;
+ else if (screen->width >= 1280)
+ screen->width = 1280;
+ else if (screen->width >= 1152)
+ screen->width = 1152;
+ else if (screen->width >= 1024)
+ screen->width = 1024;
+ else if (screen->width >= 800)
+ screen->width = 800;
+ else
+ screen->width = 640;
+
+ byte_width = screen->width * (screen->bitsPerPixel >> 3);
+ pixel_width = screen->width;
+ screen->pixelStride = pixel_width;
+ screen->byteStride = byte_width;
+
+ screen_size = byte_width * screen->height;
+
+ if (screen_size <= sisc->memory)
+ break;
+
+ /*
+ * Fix requested depth and geometry until it works
+ */
+ if (screen->depth > 16)
+ screen->depth = 16;
+ else if (screen->depth > 8)
+ screen->depth = 8;
+ else if (screen->width > 1152)
+ {
+ screen->width = 1152;
+ screen->height = 900;
+ }
+ else if (screen->width > 1024)
+ {
+ screen->width = 1024;
+ screen->height = 768;
+ }
+ else if (screen->width > 800)
+ {
+ screen->width = 800;
+ screen->height = 600;
+ }
+ else if (screen->width > 640)
+ {
+ screen->width = 640;
+ screen->height = 480;
+ }
+ else
+ {
+ xfree (siss);
+ return FALSE;
+ }
+ }
+
+ t = sisGetTiming (screen->width, screen->height, screen->rate);
+ screen->rate = t->rate;
+ screen->width = t->horizontal;
+ screen->height = t->vertical;
+
+ /*
+ * Take requested geometry and adjust to fit possible geometries
+ */
+ switch (screen->depth) {
+ case 4:
+ screen->bitsPerPixel = 4;
+ break;
+ case 8:
+ screen->bitsPerPixel = 8;
+ break;
+ case 15:
+ case 16:
+ screen->bitsPerPixel = 16;
+ break;
+ case 24:
+ case 32:
+ screen->bitsPerPixel = 24;
+ screen->dumb = TRUE;
+ break;
+ }
+
+ screen->byteStride = screen->width * (screen->bitsPerPixel >> 3);
+ screen->pixelStride = screen->width;
+
+ memory = sisc->memory - screen_size;
+
+ screen->frameBuffer = sisc->frameBuffer;
+
+ /*
+ * Cursor lives in the last 16k of memory
+ */
+ if (memory >= 16384 && !screen->softCursor)
+ {
+ siss->cursor_base = sisc->frameBuffer + (sisc->memory - 16384);
+ siss->cursor_off = siss->cursor_base - sisc->frameBuffer;
+ memory -= 16384;
+ }
+ else
+ {
+ screen->softCursor = TRUE;
+ siss->cursor_base = 0;
+ siss->cursor_off = 0;
+ }
+
+ if (memory > 8192)
+ {
+ siss->expand = screen->frameBuffer + screen_size;
+ siss->expand_off = siss->expand - sisc->frameBuffer;
+ siss->expand_len = memory;
+ memory = 0;
+ }
+ else
+ {
+ siss->expand = 0;
+ siss->expand_len = 0;
+ }
+
+ switch (screen->depth) {
+ case 8:
+ screen->visuals = ((1 << StaticGray) |
+ (1 << GrayScale) |
+ (1 << StaticColor) |
+ (1 << PseudoColor) |
+ (1 << TrueColor) |
+ (1 << DirectColor));
+ screen->blueMask = 0x00;
+ screen->greenMask = 0x00;
+ screen->redMask = 0x00;
+ break;
+ case 15:
+ screen->visuals = (1 << TrueColor);
+ screen->blueMask = 0x001f;
+ screen->greenMask = 0x03e0;
+ screen->redMask = 0x7c00;
+ break;
+ case 16:
+ screen->visuals = (1 << TrueColor);
+ screen->blueMask = 0x001f;
+ screen->greenMask = 0x07e0;
+ screen->redMask = 0xf800;
+ break;
+ case 24:
+ screen->visuals = (1 << TrueColor);
+ screen->blueMask = 0x0000ff;
+ screen->greenMask = 0x00ff00;
+ screen->redMask = 0xff0000;
+ break;
+ }
+
+ screen->driver = siss;
+
+ return TRUE;
+}
+
+static void
+_sisGetCrtc (SisCardInfo *sisc, SisCrtc *crtc)
+{
+ crtc->misc_output = _sisInb(sisc->io_base+0x4c);
+ crtc->h_total_0_7 = GetCrtc (sisc, 0x00);
+ crtc->h_display_end_0_7 = GetCrtc (sisc, 0x01);
+ crtc->h_blank_start_0_7 = GetCrtc (sisc, 0x02);
+ crtc->_h_blank_end = GetCrtc (sisc, 0x03);
+ crtc->h_sync_start_0_7 = GetCrtc (sisc, 0x04);
+ crtc->_h_sync_end = GetCrtc (sisc, 0x05);
+ crtc->v_total_0_7 = GetCrtc (sisc, 0x06);
+ crtc->crtc_overflow = GetCrtc (sisc, 0x07);
+ crtc->preset_row_scan = GetCrtc (sisc, 0x08);
+ crtc->_max_scan_line = GetCrtc (sisc, 0x09);
+
+ crtc->start_address_8_15 = GetCrtc (sisc, 0x0c);
+ crtc->start_address_0_7 = GetCrtc (sisc, 0x0d);
+
+ crtc->v_retrace_start_0_7 = GetCrtc (sisc, 0x10);
+ crtc->_v_retrace_end = GetCrtc (sisc, 0x11);
+ crtc->v_display_end_0_7 = GetCrtc (sisc, 0x12);
+ crtc->screen_off_0_7 = GetCrtc (sisc, 0x13);
+ crtc->_underline_location = GetCrtc (sisc, 0x14);
+ crtc->v_blank_start_0_7 = GetCrtc (sisc, 0x15);
+ crtc->v_blank_end_0_7 = GetCrtc (sisc, 0x16);
+ crtc->crtc_mode = GetCrtc (sisc, 0x17);
+
+ crtc->line_compare_0_7 = GetCrtc (sisc, 0x18);
+
+ crtc->mode_control = GetArtc (sisc, 0x10);
+ crtc->screen_border_color = GetArtc (sisc, 0x11);
+ crtc->enable_color_plane = GetArtc (sisc, 0x12);
+ crtc->horizontal_pixel_pan = GetArtc (sisc, 0x13);
+
+ crtc->mode_register = GetGrtc (sisc, 0x5);
+
+ crtc->clock_mode = GetSrtc (sisc, 0x1);
+
+ crtc->graphics_mode = GetSrtc (sisc, 0x6);
+ crtc->misc_control_0 = GetSrtc (sisc, 0x7);
+ crtc->crt_cpu_threshold_control_0 = GetSrtc (sisc, 0x8);
+ crtc->crt_cpu_threshold_control_1 = GetSrtc (sisc, 0x9);
+ crtc->extended_crt_overflow = GetSrtc (sisc, 0xa);
+ crtc->misc_control_1 = GetSrtc (sisc, 0xb);
+ crtc->misc_control_2 = GetSrtc (sisc, 0xc);
+
+ crtc->ddc_and_power_control = GetSrtc (sisc, 0x11);
+ crtc->extended_horizontal_overflow = GetSrtc (sisc, 0x12);
+ crtc->extended_clock_generator = GetSrtc (sisc, 0x13);
+ crtc->cursor_0_red = GetSrtc (sisc, 0x14);
+ crtc->cursor_0_green = GetSrtc (sisc, 0x15);
+ crtc->cursor_0_blue = GetSrtc (sisc, 0x16);
+ crtc->cursor_1_red = GetSrtc (sisc, 0x17);
+ crtc->cursor_1_green = GetSrtc (sisc, 0x18);
+ crtc->cursor_1_blue = GetSrtc (sisc, 0x19);
+ crtc->cursor_h_start_0_7 = GetSrtc (sisc, 0x1a);
+ crtc->cursor_h_start_1 = GetSrtc (sisc, 0x1b);
+ crtc->cursor_h_preset_0_5 = GetSrtc (sisc, 0x1c);
+ crtc->cursor_v_start_0_7 = GetSrtc (sisc, 0x1d);
+ crtc->cursor_v_start_1 = GetSrtc (sisc, 0x1e);
+ crtc->cursor_v_preset_0_5 = GetSrtc (sisc, 0x1f);
+ crtc->linear_base_19_26 = GetSrtc (sisc, 0x20);
+ crtc->linear_base_1 = GetSrtc (sisc, 0x21);
+
+ crtc->graphics_engine_0 = GetSrtc (sisc, 0x26);
+ crtc->graphics_engine_1 = GetSrtc (sisc, 0x27);
+ crtc->internal_mclk_0 = GetSrtc (sisc, 0x28);
+ crtc->internal_mclk_1 = GetSrtc (sisc, 0x29);
+ crtc->internal_vclk_0 = GetSrtc (sisc, 0x2A);
+ crtc->internal_vclk_1 = GetSrtc (sisc, 0x2B);
+
+ crtc->misc_control_7 = GetSrtc (sisc, 0x38);
+
+ crtc->misc_control_11 = GetSrtc (sisc, 0x3E);
+ crtc->misc_control_12 = GetSrtc (sisc, 0x3F);
+}
+
+static void
+_sisSetBlank (SisCardInfo *sisc, Bool blank)
+{
+ CARD8 clock;
+
+ clock = GetSrtc (sisc, 0x01);
+ if (blank)
+ clock |= 0x20;
+ else
+ clock &= ~0x20;
+ PutSrtc (sisc, 0x01, clock);
+}
+
+static void
+_sisSetCrtc (SisCardInfo *sisc, SisCrtc *crtc)
+{
+ _sisOutb(crtc->misc_output, sisc->io_base+0x4c);
+ _sisSetBlank (sisc, TRUE);
+ PutCrtc (sisc, 0x00, crtc->h_total_0_7);
+ PutCrtc (sisc, 0x01, crtc->h_display_end_0_7);
+ PutCrtc (sisc, 0x02, crtc->h_blank_start_0_7);
+ PutCrtc (sisc, 0x03, crtc->_h_blank_end);
+ PutCrtc (sisc, 0x04, crtc->h_sync_start_0_7);
+ PutCrtc (sisc, 0x05, crtc->_h_sync_end);
+ PutCrtc (sisc, 0x06, crtc->v_total_0_7);
+ PutCrtc (sisc, 0x07, crtc->crtc_overflow);
+ PutCrtc (sisc, 0x08, crtc->preset_row_scan);
+ PutCrtc (sisc, 0x09, crtc->_max_scan_line);
+
+ PutCrtc (sisc, 0x0c, crtc->start_address_8_15);
+ PutCrtc (sisc, 0x0d, crtc->start_address_0_7);
+
+ PutCrtc (sisc, 0x10, crtc->v_retrace_start_0_7);
+ PutCrtc (sisc, 0x11, crtc->_v_retrace_end);
+ PutCrtc (sisc, 0x12, crtc->v_display_end_0_7);
+ PutCrtc (sisc, 0x13, crtc->screen_off_0_7);
+ PutCrtc (sisc, 0x14, crtc->_underline_location);
+ PutCrtc (sisc, 0x15, crtc->v_blank_start_0_7);
+ PutCrtc (sisc, 0x16, crtc->v_blank_end_0_7);
+ PutCrtc (sisc, 0x17, crtc->crtc_mode);
+ PutCrtc (sisc, 0x18, crtc->line_compare_0_7);
+
+ PutArtc (sisc, 0x10, crtc->mode_control);
+ PutArtc (sisc, 0x11, crtc->screen_border_color);
+ PutArtc (sisc, 0x12, crtc->enable_color_plane);
+ PutArtc (sisc, 0x13, crtc->horizontal_pixel_pan);
+
+ PutGrtc (sisc, 0x5, crtc->mode_register);
+
+ PutSrtc (sisc, 0x1, crtc->clock_mode | 0x20);
+
+ PutSrtc (sisc, 0x6, crtc->graphics_mode);
+ PutSrtc (sisc, 0x7, crtc->misc_control_0);
+ PutSrtc (sisc, 0x8, crtc->crt_cpu_threshold_control_0);
+ PutSrtc (sisc, 0x9, crtc->crt_cpu_threshold_control_1);
+ PutSrtc (sisc, 0xa, crtc->extended_crt_overflow);
+ PutSrtc (sisc, 0xb, crtc->misc_control_1);
+ PutSrtc (sisc, 0xc, crtc->misc_control_2);
+
+ PutSrtc (sisc, 0x11, crtc->ddc_and_power_control);
+ PutSrtc (sisc, 0x12, crtc->extended_horizontal_overflow);
+ PutSrtc (sisc, 0x13, crtc->extended_clock_generator);
+ PutSrtc (sisc, 0x14, crtc->cursor_0_red);
+ PutSrtc (sisc, 0x15, crtc->cursor_0_green);
+ PutSrtc (sisc, 0x16, crtc->cursor_0_blue);
+ PutSrtc (sisc, 0x17, crtc->cursor_1_red);
+ PutSrtc (sisc, 0x18, crtc->cursor_1_green);
+ PutSrtc (sisc, 0x19, crtc->cursor_1_blue);
+ PutSrtc (sisc, 0x1a, crtc->cursor_h_start_0_7);
+ PutSrtc (sisc, 0x1b, crtc->cursor_h_start_1);
+ PutSrtc (sisc, 0x1c, crtc->cursor_h_preset_0_5);
+ PutSrtc (sisc, 0x1d, crtc->cursor_v_start_0_7);
+ PutSrtc (sisc, 0x1e, crtc->cursor_v_start_1);
+ PutSrtc (sisc, 0x1f, crtc->cursor_v_preset_0_5);
+ PutSrtc (sisc, 0x20, crtc->linear_base_19_26);
+ PutSrtc (sisc, 0x21, crtc->linear_base_1);
+
+ PutSrtc (sisc, 0x26, crtc->graphics_engine_0);
+ PutSrtc (sisc, 0x27, crtc->graphics_engine_1);
+ PutSrtc (sisc, 0x28, crtc->internal_mclk_0);
+ PutSrtc (sisc, 0x29, crtc->internal_mclk_1);
+ PutSrtc (sisc, 0x2A, crtc->internal_vclk_0);
+ PutSrtc (sisc, 0x2B, crtc->internal_vclk_1);
+
+ PutSrtc (sisc, 0x38, crtc->misc_control_7);
+
+ PutSrtc (sisc, 0x3E, crtc->misc_control_11);
+ PutSrtc (sisc, 0x3F, crtc->misc_control_12);
+
+ _sisSetBlank (sisc, FALSE);
+}
+
+CARD8
+_sisReadIndexRegister (CARD32 base, CARD8 index)
+{
+ CARD8 ret;
+
+ _sisOutb (index, base);
+ ret = _sisInb (base+1);
+ return ret;
+}
+
+void
+_sisWriteIndexRegister (CARD32 base, CARD8 index, CARD8 value)
+{
+ _sisOutb (index, base);
+ _sisOutb (value, base+1);
+}
+
+void
+sisPreserve (KdCardInfo *card)
+{
+ SisCardInfo *sisc = card->driver;
+ CARD8 *r = sisc->registers;
+ int a, i, l;
+ CARD8 line[16];
+ CARD8 prev[16];
+ BOOL gotone;
+
+ sisc->save.sr5 = GetSrtc(sisc,0x5);
+ if (sisc->save.sr5 != 0x21)
+ sisc->save.sr5 = 0x86;
+ /* unlock extension registers */
+ PutSrtc(sisc,0x5,0x86);
+
+ /* enable MMIO access to registers */
+ sisc->save.srb = GetSrtc(sisc,0xb);
+ PutSrtc(sisc, 0xb, sisc->save.srb | 0x60);
+ _sisGetCrtc (sisc, &sisc->save.crtc);
+}
+
+void
+sisEnable (ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ KdCardInfo *card = pScreenPriv->card;
+ SisCardInfo *sisc = card->driver;
+ SisScreenInfo *siss = screen->driver;
+ SisTiming *t;
+ SisCrtc crtc;
+ unsigned long pixel;
+
+ int hactive;
+ int hblank;
+ int hfp;
+ int hbp;
+
+ int vactive;
+ int vblank;
+ int vfp;
+ int vbp;
+
+ int h_total;
+ int h_display_end;
+ int h_blank_start;
+ int h_blank_end;
+ int h_sync_start;
+ int h_sync_end;
+ int h_screen_off;
+
+ int h_adjust;
+
+ int v_total;
+ int v_retrace_start;
+ int v_retrace_end;
+ int v_display_end;
+ int v_blank_start;
+ int v_blank_end;
+
+ crtc = sisc->save.crtc;
+
+ t = sisGetTiming (screen->width, screen->height, screen->rate);
+
+ /* CR11 */
+ crtc.disable_v_retrace_int = 1;
+
+ /* 3CC/3C2 */
+ crtc.io_address_select = 1;
+ crtc.display_ram_enable = 1;
+ crtc.clock_select = 3;
+
+ /* SR6 */
+ crtc.graphics_mode = 0;
+ crtc.graphics_mode_linear = 1;
+ crtc.enhanced_graphics_mode = 1;
+
+ /* SRB */
+ crtc.cpu_bitblt_enable = 1;
+ crtc.memory_mapped_mode = 3;
+
+ /* SRC */
+ crtc.graphics_mode_32bit_enable = 1;
+ crtc.text_mode_16bit_enable = 0;
+ crtc.read_ahead_enable = 1;
+
+ /* SR11 */
+ crtc.acpi_enable = 0;
+ crtc.kbd_cursor_activate = 0;
+ crtc.video_memory_activate = 0;
+ crtc.vga_standby = 0;
+ crtc.vga_suspend = 0;
+
+ /* AR10 */
+ crtc.mode_control = 0;
+ crtc.graphics_mode_enable = 1;
+ /* AR11 */
+ crtc.screen_border_color = 0;
+ /* AR12 */
+ crtc.enable_color_plane = 0xf;
+ /* AR13 */
+ crtc.horizontal_pixel_pan = 0;
+
+ /* SR27 */
+ crtc.logical_screen_width = 3;
+ crtc.graphics_prog_enable = 1;
+
+ /* SR38 */
+ crtc.extended_clock_select = 0;
+
+ if (siss->cursor_base)
+ {
+ crtc_set_cursor_start_addr (&crtc, siss->cursor_off);
+ crtc.graphics_mode_hw_cursor = 0;
+ }
+
+ hactive = t->horizontal;
+ hblank = t->hblank;
+ hbp = t->hbp;
+ hfp = t->hfp;
+
+ vactive = t->vertical;
+ vblank = t->vblank;
+ vbp = t->vbp;
+ vfp = t->vfp;
+
+ pixel = (hactive + hblank) * (vactive + vblank) * t->rate;
+
+ switch (screen->bitsPerPixel) {
+ case 8:
+ hactive /= 8;
+ hblank /= 8;
+ hfp /= 8;
+ hbp /= 8;
+
+ crtc.color_mode_256 = 1;
+ h_screen_off = hactive;
+ h_adjust = 1;
+
+ break;
+ case 16:
+ hactive /= 8;
+ hblank /= 8;
+ hfp /= 8;
+ hbp /= 8;
+
+ h_screen_off = hactive * 2;
+ h_adjust = 1;
+
+ crtc.color_mode_256 = 0;
+
+ if (screen->depth == 15)
+ crtc.graphics_mode_32k = 1;
+ else
+ crtc.graphics_mode_64k = 1;
+ break;
+ case 24:
+ hactive /= 8;
+ hblank /= 8;
+ hfp /= 8;
+ hbp /= 8;
+
+ h_screen_off = hactive * 3;
+ h_adjust = 1;
+
+ crtc.color_mode_256 = 0;
+
+ /* SR6 */
+ crtc.graphics_mode_true = 1;
+ /* SR7 */
+ crtc.direct_color_24bit = 0;
+ /* SR9 */
+ crtc.true_color_32bpp = 0;
+ /* SRB */
+ crtc.true_color_order = 1;
+ break;
+ case 32:
+ hactive /= 8;
+ hblank /= 8;
+ hfp /= 8;
+ hbp /= 8;
+
+ h_screen_off = hactive * 4;
+ h_adjust = 1;
+
+ crtc.color_mode_256 = 0;
+
+ /* SR6 */
+ crtc.graphics_mode_true = 1;
+ /* SR7 */
+ crtc.direct_color_24bit = 0;
+ /* SR9 */
+ crtc.true_color_32bpp = 1;
+ /* SRB */
+ crtc.true_color_order = 1;
+ break;
+ }
+
+ sisGetClock (pixel, &crtc);
+
+ crtc.high_speed_dac_0 = crtc.high_speed_dac_1 = pixel > 135000000;
+
+ sisEngThresh (&crtc, pixel, screen->bitsPerPixel);
+
+ /*
+ * Compute horizontal register values from timings
+ */
+ h_total = hactive + hblank - 5;
+ h_display_end = hactive - 1;
+ h_blank_start = h_display_end;
+ h_blank_end = h_blank_start + hblank;
+
+ h_sync_start = hactive + hfp + h_adjust;
+ h_sync_end = h_sync_start + hblank - hbp - hfp;
+
+ crtc_set_h_total(&crtc, h_total);
+ crtc_set_h_display_end (&crtc, h_display_end);
+ crtc_set_h_blank_start (&crtc, h_blank_start);
+ crtc_set_h_blank_end (&crtc, h_blank_end);
+ crtc_set_h_sync_start (&crtc, h_sync_start);
+ crtc_set_h_sync_end (&crtc, h_sync_end);
+ crtc_set_screen_off (&crtc, h_screen_off);
+
+ v_total = vactive + vblank - 2;
+ v_retrace_start = vactive + vfp - 1;
+ v_retrace_end = v_retrace_start + vblank - vbp - vfp;
+ v_display_end = vactive - 1;
+ v_blank_start = vactive - 1;
+ v_blank_end = v_blank_start + vblank /* - 1 */;
+
+ crtc_set_v_total(&crtc, v_total);
+ crtc_set_v_retrace_start (&crtc, v_retrace_start);
+ crtc.v_retrace_end_0_3 = v_retrace_end;
+ crtc_set_v_display_end (&crtc, v_display_end);
+ crtc_set_v_blank_start (&crtc, v_blank_start);
+ crtc.v_blank_end_0_7 = v_blank_end;
+
+ _sisSetCrtc (sisc, &crtc);
+}
+
+Bool
+sisDPMS (ScreenPtr pScreen, int mode)
+{
+ KdScreenPriv(pScreen);
+ sisCardInfo(pScreenPriv);
+ union ddc_and_power_control_u _ddc_and_power_control_u;
+
+ ddc_and_power_control = sisc->save.crtc.ddc_and_power_control;
+
+ kbd_cursor_activate = 0;
+ video_memory_activate = 0;
+ vga_standby = 0;
+ vga_suspend = 0;
+ acpi_enable = 0;
+ switch (mode) {
+ case KD_DPMS_NORMAL:
+ break;
+ case KD_DPMS_STANDBY:
+ vga_standby = 1;
+ break;
+ case KD_DPMS_SUSPEND:
+ vga_suspend = 1;
+ break;
+ case KD_DPMS_POWERDOWN:
+ acpi_enable = 1;
+ break;
+ }
+ PutSrtc (sisc, 0x11, ddc_and_power_control);
+ return TRUE;
+}
+
+void
+sisDisable (ScreenPtr pScreen)
+{
+}
+
+void
+sisRestore (KdCardInfo *card)
+{
+ SisCardInfo *sisc = (SisCardInfo *) card->driver;
+
+ _sisSetCrtc (sisc, &sisc->save.crtc);
+ PutSrtc (sisc, 0xb, sisc->save.srb);
+ PutSrtc (sisc, 0x5, sisc->save.sr5);
+}
+
+void
+sisScreenFini (KdScreenInfo *screen)
+{
+ SisScreenInfo *siss = (SisScreenInfo *) screen->driver;
+
+ xfree (siss);
+ screen->driver = 0;
+}
+
+void
+sisCardFini (KdCardInfo *card)
+{
+ SisCardInfo *sisc = (SisCardInfo *) card->driver;
+
+ KdUnmapDevice (sisc->frameBuffer, sisc->memory);
+ KdUnmapDevice (sisc->registers, sizeof (SisRec));
+ ioperm (sisc->io_base, 0x80, 0);
+}
+
+KdCardFuncs sisFuncs = {
+ sisCardInit,
+ sisScreenInit,
+ 0,
+ sisPreserve,
+ sisEnable,
+ sisDPMS,
+ sisDisable,
+ sisRestore,
+ sisScreenFini,
+ sisCardFini,
+ sisCursorInit,
+ sisCursorEnable,
+ sisCursorDisable,
+ sisCursorFini,
+ 0,
+ sisDrawInit,
+ sisDrawEnable,
+ sisDrawSync,
+ sisDrawDisable,
+ sisDrawFini,
+ sisGetColors,
+ sisPutColors,
+};
diff --git a/xc/programs/Xserver/hw/kdrive/sis530/sis.h b/xc/programs/Xserver/hw/kdrive/sis530/sis.h
new file mode 100644
index 000000000..339577751
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/sis530/sis.h
@@ -0,0 +1,1153 @@
+/*
+ * $Id: sis.h,v 1.1 2000/01/06 12:55:53 faith 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/sis530/sis.h,v 1.2 1999/12/30 03:03:14 robin Exp $ */
+
+#ifndef _SIS_H_
+#define _SIS_H_
+#include "kdrive.h"
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <asm/io.h>
+#include <stdio.h>
+
+/*
+ * Linear Addressing 000 0000 - 0ff ffff (16m)
+ * Image data transfer 100 0000 - 100 7fff (32k)
+ * Empty 100 8000 - 100 81ff
+ * MMIO registers 100 8200 - 100 8480
+ *
+ * We don't care about the image transfer or PCI regs, so
+ * this structure starts at the MMIO regs
+ */
+
+typedef volatile CARD32 VOL32;
+typedef volatile CARD16 VOL16;
+typedef volatile CARD8 VOL8;
+
+#define SIS_MMIO_OFFSET 0x8200
+
+typedef struct _sis530General {
+ VOL32 src_base; /* 8200 */
+ VOL16 src_pitch; /* 8204 */
+ VOL16 _pad0; /* 8206 */
+ VOL16 src_y; /* 8208 */
+ VOL16 src_x; /* 820a */
+ VOL16 dst_y; /* 820c */
+ VOL16 dst_x; /* 820e */
+ VOL32 dst_base; /* 8210 */
+ VOL16 dst_pitch; /* 8214 */
+ VOL16 dst_height; /* 8216 */
+ VOL16 rect_width; /* 8218 */
+ VOL16 rect_height; /* 821a */
+ VOL32 pattern_fg; /* 821c */
+ VOL32 pattern_bg; /* 8220 */
+ VOL32 src_fg; /* 8224 */
+ VOL32 src_bg; /* 8228 */
+ VOL8 mask[8]; /* 822c */
+ VOL16 clip_left; /* 8234 */
+ VOL16 clip_top; /* 8236 */
+ VOL16 clip_right; /* 8238 */
+ VOL16 clip_bottom; /* 823a */
+ VOL32 command; /* 823c */
+ VOL32 status; /* 8240 */
+ VOL8 _pad1[0xbc]; /* 8244 */
+ VOL8 pattern[256]; /* 8300 */
+ /* 8400 */
+} SisGeneral;
+
+typedef struct _sis530Line {
+ VOL8 _pad0[8]; /* 8200 */
+ VOL16 x0; /* 8208 */
+ VOL16 y0; /* 820a */
+ VOL16 x1; /* 820c */
+ VOL16 y1; /* 820e */
+ VOL32 dst_base; /* 8210 */
+ VOL16 dst_pitch; /* 8214 */
+ VOL16 dst_height; /* 8216 */
+ VOL16 count; /* 8218 */
+ VOL16 style_period; /* 821a */
+ VOL32 fg; /* 821c */
+ VOL32 bg; /* 8220 */
+ VOL8 _pad1[8]; /* 8224 */
+ VOL32 style0; /* 822c */
+ VOL32 style1; /* 8228 */
+ VOL16 clip_left; /* 8234 */
+ VOL16 clip_top; /* 8236 */
+ VOL16 clip_right; /* 8238 */
+ VOL16 clip_bottom; /* 823a */
+ VOL32 command; /* 823c */
+ VOL32 status; /* 8240 */
+ VOL8 _pad2[0xbc]; /* 8244 */
+ struct {
+ VOL16 x;
+ VOL16 y;
+ } data[96]; /* 8300 */
+ /* 8480 */
+} SisLine;
+
+typedef struct _sis530Transparent {
+ VOL32 src_base; /* 8200 */
+ VOL16 src_pitch; /* 8204 */
+ VOL16 _pad0; /* 8206 */
+ VOL16 src_y; /* 8208 */
+ VOL16 src_x; /* 820a */
+ VOL16 dst_y; /* 820c */
+ VOL16 dst_x; /* 820e */
+ VOL32 dst_base; /* 8210 */
+ VOL16 dst_pitch; /* 8214 */
+ VOL16 dst_height; /* 8216 */
+ VOL16 rect_width; /* 8218 */
+ VOL16 rect_height; /* 821a */
+ VOL32 dst_key_high; /* 821c */
+ VOL32 dst_key_low; /* 8220 */
+ VOL32 src_key_high; /* 8224 */
+ VOL32 src_key_low; /* 8228 */
+ VOL8 _pad1[8]; /* 822c */
+ VOL16 clip_left; /* 8234 */
+ VOL16 clip_top; /* 8236 */
+ VOL16 clip_right; /* 8238 */
+ VOL16 clip_bottom; /* 823a */
+ VOL32 command; /* 823c */
+ VOL32 status; /* 8240 */
+ /* 8244 */
+} SisTransparent;
+
+typedef struct _sis530Multiple {
+ VOL8 _pad0[8]; /* 8200 */
+ VOL16 count; /* 8208 */
+ VOL16 y; /* 820a */
+ VOL16 x0_start; /* 820c */
+ VOL16 x0_end; /* 820e */
+ VOL32 dst_base; /* 8210 */
+ VOL16 dst_pitch; /* 8214 */
+ VOL16 dst_height; /* 8216 */
+ VOL8 _pad1[4]; /* 8218 */
+ VOL32 fg; /* 821c */
+ VOL32 bg; /* 8220 */
+ VOL8 _pad2[8]; /* 8224 */
+ VOL8 mask[8]; /* 822c */
+ VOL16 clip_left; /* 8234 */
+ VOL16 clip_top; /* 8236 */
+ VOL16 clip_right; /* 8238 */
+ VOL16 clip_bottom; /* 823a */
+ VOL32 command; /* 823c */
+ VOL32 status; /* 8240 */
+ VOL16 x1_start; /* 8244 */
+ VOL16 x1_end; /* 8246 */
+ VOL8 _pad3[0xb8]; /* 8248 */
+ VOL8 pattern[64]; /* 8300 */
+ struct {
+ VOL16 x_start;
+ VOL16 y_end;
+ } data[80]; /* 8340 */
+ /* 8480 */
+} SisMultiple;
+
+typedef struct _sis530Trapezoid {
+ VOL8 _pad0[8]; /* 8200 */
+ VOL16 height; /* 8208 */
+ VOL16 y; /* 820a */
+ VOL16 left_x; /* 820c */
+ VOL16 right_x; /* 820e */
+ VOL32 dst_base; /* 8210 */
+ VOL16 dst_pitch; /* 8214 */
+ VOL16 dst_height; /* 8216 */
+ VOL8 _pad1[4]; /* 8218 */
+ VOL32 fg; /* 821c */
+ VOL32 bg; /* 8220 */
+ VOL8 _pad2[8]; /* 8224 */
+ VOL8 mask[8]; /* 822c */
+ VOL16 clip_left; /* 8234 */
+ VOL16 clip_top; /* 8236 */
+ VOL16 clip_right; /* 8238 */
+ VOL16 clip_bottom; /* 823a */
+ VOL32 command; /* 823c */
+ VOL32 status; /* 8240 */
+ VOL16 left_dx; /* 8244 */
+ VOL16 left_dy; /* 8246 */
+ VOL16 right_dx; /* 8248 */
+ VOL16 right_dy; /* 824a */
+ VOL32 left_error; /* 824c */
+ VOL32 right_error; /* 8250 */
+ /* 8254 */
+} SisTrapezoid;
+
+typedef struct _sis530 {
+ union {
+ SisGeneral general;
+ SisLine line;
+ SisTransparent transparent;
+ SisMultiple multiple;
+ SisTrapezoid trapezoid;
+ } u;
+} SisRec, *SisPtr;
+
+typedef struct _sisCursor {
+ int width, height;
+ int xhot, yhot;
+ Bool has_cursor;
+ CursorPtr pCursor;
+} SisCursor;
+
+#define SIS_CURSOR_WIDTH 64
+#define SIS_CURSOR_HEIGHT 64
+
+typedef struct _sisClock {
+ CARD32 vclk_numerator;
+ BOOL vclk_divide_by_2;
+ CARD32 vclk_denominator;
+ CARD32 vclk_post_scale;
+ BOOL vclk_post_scale_2;
+ BOOL high_speed_dac;
+} SisClockRec, *SisClockPtr;
+
+typedef struct _crtc {
+
+ union {
+ struct {
+ CARD8 _io_address_select : 1;
+ CARD8 _display_ram_enable : 1;
+ CARD8 _clock_select : 2;
+ CARD8 : 1;
+ CARD8 _odd_even_page : 1;
+ CARD8 _h_sync_polarity : 1;
+ CARD8 _v_sync_polarity : 1;
+ } _misc_output_s;
+ CARD8 _misc_output;
+ } _misc_output_u; /* 3CC/3C2 */
+
+#define misc_output _misc_output_u._misc_output
+#define io_address_select _misc_output_u._misc_output_s._io_address_select
+#define display_ram_enable _misc_output_u._misc_output_s._display_ram_enable
+#define clock_select _misc_output_u._misc_output_s._clock_select
+#define odd_even_page _misc_output_u._misc_output_s._odd_even_page
+#define h_sync_polarity _misc_output_u._misc_output_s._h_sync_polarity
+#define v_sync_polarity _misc_output_u._misc_output_s._v_sync_polarity
+
+ CARD8 h_total_0_7; /* CR0 */
+ CARD8 h_display_end_0_7; /* CR1 */
+ CARD8 h_blank_start_0_7; /* CR2 */
+ union {
+ struct {
+ CARD8 _h_blank_end_0_4 : 5;
+ CARD8 _display_skew : 2;
+ CARD8 : 1;
+ } _h_blank_end_s;
+ CARD8 __h_blank_end; /* CR3 */
+ } _h_blank_end_u;
+#define h_blank_end_0_4 _h_blank_end_u._h_blank_end_s._h_blank_end_0_4
+#define display_skew _h_blank_end_u._h_blank_end_s._display_skew
+#define _h_blank_end _h_blank_end_u.__h_blank_end
+
+ CARD8 h_sync_start_0_7; /* CR4 */
+
+ union {
+ struct {
+ CARD8 _h_sync_end_0_4 : 5;
+ CARD8 _horizontal_skew : 2;
+ CARD8 _h_blank_end_5 : 1;
+ } _h_sync_end_s;
+ CARD8 __h_sync_end; /* CR5 */
+ } _h_sync_end_u;
+
+#define h_sync_end_0_4 _h_sync_end_u._h_sync_end_s._h_sync_end_0_4
+#define horizontal_skew _h_sync_end_u._h_sync_end_s._horizontal_skew
+#define h_blank_end_5 _h_sync_end_u._h_sync_end_s._h_blank_end_5
+#define _h_sync_end _h_sync_end_u.__h_sync_end
+
+ CARD8 v_total_0_7; /* CR6 */
+
+ union {
+ struct {
+ CARD8 _v_total_8 : 1;
+ CARD8 _v_display_end_8 : 1;
+ CARD8 _v_retrace_start_8 : 1;
+ CARD8 _v_blank_start_8 : 1;
+ CARD8 _line_compare_8 : 1;
+ CARD8 _v_total_9 : 1;
+ CARD8 _v_display_end_9 : 1;
+ CARD8 _v_retrace_start_9 : 1;
+ } _crtc_overflow_s;
+ CARD8 _crtc_overflow; /* CR7 */
+ } _crtc_overflow_u;
+
+#define v_total_8 _crtc_overflow_u._crtc_overflow_s._v_total_8
+#define v_display_end_8 _crtc_overflow_u._crtc_overflow_s._v_display_end_8
+#define v_retrace_start_8 _crtc_overflow_u._crtc_overflow_s._v_retrace_start_8
+#define v_blank_start_8 _crtc_overflow_u._crtc_overflow_s._v_blank_start_8
+#define line_compare_8 _crtc_overflow_u._crtc_overflow_s._line_compare_8
+#define v_total_9 _crtc_overflow_u._crtc_overflow_s._v_total_9
+#define v_display_end_9 _crtc_overflow_u._crtc_overflow_s._v_display_end_9
+#define v_retrace_start_9 _crtc_overflow_u._crtc_overflow_s._v_retrace_start_9
+#define crtc_overflow _crtc_overflow_u._crtc_overflow
+
+ CARD8 preset_row_scan; /* CR8 (unused) */
+
+ union {
+ struct {
+ CARD8 _max_scan_line : 5;
+ CARD8 _v_blank_start_9 : 1;
+ CARD8 _line_compare_9 : 1;
+ CARD8 _double_scan : 1;
+ } _max_scan_line_s;
+ CARD8 __max_scan_line; /* CR9 */
+ } _max_scan_line_u;
+
+#define max_scan_line _max_scan_line_u._max_scan_line_s._max_scan_line
+#define v_blank_start_9 _max_scan_line_u._max_scan_line_s._v_blank_start_9
+#define line_compare_9 _max_scan_line_u._max_scan_line_s._line_compare_9
+#define double_scan _max_scan_line_u._max_scan_line_s._double_scan
+#define _max_scan_line _max_scan_line_u.__max_scan_line
+
+ CARD8 cursor_start;
+ CARD8 cursor_end;
+
+ CARD8 start_address_8_15; /* CRC */
+ CARD8 start_address_0_7; /* CRD */
+
+ CARD8 cursor_loc_high;
+ CARD8 cursor_loc_low;
+
+ CARD8 v_retrace_start_0_7; /* CR10 */
+ union {
+ struct {
+ CARD8 _v_retrace_end_0_3 : 4;
+ CARD8 _clear_v_retrace_int : 1;
+ CARD8 _disable_v_retrace_int : 1;
+ CARD8 _refresh_cycle_select : 1;
+ CARD8 _lock_crtc : 1;
+ } _v_retrace_end_s;
+ CARD8 __v_retrace_end; /* CR11 */
+ } _v_retrace_end_u;
+
+#define v_retrace_end_0_3 _v_retrace_end_u._v_retrace_end_s._v_retrace_end_0_3
+#define clear_v_retrace_int _v_retrace_end_u._v_retrace_end_s._clear_v_retrace_int
+#define disable_v_retrace_int _v_retrace_end_u._v_retrace_end_s._disable_v_retrace_int
+#define refresh_cycle_select _v_retrace_end_u._v_retrace_end_s._refresh_cycle_select
+#define lock_crtc _v_retrace_end_u._v_retrace_end_s._lock_crtc
+#define _v_retrace_end _v_retrace_end_u.__v_retrace_end
+
+ CARD8 v_display_end_0_7; /* CR12 */
+
+ CARD8 screen_off_0_7; /* CR13 */
+
+ union {
+ struct {
+ CARD8 _underline_location : 5;
+ CARD8 _count_by_four : 1;
+ CARD8 _doubleword_mode : 1;
+ CARD8 : 1;
+ } _underline_location_s;
+ CARD8 __underline_location; /* CR14 */
+ } _underline_location_u;
+
+#define underline_location _underline_location_u._underline_location_s._underline_location
+#define count_by_four _underline_location_u._underline_location_s._count_by_four
+#define doubleword_mode _underline_location_u._underline_location_s._doubleword_mode
+#define _underline_location _underline_location_u.__underline_location
+
+ CARD8 v_blank_start_0_7; /* CR15 */
+ CARD8 v_blank_end_0_7; /* CR16 */
+
+ union {
+ struct {
+ CARD8 _two_bk_cga : 1;
+ CARD8 _four_bk_cga : 1;
+ CARD8 _v_total_double : 1;
+ CARD8 _count_by_two : 1;
+ CARD8 : 1;
+ CARD8 _address_wrap : 1;
+ CARD8 _byte_mode : 1;
+ CARD8 _hardware_reset : 1;
+ } _crtc_mode_s;
+ CARD8 _crtc_mode; /* CR17 */
+ } _crtc_mode_u;
+
+#define crtc_mode _crtc_mode_u._crtc_mode
+#define two_bk_cga _crtc_mode_u._crtc_mode_s._two_bk_cga
+#define four_bk_cga _crtc_mode_u._crtc_mode_s._four_bk_cga
+#define v_total_double _crtc_mode_u._crtc_mode_s._v_total_double
+#define count_by_two _crtc_mode_u._crtc_mode_s._count_by_two
+#define address_wrap _crtc_mode_u._crtc_mode_s._address_wrap
+#define byte_mode _crtc_mode_u._crtc_mode_s._byte_mode
+#define hardware_reset _crtc_mode_u._crtc_mode_s._hardware_reset
+
+ CARD8 line_compare_0_7; /* CR18 (unused) */
+
+ union {
+ struct {
+ CARD8 _graphics_mode_enable : 1;
+ CARD8 _attribute_byte_mda : 1;
+ CARD8 _line_graphics_enable : 1;
+ CARD8 _background_blink : 1;
+ CARD8 : 1;
+ CARD8 _pel_panning_compat : 1;
+ CARD8 _pixel_clock_double : 1;
+ CARD8 p4_p5_source_select : 1;
+ } _mode_control_s;
+ CARD8 _mode_control;
+ } _mode_control_u; /* AR10 */
+
+#define mode_control _mode_control_u._mode_control
+#define graphics_mode_enable _mode_control_u._mode_control_s._graphics_mode_enable
+#define pixel_clock_double _mode_control_u._mode_control_s._pixel_clock_double
+
+ CARD8 screen_border_color; /* AR11 */
+ CARD8 enable_color_plane; /* AR12 */
+ CARD8 horizontal_pixel_pan; /* AR13 */
+
+ union {
+ struct {
+ CARD8 _write_mode : 2;
+ CARD8 : 1;
+ CARD8 _read_mode : 1;
+ CARD8 _odd_even_addressing : 1;
+ CARD8 _shift_register_mode : 1;
+ CARD8 _color_mode_256 : 1;
+ CARD8 : 1;
+ } _mode_register_s;
+ CARD8 _mode_register;
+ } _mode_register_u; /* GR5 */
+
+#define mode_register _mode_register_u._mode_register
+#define color_mode_256 _mode_register_u._mode_register_s._color_mode_256
+
+ union {
+ struct {
+ CARD8 _dot_clock_8_9 : 1;
+ CARD8 : 1;
+ CARD8 _shifter_load_16 : 1;
+ CARD8 _dot_clock_divide_2 : 1;
+ CARD8 _shifter_load_32 : 1;
+ CARD8 _display_off : 1;
+ CARD8 : 2;
+ } _clock_mode_s;
+ CARD8 _clock_mode;
+ } _clock_mode_u; /* SR1 */
+
+#define clock_mode _clock_mode_u._clock_mode
+#define dot_clock_8_9 _clock_mode_u._clock_mode_s._dot_clock_8_9
+#define shifter_load_16 _clock_mode_u._clock_mode_s._shifter_load_16
+#define dot_clock_divide_2 _clock_mode_u._clock_mode_s._dot_clock_divide_2
+#define shifter_load_32 _clock_mode_u._clock_mode_s._shifter_load_32
+#define display_off _clock_mode_u._clock_mode_s._display_off
+
+ union {
+ struct {
+ CARD8 _enhanced_text_mode : 1;
+ CARD8 _enhanced_graphics_mode : 1;
+ CARD8 _graphics_mode_32k : 1;
+ CARD8 _graphics_mode_64k : 1;
+ CARD8 _graphics_mode_true : 1;
+ CARD8 _graphics_mode_interlaced: 1;
+ CARD8 _graphics_mode_hw_cursor: 1;
+ CARD8 _graphics_mode_linear : 1;
+ } _graphics_mode_s;
+ CARD8 _graphics_mode;
+ } _graphics_mode_u; /* SR6 */
+
+#define graphics_mode _graphics_mode_u._graphics_mode
+#define enhanced_text_mode _graphics_mode_u._graphics_mode_s._enhanced_text_mode
+#define enhanced_graphics_mode _graphics_mode_u._graphics_mode_s._enhanced_graphics_mode
+#define graphics_mode_32k _graphics_mode_u._graphics_mode_s._graphics_mode_32k
+#define graphics_mode_64k _graphics_mode_u._graphics_mode_s._graphics_mode_64k
+#define graphics_mode_true _graphics_mode_u._graphics_mode_s._graphics_mode_true
+#define graphics_mode_interlaced _graphics_mode_u._graphics_mode_s._graphics_mode_interlaced
+#define graphics_mode_hw_cursor _graphics_mode_u._graphics_mode_s._graphics_mode_hw_cursor
+#define graphics_mode_linear _graphics_mode_u._graphics_mode_s._graphics_mode_linear
+
+ union {
+ struct {
+ CARD8 _external_dac_reference : 1;
+ CARD8 _high_speed_dac_0 : 1;
+ CARD8 _direct_color_24bit : 1;
+ CARD8 _multi_line_prefetch : 1;
+ CARD8 _extended_video_div_2 : 1;
+ CARD8 _ramdac_power_save : 1;
+ CARD8 : 1;
+ CARD8 _merge_video_fifo : 1;
+ } _misc_control_0_s;
+ CARD8 _misc_control_0;
+ } _misc_control_0_u; /* SR7 */
+
+#define misc_control_0 _misc_control_0_u._misc_control_0
+#define external_dac_reference _misc_control_0_u._misc_control_0_s._external_dac_reference
+#define high_speed_dac_0 _misc_control_0_u._misc_control_0_s._high_speed_dac_0
+#define direct_color_24bit _misc_control_0_u._misc_control_0_s._direct_color_24bit
+#define multi_line_prefetch _misc_control_0_u._misc_control_0_s._multi_line_prefetch
+#define extended_video_div_2 _misc_control_0_u._misc_control_0_s._extended_video_div_2
+#define ramdac_power_save _misc_control_0_u._misc_control_0_s._ramdac_power_save
+#define merge_video_fifo _misc_control_0_u._misc_control_0_s._merge_video_fifo
+
+ union {
+ struct {
+ CARD8 _crt_engine_threshold_high_0_3 : 4;
+ CARD8 _crt_cpu_threshold_low_0_3 : 4;
+ } _crt_cpu_threshold_control_0_s;
+ CARD8 _crt_cpu_threshold_control_0;
+ } _crt_cpu_threshold_control_0_u; /* SR8 */
+
+#define crt_cpu_threshold_control_0 _crt_cpu_threshold_control_0_u._crt_cpu_threshold_control_0
+#define crt_engine_threshold_high_0_3 _crt_cpu_threshold_control_0_u._crt_cpu_threshold_control_0_s._crt_engine_threshold_high_0_3
+#define crt_cpu_threshold_low_0_3 _crt_cpu_threshold_control_0_u._crt_cpu_threshold_control_0_s._crt_cpu_threshold_low_0_3
+
+ union {
+ struct {
+ CARD8 _crt_cpu_threshold_high_0_3 : 4;
+ CARD8 _ascii_attribute_threshold_0_2 : 3;
+ CARD8 _true_color_32bpp : 1;
+ } _crt_cpu_threshold_control_1_s;
+ CARD8 _crt_cpu_threshold_control_1;
+ } _crt_cpu_threshold_control_1_u; /* SR9 */
+
+#define crt_cpu_threshold_control_1 _crt_cpu_threshold_control_1_u._crt_cpu_threshold_control_1
+#define crt_cpu_threshold_high_0_3 _crt_cpu_threshold_control_1_u._crt_cpu_threshold_control_1_s._crt_cpu_threshold_high_0_3
+#define ascii_attribute_threshold_0_2 _crt_cpu_threshold_control_1_u._crt_cpu_threshold_control_1_s._ascii_attribute_threshold_0_2
+#define true_color_32bpp _crt_cpu_threshold_control_1_u._crt_cpu_threshold_control_1_s._true_color_32bpp
+
+ union {
+ struct {
+ CARD8 _v_total_10 : 1;
+ CARD8 _v_display_end_10 : 1;
+ CARD8 _v_blank_start_10 : 1;
+ CARD8 _v_retrace_start_10 : 1;
+ CARD8 _screen_off_8_11 : 4;
+ } _extended_crt_overflow_s;
+ CARD8 _extended_crt_overflow;
+ } _extended_crt_overflow_u; /* SRA */
+
+#define extended_crt_overflow _extended_crt_overflow_u._extended_crt_overflow
+#define v_total_10 _extended_crt_overflow_u._extended_crt_overflow_s._v_total_10
+#define v_display_end_10 _extended_crt_overflow_u._extended_crt_overflow_s._v_display_end_10
+#define v_blank_start_10 _extended_crt_overflow_u._extended_crt_overflow_s._v_blank_start_10
+#define v_retrace_start_10 _extended_crt_overflow_u._extended_crt_overflow_s._v_retrace_start_10
+#define screen_off_8_11 _extended_crt_overflow_u._extended_crt_overflow_s._screen_off_8_11
+
+ union {
+ struct {
+ CARD8 _cpu_bitblt_enable : 1; /* enable CPU bitblt */
+ CARD8 _packed_16_color_enable : 1; /* 2 pixels per byte? */
+ CARD8 _io_gating : 1; /* when write buffer not empty */
+ CARD8 _dual_segment_enable : 1; /* ? */
+ CARD8 _true_color_modulation : 1; /* ? */
+ CARD8 _memory_mapped_mode : 2; /* mmio enable */
+ CARD8 _true_color_order : 1; /* 0: RGB 1: BGR */
+ } _misc_control_1_s;
+ CARD8 _misc_control_1; /* SRB */
+ } _misc_control_1_u;
+
+#define misc_control_1 _misc_control_1_u._misc_control_1
+#define cpu_bitblt_enable _misc_control_1_u._misc_control_1_s._cpu_bitblt_enable
+#define memory_mapped_mode _misc_control_1_u._misc_control_1_s._memory_mapped_mode
+#define true_color_modulation _misc_control_1_u._misc_control_1_s._true_color_modulation
+#define true_color_order _misc_control_1_u._misc_control_1_s._true_color_order
+
+ union {
+ struct {
+ CARD8 _sync_reset_enable : 1;
+ CARD8 _memory_configuration : 3;
+#define SIS_MEMORY_CONFIG_1M_1BANK 0
+#define SIS_MEMORY_CONFIG_2M_2BANK 1
+#define SIS_MEMORY_CONFIG_4M_2BANK 2
+#define SIS_MEMORY_CONFIG_2M_1BANK 5
+#define SIS_MEMORY_CONFIG_4M_1BANK 6
+#define SIS_MEMORY_CONFIG_8M_2BANK 7
+ CARD8 _test_mode_enable : 1;
+ CARD8 _read_ahead_enable : 1;
+ CARD8 _text_mode_16bit_enable : 1;
+ CARD8 _graphics_mode_32bit_enable : 1;
+ } _misc_control_2_s;
+ CARD8 _misc_control_2;
+ } _misc_control_2_u; /* SRC */
+
+#define misc_control_2 _misc_control_2_u._misc_control_2
+#define sync_reset_enable _misc_control_2_u._misc_control_2_s._sync_reset_enable
+#define memory_configuration _misc_control_2_u._misc_control_2_s._memory_configuration
+#define test_mode_enable _misc_control_2_u._misc_control_2_s._test_mode_enable
+#define read_ahead_enable _misc_control_2_u._misc_control_2_s._read_ahead_enable
+#define text_mode_16bit_enable _misc_control_2_u._misc_control_2_s._text_mode_16bit_enable
+#define graphics_mode_32bit_enable _misc_control_2_u._misc_control_2_s._graphics_mode_32bit_enable
+
+ union ddc_and_power_control_u {
+ struct {
+ CARD8 _ddc_clk_programming : 1;
+ CARD8 _ddc_data_programming : 1;
+ CARD8 : 1;
+ CARD8 _acpi_enable : 1;
+ CARD8 _kbd_cursor_activate : 1;
+ CARD8 _video_memory_activate : 1;
+ CARD8 _vga_standby : 1;
+ CARD8 _vga_suspend : 1;
+ } _ddc_and_power_control_s;
+ CARD8 _ddc_and_power_control;
+ } _ddc_and_power_control_u; /* SR11 */
+
+#define ddc_and_power_control _ddc_and_power_control_u._ddc_and_power_control
+#define ddc_clk_programming _ddc_and_power_control_u._ddc_and_power_control_s._ddc_clk_programming
+#define ddc_data_programming _ddc_and_power_control_u._ddc_and_power_control_s._ddc_data_programming
+#define acpi_enable _ddc_and_power_control_u._ddc_and_power_control_s._acpi_enable
+#define kbd_cursor_activate _ddc_and_power_control_u._ddc_and_power_control_s._kbd_cursor_activate
+#define video_memory_activate _ddc_and_power_control_u._ddc_and_power_control_s._video_memory_activate
+#define vga_standby _ddc_and_power_control_u._ddc_and_power_control_s._vga_standby
+#define vga_suspend _ddc_and_power_control_u._ddc_and_power_control_s._vga_suspend
+
+ union {
+ struct {
+ CARD8 _h_total_8 : 1;
+ CARD8 _h_display_end_8 : 1;
+ CARD8 _h_blank_start_8 : 1;
+ CARD8 _h_sync_start_8 : 1;
+ CARD8 _h_blank_end_6 : 1;
+ CARD8 _h_retrace_skew : 3;
+ } _extended_horizontal_overflow_s;
+ CARD8 _extended_horizontal_overflow;
+ } _extended_horizontal_overflow_u; /* SR12 */
+#define extended_horizontal_overflow _extended_horizontal_overflow_u._extended_horizontal_overflow
+#define h_total_8 _extended_horizontal_overflow_u._extended_horizontal_overflow_s._h_total_8
+#define h_display_end_8 _extended_horizontal_overflow_u._extended_horizontal_overflow_s._h_display_end_8
+#define h_blank_start_8 _extended_horizontal_overflow_u._extended_horizontal_overflow_s._h_blank_start_8
+#define h_sync_start_8 _extended_horizontal_overflow_u._extended_horizontal_overflow_s._h_sync_start_8
+#define h_blank_end_6 _extended_horizontal_overflow_u._extended_horizontal_overflow_s._h_blank_end_6
+#define h_retrace_skew _extended_horizontal_overflow_u._extended_horizontal_overflow_s._h_retrace_skew
+
+ union {
+ struct {
+ CARD8 : 6;
+ CARD8 _vclk_post_scale_2 : 1;
+ CARD8 _mclk_post_scale_2 : 1;
+ } _extended_clock_generator_s;
+ CARD8 _extended_clock_generator;
+ } _extended_clock_generator_u; /* SR13 */
+
+#define extended_clock_generator _extended_clock_generator_u._extended_clock_generator
+#define vclk_post_scale_2 _extended_clock_generator_u._extended_clock_generator_s._vclk_post_scale_2
+#define mclk_post_scale_2 _extended_clock_generator_u._extended_clock_generator_s._mclk_post_scale_2
+
+ CARD8 cursor_0_red; /* SR14 */
+ CARD8 cursor_0_green; /* SR15 */
+ CARD8 cursor_0_blue; /* SR16 */
+
+ CARD8 cursor_1_red; /* SR17 */
+ CARD8 cursor_1_green; /* SR18 */
+ CARD8 cursor_1_blue; /* SR19 */
+
+ CARD8 cursor_h_start_0_7; /* SR1A */
+ union {
+ struct {
+ CARD8 _cursor_h_start_8_11 : 4;
+ CARD8 : 3;
+ CARD8 _cursor_mmio_enable : 1;
+ } _cusor_h_start_1_s;
+ CARD8 _cursor_h_start_1;
+ } _cursor_h_start_1_u; /* SR1B */
+
+#define cursor_h_start_1 _cursor_h_start_1_u._cursor_h_start_1
+#define cursor_h_start_8_11 _cursor_h_start_1_u._cursor_h_start_1_s._cursor_h_start_8_11
+
+ CARD8 cursor_h_preset_0_5; /* SR1C */
+
+ CARD8 cursor_v_start_0_7; /* SR1D */
+
+ union {
+ struct {
+ CARD8 _cursor_v_start_8_10 : 3;
+ CARD8 _cursor_side_pattern : 1;
+ CARD8 _cursor_pattern : 4;
+ } _cusor_v_start_1_s;
+ CARD8 _cursor_v_start_1;
+ } _cursor_v_start_1_u; /* SR1E */
+
+#define cursor_v_start_1 _cursor_v_start_1_u._cursor_v_start_1
+
+ CARD8 cursor_v_preset_0_5; /* SR1F */
+
+ CARD8 linear_base_19_26; /* SR20 */
+
+ union {
+ struct {
+ CARD8 _linear_base_27_31 : 5;
+ CARD8 _linear_aperture : 3;
+#define SIS_LINEAR_APERTURE_512K 0
+#define SIS_LINEAR_APERTURE_1M 1
+#define SIS_LINEAR_APERTURE_2M 2
+#define SIS_LINEAR_APERTURE_4M 3
+#define SIS_LINEAR_APERTURE_8M 4
+ } _linear_base_1_s;
+ CARD8 _linear_base_1;
+ } _linear_base_1_u; /* SR21 */
+
+#define linear_base_1 _linear_base_1_u._linear_base_1
+#define linear_base_27_31 _linear_base_1_u._linear_base_1_s._linear_base_27_31
+
+ union {
+ struct {
+ CARD8 _screen_start_addr_20 : 1;
+ CARD8 : 3;
+ CARD8 _continuous_mem_access : 1;
+ CARD8 : 1;
+ CARD8 _power_down_dac : 1;
+ CARD8 : 1;
+ } _graphics_engine_0_s;
+ CARD8 _graphics_engine_0;
+ } _graphics_engine_0_u; /* SR26 */
+
+#define graphics_engine_0 _graphics_engine_0_u._graphics_engine_0
+
+
+ union {
+ struct {
+ CARD8 _screen_start_addr_16_19: 4;
+ CARD8 _logical_screen_width : 2;
+#define SIS_LOG_SCREEN_WIDTH_1024 0
+#define SIS_LOG_SCREEN_WIDTH_2048 1
+#define SIS_LOG_SCREEN_WIDTH_4096 2
+ CARD8 _graphics_prog_enable : 1;
+ CARD8 _turbo_queue_enable : 1;
+ } _graphics_engine_1_s;
+ CARD8 _graphics_engine_1;
+ } _graphics_engine_1_u; /* SR27 */
+
+#define graphics_engine_1 _graphics_engine_1_u._graphics_engine_1
+#define screen_start_addr_16_19 _graphics_engine_1_u._graphics_engine_1_s._screen_start_addr_16_19
+#define logical_screen_width _graphics_engine_1_u._graphics_engine_1_s._logical_screen_width
+#define graphics_prog_enable _graphics_engine_1_u._graphics_engine_1_s._graphics_prog_enable
+#define turbo_queue_enable _graphics_engine_1_u._graphics_engine_1_s._turbo_queue_enable
+
+
+ union {
+ struct {
+ CARD8 _mclk_numerator : 7;
+ CARD8 _mclk_divide_by_2 : 1;
+ } _internal_mclk_0_s;
+ CARD8 _internal_mclk_0;
+ } _internal_mclk_0_u; /* SR28 */
+
+#define internal_mclk_0 _internal_mclk_0_u._internal_mclk_0
+#define mclk_numerator _internal_mclk_0_u._internal_mclk_0_s._mclk_numerator
+#define mclk_divide_by_2 _internal_mclk_0_u._internal_mclk_0_s._mclk_divide_by_2
+
+ union {
+ struct {
+ CARD8 _mclk_denominator : 5;
+ CARD8 _mclk_post_scale : 2;
+#define SIS_MCLK_POST_SCALE_1 0
+#define SIS_MCLK_POST_SCALE_2 1
+#define SIS_MCLK_POST_SCALE_3 2
+#define SIS_MCLK_POST_SCALE_4 3
+ CARD8 _mclk_vco_gain : 1;
+ } _internal_mclk_1_s;
+ CARD8 _internal_mclk_1;
+ } _internal_mclk_1_u; /* SR29 */
+
+#define internal_mclk_1 _internal_mclk_1_u._internal_mclk_1
+#define mclk_denominator _internal_mclk_1_u._internal_mclk_1_s._mclk_denominator
+#define mclk_post_scale _internal_mclk_1_u._internal_mclk_1_s._mclk_post_scale
+#define mclk_vco_gain _internal_mclk_1_u._internal_mclk_1_s._mclk_vco_gain
+
+ union {
+ struct {
+ CARD8 _vclk_numerator : 7;
+ CARD8 _vclk_divide_by_2 : 1;
+ } _internal_vclk_0_s;
+ CARD8 _internal_vclk_0;
+ } _internal_vclk_0_u; /* SR2A */
+
+#define internal_vclk_0 _internal_vclk_0_u._internal_vclk_0
+#define vclk_numerator _internal_vclk_0_u._internal_vclk_0_s._vclk_numerator
+#define vclk_divide_by_2 _internal_vclk_0_u._internal_vclk_0_s._vclk_divide_by_2
+
+ union {
+ struct {
+ CARD8 _vclk_denominator : 5;
+ CARD8 _vclk_post_scale : 2;
+#define SIS_VCLK_POST_SCALE_1 0
+#define SIS_VCLK_POST_SCALE_2 1
+#define SIS_VCLK_POST_SCALE_3 2
+#define SIS_VCLK_POST_SCALE_4 3
+ CARD8 _vclk_vco_gain : 1;
+ } _internal_vclk_1_s;
+ CARD8 _internal_vclk_1;
+ } _internal_vclk_1_u; /* SR2B */
+
+#define internal_vclk_1 _internal_vclk_1_u._internal_vclk_1
+#define vclk_denominator _internal_vclk_1_u._internal_vclk_1_s._vclk_denominator
+#define vclk_post_scale _internal_vclk_1_u._internal_vclk_1_s._vclk_post_scale
+#define vclk_vco_gain _internal_vclk_1_u._internal_vclk_1_s._vclk_vco_gain
+
+ union {
+ struct {
+ CARD8 _extended_clock_select : 2;
+#define SIS_CLOCK_SELECT_INTERNAL 0
+#define SIS_CLOCK_SELECT_25MHZ 1
+#define SIS_CLOCK_SELECT_28MHZ 2
+ CARD8 _disable_line_compare : 1;
+ CARD8 _disable_pci_read_t_o : 1;
+ CARD8 _cursor_start_addr_18_21: 4;
+ } _misc_control_7_s;
+ CARD8 _misc_control_7;
+ } _misc_control_7_u; /* SR38 */
+
+#define misc_control_7 _misc_control_7_u._misc_control_7
+#define extended_clock_select _misc_control_7_u._misc_control_7_s._extended_clock_select
+#define disable_line_compare _misc_control_7_u._misc_control_7_s._disable_line_compare
+#define disable_pci_read_t_o _misc_control_7_u._misc_control_7_s._disable_pci_read_t_o
+#define cursor_start_addr_18_21 _misc_control_7_u._misc_control_7_s._cursor_start_addr_18_21
+
+ union {
+ struct {
+ CARD8 _high_speed_dclk : 1;
+ CARD8 _sgram_block_write : 1;
+ CARD8 _cursor_start_addr_22 : 1;
+ CARD8 _dram_texture_read : 1;
+ CARD8 _sgram_16mb : 1;
+ CARD8 _agp_signal_delay : 2;
+ CARD8 _dclk_off : 1;
+ } _misc_control_11_s;
+ CARD8 _misc_control_11;
+ } _misc_control_11_u; /* SR3E */
+
+#define misc_control_11 _misc_control_11_u._misc_control_11
+#define high_speed_dclk _misc_control_11_u._misc_control_11_s._high_speed_dclk
+#define sgram_block_write _misc_control_11_u._misc_control_11_s.__sgram_block_write
+#define cursor_start_addr_22 _misc_control_11_u._misc_control_11_s._cursor_start_addr_22
+#define dram_texture_read _misc_control_11_u._misc_control_11_s._dram_texture_read
+#define sgram_16mb _misc_control_11_u._misc_control_11_s._sgram_16mb
+#define agp_signal_delay _misc_control_11_u._misc_control_11_s._agp_signal_delay
+#define dclk_off _misc_control_11_u._misc_control_11_s._dclk_off
+
+ union {
+ struct {
+ CARD8 : 1;
+ CARD8 _flat_panel_low_enable : 1;
+ CARD8 _crt_cpu_threshold_low_4: 1;
+ CARD8 _crt_engine_threshold_high_4: 1;
+ CARD8 _crt_cpu_threshold_high_4 : 1;
+ CARD8 _crt_threshold_full_control : 2;
+#define SIS_CRT_32_STAGE_THRESHOLD 0
+#define SIS_CRT_64_STAGE_THRESHOLD 1
+#define SIS_CRT_63_STAGE_THRESHOLD 2
+#define SIS_CRT_256_STAGE_THRESHOLD 3
+ CARD8 _high_speed_dac_1 : 1;
+ } _misc_control_12_s;
+ CARD8 _misc_control_12;
+ } _misc_control_12_u; /* SR3F */
+#define misc_control_12 _misc_control_12_u._misc_control_12
+#define flat_panel_low_enable _misc_control_12_u._misc_control_12_s._flat_panel_low_enable
+#define crt_cpu_threshold_low_4 _misc_control_12_u._misc_control_12_s._crt_cpu_threshold_low_4
+#define crt_engine_threshold_high_4 _misc_control_12_u._misc_control_12_s._crt_engine_threshold_high_4
+#define crt_cpu_threshold_high_4 _misc_control_12_u._misc_control_12_s._crt_cpu_threshold_high_4
+#define crt_threshold_full_control _misc_control_12_u._misc_control_12_s._crt_threshold_full_control
+#define high_speed_dac_1 _misc_control_12_u._misc_control_12_s._high_speed_dac_1
+
+ /* computed values */
+ CARD16 ge_screen_pitch;
+ CARD8 bits_per_pixel;
+ CARD8 depth;
+ CARD8 double_pixel_mode;
+ CARD16 pixel_width;
+} SisCrtc;
+
+#define crtc_v_total(crtc) ((crtc)->v_total_0_7 | \
+ ((crtc)->v_total_8 << 8) | \
+ ((crtc)->v_total_9 << 9) | \
+ ((crtc)->v_total_10 << 10))
+
+#define crtc_set_v_total(crtc,v) { \
+ ((crtc))->v_total_0_7 = (v); \
+ ((crtc))->v_total_8 = (v) >> 8; \
+ ((crtc))->v_total_9 = (v) >> 9; \
+ ((crtc))->v_total_10 = (v) >> 10; \
+}
+
+#define crtc_v_display_end(crtc) ((crtc)->v_display_end_0_7 | \
+ ((crtc)->v_display_end_8 << 8) | \
+ ((crtc)->v_display_end_9 << 9) | \
+ ((crtc)->v_display_end_10 << 10))
+
+#define crtc_set_v_display_end(crtc,v) {\
+ ((crtc))->v_display_end_0_7 = (v); \
+ ((crtc))->v_display_end_8 = (v) >> 8; \
+ ((crtc))->v_display_end_9 = (v) >> 9; \
+ ((crtc))->v_display_end_10 = (v) >> 10; \
+}
+
+#define crtc_v_retrace_start(crtc) ((crtc)->v_retrace_start_0_7 | \
+ ((crtc)->v_retrace_start_8 << 8) | \
+ ((crtc)->v_retrace_start_9 << 9) | \
+ ((crtc)->v_retrace_start_10 << 10))
+
+#define crtc_set_v_retrace_start(crtc,v) {\
+ ((crtc))->v_retrace_start_0_7 = (v); \
+ ((crtc))->v_retrace_start_8 = (v) >> 8; \
+ ((crtc))->v_retrace_start_9 = (v) >> 9; \
+ ((crtc))->v_retrace_start_10 = (v) >> 10; \
+}
+
+#define crtc_v_blank_start(crtc) ((crtc)->v_blank_start_0_7 | \
+ ((crtc)->v_blank_start_8 << 8) | \
+ ((crtc)->v_blank_start_9 << 9) | \
+ ((crtc)->v_blank_start_10 << 10))
+
+#define crtc_set_v_blank_start(crtc,v) {\
+ ((crtc))->v_blank_start_0_7 = (v); \
+ ((crtc))->v_blank_start_8 = (v) >> 8; \
+ ((crtc))->v_blank_start_9 = (v) >> 9; \
+ ((crtc))->v_blank_start_10 = (v) >> 10; \
+}
+
+#define crtc_h_total(crtc) ((crtc)->h_total_0_7 | \
+ ((crtc)->h_total_8 << 8))
+
+#define crtc_set_h_total(crtc,v) {\
+ ((crtc))->h_total_0_7 = (v); \
+ ((crtc))->h_total_8 = (v) >> 8; \
+}
+
+#define crtc_h_display_end(crtc) ((crtc)->h_display_end_0_7 | \
+ ((crtc)->h_display_end_8 << 8))
+
+#define crtc_set_h_display_end(crtc,v) {\
+ ((crtc))->h_display_end_0_7 = (v); \
+ ((crtc))->h_display_end_8 = (v) >> 8; \
+}
+
+#define crtc_h_blank_start(crtc) ((crtc)->h_blank_start_0_7 | \
+ ((crtc)->h_blank_start_8 << 8))
+
+#define crtc_set_h_blank_start(crtc,v) {\
+ ((crtc))->h_blank_start_0_7 = (v); \
+ ((crtc))->h_blank_start_8 = (v) >> 8; \
+}
+
+#define crtc_h_blank_end(crtc) ((crtc)->h_blank_end_0_4 | \
+ ((crtc)->h_blank_end_5 << 5))
+
+#define crtc_set_h_blank_end(crtc,v) {\
+ ((crtc))->h_blank_end_0_4 = (v); \
+ ((crtc))->h_blank_end_5 = (v) >> 5; \
+}
+
+#define crtc_h_sync_start(crtc) ((crtc)->h_sync_start_0_7 | \
+ ((crtc)->h_sync_start_8 << 8))
+
+#define crtc_set_h_sync_start(crtc,v) {\
+ ((crtc))->h_sync_start_0_7 = (v); \
+ ((crtc))->h_sync_start_8 = (v) >> 8; \
+}
+
+#define crtc_h_sync_end(crtc) ((crtc)->h_sync_end_0_4)
+
+#define crtc_set_h_sync_end(crtc,v) {\
+ ((crtc))->h_sync_end_0_4 = (v); \
+}
+
+#define crtc_screen_off(crtc) ((crtc)->screen_off_0_7 | \
+ ((crtc)->screen_off_8_11 << 8))
+
+#define crtc_set_screen_off(crtc,v) {\
+ ((crtc))->screen_off_0_7 = (v); \
+ ((crtc))->screen_off_8_11 = (v) >> 8; \
+}
+
+#define crtc_ge_screen_width(crtc) ((crtc)->ge_screen_width_0_1 | \
+ ((crtc)->ge_screen_width_2 << 2))
+
+#define crtc_set_ge_screen_width(crtc,v) { \
+ (crtc)->ge_screen_width_0_1 = (v); \
+ (crtc)->ge_screen_width_2 = (v) >> 2; \
+}
+
+#define crtc_h_start_fifo_fetch(crtc) ((crtc)->h_start_fifo_fetch_0_7 | \
+ ((crtc)->h_start_fifo_fetch_8 << 8))
+
+#define crtc_set_h_start_fifo_fetch(crtc,v) {\
+ (crtc)->h_start_fifo_fetch_0_7 = (v); \
+ (crtc)->h_start_fifo_fetch_8 = (v) >> 8; \
+}
+
+#define crtc_start_address(crtc) ((crtc)->start_address_0_7 | \
+ ((crtc)->start_address_8_15 << 8) | \
+ ((crtc)->start_address_16_19 << 16))
+
+#define crtc_set_start_address(crtc,v) {\
+ (crtc)->start_address_0_7 = (v); \
+ (crtc)->start_address_8_15 = (v) >> 8; \
+ (crtc)->start_address_16_19 = (v) >> 16; \
+}
+
+#define crtc_line_compare(crtc) ((crtc)->line_compare_0_7 | \
+ ((crtc)->line_compare_8 << 8) | \
+ ((crtc)->line_compare_9 << 9) | \
+ ((crtc)->line_compare_10 << 10))
+
+#define crtc_set_line_compare(crtc,v) { \
+ ((crtc))->line_compare_0_7 = (v); \
+ ((crtc))->line_compare_8 = (v) >> 8; \
+ ((crtc))->line_compare_9 = (v) >> 9; \
+ ((crtc))->line_compare_10 = (v) >> 10; \
+}
+
+#define crtc_set_cursor_start_addr(crtc,v) { \
+ (crtc)->cursor_start_addr_18_21 = (v) >> 18; \
+ (crtc)->cursor_start_addr_22 = (v) >> 22; \
+}
+
+#define _sisOutb(v,r) outb(v,r)
+#define _sisInb(r) inb(r)
+
+#define SIS_DAC_INDEX_READ 0x47
+#define SIS_DAC_INDEX_WRITE 0x48
+#define SIS_DAC_DATA 0x49
+
+#define GetCrtc(sisc,i) _sisReadIndexRegister ((sisc)->io_base+0x54,i)
+#define PutCrtc(sisc,i,v) _sisWriteIndexRegister ((sisc)->io_base+0x54,i,v)
+
+#define GetSrtc(sisc,i) _sisReadIndexRegister ((sisc)->io_base+0x44,i)
+#define PutSrtc(sisc,i,v) _sisWriteIndexRegister ((sisc)->io_base+0x44,i,v)
+
+#define GetArtc(sisc,i) _sisReadIndexRegister ((sisc)->io_base+0x40,i)
+#define PutArtc(sisc,i,v) _sisWriteIndexRegister ((sisc)->io_base+0x40,i,v)
+
+#define GetGrtc(sisc,i) _sisReadIndexRegister ((sisc)->io_base+0x4e,i)
+#define PutGrtc(sisc,i,v) _sisWriteIndexRegister ((sisc)->io_base+0x4e,i,v)
+
+#define _sisWaitVRetrace(sisc)
+
+#define LockSis(sisc)
+#define UnlockSis(sisc)
+
+typedef struct _sisTiming {
+ /* label */
+ int horizontal;
+ int vertical;
+ int rate;
+ /* horizontal timing */
+ int hfp; /* front porch */
+ int hbp; /* back porch */
+ int hblank; /* blanking */
+ /* vertical timing */
+ int vfp; /* front porch */
+ int vbp; /* back porch */
+ int vblank; /* blanking */
+} SisTiming;
+
+typedef struct _sisSave {
+ CARD8 srb;
+ CARD8 sr5;
+ SisCrtc crtc;
+} SisSave;
+
+typedef struct _sisCardInfo {
+ SisPtr sis;
+ int memory;
+ CARD8 *frameBuffer;
+ CARD8 *registers;
+ VOL32 *cpu_bitblt;
+ CARD32 io_base;
+ SisSave save;
+} SisCardInfo;
+
+typedef struct _sisScreenInfo {
+ CARD8 *cursor_base;
+ CARD32 cursor_off;
+ CARD8 *expand;
+ CARD32 expand_off;
+ int expand_len;
+ SisCursor cursor;
+} SisScreenInfo;
+
+#define getSisCardInfo(kd) ((SisCardInfo *) ((kd)->card->driver))
+#define sisCardInfo(kd) SisCardInfo *sisc = getSisCardInfo(kd)
+
+#define getSisScreenInfo(kd) ((SisScreenInfo *) ((kd)->screen->driver))
+#define sisScreenInfo(kd) SisScreenInfo *siss = getSisScreenInfo(kd)
+
+Bool sisCardInit (KdCardInfo *);
+Bool sisScreenInit (KdScreenInfo *);
+void sisEnable (ScreenPtr pScreen);
+void sisDisable (ScreenPtr pScreen);
+void sisFini (ScreenPtr pScreen);
+
+Bool sisCursorInit (ScreenPtr pScreen);
+void sisCursorEnable (ScreenPtr pScreen);
+void sisCursorDisable (ScreenPtr pScreen);
+void sisCursorFini (ScreenPtr pScreen);
+void sisRecolorCursor (ScreenPtr pScreen, int ndef, xColorItem *pdefs);
+
+Bool sisDrawInit (ScreenPtr pScreen);
+void sisDrawEnable (ScreenPtr pScreen);
+void sisDrawSync (ScreenPtr pScreen);
+void sisDrawDisable (ScreenPtr pScreen);
+void sisDrawFini (ScreenPtr pScreen);
+
+void sisGetColors (ScreenPtr pScreen, int ndef, xColorItem *pdefs);
+void sisPutColors (ScreenPtr pScreen, int ndef, xColorItem *pdefs);
+
+void SISInitCard (KdCardAttr *attr);
+
+CARD8 _sisReadIndexRegister (CARD32 base, CARD8 index);
+void _sisWriteIndexRegister (CARD32 base, CARD8 index, CARD8 value);
+
+extern KdCardFuncs sisFuncs;
+
+/*
+ * sisclock.c
+ */
+void
+sisGetClock (unsigned long clock, SisCrtc *crtc);
+
+void
+sisEngThresh (SisCrtc *crtc, unsigned long vclk, int bpp);
+
+/*
+ * siscurs.c
+ */
+
+Bool
+sisCursorInit (ScreenPtr pScreen);
+
+void
+sisCursorEnable (ScreenPtr pScreen);
+
+void
+sisCursorDisable (ScreenPtr pScreen);
+
+void
+sisCursorFini (ScreenPtr pScreen);
+
+/* sisdraw.c */
+Bool
+sisDrawInit (ScreenPtr pScreen);
+
+void
+sisDrawEnable (ScreenPtr pScreen);
+
+void
+sisDrawDisable (ScreenPtr pScreen);
+
+void
+sisDrawFini (ScreenPtr pScreen);
+
+#endif /* _SIS_H_ */
diff --git a/xc/programs/Xserver/hw/kdrive/sis530/sisclock.c b/xc/programs/Xserver/hw/kdrive/sis530/sisclock.c
new file mode 100644
index 000000000..1bf79dc83
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/sis530/sisclock.c
@@ -0,0 +1,232 @@
+/*
+ * $Id: sisclock.c,v 1.1 2000/01/06 12:55:53 faith 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/sis530/sisclock.c,v 1.1 1999/11/19 13:53:59 hohndel Exp $ */
+
+#include "sis.h"
+#include <stdio.h>
+
+#define FREF 14318180
+#define MIN_VCO FREF
+#define MAX_VCO 230000000
+#define MAX_PSN 0 /* no pre scaler for this chip */
+#define TOLERANCE 0.01 /* search smallest M and N in this tolerance */
+#define max_VLD 1
+
+/*
+ * Compute clock values given target frequency
+ */
+void
+sisGetClock (unsigned long clock, SisCrtc *crtc)
+{
+ unsigned char reg7, reg13, reg2a, reg2b;
+ int M, N, P, VLD;
+
+ int bestM, bestN, bestP, bestPSN, bestVLD;
+ double bestError, abest = 42.0, bestFout;
+
+ double Fvco, Fout;
+ double error, aerror;
+
+ double target = (double) clock;
+
+ int M_min = 2;
+ int M_max = 128;
+
+ int low_N = 2;
+ int high_N = 32;
+ int PSN = 1;
+
+ /*
+ * fd = fref*(Numerator/Denumerator)*(Divider/PostScaler)
+ *
+ * M = Numerator [1:128]
+ * N = DeNumerator [1:32]
+ * VLD = Divider (Vco Loop Divider) : divide by 1, 2
+ * P = Post Scaler : divide by 1, 2, 3, 4
+ * PSN = Pre Scaler (Reference Divisor Select)
+ *
+ * result in vclk[]
+ */
+
+ P = 1;
+ if (target < MAX_VCO / 2)
+ P = 2;
+ if (target < MAX_VCO / 3)
+ P = 3;
+ if (target < MAX_VCO / 4)
+ P = 4;
+ if (target < MAX_VCO / 6)
+ P = 6;
+ if (target < MAX_VCO / 8)
+ P = 8;
+
+ Fvco = P * target;
+
+ for (N = low_N; N <= high_N; N++)
+ {
+ double M_desired = Fvco / FREF * N;
+
+ if (M_desired > M_max * max_VLD)
+ continue;
+
+ if ( M_desired > M_max )
+ {
+ M = (int)(M_desired / 2 + 0.5);
+ VLD = 2;
+ }
+ else
+ {
+ M = (int)(M_desired + 0.5);
+ VLD = 1;
+ }
+
+ Fout = (double)FREF * (M * VLD)/(N * P);
+ error = (target - Fout) / target;
+ aerror = (error < 0) ? -error : error;
+ if (aerror < abest)
+ {
+ abest = aerror;
+ bestError = error;
+ bestM = M;
+ bestN = N;
+ bestP = P;
+ bestPSN = PSN;
+ bestVLD = VLD;
+ bestFout = Fout;
+ }
+ }
+
+ crtc->vclk_numerator = bestM - 1;
+ crtc->vclk_divide_by_2 = bestVLD == 2;
+
+ crtc->vclk_denominator = bestN - 1;
+ switch (bestP) {
+ case 1:
+ crtc->vclk_post_scale = SIS_VCLK_POST_SCALE_1;
+ crtc->vclk_post_scale_2 = 0;
+ break;
+ case 2:
+ crtc->vclk_post_scale = SIS_VCLK_POST_SCALE_2;
+ crtc->vclk_post_scale_2 = 0;
+ break;
+ case 3:
+ crtc->vclk_post_scale = SIS_VCLK_POST_SCALE_3;
+ crtc->vclk_post_scale_2 = 0;
+ break;
+ case 4:
+ crtc->vclk_post_scale = SIS_VCLK_POST_SCALE_4;
+ crtc->vclk_post_scale_2 = 0;
+ break;
+ case 6:
+ crtc->vclk_post_scale = SIS_VCLK_POST_SCALE_3;
+ crtc->vclk_post_scale_2 = 1;
+ break;
+ case 8:
+ crtc->vclk_post_scale = SIS_VCLK_POST_SCALE_4;
+ crtc->vclk_post_scale_2 = 1;
+ break;
+ }
+
+ crtc->vclk_vco_gain = 1;
+
+ /*
+ * Don't know how to set mclk for local frame buffer; for
+ * shared frame buffer, mclk is hardwired to bus speed (100MHz)?
+ */
+}
+
+sisCalcMclk (SisCrtc *crtc)
+{
+ int mclk, Numer, DeNumer;
+ double Divider, Scalar;
+
+ Numer = crtc->mclk_numerator;
+ DeNumer = crtc->mclk_denominator;
+ Divider = crtc->mclk_divide_by_2 ? 2.0 : 1.0;
+ Scalar = 1.0;
+ if (crtc->mclk_post_scale_2)
+ {
+ switch (crtc->mclk_post_scale) {
+ case 2:
+ Scalar = 6.0;
+ break;
+ case 3:
+ Scalar = 8.0;
+ break;
+ }
+ }
+ else
+ {
+ switch (crtc->mclk_post_scale) {
+ case 0:
+ Scalar = 1.0;
+ break;
+ case 1:
+ Scalar = 2.0;
+ break;
+ case 2:
+ Scalar = 3.0;
+ break;
+ case 3:
+ Scalar = 4.0;
+ break;
+ }
+ }
+
+ mclk = (int)(FREF*((double)(Numer+1)/(double)(DeNumer+1))*(Divider/Scalar));
+
+ return(mclk);
+}
+
+#define UMA_FACTOR 60
+#define LFB_FACTOR 30 // Only if local frame buffer
+#define SIS_SAYS_SO 0x1F // But how is the performance??
+#define CRT_ENG_THRESH 0x0F // But how is the performance??
+#define BUS_WIDTH 64
+#define DFP_BUS_WIDTH 32 // rumour has it for digital flat panel ??
+#define MEGAHZ (1<<20)
+
+void
+sisEngThresh (SisCrtc *crtc, unsigned long vclk, int bpp)
+{
+ int threshlow, mclk;
+
+ mclk = sisCalcMclk(crtc) / 1000000;
+ vclk = vclk / 1000000;
+ threshlow = ((((UMA_FACTOR*vclk*bpp)/
+ (mclk*BUS_WIDTH))+1)/2)+4;
+
+ crtc->crt_cpu_threshold_low_0_3 = threshlow;
+ crtc->crt_cpu_threshold_low_4 = threshlow >> 4;
+
+ crtc->crt_cpu_threshold_high_0_3 = (SIS_SAYS_SO & 0xf);
+ crtc->crt_cpu_threshold_high_4 = 0;
+
+ crtc->crt_engine_threshold_high_0_3 = CRT_ENG_THRESH;
+ crtc->crt_engine_threshold_high_4 = 1;
+
+ crtc->ascii_attribute_threshold_0_2 = (SIS_SAYS_SO >> 4);
+
+ crtc->crt_threshold_full_control = SIS_CRT_64_STAGE_THRESHOLD;
+}
diff --git a/xc/programs/Xserver/hw/kdrive/sis530/siscmap.c b/xc/programs/Xserver/hw/kdrive/sis530/siscmap.c
new file mode 100644
index 000000000..a7ed4e7f0
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/sis530/siscmap.c
@@ -0,0 +1,64 @@
+/*
+ * $Id: siscmap.c,v 1.1 2000/01/06 12:55:53 faith 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/sis530/siscmap.c,v 1.1 1999/11/19 13:53:59 hohndel Exp $ */
+
+#include "sis.h"
+
+void
+sisGetColors (ScreenPtr pScreen, int ndef, xColorItem *pdefs)
+{
+ KdScreenPriv(pScreen);
+ sisCardInfo(pScreenPriv);
+
+ LockSis (sisc);
+ while (ndef--)
+ {
+ _sisOutb (pdefs->pixel, sisc->io_base+SIS_DAC_INDEX_READ);
+ pdefs->red = _sisInb (sisc->io_base+SIS_DAC_DATA) << 10;
+ pdefs->green = _sisInb (sisc->io_base+SIS_DAC_DATA) << 10;
+ pdefs->blue = _sisInb (sisc->io_base+SIS_DAC_DATA) << 10;
+ pdefs++;
+ }
+ UnlockSis (sisc);
+}
+
+void
+sisPutColors (ScreenPtr pScreen, int ndef, xColorItem *pdefs)
+{
+ KdScreenPriv(pScreen);
+ sisCardInfo(pScreenPriv);
+
+ LockSis(sisc);
+ _sisWaitVRetrace (sisc);
+ while (ndef--)
+ {
+ _sisOutb (pdefs->pixel, sisc->io_base+SIS_DAC_INDEX_WRITE);
+ _sisOutb (pdefs->red >> 10, sisc->io_base+SIS_DAC_DATA);
+ _sisOutb (pdefs->green >> 10, sisc->io_base+SIS_DAC_DATA);
+ _sisOutb (pdefs->blue >> 10, sisc->io_base+SIS_DAC_DATA);
+ pdefs++;
+ }
+ UnlockSis(sisc);
+}
+
diff --git a/xc/programs/Xserver/hw/kdrive/sis530/siscurs.c b/xc/programs/Xserver/hw/kdrive/sis530/siscurs.c
new file mode 100644
index 000000000..6896754bc
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/sis530/siscurs.c
@@ -0,0 +1,364 @@
+/*
+ * $Id: siscurs.c,v 1.1 2000/01/06 12:55:53 faith 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/sis530/siscurs.c,v 1.1 1999/11/19 13:53:59 hohndel Exp $ */
+
+#include "sis.h"
+#include "cursorstr.h"
+
+#define SetupCursor(s) KdScreenPriv(s); \
+ sisCardInfo(pScreenPriv); \
+ sisScreenInfo(pScreenPriv); \
+ SisPtr sis = sisc->sis; \
+ SisCursor *pCurPriv = &siss->cursor
+
+static void
+_sisMoveCursor (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);
+
+ PutSrtc (sisc, 0x5, 0x86);
+ PutSrtc (sisc, 0x1c, xoff & 0x3f);
+ PutSrtc (sisc, 0x1f, yoff & 0x3f);
+
+ PutSrtc (sisc, 0x1a, xlow);
+ PutSrtc (sisc, 0x1b, xhigh & 0xf);
+
+ PutSrtc (sisc, 0x1d, ylow);
+ PutSrtc (sisc, 0x1e, yhigh & 0x7);
+}
+
+static void
+sisMoveCursor (ScreenPtr pScreen, int x, int y)
+{
+ SetupCursor (pScreen);
+
+ if (!pCurPriv->has_cursor)
+ return;
+
+ if (!pScreenPriv->enabled)
+ return;
+
+ LockSis(sisc);
+ _sisMoveCursor (pScreen, x, y);
+ UnlockSis(sisc);
+}
+
+static void
+_sisSetCursorColors (ScreenPtr pScreen)
+{
+ SetupCursor (pScreen);
+ CursorPtr pCursor = pCurPriv->pCursor;
+ /* set foreground */
+ PutSrtc (sisc, 0x17, pCursor->foreRed >> 10);
+ PutSrtc (sisc, 0x18, pCursor->foreGreen >> 10);
+ PutSrtc (sisc, 0x19, pCursor->foreBlue >> 10);
+
+ /* set background */
+ PutSrtc (sisc, 0x14, pCursor->backRed >> 10);
+ PutSrtc (sisc, 0x15, pCursor->backGreen >> 10);
+ PutSrtc (sisc, 0x16, pCursor->backBlue >> 10);
+}
+
+static void
+sisLoadCursor (ScreenPtr pScreen, int x, int y)
+{
+ SetupCursor(pScreen);
+ CursorPtr pCursor = pCurPriv->pCursor;
+ CursorBitsPtr bits = pCursor->bits;
+ int w, h;
+ unsigned short *ram, r;
+ unsigned char *msk, *mskLine, *src, *srcLine;
+ unsigned short m, s;
+
+ int i, j;
+ int cursor_address;
+ int src_stride, src_width;
+
+ CARD8 sr6;
+
+ /*
+ * Lock Sis so the cursor doesn't move while we're setting it
+ */
+ LockSis(sisc);
+
+ pCurPriv->pCursor = pCursor;
+ pCurPriv->xhot = pCursor->bits->xhot;
+ pCurPriv->yhot = pCursor->bits->yhot;
+
+ /*
+ * Stick new image into cursor memory
+ */
+ ram = (unsigned short *) siss->cursor_base;
+ mskLine = (unsigned char *) bits->mask;
+ srcLine = (unsigned char *) bits->source;
+
+ h = bits->height;
+ if (h > SIS_CURSOR_HEIGHT)
+ h = SIS_CURSOR_HEIGHT;
+
+ src_stride = BitmapBytePad(bits->width); /* bytes per line */
+ src_width = (bits->width + 7) >> 3;
+
+ for (i = 0; i < SIS_CURSOR_HEIGHT; i++) {
+ msk = mskLine;
+ src = srcLine;
+ mskLine += src_stride;
+ srcLine += src_stride;
+ for (j = 0; j < SIS_CURSOR_WIDTH / 8; j++) {
+
+ unsigned short m, s;
+
+ if (i < h && j < src_width)
+ {
+ m = *msk++;
+ s = *src++ & m;
+ m = ~m;
+ /* mask off right side */
+ if (j == src_width - 1 && (bits->width & 7))
+ {
+ m |= 0xff << (bits->width & 7);
+ }
+ }
+ else
+ {
+ m = 0xff;
+ s = 0x00;
+ }
+
+ /*
+ * The SIS530 HW cursor format is: source(AND) bit,
+ * then a mask(XOR) bit, etc.
+ * byte swapping in sis530 is:
+ * abcd ==> cdab
+ */
+
+#define bit(a,n) (((a) >> (n)) & 0x1)
+
+ r = ((bit(m, 0) << 7) | (bit(s, 0) << 6) |
+ (bit(m, 1) << 5) | (bit(s, 1) << 4) |
+ (bit(m, 2) << 3) | (bit(s, 2) << 2) |
+ (bit(m, 3) << 1) | (bit(s, 3) << 0) |
+ (bit(m, 4) << 15) | (bit(s, 4) << 14) |
+ (bit(m, 5) << 13) | (bit(s, 5) << 12) |
+ (bit(m, 6) << 11) | (bit(s, 6) << 10) |
+ (bit(m, 7) << 9) | (bit(s, 7) << 8));
+
+ *ram++ = r;
+ }
+ }
+
+ /* Set new color */
+ _sisSetCursorColors (pScreen);
+
+ /* Move to new position */
+ _sisMoveCursor (pScreen, x, y);
+
+ /* Enable cursor */
+ sr6 = GetSrtc (sisc, 0x6);
+ sr6 |= 0x40;
+ PutSrtc (sisc, 0x6, sr6);
+
+ UnlockSis(sisc);
+}
+
+static void
+sisUnloadCursor (ScreenPtr pScreen)
+{
+ SetupCursor (pScreen);
+ CARD8 sr6;
+
+ LockSis (sisc);
+
+ /* Disable cursor */
+ sr6 = GetSrtc (sisc, 0x6);
+ sr6 &= ~0x40;
+ PutSrtc (sisc, 0x6, sr6);
+ PutSrtc (sisc, 0x1b, 0x00);
+
+ UnlockSis (sisc);
+}
+
+static Bool
+sisRealizeCursor (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);
+ sisLoadCursor (pScreen, x, y);
+ }
+ }
+ return TRUE;
+}
+
+static Bool
+sisUnrealizeCursor (ScreenPtr pScreen, CursorPtr pCursor)
+{
+ return TRUE;
+}
+
+static void
+sisSetCursor (ScreenPtr pScreen, CursorPtr pCursor, int x, int y)
+{
+ SetupCursor(pScreen);
+
+ pCurPriv->pCursor = pCursor;
+
+ if (!pScreenPriv->enabled)
+ return;
+
+ if (pCursor)
+ sisLoadCursor (pScreen, x, y);
+ else
+ sisUnloadCursor (pScreen);
+}
+
+miPointerSpriteFuncRec sisPointerSpriteFuncs = {
+ sisRealizeCursor,
+ sisUnrealizeCursor,
+ sisSetCursor,
+ sisMoveCursor,
+};
+
+static void
+sisQueryBestSize (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
+sisCursorInit (ScreenPtr pScreen)
+{
+ SetupCursor (pScreen);
+
+ if (!siss->cursor_base)
+ {
+ pCurPriv->has_cursor = FALSE;
+ return FALSE;
+ }
+
+ pCurPriv->width = SIS_CURSOR_WIDTH;
+ pCurPriv->height= SIS_CURSOR_HEIGHT;
+ pScreen->QueryBestSize = sisQueryBestSize;
+ miPointerInitialize (pScreen,
+ &sisPointerSpriteFuncs,
+ &kdPointerScreenFuncs,
+ FALSE);
+ pCurPriv->has_cursor = TRUE;
+ pCurPriv->pCursor = NULL;
+ return TRUE;
+}
+
+void
+sisCursorEnable (ScreenPtr pScreen)
+{
+ SetupCursor (pScreen);
+
+ if (pCurPriv->has_cursor)
+ {
+ if (pCurPriv->pCursor)
+ {
+ int x, y;
+
+ miPointerPosition (&x, &y);
+ sisLoadCursor (pScreen, x, y);
+ }
+ else
+ sisUnloadCursor (pScreen);
+ }
+}
+
+void
+sisCursorDisable (ScreenPtr pScreen)
+{
+ SetupCursor (pScreen);
+
+ if (!pScreenPriv->enabled)
+ return;
+
+ if (pCurPriv->has_cursor)
+ {
+ if (pCurPriv->pCursor)
+ {
+ sisUnloadCursor (pScreen);
+ }
+ }
+}
+
+void
+sisCursorFini (ScreenPtr pScreen)
+{
+ SetupCursor (pScreen);
+
+ pCurPriv->pCursor = NULL;
+}
diff --git a/xc/programs/Xserver/hw/kdrive/sis530/sisdraw.c b/xc/programs/Xserver/hw/kdrive/sis530/sisdraw.c
new file mode 100644
index 000000000..fcd89962d
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/sis530/sisdraw.c
@@ -0,0 +1,1669 @@
+/*
+ * $Id: sisdraw.c,v 1.1 2000/01/06 12:55:54 faith 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/sis530/sisdraw.c,v 1.2 1999/12/30 03:03:14 robin Exp $ */
+
+#include "sis.h"
+#include "sisdraw.h"
+
+#include "Xmd.h"
+#include "gcstruct.h"
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "regionstr.h"
+#include "mistruct.h"
+#include "fontstruct.h"
+#include "dixfontstr.h"
+#include "fb.h"
+#include "migc.h"
+#include "miline.h"
+
+CARD8 sisPatRop[16] = {
+ /* GXclear */ 0x00, /* 0 */
+ /* GXand */ 0xa0, /* src AND dst */
+ /* GXandReverse */ 0x50, /* src AND NOT dst */
+ /* GXcopy */ 0xf0, /* src */
+ /* GXandInverted*/ 0x0a, /* NOT src AND dst */
+ /* GXnoop */ 0xaa, /* dst */
+ /* GXxor */ 0x5a, /* src XOR dst */
+ /* GXor */ 0xfa, /* src OR dst */
+ /* GXnor */ 0x05, /* NOT src AND NOT dst */
+ /* GXequiv */ 0xa5, /* NOT src XOR dst */
+ /* GXinvert */ 0x55, /* NOT dst */
+ /* GXorReverse */ 0xf5, /* src OR NOT dst */
+ /* GXcopyInverted*/ 0x0f, /* NOT src */
+ /* GXorInverted */ 0xaf, /* NOT src OR dst */
+ /* GXnand */ 0x5f, /* NOT src OR NOT dst */
+ /* GXset */ 0xff, /* 1 */
+};
+
+CARD8 sisBltRop[16] = {
+ /* GXclear */ 0x00, /* 0 */
+ /* GXand */ 0x88, /* src AND dst */
+ /* GXandReverse */ 0x44, /* src AND NOT dst */
+ /* GXcopy */ 0xcc, /* src */
+ /* GXandInverted*/ 0x22, /* NOT src AND dst */
+ /* GXnoop */ 0xaa, /* dst */
+ /* GXxor */ 0x66, /* src XOR dst */
+ /* GXor */ 0xee, /* src OR dst */
+ /* GXnor */ 0x11, /* NOT src AND NOT dst */
+ /* GXequiv */ 0x99, /* NOT src XOR dst */
+ /* GXinvert */ 0x55, /* NOT dst */
+ /* GXorReverse */ 0xdd, /* src OR NOT dst */
+ /* GXcopyInverted*/ 0x33, /* NOT src */
+ /* GXorInverted */ 0xbb, /* NOT src OR dst */
+ /* GXnand */ 0x77, /* NOT src OR NOT dst */
+ /* GXset */ 0xff, /* 1 */
+};
+
+/* Align blts to this boundary or risk trashing an in-progress expand */
+#define SIS_MIN_PATTERN 8
+
+/* Do plane bits in this increment to balance CPU and graphics engine */
+#define SIS_PATTERN_INC 1024
+
+typedef struct _SisExpand {
+ SisCardInfo *sisc;
+ SisScreenInfo *siss;
+ CARD32 off;
+ int last;
+} SisExpand;
+
+static void
+sisExpandInit (ScreenPtr pScreen,
+ SisExpand *e)
+{
+ KdScreenPriv(pScreen);
+ sisCardInfo(pScreenPriv);
+ sisScreenInfo(pScreenPriv);
+
+ e->sisc = sisc;
+ e->siss = siss;
+ e->off = siss->expand_off;
+ e->last = 0;
+}
+
+static CARD32 *
+sisExpandAlloc (SisExpand *e,
+ int nb)
+{
+ SisCardInfo *sisc = e->sisc;
+ SisScreenInfo *siss = e->siss;
+ SisPtr sis = sisc->sis;
+ CARD32 off;
+
+ /* round up to alignment boundary */
+ nb = (nb + SIS_MIN_PATTERN-1) & ~(SIS_MIN_PATTERN-1);
+
+ off = e->off + e->last;
+ if (off + nb > siss->expand_off + siss->expand_len)
+ {
+ _sisWaitIdleEmpty (sis);
+ off = siss->expand_off;
+ }
+ e->off = off;
+ e->last = nb;
+ return (CARD32 *) (sisc->frameBuffer + off);
+}
+
+void
+sisGlyphBltClipped (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ unsigned int nglyph,
+ CharInfoPtr *ppciInit,
+ Bool imageBlt)
+{
+ SetupSis(pDrawable->pScreen);
+ FbGCPrivPtr fbPriv = fbGetGCPrivate(pGC);
+ int height;
+ int width;
+ int xBack, yBack;
+ int hBack, wBack;
+ int nb, bwidth, nl;
+ FontPtr pfont = pGC->font;
+ CharInfoPtr pci;
+ CARD8 *bits8, b;
+ CARD16 *bits16;
+ CARD32 *bits32;
+ BoxPtr extents;
+ BoxRec bbox;
+ unsigned char alu;
+ CARD32 cmd;
+ SisExpand expand;
+ CARD32 *dst, d;
+ int nbytes;
+ int shift;
+ int x1, y1, x2, y2;
+ RegionPtr pClip = fbGetCompositeClip(pGC);
+ BoxPtr pBox;
+ int nbox;
+ int rect_in;
+ int widthBlt;
+ CharInfoPtr *ppci;
+
+ x += pDrawable->x;
+ y += pDrawable->y;
+
+ if (imageBlt)
+ {
+ xBack = x;
+ yBack = y - FONTASCENT(pGC->font);
+ wBack = 0;
+ hBack = FONTASCENT(pGC->font) + FONTDESCENT(pGC->font);
+ if (hBack)
+ {
+ height = nglyph;
+ ppci = ppciInit;
+ while (height--)
+ wBack += (*ppci++)->metrics.characterWidth;
+ }
+ if (wBack < 0)
+ {
+ xBack = xBack + wBack;
+ wBack = -wBack;
+ }
+ if (hBack < 0)
+ {
+ yBack = yBack + hBack;
+ hBack = -hBack;
+ }
+ alu = GXcopy;
+ }
+ else
+ {
+ wBack = 0;
+ alu = pGC->alu;
+ }
+
+ if (wBack)
+ {
+ _sisSetSolidRect (sis, pGC->bgPixel, GXcopy, cmd);
+ for (nbox = REGION_NUM_RECTS (pClip),
+ pBox = REGION_RECTS (pClip);
+ nbox--;
+ pBox++)
+ {
+ x1 = xBack;
+ x2 = xBack + wBack;
+ y1 = yBack;
+ y2 = yBack + hBack;
+ if (x1 < pBox->x1) x1 = pBox->x1;
+ if (x2 > pBox->x2) x2 = pBox->x2;
+ if (y1 < pBox->y1) y1 = pBox->y1;
+ if (y2 > pBox->y2) y2 = pBox->y2;
+ if (x1 < x2 && y1 < y2)
+ {
+ _sisRect (sis, x1, y1, x2 - x1, y2 - y1, cmd);
+ }
+ }
+ }
+
+ sisExpandInit (pDrawable->pScreen, &expand);
+
+ sis->u.general.src_fg = pGC->fgPixel;
+ sis->u.general.src_pitch = 0;
+ sis->u.general.src_x = 0;
+ sis->u.general.src_y = 0;
+
+ cmd = (SIS_CMD_ENH_COLOR_EXPAND |
+ SIS_CMD_SRC_SCREEN |
+ SIS_CMD_PAT_FG |
+ (sisBltRop[alu] << 8) |
+ SIS_CMD_INC_X |
+ SIS_CMD_INC_Y |
+ SIS_CMD_RECT_CLIP_ENABLE |
+ SIS_CMD_TRANSPARENT);
+
+ ppci = ppciInit;
+ while (nglyph--)
+ {
+ pci = *ppci++;
+ height = pci->metrics.ascent + pci->metrics.descent;
+ width = pci->metrics.rightSideBearing - pci->metrics.leftSideBearing;
+ widthBlt = (width + 31) & ~31;
+ nb = (widthBlt >> 3) * height;
+ if (nb)
+ {
+ x1 = x + pci->metrics.leftSideBearing;
+ y1 = y - pci->metrics.ascent;
+ bbox.x1 = x1;
+ bbox.y1 = y1;
+ bbox.x2 = x1 + width;
+ bbox.y2 = y1 + height;
+ rect_in = RECT_IN_REGION(pGC->pScreen, pClip, &bbox);
+ if (rect_in != rgnOUT)
+ {
+ dst = sisExpandAlloc (&expand, nb);
+
+ sis->u.general.src_base = expand.off;
+ sis->u.general.dst_x = x1;
+ sis->u.general.dst_y = y1;
+ sis->u.general.rect_width = widthBlt;
+ sis->u.general.rect_height = height;
+ nb >>= 2;
+ bits32 = (CARD32 *) pci->bits;
+ while (nb--)
+ {
+ d = *bits32++;
+ SisInvertBits32 (d);
+ *dst++ = d;
+ }
+ if (rect_in == rgnPART)
+ {
+ for (nbox = REGION_NUM_RECTS (pClip),
+ pBox = REGION_RECTS (pClip);
+ nbox--;
+ pBox++)
+ {
+ _sisClip (sis, pBox->x1, pBox->y1, pBox->x2, pBox->y2);
+ sis->u.general.command = cmd;
+ }
+ }
+ else
+ {
+ _sisClip (sis, 0, 0, x1+width, pScreenPriv->screen->height);
+ sis->u.general.command = cmd;
+ }
+ }
+ }
+ x += pci->metrics.characterWidth;
+ }
+ _sisClip (sis, 0, 0,
+ pScreenPriv->screen->width, pScreenPriv->screen->height);
+ KdMarkSync (pDrawable->pScreen);
+}
+
+Bool
+sisTEGlyphBlt (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int xInit,
+ int yInit,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ Bool imageBlt)
+{
+ SetupSis(pDrawable->pScreen);
+ int x, y;
+ int widthGlyphs, widthGlyph;
+ int widthBlt;
+ FbBits depthMask;
+ int glyphsPer;
+ FontPtr pfont = pGC->font;
+ unsigned long *char1, *char2, *char3, *char4, *char5;
+ CARD8 alu;
+ CARD32 *dst, tmp;
+ CARD8 *dst8, *bits8;
+ int nb;
+ int bwidth;
+ CARD32 cmd;
+ int h;
+ BoxRec bbox;
+ SisExpand expand;
+ int lwTmp, lw;
+ int extra, n;
+
+ widthGlyph = FONTMAXBOUNDS(pfont,characterWidth);
+ if (!widthGlyph)
+ return TRUE;
+
+ h = FONTASCENT(pfont) + FONTDESCENT(pfont);
+ if (!h)
+ return TRUE;
+
+ x = xInit + FONTMAXBOUNDS(pfont,leftSideBearing) + pDrawable->x;
+ y = yInit - FONTASCENT(pfont) + pDrawable->y;
+
+ bbox.x1 = x;
+ bbox.x2 = x + (widthGlyph * nglyph);
+ bbox.y1 = y;
+ bbox.y2 = y + h;
+
+ switch (RECT_IN_REGION(pGC->pScreen, fbGetCompositeClip(pGC), &bbox))
+ {
+ case rgnPART:
+ if (x < 0 || y < 0)
+ return FALSE;
+ sisGlyphBltClipped (pDrawable, pGC, xInit, yInit, nglyph, ppci, imageBlt);
+ case rgnOUT:
+ return TRUE;
+ }
+
+ if (widthGlyph <= 6)
+ glyphsPer = 5;
+ else if (widthGlyph <= 8)
+ glyphsPer = 4;
+ else if (widthGlyph <= 10)
+ glyphsPer = 3;
+ else if (widthGlyph <= 16)
+ glyphsPer = 2;
+ else
+ glyphsPer = 1;
+
+ widthGlyphs = widthGlyph * glyphsPer;
+ widthBlt = widthGlyphs;
+
+ /* make sure scanlines are 32-bit aligned */
+ if (widthGlyphs <= 24)
+ widthBlt = 25;
+
+ cmd = (SIS_CMD_ENH_COLOR_EXPAND |
+ SIS_CMD_SRC_SCREEN |
+ SIS_CMD_PAT_FG |
+ SIS_CMD_INC_X |
+ SIS_CMD_INC_Y);
+
+ if (imageBlt)
+ {
+ sis->u.general.clip_right = bbox.x2;
+ cmd |= ((sisBltRop[GXcopy] << 8) |
+ SIS_CMD_OPAQUE |
+ SIS_CMD_RECT_CLIP_ENABLE);
+ }
+ else
+ {
+ cmd |= ((sisBltRop[pGC->alu] << 8) |
+ SIS_CMD_TRANSPARENT |
+ SIS_CMD_RECT_CLIP_DISABLE);
+ }
+
+ sisExpandInit (pDrawable->pScreen, &expand);
+
+ sis->u.general.src_fg = pGC->fgPixel;
+ sis->u.general.src_bg = pGC->bgPixel;
+
+ bwidth = (widthBlt + 7) >> 3;
+
+ nb = bwidth * h;
+
+#define LoopIt(count, loadup, fetch) \
+ while (nglyph >= count) \
+ { \
+ nglyph -= count; \
+ dst = sisExpandAlloc (&expand, nb); \
+ sis->u.general.src_base = expand.off; \
+ sis->u.general.src_pitch = 0; \
+ sis->u.general.src_x = 0; \
+ sis->u.general.src_y = 0; \
+ sis->u.general.dst_x = x; \
+ sis->u.general.dst_y = y; \
+ sis->u.general.rect_width = widthBlt; \
+ sis->u.general.rect_height = h; \
+ x += widthGlyphs; \
+ loadup \
+ lwTmp = h; \
+ while (lwTmp--) { \
+ tmp = fetch; \
+ SisInvertBits32(tmp); \
+ *dst++ = tmp; \
+ } \
+ sis->u.general.command = cmd; \
+ }
+
+ switch (glyphsPer) {
+ case 5:
+ LoopIt(5,
+ char1 = (unsigned long *) (*ppci++)->bits;
+ char2 = (unsigned long *) (*ppci++)->bits;
+ char3 = (unsigned long *) (*ppci++)->bits;
+ char4 = (unsigned long *) (*ppci++)->bits;
+ char5 = (unsigned long *) (*ppci++)->bits;,
+ (*char1++ | ((*char2++ | ((*char3++ | ((*char4++ | (*char5++
+ << widthGlyph))
+ << widthGlyph))
+ << widthGlyph))
+ << widthGlyph)));
+ break;
+ case 4:
+ LoopIt(4,
+ char1 = (unsigned long *) (*ppci++)->bits;
+ char2 = (unsigned long *) (*ppci++)->bits;
+ char3 = (unsigned long *) (*ppci++)->bits;
+ char4 = (unsigned long *) (*ppci++)->bits;,
+ (*char1++ | ((*char2++ | ((*char3++ | (*char4++
+ << widthGlyph))
+ << widthGlyph))
+ << widthGlyph)));
+ break;
+ case 3:
+ LoopIt(3,
+ char1 = (unsigned long *) (*ppci++)->bits;
+ char2 = (unsigned long *) (*ppci++)->bits;
+ char3 = (unsigned long *) (*ppci++)->bits;,
+ (*char1++ | ((*char2++ | (*char3++ << widthGlyph)) << widthGlyph)));
+ break;
+ case 2:
+ LoopIt(2,
+ char1 = (unsigned long *) (*ppci++)->bits;
+ char2 = (unsigned long *) (*ppci++)->bits;,
+ (*char1++ | (*char2++ << widthGlyph)));
+ break;
+ }
+
+ widthBlt = (widthGlyph + 31) & ~31;
+
+ bwidth = widthBlt >> 3;
+
+ nb = bwidth * h;
+
+ lw = (widthBlt >> 5) * h;
+
+ while (nglyph--)
+ {
+ dst = (CARD32 *) sisExpandAlloc (&expand, nb);
+ char1 = (CARD32 *) (*ppci++)->bits;
+ sis->u.general.src_base = expand.off;
+ sis->u.general.src_pitch = 0;
+ sis->u.general.src_x = 0;
+ sis->u.general.src_y = 0;
+ sis->u.general.dst_x = x;
+ sis->u.general.dst_y = y;
+ sis->u.general.rect_width = widthBlt;
+ sis->u.general.rect_height = h;
+ lwTmp = lw;
+ while (lwTmp--)
+ {
+ tmp = *char1++;
+ SisInvertBits32 (tmp);
+ *dst++ = tmp;
+ }
+ sis->u.general.command = cmd;
+ x += widthGlyph;
+ }
+ if (imageBlt)
+ sis->u.general.clip_right = pScreenPriv->screen->width;
+ KdMarkSync (pDrawable->pScreen);
+ return TRUE;
+}
+
+Bool
+sisGlyphBlt(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ unsigned int nglyph,
+ CharInfoPtr *ppciInit,
+ Bool imageBlt)
+{
+ SetupSis(pDrawable->pScreen);
+ int height;
+ int width;
+ int xBack, yBack;
+ int hBack, wBack;
+ int nb, bwidth, nl;
+ FontPtr pfont = pGC->font;
+ CharInfoPtr pci;
+ CARD8 *bits8, b;
+ CARD16 *bits16;
+ CARD32 *bits32;
+ BoxPtr extents;
+ BoxRec bbox;
+ CharInfoPtr *ppci;
+ unsigned char alu;
+ CARD32 cmd;
+ SisExpand expand;
+ CARD32 *dst, d;
+ int nbytes;
+ int shift;
+
+ x += pDrawable->x;
+ y += pDrawable->y;
+
+ /* compute an approximate (but covering) bounding box */
+ ppci = ppciInit;
+ width = 0;
+ height = nglyph;
+ while (height--)
+ width += (*ppci++)->metrics.characterWidth;
+ if (width < 0)
+ {
+ bbox.x1 = x + width;
+ bbox.x2 = x;
+ }
+ else
+ {
+ bbox.x1 = x;
+ bbox.x2 = x + width;
+ }
+ width = FONTMINBOUNDS(pfont,leftSideBearing);
+ if (width < 0)
+ bbox.x1 += width;
+ width = FONTMAXBOUNDS(pfont, rightSideBearing) - FONTMINBOUNDS(pfont, characterWidth);
+ if (width > 0)
+ bbox.x2 += width;
+ bbox.y1 = y - FONTMAXBOUNDS(pfont,ascent);
+ bbox.y2 = y + FONTMAXBOUNDS(pfont,descent);
+
+ switch (RECT_IN_REGION(pGC->pScreen, fbGetCompositeClip(pGC), &bbox))
+ {
+ case rgnPART:
+ if (bbox.x1 < 0 || bbox.y1 < 0)
+ return FALSE;
+ sisGlyphBltClipped (pDrawable, pGC,
+ x - pDrawable->x, y - pDrawable->y,
+ nglyph, ppciInit, imageBlt);
+ case rgnOUT:
+ return TRUE;
+ }
+
+ if (imageBlt)
+ {
+ xBack = x;
+ yBack = y - FONTASCENT(pGC->font);
+ wBack = 0;
+ hBack = FONTASCENT(pGC->font) + FONTDESCENT(pGC->font);
+ if (hBack)
+ {
+ height = nglyph;
+ ppci = ppciInit;
+ while (height--)
+ wBack += (*ppci++)->metrics.characterWidth;
+ }
+ if (wBack < 0)
+ {
+ xBack = xBack + wBack;
+ wBack = -wBack;
+ }
+ if (hBack < 0)
+ {
+ yBack = yBack + hBack;
+ hBack = -hBack;
+ }
+ alu = GXcopy;
+ }
+ else
+ {
+ wBack = 0;
+ alu = pGC->alu;
+ }
+
+ if (wBack)
+ {
+ _sisSetSolidRect (sis, pGC->bgPixel, GXcopy, cmd);
+ _sisRect (sis, xBack, yBack, wBack, hBack, cmd);
+ }
+
+ sisExpandInit (pDrawable->pScreen, &expand);
+
+ sis->u.general.src_fg = pGC->fgPixel;
+
+ cmd = (SIS_CMD_ENH_COLOR_EXPAND |
+ SIS_CMD_SRC_SCREEN |
+ SIS_CMD_PAT_FG |
+ (sisBltRop[alu] << 8) |
+ SIS_CMD_INC_X |
+ SIS_CMD_INC_Y |
+ SIS_CMD_RECT_CLIP_DISABLE |
+ SIS_CMD_TRANSPARENT);
+
+ ppci = ppciInit;
+ while (nglyph--)
+ {
+ pci = *ppci++;
+ height = pci->metrics.ascent + pci->metrics.descent;
+ width = pci->metrics.rightSideBearing - pci->metrics.leftSideBearing;
+ /*
+ * For glyphs wider than 16 pixels, expand the blt to the nearest multiple
+ * of 32; this allows the scanlines to be padded to a 32-bit boundary
+ * instead of requiring byte packing
+ */
+ if (width > 16)
+ width = (width + 31) & ~31;
+ bwidth = (width + 7) >> 3;
+ nb = bwidth * height;
+ if (nb)
+ {
+ dst = sisExpandAlloc (&expand, nb);
+
+ sis->u.general.src_base = expand.off;
+ sis->u.general.src_pitch = 0;
+ sis->u.general.src_x = 0;
+ sis->u.general.src_y = 0;
+ sis->u.general.dst_x = x + pci->metrics.leftSideBearing;
+ sis->u.general.dst_y = y - pci->metrics.ascent;
+ sis->u.general.rect_width = width;
+ sis->u.general.rect_height = height;
+ switch (bwidth) {
+ case 1:
+ bits8 = (CARD8 *) pci->bits;
+ while (height >= 4)
+ {
+ d = (bits8[0] | (bits8[4] << 8) |
+ (bits8[8] << 16) | (bits8[12] << 24));
+ SisInvertBits32(d);
+ *dst++ = d;
+ bits8 += 16;
+ height -= 4;
+ }
+ if (height)
+ {
+ switch (height) {
+ case 3:
+ d = bits8[0] | (bits8[4] << 8) | (bits8[8] << 16);
+ break;
+ case 2:
+ d = bits8[0] | (bits8[4] << 8);
+ break;
+ case 1:
+ d = bits8[0];
+ break;
+ }
+ SisInvertBits32(d);
+ *dst++ = d;
+ }
+ break;
+ case 2:
+ bits16 = (CARD16 *) pci->bits;
+ while (height >= 2)
+ {
+ d = bits16[0] | (bits16[2] << 16);
+ SisInvertBits32(d);
+ *dst++ = d;
+ bits16 += 4;
+ height -= 2;
+ }
+ if (height)
+ {
+ d = bits16[0];
+ SisInvertBits32(d);
+ *dst++ = d;
+ }
+ break;
+ default:
+ nb >>= 2;
+ bits32 = (CARD32 *) pci->bits;
+ while (nb--)
+ {
+ d = *bits32++;
+ SisInvertBits32 (d);
+ *dst++ = d;
+ }
+ }
+ sis->u.general.command = cmd;
+ }
+ x += pci->metrics.characterWidth;
+ }
+ KdMarkSync (pDrawable->pScreen);
+ return TRUE;
+}
+/*
+ * Blt glyphs using Sis image transfer register, this does both
+ * poly glyph blt and image glyph blt (when pglyphBase == 1)
+ */
+
+void
+sisPolyGlyphBlt (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x, int y,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase)
+{
+ FbBits depthMask;
+
+ depthMask = FbFullMask (pDrawable->depth);
+ if ((pGC->planemask & depthMask) == depthMask &&
+ pGC->fillStyle == FillSolid)
+ {
+ if (TERMINALFONT(pGC->font))
+ {
+ if (sisTEGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, FALSE))
+ return;
+ }
+ else
+ {
+ if (sisGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, FALSE))
+ return;
+ }
+ }
+ KdCheckPolyGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
+}
+
+void
+sisImageGlyphBlt (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x, int y,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase)
+{
+ FbBits depthMask;
+
+ depthMask = FbFullMask (pDrawable->depth);
+ if ((pGC->planemask & depthMask) == depthMask)
+ {
+ if (TERMINALFONT(pGC->font))
+ {
+ if (sisTEGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, TRUE))
+ return;
+ }
+ else
+ {
+ if (sisGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, TRUE))
+ return;
+ }
+ }
+ KdCheckImageGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
+}
+
+#define sourceInvarient(alu) (((alu) & 3) == (((alu) >> 2) & 3))
+
+#define sisPatternDimOk(d) ((d) <= 8 && (((d) & ((d) - 1)) == 0))
+
+BOOL
+sisFillOk (GCPtr pGC)
+{
+ FbBits depthMask;
+
+ depthMask = FbFullMask(pGC->depth);
+ if ((pGC->planemask & depthMask) != depthMask)
+ return FALSE;
+ switch (pGC->fillStyle) {
+ case FillSolid:
+ return TRUE;
+ case FillTiled:
+ return (sisPatternDimOk (pGC->tile.pixmap->drawable.width) &&
+ sisPatternDimOk (pGC->tile.pixmap->drawable.height));
+ case FillStippled:
+ case FillOpaqueStippled:
+ return (sisPatternDimOk (pGC->stipple->drawable.width) &&
+ sisPatternDimOk (pGC->stipple->drawable.height));
+ }
+}
+
+CARD32
+sisStipplePrepare (DrawablePtr pDrawable, GCPtr pGC)
+{
+ SetupSis(pGC->pScreen);
+ PixmapPtr pStip = pGC->stipple;
+ int stipHeight = pStip->drawable.height;
+ int xRot, yRot;
+ int rot, stipX, stipY;
+ FbStip *stip, *stipEnd, bits;
+ FbStride stipStride;
+ int stipBpp;
+ int y;
+ CARD32 cmd;
+
+ xRot = pGC->patOrg.x + pDrawable->x;
+ yRot = pGC->patOrg.y + pDrawable->y;
+ modulus (- yRot, stipHeight, stipY);
+ modulus (- xRot, FB_UNIT, stipX);
+ rot = stipX;
+
+ fbGetStipDrawable (&pStip->drawable, stip, stipStride, stipBpp);
+ for (y = 0; y < 8; y++)
+ {
+ bits = stip[stipY<<1];
+ FbRotLeft(bits, rot);
+ SisInvertBits32(bits);
+ sis->u.general.mask[y] = (CARD8) bits;
+ stipY++;
+ if (stipY == stipHeight)
+ stipY = 0;
+ }
+ sis->u.general.pattern_fg = pGC->fgPixel;
+
+ cmd = (SIS_CMD_BITBLT |
+ SIS_CMD_SRC_SCREEN |
+ SIS_CMD_PAT_MONO |
+ (sisPatRop[pGC->alu] << 8) |
+ SIS_CMD_INC_X |
+ SIS_CMD_INC_Y |
+ SIS_CMD_RECT_CLIP_DISABLE |
+ SIS_CMD_RECT_CLIP_DONT_MERGE);
+ if (pGC->fillStyle == FillOpaqueStippled)
+ {
+ sis->u.general.pattern_bg = pGC->bgPixel;
+ cmd |= SIS_CMD_OPAQUE;
+ }
+ else
+ cmd |= SIS_CMD_TRANSPARENT;
+ return cmd;
+}
+
+CARD32
+sisTilePrepare (PixmapPtr pTile, int xRot, int yRot, CARD8 alu)
+{
+ SetupSis(pTile->drawable.pScreen);
+ int tileHeight = pTile->drawable.height;
+ int tileWidth = pTile->drawable.width;
+ FbBits *tile;
+ FbStride tileStride;
+ int tileBpp;
+
+ fbGetDrawable (&pTile->drawable, tile, tileStride, tileBpp);
+
+ /*
+ * Tile the pattern register
+ */
+ fbTile ((FbBits *) sis->u.general.pattern,
+ (8 * tileBpp) >> FB_SHIFT,
+ 0,
+
+ 8 * tileBpp, 8,
+
+ tile,
+ tileStride,
+ tileWidth * tileBpp,
+ tileHeight,
+ GXcopy, FB_ALLONES, tileBpp,
+ xRot * tileBpp,
+ yRot);
+
+ return (SIS_CMD_BITBLT |
+ SIS_CMD_SRC_SCREEN |
+ SIS_CMD_PAT_PATTERN |
+ (sisPatRop[alu] << 8) |
+ SIS_CMD_INC_X |
+ SIS_CMD_INC_Y |
+ SIS_CMD_RECT_CLIP_DISABLE |
+ SIS_CMD_RECT_CLIP_DONT_MERGE);
+}
+
+void
+sisFillBoxSolid (DrawablePtr pDrawable, int nBox, BoxPtr pBox,
+ unsigned long pixel, int alu)
+{
+ SetupSis(pDrawable->pScreen);
+ CARD32 cmd;
+
+ _sisSetSolidRect(sis,pixel,alu,cmd);
+
+ while (nBox--)
+ {
+ _sisRect(sis,pBox->x1,pBox->y1,pBox->x2-pBox->x1,pBox->y2-pBox->y1,cmd);
+ pBox++;
+ }
+ KdMarkSync (pDrawable->pScreen);
+}
+
+void
+sisFillBoxStipple (DrawablePtr pDrawable, GCPtr pGC,
+ int nBox, BoxPtr pBox)
+{
+ SetupSis(pDrawable->pScreen);
+ CARD32 cmd;
+
+ cmd = sisStipplePrepare (pDrawable, pGC);
+
+ while (nBox--)
+ {
+ _sisRect(sis,pBox->x1,pBox->y1,pBox->x2-pBox->x1,pBox->y2-pBox->y1,cmd);
+ pBox++;
+ }
+ KdMarkSync (pDrawable->pScreen);
+}
+
+void
+sisFillBoxTiled (DrawablePtr pDrawable,
+ int nBox, BoxPtr pBox,
+ PixmapPtr pTile, int xRot, int yRot, CARD8 alu)
+{
+ SetupSis (pDrawable->pScreen);
+ CARD32 cmd;
+
+ cmd = sisTilePrepare (pTile, xRot, yRot, alu);
+
+ while (nBox--)
+ {
+ _sisRect(sis,pBox->x1,pBox->y1,pBox->x2-pBox->x1,pBox->y2-pBox->y1,cmd);
+ pBox++;
+ }
+ KdMarkSync (pDrawable->pScreen);
+}
+
+/*
+ sisDoBitBlt
+ =============
+ Bit Blit for all window to window blits.
+*/
+
+void
+sisCopyNtoN (DrawablePtr pSrcDrawable,
+ DrawablePtr pDstDrawable,
+ GCPtr pGC,
+ BoxPtr pbox,
+ int nbox,
+ int dx,
+ int dy,
+ Bool reverse,
+ Bool upsidedown,
+ Pixel bitplane,
+ void *closure)
+{
+ SetupSis(pDstDrawable->pScreen);
+ int srcX, srcY, dstX, dstY;
+ int w, h;
+ CARD32 flags;
+ CARD32 cmd;
+ CARD8 alu;
+
+ if (pGC)
+ {
+ alu = pGC->alu;
+ if (sourceInvarient (pGC->alu))
+ {
+ sisFillBoxSolid (pDstDrawable, nbox, pbox, 0, pGC->alu);
+ return;
+ }
+ }
+ else
+ alu = GXcopy;
+
+ _sisSetBlt(sis,alu,cmd);
+ while (nbox--)
+ {
+ w = pbox->x2 - pbox->x1;
+ h = pbox->y2 - pbox->y1;
+ flags = 0;
+ if (reverse)
+ {
+ dstX = pbox->x2 - 1;
+ }
+ else
+ {
+ dstX = pbox->x1;
+ flags |= SIS_CMD_INC_X;
+ }
+ srcX = dstX + dx;
+
+ if (upsidedown)
+ {
+ dstY = pbox->y2 - 1;
+ }
+ else
+ {
+ dstY = pbox->y1;
+ flags |= SIS_CMD_INC_Y;
+ }
+ srcY = dstY + dy;
+
+ _sisBlt (sis, srcX, srcY, dstX, dstY, w, h, cmd|flags);
+ pbox++;
+ }
+ KdMarkSync (pDstDrawable->pScreen);
+}
+
+RegionPtr
+sisCopyArea(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC,
+ int srcx, int srcy, int width, int height, int dstx, int dsty)
+{
+ KdScreenPriv(pDstDrawable->pScreen);
+ FbBits depthMask;
+
+ depthMask = FbFullMask (pDstDrawable->depth);
+ if ((pGC->planemask & depthMask) == depthMask &&
+ pSrcDrawable->type == DRAWABLE_WINDOW &&
+ pDstDrawable->type == DRAWABLE_WINDOW)
+ {
+ return fbDoCopy (pSrcDrawable, pDstDrawable, pGC,
+ srcx, srcy, width, height,
+ dstx, dsty, sisCopyNtoN, 0, 0);
+ }
+ return KdCheckCopyArea (pSrcDrawable, pDstDrawable, pGC,
+ srcx, srcy, width, height, dstx, dsty);
+}
+
+typedef struct _sis1toNargs {
+ unsigned long copyPlaneFG, copyPlaneBG;
+} sis1toNargs;
+
+void
+_sisStipple (ScreenPtr pScreen,
+ FbStip *psrcBase,
+ FbStride widthSrc,
+ CARD8 alu,
+ int srcx,
+ int srcy,
+ int dstx,
+ int dsty,
+ int width,
+ int height)
+{
+ SetupSis(pScreen);
+ FbStip *psrcLine, *psrc;
+ FbStride widthRest;
+ FbStip bits, tmp, lastTmp;
+ int leftShift, rightShift;
+ int nl, nlMiddle;
+ int r;
+ SisExpand expand;
+ CARD32 *dst;
+ int hthis;
+ int hper;
+ int bwidth;
+ CARD32 cmd;
+
+ sisExpandInit (pScreen, &expand);
+
+ /* Compute blt address and parameters */
+ psrc = psrcBase + srcy * widthSrc + (srcx >> 5);
+ nlMiddle = (width + 31) >> 5;
+ leftShift = srcx & 0x1f;
+ rightShift = 32 - leftShift;
+ widthRest = widthSrc - nlMiddle;
+
+ cmd = (SIS_CMD_ENH_COLOR_EXPAND |
+ SIS_CMD_SRC_SCREEN |
+ SIS_CMD_PAT_FG |
+ (sisBltRop[alu] << 8) |
+ SIS_CMD_INC_X |
+ SIS_CMD_INC_Y |
+ SIS_CMD_OPAQUE |
+ SIS_CMD_RECT_CLIP_ENABLE);
+
+ if (leftShift != 0)
+ widthRest--;
+
+ sis->u.general.src_x = 0;
+ sis->u.general.src_y = 0;
+ sis->u.general.dst_x = dstx;
+ sis->u.general.rect_width = (width + 31) & ~31;
+ sis->u.general.clip_right = (dstx + width);
+
+ bwidth = nlMiddle << 2;
+ hper = SIS_PATTERN_INC / bwidth;
+ if (hper == 0)
+ hper = 1;
+
+ while (height)
+ {
+ hthis = hper;
+ if (hthis > height)
+ hthis = height;
+ dst = sisExpandAlloc (&expand, bwidth * hthis);
+ sis->u.general.src_base = expand.off;
+ sis->u.general.dst_y = dsty;
+ sis->u.general.rect_height = hthis;
+
+ dsty += hthis;
+ height -= hthis;
+
+ if (leftShift == 0)
+ {
+ while (hthis--)
+ {
+ nl = nlMiddle;
+ while (nl--)
+ {
+ tmp = *psrc++;
+ SisInvertBits32(tmp);
+ *dst++ = tmp;
+ }
+ psrc += widthRest;
+ }
+ }
+ else
+ {
+ while (hthis--)
+ {
+ bits = *psrc++;
+ nl = nlMiddle;
+ while (nl--)
+ {
+ tmp = FbStipLeft(bits, leftShift);
+ bits = *psrc++;
+ tmp |= FbStipRight(bits, rightShift);
+ SisInvertBits32(tmp);
+ *dst++ = tmp;
+ }
+ psrc += widthRest;
+ }
+ }
+ sis->u.general.command = cmd;
+ }
+ sis->u.general.clip_right = pScreenPriv->screen->width;
+}
+
+void
+sisCopy1toN (DrawablePtr pSrcDrawable,
+ DrawablePtr pDstDrawable,
+ GCPtr pGC,
+ BoxPtr pbox,
+ int nbox,
+ int dx,
+ int dy,
+ Bool reverse,
+ Bool upsidedown,
+ Pixel bitplane,
+ void *closure)
+{
+ SetupSis(pDstDrawable->pScreen);
+
+ sis1toNargs *args = closure;
+ int dstx, dsty;
+ FbStip *psrcBase;
+ FbStride widthSrc;
+ int srcBpp;
+
+ if (sourceInvarient (pGC->alu))
+ {
+ sisFillBoxSolid (pDstDrawable, nbox, pbox,
+ pGC->bgPixel, pGC->alu);
+ return;
+ }
+
+ fbGetStipDrawable (pSrcDrawable, psrcBase, widthSrc, srcBpp);
+
+ sis->u.general.src_fg = args->copyPlaneFG;
+ sis->u.general.src_bg = args->copyPlaneBG;
+
+ while (nbox--)
+ {
+ dstx = pbox->x1;
+ dsty = pbox->y1;
+
+ _sisStipple (pDstDrawable->pScreen,
+ psrcBase, widthSrc,
+ pGC->alu,
+ dstx + dx, dsty + dy,
+ dstx, dsty,
+ pbox->x2 - dstx, pbox->y2 - dsty);
+ pbox++;
+ }
+ KdMarkSync (pDstDrawable->pScreen);
+}
+
+RegionPtr
+sisCopyPlane(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC,
+ int srcx, int srcy, int width, int height,
+ int dstx, int dsty, unsigned long bitPlane)
+{
+ KdScreenPriv (pDstDrawable->pScreen);
+ RegionPtr ret;
+ sis1toNargs args;
+ FbBits depthMask;
+
+ depthMask = FbFullMask (pDstDrawable->depth);
+ if ((pGC->planemask & depthMask) == depthMask &&
+ pDstDrawable->type == DRAWABLE_WINDOW &&
+ pSrcDrawable->depth == 1)
+ {
+ args.copyPlaneFG = pGC->fgPixel;
+ args.copyPlaneBG = pGC->bgPixel;
+ return fbDoCopy (pSrcDrawable, pDstDrawable, pGC,
+ srcx, srcy, width, height,
+ dstx, dsty, sisCopy1toN, bitPlane, &args);
+ }
+ return KdCheckCopyPlane(pSrcDrawable, pDstDrawable, pGC,
+ srcx, srcy, width, height,
+ dstx, dsty, bitPlane);
+}
+
+void
+sisFillSpans (DrawablePtr pDrawable, GCPtr pGC, int n,
+ DDXPointPtr ppt, int *pwidth, int fSorted)
+{
+ SetupSis(pDrawable->pScreen);
+ DDXPointPtr pptFree;
+ FbGCPrivPtr fbPriv = fbGetGCPrivate(pGC);
+ int *pwidthFree;/* copies of the pointers to free */
+ CARD32 cmd;
+ int nTmp;
+ INT16 x, y;
+ int width;
+
+ if (!sisFillOk (pGC))
+ {
+ KdCheckFillSpans (pDrawable, pGC, n, ppt, pwidth, fSorted);
+ return;
+ }
+ nTmp = n * miFindMaxBand(fbGetCompositeClip(pGC));
+ pwidthFree = (int *)ALLOCATE_LOCAL(nTmp * sizeof(int));
+ pptFree = (DDXPointRec *)ALLOCATE_LOCAL(nTmp * sizeof(DDXPointRec));
+ if(!pptFree || !pwidthFree)
+ {
+ if (pptFree) DEALLOCATE_LOCAL(pptFree);
+ if (pwidthFree) DEALLOCATE_LOCAL(pwidthFree);
+ return;
+ }
+ n = miClipSpans(fbGetCompositeClip(pGC),
+ ppt, pwidth, n,
+ pptFree, pwidthFree, fSorted);
+ pwidth = pwidthFree;
+ ppt = pptFree;
+ switch (pGC->fillStyle) {
+ case FillSolid:
+ _sisSetSolidRect(sis,pGC->fgPixel,pGC->alu,cmd);
+ break;
+ case FillTiled:
+ cmd = sisTilePrepare (pGC->tile.pixmap,
+ pGC->patOrg.x + pDrawable->x,
+ pGC->patOrg.y + pDrawable->y,
+ pGC->alu);
+ break;
+ default:
+ cmd = sisStipplePrepare (pDrawable, pGC);
+ break;
+ }
+ while (n--)
+ {
+ x = ppt->x;
+ y = ppt->y;
+ ppt++;
+ width = *pwidth++;
+ if (width)
+ {
+ _sisRect(sis,x,y,width,1,cmd);
+ }
+ }
+ KdMarkSync (pDrawable->pScreen);
+ DEALLOCATE_LOCAL(pptFree);
+ DEALLOCATE_LOCAL(pwidthFree);
+}
+
+#define NUM_STACK_RECTS 1024
+
+void
+sisPolyFillRect (DrawablePtr pDrawable, GCPtr pGC,
+ int nrectFill, xRectangle *prectInit)
+{
+ SetupSis(pDrawable->pScreen);
+ xRectangle *prect;
+ RegionPtr prgnClip;
+ register BoxPtr pbox;
+ register BoxPtr pboxClipped;
+ BoxPtr pboxClippedBase;
+ BoxPtr pextent;
+ BoxRec stackRects[NUM_STACK_RECTS];
+ FbGCPrivPtr fbPriv = fbGetGCPrivate (pGC);
+ int numRects;
+ int n;
+ int xorg, yorg;
+ int x, y;
+
+ if (!sisFillOk (pGC))
+ {
+ KdCheckPolyFillRect (pDrawable, pGC, nrectFill, prectInit);
+ return;
+ }
+ prgnClip = fbGetCompositeClip(pGC);
+ xorg = pDrawable->x;
+ yorg = pDrawable->y;
+
+ if (xorg || yorg)
+ {
+ prect = prectInit;
+ n = nrectFill;
+ while(n--)
+ {
+ prect->x += xorg;
+ prect->y += yorg;
+ prect++;
+ }
+ }
+
+ prect = prectInit;
+
+ numRects = REGION_NUM_RECTS(prgnClip) * nrectFill;
+ if (numRects > NUM_STACK_RECTS)
+ {
+ pboxClippedBase = (BoxPtr)ALLOCATE_LOCAL(numRects * sizeof(BoxRec));
+ if (!pboxClippedBase)
+ return;
+ }
+ else
+ pboxClippedBase = stackRects;
+
+ pboxClipped = pboxClippedBase;
+
+ if (REGION_NUM_RECTS(prgnClip) == 1)
+ {
+ int x1, y1, x2, y2, bx2, by2;
+
+ pextent = REGION_RECTS(prgnClip);
+ x1 = pextent->x1;
+ y1 = pextent->y1;
+ x2 = pextent->x2;
+ y2 = pextent->y2;
+ while (nrectFill--)
+ {
+ if ((pboxClipped->x1 = prect->x) < x1)
+ pboxClipped->x1 = x1;
+
+ if ((pboxClipped->y1 = prect->y) < y1)
+ pboxClipped->y1 = y1;
+
+ bx2 = (int) prect->x + (int) prect->width;
+ if (bx2 > x2)
+ bx2 = x2;
+ pboxClipped->x2 = bx2;
+
+ by2 = (int) prect->y + (int) prect->height;
+ if (by2 > y2)
+ by2 = y2;
+ pboxClipped->y2 = by2;
+
+ prect++;
+ if ((pboxClipped->x1 < pboxClipped->x2) &&
+ (pboxClipped->y1 < pboxClipped->y2))
+ {
+ pboxClipped++;
+ }
+ }
+ }
+ else
+ {
+ int x1, y1, x2, y2, bx2, by2;
+
+ pextent = REGION_EXTENTS(pGC->pScreen, prgnClip);
+ x1 = pextent->x1;
+ y1 = pextent->y1;
+ x2 = pextent->x2;
+ y2 = pextent->y2;
+ while (nrectFill--)
+ {
+ BoxRec box;
+
+ if ((box.x1 = prect->x) < x1)
+ box.x1 = x1;
+
+ if ((box.y1 = prect->y) < y1)
+ box.y1 = y1;
+
+ bx2 = (int) prect->x + (int) prect->width;
+ if (bx2 > x2)
+ bx2 = x2;
+ box.x2 = bx2;
+
+ by2 = (int) prect->y + (int) prect->height;
+ if (by2 > y2)
+ by2 = y2;
+ box.y2 = by2;
+
+ prect++;
+
+ if ((box.x1 >= box.x2) || (box.y1 >= box.y2))
+ continue;
+
+ n = REGION_NUM_RECTS (prgnClip);
+ pbox = REGION_RECTS(prgnClip);
+
+ /* clip the rectangle to each box in the clip region
+ this is logically equivalent to calling Intersect()
+ */
+ while(n--)
+ {
+ pboxClipped->x1 = max(box.x1, pbox->x1);
+ pboxClipped->y1 = max(box.y1, pbox->y1);
+ pboxClipped->x2 = min(box.x2, pbox->x2);
+ pboxClipped->y2 = min(box.y2, pbox->y2);
+ pbox++;
+
+ /* see if clipping left anything */
+ if(pboxClipped->x1 < pboxClipped->x2 &&
+ pboxClipped->y1 < pboxClipped->y2)
+ {
+ pboxClipped++;
+ }
+ }
+ }
+ }
+ if (pboxClipped != pboxClippedBase)
+ {
+ switch (pGC->fillStyle) {
+ case FillSolid:
+ sisFillBoxSolid(pDrawable,
+ pboxClipped-pboxClippedBase, pboxClippedBase,
+ pGC->fgPixel, pGC->alu);
+ break;
+ case FillTiled:
+ sisFillBoxTiled(pDrawable,
+ pboxClipped-pboxClippedBase, pboxClippedBase,
+ pGC->tile.pixmap,
+ pGC->patOrg.x + pDrawable->x,
+ pGC->patOrg.y + pDrawable->y,
+ pGC->alu);
+ break;
+ case FillStippled:
+ case FillOpaqueStippled:
+ sisFillBoxStipple (pDrawable, pGC,
+ pboxClipped-pboxClippedBase, pboxClippedBase);
+ break;
+ }
+ }
+ if (pboxClippedBase != stackRects)
+ DEALLOCATE_LOCAL(pboxClippedBase);
+}
+
+static const GCOps sisOps = {
+ sisFillSpans,
+ KdCheckSetSpans,
+ KdCheckPutImage,
+ sisCopyArea,
+ sisCopyPlane,
+ KdCheckPolyPoint,
+ KdCheckPolylines,
+ KdCheckPolySegment,
+ miPolyRectangle,
+ KdCheckPolyArc,
+ miFillPolygon,
+ sisPolyFillRect,
+ KdCheckPolyFillArc,
+ miPolyText8,
+ miPolyText16,
+ miImageText8,
+ miImageText16,
+ sisImageGlyphBlt,
+ sisPolyGlyphBlt,
+ KdCheckPushPixels,
+#ifdef NEED_LINEHELPER
+ ,NULL
+#endif
+};
+
+void
+sisValidateGC (GCPtr pGC, Mask changes, DrawablePtr pDrawable)
+{
+ FbGCPrivPtr fbPriv = fbGetGCPrivate(pGC);
+
+ fbValidateGC (pGC, changes, pDrawable);
+
+ if (pDrawable->type == DRAWABLE_WINDOW)
+ pGC->ops = (GCOps *) &sisOps;
+ else
+ pGC->ops = (GCOps *) &kdAsyncPixmapGCOps;
+}
+
+GCFuncs sisGCFuncs = {
+ sisValidateGC,
+ miChangeGC,
+ miCopyGC,
+ miDestroyGC,
+ miChangeClip,
+ miDestroyClip,
+ miCopyClip
+};
+
+int
+sisCreateGC (GCPtr pGC)
+{
+ if (!fbCreateGC (pGC))
+ return FALSE;
+
+ if (pGC->depth != 1)
+ pGC->funcs = &sisGCFuncs;
+
+ pGC->ops = (GCOps *) &kdAsyncPixmapGCOps;
+
+ return TRUE;
+}
+
+void
+sisCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ KdScreenPriv(pScreen);
+ RegionRec rgnDst;
+ int dx, dy;
+ WindowPtr pwinRoot;
+
+ pwinRoot = WindowTable[pWin->drawable.pScreen->myNum];
+
+ dx = ptOldOrg.x - pWin->drawable.x;
+ dy = ptOldOrg.y - pWin->drawable.y;
+ REGION_TRANSLATE(pWin->drawable.pScreen, prgnSrc, -dx, -dy);
+
+ REGION_INIT (pWin->drawable.pScreen, &rgnDst, NullBox, 0);
+
+ REGION_INTERSECT(pWin->drawable.pScreen, &rgnDst, &pWin->borderClip, prgnSrc);
+
+ fbCopyRegion ((DrawablePtr)pwinRoot, (DrawablePtr)pwinRoot,
+ 0,
+ &rgnDst, dx, dy, sisCopyNtoN, 0, 0);
+
+ REGION_UNINIT(pWin->drawable.pScreen, &rgnDst);
+}
+
+void
+sisPaintWindow(WindowPtr pWin, RegionPtr pRegion, int what)
+{
+ KdScreenPriv(pWin->drawable.pScreen);
+ PixmapPtr pTile;
+
+ if (!REGION_NUM_RECTS(pRegion))
+ return;
+ switch (what) {
+ case PW_BACKGROUND:
+ switch (pWin->backgroundState) {
+ case None:
+ return;
+ case ParentRelative:
+ do {
+ pWin = pWin->parent;
+ } while (pWin->backgroundState == ParentRelative);
+ (*pWin->drawable.pScreen->PaintWindowBackground)(pWin, pRegion,
+ what);
+ return;
+ case BackgroundPixmap:
+ pTile = pWin->background.pixmap;
+ if (sisPatternDimOk (pTile->drawable.width) &&
+ sisPatternDimOk (pTile->drawable.height))
+ {
+ sisFillBoxTiled ((DrawablePtr)pWin,
+ (int)REGION_NUM_RECTS(pRegion),
+ REGION_RECTS(pRegion),
+ pTile,
+ pWin->drawable.x, pWin->drawable.y, GXcopy);
+ return;
+ }
+ break;
+ case BackgroundPixel:
+ sisFillBoxSolid((DrawablePtr)pWin,
+ (int)REGION_NUM_RECTS(pRegion),
+ REGION_RECTS(pRegion),
+ pWin->background.pixel, GXcopy);
+ return;
+ }
+ break;
+ case PW_BORDER:
+ if (pWin->borderIsPixel)
+ {
+ sisFillBoxSolid((DrawablePtr)pWin,
+ (int)REGION_NUM_RECTS(pRegion),
+ REGION_RECTS(pRegion),
+ pWin->border.pixel, GXcopy);
+ return;
+ }
+ else
+ {
+ pTile = pWin->border.pixmap;
+ if (sisPatternDimOk (pTile->drawable.width) &&
+ sisPatternDimOk (pTile->drawable.height))
+ {
+ sisFillBoxTiled ((DrawablePtr)pWin,
+ (int)REGION_NUM_RECTS(pRegion),
+ REGION_RECTS(pRegion),
+ pTile,
+ pWin->drawable.x, pWin->drawable.y, GXcopy);
+ return;
+ }
+ }
+ break;
+ }
+ KdCheckPaintWindow (pWin, pRegion, what);
+}
+
+Bool
+sisDrawInit (ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ sisScreenInfo(pScreenPriv);
+
+ /*
+ * Hook up asynchronous drawing
+ */
+ KdScreenInitAsync (pScreen);
+ /*
+ * Replace various fb screen functions
+ */
+ pScreen->CreateGC = sisCreateGC;
+ pScreen->CopyWindow = sisCopyWindow;
+ pScreen->PaintWindowBackground = sisPaintWindow;
+ pScreen->PaintWindowBorder = sisPaintWindow;
+
+ return TRUE;
+}
+
+void
+sisDrawEnable (ScreenPtr pScreen)
+{
+ SetupSis(pScreen);
+ sisScreenInfo(pScreenPriv);
+ CARD32 cmd;
+ CARD32 base;
+ CARD16 stride;
+
+ base = pScreenPriv->screen->frameBuffer - sisc->frameBuffer;
+ stride = pScreenPriv->screen->byteStride;
+ sis->u.general.dst_base = base;
+ sis->u.general.dst_pitch = stride;
+ sis->u.general.dst_height = pScreenPriv->screen->height;
+ _sisClip (sis, 0, 0,
+ pScreenPriv->screen->width, pScreenPriv->screen->height);
+ _sisSetSolidRect(sis, pScreen->blackPixel, GXcopy, cmd);
+ _sisRect (sis, 0, 0,
+ pScreenPriv->screen->width, pScreenPriv->screen->height,
+ cmd);
+ KdMarkSync (pScreen);
+}
+
+void
+sisDrawSync (ScreenPtr pScreen)
+{
+ SetupSis(pScreen);
+
+ _sisWaitIdleEmpty (sis);
+}
+
+void
+sisDrawDisable (ScreenPtr pScreen)
+{
+}
+
+void
+sisDrawFini (ScreenPtr pScreen)
+{
+}
diff --git a/xc/programs/Xserver/hw/kdrive/sis530/sisdraw.h b/xc/programs/Xserver/hw/kdrive/sis530/sisdraw.h
new file mode 100644
index 000000000..decae0175
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/sis530/sisdraw.h
@@ -0,0 +1,183 @@
+/*
+ * $Id: sisdraw.h,v 1.1 2000/01/06 12:55:54 faith 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/sis530/sisdraw.h,v 1.1 1999/11/19 13:53:59 hohndel Exp $ */
+
+#ifndef _SISDRAW_H_
+#define _SISDRAW_H_
+
+#define SetupSis(s) KdScreenPriv(s); \
+ sisCardInfo(pScreenPriv); \
+ SisPtr sis = sisc->sis
+
+#define SIS_CMD_BITBLT (0)
+#define SIS_CMD_COLOR_EXPAND (1)
+#define SIS_CMD_ENH_COLOR_EXPAND (2)
+#define SIS_CMD_MULTI_SCANLINE (3)
+#define SIS_CMD_LINE (4)
+#define SIS_CMD_TRAPEZOID (5)
+#define SIS_CMD_TRANSPARENT_BITBLT (6)
+
+#define SIS_CMD_SRC_SCREEN (0 << 4)
+#define SIS_CMD_SRC_CPU (1 << 4)
+
+#define SIS_CMD_PAT_FG (0 << 6)
+#define SIS_CMD_PAT_PATTERN (1 << 6)
+#define SIS_CMD_PAT_MONO (2 << 6)
+
+/* 8->15 rop */
+
+#define SIS_CMD_DEC_X (0 << 16)
+#define SIS_CMD_INC_X (1 << 16)
+
+#define SIS_CMD_DEC_Y (0 << 17)
+#define SIS_CMD_INC_Y (1 << 17)
+
+#define SIS_CMD_RECT_CLIP_DISABLE (0 << 18)
+#define SIS_CMD_RECT_CLIP_ENABLE (1 << 18)
+
+#define SIS_CMD_OPAQUE (0 << 20)
+#define SIS_CMD_TRANSPARENT (1 << 20)
+
+#define SIS_CMD_RECT_CLIP_MERGE (0 << 26)
+#define SIS_CMD_RECT_CLIP_DONT_MERGE (1 << 26)
+
+#define SIS_STAT_2D_IDLE (1 << 31)
+#define SIS_STAT_3D_IDLE (1 << 30)
+#define SIS_STAT_EMPTY (1 << 29)
+#define SIS_STAT_CPU_BITBLT (0xf << 24)
+#define SIS_STAT_ENH_COLOR_EXPAND (1 << 23)
+#define SIS_STAT_AVAIL (0x1fff)
+
+extern CARD8 sisPatRop[16];
+extern CARD8 sisBltRop[16];
+
+#define _sisSetSolidRect(sis,pix,alu,cmd) {\
+ (sis)->u.general.pattern_fg = (pix); \
+ (cmd) = (SIS_CMD_BITBLT | \
+ SIS_CMD_SRC_SCREEN | \
+ SIS_CMD_PAT_FG | \
+ (sisPatRop[alu] << 8) | \
+ SIS_CMD_INC_X | \
+ SIS_CMD_INC_Y | \
+ SIS_CMD_RECT_CLIP_DISABLE | \
+ SIS_CMD_OPAQUE | \
+ SIS_CMD_RECT_CLIP_DONT_MERGE); \
+}
+
+#define _sisClip(sis,x1,y1,x2,y2) { \
+ (sis)->u.general.clip_left = (x1); \
+ (sis)->u.general.clip_top = (y1); \
+ (sis)->u.general.clip_right = (x2); \
+ (sis)->u.general.clip_bottom = (y2); \
+}
+
+#define _sisRect(sis,x,y,w,h,cmd) { \
+ (sis)->u.general.dst_x = (x); \
+ (sis)->u.general.dst_y = (y); \
+ (sis)->u.general.rect_width = (w); \
+ (sis)->u.general.rect_height = (h); \
+ (sis)->u.general.command = (cmd); \
+}
+
+#define _sisSetTransparentPlaneBlt(sis, alu, fg, cmd) { \
+ (sis)->u.general.src_fg = (fg); \
+ (cmd) = (SIS_CMD_ENH_COLOR_EXPAND | \
+ SIS_CMD_SRC_CPU | \
+ SIS_CMD_PAT_FG | \
+ (sisBltRop[alu] << 8) | \
+ SIS_CMD_INC_X | \
+ SIS_CMD_INC_Y | \
+ SIS_CMD_RECT_CLIP_DISABLE | \
+ SIS_CMD_TRANSPARENT | \
+ SIS_CMD_RECT_CLIP_DONT_MERGE); \
+}
+
+#define _sisSetOpaquePlaneBlt(sis, alu, fg, bg, cmd) { \
+ (sis)->u.general.src_fg = (fg); \
+ (sis)->u.general.src_bg = (bg); \
+ (cmd) = (SIS_CMD_ENH_COLOR_EXPAND | \
+ SIS_CMD_SRC_CPU | \
+ SIS_CMD_PAT_FG | \
+ (sisBltRop[alu] << 8) | \
+ SIS_CMD_INC_X | \
+ SIS_CMD_INC_Y | \
+ SIS_CMD_RECT_CLIP_DISABLE | \
+ SIS_CMD_OPAQUE | \
+ SIS_CMD_RECT_CLIP_DONT_MERGE); \
+}
+
+#define _sisPlaneBlt(sis,x,y,w,h,cmd) _sisSolidRect(sis,x,y,w,h,cmd)
+
+#define _sisSetBlt(sis,alu,cmd) { \
+ (sis)->u.general.src_base = (sis)->u.general.dst_base; \
+ (sis)->u.general.src_pitch = (sis)->u.general.dst_pitch; \
+ (cmd) = (SIS_CMD_RECT_CLIP_DONT_MERGE |\
+ (sisBltRop[alu] << 8) |\
+ SIS_CMD_PAT_FG |\
+ SIS_CMD_SRC_SCREEN |\
+ SIS_CMD_BITBLT); \
+}
+
+#define _sisBlt(sis,sx,sy,dx,dy,w,h,cmd) { \
+ (sis)->u.general.src_x = (sx); \
+ (sis)->u.general.src_y = (sy); \
+ (sis)->u.general.dst_x = (dx); \
+ (sis)->u.general.dst_y = (dy); \
+ (sis)->u.general.rect_width = (w); \
+ (sis)->u.general.rect_height = (h); \
+ (sis)->u.general.command = (cmd); \
+}
+
+#define SIS_IE (SIS_STAT_2D_IDLE|SIS_STAT_EMPTY)
+
+#define _sisWaitIdleEmpty(sis) \
+ while (((sis)->u.general.status & SIS_IE) != SIS_IE)
+
+/*
+ * Ok, so the Sis530 is broken -- it expects bitmaps to come MSB bit order,
+ * but it's willing to take them in LSB byte order. These macros
+ * flip bits around without flipping bytes. Instead of using a table
+ * and burning memory bandwidth, do them in place with the CPU.
+ */
+
+/* The MIPS compiler automatically places these constants in registers */
+#define SisInvertBits32(v) { \
+ v = ((v & 0x55555555) << 1) | ((v >> 1) & 0x55555555); \
+ v = ((v & 0x33333333) << 2) | ((v >> 2) & 0x33333333); \
+ v = ((v & 0x0f0f0f0f) << 4) | ((v >> 4) & 0x0f0f0f0f); \
+}
+
+#define SisInvertBits16(v) { \
+ v = ((v & 0x5555) << 1) | ((v >> 1) & 0x5555); \
+ v = ((v & 0x3333) << 2) | ((v >> 2) & 0x3333); \
+ v = ((v & 0x0f0f) << 4) | ((v >> 4) & 0x0f0f); \
+}
+
+#define SisInvertBits8(v) { \
+ v = ((v & 0x55) << 1) | ((v >> 1) & 0x55); \
+ v = ((v & 0x33) << 2) | ((v >> 2) & 0x33); \
+ v = ((v & 0x0f) << 4) | ((v >> 4) & 0x0f); \
+}
+
+#endif
diff --git a/xc/programs/Xserver/hw/kdrive/sis530/sisio.c b/xc/programs/Xserver/hw/kdrive/sis530/sisio.c
new file mode 100644
index 000000000..9b31731e6
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/sis530/sisio.c
@@ -0,0 +1,30 @@
+/*
+ * $Id: sisio.c,v 1.1 2000/01/06 12:55:54 faith 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/sis530/sisio.c,v 1.1 1999/11/19 13:54:00 hohndel Exp $ */
+
+#ifdef linux
+#define extern
+#include <asm/io.h>
+#undef extern
+#endif
diff --git a/xc/programs/Xserver/hw/kdrive/sis530/sisstub.c b/xc/programs/Xserver/hw/kdrive/sis530/sisstub.c
new file mode 100644
index 000000000..66a02ec73
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/sis530/sisstub.c
@@ -0,0 +1,53 @@
+/*
+ * $Id: sisstub.c,v 1.1 2000/01/06 12:55:54 faith 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/sis530/sisstub.c,v 1.2 1999/12/30 03:03:15 robin Exp $ */
+
+#include "sis.h"
+
+void
+InitCard (char *name)
+{
+ KdCardAttr attr;
+ if (LinuxFindPci (0x1039, 0x6306, 0, &attr))
+ KdCardInfoAdd (&sisFuncs, &attr, 0);
+}
+
+void
+InitOutput (ScreenInfo *pScreenInfo, int argc, char **argv)
+{
+ KdInitOutput (pScreenInfo, argc, argv);
+}
+
+void
+InitInput (int argc, char **argv)
+{
+ KdInitInput (&Ps2MouseFuncs, &LinuxKeyboardFuncs);
+}
+
+int
+ddxProcessArgument (int argc, char **argv, int i)
+{
+ return KdProcessArgument (argc, argv, i);
+}
diff --git a/xc/programs/Xserver/hw/kdrive/trident/Imakefile b/xc/programs/Xserver/hw/kdrive/trident/Imakefile
new file mode 100644
index 000000000..f6a9f03cb
--- /dev/null
+++ b/xc/programs/Xserver/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/kdrive/trident/Imakefile,v 1.1 1999/11/19 13:54:00 hohndel 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/xc/programs/Xserver/hw/kdrive/trident/trident.c b/xc/programs/Xserver/hw/kdrive/trident/trident.c
new file mode 100644
index 000000000..cfd892e70
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/trident/trident.c
@@ -0,0 +1,287 @@
+/*
+ * $Id: trident.c,v 1.1 2000/01/06 12:55:54 faith 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/trident/trident.c,v 1.2 1999/12/30 03:03:15 robin Exp $ */
+
+#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;
+}
+
+Bool
+tridentInitScreen (ScreenPtr pScreen)
+{
+ return fbdevInitScreen (pScreen);
+}
+
+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 */
+ tridentInitScreen, /* initScreen */
+ 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 */
+ tridentDrawSync, /* syncAccel */
+ tridentDrawDisable, /* disableAccel */
+ tridentDrawFini, /* finiAccel */
+
+ fbdevGetColors, /* getColors */
+ fbdevPutColors, /* putColors */
+};
diff --git a/xc/programs/Xserver/hw/kdrive/trident/trident.h b/xc/programs/Xserver/hw/kdrive/trident/trident.h
new file mode 100644
index 000000000..d02199426
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/trident/trident.h
@@ -0,0 +1,217 @@
+/*
+ * $Id: trident.h,v 1.1 2000/01/06 12:55:54 faith 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/trident/trident.h,v 1.2 1999/12/30 03:03:16 robin Exp $ */
+
+#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
+
+
+#define COP_ALPHA_RESULT_ALPHA 0x00100000
+#define COP_ALPHA_DEST_ALPHA 0x00200000
+#define COP_ALPHA_SOURCE_ALPHA 0x00400000
+#define COP_ALPHA_WRITE_ENABLE 0x00800000
+#define COP_ALPHA_TEST_ENABLE 0x01000000
+#define COP_ALPHA_BLEND_ENABLE 0x02000000
+#define COP_ALPHA_DEST_VALUE 0x04000000
+#define COP_ALPHA_SOURCE_VALUE 0x08000000
+
+ 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
+tridentDrawSync (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/xc/programs/Xserver/hw/kdrive/trident/tridentcurs.c b/xc/programs/Xserver/hw/kdrive/trident/tridentcurs.c
new file mode 100644
index 000000000..28592b9de
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/trident/tridentcurs.c
@@ -0,0 +1,389 @@
+/*
+ * $Id: tridentcurs.c,v 1.1 2000/01/06 12:55:54 faith 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/trident/tridentcurs.c,v 1.2 1999/12/30 03:03:17 robin Exp $ */
+
+#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;
+
+ KdAllocateCursorPixels (pScreen, pCursor,
+ &pCurPriv->source, &pCurPriv->mask);
+ 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/xc/programs/Xserver/hw/kdrive/trident/tridentdraw.c b/xc/programs/Xserver/hw/kdrive/trident/tridentdraw.c
new file mode 100644
index 000000000..df8c62096
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/trident/tridentdraw.c
@@ -0,0 +1,874 @@
+/*
+ * $Id: tridentdraw.c,v 1.1 2000/01/06 12:55:55 faith 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/trident/tridentdraw.c,v 1.2 1999/12/30 03:03:17 robin Exp $ */
+
+#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++;
+ }
+ KdMarkSync(pDrawable->pScreen);
+}
+
+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++;
+ }
+ KdMarkSync(pDstDrawable->pScreen);
+}
+
+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 KdCheckCopyArea (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))
+ {
+ KdCheckFillSpans (pDrawable, pGC, n, ppt, pwidth, fSorted);
+ return;
+ }
+ nTmp = n * miFindMaxBand(fbGetCompositeClip(pGC));
+ pwidthFree = (int *)ALLOCATE_LOCAL(nTmp * sizeof(int));
+ pptFree = (DDXPointRec *)ALLOCATE_LOCAL(nTmp * sizeof(DDXPointRec));
+ if(!pptFree || !pwidthFree)
+ {
+ if (pptFree) DEALLOCATE_LOCAL(pptFree);
+ if (pwidthFree) DEALLOCATE_LOCAL(pwidthFree);
+ return;
+ }
+ n = miClipSpans(fbGetCompositeClip(pGC),
+ ppt, pwidth, n,
+ pptFree, pwidthFree, fSorted);
+ pwidth = pwidthFree;
+ ppt = pptFree;
+ _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 - 1,y,cmd);
+ }
+ }
+ KdMarkSync(pDrawable->pScreen);
+ 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))
+ {
+ KdCheckPolyFillRect (pDrawable, pGC, nrectFill, prectInit);
+ return;
+ }
+ prgnClip = fbGetCompositeClip(pGC);
+ xorg = pDrawable->x;
+ yorg = pDrawable->y;
+
+ if (xorg || yorg)
+ {
+ prect = prectInit;
+ n = nrectFill;
+ while(n--)
+ {
+ prect->x += xorg;
+ prect->y += yorg;
+ prect++;
+ }
+ }
+
+ prect = prectInit;
+
+ numRects = REGION_NUM_RECTS(prgnClip) * nrectFill;
+ if (numRects > NUM_STACK_RECTS)
+ {
+ pboxClippedBase = (BoxPtr)xalloc(numRects * sizeof(BoxRec));
+ if (!pboxClippedBase)
+ return;
+ }
+ else
+ pboxClippedBase = stackRects;
+
+ pboxClipped = pboxClippedBase;
+
+ if (REGION_NUM_RECTS(prgnClip) == 1)
+ {
+ int x1, y1, x2, y2, bx2, by2;
+
+ pextent = REGION_RECTS(prgnClip);
+ x1 = pextent->x1;
+ y1 = pextent->y1;
+ x2 = pextent->x2;
+ y2 = pextent->y2;
+ while (nrectFill--)
+ {
+ if ((pboxClipped->x1 = prect->x) < x1)
+ pboxClipped->x1 = x1;
+
+ if ((pboxClipped->y1 = prect->y) < y1)
+ pboxClipped->y1 = y1;
+
+ bx2 = (int) prect->x + (int) prect->width;
+ if (bx2 > x2)
+ bx2 = x2;
+ pboxClipped->x2 = bx2;
+
+ by2 = (int) prect->y + (int) prect->height;
+ if (by2 > y2)
+ by2 = y2;
+ pboxClipped->y2 = by2;
+
+ prect++;
+ if ((pboxClipped->x1 < pboxClipped->x2) &&
+ (pboxClipped->y1 < pboxClipped->y2))
+ {
+ pboxClipped++;
+ }
+ }
+ }
+ else
+ {
+ int x1, y1, x2, y2, bx2, by2;
+
+ pextent = REGION_EXTENTS(pGC->pScreen, prgnClip);
+ x1 = pextent->x1;
+ y1 = pextent->y1;
+ x2 = pextent->x2;
+ y2 = pextent->y2;
+ while (nrectFill--)
+ {
+ BoxRec box;
+
+ if ((box.x1 = prect->x) < x1)
+ box.x1 = x1;
+
+ if ((box.y1 = prect->y) < y1)
+ box.y1 = y1;
+
+ bx2 = (int) prect->x + (int) prect->width;
+ if (bx2 > x2)
+ bx2 = x2;
+ box.x2 = bx2;
+
+ by2 = (int) prect->y + (int) prect->height;
+ if (by2 > y2)
+ by2 = y2;
+ box.y2 = by2;
+
+ prect++;
+
+ if ((box.x1 >= box.x2) || (box.y1 >= box.y2))
+ continue;
+
+ n = REGION_NUM_RECTS (prgnClip);
+ pbox = REGION_RECTS(prgnClip);
+
+ /* clip the rectangle to each box in the clip region
+ this is logically equivalent to calling Intersect()
+ */
+ while(n--)
+ {
+ pboxClipped->x1 = max(box.x1, pbox->x1);
+ pboxClipped->y1 = max(box.y1, pbox->y1);
+ pboxClipped->x2 = min(box.x2, pbox->x2);
+ pboxClipped->y2 = min(box.y2, pbox->y2);
+ pbox++;
+
+ /* see if clipping left anything */
+ if(pboxClipped->x1 < pboxClipped->x2 &&
+ pboxClipped->y1 < pboxClipped->y2)
+ {
+ pboxClipped++;
+ }
+ }
+ }
+ }
+ if (pboxClipped != pboxClippedBase)
+ {
+ switch (pGC->fillStyle) {
+ case FillSolid:
+ 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);
+ }
+ KdMarkSync(pDrawable->pScreen);
+}
+
+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)
+ {
+ KdCheckImageGlyphBlt(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;
+ }
+
+ KdCheckSync (pDrawable->pScreen);
+
+ 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,
+ KdCheckSetSpans,
+ KdCheckPutImage,
+ tridentCopyArea,
+ KdCheckCopyPlane,
+ KdCheckPolyPoint,
+ KdCheckPolylines,
+ KdCheckPolySegment,
+ miPolyRectangle,
+ KdCheckPolyArc,
+ miFillPolygon,
+ tridentPolyFillRect,
+ KdCheckPolyFillArc,
+ miPolyText8,
+ miPolyText16,
+ miImageText8,
+ miImageText16,
+ tridentImageGlyphBlt,
+ KdCheckPolyGlyphBlt,
+ KdCheckPushPixels,
+#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 *) &kdAsyncPixmapGCOps;
+}
+
+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;
+ }
+ KdCheckPaintWindow (pWin, pRegion, what);
+}
+
+Bool
+tridentDrawInit (ScreenPtr pScreen)
+{
+ /*
+ * Hook up asynchronous drawing
+ */
+ KdScreenInitAsync (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;
+ CARD32 alpha;
+ 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);
+ KdMarkSync (pScreen);
+}
+
+void
+tridentDrawDisable (ScreenPtr pScreen)
+{
+}
+
+void
+tridentDrawFini (ScreenPtr pScreen)
+{
+}
+
+void
+tridentDrawSync (ScreenPtr pScreen)
+{
+ SetupTrident(pScreen);
+
+ _tridentWaitIdleEmpty(cop);
+}
diff --git a/xc/programs/Xserver/hw/kdrive/trident/tridentdraw.h b/xc/programs/Xserver/hw/kdrive/trident/tridentdraw.h
new file mode 100644
index 000000000..f85780f3a
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/trident/tridentdraw.h
@@ -0,0 +1,66 @@
+/*
+ * $Id: tridentdraw.h,v 1.1 2000/01/06 12:55:55 faith 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/trident/tridentdraw.h,v 1.2 1999/12/30 03:03:18 robin Exp $ */
+
+#ifndef _TRIDENTDRAW_H_
+#define _TRIDENTDRAW_H_
+
+#define SetupTrident(s) KdScreenPriv(s); \
+ tridentCardInfo(pScreenPriv); \
+ Cop *cop = tridentc->cop
+
+#define TridentAlpha (COP_MULTI_ALPHA|COP_ALPHA_WRITE_ENABLE)
+
+#define _tridentInit(cop,tridentc) { \
+ if ((cop)->status == 0xffffffff) tridentSetMMIO(tridentc); \
+ (cop)->multi = (tridentc)->cop_depth; \
+ (cop)->multi = (tridentc)->cop_stride; \
+ (cop)->multi = TridentAlpha; \
+} \
+
+#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/xc/programs/Xserver/hw/kdrive/trident/tridentstub.c b/xc/programs/Xserver/hw/kdrive/trident/tridentstub.c
new file mode 100644
index 000000000..b73d5a845
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/trident/tridentstub.c
@@ -0,0 +1,54 @@
+/*
+ * $Id: tridentstub.c,v 1.1 2000/01/06 12:55:55 faith 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/trident/tridentstub.c,v 1.2 1999/12/30 03:03:18 robin Exp $ */
+
+#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);
+}
+
+int
+ddxProcessArgument (int argc, char **argv, int i)
+{
+ return KdProcessArgument (argc, argv, i);
+}
diff --git a/xc/programs/Xserver/hw/kdrive/trio/Imakefile b/xc/programs/Xserver/hw/kdrive/trio/Imakefile
new file mode 100644
index 000000000..5ba216aea
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/trio/Imakefile
@@ -0,0 +1,21 @@
+XCOMM $XConsortium: Imakefile /main/10 1996/12/02 10:20:33 lehors $
+XCOMM $XFree86: xc/programs/Xserver/hw/kdrive/trio/Imakefile,v 1.1 1999/11/19 13:54:02 hohndel Exp $
+#include <Server.tmpl>
+
+SRCS = s3.c s3clock.c s3cmap.c s3curs.c s3draw.c s3gc.c s3stub.c
+
+OBJS = s3.o s3clock.o s3cmap.o s3curs.o s3draw.o s3gc.o s3stub.o
+
+INCLUDES = -I.. -I. -I$(XBUILDINCDIR) -I$(FONTINCSRC) \
+ -I../../../fb -I../../../mi -I../../../include -I../../../os \
+ -I$(EXTINCSRC) -I$(XINCLUDESRC)
+
+DEFINES = -DS3_TRIO
+
+NormalLibraryObjectRule()
+NormalLibraryTarget(trio,$(OBJS))
+DependTarget()
+
+LinkSourceFile(s3draw.h,../savage)
+LinkSourceFile(s3draw.c,../savage)
+LinkSourceFile(s3gc.c,../savage)
diff --git a/xc/programs/Xserver/hw/kdrive/trio/s3.c b/xc/programs/Xserver/hw/kdrive/trio/s3.c
new file mode 100644
index 000000000..d71deac01
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/trio/s3.c
@@ -0,0 +1,1010 @@
+/*
+ * $Id: s3.c,v 1.1 2000/01/06 12:55:55 faith 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/trio/s3.c,v 1.2 1999/12/30 03:03:19 robin Exp $ */
+
+#include "s3.h"
+
+#define REGISTERS_OFFSET (0x1000000)
+#define PACKED_OFFSET (0x8100)
+
+
+CARD8
+_s3ReadIndexRegister (volatile CARD8 *base, CARD8 index)
+{
+ CARD8 ret;
+ *base = index;
+ ret = *(base + 1);
+ DRAW_DEBUG ((DEBUG_CRTC, " 0x%3x 0x%02x -> 0x%02x",
+ ((int) base) & 0xfff, index, ret));
+ return ret;
+}
+
+void
+_s3WriteIndexRegister (volatile CARD8 *base, CARD8 index, CARD8 value)
+{
+ DRAW_DEBUG ((DEBUG_CRTC, " 0x%3x 0x%02x <- 0x%02x",
+ ((int) base) & 0xfff, index, value));
+ *base = index;
+ *(base + 1) = value;
+}
+
+/*
+ * Map the S3 card and detect its configuration. Do not touch the card
+ */
+
+static void
+_s3LoadCrtc (S3Ptr s3, S3Crtc *crtc)
+{
+ crtc->h_total_0_7 = GetCrtc (s3, 0x00);
+ crtc->h_display_end_0_7 = GetCrtc (s3, 0x01);
+ crtc->h_blank_start_0_7 = GetCrtc (s3, 0x02);
+ crtc->_h_blank_end = GetCrtc (s3, 0x03);
+ crtc->h_sync_start_0_7 = GetCrtc (s3, 0x04);
+ crtc->_h_sync_end = GetCrtc (s3, 0x05);
+ crtc->v_total_0_7 = GetCrtc (s3, 0x06);
+ crtc->crtc_overflow = GetCrtc (s3, 0x07);
+ crtc->preset_row_scan = GetCrtc (s3, 0x08);
+ crtc->_max_scan_line = GetCrtc (s3, 0x09);
+
+ crtc->start_address_8_15 = GetCrtc (s3, 0x0c);
+ crtc->start_address_0_7 = GetCrtc (s3, 0x0d);
+
+ crtc->v_retrace_start_0_7 = GetCrtc (s3, 0x10);
+ crtc->_v_retrace_end = GetCrtc (s3, 0x11);
+ crtc->v_display_end_0_7 = GetCrtc (s3, 0x12);
+ crtc->screen_off_0_7 = GetCrtc (s3, 0x13);
+
+ crtc->v_blank_start_0_7 = GetCrtc (s3, 0x15);
+ crtc->v_blank_end_0_7 = GetCrtc (s3, 0x16);
+
+ crtc->line_compare_0_7 = GetCrtc (s3, 0x18);
+
+ crtc->memory_configuration = GetCrtc (s3, 0x31);
+
+ crtc->misc_1 = GetCrtc (s3, 0x3a);
+ crtc->h_start_fifo_fetch_0_7 = GetCrtc (s3, 0x3b);
+
+ crtc->mode_control = GetCrtc (s3, 0x42);
+
+ crtc->hardware_cursor_mode = GetCrtc (s3, 0x45);
+ crtc->cursor_address_8_15 = GetCrtc (s3, 0x4C);
+ crtc->cursor_address_0_7 = GetCrtc (s3, 0x4D);
+
+ crtc->extended_system_control_1 = GetCrtc (s3, 0x50);
+ crtc->extended_system_control_2 = GetCrtc (s3, 0x51);
+
+ crtc->extended_memory_control = GetCrtc (s3, 0x53);
+
+ crtc->extended_ramdac_control = GetCrtc (s3, 0x55);
+
+ crtc->extended_horizontal_overflow = GetCrtc (s3, 0x5d);
+ crtc->extended_vertical_overflow = GetCrtc (s3, 0x5e);
+
+ crtc->l_parm_0_7 = GetCrtc (s3, 0x62);
+
+ crtc->extended_misc_control = GetCrtc (s3, 0x65);
+
+ crtc->extended_misc_control_2 = GetCrtc (s3, 0x67);
+
+ crtc->configuration_3 = GetCrtc (s3, 0x68);
+
+ crtc->extended_system_control_3 = GetCrtc (s3, 0x69);
+
+ crtc->extended_bios_5 = GetCrtc (s3, 0x6d);
+
+ crtc->extended_sequencer_b = GetSrtc (s3, 0x0b);
+ crtc->extended_sequencer_d = GetSrtc (s3, 0x0d);
+ crtc->dclk_value_low = GetSrtc (s3, 0x12);
+ crtc->dclk_value_high = GetSrtc (s3, 0x13);
+ crtc->control_2 = GetSrtc (s3, 0x15);
+ crtc->ramdac_control = GetSrtc (s3, 0x18);
+
+/* combine values */
+
+ switch (crtc_ge_screen_width(crtc)) {
+ case 0:
+ if (crtc->enable_two_page)
+ crtc->ge_screen_pitch = 2048;
+ else
+ crtc->ge_screen_pitch = 1024;
+ break;
+ case 1:
+ crtc->ge_screen_pitch = 640;
+ break;
+ case 2:
+ /* ignore magic 1600x1200x4 mode */
+ crtc->ge_screen_pitch = 800;
+ break;
+ case 3:
+ crtc->ge_screen_pitch = 1280;
+ break;
+ case 4:
+ crtc->ge_screen_pitch = 1152;
+ break;
+ case 5:
+ crtc->ge_screen_pitch = 0; /* reserved */
+ break;
+ case 6:
+ crtc->ge_screen_pitch = 1600;
+ break;
+ case 7:
+ crtc->ge_screen_pitch = 0; /* reserved */
+ break;
+ }
+ switch (crtc->pixel_length) {
+ case 0:
+ crtc->bits_per_pixel = 8;
+ crtc->pixel_width = (crtc_h_display_end(crtc) + 1) * 8;
+ break;
+ case 1:
+ crtc->bits_per_pixel = 16;
+ crtc->pixel_width = (crtc_h_display_end(crtc) + 1) * 4;
+ break;
+ case 3:
+ crtc->bits_per_pixel = 32;
+ crtc->pixel_width = (crtc_h_display_end(crtc) + 1) * 8;
+ break;
+ }
+ crtc->double_pixel_mode = 0;
+ switch (crtc->color_mode) {
+ case 0x0:
+ crtc->depth = 8; break;
+ case 0x1:
+ crtc->depth = 8; crtc->double_pixel_mode = 1; break;
+ case 0x3:
+ crtc->depth = 15; break;
+ case 0x5:
+ crtc->depth = 16; break;
+ case 0x7:
+ crtc->depth = 24; break; /* unused */
+ case 0xd:
+ crtc->depth = 24; break;
+ }
+}
+
+static void
+_s3SetBlank (S3Ptr s3, Bool blank)
+{
+ CARD8 clock_mode;
+
+ DRAW_DEBUG ((DEBUG_S3INIT, "3c4 at 0x%x\n", &s3->crt_vga_3c4));
+ clock_mode = _s3ReadIndexRegister (&s3->crt_vga_3c4, 0x01);
+ if (blank)
+ clock_mode |= 0x20;
+ else
+ clock_mode &= ~0x20;
+ _s3WaitVRetrace (s3);
+ _s3WriteIndexRegister (&s3->crt_vga_3c4, 0x01, clock_mode);
+ DRAW_DEBUG ((DEBUG_S3INIT, "blank is set to 0x%x", clock_mode));
+}
+
+static void
+_s3SetDepth (S3Ptr s3, S3Crtc *crtc)
+{
+ CARD8 save_3c2;
+ _s3SetBlank (s3, TRUE);
+ PutCrtc(s3, 0x38, 0x48);
+ PutCrtc(s3, 0x39, 0xA0);
+ PutCrtc(s3, 0x00, crtc->h_total_0_7);
+ PutCrtc(s3, 0x01, crtc->h_display_end_0_7);
+ PutCrtc(s3, 0x02, crtc->h_blank_start_0_7);
+ PutCrtc(s3, 0x03, crtc->_h_blank_end);
+ PutCrtc(s3, 0x04, crtc->h_sync_start_0_7);
+ PutCrtc(s3, 0x05, crtc->_h_sync_end);
+ PutCrtc(s3, 0x06, crtc->v_total_0_7);
+ PutCrtc(s3, 0x07, crtc->crtc_overflow);
+ PutCrtc(s3, 0x09, crtc->_max_scan_line);
+ PutCrtc(s3, 0x0c, crtc->start_address_8_15);
+ PutCrtc(s3, 0x0d, crtc->start_address_0_7);
+ PutCrtc(s3, 0x10, crtc->v_retrace_start_0_7);
+ PutCrtc(s3, 0x11, crtc->_v_retrace_end);
+ PutCrtc(s3, 0x12, crtc->v_display_end_0_7);
+ PutCrtc(s3, 0x13, crtc->screen_off_0_7);
+ PutCrtc(s3, 0x15, crtc->v_blank_start_0_7);
+ PutCrtc(s3, 0x16, crtc->v_blank_end_0_7);
+ PutCrtc(s3, 0x18, crtc->line_compare_0_7);
+ PutCrtc(s3, 0x31, crtc->memory_configuration);
+ PutCrtc(s3, 0x3a, crtc->misc_1);
+ PutCrtc(s3, 0x3b, crtc->h_start_fifo_fetch_0_7);
+ PutCrtc(s3, 0x42, crtc->mode_control);
+ PutCrtc(s3, 0x45, crtc->hardware_cursor_mode);
+ PutCrtc(s3, 0x4c, crtc->cursor_address_8_15);
+ PutCrtc(s3, 0x4d, crtc->cursor_address_0_7);
+ PutCrtc(s3, 0x50, crtc->extended_system_control_1);
+ PutCrtc(s3, 0x51, crtc->extended_system_control_2);
+ PutCrtc(s3, 0x53, crtc->extended_memory_control);
+ PutCrtc(s3, 0x55, crtc->extended_ramdac_control);
+ PutCrtc(s3, 0x5d, crtc->extended_horizontal_overflow);
+ PutCrtc(s3, 0x5e, crtc->extended_vertical_overflow);
+ PutCrtc(s3, 0x62, crtc->l_parm_0_7);
+ PutCrtc(s3, 0x65, crtc->extended_misc_control);
+ PutCrtc(s3, 0x67, crtc->extended_misc_control_2);
+ PutCrtc(s3, 0x68, crtc->configuration_3);
+ PutCrtc(s3, 0x69, crtc->extended_system_control_3);
+ PutCrtc(s3, 0x6d, crtc->extended_bios_5);
+ PutCrtc(s3, 0x39, 0x00);
+ PutCrtc(s3, 0x38, 0x00);
+ PutSrtc(s3, 0x0b, crtc->extended_sequencer_b);
+ PutSrtc(s3, 0x0d, crtc->extended_sequencer_d);
+ /*
+ * Move new dclk/mclk values into PLL
+ */
+ save_3c2 = s3->crt_vga_3cc;
+ DRAW_DEBUG ((DEBUG_S3INIT, "save_3c2 0x%x", save_3c2));
+ s3->crt_vga_3c2 = save_3c2 | 0x0c;
+
+ PutSrtc(s3, 0x12, crtc->dclk_value_low);
+ PutSrtc(s3, 0x13, crtc->dclk_value_high);
+
+ DRAW_DEBUG ((DEBUG_S3INIT, "Set PLL load enable, frobbing clk_load..."));
+ crtc->dfrq_en = 1;
+ PutSrtc(s3, 0x15, crtc->control_2);
+ PutSrtc(s3, 0x18, crtc->ramdac_control);
+
+ DRAW_DEBUG ((DEBUG_S3INIT, "Clk load frobbed, restoring 3c2 to 0x%x", save_3c2));
+ s3->crt_vga_3c2 = save_3c2;
+
+ DRAW_DEBUG ((DEBUG_S3INIT, "Enabling display"));
+ _s3SetBlank (s3, FALSE);
+}
+
+void
+_s3RestoreCrtc (S3Ptr s3, S3Crtc *crtc)
+{
+ _s3SetDepth (s3, crtc);
+}
+
+s3Reset (S3CardInfo *s3c)
+{
+ S3Ptr s3 = s3c->s3;
+ S3Save *save = &s3c->save;
+ CARD8 *cursor_base;
+
+ LockS3 (s3c);
+
+ _s3UnlockExt (s3);
+
+ _s3RestoreCrtc (s3, &save->crtc);
+
+ /* set foreground */
+ /* Reset cursor color stack pointers */
+ (void) GetCrtc(s3, 0x45);
+ PutCrtc(s3, 0x4a, save->cursor_fg);
+ /* XXX for deeper screens? */
+
+ /* set background */
+ /* Reset cursor color stack pointers */
+ (void) GetCrtc(s3, 0x45);
+ PutCrtc(s3, 0x4b, save->cursor_bg);
+
+ _s3LockExt (s3);
+
+ /* graphics engine state */
+ s3->alt_mix = save->alt_mix;
+ s3->write_mask = save->write_mask;
+ s3->fg = save->fg;
+ s3->bg = save->bg;
+ /* XXX should save and restore real values? */
+ s3->scissors_tl = 0x00000000;
+ s3->scissors_br = 0x0fff0fff;
+
+ _s3WriteIndexRegister (&s3->crt_vga_3c4, 0x01, save->clock_mode);
+ PutCrtc(s3, 0x39, save->lock2);
+ PutCrtc(s3, 0x38, save->lock1);
+
+ UnlockS3 (s3c);
+}
+
+void
+s3Save (S3CardInfo *s3c)
+{
+ S3Ptr s3 = s3c->s3;
+ S3Save *save = &s3c->save;
+ S3Crtc newCrtc;
+ CARD8 t1, t2;
+ CARD8 *cursor_base;
+
+ LockS3 (s3c);
+
+ save->alt_mix = s3->alt_mix;
+ save->write_mask = s3->write_mask;
+ save->fg = s3->fg;
+ save->bg = s3->bg;
+
+ save->lock1 = GetCrtc(s3, 0x38);
+ save->lock2 = GetCrtc(s3, 0x39);
+ save->clock_mode = _s3ReadIndexRegister (&s3->crt_vga_3c4, 0x01);
+
+ _s3UnlockExt (s3);
+ save->cursor_fg = GetCrtc(s3, 0x4a);
+ save->cursor_bg = GetCrtc(s3, 0x4b);
+
+ _s3LoadCrtc (s3, &save->crtc);
+
+ _s3LockExt (s3);
+
+ UnlockS3 (s3c);
+}
+Bool
+s3CardInit (KdCardInfo *card)
+{
+ S3CardInfo *s3c;
+ S3Ptr s3;
+ int size;
+ CARD8 *registers;
+ CARD32 s3Address = card->attr.address[0];
+ CARD8 *temp_buffer;
+
+ DRAW_DEBUG ((DEBUG_S3INIT, "s3CardInit"));
+ s3c = (S3CardInfo *) xalloc (sizeof (S3CardInfo));
+ if (!s3c)
+ {
+ DRAW_DEBUG ((DEBUG_FAILURE, "can't alloc s3 card info"));
+ goto bail0;
+ }
+
+ memset (s3c, '\0', sizeof (S3CardInfo));
+
+ card->driver = s3c;
+
+ fprintf (stderr, "S3 at 0x%x\n", s3Address);
+ registers = KdMapDevice (s3Address + REGISTERS_OFFSET,
+ sizeof (S3) + PACKED_OFFSET);
+ if (!registers)
+ {
+ ErrorF ("Can't map s3 device\n");
+ goto bail2;
+ }
+ s3 = (S3Ptr) (registers + PACKED_OFFSET);
+ s3c->registers = registers;
+ s3c->s3 = s3;
+
+ s3->crt_vga_3c3 = 1; /* wake up part from deep sleep */
+ s3->crt_vga_3c2 = 0x01 | 0x02 | 0x0c;
+
+ s3->crt_vga_3c4 = 0x58;
+ s3->crt_vga_3c5 = 0x10 | 0x3;
+
+ /*
+ * Can't trust S3 register value for frame buffer amount, must compute
+ */
+ temp_buffer = KdMapDevice (s3Address, 4096 * 1024);
+
+ s3c->memory = KdFrameBufferSize (temp_buffer, 4096 * 1024);
+
+ DRAW_DEBUG ((DEBUG_S3INIT, "Detected frame buffer %d", s3c->memory));
+
+ KdUnmapDevice (temp_buffer, 4096 * 1024);
+
+ if (!s3c->memory)
+ {
+ ErrorF ("Can't detect s3 frame buffer\n");
+ goto bail3;
+ }
+
+ s3c->frameBuffer = KdMapDevice (s3Address, s3c->memory);
+ if (!s3c->frameBuffer)
+ {
+ ErrorF ("Can't map s3 frame buffer\n");
+ goto bail3;
+ }
+
+ card->driver = s3c;
+
+ return TRUE;
+bail3:
+ KdUnmapDevice ((void *) s3, sizeof (S3));
+bail2:
+bail1:
+ xfree (s3c);
+bail0:
+ return FALSE;
+}
+
+Bool
+s3ModeSupported (KdScreenInfo *screen,
+ const KdMonitorTiming *t)
+{
+ if (t->horizontal != 1600 &&
+ t->horizontal != 1280 &&
+ t->horizontal != 1152 &&
+ t->horizontal != 800 &&
+ t->horizontal != 640)
+ return FALSE;
+ if (t->clock > S3_MAX_CLOCK * 2)
+ return FALSE;
+}
+
+Bool
+s3ModeUsable (KdScreenInfo *screen)
+{
+ KdCardInfo *card = screen->card;
+ S3CardInfo *s3c = (S3CardInfo *) card->driver;
+ int screen_size;
+ int pixel_width;
+ int byte_width;
+
+ if (screen->depth >= 24)
+ {
+ screen->depth = 24;
+ screen->bitsPerPixel = 32;
+ }
+ else if (screen->depth >= 16)
+ {
+ screen->depth = 16;
+ screen->bitsPerPixel = 16;
+ }
+ else if (screen->depth >= 15)
+ {
+ screen->depth = 15;
+ screen->bitsPerPixel = 16;
+ }
+ else
+ {
+ screen->depth = 8;
+ screen->bitsPerPixel = 8;
+ }
+
+ byte_width = screen->width * (screen->bitsPerPixel >> 3);
+ pixel_width = screen->width;
+ screen->pixelStride = pixel_width;
+ screen->byteStride = byte_width;
+
+ screen_size = byte_width * screen->height;
+
+ return screen_size <= s3c->memory;
+}
+
+Bool
+s3ScreenInit (KdScreenInfo *screen)
+{
+ KdCardInfo *card = screen->card;
+ S3CardInfo *s3c = (S3CardInfo *) card->driver;
+ S3ScreenInfo *s3s;
+ int screen_size;
+ int memory;
+ int requested_memory;
+ int v_total, h_total;
+ int byte_width;
+ int pixel_width;
+ int m, n, r;
+ int i;
+ const KdMonitorTiming *t;
+
+ DRAW_DEBUG ((DEBUG_S3INIT, "s3ScreenInit"));
+ s3s = (S3ScreenInfo *) xalloc (sizeof (S3ScreenInfo));
+ if (!s3s)
+ return FALSE;
+
+ memset (s3s, '\0', sizeof (S3ScreenInfo));
+
+ if (!screen->width || !screen->height)
+ {
+ screen->width = 800;
+ screen->height = 600;
+ screen->rate = 72;
+ }
+ if (!screen->depth)
+ screen->depth = 8;
+
+ DRAW_DEBUG ((DEBUG_S3INIT, "Requested parameters %dx%dx%d",
+ screen->width, screen->height, screen->rate));
+ t = KdFindMode (screen, s3ModeSupported);
+ screen->rate = t->rate;
+ screen->width = t->horizontal;
+ screen->height = t->vertical;
+ s3GetClock (t->clock, &m, &n, &r, 127, 31, 3);
+#if 0
+ fprintf (stderr, "computed %d,%d,%d (%d) provided %d,%d,%d (%d)\n",
+ m, n, r, S3_CLOCK(m,n,r),
+ t->dac_m, t->dac_n, t->dac_r,
+ S3_CLOCK(t->dac_m, t->dac_n, t->dac_r));
+#endif
+ /*
+ * Can only operate in pixel-doubled mode at 8 bits per pixel
+ */
+ if (screen->depth > 8 && S3_CLOCK(m,n,r) > S3_MAX_CLOCK)
+ screen->depth = 8;
+
+ if (!KdTuneMode (screen, s3ModeUsable, s3ModeSupported))
+ {
+ xfree (s3s);
+ return FALSE;
+ }
+
+ memory = s3c->memory - screen_size;
+
+ /*
+ * Stick frame buffer at start of memory
+ */
+ screen->frameBuffer = s3c->frameBuffer;
+
+ /*
+ * Stick cursor at end of memory
+ */
+ if (memory >= 2048)
+ {
+ s3s->cursor_base = s3c->frameBuffer + (s3c->memory - 2048);
+ memory -= 2048;
+ }
+ else
+ s3s->cursor_base = 0;
+
+ /*
+ * Use remaining memory for off-screen storage, but only use
+ * one piece (either right or bottom).
+ */
+ if (memory >= byte_width * S3_TILE_SIZE)
+ {
+ s3s->offscreen = s3c->frameBuffer + screen_size;
+ s3s->offscreen_x = 0;
+ s3s->offscreen_y = screen_size / byte_width;
+ s3s->offscreen_width = pixel_width;
+ s3s->offscreen_height = memory / byte_width;
+ memory -= s3s->offscreen_height * byte_width;
+ }
+ else if (pixel_width - screen->width >= S3_TILE_SIZE)
+ {
+ s3s->offscreen = s3c->frameBuffer + screen->width;
+ s3s->offscreen_x = screen->width;
+ s3s->offscreen_y = 0;
+ s3s->offscreen_width = pixel_width - screen->width;
+ s3s->offscreen_height = screen->height;
+ }
+ else
+ s3s->offscreen = 0;
+
+ DRAW_DEBUG ((DEBUG_S3INIT, "depth %d bits %d", screen->depth, screen->bitsPerPixel));
+
+ DRAW_DEBUG ((DEBUG_S3INIT, "Screen size %dx%d memory %d",
+ screen->width, screen->height, s3c->memory));
+ DRAW_DEBUG ((DEBUG_S3INIT, "frame buffer 0x%x cursor 0x%x offscreen 0x%x",
+ s3c->frameBuffer, s3s->cursor_base, s3s->offscreen));
+ DRAW_DEBUG ((DEBUG_S3INIT, "offscreen %dx%d+%d+%d",
+ s3s->offscreen_width, s3s->offscreen_height,
+ s3s->offscreen_x, s3s->offscreen_y));
+
+ switch (screen->depth) {
+ case 8:
+ screen->visuals = ((1 << StaticGray) |
+ (1 << GrayScale) |
+ (1 << StaticColor) |
+ (1 << PseudoColor) |
+ (1 << TrueColor) |
+ (1 << DirectColor));
+ screen->blueMask = 0x00;
+ screen->greenMask = 0x00;
+ screen->redMask = 0x00;
+ break;
+ case 15:
+ screen->visuals = (1 << TrueColor);
+ screen->blueMask = 0x001f;
+ screen->greenMask = 0x03e0;
+ screen->redMask = 0x7c00;
+ break;
+ case 16:
+ screen->visuals = (1 << TrueColor);
+ screen->blueMask = 0x001f;
+ screen->greenMask = 0x07e0;
+ screen->redMask = 0xf800;
+ break;
+ case 24:
+ screen->visuals = (1 << TrueColor);
+ screen->blueMask = 0x0000ff;
+ screen->greenMask = 0x00ff00;
+ screen->redMask = 0xff0000;
+ break;
+ }
+
+ screen->driver = s3s;
+
+ return TRUE;
+}
+
+void
+s3Preserve (KdCardInfo *card)
+{
+ S3CardInfo *s3c = card->driver;
+
+ s3Save (s3c);
+}
+
+/*
+ * Enable the card for rendering. Manipulate the initial settings
+ * of the card here.
+ */
+void
+s3Enable (ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ KdCardInfo *card = pScreenPriv->card;
+ KdScreenInfo *screen = pScreenPriv->screen;
+ s3CardInfo (pScreenPriv);
+ s3ScreenInfo (pScreenPriv);
+
+ S3Crtc crtcR, *crtc;
+ int hactive, hblank, hfp, hbp;
+ int vactive, vblank, vfp, vbp;
+ int hsize;
+
+ int h_total;
+ int h_display_end;
+ int h_blank_start;
+ int h_blank_end;
+ int h_sync_start;
+ int h_sync_end;
+ int h_screen_off;
+ int h_start_fifo_fetch;
+
+ int v_total;
+ int v_retrace_start;
+ int v_retrace_end;
+ int v_display_end;
+ int v_blank_start;
+ int v_blank_end;
+
+ int h_adjust;
+ int h_sync_extend_;
+ int h_blank_extend_;
+ int i;
+ CARD16 cursor_address;
+ const KdMonitorTiming *t;
+ int m, n, r;
+
+ DRAW_DEBUG ((DEBUG_S3INIT, "s3Enable"));
+
+ DRAW_DEBUG ((DEBUG_S3INIT, "requested bpp %d current %d",
+ pScreenPriv->bitsPerPixel, s3c->save.crtc.bits_per_pixel));
+
+ t = KdFindMode (screen, s3ModeSupported);
+
+ hfp = t->hfp;
+ hbp = t->hbp;
+ hblank = t->hblank;
+ hactive = t->horizontal;
+
+ vfp = t->vfp;
+ vbp = t->vbp;
+ vblank = t->vblank;
+ vactive = t->vertical;
+
+ crtcR = s3c->save.crtc;
+ crtc = &crtcR;
+
+ s3GetClock (t->clock, &m, &n, &r, 127, 31, 3);
+ crtc->dclk_pll_m_trio = m;
+ crtc->dclk_pll_n_trio = n;
+ crtc->dclk_pll_r_trio = r;
+
+ crtc->alt_refresh_count = 0x02;
+ crtc->enable_alt_refresh = 1;
+ crtc->enable_256_or_more = 1;
+
+ DRAW_DEBUG ((DEBUG_S3INIT, "memory_bus_size %d\n", crtc->memory_bus_size));
+ crtc->memory_bus_size = 1;
+
+ crtc->dclk_over_2 = 0;
+ crtc->dclk_invert = 0;
+ crtc->enable_clock_double = 0;
+ crtc->delay_blank = 0;
+ crtc->extended_bios_5 = 0;
+ /*
+ * Compute character lengths for horizontal timing values
+ */
+ switch (screen->bitsPerPixel) {
+ case 8:
+ hactive = screen->width / 8;
+ hblank /= 8;
+ hfp /= 8;
+ hbp /= 8;
+ h_screen_off = hactive;
+ crtc->pixel_length = 0;
+ crtc->color_mode = 0;
+ /*
+ * Set up for double-pixel mode, switch color modes,
+ * divide the dclk and delay h blank by 2 dclks
+ */
+ if (S3_CLOCK(crtc->dclk_pll_m_trio, crtc->dclk_pll_n_trio,
+ crtc->dclk_pll_r_trio) > S3_MAX_CLOCK)
+ {
+ DRAW_DEBUG ((DEBUG_S3INIT, "S3 clock %g > 80MHz, using pixel double mode",
+ S3_CLOCK(crtc->dclk_pll_m_trio, crtc->dclk_pll_n_trio,
+ crtc->dclk_pll_r_trio)));
+ crtc->color_mode = 1;
+ crtc->dclk_over_2 = 1;
+ crtc->enable_clock_double = 1;
+ crtc->delay_blank = 2;
+ crtc->extended_bios_5 = 2;
+ }
+ h_adjust = 1;
+ break;
+ case 16:
+ hactive = screen->width / 4;
+ hblank /= 4;
+ hfp /= 4;
+ hbp /= 4;
+ h_screen_off = hactive;
+ crtc->pixel_length = 1;
+ crtc->extended_bios_5 = 2;
+ if (crtc->depth == 15)
+ crtc->color_mode = 3;
+ else
+ crtc->color_mode = 5;
+ h_adjust = 2;
+ break;
+ case 32:
+ hactive = screen->width / 8;
+ hblank /= 8;
+ hfp /= 8;
+ hbp /= 8;
+ h_screen_off = hactive * 4;
+ crtc->pixel_length = 3;
+ crtc->color_mode = 0xd;
+ h_adjust = 1;
+ break;
+ }
+
+ /*
+ * X server starts frame buffer at top of memory
+ */
+ DRAW_DEBUG ((DEBUG_S3INIT, "Old start address 0x%x\n",
+ crtc_start_address (crtc)));
+ crtc_set_start_address (crtc, 0);
+
+ /*
+ * Compute horizontal register values from timings
+ */
+ h_total = hactive + hblank - 5;
+ h_display_end = hactive - 1;
+ h_blank_start = h_display_end;
+ h_blank_end = h_blank_start + hblank - h_adjust;
+ h_sync_start = hactive + hfp + h_adjust;
+ h_sync_end = h_sync_start + hblank - hbp - hfp;
+ h_start_fifo_fetch = h_total - 5;
+
+ DRAW_DEBUG ((DEBUG_S3INIT, "blank_end 0x%x sync_end 0x%x sync_start 0x%x\n",
+ h_blank_end, h_sync_end, h_sync_start));
+
+ if (h_blank_end - h_blank_start > 0x40)
+ h_blank_extend_ = 1;
+ else
+ h_blank_extend_ = 0;
+
+ if (h_sync_end - h_sync_start > 0x20)
+ h_sync_extend_ = 1;
+ else
+ h_sync_extend_ = 0;
+
+ DRAW_DEBUG ((DEBUG_S3INIT, "blank_end 0x%x sync_end 0x%x extend %d\n",
+ h_blank_end, h_sync_end, h_sync_extend_));
+
+ crtc_set_h_total(crtc, h_total);
+ crtc_set_h_display_end (crtc, h_display_end);
+ crtc_set_h_blank_start (crtc, h_blank_start);
+ crtc_set_h_blank_end (crtc, h_blank_end);
+ crtc_set_h_sync_start (crtc, h_sync_start);
+ crtc_set_h_sync_end (crtc, h_sync_end);
+ crtc_set_screen_off (crtc, h_screen_off);
+ crtc_set_h_start_fifo_fetch (crtc, h_start_fifo_fetch);
+ crtc->h_sync_extend = h_sync_extend_;
+ crtc->h_blank_extend = h_blank_extend_;
+
+
+ v_total = vactive + vblank - 2;
+ v_retrace_start = vactive + vfp - 1;
+ v_retrace_end = v_retrace_start + vblank - vbp - 1;
+ v_display_end = vactive - 1;
+ v_blank_start = vactive - 1;
+ v_blank_end = v_blank_start + vblank - 1;
+
+ crtc_set_v_total(crtc, v_total);
+ crtc_set_v_retrace_start (crtc, v_retrace_start);
+ crtc->v_retrace_end_0_3 = v_retrace_end;
+ crtc_set_v_display_end (crtc, v_display_end);
+ crtc_set_v_blank_start (crtc, v_blank_start);
+ crtc->v_blank_end_0_7 = v_blank_end;
+
+ /*
+ * Set cursor
+ */
+ if (!screen->softCursor)
+ {
+ cursor_address = (s3s->cursor_base - screen->frameBuffer) / 1024;
+
+ crtc->cursor_address_0_7 = cursor_address;
+ crtc->cursor_address_8_15 = cursor_address >> 8;
+ crtc->hardware_cursor_ms_x11 = 0;
+ crtc->hardware_cursor_enable = 1;
+ }
+ else
+ crtc->hardware_cursor_enable = 0;
+
+ /*
+ * Set accelerator
+ */
+ switch (screen->width) {
+ case 640: crtc_set_ge_screen_width(crtc,1); break;
+ case 800: crtc_set_ge_screen_width(crtc,2); break;
+ case 1024: crtc_set_ge_screen_width(crtc,0); break;
+ case 1152: crtc_set_ge_screen_width(crtc,4); break;
+ case 1280: crtc_set_ge_screen_width(crtc,3); break;
+ case 1600: crtc_set_ge_screen_width(crtc,6); break;
+ }
+
+ /*
+ * Set depth values
+ */
+ crtc->bits_per_pixel = screen->bitsPerPixel;
+ crtc->depth = screen->depth;
+
+ crtc->l_parm_0_7 = screen->width / 4; /* Undocumented. */
+
+ crtc->disable_v_retrace_int = 1; /* don't let retrace interrupt */
+
+ DRAW_DEBUG ((DEBUG_S3INIT, "new h total %d display_end %d",
+ crtc_h_total(crtc),
+ crtc_h_display_end(crtc)));
+ DRAW_DEBUG ((DEBUG_S3INIT, " sync_start %d sync_end %d (%d)",
+ crtc_h_sync_start(crtc),
+ crtc_h_sync_end(crtc), h_sync_end));
+
+ DRAW_DEBUG ((DEBUG_S3INIT, " blank_start %d blank_end %d",
+ crtc_h_blank_start(crtc),
+ crtc_h_blank_end(crtc)));
+
+ DRAW_DEBUG ((DEBUG_S3INIT, " screen_off %d start_fifo %d",
+ crtc_screen_off(crtc), crtc_h_start_fifo_fetch(crtc)));
+
+ DRAW_DEBUG ((DEBUG_S3INIT, " active %d blank %d fp %d bp %d",
+ hactive, hblank, hfp, hbp));
+
+ DRAW_DEBUG ((DEBUG_S3INIT, "new v total %d display_end %d",
+ crtc_v_total(crtc),
+ crtc_v_display_end(crtc)));
+ DRAW_DEBUG ((DEBUG_S3INIT, " retrace_start %d retrace_end %d (%d)",
+ crtc_v_retrace_start(crtc),
+ crtc->v_retrace_end,
+ v_retrace_end));
+ DRAW_DEBUG ((DEBUG_S3INIT, " blank_start %d blank_end %d",
+ crtc_v_blank_start(crtc),
+ crtc->v_blank_end_0_7));
+
+ DRAW_DEBUG ((DEBUG_S3INIT, " active %d blank %d fp %d bp %d",
+ vactive, vblank, vfp, vbp));
+
+ /*
+ * Set DPMS to normal
+ */
+ crtc->hsync_control = 0;
+ crtc->vsync_control = 0;
+
+ LockS3 (s3c);
+ _s3SetDepth (s3c->s3, crtc);
+ UnlockS3 (s3c);
+}
+
+void
+s3Disable (ScreenPtr pScreen)
+{
+}
+
+void
+s3Restore (KdCardInfo *card)
+{
+ S3CardInfo *s3c = card->driver;
+
+ s3Reset (s3c);
+}
+
+void
+_s3SetSync (S3CardInfo *s3c, int hsync, int vsync)
+{
+ /* this abuses the macros defined to access the crtc structure */
+ union extended_sequencer_d_u _extended_sequencer_d_u;
+ S3Ptr s3 = s3c->s3;
+
+ extended_sequencer_d = s3c->save.crtc.extended_sequencer_d;
+ hsync_control = hsync;
+ vsync_control = vsync;
+ PutSrtc (s3, 0x0d, extended_sequencer_d);
+}
+
+Bool
+s3DPMS (ScreenPtr pScreen, int mode)
+{
+ KdScreenPriv(pScreen);
+ s3CardInfo(pScreenPriv);
+
+ switch (mode) {
+ case KD_DPMS_NORMAL:
+ _s3SetSync (s3c, 0, 0);
+ _s3SetBlank (s3c->s3, FALSE);
+ break;
+ case KD_DPMS_STANDBY:
+ _s3SetBlank (s3c->s3, TRUE);
+ _s3SetSync (s3c, 1, 0);
+ break;
+ case KD_DPMS_SUSPEND:
+ _s3SetBlank (s3c->s3, TRUE);
+ _s3SetSync (s3c, 0, 1);
+ break;
+ case KD_DPMS_POWERDOWN:
+ _s3SetBlank (s3c->s3, TRUE);
+ _s3SetSync (s3c, 1, 1);
+ break;
+ }
+ return TRUE;
+}
+
+void
+s3ScreenFini (KdScreenInfo *screen)
+{
+ S3ScreenInfo *s3s = (S3ScreenInfo *) screen->driver;
+
+ xfree (s3s);
+ screen->driver = 0;
+}
+
+void
+s3CardFini (KdCardInfo *card)
+{
+ S3CardInfo *s3c = (S3CardInfo *) card->driver;
+
+ KdUnmapDevice (s3c->frameBuffer, s3c->memory);
+ KdUnmapDevice (s3c->registers, sizeof (S3) + PACKED_OFFSET);
+/* DeleteCriticalSection (&s3c->lock); */
+ xfree (s3c);
+ card->driver = 0;
+}
+
+KdCardFuncs s3Funcs = {
+ s3CardInit,
+ s3ScreenInit,
+ 0,
+ s3Preserve,
+ s3Enable,
+ s3DPMS,
+ s3Disable,
+ s3Restore,
+ s3ScreenFini,
+ s3CardFini,
+ s3CursorInit,
+ s3CursorEnable,
+ s3CursorDisable,
+ s3CursorFini,
+ s3RecolorCursor,
+ s3DrawInit,
+ s3DrawEnable,
+ s3DrawSync,
+ s3DrawDisable,
+ s3DrawFini,
+ s3GetColors,
+ s3PutColors,
+};
+
+void
+S3InitCard (KdCardAttr *attr)
+{
+ KdCardInfoAdd (&s3Funcs, attr, 0);
+}
diff --git a/xc/programs/Xserver/hw/kdrive/trio/s3.h b/xc/programs/Xserver/hw/kdrive/trio/s3.h
new file mode 100644
index 000000000..732a970f8
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/trio/s3.h
@@ -0,0 +1,1196 @@
+/*
+ * $Id: s3.h,v 1.1 2000/01/06 12:55:56 faith 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/trio/s3.h,v 1.2 1999/12/30 03:03:19 robin Exp $ */
+
+#ifndef _S3_H_
+#define _S3_H_
+
+#include "kdrive.h"
+
+#define PLATFORM 300
+
+#define DRAW_DEBUG(a)
+
+#define DEBUG_S3INIT (DEBUG_ACCEL)
+#define DEBUG_CRTC (DEBUG_ACCEL+1)
+#define DEBUG_PATTERN (DEBUG_ACCEL+2)
+#define DEBUG_RECT (DEBUG_ACCEL+3)
+#define DEBUG_PAINT_WINDOW (DEBUG_ACCEL+4)
+#define DEBUG_SET (DEBUG_ACCEL+5)
+#define DEBUG_RENDER (DEBUG_ACCEL+6)
+#define DEBUG_REGISTERS (DEBUG_ACCEL+7)
+#define DEBUG_ARCS (DEBUG_ACCEL+8)
+#define DEBUG_TEXT (DEBUG_ACCEL+9)
+#define DEBUG_POLYGON (DEBUG_ACCEL+10)
+#define DEBUG_CLIP (DEBUG_ACCEL+11)
+
+/* VESA Approved Register Definitions */
+
+/*
+ * Linear Addressing 000 0000 - 0ff ffff (16m)
+ * Image data transfer 100 0000 - 100 7fff (32k)
+ * PCI config 100 8000 - 100 8043
+ * Packed enhanced regs 100 8100 - 100 814a
+ * Streams regs 100 8180 - 100 81ff
+ * Current Y pos 100 82e8
+ * CRT VGA 3b? regs 100 83b0 - 100 83bf
+ * CRT VGA 3c? regs 100 83c0 - 100 83cf
+ * CRT VGA 3d? regs 100 83d0 - 100 83df
+ * Subsystem status (42e8h) 100 8504
+ * Advanced function (42e8h) 100 850c
+ * Enhanced regs 100 86e8 - 100 eeea
+ * Local peripheral bus 100 ff00 - 100 ff5c
+ *
+ * We don't care about the image transfer or PCI regs, so
+ * this structure starts at the packed enhanced regs
+ */
+
+typedef volatile CARD32 VOL32;
+typedef volatile CARD16 VOL16;
+typedef volatile CARD8 VOL8;
+
+typedef volatile struct _s3 {
+ VOL32 alt_curxy; /* 8100 */
+ VOL32 _pad0; /* 8104 */
+ VOL32 alt_step; /* 8108 */
+ VOL32 _pad1; /* 810c */
+ VOL32 err_term; /* 8110 */
+ VOL32 _pad2; /* 8114 */
+ VOL32 cmd_gp_stat; /* 8118 */
+ VOL32 short_stroke; /* 811c */
+ VOL32 bg; /* 8120 */
+ VOL32 fg; /* 8124 */
+ VOL32 write_mask; /* 8128 */
+ VOL32 read_mask; /* 812c */
+ VOL32 color_cmp; /* 8130 */
+ VOL32 alt_mix; /* 8134 */
+ VOL32 scissors_tl; /* 8138 */
+ VOL32 scissors_br; /* 813c */
+ VOL32 pix_cntl_mult_misc2; /* 8140 */
+ VOL32 mult_misc_read_sel; /* 8144 */
+ VOL32 alt_pcnt; /* 8148 min_axis_pcnt, maj_axis_pcnt */
+ VOL8 _pad3[0x19c]; /* 814c */
+ VOL16 cur_y; /* 82e8 */
+ VOL8 _pad4[0xc6]; /* 82ea */
+
+ VOL8 crt_vga_3b0; /* 83b0 */
+ VOL8 crt_vga_3b1; /* 83b1 */
+ VOL8 crt_vga_3b2; /* 83b2 */
+ VOL8 crt_vga_3b3; /* 83b3 */
+ VOL8 crt_vga_3b4; /* 83b4 */
+ VOL8 crt_vga_3b5; /* 83b5 */
+ VOL8 crt_vga_3b6; /* 83b6 */
+ VOL8 crt_vga_3b7; /* 83b7 */
+ VOL8 crt_vga_3b8; /* 83b8 */
+ VOL8 crt_vga_3b9; /* 83b9 */
+ VOL8 crt_vga_3ba; /* 83ba */
+ VOL8 crt_vga_3bb; /* 83bb */
+ VOL8 crt_vga_3bc; /* 83bc */
+ VOL8 crt_vga_3bd; /* 83bd */
+ VOL8 crt_vga_3be; /* 83be */
+ VOL8 crt_vga_3bf; /* 83bf */
+
+ VOL8 crt_vga_3c0; /* 83c0 */
+ VOL8 crt_vga_3c1; /* 83c1 */
+ VOL8 crt_vga_3c2; /* 83c2 */
+ VOL8 crt_vga_3c3; /* 83c3 */
+ VOL8 crt_vga_3c4; /* 83c4 */
+ VOL8 crt_vga_3c5; /* 83c5 */
+ VOL8 crt_vga_dac_ad_mk; /* 83c6 */
+ VOL8 crt_vga_dac_rd_ad; /* 83c7 */
+ VOL8 crt_vga_dac_wt_ad; /* 83c8 */
+ VOL8 crt_vga_dac_data; /* 83c9 */
+ VOL8 crt_vga_3ca; /* 83ca */
+ VOL8 crt_vga_3cb; /* 83cb */
+ VOL8 crt_vga_3cc; /* 83cc */
+ VOL8 crt_vga_3cd; /* 83cd */
+ VOL8 crt_vga_3ce; /* 83ce */
+ VOL8 crt_vga_3cf; /* 83cf */
+
+ VOL8 crt_vga_3d0; /* 83d0 */
+ VOL8 crt_vga_3d1; /* 83d1 */
+ VOL8 crt_vga_3d2; /* 83d2 */
+ VOL8 crt_vga_3d3; /* 83d3 */
+ VOL8 crt_vga_3d4; /* 83d4 */
+ VOL8 crt_vga_3d5; /* 83d5 */
+ VOL8 crt_vga_3d6; /* 83d6 */
+ VOL8 crt_vga_3d7; /* 83d7 */
+ VOL8 crt_vga_3d8; /* 83d8 */
+ VOL8 crt_vga_3d9; /* 83d9 */
+ VOL8 crt_vga_status_1; /* 83da */
+ VOL8 crt_vga_3db; /* 83db */
+ VOL8 crt_vga_3dc; /* 83dc */
+ VOL8 crt_vga_3dd; /* 83dd */
+ VOL8 crt_vga_3de; /* 83de */
+ VOL8 crt_vga_3df; /* 83df */
+
+ VOL8 _pad5[0x124]; /* 83e0 */
+ VOL16 subsys_status; /* 8504 */
+ VOL8 _pad6[0x6]; /* 8506 */
+ VOL16 adv_control; /* 850c */
+ VOL8 _pad7[0x1da]; /* 850e */
+ VOL16 cur_x; /* 86e8 */
+ VOL8 _pad8[0x3fe]; /* 86ea */
+ VOL16 desty_axstp; /* 8ae8 */
+ VOL8 _pad9[0x3fe]; /* 8aea */
+ VOL16 destx_diastp; /* 8ee8 */
+ VOL8 _pad10[0x3fe]; /* 8eea */
+ VOL16 enh_err_term; /* 92e8 */
+ VOL8 _pad11[0x3fe]; /* 92ea */
+ VOL16 maj_axis_pcnt; /* 96e8 */
+ VOL8 _pad12[0x3fe]; /* 96ea */
+ VOL16 enh_cmd_gp_stat; /* 9ae8 */
+ VOL8 _pad13[0x3fe]; /* 9aea */
+ VOL16 enh_short_stroke; /* 9ee8 */
+ VOL8 _pad14[0x3fe]; /* 9eea */
+ VOL16 enh_bg; /* a2e8 */
+ VOL8 _pad15[0x3fe]; /* a2ea */
+ VOL16 enh_fg; /* a6e8 */
+ VOL8 _pad16[0x3fe]; /* a6ea */
+ VOL16 enh_wrt_mask; /* aae8 */
+ VOL8 _pad17[0x3fe]; /* aaea */
+ VOL16 enh_rd_mask; /* aee8 */
+ VOL8 _pad18[0x3fe]; /* aeea */
+ VOL16 enh_color_cmp; /* b2e8 */
+ VOL8 _pad19[0x3fe]; /* b2ea */
+ VOL16 enh_bg_mix; /* b6e8 */
+ VOL8 _pad20[0x3fe]; /* b6ea */
+ VOL16 enh_fg_mix; /* bae8 */
+ VOL8 _pad21[0x3fe]; /* baea */
+ VOL16 enh_rd_reg_dt; /* bee8 */
+ VOL8 _pad22[0x23fe]; /* beea */
+ VOL32 pix_trans; /* e2e8 */
+} S3, *S3Ptr;
+
+#define VGA_STATUS_1_DTM 0x01
+#define VGA_STATUS_1_VSY 0x08
+
+#define DAC_MASK 0x03c6
+#define DAC_R_INDEX 0x03c7
+#define DAC_W_INDEX 0x03c8
+#define DAC_DATA 0x03c9
+#define DISP_STAT 0x02e8
+#define H_TOTAL 0x02e8
+#define H_DISP 0x06e8
+#define H_SYNC_STRT 0x0ae8
+#define H_SYNC_WID 0x0ee8
+#define V_TOTAL 0x12e8
+#define V_DISP 0x16e8
+#define V_SYNC_STRT 0x1ae8
+#define V_SYNC_WID 0x1ee8
+#define DISP_CNTL 0x22e8
+#define ADVFUNC_CNTL 0x4ae8
+#define SUBSYS_STAT 0x42e8
+#define SUBSYS_CNTL 0x42e8
+#define ROM_PAGE_SEL 0x46e8
+#define CUR_Y 0x82e8
+#define CUR_X 0x86e8
+#define DESTY_AXSTP 0x8ae8
+#define DESTX_DIASTP 0x8ee8
+#define ERR_TERM 0x92e8
+#define MAJ_AXIS_PCNT 0x96e8
+#define GP_STAT 0x9ae8
+#define CMD 0x9ae8
+#define SHORT_STROKE 0x9ee8
+#define BKGD_COLOR 0xa2e8
+#define FRGD_COLOR 0xa6e8
+#define WRT_MASK 0xaae8
+#define RD_MASK 0xaee8
+#define COLOR_CMP 0xb2e8
+#define BKGD_MIX 0xb6e8
+#define FRGD_MIX 0xbae8
+#define MULTIFUNC_CNTL 0xbee8
+#define MIN_AXIS_PCNT 0x0000
+#define SCISSORS_T 0x1000
+#define SCISSORS_L 0x2000
+#define SCISSORS_B 0x3000
+#define SCISSORS_R 0x4000
+#define MEM_CNTL 0x5000
+#define PATTERN_L 0x8000
+#define PATTERN_H 0x9000
+#define PIX_CNTL 0xa000
+#define CONTROL_MISC2 0xd000
+#define PIX_TRANS 0xe2e8
+
+/* Advanced Function Control Regsiter */
+#define CLKSEL 0x0004
+#define DISABPASSTHRU 0x0001
+
+/* Graphics Processor Status Register */
+
+#define GPNSLOT 13
+
+#define GPBUSY_1 0x0080
+#define GPBUSY_2 0x0040
+#define GPBUSY_3 0x0020
+#define GPBUSY_4 0x0010
+#define GPBUSY_5 0x0008
+#define GPBUSY_6 0x0004
+#define GPBUSY_7 0x0002
+#define GPBUSY_8 0x0001
+#define GPBUSY_9 0x8000
+#define GPBUSY_10 0x4000
+#define GPBUSY_11 0x2000
+#define GPBUSY_12 0x1000
+#define GPBUSY_13 0x0800
+
+#define GPEMPTY 0x0400
+#define GPBUSY 0x0200
+#define DATDRDY 0x0100
+
+/* Command Register */
+#define CMD_NOP 0x0000
+#define CMD_LINE 0x2000
+#define CMD_RECT 0x4000
+#define CMD_RECTV1 0x6000
+#define CMD_RECTV2 0x8000
+#define CMD_LINEAF 0xa000
+#define CMD_BITBLT 0xc000
+#define CMD_PATBLT 0xe000
+#define CMD_OP_MSK 0xe000
+#define BYTSEQ 0x1000
+#define _32BITNOPAD 0x0600
+#define _32BIT 0x0400
+#define _16BIT 0x0200
+#define _8BIT 0x0000
+#define PCDATA 0x0100
+#define INC_Y 0x0080
+#define YMAJAXIS 0x0040
+#define INC_X 0x0020
+#define DRAW 0x0010
+#define LINETYPE 0x0008
+#define LASTPIX 0x0004 /* Draw last pixel in line */
+#define PLANAR 0x0002
+#define WRTDATA 0x0001
+
+/* Background Mix Register */
+#define BSS_BKGDCOL 0x0000
+#define BSS_FRGDCOL 0x0020
+#define BSS_PCDATA 0x0040
+#define BSS_BITBLT 0x0060
+
+/* Foreground Mix Register */
+#define FSS_BKGDCOL 0x0000
+#define FSS_FRGDCOL 0x0020
+#define FSS_PCDATA 0x0040
+#define FSS_BITBLT 0x0060
+
+/* The Mixes */
+#define MIX_MASK 0x001f
+
+#define MIX_NOT_DST 0x0000
+#define MIX_0 0x0001
+#define MIX_1 0x0002
+#define MIX_DST 0x0003
+#define MIX_NOT_SRC 0x0004
+#define MIX_XOR 0x0005
+#define MIX_XNOR 0x0006
+#define MIX_SRC 0x0007
+#define MIX_NAND 0x0008
+#define MIX_NOT_SRC_OR_DST 0x0009
+#define MIX_SRC_OR_NOT_DST 0x000a
+#define MIX_OR 0x000b
+#define MIX_AND 0x000c
+#define MIX_SRC_AND_NOT_DST 0x000d
+#define MIX_NOT_SRC_AND_DST 0x000e
+#define MIX_NOR 0x000f
+
+#define MIX_MIN 0x0010
+#define MIX_DST_MINUS_SRC 0x0011
+#define MIX_SRC_MINUS_DST 0x0012
+#define MIX_PLUS 0x0013
+#define MIX_MAX 0x0014
+#define MIX_HALF__DST_MINUS_SRC 0x0015
+#define MIX_HALF__SRC_MINUS_DST 0x0016
+#define MIX_AVERAGE 0x0017
+#define MIX_DST_MINUS_SRC_SAT 0x0018
+#define MIX_SRC_MINUS_DST_SAT 0x001a
+#define MIX_HALF__DST_MINUS_SRC_SAT 0x001c
+#define MIX_HALF__SRC_MINUS_DST_SAT 0x001e
+#define MIX_AVERAGE_SAT 0x001f
+
+/* Pixel Control Register */
+#define MIXSEL_FRGDMIX 0x0000
+#define MIXSEL_PATT 0x0040
+#define MIXSEL_EXPPC 0x0080
+#define MIXSEL_EXPBLT 0x00c0
+#define COLCMPOP_F 0x0000
+#define COLCMPOP_T 0x0008
+#define COLCMPOP_GE 0x0010
+#define COLCMPOP_LT 0x0018
+#define COLCMPOP_NE 0x0020
+#define COLCMPOP_EQ 0x0028
+#define COLCMPOP_LE 0x0030
+#define COLCMPOP_GT 0x0038
+#define PLANEMODE 0x0004
+
+#define FIFO_SLOTS 13
+
+#define GPSLOT(n) (1 << ((n) > 8 ? (15 - ((n) - 9)) : (8 - (n))))
+
+/* Wait for n slots to become available */
+#if 0
+#define _s3WaitSlots(s3,n) { \
+ DRAW_DEBUG ((DEBUG_CRTC, "_s3WaitSlots 0x%x %d", (s3)->cmd_gp_stat, n)); \
+ while (((s3)->cmd_gp_stat & GPSLOT(n)) != 0); \
+ DRAW_DEBUG ((DEBUG_CRTC, " s3 0x%x %d slots ready", (s3)->cmd_gp_stat, n)); \
+}
+#else
+/* let PCI retries solve this problem */
+#define _s3WaitSlots(s3,n)
+#endif
+
+/* Wait until queue is empty */
+#define _s3WaitEmpty(s3) { \
+ DRAW_DEBUG ((DEBUG_CRTC, "_s3WaitEmpty 0x%x", (s3)->cmd_gp_stat)); \
+ while (!((s3)->cmd_gp_stat & GPEMPTY)) ; \
+ DRAW_DEBUG ((DEBUG_CRTC, " s3 empty")); \
+}
+
+/* Wait until GP is idle and queue is empty */
+#define _s3WaitIdleEmpty(s3) { \
+ DRAW_DEBUG ((DEBUG_CRTC, "_s3WaitIdleEmpty 0x%x", (s3)->cmd_gp_stat)); \
+ while (((s3)->cmd_gp_stat & (GPBUSY|GPEMPTY)) != GPEMPTY) ; \
+ DRAW_DEBUG ((DEBUG_CRTC, " s3 idle empty")); \
+}
+
+/* Wait until GP is idle */
+#define _s3WaitIdle(s3) { \
+ DRAW_DEBUG ((DEBUG_CRTC, "_s3WaitIdle 0x%x", (s3)->cmd_gp_stat)); \
+ while ((s3)->cmd_gp_stat & GPBUSY) ; \
+ DRAW_DEBUG ((DEBUG_CRTC, " s3 idle")); \
+}
+
+typedef struct _s3Cursor {
+ int width, height;
+ int xhot, yhot;
+ Bool has_cursor;
+ CursorPtr pCursor;
+ Pixel source, mask;
+} S3Cursor;
+
+typedef struct _s3PatternCache {
+ int id;
+ int x, y;
+} S3PatternCache;
+
+typedef struct _s3Patterns {
+ S3PatternCache *cache;
+ int ncache;
+ int last_used;
+ int last_id;
+} S3Patterns;
+
+typedef struct _crtc {
+ CARD8 h_total_0_7; /* CR0 */
+ CARD8 h_display_end_0_7; /* CR1 */
+ CARD8 h_blank_start_0_7; /* CR2 */
+ union {
+ struct {
+ CARD8 _h_blank_end_0_4 : 5;
+ CARD8 _display_skew : 2;
+ CARD8 : 1;
+ } _h_blank_end_s;
+ CARD8 __h_blank_end; /* CR3 */
+ } _h_blank_end_u;
+#define h_blank_end_0_4 _h_blank_end_u._h_blank_end_s._h_blank_end_0_4
+#define display_skew _h_blank_end_u._h_blank_end_s._display_skew
+#define _h_blank_end _h_blank_end_u.__h_blank_end
+
+ CARD8 h_sync_start_0_7; /* CR4 */
+
+ union {
+ struct {
+ CARD8 _h_sync_end_0_4 : 5;
+ CARD8 _horizontal_skew : 2;
+ CARD8 _h_blank_end_5 : 1;
+ } _h_sync_end_s;
+ CARD8 __h_sync_end; /* CR5 */
+ } _h_sync_end_u;
+
+#define h_sync_end_0_4 _h_sync_end_u._h_sync_end_s._h_sync_end_0_4
+#define horizontal_skew _h_sync_end_u._h_sync_end_s._horizontal_skew
+#define h_blank_end_5 _h_sync_end_u._h_sync_end_s._h_blank_end_5
+#define _h_sync_end _h_sync_end_u.__h_sync_end
+
+ CARD8 v_total_0_7; /* CR6 */
+
+ union {
+ struct {
+ CARD8 _v_total_8 : 1;
+ CARD8 _v_display_end_8 : 1;
+ CARD8 _v_retrace_start_8 : 1;
+ CARD8 _v_blank_start_8 : 1;
+ CARD8 _line_compare_8 : 1;
+ CARD8 _v_total_9 : 1;
+ CARD8 _v_display_end_9 : 1;
+ CARD8 _v_retrace_start_9 : 1;
+ } _crtc_overflow_s;
+ CARD8 _crtc_overflow; /* CR7 */
+ } _crtc_overflow_u;
+
+#define v_total_8 _crtc_overflow_u._crtc_overflow_s._v_total_8
+#define v_display_end_8 _crtc_overflow_u._crtc_overflow_s._v_display_end_8
+#define v_retrace_start_8 _crtc_overflow_u._crtc_overflow_s._v_retrace_start_8
+#define v_blank_start_8 _crtc_overflow_u._crtc_overflow_s._v_blank_start_8
+#define line_compare_8 _crtc_overflow_u._crtc_overflow_s._line_compare_8
+#define v_total_9 _crtc_overflow_u._crtc_overflow_s._v_total_9
+#define v_display_end_9 _crtc_overflow_u._crtc_overflow_s._v_display_end_9
+#define v_retrace_start_9 _crtc_overflow_u._crtc_overflow_s._v_retrace_start_9
+#define crtc_overflow _crtc_overflow_u._crtc_overflow
+
+ CARD8 preset_row_scan; /* CR8 (unused) */
+
+ union {
+ struct {
+ CARD8 _max_scan_line : 5;
+ CARD8 _v_blank_start_9 : 1;
+ CARD8 _line_compare_9 : 1;
+ CARD8 _double_scan : 1;
+ } _max_scan_line_s;
+ CARD8 __max_scan_line; /* CR9 */
+ } _max_scan_line_u;
+
+#define max_scan_line _max_scan_line_u._max_scan_line_s._max_scan_line
+#define v_blank_start_9 _max_scan_line_u._max_scan_line_s._v_blank_start_9
+#define line_compare_9 _max_scan_line_u._max_scan_line_s._line_compare_9
+#define double_scan _max_scan_line_u._max_scan_line_s._double_scan
+#define _max_scan_line _max_scan_line_u.__max_scan_line
+
+ CARD8 cursor_start;
+ CARD8 cursor_end;
+
+ CARD8 start_address_8_15; /* CRC */
+ CARD8 start_address_0_7; /* CRD */
+
+ CARD8 cursor_loc_high;
+ CARD8 cursor_loc_low;
+
+ CARD8 v_retrace_start_0_7; /* CR10 */
+ union {
+ struct {
+ CARD8 _v_retrace_end_0_3 : 4;
+ CARD8 _clear_v_retrace_int : 1;
+ CARD8 _disable_v_retrace_int : 1;
+ CARD8 _refresh_cycle_select : 1;
+ CARD8 _lock_crtc : 1;
+ } _v_retrace_end_s;
+ CARD8 __v_retrace_end; /* CR11 */
+ } _v_retrace_end_u;
+
+#define v_retrace_end_0_3 _v_retrace_end_u._v_retrace_end_s._v_retrace_end_0_3
+#define clear_v_retrace_int _v_retrace_end_u._v_retrace_end_s._clear_v_retrace_int
+#define disable_v_retrace_int _v_retrace_end_u._v_retrace_end_s._disable_v_retrace_int
+#define refresh_cycle_select _v_retrace_end_u._v_retrace_end_s._refresh_cycle_select
+#define lock_crtc _v_retrace_end_u._v_retrace_end_s._lock_crtc
+#define _v_retrace_end _v_retrace_end_u.__v_retrace_end
+
+ CARD8 v_display_end_0_7; /* CR12 */
+
+ CARD8 screen_off_0_7; /* CR13 */
+
+ union {
+ struct {
+ CARD8 _underline_location : 5;
+ CARD8 _count_by_four : 1;
+ CARD8 _doubleword_mode : 1;
+ CARD8 : 1;
+ } _underline_location_s;
+ CARD8 __underline_location; /* CR14 (unused) */
+ } _underline_location_u;
+
+#define underline_location _underline_location_u._underline_location_s._underline_location
+#define count_by_four _underline_location_u._underline_location_s._count_by_four
+#define doubleword_mode _underline_location_u._underline_location_s._doubleword_mode
+#define _underline_location _underline_location_u.__underline_location
+
+ CARD8 v_blank_start_0_7; /* CR15 */
+ CARD8 v_blank_end_0_7; /* CR16 */
+
+ union {
+ struct {
+ CARD8 _two_bk_cga : 1;
+ CARD8 _four_bk_cga : 1;
+ CARD8 _v_total_double : 1;
+ CARD8 _word_mode : 1;
+ CARD8 : 1;
+ CARD8 _address_wrap : 1;
+ CARD8 _byte_mode : 1;
+ CARD8 _hardware_reset : 1;
+ } _crtc_mode_s;
+ CARD8 _crtc_mode; /* CR17 (unused) */
+ } _crtc_mode_u;
+
+ CARD8 line_compare_0_7; /* CR18 (unused) */
+
+ union {
+ struct {
+ CARD8 _enable_base_offset : 1;
+ CARD8 _enable_two_page : 1;
+ CARD8 _enable_vga_16_bit : 1;
+ CARD8 _enhanced_mode_mapping : 1;
+ CARD8 _old_display_start : 2;
+ CARD8 _enable_high_speed_text : 1;
+ CARD8 : 1;
+ } _memory_configuration_s;
+ CARD8 _memory_configuration; /* CR31 (unused) */
+ } _memory_configuration_u;
+
+#define memory_configuration _memory_configuration_u._memory_configuration
+#define enable_base_offset _memory_configuration_u._memory_configuration_s._enable_base_offset
+#define enable_two_page _memory_configuration_u._memory_configuration_s._enable_two_page
+#define enable_vga_16_bit _memory_configuration_u._memory_configuration_s._enable_vga_16_bit
+#define enhanved_mode_mapping _memory_configuration_u._memory_configuration_s._enhanced_mode_mapping
+#define old_display_start _memory_configuration_u._memory_configuration_s._old_display_start
+#define enable_high_speed_text _memory_configuration_u._memory_configuration_s._enable_high_speed_text
+
+ union {
+ struct {
+ CARD8 _alt_refresh_count : 2;
+ CARD8 _enable_alt_refresh : 1;
+ CARD8 _enable_top_memory : 1;
+ CARD8 _enable_256_or_more : 1;
+ CARD8 _high_speed_text : 1;
+ CARD8 : 1;
+ CARD8 _pci_burst_disabled : 1;
+ } _misc_1_s;
+ CARD8 _misc_1; /* CR3A */
+ } _misc_1_u;
+#define misc_1 _misc_1_u._misc_1
+#define alt_refresh_count _misc_1_u._misc_1_s._alt_refresh_count
+#define enable_alt_refresh _misc_1_u._misc_1_s._enable_alt_refresh
+#define enable_top_memory _misc_1_u._misc_1_s._enable_top_memory
+#define enable_256_or_more _misc_1_u._misc_1_s._enable_256_or_more
+#define high_speed_text _misc_1_u._misc_1_s._high_speed_text
+#define pci_burst_disabled _misc_1_u._misc_1_s._pci_burst_disabled
+
+ CARD8 h_start_fifo_fetch_0_7; /* CR3B */
+
+ union {
+ struct {
+ CARD8 : 5;
+ CARD8 interlace : 1;
+ CARD8 : 2;
+ } _mode_control_s;
+ CARD8 _mode_control; /* CR42 */
+ } _mode_control_u;
+
+#define mode_control _mode_control_u._mode_control
+
+ union {
+ struct {
+ CARD8 : 2;
+ CARD8 _old_screen_off_8 : 1;
+ CARD8 : 4;
+ CARD8 h_counter_double_mode : 1;
+ } _extended_mode_s;
+ CARD8 _extended_mode; /* CR43 (unused) */
+ } _extended_mode_u;
+
+#define extended_mode _extended_mode_u._extended_mode
+#define old_screen_off_8 _extended_mode_u._extended_mode_s._old_screen_off_8
+
+ union {
+ struct {
+ CARD8 _hardware_cursor_enable : 1;
+ CARD8 : 3;
+ CARD8 _hardware_cursor_right : 1;
+ CARD8 : 3;
+ } _hardware_cursor_mode_s;
+ CARD8 _hardware_cursor_mode; /* CR45 */
+ } _hardware_cursor_mode_u;
+
+#define hardware_cursor_mode _hardware_cursor_mode_u._hardware_cursor_mode
+#define hardware_cursor_enable _hardware_cursor_mode_u._hardware_cursor_mode_s._hardware_cursor_enable
+
+ CARD8 cursor_address_8_15; /* CR4C */
+ CARD8 cursor_address_0_7; /* CR4D */
+
+ union {
+ struct {
+ CARD8 _ge_screen_width_2 : 1;
+ CARD8 : 3;
+ CARD8 _pixel_length : 2;
+ CARD8 _ge_screen_width_0_1 : 2;
+ } _extended_system_control_1_s;
+ CARD8 _extended_system_control_1; /* CR50 */
+ } _extended_system_control_1_u;
+#define ge_screen_width_2 _extended_system_control_1_u._extended_system_control_1_s._ge_screen_width_2
+#define pixel_length _extended_system_control_1_u._extended_system_control_1_s._pixel_length
+#define ge_screen_width_0_1 _extended_system_control_1_u._extended_system_control_1_s._ge_screen_width_0_1
+#define extended_system_control_1 _extended_system_control_1_u._extended_system_control_1
+
+ union {
+ struct {
+ CARD8 : 4;
+ CARD8 _screen_off_8_9 : 2;
+ CARD8 : 2;
+ } _extended_system_control_2_s;
+ CARD8 _extended_system_control_2; /* CR51 */
+ } _extended_system_control_2_u;
+#define extended_system_control_2 _extended_system_control_2_u._extended_system_control_2
+#define screen_off_8_9 _extended_system_control_2_u._extended_system_control_2_s._screen_off_8_9
+
+ union {
+ struct {
+ CARD8 : 1;
+ CARD8 big_endian_linear : 2;
+ CARD8 mmio_select : 2;
+ CARD8 mmio_window : 1;
+ CARD8 swap_nibbles : 1;
+ CARD8 : 1;
+ } _extended_memory_control_s;
+ CARD8 _extended_memory_control; /* CR53 */
+ } _extended_memory_control_u;
+#define extended_memory_control _extended_memory_control_u._extended_memory_control
+
+ union {
+ struct {
+ CARD8 : 2;
+ CARD8 _enable_gir : 1;
+ CARD8 : 1;
+ CARD8 _hardware_cursor_ms_x11 : 1;
+ CARD8 : 2;
+ CARD8 _tri_state_off_vclk : 1;
+ } _extended_ramdac_control_s;
+ CARD8 _extended_ramdac_control; /* CR55 */
+ } _extended_ramdac_control_u;
+#define extended_ramdac_control _extended_ramdac_control_u._extended_ramdac_control
+#define hardware_cursor_ms_x11 _extended_ramdac_control_u._extended_ramdac_control_s._hardware_cursor_ms_x11
+
+
+ union {
+ struct {
+ CARD8 _h_total_8 : 1;
+ CARD8 _h_display_end_8 : 1;
+ CARD8 _h_blank_start_8 : 1;
+ CARD8 _h_blank_extend : 1; /* extend h_blank by 64 */
+ CARD8 _h_sync_start_8 : 1;
+ CARD8 _h_sync_extend : 1; /* extend h_sync by 32 */
+ CARD8 _h_start_fifo_fetch_8 : 1;
+ CARD8 : 1;
+ } _extended_horizontal_overflow_s;
+ CARD8 _extended_horizontal_overflow; /* CR5D */
+ } _extended_horizontal_overflow_u;
+#define extended_horizontal_overflow _extended_horizontal_overflow_u._extended_horizontal_overflow
+#define h_total_8 _extended_horizontal_overflow_u._extended_horizontal_overflow_s._h_total_8
+#define h_display_end_8 _extended_horizontal_overflow_u._extended_horizontal_overflow_s._h_display_end_8
+#define h_blank_start_8 _extended_horizontal_overflow_u._extended_horizontal_overflow_s._h_blank_start_8
+#define h_blank_extend _extended_horizontal_overflow_u._extended_horizontal_overflow_s._h_blank_extend
+#define h_sync_start_8 _extended_horizontal_overflow_u._extended_horizontal_overflow_s._h_sync_start_8
+#define h_sync_extend _extended_horizontal_overflow_u._extended_horizontal_overflow_s._h_sync_extend
+#define h_start_fifo_fetch_8 _extended_horizontal_overflow_u._extended_horizontal_overflow_s._h_start_fifo_fetch_8
+
+
+ union {
+ struct {
+ CARD8 _v_total_10 : 1;
+ CARD8 _v_display_end_10 : 1;
+ CARD8 _v_blank_start_10 : 1;
+ CARD8 : 1;
+ CARD8 _v_retrace_start_10 : 1;
+ CARD8 : 1;
+ CARD8 _line_compare_10 : 1;
+ CARD8 : 1;
+ } _extended_vertical_overflow_s;
+ CARD8 _extended_vertical_overflow; /* CR5E */
+ } _extended_vertical_overflow_u;
+#define extended_vertical_overflow _extended_vertical_overflow_u._extended_vertical_overflow
+#define v_total_10 _extended_vertical_overflow_u._extended_vertical_overflow_s._v_total_10
+#define v_display_end_10 _extended_vertical_overflow_u._extended_vertical_overflow_s._v_display_end_10
+#define v_blank_start_10 _extended_vertical_overflow_u._extended_vertical_overflow_s._v_blank_start_10
+#define v_retrace_start_10 _extended_vertical_overflow_u._extended_vertical_overflow_s._v_retrace_start_10
+#define line_compare_10 _extended_vertical_overflow_u._extended_vertical_overflow_s._line_compare_10
+
+
+ CARD8 l_parm_0_7; /* CR62 (undocumented) */
+
+ union {
+ struct {
+ CARD8 : 3;
+ CARD8 _delay_blank : 2;
+ CARD8 : 3;
+ } _extended_misc_control_s;
+ CARD8 _extended_misc_control; /* CR65 */
+ } _extended_misc_control_u;
+#define extended_misc_control _extended_misc_control_u._extended_misc_control
+#define delay_blank _extended_misc_control_u._extended_misc_control_s._delay_blank
+
+ union {
+ struct {
+ CARD8 _v_clock_phase : 1;
+ CARD8 : 3;
+ CARD8 _color_mode : 4;
+ } _extended_misc_control_2_s;
+ CARD8 _extended_misc_control_2; /* CR67 */
+ } _extended_misc_control_2_u;
+
+#define v_clock_phase _extended_misc_control_2_u._extended_misc_control_2_s._v_clock_phase
+#define color_mode _extended_misc_control_2_u._extended_misc_control_2_s._color_mode
+#define extended_misc_control_2 _extended_misc_control_2_u._extended_misc_control_2
+
+
+ union {
+ struct {
+ CARD8 cas_oe_str : 2;
+ CARD8 ras_low : 1;
+ CARD8 ras_precharge : 1;
+ CARD8 : 3;
+ CARD8 _memory_bus_size : 1; /* 0 = 32, 1 = 32/64 */
+ } _configuration_3_s;
+ CARD8 _configuration_3; /* CR68 */
+ } _configuration_3_u;
+#define configuration_3 _configuration_3_u._configuration_3
+#define memory_bus_size _configuration_3_u._configuration_3_s._memory_bus_size
+
+ union {
+ struct {
+ CARD8 _start_address_16_19 : 4;
+ CARD8 : 4;
+ } _extended_system_control_3_s;
+ CARD8 _extended_system_control_3; /* CR69 */
+ } _extended_system_control_3_u;
+#define extended_system_control_3 _extended_system_control_3_u._extended_system_control_3
+#define start_address_16_19 _extended_system_control_3_u._extended_system_control_3_s._start_address_16_19
+
+ CARD8 extended_bios_5; /* CR6D */
+
+ union {
+ struct {
+ CARD8 dot_clock_vclki : 1; /* testing only */
+ CARD8 vclki_with_vafc : 1; /* feature connector */
+ CARD8 : 1;
+ CARD8 bpp_24_mode : 1; /* 24 bpp mode */
+ CARD8 alt_color_mode : 4; /* feature connector mode */
+ } _extended_sequencer_b_s;
+ CARD8 _extended_sequencer_b; /* SRB */
+ } _extended_sequencer_b_u;
+
+#define extended_sequencer_b _extended_sequencer_b_u._extended_sequencer_b
+
+ union extended_sequencer_d_u {
+ struct {
+ CARD8 enable_feature : 1;
+ CARD8 lpb_feature : 1;
+ CARD8 : 2;
+ CARD8 _hsync_control : 2;
+ CARD8 _vsync_control : 2;
+ } _extended_sequencer_d_s;
+ CARD8 _extended_sequencer_d;
+ } _extended_sequencer_d_u;
+
+#define extended_sequencer_d _extended_sequencer_d_u._extended_sequencer_d
+#define hsync_control _extended_sequencer_d_u._extended_sequencer_d_s._hsync_control
+#define vsync_control _extended_sequencer_d_u._extended_sequencer_d_s._vsync_control
+
+ union {
+ struct {
+ CARD8 _dclk_pll_n : 5;
+ CARD8 _dclk_pll_r : 2;
+ CARD8 : 1;
+ } _dclk_value_low_s;
+ CARD8 _dclk_value_low; /* SR12 */
+ } _dclk_value_low_u;
+
+#define dclk_value_low _dclk_value_low_u._dclk_value_low
+#define dclk_pll_n_trio _dclk_value_low_u._dclk_value_low_s._dclk_pll_n
+#define dclk_pll_r_trio _dclk_value_low_u._dclk_value_low_s._dclk_pll_r
+
+ union {
+ struct {
+ CARD8 _dclk_pll_m : 7;
+ CARD8 : 1;
+ } _dclk_value_high_s;
+ CARD8 _dclk_value_high; /* SR13 */
+ } _dclk_value_high_u;
+
+#define dclk_value_high _dclk_value_high_u._dclk_value_high
+#define dclk_pll_m_trio _dclk_value_high_u._dclk_value_high_s._dclk_pll_m
+
+ union {
+ struct {
+ CARD8 _mfrq_en : 1;
+ CARD8 _dfrq_en : 1;
+ CARD8 _mclk_out : 1;
+ CARD8 _vclk_out : 1;
+ CARD8 _dclk_over_2 : 1;
+ CARD8 _clk_load : 1;
+ CARD8 _dclk_invert : 1;
+ CARD8 _ena_2_cycle_write : 1;
+ } _control_2_s;
+ CARD8 _control_2; /* SR15 */
+ } _control_2_u;
+
+#define control_2 _control_2_u._control_2
+#define mfrq_en _control_2_u._control_2_s._mfrq_en
+#define dfrq_en _control_2_u._control_2_s._dfrq_en
+#define mclk_out _control_2_u._control_2_s._mclk_out
+#define vclk_out _control_2_u._control_2_s._vclk_out
+#define dclk_over_2 _control_2_u._control_2_s._dclk_over_2
+#define clk_load _control_2_u._control_2_s._clk_load
+#define dclk_invert _control_2_u._control_2_s._dclk_invert
+#define ena_2_cycle_write _control_2_u._control_2_s._ena_2_cycle_write
+
+ union {
+ struct {
+ CARD8 : 5;
+ CARD8 _dac_power_down : 1;
+ CARD8 _lut_write_control : 1;
+ CARD8 _enable_clock_double : 1;
+ } _ramdac_control_s;
+ CARD8 _ramdac_control; /* SR18 */
+ } _ramdac_control_u;
+
+#define ramdac_control _ramdac_control_u._ramdac_control
+#define enable_clock_double _ramdac_control_u._ramdac_control_s._enable_clock_double
+
+ union {
+ struct {
+ CARD8 _dclk_pll_n : 6;
+ CARD8 _dclk_pll_r : 2;
+ } _dclk_value_low_s;
+ CARD8 _dclk_value_low; /* SR36 */
+ } _dclk_value_low_savage_u;
+
+#define dclk_value_low_savage _dclk_value_low_savage_u._dclk_value_low
+#define dclk_pll_n_savage_0_5 _dclk_value_low_savage_u._dclk_value_low_s._dclk_pll_n
+#define dclk_pll_r_savage_0_1 _dclk_value_low_savage_u._dclk_value_low_s._dclk_pll_r
+
+ CARD8 dclk_pll_m0_savage_0_7; /* SR37 */
+ CARD8 dclk_pll_m1_savage_0_7; /* SR38 */
+
+ struct {
+ CARD8 _dclk_pll_m : 8;
+ } _dclk_value_high_s_savage;
+
+ union {
+ struct {
+ CARD8 _dclk_select : 1;
+ CARD8 : 1;
+ CARD8 _dclk_pll_r_2 : 1;
+ CARD8 _dclk_pll_m_8 : 1;
+ CARD8 _dclk_pll_n_6 : 1;
+ CARD8 _pce : 1;
+ CARD8 _ccg : 1;
+ CARD8 _csp : 1;
+ } _extended_seq_39_s;
+ CARD8 _extended_seq_39; /* SR39 */
+ } _extended_seq_39_u;
+
+#define extended_seq_39 _extended_seq_39_u._extended_seq_39
+#define dclk_pll_select_savage _extended_seq_39_u._extended_seq_39_s._dclk_select
+#define dclk_pll_r_savage_2 _extended_seq_39_u._extended_seq_39_s._dclk_pll_r_2
+#define dclk_pll_m_savage_8 _extended_seq_39_u._extended_seq_39_s._dclk_pll_m_8
+#define dclk_pll_n_savage_6 _extended_seq_39_u._extended_seq_39_s._dclk_pll_n_6
+
+ /* computed values */
+ CARD16 ge_screen_pitch;
+ CARD8 bits_per_pixel;
+ CARD8 depth;
+ CARD8 double_pixel_mode;
+ CARD16 pixel_width;
+} S3Crtc;
+
+#define crtc_v_total(crtc) ((crtc)->v_total_0_7 | \
+ ((crtc)->v_total_8 << 8) | \
+ ((crtc)->v_total_9 << 9) | \
+ ((crtc)->v_total_10 << 10))
+
+#define crtc_set_v_total(crtc,v) { \
+ ((crtc))->v_total_0_7 = (v); \
+ ((crtc))->v_total_8 = (v) >> 8; \
+ ((crtc))->v_total_9 = (v) >> 9; \
+ ((crtc))->v_total_10 = (v) >> 10; \
+}
+
+#define crtc_v_display_end(crtc) ((crtc)->v_display_end_0_7 | \
+ ((crtc)->v_display_end_8 << 8) | \
+ ((crtc)->v_display_end_9 << 9) | \
+ ((crtc)->v_display_end_10 << 10))
+
+#define crtc_set_v_display_end(crtc,v) {\
+ ((crtc))->v_display_end_0_7 = (v); \
+ ((crtc))->v_display_end_8 = (v) >> 8; \
+ ((crtc))->v_display_end_9 = (v) >> 9; \
+ ((crtc))->v_display_end_10 = (v) >> 10; \
+}
+
+#define crtc_v_retrace_start(crtc) ((crtc)->v_retrace_start_0_7 | \
+ ((crtc)->v_retrace_start_8 << 8) | \
+ ((crtc)->v_retrace_start_9 << 9) | \
+ ((crtc)->v_retrace_start_10 << 10))
+
+#define crtc_set_v_retrace_start(crtc,v) {\
+ ((crtc))->v_retrace_start_0_7 = (v); \
+ ((crtc))->v_retrace_start_8 = (v) >> 8; \
+ ((crtc))->v_retrace_start_9 = (v) >> 9; \
+ ((crtc))->v_retrace_start_10 = (v) >> 10; \
+}
+
+#define crtc_v_blank_start(crtc) ((crtc)->v_blank_start_0_7 | \
+ ((crtc)->v_blank_start_8 << 8) | \
+ ((crtc)->v_blank_start_9 << 9) | \
+ ((crtc)->v_blank_start_10 << 10))
+
+#define crtc_set_v_blank_start(crtc,v) {\
+ ((crtc))->v_blank_start_0_7 = (v); \
+ ((crtc))->v_blank_start_8 = (v) >> 8; \
+ ((crtc))->v_blank_start_9 = (v) >> 9; \
+ ((crtc))->v_blank_start_10 = (v) >> 10; \
+}
+
+#define crtc_h_total(crtc) ((crtc)->h_total_0_7 | \
+ ((crtc)->h_total_8 << 8))
+
+#define crtc_set_h_total(crtc,v) {\
+ ((crtc))->h_total_0_7 = (v); \
+ ((crtc))->h_total_8 = (v) >> 8; \
+}
+
+#define crtc_h_display_end(crtc) ((crtc)->h_display_end_0_7 | \
+ ((crtc)->h_display_end_8 << 8))
+
+#define crtc_set_h_display_end(crtc,v) {\
+ ((crtc))->h_display_end_0_7 = (v); \
+ ((crtc))->h_display_end_8 = (v) >> 8; \
+}
+
+#define crtc_h_blank_start(crtc) ((crtc)->h_blank_start_0_7 | \
+ ((crtc)->h_blank_start_8 << 8))
+
+#define crtc_set_h_blank_start(crtc,v) {\
+ ((crtc))->h_blank_start_0_7 = (v); \
+ ((crtc))->h_blank_start_8 = (v) >> 8; \
+}
+
+#define crtc_h_blank_end(crtc) ((crtc)->h_blank_end_0_4 | \
+ ((crtc)->h_blank_end_5 << 5))
+
+#define crtc_set_h_blank_end(crtc,v) {\
+ ((crtc))->h_blank_end_0_4 = (v); \
+ ((crtc))->h_blank_end_5 = (v) >> 5; \
+}
+
+#define crtc_h_sync_start(crtc) ((crtc)->h_sync_start_0_7 | \
+ ((crtc)->h_sync_start_8 << 8))
+
+#define crtc_set_h_sync_start(crtc,v) {\
+ ((crtc))->h_sync_start_0_7 = (v); \
+ ((crtc))->h_sync_start_8 = (v) >> 8; \
+}
+
+#define crtc_h_sync_end(crtc) ((crtc)->h_sync_end_0_4)
+
+#define crtc_set_h_sync_end(crtc,v) {\
+ ((crtc))->h_sync_end_0_4 = (v); \
+}
+
+#define crtc_screen_off(crtc) ((crtc)->screen_off_0_7 | \
+ (((crtc)->screen_off_8_9 ? \
+ ((crtc))->screen_off_8_9 : \
+ ((crtc))->old_screen_off_8) << 8))
+
+#define crtc_set_screen_off(crtc,v) {\
+ ((crtc))->screen_off_0_7 = (v); \
+ ((crtc))->old_screen_off_8 = 0; \
+ ((crtc))->screen_off_8_9 = (v) >> 8; \
+}
+
+#define crtc_ge_screen_width(crtc) ((crtc)->ge_screen_width_0_1 | \
+ ((crtc)->ge_screen_width_2 << 2))
+
+#define crtc_set_ge_screen_width(crtc,v) { \
+ (crtc)->ge_screen_width_0_1 = (v); \
+ (crtc)->ge_screen_width_2 = (v) >> 2; \
+}
+
+#define crtc_h_start_fifo_fetch(crtc) ((crtc)->h_start_fifo_fetch_0_7 | \
+ ((crtc)->h_start_fifo_fetch_8 << 8))
+
+#define crtc_set_h_start_fifo_fetch(crtc,v) {\
+ (crtc)->h_start_fifo_fetch_0_7 = (v); \
+ (crtc)->h_start_fifo_fetch_8 = (v) >> 8; \
+}
+
+#define crtc_start_address(crtc) ((crtc)->start_address_0_7 | \
+ ((crtc)->start_address_8_15 << 8) | \
+ ((crtc)->start_address_16_19 << 16))
+
+#define crtc_set_start_address(crtc,v) {\
+ (crtc)->start_address_0_7 = (v); \
+ (crtc)->start_address_8_15 = (v) >> 8; \
+ (crtc)->start_address_16_19 = (v) >> 16; \
+}
+
+#define crtc_line_compare(crtc) ((crtc)->line_compare_0_7 | \
+ ((crtc)->line_compare_8 << 8) | \
+ ((crtc)->line_compare_9 << 9) | \
+ ((crtc)->line_compare_10 << 10))
+
+#define crtc_set_line_compare(crtc,v) { \
+ ((crtc))->line_compare_0_7 = (v); \
+ ((crtc))->line_compare_8 = (v) >> 8; \
+ ((crtc))->line_compare_9 = (v) >> 9; \
+ ((crtc))->line_compare_10 = (v) >> 10; \
+}
+
+
+#define GetCrtc(s3,i) _s3ReadIndexRegister (&(s3)->crt_vga_3d4, (i))
+#define PutCrtc(s3,i,v) _s3WriteIndexRegister (&(s3)->crt_vga_3d4, (i), (v))
+
+#define GetSrtc(s3,i) _s3ReadIndexRegister (&(s3)->crt_vga_3c4, (i))
+#define PutSrtc(s3,i,v) _s3WriteIndexRegister (&(s3)->crt_vga_3c4, (i), (v))
+
+#define S3_CLOCK_REF 14318 /* KHz */
+
+#define S3_CLOCK(m,n,r) (S3_CLOCK_REF * ((m) + 2) / (((n) + 2) * (1 << (r))))
+
+#if PLATFORM == 200
+#define S3_MAX_CLOCK 80000 /* KHz */
+#endif
+#if PLATFORM == 300
+#define S3_MAX_CLOCK 135000 /* KHz */
+#endif
+
+typedef struct _s3Save {
+ CARD8 cursor_fg;
+ CARD8 cursor_bg;
+ CARD8 lock1;
+ CARD8 lock2;
+ CARD8 locksrtc;
+ CARD8 clock_mode;
+ CARD32 alt_mix;
+ CARD32 write_mask;
+ CARD32 fg;
+ CARD32 bg;
+ S3Crtc crtc;
+} S3Save;
+
+typedef struct _s3CardInfo {
+ S3Ptr s3; /* pointer to register structure */
+ int memory; /* amount of memory */
+ CARD8 *frameBuffer; /* pointer to frame buffer */
+ CARD8 *registers; /* pointer to register map */
+ S3Save save;
+ Bool savage;
+ Bool need_sync;
+} S3CardInfo;
+
+typedef struct _s3ScreenInfo {
+ CARD8 *cursor_base; /* pointer to cursor area */
+ CARD8 *offscreen; /* pointer to offscreen area */
+ int offscreen_y; /* top y coordinate of offscreen area */
+ int offscreen_x; /* top x coordinate of offscreen area */
+ int offscreen_width; /* width of offscreen area */
+ int offscreen_height; /* height of offscreen area */
+ S3Cursor cursor;
+ S3Patterns patterns;
+} S3ScreenInfo;
+
+#define LockS3(s3c)
+#define UnlockS3(s3c)
+
+#define getS3CardInfo(kd) ((S3CardInfo *) ((kd)->card->driver))
+#define s3CardInfo(kd) S3CardInfo *s3c = getS3CardInfo(kd)
+
+#define getS3ScreenInfo(kd) ((S3ScreenInfo *) ((kd)->screen->driver))
+#define s3ScreenInfo(kd) S3ScreenInfo *s3s = getS3ScreenInfo(kd)
+
+Bool s3CardInit (KdCardInfo *);
+Bool s3ScreenInit (KdScreenInfo *);
+void s3Enable (ScreenPtr pScreen);
+void s3Disable (ScreenPtr pScreen);
+void s3Fini (ScreenPtr pScreen);
+
+Bool s3CursorInit (ScreenPtr pScreen);
+void s3CursorEnable (ScreenPtr pScreen);
+void s3CursorDisable (ScreenPtr pScreen);
+void s3CursorFini (ScreenPtr pScreen);
+void s3RecolorCursor (ScreenPtr pScreen, int ndef, xColorItem *pdefs);
+
+Bool s3DrawInit (ScreenPtr pScreen);
+void s3DrawEnable (ScreenPtr pScreen);
+void s3DrawSync (ScreenPtr pScreen);
+void s3DrawDisable (ScreenPtr pScreen);
+void s3DrawFini (ScreenPtr pScreen);
+
+void s3GetColors (ScreenPtr pScreen, int ndef, xColorItem *pdefs);
+void s3PutColors (ScreenPtr pScreen, int ndef, xColorItem *pdefs);
+
+void S3InitCard (KdCardAttr *attr);
+
+void s3GetClock (int target, int *Mp, int *Np, int *Rp, int maxM, int maxN, int maxR);
+
+CARD8 _s3ReadIndexRegister (VOL8 *base, CARD8 index);
+void _s3WriteIndexRegister (VOL8 *base, CARD8 index, CARD8 value);
+
+extern KdCardFuncs s3Funcs;
+
+/*
+ * Wait for the begining of the retrace interval
+ */
+
+#define S3_RETRACE_LOOP_CHECK if (++_loop_count > 300000) {\
+ DRAW_DEBUG ((DEBUG_FAILURE, "S3 wait loop failed at %s:%d", \
+ __FILE__, __LINE__)); \
+ break; \
+}
+
+#define _s3WaitVRetrace(s3) { \
+ VOL8 *_status = &s3->crt_vga_status_1; \
+ int _loop_count; \
+ DRAW_DEBUG ((DEBUG_CRTC, "_s3WaitVRetrace 0x%x", *_status)); \
+ _loop_count = 0; \
+ while ((*_status & VGA_STATUS_1_VSY) != 0) S3_RETRACE_LOOP_CHECK; \
+ _loop_count = 0; \
+ while ((*_status & VGA_STATUS_1_VSY) == 0) S3_RETRACE_LOOP_CHECK; \
+}
+/*
+ * Wait for the begining of the retrace interval
+ */
+#define _s3WaitVRetraceEnd(s3) { \
+ VOL8 *_status = &s3->crt_vga_status_1; \
+ int _loop_count; \
+ DRAW_DEBUG ((DEBUG_CRTC, "_s3WaitVRetraceEnd 0x%x", *_status)); \
+ _loop_count = 0; \
+ while ((*_status & VGA_STATUS_1_VSY) == 0) S3_RETRACE_LOOP_CHECK; \
+ _loop_count = 0; \
+ while ((*_status & VGA_STATUS_1_VSY) != 0) S3_RETRACE_LOOP_CHECK; \
+}
+
+/*
+ * This extension register must contain a magic bit pattern to enable
+ * the remaining extended registers
+ */
+
+#define _s3UnlockExt(s3) _s3WriteIndexRegister (&s3->crt_vga_3d4, 0x39, 0xa0)
+#define _s3LockExt(s3) _s3WriteIndexRegister (&s3->crt_vga_3d4, 0x39, 0x00)
+
+#define S3_CURSOR_WIDTH 64
+#define S3_CURSOR_HEIGHT 64
+#define S3_CURSOR_SIZE ((S3_CURSOR_WIDTH * S3_CURSOR_HEIGHT + 7) / 8)
+
+#define S3_TILE_SIZE 8
+
+#endif /* _S3_H_ */
diff --git a/xc/programs/Xserver/hw/kdrive/trio/s3clock.c b/xc/programs/Xserver/hw/kdrive/trio/s3clock.c
new file mode 100644
index 000000000..0ec0b95c8
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/trio/s3clock.c
@@ -0,0 +1,85 @@
+/*
+ * $Id: s3clock.c,v 1.1 2000/01/06 12:55:56 faith 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/trio/s3clock.c,v 1.2 1999/12/30 03:03:19 robin Exp $ */
+
+#include "s3.h"
+
+/*
+ * Clock synthesis:
+ *
+ * f_out = f_ref * ((M + 2) / ((N + 2) * (1 << R)))
+ *
+ * Constraints:
+ *
+ * 1. 135MHz <= f_ref * ((M + 2) / (N + 2)) <= 270 MHz
+ * 2. N >= 1
+ *
+ * Vertical refresh rate = clock / ((hsize + hblank) * (vsize + vblank))
+ * Horizontal refresh rate = clock / (hsize + hblank)
+ */
+
+/* all in kHz */
+#define MIN_VCO 180000.0
+#define MAX_VCO 360000.0
+
+void
+s3GetClock (int target, int *Mp, int *Np, int *Rp, int maxM, int maxN, int maxR)
+{
+ int M, N, R, bestM, bestN;
+ int f_vco, f_out;
+ int err, abserr, besterr;
+
+ /*
+ * Compute correct R value to keep VCO in range
+ */
+ for (R = 0; R <= maxR; R++)
+ {
+ f_vco = target * (1 << R);
+ if (MIN_VCO <= f_vco && f_vco < MAX_VCO)
+ break;
+ }
+
+ /* M = f_out / f_ref * ((N + 2) * (1 << R)); */
+ besterr = target;
+ for (N = 0; N <= maxN; N++)
+ {
+ M = (target * (N + 2) * (1 << R) + (S3_CLOCK_REF/2)) / S3_CLOCK_REF - 2;
+ if (0 <= M && M <= maxM)
+ {
+ f_out = S3_CLOCK(M,N,R);
+ err = target - f_out;
+ if (err < 0)
+ err = -err;
+ if (err < besterr)
+ {
+ besterr = err;
+ bestM = M;
+ bestN = N;
+ }
+ }
+ }
+ *Mp = bestM;
+ *Np = bestN;
+ *Rp = R;
+}
diff --git a/xc/programs/Xserver/hw/kdrive/trio/s3cmap.c b/xc/programs/Xserver/hw/kdrive/trio/s3cmap.c
new file mode 100644
index 000000000..f4357e2f9
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/trio/s3cmap.c
@@ -0,0 +1,70 @@
+/*
+ * $Id: s3cmap.c,v 1.1 2000/01/06 12:55:56 faith 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/trio/s3cmap.c,v 1.1 1999/11/19 13:54:05 hohndel Exp $ */
+
+#include "s3.h"
+
+void
+s3GetColors (ScreenPtr pScreen, int ndef, xColorItem *pdefs)
+{
+ KdScreenPriv(pScreen);
+ s3CardInfo(pScreenPriv);
+ S3Ptr s3 = s3c->s3;
+ VOL8 *dac_rd_ad = &s3->crt_vga_dac_rd_ad;
+ VOL8 *dac_data = &s3->crt_vga_dac_data;
+
+ LockS3 (s3c);
+ while (ndef--)
+ {
+ *dac_rd_ad = pdefs->pixel;
+ pdefs->red = *dac_data << 10;
+ pdefs->green = *dac_data << 10;
+ pdefs->blue = *dac_data << 10;
+ pdefs++;
+ }
+ UnlockS3(s3c);
+}
+
+void
+s3PutColors (ScreenPtr pScreen, int ndef, xColorItem *pdefs)
+{
+ KdScreenPriv(pScreen);
+ s3CardInfo(pScreenPriv);
+ S3Ptr s3 = s3c->s3;
+ VOL8 *dac_wt_ad = &s3->crt_vga_dac_wt_ad;
+ VOL8 *dac_data = &s3->crt_vga_dac_data;
+
+ LockS3(s3c);
+ _s3WaitVRetrace (s3);
+ while (ndef--)
+ {
+ *dac_wt_ad = pdefs->pixel;
+ *dac_data = pdefs->red >> 10;
+ *dac_data = pdefs->green >> 10;
+ *dac_data = pdefs->blue >> 10;
+ pdefs++;
+ }
+ UnlockS3(s3c);
+}
+
diff --git a/xc/programs/Xserver/hw/kdrive/trio/s3curs.c b/xc/programs/Xserver/hw/kdrive/trio/s3curs.c
new file mode 100644
index 000000000..b33b651d1
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/trio/s3curs.c
@@ -0,0 +1,416 @@
+/*
+ * $Id: s3curs.c,v 1.1 2000/01/06 12:55:56 faith 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/trio/s3curs.c,v 1.2 1999/12/30 03:03:19 robin Exp $ */
+
+#include "s3.h"
+#include "s3draw.h"
+#include "cursorstr.h"
+
+#define SetupCursor(s) KdScreenPriv(s); \
+ s3CardInfo(pScreenPriv); \
+ s3ScreenInfo(pScreenPriv); \
+ S3Ptr s3 = s3c->s3; \
+ S3Cursor *pCurPriv = &s3s->cursor
+
+static void
+_s3MoveCursor (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 */
+
+ _s3WriteIndexRegister (&s3->crt_vga_3d4, 0x46, xhigh);
+ _s3WriteIndexRegister (&s3->crt_vga_3d4, 0x47, xlow);
+ _s3WriteIndexRegister (&s3->crt_vga_3d4, 0x49, ylow);
+ _s3WriteIndexRegister (&s3->crt_vga_3d4, 0x4e, xoff);
+ _s3WriteIndexRegister (&s3->crt_vga_3d4, 0x4f, yoff);
+ _s3WriteIndexRegister (&s3->crt_vga_3d4, 0x48, yhigh);
+}
+
+static void
+s3MoveCursor (ScreenPtr pScreen, int x, int y)
+{
+ SetupCursor (pScreen);
+
+ if (!pCurPriv->has_cursor)
+ return;
+
+ if (!pScreenPriv->enabled)
+ return;
+
+ LockS3(s3c);
+ _s3UnlockExt(s3);
+ _s3MoveCursor (pScreen, x, y);
+ _s3LockExt(s3);
+ UnlockS3(s3c);
+}
+
+static void
+s3AllocCursorColors (ScreenPtr pScreen)
+{
+ SetupCursor (pScreen);
+ CursorPtr pCursor = pCurPriv->pCursor;
+ xColorItem sourceColor, maskColor;
+
+ KdAllocateCursorPixels (pScreen, pCursor,
+ &pCurPriv->source, &pCurPriv->mask);
+ 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
+_s3SetCursorColors (ScreenPtr pScreen)
+{
+ SetupCursor (pScreen);
+ /* set foreground */
+ /* Reset cursor color stack pointers */
+ (void) _s3ReadIndexRegister(&s3->crt_vga_3d4, 0x45);
+ _s3WriteIndexRegister (&s3->crt_vga_3d4, 0x4a, pCurPriv->source);
+ _s3WriteIndexRegister (&s3->crt_vga_3d4, 0x4a, pCurPriv->source >> 8);
+ _s3WriteIndexRegister (&s3->crt_vga_3d4, 0x4a, pCurPriv->source >> 16);
+
+ /* set background */
+ /* Reset cursor color stack pointers */
+ (void) _s3ReadIndexRegister(&s3->crt_vga_3d4, 0x45);
+ _s3WriteIndexRegister (&s3->crt_vga_3d4, 0x4b, pCurPriv->mask);
+ _s3WriteIndexRegister (&s3->crt_vga_3d4, 0x4b, pCurPriv->mask >> 8);
+ _s3WriteIndexRegister (&s3->crt_vga_3d4, 0x4b, pCurPriv->mask >> 16);
+}
+
+void
+s3RecolorCursor (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;
+ }
+ s3AllocCursorColors (pScreen);
+ LockS3 (s3c);
+ _s3UnlockExt(s3);
+ _s3SetCursorColors (pScreen);
+ _s3LockExt (s3);
+ UnlockS3 (s3c);
+}
+
+static void
+s3LoadCursor (ScreenPtr pScreen, int x, int y)
+{
+ SetupCursor(pScreen);
+ CursorPtr pCursor = pCurPriv->pCursor;
+ CursorBitsPtr bits = pCursor->bits;
+ int w, h;
+ unsigned char r[2], g[2], b[2];
+ unsigned long *ram;
+ unsigned long *msk, *mskLine, *src, *srcLine;
+ unsigned long and, xor;
+ int i, j;
+ int cursor_address;
+ int wsrc;
+ unsigned char ramdac_control_;
+
+ /*
+ * Allocate new colors
+ */
+ s3AllocCursorColors (pScreen);
+
+ pCurPriv->pCursor = pCursor;
+ pCurPriv->xhot = pCursor->bits->xhot;
+ pCurPriv->yhot = pCursor->bits->yhot;
+
+ /*
+ * Stick new image into cursor memory
+ */
+ ram = (unsigned long *) s3s->cursor_base;
+ mskLine = (unsigned long *) bits->mask;
+ srcLine = (unsigned long *) bits->source;
+
+ h = bits->height;
+ if (h > S3_CURSOR_HEIGHT)
+ h = S3_CURSOR_HEIGHT;
+
+ wsrc = BitmapBytePad(bits->width) / 4; /* ulongs per line */
+
+ for (i = 0; i < S3_CURSOR_HEIGHT; i++)
+ {
+ msk = mskLine;
+ src = srcLine;
+ mskLine += wsrc;
+ srcLine += wsrc;
+ for (j = 0; j < S3_CURSOR_WIDTH / 32; j++) {
+
+ unsigned long m, s;
+
+ if (i < h && j < wsrc)
+ {
+ m = *msk++;
+ s = *src++;
+ xor = m & s;
+ and = ~m;
+ }
+ else
+ {
+ and = 0xffffffff;
+ xor = 0x00000000;
+ }
+
+ S3AdjustBits32(and);
+ S3AdjustBits32(xor);
+ *ram++ = (and & 0xffff) | (xor << 16);
+ *ram++ = (and >> 16) | (xor & 0xffff0000);
+ }
+ }
+
+ _s3WaitIdle (s3);
+ _s3UnlockExt (s3);
+
+ /* Set new color */
+ _s3SetCursorColors (pScreen);
+
+ /* Enable the cursor */
+ _s3WriteIndexRegister (&s3->crt_vga_3d4, 0x45, 0x01);
+
+ /* Wait for VRetrace to make sure the position is read */
+ _s3WaitVRetrace (s3);
+
+ /* Move to new position */
+ _s3MoveCursor (pScreen, x, y);
+
+ _s3LockExt (s3);
+ UnlockS3(s3c);
+}
+
+static void
+s3UnloadCursor (ScreenPtr pScreen)
+{
+ SetupCursor (pScreen);
+
+ LockS3 (s3c);
+ _s3UnlockExt(s3);
+
+ /* Disable cursor */
+ _s3WriteIndexRegister (&s3->crt_vga_3d4, 0x45, 0);
+
+ _s3LockExt(s3);
+ UnlockS3 (s3c);
+}
+
+static Bool
+s3RealizeCursor (ScreenPtr pScreen, CursorPtr pCursor)
+{
+ SetupCursor(pScreen);
+
+ if (!pScreenPriv->enabled)
+ return TRUE;
+
+ /* miRecolorCursor does this */
+ if (pCurPriv->pCursor == pCursor)
+ {
+ if (pCursor)
+ {
+#ifdef FB_OLD_SCREEN
+ short x, y;
+#else
+ int x, y;
+#endif
+
+ miPointerPosition (&x, &y);
+ s3LoadCursor (pScreen, x, y);
+ }
+ }
+ return TRUE;
+}
+
+static Bool
+s3UnrealizeCursor (ScreenPtr pScreen, CursorPtr pCursor)
+{
+ return TRUE;
+}
+
+static void
+s3SetCursor (ScreenPtr pScreen, CursorPtr pCursor, int x, int y)
+{
+ SetupCursor(pScreen);
+
+ pCurPriv->pCursor = pCursor;
+
+ if (!pScreenPriv->enabled)
+ return;
+
+ if (pCursor)
+ s3LoadCursor (pScreen, x, y);
+ else
+ s3UnloadCursor (pScreen);
+}
+
+miPointerSpriteFuncRec s3PointerSpriteFuncs = {
+ s3RealizeCursor,
+ s3UnrealizeCursor,
+ s3SetCursor,
+ s3MoveCursor,
+};
+
+static void
+s3QueryBestSize (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
+s3CursorInit (ScreenPtr pScreen)
+{
+ SetupCursor (pScreen);
+
+ if (!s3s->cursor_base)
+ {
+ pCurPriv->has_cursor = FALSE;
+ return FALSE;
+ }
+
+ pCurPriv->width = S3_CURSOR_WIDTH;
+ pCurPriv->height= S3_CURSOR_HEIGHT;
+ pScreen->QueryBestSize = s3QueryBestSize;
+ miPointerInitialize (pScreen,
+ &s3PointerSpriteFuncs,
+ &kdPointerScreenFuncs,
+ FALSE);
+ pCurPriv->has_cursor = TRUE;
+ pCurPriv->pCursor = NULL;
+ return TRUE;
+}
+
+void
+s3CursorEnable (ScreenPtr pScreen)
+{
+ SetupCursor (pScreen);
+
+ if (pCurPriv->has_cursor)
+ {
+ if (pCurPriv->pCursor)
+ {
+#ifdef FB_OLD_SCREEN
+ short x, y;
+#else
+ int x, y;
+#endif
+
+ miPointerPosition (&x, &y);
+ s3LoadCursor (pScreen, x, y);
+ }
+ else
+ s3UnloadCursor (pScreen);
+ }
+}
+
+void
+s3CursorDisable (ScreenPtr pScreen)
+{
+ SetupCursor (pScreen);
+
+ if (!pScreenPriv->enabled)
+ return;
+
+ if (pCurPriv->has_cursor)
+ {
+ if (pCurPriv->pCursor)
+ {
+ s3UnloadCursor (pScreen);
+ }
+ }
+}
+
+void
+s3CursorFini (ScreenPtr pScreen)
+{
+ SetupCursor (pScreen);
+
+ pCurPriv->pCursor = NULL;
+}
diff --git a/xc/programs/Xserver/hw/kdrive/trio/s3stub.c b/xc/programs/Xserver/hw/kdrive/trio/s3stub.c
new file mode 100644
index 000000000..008b945cd
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/trio/s3stub.c
@@ -0,0 +1,59 @@
+/*
+ * $Id: s3stub.c,v 1.1 2000/01/06 12:55:56 faith 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/trio/s3stub.c,v 1.2 1999/12/30 03:03:20 robin Exp $ */
+
+#include "s3.h"
+
+void
+InitCard (char *name)
+{
+ KdCardAttr attr;
+ CARD32 count;
+
+ count = 0;
+ while (LinuxFindPci (0x5333, 0x8904, count, &attr))
+ {
+ KdCardInfoAdd (&s3Funcs, &attr, 0);
+ count++;
+ }
+}
+
+void
+InitOutput (ScreenInfo *pScreenInfo, int argc, char **argv)
+{
+ KdInitOutput (pScreenInfo, argc, argv);
+}
+
+void
+InitInput (int argc, char **argv)
+{
+ KdInitInput (&Ps2MouseFuncs, &LinuxKeyboardFuncs);
+}
+
+int
+ddxProcessArgument (int argc, char **argv, int i)
+{
+ return KdProcessArgument (argc, argv, i);
+}
diff --git a/xc/programs/Xserver/hw/kdrive/ts300/Imakefile b/xc/programs/Xserver/hw/kdrive/ts300/Imakefile
new file mode 100644
index 000000000..b7bd268c7
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/ts300/Imakefile
@@ -0,0 +1,15 @@
+XCOMM $XConsortium: Imakefile /main/10 1996/12/02 10:20:33 lehors $
+XCOMM $XFree86: xc/programs/Xserver/hw/kdrive/ts300/Imakefile,v 1.1 1999/11/19 13:54:06 hohndel Exp $
+#include <Server.tmpl>
+
+SRCS = ts300.c
+
+OBJS = ts300.o
+
+INCLUDES = -I../trio -I../sis530 -I.. -I. -I$(XBUILDINCDIR) -I$(FONTINCSRC) \
+ -I../../../fb -I../../../mi -I../../../include -I../../../os \
+ -I$(EXTINCSRC) -I$(XINCLUDESRC)
+
+NormalLibraryObjectRule()
+NormalLibraryTarget(ts300,$(OBJS))
+DependTarget()
diff --git a/xc/programs/Xserver/hw/kdrive/ts300/ts300.c b/xc/programs/Xserver/hw/kdrive/ts300/ts300.c
new file mode 100644
index 000000000..e6939ff72
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/ts300/ts300.c
@@ -0,0 +1,130 @@
+/*
+ * $Id: ts300.c,v 1.1 2000/01/06 12:55:56 faith 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/ts300/ts300.c,v 1.2 1999/12/30 03:03:20 robin Exp $ */
+
+#include "kdrive.h"
+
+extern KdCardFuncs sisFuncs;
+extern KdCardFuncs s3Funcs;
+
+/*
+ * Kludgy code to parse the ascii /proc/pci file as the TS300
+ * is running a 2.0 kernel
+ */
+BOOL
+HasPCI (char *name, KdCardAttr *attr)
+{
+ FILE *f;
+ char line[1024];
+ BOOL waiting;
+ BOOL found = FALSE;
+ char *mem;
+
+ f = fopen ("/proc/pci", "r");
+ if (!f)
+ return FALSE;
+ waiting = FALSE;
+ attr->naddr = 0;
+ while (fgets (line, sizeof (line), f))
+ {
+ if (waiting)
+ {
+
+ if (mem = strstr (line, "memory at "))
+ {
+ mem += strlen ("memory at ");
+ attr->address[attr->naddr++] = strtoul (mem, NULL, 0);
+ found = TRUE;
+ }
+ else if (mem = strstr (line, "I/O at "))
+ {
+ mem += strlen ("I/O at ");
+ attr->io = strtoul (mem, NULL, 0);
+ found = TRUE;
+ }
+ else if (strstr (line, "Bus") && strstr (line, "device") &&
+ strstr (line, "function"))
+ break;
+ }
+ else if (strstr (line, "VGA compatible controller"))
+ {
+ if (strstr (line, name))
+ waiting = TRUE;
+ }
+ }
+ fclose (f);
+ return found;
+}
+
+typedef struct _PCICard {
+ char *user;
+ char *name;
+ KdCardFuncs *funcs;
+} PCICard;
+
+PCICard PCICards[] = {
+ "sis", "Silicon Integrated Systems", &sisFuncs,
+ "s3", "S3 Inc.", &s3Funcs,
+};
+
+#define NUM_PCI_CARDS (sizeof (PCICards) / sizeof (PCICards[0]))
+
+void
+InitCard (char *name)
+{
+ KdCardInfo *card;
+ CARD32 fb;
+ int i;
+ KdCardAttr attr;
+
+ for (i = 0; i < NUM_PCI_CARDS; i++)
+ {
+ if (!name || !strcmp (name, PCICards[i].user))
+ {
+ if (HasPCI (PCICards[i].name, &attr))
+ {
+ KdCardInfoAdd (PCICards[i].funcs, &attr, 0);
+ return;
+ }
+ }
+ }
+}
+
+void
+InitOutput (ScreenInfo *pScreenInfo, int argc, char **argv)
+{
+ KdInitOutput (pScreenInfo, argc, argv);
+}
+
+void
+InitInput (int argc, char **argv)
+{
+ KdInitInput (&Ps2MouseFuncs, &LinuxKeyboardFuncs);
+}
+
+int
+ddxProcessArgument (int argc, char **argv, int i)
+{
+ return KdProcessArgument (argc, argv, i);
+}
diff --git a/xc/programs/Xserver/hw/kdrive/vga.c b/xc/programs/Xserver/hw/kdrive/vga.c
new file mode 100644
index 000000000..93c583723
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/vga.c
@@ -0,0 +1,323 @@
+/*
+ * $Id: vga.c,v 1.1 2000/01/06 12:55:48 faith 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/vga.c,v 1.2 1999/12/30 03:03:07 robin Exp $ */
+
+#include "vga.h"
+#include <stdio.h>
+
+#ifdef linux
+#define extern static
+#include <asm/io.h>
+#undef extern
+
+#define _VgaInb(r) inb(r)
+#define _VgaOutb(v,r) outb(v,r)
+
+#define _VgaByteAddr(a) ((VGAVOL8 *) (a))
+#define _VgaBytePort(a) (a)
+#endif
+
+#ifdef VXWORKS
+#define _VgaInb(r) 0
+#define _VgaOutb(v,r) 0
+
+#define _VgaByteAddr(a) ((VGAVOL8 *) ((VGA32) (a) ^ 3))
+#define _VgaBytePort(a) 0
+
+#undef stderr
+#define stderr stdout
+
+#endif
+
+#undef VGA_DEBUG_REGISTERS
+#ifdef VGA_DEBUG_REGISTERS
+#define VGA_DEBUG(a) fprintf a
+#else
+#define VGA_DEBUG(a)
+#endif
+
+VGA8
+VgaInb (VGA16 r)
+{
+ return _VgaInb(r);
+}
+
+void
+VgaOutb (VGA8 v, VGA16 r)
+{
+ _VgaOutb (v,r);
+}
+
+VGA8
+VgaReadMemb (VGA32 addr)
+{
+ return *_VgaByteAddr(addr);
+}
+
+void
+VgaWriteMemb (VGA8 v, VGA32 addr)
+{
+ *_VgaByteAddr(addr) = v;
+}
+
+VGA8
+VgaFetch (VgaCard *card, VGA16 reg)
+{
+ VgaMap map;
+ VGA8 value;
+
+ (*card->map) (card, reg, &map, VGAFALSE);
+ switch (map.access) {
+ case VgaAccessMem:
+ value = VgaReadMemb (map.port);
+ VGA_DEBUG ((stderr, "%08x -> %2x\n", map.port, value));
+ break;
+ case VgaAccessIo:
+ value = _VgaInb (map.port);
+ VGA_DEBUG ((stderr, "%4x -> %2x\n", map.port, value));
+ break;
+ case VgaAccessIndMem:
+ VgaWriteMemb (map.index, map.port + map.addr);
+ value = VgaReadMemb (map.port + map.value);
+ VGA_DEBUG ((stderr, "%4x/%2x -> %2x\n", map.port, map.index, value));
+ break;
+ case VgaAccessIndIo:
+ _VgaOutb (map.index, map.port + map.addr);
+ value = _VgaInb (map.port + map.value);
+ VGA_DEBUG ((stderr, "%4x/%2x -> %2x\n", map.port, map.index, value));
+ break;
+ case VgaAccessDone:
+ value = map.value;
+ VGA_DEBUG ((stderr, "direct %4x -> %2x\n", reg, value));
+ break;
+ }
+ return value;
+}
+
+void
+VgaStore (VgaCard *card, VGA16 reg, VGA8 value)
+{
+ VgaMap map;
+
+ map.value = value;
+ (*card->map) (card, reg, &map, VGATRUE);
+ switch (map.access) {
+ case VgaAccessMem:
+ VGA_DEBUG ((stderr, "%8x <- %2x\n", map.port, value));
+ VgaWriteMemb (map.value, map.port);
+ break;
+ case VgaAccessIo:
+ VGA_DEBUG ((stderr, "%4x <- %2x\n", map.port, value));
+ _VgaOutb (value, map.port);
+ break;
+ case VgaAccessIndMem:
+ VgaWriteMemb (map.index, map.port + map.addr);
+ VgaWriteMemb (value, map.port + map.value);
+ VGA_DEBUG ((stderr, "%4x/%2x <- %2x\n", map.port, map.index, value));
+ break;
+ case VgaAccessIndIo:
+ VGA_DEBUG ((stderr, "%4x/%2x <- %2x\n", map.port, map.index, value));
+ _VgaOutb (map.index, map.port + map.addr);
+ _VgaOutb (value, map.port + map.value);
+ break;
+ case VgaAccessDone:
+ VGA_DEBUG ((stderr, "direct %4x <- %2x\n", reg, value));
+ break;
+ }
+}
+
+void
+VgaPreserve (VgaCard *card)
+{
+ VgaSave *s;
+ VGA16 id;
+
+ for (s = card->saves; s->first != VGA_REG_NONE; s++)
+ {
+ for (id = s->first; id <= s->last; id++)
+ {
+ card->values[id].cur = VgaFetch (card, id);
+ card->values[id].save = card->values[id].cur;
+ card->values[id].flags = VGA_VALUE_VALID | VGA_VALUE_SAVED;
+ }
+ }
+}
+
+void
+VgaRestore (VgaCard *card)
+{
+ VgaSave *s;
+ VGA16 id;
+
+ for (s = card->saves; s->first != VGA_REG_NONE; s++)
+ {
+ for (id = s->first; id <= s->last; id++)
+ {
+ if (card->values[id].flags & VGA_VALUE_SAVED)
+ {
+ VgaStore (card, id, card->values[id].save);
+ card->values[id].cur = card->values[id].save;
+ }
+ }
+ }
+}
+
+void
+VgaFinish (VgaCard *card)
+{
+ VGA16 id;
+
+ for (id = 0; id < card->max; id++)
+ card->values[id].flags = 0;
+}
+
+void
+VgaInvalidate (VgaCard *card)
+{
+ VGA16 id;
+
+ for (id = 0; id < card->max; id++)
+ card->values[id].flags &= ~VGA_VALUE_VALID;
+}
+
+
+void
+_VgaSync (VgaCard *card, VGA16 id)
+{
+ if (!(card->values[id].flags & VGA_VALUE_VALID))
+ {
+ card->values[id].cur = VgaFetch (card, id);
+ card->values[id].flags |= VGA_VALUE_VALID;
+ }
+}
+
+void
+VgaSet (VgaCard *card, VgaReg *reg, VGA32 value)
+{
+ VGA8 v, mask, new;
+
+ while (reg->len)
+ {
+ if (reg->id != VGA_REG_NONE)
+ {
+ _VgaSync (card, reg->id);
+ mask = ((1 << reg->len) - 1);
+ new = value & mask;
+ mask <<= reg->base;
+ new <<= reg->base;
+ v = card->values[reg->id].cur;
+ v = v & ~mask | new;
+ card->values[reg->id].cur = v;
+ card->values[reg->id].flags |= VGA_VALUE_MODIFIED|VGA_VALUE_DIRTY;
+ }
+ value >>= reg->len;
+ reg++;
+ }
+}
+
+void
+VgaFlushReg (VgaCard *card, VgaReg *reg)
+{
+ while (reg->len)
+ {
+ if (reg->id != VGA_REG_NONE)
+ {
+ if (card->values[reg->id].flags & VGA_VALUE_DIRTY)
+ {
+ VgaStore (card, reg->id, card->values[reg->id].cur);
+ card->values[reg->id].flags &= ~VGA_VALUE_DIRTY;
+ }
+ }
+ reg++;
+ }
+
+}
+
+void
+VgaSetImm (VgaCard *card, VgaReg *reg, VGA32 value)
+{
+ VgaSet (card, reg, value);
+ VgaFlushReg (card, reg);
+}
+
+VGA32
+VgaGet (VgaCard *card, VgaReg *reg)
+{
+ VGA32 value, offset, v;
+ VGA8 mask;
+
+ value = 0;
+ offset = 0;
+ while (reg->len)
+ {
+ if (reg->id != VGA_REG_NONE)
+ {
+ _VgaSync (card, reg->id);
+ mask = ((1 << reg->len) - 1);
+ v = (card->values[reg->id].cur >> reg->base) & mask;
+ value |= (v << offset);
+ }
+ offset += reg->len;
+ reg++;
+ }
+ return value;
+}
+
+VGA32
+VgaGetImm (VgaCard *card, VgaReg *reg)
+{
+ VgaReg *r = reg;
+
+ while (r->len)
+ {
+ if (r->id != VGA_REG_NONE)
+ card->values[r->id].flags &= ~VGA_VALUE_VALID;
+ r++;
+ }
+ return VgaGet (card, reg);
+}
+
+void
+VgaFlush (VgaCard *card)
+{
+ VGA16 id;
+
+ for (id = 0; id < card->max; id++)
+ {
+ if (card->values[id].flags & VGA_VALUE_DIRTY)
+ {
+ VgaStore (card, id, card->values[id].cur);
+ card->values[id].flags &= ~VGA_VALUE_DIRTY;
+ }
+ }
+}
+
+void
+VgaFill (VgaCard *card, VGA16 low, VGA16 high)
+{
+ VGA16 id;
+
+ for (id = low; id < high; id++)
+ _VgaSync (card, id);
+}
diff --git a/xc/programs/Xserver/hw/kdrive/vga.h b/xc/programs/Xserver/hw/kdrive/vga.h
new file mode 100644
index 000000000..f88597ecf
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/vga.h
@@ -0,0 +1,141 @@
+/*
+ * $Id: vga.h,v 1.1 2000/01/06 12:55:48 faith 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/vga.h,v 1.2 1999/12/30 03:03:07 robin Exp $ */
+
+#ifndef _VGA_H_
+#define _VGA_H_
+
+typedef unsigned long VGA32;
+typedef unsigned short VGA16;
+typedef unsigned char VGA8;
+typedef int VGABOOL;
+typedef volatile VGA8 VGAVOL8;
+
+#define VGATRUE 1
+#define VGAFALSE 0
+
+typedef struct _vgaReg {
+ VGA16 id;
+ VGA8 base;
+ VGA8 len;
+} VgaReg;
+
+#define VGA_REG_NONE 0xffff
+#define VGA_REG_END VGA_REG_NONE, 0, 0
+
+typedef struct _vgaValue {
+ VGA8 save;
+ VGA8 cur;
+ VGA16 flags;
+} VgaValue;
+
+#define VGA_VALUE_VALID 1 /* value ever fetched */
+#define VGA_VALUE_MODIFIED 2 /* value ever changed */
+#define VGA_VALUE_DIRTY 4 /* value needs syncing */
+#define VGA_VALUE_SAVED 8 /* value preserved */
+
+typedef enum _vgaAccess {
+ VgaAccessMem, VgaAccessIo, VgaAccessIndMem, VgaAccessIndIo,
+ VgaAccessDone,
+} VgaAccess;
+
+typedef struct _vgaMap {
+ VgaAccess access;
+ VGA32 port;
+ VGA8 addr; /* for Ind access; addr offset from port */
+ VGA8 value; /* for Ind access; value offset from port */
+ VGA8 index; /* for Ind access; index value */
+} VgaMap;
+
+#define VGA_UNLOCK_FIXED 1 /* dont save current value */
+#define VGA_UNLOCK_LOCK 2 /* execute only on relock */
+#define VGA_UNLOCK_UNLOCK 4 /* execute only on unlock */
+
+typedef struct _vgaSave {
+ VGA16 first;
+ VGA16 last;
+} VgaSave;
+
+#define VGA_SAVE_END VGA_REG_NONE, VGA_REG_NONE
+
+typedef struct _vgaCard {
+ void (*map) (struct _vgaCard *card, VGA16 reg, VgaMap *map, VGABOOL write);
+ void *closure;
+ int max;
+ VgaValue *values;
+ VgaSave *saves;
+} VgaCard;
+
+VGA8
+VgaInb (VGA16 r);
+
+void
+VgaOutb (VGA8 v, VGA16 r);
+
+VGA8
+VgaReadMemb (VGA32 addr);
+
+void
+VgaWriteMemb (VGA8 v, VGA32 addr);
+
+void
+VgaSetImm (VgaCard *card, VgaReg *reg, VGA32 value);
+
+VGA32
+VgaGetImm (VgaCard *card, VgaReg *reg);
+
+void
+VgaSet (VgaCard *card, VgaReg *reg, VGA32 value);
+
+VGA32
+VgaGet (VgaCard *card, VgaReg *reg);
+
+void
+VgaFlush (VgaCard *card);
+
+void
+VgaFill (VgaCard *card, VGA16 low, VGA16 high);
+
+void
+VgaPreserve (VgaCard *card);
+
+void
+VgaInvalidate (VgaCard *card);
+
+void
+VgaRestore (VgaCard *card);
+
+VGA8
+VgaFetch (VgaCard *card, VGA16 id);
+
+void
+VgaStore (VgaCard *card, VGA16 id, VGA8 value);
+
+VGA8
+_VgaFetchInd (VGA16 port, VGA8 reg);
+
+void
+_VgaStoreInd (VGA16 port, VGA8 reg, VGA8 value);
+
+#endif /* _VGA_H_ */
diff --git a/xc/programs/Xserver/hw/kdrive/vxworks/Imakefile b/xc/programs/Xserver/hw/kdrive/vxworks/Imakefile
new file mode 100644
index 000000000..2293267f6
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/vxworks/Imakefile
@@ -0,0 +1,15 @@
+XCOMM $XFree86: xc/programs/Xserver/hw/kdrive/vxworks/Imakefile,v 1.1 1999/12/30 03:03:21 robin Exp $
+#include <Server.tmpl>
+
+SRCS = vxworks.c vxkbd.c vxkmouse.c
+
+OBJS = vxworks.o vxkbd.o vxkmouse.o
+
+INCLUDES = -I. -I.. -I$(XBUILDINCDIR) -I$(FONTINCSRC) \
+ -I../../../fb -I../../../mi -I../../../include -I../../../os \
+ -I$(EXTINCSRC) -I$(XINCLUDESRC)
+
+NormalLibraryObjectRule()
+NormalLibraryTarget(vxworks,$(OBJS))
+
+DependTarget()
diff --git a/xc/programs/Xserver/hw/kdrive/vxworks/vxkbd.c b/xc/programs/Xserver/hw/kdrive/vxworks/vxkbd.c
new file mode 100644
index 000000000..d6636b073
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/vxworks/vxkbd.c
@@ -0,0 +1,262 @@
+/*
+ * $Id: vxkbd.c,v 1.1 2000/01/06 12:55:57 faith Exp $
+ *
+ * Copyright © 1999 Network Computing Devices, Inc. All rights reserved.
+ *
+ * Author: Keith Packard
+ */
+
+#include "kdrive.h"
+#include "kkeymap.h"
+#include <X11/keysym.h>
+#include <inputstr.h>
+
+#define VXWORKS_WIDTH 2
+
+KeySym VxWorksKeymap[] = {
+/*7 f1 */ XK_F1, NoSymbol,
+/*8 escape */ XK_Escape, NoSymbol,
+ NoSymbol, NoSymbol,
+ NoSymbol, NoSymbol,
+ NoSymbol, NoSymbol,
+ NoSymbol, NoSymbol,
+/*13 tab */ XK_Tab, NoSymbol,
+/*14 ` */ XK_grave, XK_asciitilde,
+/*15 f2 */ XK_F2, NoSymbol,
+ NoSymbol, NoSymbol,
+/*17 lctrl */ XK_Control_L, NoSymbol,
+/*18 lshift */ XK_Shift_L, NoSymbol,
+ NoSymbol, NoSymbol,
+/*20 lock */ XK_Caps_Lock, NoSymbol,
+/*21 q */ XK_Q, NoSymbol,
+/*22 1 */ XK_1, XK_exclam,
+/*23 f3 */ XK_F3, NoSymbol,
+ NoSymbol, NoSymbol,
+/*25 lalt */ XK_Meta_L, XK_Alt_L,
+/*26 z */ XK_Z, NoSymbol,
+/*27 s */ XK_S, NoSymbol,
+/*28 a */ XK_A, NoSymbol,
+/*29 w */ XK_W, NoSymbol,
+/*30 2 */ XK_2, XK_at,
+/*31 f4 */ XK_F4, NoSymbol,
+ NoSymbol, NoSymbol,
+/*33 c */ XK_C, NoSymbol,
+/*34 x */ XK_X, NoSymbol,
+/*35 d */ XK_D, NoSymbol,
+/*36 e */ XK_E, NoSymbol,
+/*37 4 */ XK_4, XK_dollar,
+/*38 3 */ XK_3, XK_numbersign,
+/*39 f5 */ XK_F5, NoSymbol,
+ NoSymbol, NoSymbol,
+/*41 space */ XK_space, NoSymbol,
+/*42 v */ XK_V, NoSymbol,
+/*43 f */ XK_F, NoSymbol,
+/*44 t */ XK_T, NoSymbol,
+/*45 r */ XK_R, NoSymbol,
+/*46 5 */ XK_5, XK_percent,
+/*47 f6 */ XK_F6, NoSymbol,
+ NoSymbol, NoSymbol,
+/*49 n */ XK_N, NoSymbol,
+/*50 b */ XK_B, NoSymbol,
+/*51 h */ XK_H, NoSymbol,
+/*52 g */ XK_G, NoSymbol,
+/*53 y */ XK_Y, NoSymbol,
+/*54 6 */ XK_6, XK_asciicircum,
+/*55 f7 */ XK_F7, NoSymbol,
+ NoSymbol, NoSymbol,
+/*57 ralt */ XK_Meta_R, XK_Alt_R,
+/*58 m */ XK_M, NoSymbol,
+/*59 j */ XK_J, NoSymbol,
+/*60 u */ XK_U, NoSymbol,
+/*61 7 */ XK_7, XK_ampersand,
+/*62 8 */ XK_8, XK_asterisk,
+/*63 f8 */ XK_F8, NoSymbol,
+ NoSymbol, NoSymbol,
+/*65 , */ XK_comma, XK_less,
+/*66 k */ XK_K, NoSymbol,
+/*67 i */ XK_I, NoSymbol,
+/*68 o */ XK_O, NoSymbol,
+/*69 0 */ XK_0, XK_parenright,
+/*70 9 */ XK_9, XK_parenleft,
+/*71 f9 */ XK_F9, NoSymbol,
+ NoSymbol, NoSymbol,
+/*73 . */ XK_period, XK_greater,
+/*74 / */ XK_slash, XK_question,
+/*75 l */ XK_L, NoSymbol,
+/*76 ; */ XK_semicolon, XK_colon,
+/*77 p */ XK_P, NoSymbol,
+/*78 - */ XK_minus, XK_underscore,
+/*79 f10 */ XK_F10, NoSymbol,
+ NoSymbol, NoSymbol,
+ NoSymbol, NoSymbol,
+/*82 ' */ XK_apostrophe, XK_quotedbl,
+ NoSymbol, NoSymbol,
+/*84 [ */ XK_bracketleft, XK_braceleft,
+/*85 = */ XK_equal, XK_plus,
+/*86 f11 */ XK_F11, NoSymbol,
+/*87 sysrq */ XK_Sys_Req, XK_Print,
+/*88 rctrl */ XK_Control_R, NoSymbol,
+/*89 rshift */ XK_Shift_R, NoSymbol,
+/*90 enter */ XK_Return, NoSymbol,
+/*91 ] */ XK_bracketright, XK_braceright,
+/*92 \ */ XK_backslash, XK_bar,
+ NoSymbol, NoSymbol,
+/*94 f12 */ XK_F12, NoSymbol,
+/*95 scrolllock*/ XK_Scroll_Lock, NoSymbol,
+/*96 down */ XK_Down, NoSymbol,
+/*97 left */ XK_Left, NoSymbol,
+/*98 pause */ XK_Break, XK_Pause,
+/*99 up */ XK_Up, NoSymbol,
+/*100 delete */ XK_Delete, NoSymbol,
+/*101 end */ XK_End, NoSymbol,
+/*102 bs */ XK_BackSpace, NoSymbol,
+/*103 insert */ XK_Insert, NoSymbol,
+ NoSymbol, NoSymbol,
+/*105 np 1 */ XK_KP_End, XK_KP_1,
+/*106 right */ XK_Right, NoSymbol,
+/*107 np 4 */ XK_KP_Left, XK_KP_4,
+/*108 np 7 */ XK_KP_Home, XK_KP_7,
+/*109 pgdn */ XK_Page_Down, NoSymbol,
+/*110 home */ XK_Home, NoSymbol,
+/*111 pgup */ XK_Page_Up, NoSymbol,
+/*112 np 0 */ XK_KP_Insert, XK_KP_0,
+/*113 np . */ XK_KP_Delete, XK_KP_Decimal,
+/*114 np 2 */ XK_KP_Down, XK_KP_2,
+/*115 np 5 */ XK_KP_5, NoSymbol,
+/*116 np 6 */ XK_KP_Right, XK_KP_6,
+/*117 np 8 */ XK_KP_Up, XK_KP_8,
+/*118 numlock */ XK_Num_Lock, NoSymbol,
+/*119 np / */ XK_KP_Divide, NoSymbol,
+ NoSymbol, NoSymbol,
+/*121 np enter */ XK_KP_Enter, NoSymbol,
+/*122 np 3 */ XK_KP_Page_Down, XK_KP_3,
+ NoSymbol, NoSymbol,
+/*124 np + */ XK_KP_Add, NoSymbol,
+/*125 np 9 */ XK_KP_Page_Up, XK_KP_9,
+/*126 np * */ XK_KP_Multiply, NoSymbol,
+ NoSymbol, NoSymbol,
+ NoSymbol, NoSymbol,
+ NoSymbol, NoSymbol,
+ NoSymbol, NoSymbol,
+ NoSymbol, NoSymbol,
+/*132 np - */ XK_KP_Subtract, NoSymbol,
+ NoSymbol, NoSymbol,
+ NoSymbol, NoSymbol,
+ NoSymbol, NoSymbol,
+ NoSymbol, NoSymbol,
+ NoSymbol, NoSymbol,
+ NoSymbol, NoSymbol,
+/*139 lwin */ XK_Super_L, NoSymbol,
+/*140 rwin */ XK_Super_R, NoSymbol,
+/*141 menu */ XK_Menu, NoSymbol,
+};
+
+void
+VxWorksKeyboardLoad (void)
+{
+ KeySym *k;
+
+ kdMinScanCode = 7;
+ kdKeymapWidth = VXWORKS_WIDTH;
+ kdMaxScanCode = 141;
+ memcpy (kdKeymap, VxWorksKeymap, sizeof (VxWorksKeymap));
+}
+
+static int kbdFd = -1;
+
+#include <errno.h>
+#include <event.h>
+#include <kbd_ioctl.h>
+
+extern KeybdCtrl defaultKeyboardControl;
+
+static void
+VxWorksSetAutorepeat (unsigned char *repeats, Bool on)
+{
+ int i;
+ unsigned char mask;
+ int scan_code;
+ int key_code;
+ unsigned char realkc;
+
+ if (on)
+ {
+ realkc = 1;
+ ioctl (kbdFd, KBD_ALL_REPEAT, &realkc);
+ for (scan_code = 7; scan_code <= 141; scan_code++)
+ {
+ key_code = scan_code + 1;
+ i = key_code >> 3;
+ mask = 1 << (key_code & 7);
+ if ((repeats[i] & mask) == 0)
+ {
+ realkc = scan_code;
+ ioctl (kbdFd, KBD_NO_REPEAT, &realkc);
+ }
+ }
+ }
+ else
+ {
+ realkc = 0;
+ ioctl (kbdFd, KBD_ALL_REPEAT, &realkc);
+ }
+}
+
+int
+VxWorksKeyboardInit (void)
+{
+
+ kbdFd = open ("/dev/kbd", O_RDONLY, 0);
+ if (kbdFd < 0)
+ ErrorF ("keyboard open failure %d\n", errno);
+ VxWorksSetAutorepeat (defaultKeyboardControl.autoRepeats, TRUE);
+ return -1;
+}
+
+void
+VxWorksKeyboardFini (int fd)
+{
+ if (kbdFd >= 0)
+ {
+ close (kbdFd);
+ kbdFd = -1;
+ }
+}
+
+void
+VxWorksKeyboardRead (int fd)
+{
+}
+
+void
+VxWorksKeyboardLeds (int leds)
+{
+ DeviceIntPtr pKeyboard = (DeviceIntPtr) LookupKeyboardDevice ();
+ KeybdCtrl *ctrl = &pKeyboard->kbdfeed->ctrl;
+ led_ioctl_info led_info;
+ int i;
+
+ VxWorksSetAutorepeat (ctrl->autoRepeats, ctrl->autoRepeat);
+ for (i = 0; i < 3; i++)
+ {
+ led_info.bit_n = 1 << i;
+ led_info.OFF_or_ON = (leds & (1 << i)) != 0;
+ led_info.reversed = 0;
+ ioctl (kbdFd, KBD_SET_LED, &led_info);
+ }
+}
+
+void
+VxWorksKeyboardBell (int volume, int frequency, int duration)
+{
+}
+
+KdKeyboardFuncs VxWorksKeyboardFuncs = {
+ VxWorksKeyboardLoad,
+ VxWorksKeyboardInit,
+ VxWorksKeyboardRead,
+ VxWorksKeyboardLeds,
+ VxWorksKeyboardBell,
+ VxWorksKeyboardFini,
+ 3,
+};
diff --git a/xc/programs/Xserver/hw/kdrive/vxworks/vxmouse.c b/xc/programs/Xserver/hw/kdrive/vxworks/vxmouse.c
new file mode 100644
index 000000000..53d44686d
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/vxworks/vxmouse.c
@@ -0,0 +1,121 @@
+/*
+ * $Id: vxmouse.c,v 1.1 2000/01/06 12:55:57 faith Exp $
+ *
+ * Copyright © 1999 Network Computing Devices, Inc. All rights reserved.
+ *
+ * Author: Keith Packard
+ */
+
+#define NEED_EVENTS
+#include "X.h"
+#include "Xproto.h"
+#include "inputstr.h"
+#include "scrnintstr.h"
+#include "kdrive.h"
+#include "Xpoll.h"
+#include <event.h>
+#include <smem.h>
+
+static unsigned long mouseState;
+
+#define BUTTON1 0x01
+#define BUTTON2 0x02
+#define BUTTON3 0x04
+
+#include <errno.h>
+
+static int mouseFd = -1;
+
+static eventqueue *eventQueue;
+
+void
+VxMouseRead (int mousePort)
+{
+ Event ev;
+ int dx, dy;
+ unsigned long flags;
+ unsigned long mask;
+ int n;
+
+ while (eventQueue->head != eventQueue->tail)
+ {
+ ev = *eventQueue->head;
+ if (eventQueue->head >= &eventQueue->events[eventQueue->size-1])
+ eventQueue->head = &eventQueue->events[0];
+ else
+ eventQueue->head++;
+ switch (ev.e_type) {
+ case E_BUTTON:
+ switch (ev.e_device) {
+ case E_MOUSE:
+ switch (ev.e_key) {
+ case BUTTON1:
+ mask = KD_BUTTON_1;
+ break;
+ case BUTTON2:
+ mask = KD_BUTTON_2;
+ break;
+ case BUTTON3:
+ mask = KD_BUTTON_3;
+ break;
+ default:
+ mask = 0;
+ break;
+ }
+ if (ev.e_direction == E_KBUP)
+ mouseState &= ~mask;
+ else
+ mouseState |= mask;
+ KdEnqueueMouseEvent (mouseState | KD_MOUSE_DELTA, 0, 0);
+ break;
+ case E_DKB:
+ KdEnqueueKeyboardEvent (ev.e_key, ev.e_direction == E_KBUP);
+ break;
+ }
+ break;
+ case E_MMOTION:
+ KdEnqueueMouseEvent (mouseState | KD_MOUSE_DELTA,
+ ev.e_x, ev.e_y);
+ break;
+ }
+ }
+}
+
+int
+VxMouseInit (void)
+{
+ int mousePort;
+ unsigned long ev_size;
+
+ mouseState = 0;
+ mousePort = open ("/dev/xdev", O_RDONLY, 0);
+ if (mousePort < 0)
+ ErrorF ("event port open failure %d\n", errno);
+ mouseFd = open ("/dev/mouse", O_RDONLY, 0);
+ if (mouseFd < 0)
+ ErrorF ("mouse open failure %d\n", errno);
+ if (eventQueue == 0)
+ {
+ ioctl (mousePort, EVENT_QUEUE_SMSIZE, &ev_size);
+ eventQueue = (eventqueue *) smem_get ("event", ev_size, (SM_READ|SM_WRITE));
+ }
+ return mousePort;
+}
+
+void
+VxMouseFini (int mousePort)
+{
+ if (mousePort >= 0)
+ close (mousePort);
+ if (mouseFd >= 0)
+ {
+ close (mouseFd);
+ mouseFd = -1;
+ }
+}
+
+KdMouseFuncs VxWorksMouseFuncs = {
+ VxMouseInit,
+ VxMouseRead,
+ VxMouseFini
+};
diff --git a/xc/programs/Xserver/hw/kdrive/vxworks/vxworks.c b/xc/programs/Xserver/hw/kdrive/vxworks/vxworks.c
new file mode 100644
index 000000000..ad9ce0659
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/vxworks/vxworks.c
@@ -0,0 +1,65 @@
+/*
+ * $Id: vxworks.c,v 1.1 2000/01/06 12:55:57 faith Exp $
+ *
+ * Copyright © 1999 Network Computing Devices, Inc. All rights reserved.
+ *
+ * Author: Keith Packard
+ */
+
+#include "kdrive.h"
+#include <X11/keysym.h>
+
+int
+VxWorksInit (void)
+{
+ return 1;
+}
+
+void
+VxWorksEnable (void)
+{
+}
+
+Bool
+VxWorksSpecialKey (KeySym sym)
+{
+ switch (sym) {
+ case XK_Sys_Req:
+ download(1, "setup", 0);
+ return TRUE;
+ case XK_Break:
+ download(1, "launcher", 0);
+ return TRUE;
+ case XK_Delete:
+ dispatchException |= DE_REBOOT;
+ return TRUE;
+ case XK_BackSpace:
+ dispatchException |= DE_RESET;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void
+VxWorksDisable (void)
+{
+}
+
+void
+VxWorksFini (void)
+{
+}
+
+KdOsFuncs VxWorksFuncs = {
+ VxWorksInit,
+ VxWorksEnable,
+ VxWorksSpecialKey,
+ VxWorksDisable,
+ VxWorksFini,
+};
+
+void
+OsVendorInit (void)
+{
+ KdOsInit (&VxWorksFuncs);
+}